drv_emmc.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. #include "xil_exception.h"
  2. #include "xsdps.h"
  3. #include <stdio.h>
  4. #include "xparameters.h"
  5. #include "rtthread.h"
  6. #include <rtdevice.h>
  7. #define DBG_TAG "drv.mmc"
  8. #define DBG_LVL DBG_INFO
  9. #include <rtdbg.h>
  10. #define EMMC_BLOCK_SIZE (512)
  11. extern u16 TransferMode;
  12. extern s32 XSdPs_CmdTransfer(XSdPs *InstancePtr, u32 Cmd, u32 Arg, u32 BlkCnt);
  13. extern void XSdPs_SetupADMA2DescTbl(XSdPs *InstancePtr, u32 BlkCnt, const u8 *Buff);
  14. // replace XSdPs_ReadPolled, using `rt_thread_mdelay`
  15. s32 XSdPs_ReadPolled_rtt(XSdPs *InstancePtr, u32 Arg, u32 BlkCnt, u8 *Buff)
  16. {
  17. s32 Status;
  18. u32 PresentStateReg;
  19. u32 StatusReg;
  20. if ((InstancePtr->HC_Version != XSDPS_HC_SPEC_V3) ||
  21. ((InstancePtr->Host_Caps & XSDPS_CAPS_SLOT_TYPE_MASK)
  22. != XSDPS_CAPS_EMB_SLOT)) {
  23. if(InstancePtr->Config.CardDetect != 0U) {
  24. /* Check status to ensure card is initialized */
  25. PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
  26. XSDPS_PRES_STATE_OFFSET);
  27. if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0x0U) {
  28. Status = XST_FAILURE;
  29. goto RETURN_PATH;
  30. }
  31. }
  32. }
  33. /* Set block size to 512 if not already set */
  34. if( XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
  35. XSDPS_BLK_SIZE_OFFSET) != XSDPS_BLK_SIZE_512_MASK ) {
  36. Status = XSdPs_SetBlkSize(InstancePtr,
  37. XSDPS_BLK_SIZE_512_MASK);
  38. if (Status != XST_SUCCESS) {
  39. Status = XST_FAILURE;
  40. goto RETURN_PATH;
  41. }
  42. }
  43. XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, Buff);
  44. TransferMode = XSDPS_TM_AUTO_CMD12_EN_MASK |
  45. XSDPS_TM_BLK_CNT_EN_MASK | XSDPS_TM_DAT_DIR_SEL_MASK |
  46. XSDPS_TM_DMA_EN_MASK | XSDPS_TM_MUL_SIN_BLK_SEL_MASK;
  47. if (InstancePtr->Config.IsCacheCoherent == 0) {
  48. Xil_DCacheInvalidateRange((INTPTR)Buff,
  49. BlkCnt * XSDPS_BLK_SIZE_512_MASK);
  50. }
  51. /* Send block read command */
  52. Status = XSdPs_CmdTransfer(InstancePtr, CMD18, Arg, BlkCnt);
  53. if (Status != XST_SUCCESS) {
  54. Status = XST_FAILURE;
  55. goto RETURN_PATH;
  56. }
  57. /* Check for transfer complete */
  58. do {
  59. StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
  60. XSDPS_NORM_INTR_STS_OFFSET);
  61. if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
  62. /* Write to clear error bits */
  63. XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
  64. XSDPS_ERR_INTR_STS_OFFSET,
  65. XSDPS_ERROR_INTR_ALL_MASK);
  66. Status = XST_FAILURE;
  67. goto RETURN_PATH;
  68. }
  69. // delay 1ms
  70. if ((StatusReg & XSDPS_INTR_TC_MASK) == 0U)
  71. rt_thread_mdelay(1);
  72. } while((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
  73. /* Write to clear bit */
  74. XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
  75. XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
  76. Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
  77. XSDPS_RESP0_OFFSET);
  78. Status = XST_SUCCESS;
  79. RETURN_PATH:
  80. return Status;
  81. }
  82. // replace XSdPs_WritePolled, using rt_thread_mdelay
  83. s32 XSdPs_WritePolled_rtt(XSdPs *InstancePtr, u32 Arg, u32 BlkCnt, const u8 *Buff)
  84. {
  85. s32 Status;
  86. u32 PresentStateReg;
  87. u32 StatusReg;
  88. if ((InstancePtr->HC_Version != XSDPS_HC_SPEC_V3) ||
  89. ((InstancePtr->Host_Caps & XSDPS_CAPS_SLOT_TYPE_MASK)
  90. != XSDPS_CAPS_EMB_SLOT)) {
  91. if(InstancePtr->Config.CardDetect != 0U) {
  92. /* Check status to ensure card is initialized */
  93. PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
  94. XSDPS_PRES_STATE_OFFSET);
  95. if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0x0U) {
  96. Status = XST_FAILURE;
  97. goto RETURN_PATH;
  98. }
  99. }
  100. }
  101. /* Set block size to 512 if not already set */
  102. if( XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
  103. XSDPS_BLK_SIZE_OFFSET) != XSDPS_BLK_SIZE_512_MASK ) {
  104. Status = XSdPs_SetBlkSize(InstancePtr,
  105. XSDPS_BLK_SIZE_512_MASK);
  106. if (Status != XST_SUCCESS) {
  107. Status = XST_FAILURE;
  108. goto RETURN_PATH;
  109. }
  110. }
  111. XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, Buff);
  112. if (InstancePtr->Config.IsCacheCoherent == 0) {
  113. Xil_DCacheFlushRange((INTPTR)Buff,
  114. BlkCnt * XSDPS_BLK_SIZE_512_MASK);
  115. }
  116. TransferMode = XSDPS_TM_AUTO_CMD12_EN_MASK |
  117. XSDPS_TM_BLK_CNT_EN_MASK |
  118. XSDPS_TM_MUL_SIN_BLK_SEL_MASK | XSDPS_TM_DMA_EN_MASK;
  119. /* Send block write command */
  120. Status = XSdPs_CmdTransfer(InstancePtr, CMD25, Arg, BlkCnt);
  121. if (Status != XST_SUCCESS) {
  122. Status = XST_FAILURE;
  123. goto RETURN_PATH;
  124. }
  125. /*
  126. * Check for transfer complete
  127. * Polling for response for now
  128. */
  129. do {
  130. StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
  131. XSDPS_NORM_INTR_STS_OFFSET);
  132. if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
  133. /* Write to clear error bits */
  134. XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
  135. XSDPS_ERR_INTR_STS_OFFSET,
  136. XSDPS_ERROR_INTR_ALL_MASK);
  137. Status = XST_FAILURE;
  138. goto RETURN_PATH;
  139. }
  140. if ((StatusReg & XSDPS_INTR_TC_MASK) == 0U)
  141. rt_thread_mdelay(1);
  142. } while((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
  143. /* Write to clear bit */
  144. XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
  145. XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
  146. Status = XST_SUCCESS;
  147. RETURN_PATH:
  148. return Status;
  149. }
  150. struct rt_hw_emmc_device {
  151. struct rt_device dev;
  152. XSdPs emmc;
  153. XSdPs_Config *cfg;
  154. struct rt_mutex lock;
  155. u16 dev_id;
  156. };
  157. #ifdef BSP_USING_SDIO0
  158. static struct rt_hw_emmc_device emmc0 = {
  159. .dev_id = XPAR_PS7_SD_0_DEVICE_ID,
  160. };
  161. #endif
  162. #ifdef BSP_USING_SDIO1
  163. static struct rt_hw_emmc_device emmc1 = {
  164. .dev_id = XPAR_PS7_SD_1_DEVICE_ID,
  165. };
  166. #endif
  167. #define __INIT_CHECK_CFG(cfg) \
  168. if (Status != XST_SUCCESS) \
  169. { \
  170. rt_kprintf("EMMC Config '%s' failed: err: %d\n", cfg, Status); \
  171. return -RT_EIO; \
  172. }
  173. static rt_err_t rt_sdcard_init(rt_device_t dev)
  174. {
  175. RT_ASSERT(dev);
  176. struct rt_hw_emmc_device *pdev = rt_container_of(dev, struct rt_hw_emmc_device, dev);
  177. RT_ASSERT(pdev != RT_NULL);
  178. rt_mutex_take(&pdev->lock, RT_WAITING_FOREVER);
  179. if (pdev->cfg != RT_NULL)
  180. {
  181. LOG_I("init '%s' success", pdev->dev.parent.name);
  182. rt_mutex_release(&pdev->lock);
  183. return RT_EOK;
  184. }
  185. pdev->cfg = XSdPs_LookupConfig(pdev->dev_id);
  186. RT_ASSERT(pdev->cfg != RT_NULL);
  187. s32 Status = XSdPs_CfgInitialize(&pdev->emmc, pdev->cfg, pdev->cfg->BaseAddress);
  188. __INIT_CHECK_CFG("cfg");
  189. Status = XSdPs_CardInitialize(&pdev->emmc);
  190. __INIT_CHECK_CFG("init");
  191. LOG_I("init '%s' success", pdev->dev.parent.name);
  192. rt_mutex_release(&pdev->lock);
  193. return RT_EOK;
  194. }
  195. rt_inline rt_uint32_t _emmc_start_addr(struct rt_hw_emmc_device *pdev)
  196. {
  197. return 0;
  198. }
  199. rt_inline rt_uint32_t _emmc_size(struct rt_hw_emmc_device *pdev)
  200. {
  201. return pdev->emmc.SectorCount;
  202. }
  203. rt_inline rt_uint32_t _emmc_end_addr(struct rt_hw_emmc_device *pdev)
  204. {
  205. return pdev->emmc.SectorCount;
  206. }
  207. static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
  208. {
  209. return RT_EOK;
  210. }
  211. static rt_err_t rt_sdcard_close(rt_device_t dev)
  212. {
  213. return RT_EOK;
  214. }
  215. static rt_ssize_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  216. {
  217. s32 status;
  218. RT_ASSERT(dev);
  219. struct rt_hw_emmc_device *pdev = rt_container_of(dev, struct rt_hw_emmc_device, dev);
  220. RT_ASSERT(pdev != RT_NULL);
  221. pos += _emmc_start_addr(pdev);
  222. if (size + pos >= _emmc_end_addr(pdev))
  223. {
  224. LOG_E("addr out of ranger: %d %d", pos, size);
  225. return 0;
  226. }
  227. rt_mutex_take(&pdev->lock, RT_WAITING_FOREVER);
  228. status = XSdPs_ReadPolled_rtt(&pdev->emmc, pos, size, buffer);
  229. rt_mutex_release(&pdev->lock);
  230. if (status == XST_SUCCESS)
  231. return size;
  232. rt_kprintf("sdcard read failed: %d\n", status);
  233. return 0;
  234. }
  235. static rt_uint8_t sdio_write_buf[2][EMMC_BLOCK_SIZE] __attribute__((aligned(32)));
  236. static rt_ssize_t rt_sdcard_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  237. {
  238. s32 status;
  239. rt_ssize_t rt = 0;
  240. RT_ASSERT(dev);
  241. struct rt_hw_emmc_device *pdev = rt_container_of(dev, struct rt_hw_emmc_device, dev);
  242. RT_ASSERT(pdev != RT_NULL);
  243. pos += _emmc_start_addr(pdev);
  244. if (size + pos >= _emmc_end_addr(pdev))
  245. {
  246. LOG_E("addr out of ranger: %d %d", pos, size);
  247. return 0;
  248. }
  249. rt_mutex_take(&pdev->lock, RT_WAITING_FOREVER);
  250. for (int i = 0; i < size; i++)
  251. {
  252. rt_memcpy(sdio_write_buf[pdev->dev_id], ((rt_uint8_t *)buffer) + EMMC_BLOCK_SIZE * i, EMMC_BLOCK_SIZE);
  253. status = XSdPs_WritePolled_rtt(&pdev->emmc, pos + i, 1, sdio_write_buf[pdev->dev_id]);
  254. if (status != XST_SUCCESS)
  255. {
  256. rt_kprintf("sdcard write failed: %d\n", status);
  257. break;
  258. }
  259. rt++;
  260. }
  261. rt_mutex_release(&pdev->lock);
  262. return rt;
  263. }
  264. static rt_err_t rt_sdcard_control(rt_device_t dev, int cmd, void *args)
  265. {
  266. RT_ASSERT(dev);
  267. struct rt_hw_emmc_device *pdev = rt_container_of(dev, struct rt_hw_emmc_device, dev);
  268. RT_ASSERT(pdev != RT_NULL);
  269. if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
  270. {
  271. struct rt_device_blk_geometry *geometry;
  272. geometry = (struct rt_device_blk_geometry *)args;
  273. if (geometry == RT_NULL)
  274. return -RT_ERROR;
  275. geometry->bytes_per_sector = EMMC_BLOCK_SIZE;
  276. geometry->block_size = EMMC_BLOCK_SIZE;
  277. geometry->sector_count = _emmc_size(pdev);
  278. }
  279. return RT_EOK;
  280. }
  281. static void _init_emmc_dev(struct rt_hw_emmc_device *pdev, const char *name)
  282. {
  283. rt_mutex_init(&pdev->lock, name, RT_IPC_FLAG_PRIO);
  284. pdev->dev.type = RT_Device_Class_Block;
  285. pdev->dev.init = rt_sdcard_init;
  286. pdev->dev.open = rt_sdcard_open;
  287. pdev->dev.close = rt_sdcard_close;
  288. pdev->dev.read = rt_sdcard_read;
  289. pdev->dev.write = rt_sdcard_write;
  290. pdev->dev.control = rt_sdcard_control;
  291. pdev->dev.user_data = RT_NULL;
  292. rt_device_register(&pdev->dev, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
  293. }
  294. int rt_hw_emmc_init(void)
  295. {
  296. #ifdef BSP_USING_SDIO0
  297. _init_emmc_dev(&emmc0, "sd0");
  298. #endif
  299. #ifdef BSP_USING_SDIO1
  300. _init_emmc_dev(&emmc1, "sd1");
  301. #endif
  302. return RT_EOK;
  303. }
  304. INIT_BOARD_EXPORT(rt_hw_emmc_init);