drv_sdmmc_imp.h 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063
  1. /* Copyright (C) 2019 RDA Technologies Limited and/or its affiliates("RDA").
  2. * All rights reserved.
  3. *
  4. * This software is supplied "AS IS" without any warranties.
  5. * RDA assumes no responsibility or liability for the use of the software,
  6. * conveys no license or title under any patent, copyright, or mask work
  7. * right to the product. RDA reserves the right to make changes in the
  8. * software without notification. RDA also make no representation or
  9. * warranty that such application will be suitable for the specified use
  10. * without further testing or modification.
  11. */
  12. #ifndef _DRV_SDMMC_IMP_H_
  13. #define _DRV_SDMMC_IMP_H_
  14. #include "osi_compiler.h"
  15. #include "drv_names.h"
  16. #include "drv_config.h"
  17. #include "osi_api.h"
  18. #include "osi_clock.h"
  19. #include "hwregs.h"
  20. #include "drv_ifc.h"
  21. #include <assert.h>
  22. #include "quec_proj_config.h"
  23. OSI_EXTERN_C_BEGIN
  24. #ifndef CONFIG_8910_EMMC_SUPPORT
  25. #ifdef CONFIG_SOC_8910
  26. #define SDMMC_CLOCK_SOURCE CONFIG_DEFAULT_SYSAXI_FREQ
  27. #endif
  28. #if defined(CONFIG_SOC_8811) || defined(CONFIG_SOC_8850)
  29. #define SDMMC_CLOCK_SOURCE CONFIG_DEFAULT_SYS_CLK_FREQ
  30. #endif
  31. #define SDMMC_CLK_FREQ_IDENTIFY (400000)
  32. #define SDMMC_CLK_FREQ_SD CONFIG_SDMMC_CLK_FREQ_SD
  33. #define SDMMC_CLK_FREQ_SDHC CONFIG_SDMMC_CLK_FREQ_SDHC
  34. #define SDMMC_CMD8_CHECK_PATTERN 0xaa
  35. #define SDMMC_CMD8_VOLTAGE_SEL (0x1 << 8)
  36. #define SDMMC_READ_TIMEOUT_MS (5000)
  37. #define SDMMC_WRITE_TIMEOUT_MS (5000)
  38. #if QUEC_PATCH_SDMMC_WRITE_READ_BIG_FILE
  39. #define SDMMC_CMD_TIMEOUT_US (10000)
  40. #define SDMMC_RESP_TIMEOUT_US (10000)
  41. #define QUEC_SDMMC_CMD_LONG_TIMEOUT_US (2000000)
  42. #define QUEC_SDMMC_RESP_LONG_TIMEOUT_US (2000000)
  43. #else
  44. #define SDMMC_CMD_TIMEOUT_US (30000)
  45. #define SDMMC_RESP_TIMEOUT_US (30000)
  46. #endif
  47. #define SDMMC_TRAN_TIMEOUT_US (2000000)
  48. #define SDMMC_SDMMC_OCR_TIMEOUT_US (1000000) // the card is supposed to answer within 1s
  49. #define SDMMC_CSD_VERSION_1 0
  50. #define SDMMC_CSD_VERSION_2 1
  51. #define SDMMC_CSD_VERSION_3 2
  52. typedef struct
  53. {
  54. uint32_t v[4];
  55. } drvSdmmcResp_t;
  56. /**
  57. * sdmmcCardState_t
  58. *
  59. * The state of the card when receiving the command. If the command execution
  60. * causes a state change, it will be visible to the host in the response to
  61. * the next command. The four bits are interpreted as a binary coded number
  62. * between 0 and 15.
  63. */
  64. typedef enum
  65. {
  66. SDMMC_CARD_STATE_IDLE = 0,
  67. SDMMC_CARD_STATE_READY = 1,
  68. SDMMC_CARD_STATE_IDENT = 2,
  69. SDMMC_CARD_STATE_STBY = 3,
  70. SDMMC_CARD_STATE_TRAN = 4,
  71. SDMMC_CARD_STATE_DATA = 5,
  72. SDMMC_CARD_STATE_RCV = 6,
  73. SDMMC_CARD_STATE_PRG = 7,
  74. SDMMC_CARD_STATE_DIS = 8
  75. } sdmmcCardState_t;
  76. typedef union {
  77. uint32_t v;
  78. struct
  79. {
  80. uint32_t vdd_win : 24; // [23:0]
  81. uint32_t s18a : 1; // [24]
  82. uint32_t __16_15 : 2; // [26:25]
  83. uint32_t co2t : 1; // [27]
  84. uint32_t __28_28 : 1; // [28]
  85. uint32_t uhs2 : 1; // [29]
  86. uint32_t ccs : 1; // [30]
  87. uint32_t power_on_finish : 1; // [31]
  88. } b;
  89. } sdmmcOcr_t;
  90. /**
  91. * sdmmcCardStatus_t
  92. *
  93. * Card status as returned by R1 reponses (spec V2 pdf p.)
  94. */
  95. #ifdef CONFIG_QUEC_PROJECT_FEATURE_EMMC2
  96. typedef union {
  97. uint32_t v;
  98. struct
  99. {
  100. uint32_t __2_0 : 3; // [0:2]
  101. uint32_t ake_seq_error : 1; // [3]
  102. uint32_t __4_4 : 1; // [4]
  103. uint32_t app_cmd : 1; // [5]
  104. uint32_t fx_event : 1; // [6]
  105. uint32_t __7_7 : 1; // [7]
  106. uint32_t ready_for_data : 1; // [8]
  107. sdmmcCardState_t current_state : 4; // [9:12]
  108. uint32_t erase_reset : 1; // [13]
  109. uint32_t card_ecc_disabled : 1; // [14]
  110. uint32_t wp_erase_skip : 1; // [15]
  111. uint32_t csd_overwrite : 1; // [16]
  112. uint32_t __18_17 : 2; // [17:18]
  113. uint32_t error : 1; // [19]
  114. uint32_t cc_error : 1; // [20]
  115. uint32_t card_ecc_failed : 1; // [21]
  116. uint32_t illegal_command : 1; // [22]
  117. uint32_t com_crc_error : 1; // [23]
  118. uint32_t lock_unlock_fail : 1; // [24]
  119. uint32_t card_is_locked : 1; // [25]
  120. uint32_t wp_violation : 1; // [26]
  121. uint32_t erase_param : 1; // [27]
  122. uint32_t erase_seq_error : 1; // [28]
  123. uint32_t block_len_error : 1; // [29]
  124. uint32_t address_error : 1; // [30]
  125. uint32_t out_of_range : 1; // [31]
  126. } b;
  127. } sdmmcCardStatus_SD_t;
  128. //重新定义一个符合EMMC 5.1协议的sdmmcCardStatus_t
  129. typedef union {
  130. uint32_t v;
  131. struct
  132. {
  133. uint32_t __4_0 : 5; // [0:4]
  134. uint32_t app_cmd : 1; // [5]
  135. uint32_t exception_event : 1; // [6]
  136. uint32_t switch_error : 1; // [7]
  137. uint32_t ready_for_data : 1; // [8]
  138. sdmmcCardState_t current_state : 4; // [9:12]
  139. uint32_t erase_reset : 1; // [13]
  140. uint32_t __14_14 : 1; // [14]
  141. uint32_t wp_erase_skip : 1; // [15]
  142. uint32_t csd_overwrite : 1; // [16]
  143. uint32_t obsolete : 2; // [17:18]
  144. uint32_t error : 1; // [19]
  145. uint32_t cc_error : 1; // [20]
  146. uint32_t device_ecc_failed : 1; // [21]
  147. uint32_t illegal_command : 1; // [22]
  148. uint32_t com_crc_error : 1; // [23]
  149. uint32_t lock_unlock_failed : 1; // [24]
  150. uint32_t device_is_locked : 1; // [25]
  151. uint32_t wp_violation : 1; // [26]
  152. uint32_t erase_param : 1; // [27]
  153. uint32_t erase_seq_error : 1; // [28]
  154. uint32_t block_len_error : 1; // [29]
  155. uint32_t address_misalign : 1; // [30]
  156. uint32_t address_out_of_range : 1; // [31]
  157. } b;
  158. } sdmmcCardStatus_t;
  159. #else
  160. typedef union {
  161. uint32_t v;
  162. struct
  163. {
  164. uint32_t __2_0 : 3; // [0:2]
  165. uint32_t ake_seq_error : 1; // [3]
  166. uint32_t __4_4 : 1; // [4]
  167. uint32_t app_cmd : 1; // [5]
  168. uint32_t fx_event : 1; // [6]
  169. uint32_t __7_7 : 1; // [7]
  170. uint32_t ready_for_data : 1; // [8]
  171. sdmmcCardState_t current_state : 4; // [9:12]
  172. uint32_t erase_reset : 1; // [13]
  173. uint32_t card_ecc_disabled : 1; // [14]
  174. uint32_t wp_erase_skip : 1; // [15]
  175. uint32_t csd_overwrite : 1; // [16]
  176. uint32_t __18_17 : 2; // [17:18]
  177. uint32_t error : 1; // [19]
  178. uint32_t cc_error : 1; // [20]
  179. uint32_t card_ecc_failed : 1; // [21]
  180. uint32_t illegal_command : 1; // [22]
  181. uint32_t com_crc_error : 1; // [23]
  182. uint32_t lock_unlock_fail : 1; // [24]
  183. uint32_t card_is_locked : 1; // [25]
  184. uint32_t wp_violation : 1; // [26]
  185. uint32_t erase_param : 1; // [27]
  186. uint32_t erase_seq_error : 1; // [28]
  187. uint32_t block_len_error : 1; // [29]
  188. uint32_t address_error : 1; // [30]
  189. uint32_t out_of_range : 1; // [31]
  190. } b;
  191. } sdmmcCardStatus_t;
  192. #endif
  193. typedef struct __attribute__((packed, aligned(1)))
  194. {
  195. unsigned __0__0 : 1; // [0:0]
  196. unsigned crc : 7; // [7:1]
  197. unsigned mdt : 12; // [19:8]
  198. unsigned __23_20 : 4; // [23:20]
  199. unsigned psn : 32; // [55:24]
  200. unsigned prv : 8; // [63:56]
  201. uint64_t pnm : 40; // [103:64]
  202. unsigned oid : 16; // [119:104]
  203. unsigned mid : 8; // [127:120]
  204. } sdmmcCid_t;
  205. #ifdef CONFIG_QUEC_PROJECT_FEATURE_EMMC2
  206. typedef struct __attribute__((packed, aligned(1)))
  207. {
  208. unsigned __0__0 : 1; // [0:0]
  209. unsigned crc : 7; // [7:1]
  210. unsigned mdt : 8; // [15:8]
  211. unsigned psn : 32; // [47:16]
  212. unsigned prv : 8; // [55:48]
  213. uint64_t pnm : 48; // [103:56]
  214. unsigned oid : 8; // [111:104]
  215. unsigned cbx : 2; // [113:112]
  216. unsigned _119_114 : 6;// [119:114]
  217. unsigned mid : 8; // [127:120]
  218. } sdmmcCidEmmc_t;
  219. #endif
  220. typedef struct __attribute__((packed, aligned(1)))
  221. {
  222. unsigned __0_0 : 1; // [0:0]
  223. unsigned crc : 7; // [7:1]
  224. unsigned __9_8 : 2; // [9:8]
  225. unsigned file_format : 2; // [11:10]
  226. unsigned tmp_write_protect : 1; // [12:12]
  227. unsigned perm_write_protect : 1; // [13:13]
  228. unsigned copy : 1; // [14:14]
  229. unsigned file_format_grp : 1; // [15:15]
  230. unsigned __20_16 : 5; // [20:16]
  231. unsigned write_bl_partial : 1; // [21:21]
  232. unsigned write_bl_len : 4; // [25:22]
  233. unsigned r2w_factor : 3; // [28:26]
  234. unsigned __30_29 : 2; // [30:29]
  235. unsigned wr_grp_enable : 1; // [31:31]
  236. unsigned wr_grp_size : 7; // [38:32]
  237. unsigned sector_size : 7; // [45:39]
  238. unsigned erase_blk_en : 1; // [46:46]
  239. unsigned c_size_mult : 3; // [49:47]
  240. unsigned vdd_w_curr_max : 3; // [52:50]
  241. unsigned vdd_w_curr_min : 3; // [55:53]
  242. unsigned vdd_r_curr_max : 3; // [58:56]
  243. unsigned vdd_r_curr_min : 3; // [61:59]
  244. unsigned c_size : 12; // [73:62]
  245. unsigned __75_74 : 2; // [75:74]
  246. unsigned dsr_imp : 1; // [76:76]
  247. unsigned read_blk_misalign : 1; // [77:77]
  248. unsigned write_blk_misalign : 1; // [78:78]
  249. unsigned read_bl_partial : 1; // [79:79]
  250. unsigned read_bl_len : 4; // [83:80]
  251. unsigned ccc : 12; // [95:84]
  252. unsigned trans_speed : 8; // [103:96]
  253. unsigned nsac : 8; // [111:104]
  254. unsigned taac : 8; // [119:112]
  255. unsigned __125_120 : 6; // [125:120]
  256. unsigned csd_struct : 2; // [127:126]
  257. } sdmmcCsdV1_t;
  258. typedef struct __attribute__((packed, aligned(1)))
  259. {
  260. unsigned __0_0 : 1; // [0:0]
  261. unsigned crc : 7; // [7:1]
  262. unsigned __9_8 : 2; // [9:8]
  263. unsigned file_format : 2; // [11:10]
  264. unsigned tmp_write_protect : 1; // [12:12]
  265. unsigned perm_write_protect : 1; // [13:13]
  266. unsigned copy : 1; // [14:14]
  267. unsigned file_format_grp : 1; // [15:15]
  268. unsigned __20_16 : 5; // [20:16]
  269. unsigned write_bl_partial : 1; // [21:21]
  270. unsigned write_bl_len : 4; // [25:22]
  271. unsigned r2w_factor : 3; // [28:26]
  272. unsigned __30_29 : 2; // [30:29]
  273. unsigned wr_grp_enable : 1; // [31:31]
  274. unsigned wr_grp_size : 7; // [38:32]
  275. unsigned sector_size : 7; // [45:39]
  276. unsigned erase_blk_en : 1; // [46:46]
  277. unsigned __47_47 : 1; // [47:47]
  278. unsigned c_size : 22; // [69:48]
  279. unsigned __75_70 : 6; // [75:70]
  280. unsigned dsr_imp : 1; // [76:76]
  281. unsigned read_blk_misalign : 1; // [77:77]
  282. unsigned write_blk_misalign : 1; // [78:78]
  283. unsigned read_bl_partial : 1; // [79:79]
  284. unsigned read_bl_len : 4; // [83:80]
  285. unsigned ccc : 12; // [95:84]
  286. unsigned trans_speed : 8; // [103:96]
  287. unsigned nsac : 8; // [111:104]
  288. unsigned taac : 8; // [119:112]
  289. unsigned __125_120 : 6; // [125:120]
  290. unsigned csd_struct : 2; // [127:126]
  291. } sdmmcCsdV2_t;
  292. typedef struct __attribute__((packed, aligned(1)))
  293. {
  294. unsigned __0_0 : 1; // [0:0]
  295. unsigned crc : 7; // [7:1]
  296. unsigned __9_8 : 2; // [9:8]
  297. unsigned file_format : 2; // [11:10]
  298. unsigned tmp_write_protect : 1; // [12:12]
  299. unsigned perm_write_protect : 1; // [13:13]
  300. unsigned copy : 1; // [14:14]
  301. unsigned file_format_grp : 1; // [15:15]
  302. unsigned __20_16 : 5; // [20:16]
  303. unsigned write_bl_partial : 1; // [21:21]
  304. unsigned write_bl_len : 4; // [25:22]
  305. unsigned r2w_factor : 3; // [28:26]
  306. unsigned __30_29 : 2; // [30:29]
  307. unsigned wr_grp_enable : 1; // [31:31]
  308. unsigned wr_grp_size : 7; // [38:32]
  309. unsigned sector_size : 7; // [45:39]
  310. unsigned erase_blk_en : 1; // [46:46]
  311. unsigned __47_47 : 1; // [47:47]
  312. unsigned c_size : 28; // [75:48]
  313. unsigned dsr_imp : 1; // [76:76]
  314. unsigned read_blk_misalign : 1; // [77:77]
  315. unsigned write_blk_misalign : 1; // [78:78]
  316. unsigned read_bl_partial : 1; // [79:79]
  317. unsigned read_bl_len : 4; // [83:80]
  318. unsigned ccc : 12; // [95:84]
  319. unsigned trans_speed : 8; // [103:96]
  320. unsigned nsac : 8; // [111:104]
  321. unsigned taac : 8; // [119:112]
  322. unsigned __125_120 : 6; // [125:120]
  323. unsigned csd_struct : 2; // [127:126]
  324. } sdmmcCsdV3_t;
  325. #ifdef CONFIG_QUEC_PROJECT_FEATURE_EMMC2
  326. //符合EMMC 4.4和EMMC 5.1规范的CSD寄存器定义
  327. typedef struct __attribute__((packed, aligned(1)))
  328. {
  329. unsigned __0_0 : 1; // [0:0]
  330. unsigned crc : 7; // [7:1]
  331. unsigned ecc : 2; // [9:8]
  332. unsigned file_format : 2; // [11:10]
  333. unsigned tmp_write_protect : 1; // [12:12]
  334. unsigned perm_write_protect : 1; // [13:13]
  335. unsigned copy : 1; // [14:14]
  336. unsigned file_format_grp : 1; // [15:15]
  337. unsigned content_prot_app : 1; // [16:16]
  338. unsigned __20_17 : 4; // [20:17]
  339. unsigned write_bl_partial : 1; // [21:21]
  340. unsigned write_bl_len : 4; // [25:22]
  341. unsigned r2w_factor : 3; // [28:26]
  342. unsigned default_ecc : 2; // [30:29]
  343. unsigned wp_grp_enable : 1; // [31:31]
  344. unsigned wp_grp_size : 5; // [36:32]
  345. unsigned erase_grp_mult : 5; // [41:37]
  346. unsigned erase_grp_size : 5; // [46:42]
  347. unsigned c_size_mult : 3; // [49:47]
  348. unsigned vdd_w_curr_max : 3; // [52:50]
  349. unsigned vdd_w_curr_min : 3; // [55:53]
  350. unsigned vdd_r_curr_max : 3; // [58:56]
  351. unsigned vdd_r_curr_min : 3; // [61:59]
  352. unsigned c_size : 12; // [73:62]
  353. unsigned __75_74 : 2; // [75:74]
  354. unsigned dsr_imp : 1; // [76:76]
  355. unsigned read_blk_misalign : 1; // [77:77]
  356. unsigned write_blk_misalign : 1; // [78:78]
  357. unsigned read_bl_partial : 1; // [79:79]
  358. unsigned read_bl_len : 4; // [83:80]
  359. unsigned ccc : 12; // [95:84]
  360. unsigned trans_speed : 8; // [103:96]
  361. unsigned nsac : 8; // [111:104]
  362. unsigned taac : 8; // [119:112]
  363. unsigned __121_120 : 2; // [121:120]
  364. unsigned spec_vers : 4; // [125:122]
  365. unsigned csd_struct : 2; // [127:126]
  366. } sdmmcCsdV4_t;
  367. #endif
  368. typedef union {
  369. sdmmcCsdV1_t v1;
  370. sdmmcCsdV2_t v2;
  371. sdmmcCsdV3_t v3;
  372. #ifdef CONFIG_QUEC_PROJECT_FEATURE_EMMC2
  373. sdmmcCsdV4_t v4;
  374. #endif
  375. } sdmmcCsd_t;
  376. #define CSD_FIELD(csd, f) (csd->v1.csd_struct == 0 ? csd->v1.f : csd->v1.csd_struct == 1 ? csd->v2.f : csd->v3.f)
  377. static_assert(sizeof(sdmmcCsdV1_t) == 16, "sdmmcCsdV1_t is wrong");
  378. static_assert(sizeof(sdmmcCsdV2_t) == 16, "sdmmcCsdV2_t is wrong");
  379. static_assert(sizeof(sdmmcCsdV3_t) == 16, "sdmmcCsdV3_t is wrong");
  380. static_assert(sizeof(sdmmcCsd_t) == 16, "sdmmcCsd_t is wrong");
  381. static_assert(sizeof(sdmmcCid_t) == 16, "sdmmcCid_t is wrong");
  382. static inline unsigned prvCsdStruct(sdmmcCsd_t *csd) { return csd->v1.csd_struct; }
  383. static inline unsigned prvCsdTaac(sdmmcCsd_t *csd) { return CSD_FIELD(csd, taac); }
  384. static inline unsigned prvCsdNsac(sdmmcCsd_t *csd) { return CSD_FIELD(csd, nsac); }
  385. static inline unsigned prvCsdTransSpeed(sdmmcCsd_t *csd) { return CSD_FIELD(csd, trans_speed); }
  386. static inline unsigned prvCsdCcc(sdmmcCsd_t *csd) { return CSD_FIELD(csd, ccc); }
  387. static inline unsigned prvCsdReadBlLen(sdmmcCsd_t *csd) { return CSD_FIELD(csd, read_bl_len); }
  388. static inline unsigned prvCsdReadBlPartial(sdmmcCsd_t *csd) { return CSD_FIELD(csd, read_bl_partial); }
  389. static inline unsigned prvCsdWriteBlkMisalign(sdmmcCsd_t *csd) { return CSD_FIELD(csd, write_blk_misalign); }
  390. static inline unsigned prvCsdReadBlkMisalign(sdmmcCsd_t *csd) { return CSD_FIELD(csd, read_blk_misalign); }
  391. static inline unsigned prvCsdDsrImp(sdmmcCsd_t *csd) { return CSD_FIELD(csd, dsr_imp); }
  392. static inline unsigned prvCsdCSize(sdmmcCsd_t *csd) { return CSD_FIELD(csd, c_size); }
  393. static inline unsigned prvCsdVddRCurrMin(sdmmcCsd_t *csd) { return csd->v1.vdd_r_curr_min; }
  394. static inline unsigned prvCsdVddRCurrMax(sdmmcCsd_t *csd) { return csd->v1.vdd_r_curr_max; }
  395. static inline unsigned prvCsdVddWCurrMin(sdmmcCsd_t *csd) { return csd->v1.vdd_w_curr_min; }
  396. static inline unsigned prvCsdVddWCurrMax(sdmmcCsd_t *csd) { return csd->v1.vdd_w_curr_max; }
  397. static inline unsigned prvCsdCSizeMult(sdmmcCsd_t *csd) { return csd->v1.c_size_mult; }
  398. static inline unsigned prvCsdEraseBlkEn(sdmmcCsd_t *csd) { return CSD_FIELD(csd, erase_blk_en); }
  399. static inline unsigned prvCsdSectorSize(sdmmcCsd_t *csd) { return CSD_FIELD(csd, sector_size); }
  400. static inline unsigned prvCsdWrGrpSize(sdmmcCsd_t *csd) { return CSD_FIELD(csd, wr_grp_size); }
  401. static inline unsigned prvCsdWrGrpEnable(sdmmcCsd_t *csd) { return CSD_FIELD(csd, wr_grp_enable); }
  402. static inline unsigned prvCsdR2wFactor(sdmmcCsd_t *csd) { return CSD_FIELD(csd, r2w_factor); }
  403. static inline unsigned prvCsdWriteBlLen(sdmmcCsd_t *csd) { return CSD_FIELD(csd, write_bl_len); }
  404. static inline unsigned prvCsdWriteBlPartial(sdmmcCsd_t *csd) { return CSD_FIELD(csd, write_bl_partial); }
  405. static inline unsigned prvCsdFileFormatGrp(sdmmcCsd_t *csd) { return CSD_FIELD(csd, file_format_grp); }
  406. static inline unsigned prvCsdCopy(sdmmcCsd_t *csd) { return CSD_FIELD(csd, copy); }
  407. static inline unsigned prvCsdPermWriteProtect(sdmmcCsd_t *csd) { return CSD_FIELD(csd, perm_write_protect); }
  408. static inline unsigned prvCsdTmpWriteProtect(sdmmcCsd_t *csd) { return CSD_FIELD(csd, tmp_write_protect); }
  409. static inline unsigned prvCsdFileFormat(sdmmcCsd_t *csd) { return CSD_FIELD(csd, file_format_grp); }
  410. static inline unsigned prvCsdCrc(sdmmcCsd_t *csd) { return CSD_FIELD(csd, crc); }
  411. /**
  412. * SDMMC_ACMD_SEL
  413. * mark a command as application specific
  414. */
  415. #define SDMMC_ACMD_SEL 0x80000000
  416. /**
  417. * SDMMC_CMD_MASK
  418. *
  419. * Mask to get from a sdmmcCmd_t value the corresponding
  420. * command index
  421. */
  422. #define SDMMC_CMD_MASK 0x3F
  423. /**
  424. * sdmmcCmd_t
  425. * SD commands index
  426. */
  427. typedef enum
  428. {
  429. SDMMC_CMD_GO_IDLE_STATE = 0,
  430. SDMMC_CMD_MMC_SEND_OP_COND = 1,
  431. SDMMC_CMD_ALL_SEND_CID = 2,
  432. SDMMC_CMD_SEND_RELATIVE_ADDR = 3,
  433. SDMMC_CMD_SET_DSR = 4,
  434. SDMMC_CMD_SWITCH = 6,
  435. SDMMC_CMD_SELECT_CARD = 7,
  436. SDMMC_CMD_SEND_IF_COND = 8,
  437. #ifdef CONFIG_QUEC_PROJECT_FEATURE_EMMC2
  438. SEND_EXT_CSD = SDMMC_CMD_SEND_IF_COND,
  439. #endif
  440. SDMMC_CMD_SEND_CSD = 9,
  441. SDMMC_CMD_STOP_TRANSMISSION = 12,
  442. SDMMC_CMD_SEND_STATUS = 13,
  443. SDMMC_CMD_SET_BLOCKLEN = 16,
  444. SDMMC_CMD_READ_SINGLE_BLOCK = 17,
  445. SDMMC_CMD_READ_MULT_BLOCK = 18,
  446. SDMMC_CMD_WRITE_SINGLE_BLOCK = 24,
  447. SDMMC_CMD_WRITE_MULT_BLOCK = 25,
  448. SDMMC_CMD_APP_CMD = 55,
  449. SDMMC_CMD_SET_BUS_WIDTH = (6 | SDMMC_ACMD_SEL),
  450. SDMMC_CMD_SEND_NUM_WR_BLOCKS = (22 | SDMMC_ACMD_SEL),
  451. #ifdef CONFIG_QUEC_PROJECT_FEATURE_EMMC2
  452. SDMMC_CMD_SET_WR_BLK_COUNT_EMMC = 23,
  453. #endif
  454. SDMMC_CMD_SET_WR_BLK_COUNT = (23 | SDMMC_ACMD_SEL),
  455. SDMMC_CMD_SEND_OP_COND = (41 | SDMMC_ACMD_SEL)
  456. } sdmmcCmd_t;
  457. /**
  458. * sdmmcCheckStatus_t
  459. *
  460. * check register hwp->sdmmc_status different bit
  461. */
  462. typedef enum
  463. {
  464. SDMMC_CHECK_TRANSFER_DONE,
  465. SDMMC_CHECK_RESPONSE_OK,
  466. SDMMC_CHECK_CRC_OK,
  467. SDMMC_CHECK_DATA_OK,
  468. } sdmmcCheckStatus_t;
  469. /**
  470. * sdmmcDataBusWidth_t
  471. *
  472. * Cf spec v2 pdf p. 76 for ACMD6 argument
  473. * That type is used to describe how many data lines are used to transfer data
  474. * to and from the SD card.
  475. */
  476. typedef enum
  477. {
  478. SDMMC_DATA_BUS_WIDTH_1 = 0x0,
  479. SDMMC_DATA_BUS_WIDTH_4 = 0x2,
  480. SDMMC_DATA_BUS_WIDTH_8 = 0x4
  481. } sdmmcDataBusWidth_t;
  482. typedef enum
  483. {
  484. SDMMC_RESP_NONE = 0,
  485. SDMMC_RESP_FETCH = 1,
  486. SDMMC_RESP_CHECK = 2,
  487. } sdmmcRespOption_t;
  488. /**
  489. * Maximum block count per transfter are affected by 2 registers:
  490. * 1. sdmmc_block_cnt_reg: 16bits
  491. * 2. ifc.tc: 23bits, 14bits when block size is 512
  492. */
  493. #define SDMMC_MAX_BLOCK_PER_XFER (0x3fff)
  494. #if QUEC_PATCH_SDMMC_WRITE_READ_BIG_FILE
  495. typedef enum
  496. {
  497. QUEC_SDMMC_CMD_RESP_SHORT_WAIT = 0, //10ms超时。默认为0。上电时序使用0
  498. QUEC_SDMMC_CMD_RESP_LONG_WAIT, //2S超时,只有在读写的时候使用
  499. }quec_sdmmc_cmd_resp_wait_time_e;
  500. #endif
  501. struct drvSdmmc
  502. {
  503. uint32_t name;
  504. HWP_SDMMC_T *hwp;
  505. drvIfcChannel_t rx_ifc;
  506. drvIfcChannel_t tx_ifc;
  507. uint32_t irqn;
  508. drvSdmmcResp_t resp;
  509. sdmmcCsd_t csd;
  510. sdmmcCid_t cid;
  511. sdmmcOcr_t ocr;
  512. uint32_t rca;
  513. uint32_t dsr;
  514. uint8_t clk_adj;
  515. uint8_t clk_inv;
  516. bool card_is_sdhc;
  517. sdmmcDataBusWidth_t bus_width;
  518. uint32_t max_clk;
  519. uint32_t master_clk;
  520. uint32_t card_type;
  521. bool opened;
  522. bool rx_enabled;
  523. bool tx_enabled;
  524. uint32_t block_count;
  525. uint32_t block_size;
  526. osiClockConstrainRegistry_t clk_constrain;
  527. osiPmSource_t *pm_source;
  528. osiSemaphore_t *tx_done_sema;
  529. osiSemaphore_t *rx_done_sema;
  530. osiMutex_t *lock;
  531. struct
  532. {
  533. unsigned sdmmc_trans_speed;
  534. } pm_ctx;
  535. #if QUEC_PATCH_SDMMC_WRITE_READ_BIG_FILE
  536. quec_sdmmc_cmd_resp_wait_time_e quec_cmd_resp_loog_wait; //默认为QUEC_SDMMC_CMD_RESP_SHORT_WAIT
  537. #endif
  538. };
  539. #else
  540. #ifdef CONFIG_SOC_8910
  541. #define SDMMC_CLOCK_SOURCE CONFIG_DEFAULT_SYSAXI_FREQ
  542. #endif
  543. #ifdef CONFIG_SOC_8811
  544. #define SDMMC_CLOCK_SOURCE CONFIG_DEFAULT_SYS_CLK_FREQ
  545. #endif
  546. #define SDMMC_CLK_FREQ_IDENTIFY (400000)
  547. #define SDMMC_CLK_FREQ_SD CONFIG_SDMMC_CLK_FREQ_SD
  548. #define SDMMC_CLK_FREQ_SDHC CONFIG_SDMMC_CLK_FREQ_SDHC
  549. #define SDMMC_CMD8_CHECK_PATTERN 0xaa
  550. #define SDMMC_CMD8_VOLTAGE_SEL (0x1 << 8)
  551. #define SDMMC_READ_TIMEOUT_MS (5000)
  552. #define SDMMC_WRITE_TIMEOUT_MS (5000)
  553. #define SDMMC_CMD_TIMEOUT_US (10000)
  554. #define SDMMC_RESP_TIMEOUT_US (10000)
  555. #define SDMMC_TRAN_TIMEOUT_US (2000000)
  556. #define SDMMC_SDMMC_OCR_TIMEOUT_US (1000000) // the card is supposed to answer within 1s
  557. #define SDMMC_CSD_VERSION_1 0
  558. #define SDMMC_CSD_VERSION_2 1
  559. #define SDMMC_CSD_VERSION_3 2
  560. typedef struct
  561. {
  562. uint32_t v[4];
  563. } drvSdmmcResp_t;
  564. /**
  565. * sdmmcCardState_t
  566. *
  567. * The state of the card when receiving the command. If the command execution
  568. * causes a state change, it will be visible to the host in the response to
  569. * the next command. The four bits are interpreted as a binary coded number
  570. * between 0 and 15.
  571. */
  572. typedef enum
  573. {
  574. SDMMC_CARD_STATE_IDLE = 0,
  575. SDMMC_CARD_STATE_READY = 1,
  576. SDMMC_CARD_STATE_IDENT = 2,
  577. SDMMC_CARD_STATE_STBY = 3,
  578. SDMMC_CARD_STATE_TRAN = 4,
  579. SDMMC_CARD_STATE_DATA = 5,
  580. SDMMC_CARD_STATE_RCV = 6,
  581. SDMMC_CARD_STATE_PRG = 7,
  582. SDMMC_CARD_STATE_DIS = 8
  583. } sdmmcCardState_t;
  584. typedef union {
  585. uint32_t v;
  586. struct
  587. {
  588. uint32_t vdd_win : 24; // [23:0]
  589. uint32_t s18a : 1; // [24]
  590. uint32_t __16_15 : 2; // [26:25]
  591. uint32_t co2t : 1; // [27]
  592. uint32_t __28_28 : 1; // [28]
  593. uint32_t uhs2 : 1; // [29]
  594. uint32_t ccs : 1; // [30]
  595. uint32_t power_on_finish : 1; // [31]
  596. } b;
  597. } sdmmcOcr_t;
  598. /**
  599. * sdmmcCardStatus_t
  600. *
  601. * Card status as returned by R1 reponses (spec V2 pdf p.)
  602. */
  603. /*
  604. typedef union {
  605. uint32_t v;
  606. struct
  607. {
  608. uint32_t __2_0 : 3; // [0:2]
  609. uint32_t ake_seq_error : 1; // [3]
  610. uint32_t __4_4 : 1; // [4]
  611. uint32_t app_cmd : 1; // [5]
  612. uint32_t fx_event : 1; // [6]
  613. uint32_t __7_7 : 1; // [7]
  614. uint32_t ready_for_data : 1; // [8]
  615. sdmmcCardState_t current_state : 4; // [9:12]
  616. uint32_t erase_reset : 1; // [13]
  617. uint32_t card_ecc_disabled : 1; // [14]
  618. uint32_t wp_erase_skip : 1; // [15]
  619. uint32_t csd_overwrite : 1; // [16]
  620. uint32_t __18_17 : 2; // [17:18]
  621. uint32_t error : 1; // [19]
  622. uint32_t cc_error : 1; // [20]
  623. uint32_t card_ecc_failed : 1; // [21]
  624. uint32_t illegal_command : 1; // [22]
  625. uint32_t com_crc_error : 1; // [23]
  626. uint32_t lock_unlock_fail : 1; // [24]
  627. uint32_t card_is_locked : 1; // [25]
  628. uint32_t wp_violation : 1; // [26]
  629. uint32_t erase_param : 1; // [27]
  630. uint32_t erase_seq_error : 1; // [28]
  631. uint32_t block_len_error : 1; // [29]
  632. uint32_t address_error : 1; // [30]
  633. uint32_t out_of_range : 1; // [31]
  634. } b;
  635. } sdmmcCardStatus_t;
  636. */
  637. //重新定义一个符合EMMC 5.1协议的sdmmcCardStatus_t
  638. typedef union {
  639. uint32_t v;
  640. struct
  641. {
  642. uint32_t __4_0 : 5; // [0:4]
  643. uint32_t app_cmd : 1; // [5]
  644. uint32_t exception_event : 1; // [6]
  645. uint32_t switch_error : 1; // [7]
  646. uint32_t ready_for_data : 1; // [8]
  647. sdmmcCardState_t current_state : 4; // [9:12]
  648. uint32_t erase_reset : 1; // [13]
  649. uint32_t __14_14 : 1; // [14]
  650. uint32_t wp_erase_skip : 1; // [15]
  651. uint32_t csd_overwrite : 1; // [16]
  652. uint32_t obsolete : 2; // [17:18]
  653. uint32_t error : 1; // [19]
  654. uint32_t cc_error : 1; // [20]
  655. uint32_t device_ecc_failed : 1; // [21]
  656. uint32_t illegal_command : 1; // [22]
  657. uint32_t com_crc_error : 1; // [23]
  658. uint32_t lock_unlock_failed : 1; // [24]
  659. uint32_t device_is_locked : 1; // [25]
  660. uint32_t wp_violation : 1; // [26]
  661. uint32_t erase_param : 1; // [27]
  662. uint32_t erase_seq_error : 1; // [28]
  663. uint32_t block_len_error : 1; // [29]
  664. uint32_t address_misalign : 1; // [30]
  665. uint32_t address_out_of_range : 1; // [31]
  666. } b;
  667. } sdmmcCardStatus_t;
  668. typedef struct __attribute__((packed, aligned(1)))
  669. {
  670. unsigned __0__0 : 1; // [0:0]
  671. unsigned crc : 7; // [7:1]
  672. unsigned mdt : 12; // [19:8]
  673. unsigned __23_20 : 4; // [23:20]
  674. unsigned psn : 32; // [55:24]
  675. unsigned prv : 8; // [63:56]
  676. uint64_t pnm : 40; // [103:64]
  677. unsigned oid : 16; // [119:104]
  678. unsigned mid : 8; // [127:120]
  679. } sdmmcCid_t;
  680. typedef struct __attribute__((packed, aligned(1)))
  681. {
  682. unsigned __0_0 : 1; // [0:0]
  683. unsigned crc : 7; // [7:1]
  684. unsigned __9_8 : 2; // [9:8]
  685. unsigned file_format : 2; // [11:10]
  686. unsigned tmp_write_protect : 1; // [12:12]
  687. unsigned perm_write_protect : 1; // [13:13]
  688. unsigned copy : 1; // [14:14]
  689. unsigned file_format_grp : 1; // [15:15]
  690. unsigned __20_16 : 5; // [20:16]
  691. unsigned write_bl_partial : 1; // [21:21]
  692. unsigned write_bl_len : 4; // [25:22]
  693. unsigned r2w_factor : 3; // [28:26]
  694. unsigned __30_29 : 2; // [30:29]
  695. unsigned wr_grp_enable : 1; // [31:31]
  696. unsigned wr_grp_size : 7; // [38:32]
  697. unsigned sector_size : 7; // [45:39]
  698. unsigned erase_blk_en : 1; // [46:46]
  699. unsigned c_size_mult : 3; // [49:47]
  700. unsigned vdd_w_curr_max : 3; // [52:50]
  701. unsigned vdd_w_curr_min : 3; // [55:53]
  702. unsigned vdd_r_curr_max : 3; // [58:56]
  703. unsigned vdd_r_curr_min : 3; // [61:59]
  704. unsigned c_size : 12; // [73:62]
  705. unsigned __75_74 : 2; // [75:74]
  706. unsigned dsr_imp : 1; // [76:76]
  707. unsigned read_blk_misalign : 1; // [77:77]
  708. unsigned write_blk_misalign : 1; // [78:78]
  709. unsigned read_bl_partial : 1; // [79:79]
  710. unsigned read_bl_len : 4; // [83:80]
  711. unsigned ccc : 12; // [95:84]
  712. unsigned trans_speed : 8; // [103:96]
  713. unsigned nsac : 8; // [111:104]
  714. unsigned taac : 8; // [119:112]
  715. unsigned __125_120 : 6; // [125:120]
  716. unsigned csd_struct : 2; // [127:126]
  717. } sdmmcCsdV1_t;
  718. typedef struct __attribute__((packed, aligned(1)))
  719. {
  720. unsigned __0_0 : 1; // [0:0]
  721. unsigned crc : 7; // [7:1]
  722. unsigned __9_8 : 2; // [9:8]
  723. unsigned file_format : 2; // [11:10]
  724. unsigned tmp_write_protect : 1; // [12:12]
  725. unsigned perm_write_protect : 1; // [13:13]
  726. unsigned copy : 1; // [14:14]
  727. unsigned file_format_grp : 1; // [15:15]
  728. unsigned __20_16 : 5; // [20:16]
  729. unsigned write_bl_partial : 1; // [21:21]
  730. unsigned write_bl_len : 4; // [25:22]
  731. unsigned r2w_factor : 3; // [28:26]
  732. unsigned __30_29 : 2; // [30:29]
  733. unsigned wr_grp_enable : 1; // [31:31]
  734. unsigned wr_grp_size : 7; // [38:32]
  735. unsigned sector_size : 7; // [45:39]
  736. unsigned erase_blk_en : 1; // [46:46]
  737. unsigned __47_47 : 1; // [47:47]
  738. unsigned c_size : 22; // [69:48]
  739. unsigned __75_70 : 6; // [75:70]
  740. unsigned dsr_imp : 1; // [76:76]
  741. unsigned read_blk_misalign : 1; // [77:77]
  742. unsigned write_blk_misalign : 1; // [78:78]
  743. unsigned read_bl_partial : 1; // [79:79]
  744. unsigned read_bl_len : 4; // [83:80]
  745. unsigned ccc : 12; // [95:84]
  746. unsigned trans_speed : 8; // [103:96]
  747. unsigned nsac : 8; // [111:104]
  748. unsigned taac : 8; // [119:112]
  749. unsigned __125_120 : 6; // [125:120]
  750. unsigned csd_struct : 2; // [127:126]
  751. } sdmmcCsdV2_t;
  752. typedef struct __attribute__((packed, aligned(1)))
  753. {
  754. unsigned __0_0 : 1; // [0:0]
  755. unsigned crc : 7; // [7:1]
  756. unsigned __9_8 : 2; // [9:8]
  757. unsigned file_format : 2; // [11:10]
  758. unsigned tmp_write_protect : 1; // [12:12]
  759. unsigned perm_write_protect : 1; // [13:13]
  760. unsigned copy : 1; // [14:14]
  761. unsigned file_format_grp : 1; // [15:15]
  762. unsigned __20_16 : 5; // [20:16]
  763. unsigned write_bl_partial : 1; // [21:21]
  764. unsigned write_bl_len : 4; // [25:22]
  765. unsigned r2w_factor : 3; // [28:26]
  766. unsigned __30_29 : 2; // [30:29]
  767. unsigned wr_grp_enable : 1; // [31:31]
  768. unsigned wr_grp_size : 7; // [38:32]
  769. unsigned sector_size : 7; // [45:39]
  770. unsigned erase_blk_en : 1; // [46:46]
  771. unsigned __47_47 : 1; // [47:47]
  772. unsigned c_size : 28; // [75:48]
  773. unsigned dsr_imp : 1; // [76:76]
  774. unsigned read_blk_misalign : 1; // [77:77]
  775. unsigned write_blk_misalign : 1; // [78:78]
  776. unsigned read_bl_partial : 1; // [79:79]
  777. unsigned read_bl_len : 4; // [83:80]
  778. unsigned ccc : 12; // [95:84]
  779. unsigned trans_speed : 8; // [103:96]
  780. unsigned nsac : 8; // [111:104]
  781. unsigned taac : 8; // [119:112]
  782. unsigned __125_120 : 6; // [125:120]
  783. unsigned csd_struct : 2; // [127:126]
  784. } sdmmcCsdV3_t;
  785. //符合EMMC 4.4和EMMC 5.1规范的CSD寄存器定义
  786. typedef struct __attribute__((packed, aligned(1)))
  787. {
  788. unsigned __0_0 : 1; // [0:0]
  789. unsigned crc : 7; // [7:1]
  790. unsigned ecc : 2; // [9:8]
  791. unsigned file_format : 2; // [11:10]
  792. unsigned tmp_write_protect : 1; // [12:12]
  793. unsigned perm_write_protect : 1; // [13:13]
  794. unsigned copy : 1; // [14:14]
  795. unsigned file_format_grp : 1; // [15:15]
  796. unsigned content_prot_app : 1; // [16:16]
  797. unsigned __20_17 : 4; // [20:17]
  798. unsigned write_bl_partial : 1; // [21:21]
  799. unsigned write_bl_len : 4; // [25:22]
  800. unsigned r2w_factor : 3; // [28:26]
  801. unsigned default_ecc : 2; // [30:29]
  802. unsigned wp_grp_enable : 1; // [31:31]
  803. unsigned wp_grp_size : 5; // [36:32]
  804. unsigned erase_grp_mult : 5; // [41:37]
  805. unsigned erase_grp_size : 5; // [46:42]
  806. unsigned c_size_mult : 3; // [49:47]
  807. unsigned vdd_w_curr_max : 3; // [52:50]
  808. unsigned vdd_w_curr_min : 3; // [55:53]
  809. unsigned vdd_r_curr_max : 3; // [58:56]
  810. unsigned vdd_r_curr_min : 3; // [61:59]
  811. unsigned c_size : 12; // [73:62]
  812. unsigned __75_74 : 2; // [75:74]
  813. unsigned dsr_imp : 1; // [76:76]
  814. unsigned read_blk_misalign : 1; // [77:77]
  815. unsigned write_blk_misalign : 1; // [78:78]
  816. unsigned read_bl_partial : 1; // [79:79]
  817. unsigned read_bl_len : 4; // [83:80]
  818. unsigned ccc : 12; // [95:84]
  819. unsigned trans_speed : 8; // [103:96]
  820. unsigned nsac : 8; // [111:104]
  821. unsigned taac : 8; // [119:112]
  822. unsigned __121_120 : 2; // [121:120]
  823. unsigned spec_vers : 4; // [125:122]
  824. unsigned csd_struct : 2; // [127:126]
  825. } sdmmcCsdV4_t;
  826. typedef union {
  827. sdmmcCsdV1_t v1;
  828. sdmmcCsdV2_t v2;
  829. sdmmcCsdV3_t v3;
  830. sdmmcCsdV4_t v4;
  831. } sdmmcCsd_t;
  832. // #define CSD_FIELD(csd, f) (csd->v1.csd_struct == 0 ? csd->v1.f : csd->v1.csd_struct == 1 ? csd->v2.f : csd->v3.f)
  833. #define CSD_FIELD(csd, f) (csd->v4.f)
  834. static_assert(sizeof(sdmmcCsdV1_t) == 16, "sdmmcCsdV1_t is wrong");
  835. static_assert(sizeof(sdmmcCsdV2_t) == 16, "sdmmcCsdV2_t is wrong");
  836. static_assert(sizeof(sdmmcCsdV3_t) == 16, "sdmmcCsdV3_t is wrong");
  837. static_assert(sizeof(sdmmcCsdV4_t) == 16, "sdmmcCsdV4_t is wrong");
  838. static_assert(sizeof(sdmmcCsd_t) == 16, "sdmmcCsd_t is wrong");
  839. static_assert(sizeof(sdmmcCid_t) == 16, "sdmmcCid_t is wrong");
  840. static inline unsigned prvCsdStruct(sdmmcCsd_t *csd) { return csd->v4.csd_struct; }
  841. static inline unsigned prvCsdSpecVers(sdmmcCsd_t *csd) { return CSD_FIELD(csd, spec_vers); }
  842. static inline unsigned prvCsdTaac(sdmmcCsd_t *csd) { return CSD_FIELD(csd, taac); }
  843. static inline unsigned prvCsdNsac(sdmmcCsd_t *csd) { return CSD_FIELD(csd, nsac); }
  844. static inline unsigned prvCsdTransSpeed(sdmmcCsd_t *csd) { return CSD_FIELD(csd, trans_speed); }
  845. static inline unsigned prvCsdCcc(sdmmcCsd_t *csd) { return CSD_FIELD(csd, ccc); }
  846. static inline unsigned prvCsdReadBlLen(sdmmcCsd_t *csd) { return CSD_FIELD(csd, read_bl_len); }
  847. static inline unsigned prvCsdReadBlPartial(sdmmcCsd_t *csd) { return CSD_FIELD(csd, read_bl_partial); }
  848. static inline unsigned prvCsdWriteBlkMisalign(sdmmcCsd_t *csd) { return CSD_FIELD(csd, write_blk_misalign); }
  849. static inline unsigned prvCsdReadBlkMisalign(sdmmcCsd_t *csd) { return CSD_FIELD(csd, read_blk_misalign); }
  850. static inline unsigned prvCsdDsrImp(sdmmcCsd_t *csd) { return CSD_FIELD(csd, dsr_imp); }
  851. static inline unsigned prvCsdCSize(sdmmcCsd_t *csd) { return CSD_FIELD(csd, c_size); }
  852. static inline unsigned prvCsdVddRCurrMin(sdmmcCsd_t *csd) { return csd->v4.vdd_r_curr_min; }
  853. static inline unsigned prvCsdVddRCurrMax(sdmmcCsd_t *csd) { return csd->v4.vdd_r_curr_max; }
  854. static inline unsigned prvCsdVddWCurrMin(sdmmcCsd_t *csd) { return csd->v4.vdd_w_curr_min; }
  855. static inline unsigned prvCsdVddWCurrMax(sdmmcCsd_t *csd) { return csd->v4.vdd_w_curr_max; }
  856. static inline unsigned prvCsdCSizeMult(sdmmcCsd_t *csd) { return csd->v4.c_size_mult; }
  857. static inline unsigned prvCsdEraseGrpSize(sdmmcCsd_t *csd) { return CSD_FIELD(csd, erase_grp_size); }
  858. static inline unsigned prvCsdEraseGrpMult(sdmmcCsd_t *csd) { return CSD_FIELD(csd, erase_grp_mult); }
  859. static inline unsigned prvCsdWpGrpSize(sdmmcCsd_t *csd) { return CSD_FIELD(csd, wp_grp_size); }
  860. static inline unsigned prvCsdWpGrpEnable(sdmmcCsd_t *csd) { return CSD_FIELD(csd, wp_grp_enable); }
  861. static inline unsigned prvCsdDefaultEcc(sdmmcCsd_t *csd) { return CSD_FIELD(csd, default_ecc); }
  862. static inline unsigned prvCsdR2wFactor(sdmmcCsd_t *csd) { return CSD_FIELD(csd, r2w_factor); }
  863. static inline unsigned prvCsdWriteBlLen(sdmmcCsd_t *csd) { return CSD_FIELD(csd, write_bl_len); }
  864. static inline unsigned prvCsdWriteBlPartial(sdmmcCsd_t *csd) { return CSD_FIELD(csd, write_bl_partial); }
  865. static inline unsigned prvCsdContentProtApp(sdmmcCsd_t *csd) { return CSD_FIELD(csd, content_prot_app); }
  866. static inline unsigned prvCsdFileFormatGrp(sdmmcCsd_t *csd) { return CSD_FIELD(csd, file_format_grp); }
  867. static inline unsigned prvCsdCopy(sdmmcCsd_t *csd) { return CSD_FIELD(csd, copy); }
  868. static inline unsigned prvCsdPermWriteProtect(sdmmcCsd_t *csd) { return CSD_FIELD(csd, perm_write_protect); }
  869. static inline unsigned prvCsdTmpWriteProtect(sdmmcCsd_t *csd) { return CSD_FIELD(csd, tmp_write_protect); }
  870. static inline unsigned prvCsdFileFormat(sdmmcCsd_t *csd) { return CSD_FIELD(csd, file_format); }
  871. static inline unsigned prvCsdEcc(sdmmcCsd_t *csd) { return CSD_FIELD(csd, ecc); }
  872. static inline unsigned prvCsdCrc(sdmmcCsd_t *csd) { return CSD_FIELD(csd, crc); }
  873. /**
  874. * SDMMC_ACMD_SEL
  875. * mark a command as application specific
  876. */
  877. #define SDMMC_ACMD_SEL 0x80000000
  878. /**
  879. * SDMMC_CMD_MASK
  880. *
  881. * Mask to get from a sdmmcCmd_t value the corresponding
  882. * command index
  883. */
  884. #define SDMMC_CMD_MASK 0x3F
  885. /**
  886. * sdmmcCmd_t
  887. * SD commands index
  888. */
  889. typedef enum
  890. {
  891. SDMMC_CMD_GO_IDLE_STATE = 0,
  892. SDMMC_CMD_MMC_SEND_OP_COND = 1,
  893. SDMMC_CMD_ALL_SEND_CID = 2,
  894. SDMMC_CMD_SEND_RELATIVE_ADDR = 3,
  895. SDMMC_CMD_SET_DSR = 4,
  896. SDMMC_CMD_SWITCH = 6,
  897. SDMMC_CMD_SELECT_CARD = 7,
  898. // SDMMC_CMD_SEND_IF_COND = 8,
  899. SEND_EXT_CSD = 8,
  900. SDMMC_CMD_SEND_CSD = 9,
  901. SDMMC_CMD_STOP_TRANSMISSION = 12,
  902. SDMMC_CMD_SEND_STATUS = 13,
  903. SDMMC_CMD_SET_BLOCKLEN = 16,
  904. SDMMC_CMD_READ_SINGLE_BLOCK = 17,
  905. SDMMC_CMD_READ_MULT_BLOCK = 18,
  906. SDMMC_CMD_WRITE_SINGLE_BLOCK = 24,
  907. SDMMC_CMD_WRITE_MULT_BLOCK = 25,
  908. SDMMC_CMD_APP_CMD = 55,
  909. SDMMC_CMD_SET_BUS_WIDTH = (6 | SDMMC_ACMD_SEL),
  910. SDMMC_CMD_SEND_NUM_WR_BLOCKS = (22 | SDMMC_ACMD_SEL),
  911. SDMMC_CMD_SET_WR_BLK_COUNT = 23, //(23 | SDMMC_ACMD_SEL),
  912. SDMMC_CMD_SEND_OP_COND = (41 | SDMMC_ACMD_SEL)
  913. } sdmmcCmd_t;
  914. /**
  915. * sdmmcCheckStatus_t
  916. *
  917. * check register hwp->sdmmc_status different bit
  918. */
  919. typedef enum
  920. {
  921. SDMMC_CHECK_TRANSFER_DONE,
  922. SDMMC_CHECK_RESPONSE_OK,
  923. SDMMC_CHECK_CRC_OK,
  924. SDMMC_CHECK_DATA_OK,
  925. } sdmmcCheckStatus_t;
  926. /**
  927. * sdmmcDataBusWidth_t
  928. *
  929. * Cf spec v2 pdf p. 76 for ACMD6 argument
  930. * That type is used to describe how many data lines are used to transfer data
  931. * to and from the SD card.
  932. */
  933. typedef enum
  934. {
  935. SDMMC_DATA_BUS_WIDTH_1 = 0x0,
  936. SDMMC_DATA_BUS_WIDTH_4 = 0x2,
  937. SDMMC_DATA_BUS_WIDTH_8 = 0x4
  938. } sdmmcDataBusWidth_t;
  939. typedef enum
  940. {
  941. SDMMC_RESP_NONE = 0,
  942. SDMMC_RESP_FETCH = 1,
  943. SDMMC_RESP_CHECK = 2,
  944. } sdmmcRespOption_t;
  945. /**
  946. * Maximum block count per transfter are affected by 2 registers:
  947. * 1. sdmmc_block_cnt_reg: 16bits
  948. * 2. ifc.tc: 23bits, 14bits when block size is 512
  949. */
  950. #define SDMMC_MAX_BLOCK_PER_XFER (0x3fff)
  951. struct drvSdmmc
  952. {
  953. uint32_t name;
  954. HWP_SDMMC_T *hwp;
  955. drvIfcChannel_t rx_ifc;
  956. drvIfcChannel_t tx_ifc;
  957. uint32_t irqn;
  958. drvSdmmcResp_t resp;
  959. sdmmcCsd_t csd;
  960. sdmmcCid_t cid;
  961. sdmmcOcr_t ocr;
  962. uint32_t rca;
  963. uint32_t dsr;
  964. uint8_t clk_adj;
  965. uint8_t clk_inv;
  966. bool card_is_sdhc;
  967. sdmmcDataBusWidth_t bus_width;
  968. uint32_t max_clk;
  969. uint32_t master_clk;
  970. uint32_t card_type;
  971. bool opened;
  972. bool rx_enabled;
  973. bool tx_enabled;
  974. uint32_t block_count;
  975. uint32_t block_size;
  976. osiClockConstrainRegistry_t clk_constrain;
  977. osiPmSource_t *pm_source;
  978. osiSemaphore_t *tx_done_sema;
  979. osiSemaphore_t *rx_done_sema;
  980. osiMutex_t *lock;
  981. struct
  982. {
  983. unsigned sdmmc_trans_speed;
  984. } pm_ctx;
  985. };
  986. #endif
  987. OSI_EXTERN_C_END
  988. #endif