drv_sdif_msg.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Email: opensource_embedded@phytium.com.cn
  7. *
  8. * Change Logs:
  9. * Date Author Notes
  10. * 2023/7/11 liqiaozhong init SD card and mount file system
  11. * 2023/11/8 zhugengyu add interrupt handling for dma waiting, unify function naming
  12. * 2024/4/7 zhugengyu support use two sdif device
  13. */
  14. /***************************** Include Files *********************************/
  15. #include "rtconfig.h"
  16. #if defined(BSP_USING_SDIF_LAYER)
  17. #include <rthw.h>
  18. #include <rtdef.h>
  19. #include <rtthread.h>
  20. #include <rtdevice.h>
  21. #include <rtdbg.h>
  22. #include <drivers/dev_mmcsd_core.h>
  23. #ifdef RT_USING_SMART
  24. #include "ioremap.h"
  25. #endif
  26. #include "mm_aspace.h"
  27. #include "interrupt.h"
  28. #define LOG_TAG "sdif_msg_drv"
  29. #include "drv_log.h"
  30. #include "ftypes.h"
  31. #include "fparameters.h"
  32. #include "fcpu_info.h"
  33. #include "fsdif_timing.h"
  34. #include "fsdif_msg.h"
  35. #include "fsdif_msg_hw.h"
  36. #include "drv_sdif_msg.h"
  37. /************************** Constant Definitions *****************************/
  38. #define SDIF_CARD_TYPE_MICRO_SD 1
  39. #define SDIF_CARD_TYPE_EMMC 2
  40. #define SDIF_CARD_TYPE_SDIO 3
  41. #define SDIF_DMA_BLK_SZ 512U
  42. #define SDIF_MAX_BLK_TRANS 1024U
  43. #define SDIF_DMA_ALIGN SDIF_DMA_BLK_SZ
  44. /* preserve pointer to host instance */
  45. static struct rt_mmcsd_host *mmc_host[FSDIF_NUM] = {RT_NULL};
  46. /**************************** Type Definitions *******************************/
  47. typedef struct
  48. {
  49. FSdifMsgCtrl sdif;
  50. rt_int32_t sd_type;
  51. FSdifMsgIDmaDesc *rw_desc;
  52. uintptr_t rw_desc_dma;
  53. rt_size_t rw_desc_num;
  54. struct rt_event event;
  55. #define SDIF_EVENT_CARD_DETECTED (1 << 0)
  56. #define SDIF_EVENT_COMMAND_DONE (1 << 1)
  57. #define SDIF_EVENT_DATA_DONE (1 << 2)
  58. #define SDIF_EVENT_ERROR_OCCUR (1 << 3)
  59. #define SDIF_EVENT_SDIO_IRQ (1 << 4)
  60. void *aligned_buffer;
  61. uintptr_t aligned_buffer_dma;
  62. rt_size_t aligned_buffer_size;
  63. FSdifMsgCommand req_cmd;
  64. FSdifMsgData req_data;
  65. FSdifMsgRequest req;
  66. } sdif_info_t;
  67. /************************** Variable Definitions *****************************/
  68. /***************** Macros (Inline Functions) Definitions *********************/
  69. /******************************* Functions *********************************/
  70. void sdif_change(rt_uint32_t id)
  71. {
  72. RT_ASSERT(id < FSDIF_NUM);
  73. if (mmc_host[id])
  74. {
  75. mmcsd_change(mmc_host[id]);
  76. }
  77. }
  78. rt_int32_t sdif_card_inserted(rt_uint32_t id)
  79. {
  80. RT_ASSERT(id < FSDIF_NUM);
  81. if (mmc_host[id])
  82. {
  83. return mmc_host[id]->ops->get_card_status(mmc_host[id]);
  84. }
  85. return 0;
  86. }
  87. static void sdif_card_detect_callback(FSdifMsgCtrl *const instance_p, void *args, void *data)
  88. {
  89. struct rt_mmcsd_host *host = (struct rt_mmcsd_host *)args;
  90. sdif_info_t *host_info = (sdif_info_t *)host->private_data;
  91. rt_event_send(&host_info->event, SDIF_EVENT_CARD_DETECTED);
  92. sdif_change(host_info->sdif.config.instance_id);
  93. }
  94. static void sdif_command_done_callback(FSdifMsgCtrl *const instance_p, void *args, void *data)
  95. {
  96. struct rt_mmcsd_host *host = (struct rt_mmcsd_host *)args;
  97. sdif_info_t *host_info = (sdif_info_t *)host->private_data;
  98. rt_event_send(&host_info->event, SDIF_EVENT_COMMAND_DONE);
  99. }
  100. static void sdif_data_done_callback(FSdifMsgCtrl *const instance_p, void *args, void *data)
  101. {
  102. struct rt_mmcsd_host *host = (struct rt_mmcsd_host *)args;
  103. sdif_info_t *host_info = (sdif_info_t *)host->private_data;
  104. rt_event_send(&host_info->event, SDIF_EVENT_DATA_DONE);
  105. }
  106. static void sdif_error_occur_callback(FSdifMsgCtrl *const instance_p, void *args, void *data)
  107. {
  108. struct rt_mmcsd_host *host = (struct rt_mmcsd_host *)args;
  109. sdif_info_t *host_info = (sdif_info_t *)host->private_data;
  110. FSdifMsgDataErrIrq *err_data = (FSdifMsgDataErrIrq *)data;
  111. if (err_data)
  112. {
  113. u32 status = err_data->raw_ints;
  114. u32 dmac_status = err_data->dmac_status;
  115. LOG_E("SDIF ERROR:");
  116. LOG_E("Status: 0x%x, dmac status: 0x%x.", status, dmac_status);
  117. if (status & FSDIF_INT_RE_BIT)
  118. LOG_E("[CMD_FAIL]Response err. 0x%x", FSDIF_INT_RE_BIT);
  119. if (status & FSDIF_INT_RTO_BIT)
  120. LOG_E("[CMD_FAIL]Response timeout. 0x%x", FSDIF_INT_RTO_BIT);
  121. if (dmac_status & FSDIF_DMAC_STATUS_DU)
  122. LOG_E("[DATA_FAIL]Descriptor un-readable. 0x%x", FSDIF_DMAC_STATUS_DU);
  123. if (status & FSDIF_INT_DCRC_BIT)
  124. LOG_E("[DATA_FAIL]Data CRC error. 0x%x", FSDIF_INT_DCRC_BIT);
  125. if (status & FSDIF_INT_RCRC_BIT)
  126. LOG_E("[DATA_FAIL]Data CRC error. 0x%x", FSDIF_INT_RCRC_BIT);
  127. rt_event_send(&host_info->event, SDIF_EVENT_ERROR_OCCUR);
  128. }
  129. }
  130. static rt_err_t sdif_pre_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
  131. {
  132. rt_err_t err = RT_EOK;
  133. sdif_info_t *host_info = (sdif_info_t *)host->private_data;
  134. if (host_info->sd_type != SDIF_CARD_TYPE_SDIO)
  135. {
  136. /* ignore SDIO detect command */
  137. if ((req->cmd->cmd_code == SD_IO_SEND_OP_COND) ||
  138. (req->cmd->cmd_code == SD_IO_RW_DIRECT))
  139. {
  140. req->cmd->err = -1;
  141. mmcsd_req_complete(host);
  142. err = RT_EEMPTY;
  143. }
  144. }
  145. if (host_info->sd_type == SDIF_CARD_TYPE_EMMC)
  146. {
  147. /* ignore micro SD detect command, not in eMMC spec. */
  148. if ((req->cmd->cmd_code == SD_APP_OP_COND) ||
  149. (req->cmd->cmd_code == APP_CMD))
  150. {
  151. req->cmd->err = -1;
  152. mmcsd_req_complete(host);
  153. err = RT_EEMPTY;
  154. }
  155. /* ignore mmcsd_send_if_cond(CMD-8) which will failed for eMMC
  156. but check cmd arg to let SEND_EXT_CSD (CMD-8) run */
  157. if ((req->cmd->cmd_code == SD_SEND_IF_COND) &&
  158. (req->cmd->arg == 0x1AA)) /* 0x1AA is the send_if_cond pattern, use it by care */
  159. {
  160. req->cmd->err = -1;
  161. mmcsd_req_complete(host);
  162. err = RT_EEMPTY;
  163. }
  164. }
  165. if ((req->cmd->cmd_code == READ_MULTIPLE_BLOCK) ||
  166. (req->cmd->cmd_code == WRITE_MULTIPLE_BLOCK)) /* set block count */
  167. {
  168. struct rt_mmcsd_req sbc;
  169. struct rt_mmcsd_cmd sbc_cmd;
  170. rt_memset(&sbc, 0, sizeof(sbc));
  171. rt_memset(&sbc_cmd, 0, sizeof(sbc_cmd));
  172. sbc_cmd.cmd_code = SET_BLOCK_COUNT;
  173. RT_ASSERT(req->data);
  174. sbc_cmd.arg = req->data->blks;
  175. sbc_cmd.flags = RESP_R1;
  176. LOG_I("set block_count = %d", req->data->blks);
  177. sbc.data = RT_NULL;
  178. sbc.cmd = &sbc_cmd;
  179. sbc.stop = RT_NULL;
  180. sbc.sbc = RT_NULL;
  181. mmcsd_send_request(host, &sbc);
  182. err = sbc_cmd.err;
  183. if (req->cmd->busy_timeout < 1000) /* in case rt-thread do not give wait timeout */
  184. {
  185. req->cmd->busy_timeout = 5000;
  186. }
  187. }
  188. return err;
  189. }
  190. static rt_err_t sdif_do_transfer(struct rt_mmcsd_host *host, FSdifMsgRequest *request, rt_int32_t timeout_ms)
  191. {
  192. FError ret = FT_SUCCESS;
  193. sdif_info_t *host_info = (sdif_info_t *)host->private_data;
  194. rt_uint32_t event = 0U;
  195. rt_uint32_t wait_event = 0U;
  196. if (request->data)
  197. {
  198. wait_event = SDIF_EVENT_COMMAND_DONE | SDIF_EVENT_DATA_DONE;
  199. }
  200. else
  201. {
  202. wait_event = SDIF_EVENT_COMMAND_DONE;
  203. }
  204. ret = FSdifMsgDMATransfer(&host_info->sdif, request);
  205. if (ret != FT_SUCCESS)
  206. {
  207. LOG_E("FSdifMsgDMATransfer() fail. ret = 0x%x", ret);
  208. return -RT_ERROR;
  209. }
  210. while (TRUE)
  211. {
  212. /*
  213. * transfer without data: wait COMMAND_DONE event
  214. * transfer with data: wait COMMAND_DONE and DATA_DONE event
  215. */
  216. if (rt_event_recv(&host_info->event,
  217. (wait_event),
  218. (RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR),
  219. rt_tick_from_millisecond(1000),
  220. &event) == RT_EOK)
  221. {
  222. break;
  223. }
  224. /*
  225. * transfer with error: check if ERROR_OCCUR event exists, no wait
  226. */
  227. if (rt_event_recv(&host_info->event,
  228. (SDIF_EVENT_ERROR_OCCUR),
  229. (RT_EVENT_FLAG_AND | RT_WAITING_NO),
  230. 0,
  231. &event) == RT_EOK)
  232. {
  233. LOG_E("SDIF dma-transfer endup with error !!!");
  234. return -RT_EIO;
  235. }
  236. timeout_ms -= 1000;
  237. if (timeout_ms <= 0)
  238. {
  239. LOG_E("Sdif DMA transfer endup with timeout !!!");
  240. return -RT_EIO;
  241. }
  242. }
  243. return RT_EOK;
  244. }
  245. static uint32_t sdif_prepare_raw_command(struct rt_mmcsd_req *req)
  246. {
  247. struct rt_mmcsd_cmd *input_cmd = req->cmd;
  248. struct rt_mmcsd_data *input_data = req->data;
  249. uint32_t opcode = input_cmd->cmd_code;
  250. uint32_t raw_cmd = FSDIF_CMD_INDX_SET(opcode);
  251. rt_uint32_t resp_type = resp_type(input_cmd);
  252. if (GO_IDLE_STATE == opcode)
  253. {
  254. raw_cmd |= FSDIF_CMD_INIT;
  255. }
  256. if (GO_INACTIVE_STATE == opcode)
  257. {
  258. raw_cmd |= FSDIF_CMD_STOP_ABORT;
  259. }
  260. if (RESP_NONE != resp_type)
  261. {
  262. raw_cmd |= FSDIF_CMD_RESP_EXP;
  263. if (RESP_R2 == resp_type)
  264. {
  265. /* need 136 bits long response */
  266. raw_cmd |= FSDIF_CMD_RESP_LONG;
  267. }
  268. if ((RESP_R3 != resp_type) && (RESP_R4 != resp_type))
  269. {
  270. /* most cmds need CRC */
  271. raw_cmd |= FSDIF_CMD_RESP_CRC;
  272. }
  273. }
  274. if (VOLTAGE_SWITCH == opcode)
  275. {
  276. /* CMD11 need switch voltage */
  277. raw_cmd |= FSDIF_CMD_VOLT_SWITCH;
  278. }
  279. if (input_data)
  280. {
  281. raw_cmd |= FSDIF_CMD_DAT_EXP;
  282. if (input_data->flags & DATA_DIR_WRITE)
  283. {
  284. raw_cmd |= FSDIF_CMD_DAT_WRITE;
  285. }
  286. }
  287. raw_cmd |= FSDIF_CMD_START;
  288. return raw_cmd;
  289. }
  290. void sdif_prepare_data_transfer(FSdifMsgDataStartData *msg_data, struct rt_mmcsd_req *req)
  291. {
  292. struct rt_mmcsd_cmd *input_cmd = req->cmd;
  293. struct rt_mmcsd_data *input_data = req->data;
  294. rt_memset(msg_data, 0U, sizeof(*msg_data));
  295. msg_data->cmd_arg = input_cmd->arg;
  296. msg_data->raw_cmd = sdif_prepare_raw_command(req);
  297. if ((input_cmd->cmd_code == WRITE_BLOCK) ||
  298. (input_cmd->cmd_code == WRITE_MULTIPLE_BLOCK))
  299. {
  300. msg_data->data_flags = FSDIF_MMC_DATA_WRITE;
  301. }
  302. else
  303. {
  304. msg_data->data_flags = FSDIF_MMC_DATA_READ;
  305. }
  306. msg_data->adtc_type = FSDIF_BLOCK_RW_ADTC;
  307. msg_data->adma_addr = 0U; /* we do not know the descriptor addr here */
  308. msg_data->mrq_data_blksz = input_data->blksize;
  309. msg_data->mrq_data_blocks = input_data->blks;
  310. return;
  311. }
  312. static uint32_t sdif_prepare_sd_command_flags(struct rt_mmcsd_req *req)
  313. {
  314. struct rt_mmcsd_cmd *input_cmd = req->cmd;
  315. uint32_t opcode = input_cmd->cmd_code;
  316. uint32_t argument = input_cmd->arg;
  317. uint32_t flags = 0U;
  318. switch(opcode)
  319. {
  320. case GO_IDLE_STATE: /* MMC_GO_IDLE_STATE 0 */
  321. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_NONE | FSDIF_MMC_CMD_BC;
  322. break;
  323. case SEND_EXT_CSD: /* SD_SEND_IF_COND 8 */
  324. flags |= FSDIF_MMC_RSP_SPI_R7 | FSDIF_MMC_RSP_R7 | FSDIF_MMC_CMD_BCR;
  325. break;
  326. case SD_APP_OP_COND: /* SD_APP_OP_COND 41 */
  327. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R3 | FSDIF_MMC_CMD_BCR;
  328. break;
  329. case VOLTAGE_SWITCH: /* SD_SWITCH_VOLTAGE 11 */
  330. flags |= FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_AC;
  331. break;
  332. case ALL_SEND_CID: /* MMC_ALL_SEND_CID 2 */
  333. flags |= FSDIF_MMC_RSP_R2 | FSDIF_MMC_CMD_AC;
  334. break;
  335. case SET_RELATIVE_ADDR: /* SD_SEND_RELATIVE_ADDR 3 */
  336. flags |= FSDIF_MMC_RSP_R6 | FSDIF_MMC_CMD_BCR;
  337. break;
  338. case SEND_CSD: /* MMC_SEND_CSD 9 */
  339. flags |= FSDIF_MMC_RSP_R2 | FSDIF_MMC_CMD_AC;
  340. break;
  341. case SELECT_CARD: /* MMC_SELECT_CARD 7 */
  342. if (argument)
  343. {
  344. flags |= FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_AC;
  345. }
  346. else
  347. {
  348. flags |= FSDIF_MMC_RSP_NONE | FSDIF_MMC_CMD_AC;
  349. }
  350. break;
  351. case APP_CMD: /* MMC_APP_CMD 55 */
  352. if (argument)
  353. {
  354. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_AC;
  355. }
  356. else
  357. {
  358. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_BCR;
  359. }
  360. break;
  361. case SD_APP_SEND_SCR: /* SD_APP_SEND_SCR 51 */
  362. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_ADTC;
  363. break;
  364. case SD_APP_SET_BUS_WIDTH: /* SD_APP_SET_BUS_WIDTH 6 */
  365. flags |= FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_AC;
  366. break;
  367. case SEND_STATUS: /* SD_APP_SD_STATUS 13 */
  368. flags |= FSDIF_MMC_RSP_SPI_R2 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_ADTC;
  369. break;
  370. case SET_BLOCKLEN : /* MMC_SET_BLOCKLEN 16 */
  371. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_AC;
  372. break;
  373. case SET_BLOCK_COUNT: /* MMC_SET_BLOCK_COUNT 23 */
  374. flags |= FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_AC;
  375. break;
  376. case WRITE_BLOCK: /* MMC_WRITE_BLOCK 24 */
  377. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_ADTC;
  378. break;
  379. case WRITE_MULTIPLE_BLOCK: /* MMC_WRITE_MULTIPLE_BLOCK 25 */
  380. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_ADTC;
  381. break;
  382. case READ_SINGLE_BLOCK: /* MMC_READ_SINGLE_BLOCK 17 */
  383. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_ADTC;
  384. break;
  385. case READ_MULTIPLE_BLOCK: /* MMC_READ_MULTIPLE_BLOCK 18 */
  386. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_ADTC;
  387. break;
  388. default:
  389. LOG_E("unhandled command-%d !!!", opcode);
  390. break;
  391. }
  392. return flags;
  393. }
  394. static uint32_t sdif_prepar_emmc_command_flags(struct rt_mmcsd_req *req)
  395. {
  396. struct rt_mmcsd_cmd *input_cmd = req->cmd;
  397. uint32_t opcode = input_cmd->cmd_code;
  398. uint32_t argument = input_cmd->arg;
  399. uint32_t flags = 0U;
  400. switch(opcode)
  401. {
  402. case GO_IDLE_STATE: /* MMC_GO_IDLE_STATE 0 */
  403. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_NONE | FSDIF_MMC_CMD_BC;
  404. break;
  405. case SEND_OP_COND: /* MMC_SEND_OP_COND 1 */
  406. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R3 | FSDIF_MMC_CMD_BCR;
  407. break;
  408. case ALL_SEND_CID: /* MMC_ALL_SEND_CID 2 */
  409. flags |= FSDIF_MMC_RSP_R2 | FSDIF_MMC_CMD_AC;
  410. break;
  411. case SET_RELATIVE_ADDR: /* MMC_SET_RELATIVE_ADDR 3 */
  412. flags |= FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_AC;
  413. break;
  414. case SEND_CSD: /* MMC_SEND_CSD 9 */
  415. flags |= FSDIF_MMC_RSP_R2 | FSDIF_MMC_CMD_AC;
  416. break;
  417. case SELECT_CARD: /* MMC_SELECT_CARD 7 */
  418. if (argument)
  419. {
  420. flags |= FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_AC;
  421. }
  422. else
  423. {
  424. flags |= FSDIF_MMC_RSP_NONE | FSDIF_MMC_CMD_AC;
  425. }
  426. break;
  427. case SEND_EXT_CSD: /* MMC_SEND_EXT_CSD 8 */
  428. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_ADTC;
  429. break;
  430. case SWITCH: /* MMC_SWITCH 6 */
  431. flags |= FSDIF_MMC_CMD_AC | FSDIF_MMC_RSP_SPI_R1B | FSDIF_MMC_RSP_R1B;
  432. break;
  433. case SEND_STATUS: /* MMC_SEND_STATUS 13 */
  434. flags |= FSDIF_MMC_RSP_SPI_R2 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_AC;
  435. break;
  436. case SET_BLOCKLEN: /* MMC_SET_BLOCKLEN 16 */
  437. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_AC;
  438. break;
  439. case SET_BLOCK_COUNT: /* MMC_SET_BLOCK_COUNT 23 */
  440. flags |= FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_AC;
  441. break;
  442. case WRITE_BLOCK: /* MMC_WRITE_BLOCK 24 */
  443. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_ADTC;
  444. break;
  445. case WRITE_MULTIPLE_BLOCK: /* MMC_WRITE_MULTIPLE_BLOCK 25 */
  446. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_ADTC;
  447. break;
  448. case READ_SINGLE_BLOCK: /* MMC_READ_SINGLE_BLOCK 17 */
  449. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_ADTC;
  450. break;
  451. case READ_MULTIPLE_BLOCK: /* MMC_READ_MULTIPLE_BLOCK 18 */
  452. flags |= FSDIF_MMC_RSP_SPI_R1 | FSDIF_MMC_RSP_R1 | FSDIF_MMC_CMD_ADTC;
  453. break;
  454. default:
  455. LOG_E("unhandled command-%d !!!", opcode);
  456. break;
  457. }
  458. return flags;
  459. }
  460. void sdif_prepare_command_trasnfer(FSdifMsgDataStartCmd *msg_cmd, struct rt_mmcsd_req *req, rt_uint32_t type)
  461. {
  462. struct rt_mmcsd_cmd *input_cmd = req->cmd;
  463. rt_memset(msg_cmd, 0U, sizeof(*msg_cmd));
  464. msg_cmd->opcode = input_cmd->cmd_code;
  465. msg_cmd->cmd_arg = input_cmd->arg;
  466. msg_cmd->raw_cmd = sdif_prepare_raw_command(req);
  467. if (type == SDIF_CARD_TYPE_MICRO_SD)
  468. {
  469. msg_cmd->flags = sdif_prepare_sd_command_flags(req);
  470. }
  471. else if (type == SDIF_CARD_TYPE_EMMC)
  472. {
  473. msg_cmd->flags = sdif_prepar_emmc_command_flags(req);
  474. }
  475. return;
  476. }
  477. static void sdif_send_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
  478. {
  479. sdif_info_t *host_info = (sdif_info_t *)host->private_data;
  480. FSdifMsgCtrl *sdif = &host_info->sdif;
  481. FSdifMsgCommand *req_cmd = &host_info->req_cmd;
  482. FSdifMsgData *req_data = &host_info->req_data;
  483. FSdifMsgRequest *request = &host_info->req;
  484. rt_err_t err = sdif_pre_request(host, req);
  485. if (err != RT_EOK)
  486. {
  487. if (err != RT_EEMPTY)
  488. {
  489. LOG_E("sdif_pre_request fail.");
  490. }
  491. return;
  492. }
  493. rt_memset(request, 0U, sizeof(*request));
  494. if (req->data)
  495. {
  496. rt_memset(req_data, 0U, sizeof(*req_data));
  497. req_data->buf = (void *)(req->data->buf);
  498. req_data->buf_dma = (uintptr)req_data->buf + PV_OFFSET;
  499. request->data = req_data;
  500. sdif_prepare_data_transfer(&(req_data->datainfo), req);
  501. err = FSdifMsgSetupDMADescriptor(sdif, req_data);
  502. if (FSDIF_SUCCESS != err)
  503. {
  504. LOG_E("SDIF setup DMA failed, err = 0x%x", err);
  505. return;
  506. }
  507. }
  508. rt_memset(req_cmd, 0, sizeof(*req_cmd));
  509. request->command = req_cmd;
  510. sdif_prepare_command_trasnfer(&(req_cmd->cmdinfo), req, host_info->sd_type);
  511. req->cmd->err = sdif_do_transfer(host, request, req->cmd->busy_timeout);
  512. if (resp_type(req->cmd) & RESP_MASK)
  513. {
  514. if (resp_type(req->cmd) == RESP_R2)
  515. {
  516. req->cmd->resp[3] = req_cmd->response[3];
  517. req->cmd->resp[2] = req_cmd->response[2];
  518. req->cmd->resp[1] = req_cmd->response[1];
  519. req->cmd->resp[0] = req_cmd->response[0];
  520. }
  521. else
  522. {
  523. req->cmd->resp[0] = req_cmd->response[0];
  524. }
  525. }
  526. mmcsd_req_complete(host);
  527. }
  528. static void sdif_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
  529. {
  530. FError ret = FT_SUCCESS;
  531. sdif_info_t *host_info = (sdif_info_t *)host->private_data;
  532. FSdifMsgCtrl *sdif = &host_info->sdif;
  533. FSdifMsgDataSetIos target_ios;
  534. /* ClockData set */
  535. if (0 != io_cfg->clock)
  536. {
  537. target_ios.ios_clock = io_cfg->clock;
  538. }
  539. /* Timing set */
  540. if (0 != io_cfg->timing)
  541. {
  542. if (host_info->sd_type == SDIF_CARD_TYPE_MICRO_SD)
  543. {
  544. if (io_cfg->signal_voltage == MMCSD_SIGNAL_VOLTAGE_330)
  545. {
  546. if (target_ios.ios_clock == FSDIF_CLK_SPEED_400KHZ)
  547. {
  548. target_ios.ios_timing = FSDIF_MMC_TIMING_LEGACY;
  549. }
  550. else
  551. {
  552. target_ios.ios_timing = FSDIF_MMC_TIMING_SD_HS;
  553. }
  554. }
  555. else
  556. {
  557. switch (io_cfg->timing)
  558. {
  559. case MMCSD_TIMING_UHS_SDR12:
  560. target_ios.ios_timing = FSDIF_MMC_TIMING_UHS_SDR12;
  561. break;
  562. case MMCSD_TIMING_UHS_SDR25:
  563. target_ios.ios_timing = FSDIF_MMC_TIMING_UHS_SDR25;
  564. break;
  565. case MMCSD_TIMING_UHS_SDR50:
  566. target_ios.ios_timing = FSDIF_MMC_TIMING_UHS_SDR50;
  567. break;
  568. case MMCSD_TIMING_UHS_SDR104:
  569. target_ios.ios_timing = FSDIF_MMC_TIMING_UHS_SDR104;
  570. break;
  571. case MMCSD_TIMING_UHS_DDR50:
  572. target_ios.ios_timing = FSDIF_MMC_TIMING_UHS_DDR50;
  573. break;
  574. default:
  575. break;
  576. }
  577. }
  578. }
  579. else if (host_info->sd_type == SDIF_CARD_TYPE_EMMC)
  580. {
  581. switch (io_cfg->timing)
  582. {
  583. case MMCSD_TIMING_LEGACY:
  584. target_ios.ios_timing = FSDIF_MMC_TIMING_LEGACY;
  585. break;
  586. case MMCSD_TIMING_MMC_HS:
  587. target_ios.ios_timing = FSDIF_MMC_TIMING_MMC_HS;
  588. break;
  589. case MMCSD_TIMING_MMC_HS200:
  590. target_ios.ios_timing = FSDIF_MMC_TIMING_MMC_HS200;
  591. break;
  592. case MMCSD_TIMING_MMC_HS400:
  593. case MMCSD_TIMING_MMC_HS400_ENH_DS:
  594. target_ios.ios_timing = FSDIF_MMC_TIMING_MMC_HS400;
  595. break;
  596. default:
  597. break;
  598. }
  599. }
  600. }
  601. /* dataBusWidth set */
  602. switch (io_cfg->bus_width)
  603. {
  604. case MMCSD_BUS_WIDTH_1:
  605. target_ios.ios_bus_width = FSDIF_MMC_BUS_WIDTH_1;
  606. break;
  607. case MMCSD_BUS_WIDTH_4:
  608. target_ios.ios_bus_width = FSDIF_MMC_BUS_WIDTH_4;
  609. break;
  610. case MMCSD_BUS_WIDTH_8:
  611. target_ios.ios_bus_width = FSDIF_MMC_BUS_WIDTH_8;
  612. break;
  613. default:
  614. LOG_E("Invalid bus width %d", io_cfg->bus_width);
  615. break;
  616. }
  617. ret = FSdifMsgSetIos(sdif, &target_ios);
  618. if (FSDIF_SUCCESS != ret)
  619. {
  620. LOG_E("Set card bus width failed.");
  621. }
  622. }
  623. static rt_int32_t sdif_card_status(struct rt_mmcsd_host *host)
  624. {
  625. sdif_info_t *host_info = (sdif_info_t *)host->private_data;
  626. FSdifMsgCtrl *sdif = &host_info->sdif;
  627. return FSdifMsgCheckifCardExists(sdif) ? 1 : 0;
  628. }
  629. static const struct rt_mmcsd_host_ops ops =
  630. {
  631. .request = sdif_send_request,
  632. .set_iocfg = sdif_set_iocfg,
  633. .get_card_status = sdif_card_status,
  634. .enable_sdio_irq = RT_NULL,
  635. .execute_tuning = RT_NULL,
  636. };
  637. static void sdif_ctrl_setup_interrupt(struct rt_mmcsd_host *host)
  638. {
  639. sdif_info_t *host_info = (sdif_info_t *)host->private_data;
  640. FSdifMsgCtrl *sdif = &(host_info->sdif);
  641. FSdifMsgConfig *config_p = &sdif->config;
  642. rt_uint32_t cpu_id = rt_hw_cpu_id();
  643. rt_hw_interrupt_set_target_cpus(config_p->irq_num, cpu_id);
  644. rt_hw_interrupt_set_priority(config_p->irq_num, 0xc);
  645. /* register intr callback */
  646. rt_hw_interrupt_install(config_p->irq_num,
  647. FSdifMsgInterruptHandler,
  648. sdif,
  649. NULL);
  650. /* enable irq */
  651. rt_hw_interrupt_umask(config_p->irq_num);
  652. return;
  653. }
  654. void sdif_msg_prepare_init_data(FSdifMsgDataInit *msg_data_init, rt_uint32_t type)
  655. {
  656. rt_memset(msg_data_init, 0U, sizeof(*msg_data_init));
  657. if (type == SDIF_CARD_TYPE_MICRO_SD)
  658. {
  659. msg_data_init->caps = FSDIF_MMC_CAP_4_BIT_DATA | FSDIF_MMC_CAP_SD_HIGHSPEED |
  660. FSDIF_MMC_CAP_UHS | FSDIF_MMC_CAP_CMD23;
  661. }
  662. else if (type == SDIF_CARD_TYPE_EMMC)
  663. {
  664. msg_data_init->caps = FSDIF_MMC_CAP_4_BIT_DATA | FSDIF_MMC_CAP_8_BIT_DATA |
  665. FSDIF_MMC_CAP_MMC_HIGHSPEED | FSDIF_MMC_CAP_NONREMOVABLE |
  666. FSDIF_MMC_CAP_1_8V_DDR | FSDIF_MMC_CAP_CMD23 | FSDIF_MMC_CAP_HW_RESET;
  667. }
  668. msg_data_init->clk_rate = FSDIF_CLK_FREQ_HZ; /*1.2GHz*/
  669. }
  670. static rt_err_t sdif_prepare_init_ios(FSdifMsgCtrl *const instance)
  671. {
  672. FSdifMsgDataSetIos target_ios;
  673. target_ios.ios_clock = 0U;
  674. target_ios.ios_timing = FSDIF_MMC_TIMING_LEGACY;
  675. target_ios.ios_bus_width = FSDIF_MMC_BUS_WIDTH_1;
  676. target_ios.ios_power_mode = FSDIF_MMC_POWER_UP;
  677. if (FSDIF_SUCCESS != FSdifMsgSetIos(instance, &target_ios))
  678. {
  679. LOG_E("Set init IOS failed.");
  680. return -RT_ERROR;
  681. }
  682. instance->cur_ios.ios_power_mode = FSDIF_MMC_POWER_ON;
  683. return RT_EOK;
  684. }
  685. static rt_err_t sdif_prepare_init_volt(FSdifMsgCtrl *const instance, rt_uint32_t type)
  686. {
  687. FSdifMsgDataSwitchVolt target_volt;
  688. if (type == SDIF_CARD_TYPE_MICRO_SD)
  689. {
  690. target_volt.signal_voltage = FSDIF_MMC_SIGNAL_VOLTAGE_330;
  691. }
  692. else if (type == SDIF_CARD_TYPE_EMMC)
  693. {
  694. target_volt.signal_voltage = FSDIF_MMC_SIGNAL_VOLTAGE_180;
  695. }
  696. if (FSDIF_SUCCESS != FSdifMsgSetVoltage(instance, &target_volt))
  697. {
  698. LOG_E("Set init VOLT failed.");
  699. return -RT_ERROR;
  700. }
  701. return RT_EOK;
  702. }
  703. static rt_err_t sdif_host_init(rt_uint32_t id, rt_uint32_t type)
  704. {
  705. struct rt_mmcsd_host *host = RT_NULL;
  706. sdif_info_t *host_info = RT_NULL;
  707. const FSdifMsgConfig *default_sdif_config = RT_NULL;
  708. FSdifMsgConfig sdif_config;
  709. rt_err_t result = RT_EOK;
  710. host = mmcsd_alloc_host();
  711. if (!host)
  712. {
  713. LOG_E("Alloc host failed");
  714. result = RT_ENOMEM;
  715. goto err_free;
  716. }
  717. host_info = rt_malloc(sizeof(sdif_info_t));
  718. if (!host_info)
  719. {
  720. LOG_E("Malloc host_info failed");
  721. result = RT_ENOMEM;
  722. goto err_free;
  723. }
  724. rt_memset(host_info, 0, sizeof(*host_info));
  725. result = rt_event_init(&host_info->event, "sdif_event", RT_IPC_FLAG_FIFO);
  726. RT_ASSERT(RT_EOK == result);
  727. host_info->aligned_buffer_size = SDIF_DMA_BLK_SZ * SDIF_MAX_BLK_TRANS;
  728. host_info->aligned_buffer = rt_malloc_align(host_info->aligned_buffer_size,
  729. SDIF_DMA_ALIGN);
  730. if (!host_info->aligned_buffer)
  731. {
  732. LOG_E("Malloc aligned buffer failed");
  733. result = RT_ENOMEM;
  734. goto err_free;
  735. }
  736. host_info->aligned_buffer_dma = (uintptr_t)host_info->aligned_buffer + PV_OFFSET;
  737. rt_memset(host_info->aligned_buffer, 0, host_info->aligned_buffer_size);
  738. host_info->rw_desc_num = (SDIF_DMA_BLK_SZ * SDIF_MAX_BLK_TRANS) / FSDIF_IDMAC_MAX_BUF_SIZE + 1;
  739. host_info->rw_desc = rt_malloc_align(host_info->rw_desc_num * sizeof(FSdifMsgIDmaDesc),
  740. SDIF_DMA_ALIGN);
  741. if (!host_info->rw_desc)
  742. {
  743. LOG_E("Malloc rw_desc failed");
  744. result = RT_ENOMEM;
  745. goto err_free;
  746. }
  747. host_info->rw_desc_dma = (uintptr_t)host_info->rw_desc + PV_OFFSET;
  748. rt_memset(host_info->rw_desc, 0, host_info->rw_desc_num * sizeof(FSdifMsgIDmaDesc));
  749. /* host data init */
  750. host->ops = &ops;
  751. host->freq_min = FSDIF_CLK_SPEED_400KHZ;
  752. if (type == SDIF_CARD_TYPE_MICRO_SD)
  753. {
  754. host->freq_max = FSDIF_CLK_SPEED_50_MHZ;
  755. }
  756. else
  757. {
  758. host->freq_max = FSDIF_CLK_SPEED_52_MHZ;
  759. }
  760. host->valid_ocr = VDD_32_33 | VDD_33_34; /* voltage 3.3v */
  761. host->flags = MMCSD_MUTBLKWRITE | MMCSD_BUSWIDTH_4;
  762. host->max_seg_size = SDIF_DMA_BLK_SZ; /* used in block_dev.c */
  763. host->max_dma_segs = SDIF_MAX_BLK_TRANS; /* physical segment number */
  764. host->max_blk_size = SDIF_DMA_BLK_SZ; /* all the 4 para limits size of one blk tran */
  765. host->max_blk_count = SDIF_MAX_BLK_TRANS;
  766. host->private_data = host_info;
  767. host->name[0] = 's';
  768. host->name[1] = 'd';
  769. host->name[2] = '0' + id;
  770. host->name[3] = '\0';
  771. mmc_host[id] = host;
  772. default_sdif_config = FSdifMsgLookupConfig(id);
  773. RT_ASSERT(default_sdif_config != RT_NULL);
  774. sdif_config = *default_sdif_config;
  775. #ifdef RT_USING_SMART
  776. sdif_config.dev_msg.shmem = (uintptr)rt_ioremap((void *)input_cfg.msg.shmem, 0x1000);
  777. sdif_config.dev_msg.regfile = (uintptr)rt_ioremap((void *)input_cfg.msg.regfile, 0x1000);
  778. #endif
  779. if (type == SDIF_CARD_TYPE_MICRO_SD)
  780. {
  781. sdif_config.non_removable = FALSE; /* TF card is removable on board */
  782. }
  783. else if (type == SDIF_CARD_TYPE_EMMC)
  784. {
  785. sdif_config.non_removable = TRUE; /* eMMC is unremovable on board */
  786. }
  787. sdif_msg_prepare_init_data(&(sdif_config.init), type);
  788. FSdifMsgCtrl *sdif = &(host_info->sdif);
  789. if (FSDIF_SUCCESS != FSdifMsgCfgInitialize(sdif, &sdif_config))
  790. {
  791. LOG_E("Sdif v2 ctrl init failed.");
  792. result = RT_EIO;
  793. goto err_free;
  794. }
  795. if (FSDIF_SUCCESS != FSdifMsgSetIDMAList(sdif,
  796. host_info->rw_desc,
  797. host_info->rw_desc_dma,
  798. host_info->rw_desc_num))
  799. {
  800. LOG_E("SDIF controller setup DMA failed.");
  801. result = RT_EIO;
  802. goto err_free;
  803. }
  804. host_info->sd_type = type;
  805. LOG_I("Init sdif-%d as %d", id, type);
  806. /* setup interrupt */
  807. sdif_ctrl_setup_interrupt(host);
  808. FSdifMsgRegisterEvtHandler(sdif, FSDIF_EVT_CARD_DETECTED, sdif_card_detect_callback, host);
  809. FSdifMsgRegisterEvtHandler(sdif, FSDIF_EVT_ERR_OCCURE, sdif_error_occur_callback, host);
  810. FSdifMsgRegisterEvtHandler(sdif, FSDIF_EVT_CMD_DONE, sdif_command_done_callback, host);
  811. FSdifMsgRegisterEvtHandler(sdif, FSDIF_EVT_DATA_DONE, sdif_data_done_callback, host);
  812. if (sdif_prepare_init_ios(sdif) == RT_EOK)
  813. {
  814. result = sdif_prepare_init_volt(sdif, type);
  815. }
  816. return result;
  817. err_free:
  818. if (host)
  819. {
  820. mmcsd_free_host(host);
  821. }
  822. if (host_info)
  823. {
  824. if (host_info->aligned_buffer)
  825. {
  826. rt_free(host_info->aligned_buffer);
  827. host_info->aligned_buffer = RT_NULL;
  828. host_info->aligned_buffer_size = 0U;
  829. }
  830. if (host_info->rw_desc)
  831. {
  832. rt_free(host_info->rw_desc);
  833. host_info->rw_desc = RT_NULL;
  834. host_info->rw_desc_num = 0;
  835. }
  836. rt_free(host_info);
  837. }
  838. return result;
  839. }
  840. int rt_hw_sdif_init(void)
  841. {
  842. int status = RT_EOK;
  843. rt_uint32_t sd_type;
  844. FSdifTimingInit();
  845. #ifdef USING_SDIF0
  846. #if defined(USE_SDIF0_TF)
  847. sd_type = SDIF_CARD_TYPE_MICRO_SD;
  848. #elif defined(USE_SDIF0_EMMC)
  849. sd_type = SDIF_CARD_TYPE_EMMC;
  850. #endif
  851. status = sdif_host_init(FSDIF0_ID, sd_type);
  852. if (status != RT_EOK)
  853. {
  854. LOG_E("SDIF0 init failed, status = %d", status);
  855. return status;
  856. }
  857. #endif
  858. return status;
  859. }
  860. INIT_DEVICE_EXPORT(rt_hw_sdif_init);
  861. #endif