drv_mmc.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134
  1. /*
  2. * File : drv_mmc.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2013 - 2015, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2013-03-09 aozima the first version
  13. * 2013-03-29 aozima support Jz4770.
  14. * 2013-04-01 aozima add interrupt support for Jz4770.
  15. */
  16. #include <rthw.h>
  17. #include <rtthread.h>
  18. #include <rtdevice.h>
  19. #include <drivers/mmcsd_core.h>
  20. #include <drivers/sdio.h>
  21. #include "board.h"
  22. #include "drv_gpio.h"
  23. #include "drv_clock.h"
  24. #include "drv_mmc.h"
  25. #include <cache.h>
  26. #include <string.h>
  27. #define DMA_BUFFER
  28. #define DMA_ALIGN (32U)
  29. #define PIO_THRESHOLD 64 /* use pio mode if data length < PIO_THRESHOLD */
  30. #define DEBUG_ENABLE
  31. #define DEBUG_SECTION_NAME "SDIO"
  32. #define DEBUG_LEVEL DBG_INFO
  33. // #define DEBUG_LEVEL DBG_LOG
  34. #define DEBUG_COLOR
  35. #include <rtdbg.h>
  36. /*
  37. * Error status including CRC_READ_ERROR, CRC_WRITE_ERROR,
  38. * CRC_RES_ERR, TIME_OUT_RES, TIME_OUT_READ
  39. */
  40. #define ERROR_STAT 0x3f
  41. #define JZMMC_USE_PIO 2
  42. /* Register access macros */
  43. #define msc_readl(host,reg) \
  44. readl((host)->hw_base + reg)
  45. #define msc_writel(host,reg,value) \
  46. writel((value), (host)->hw_base + (reg))
  47. #define is_pio_mode(host) \
  48. (host->flags & (1 << JZMMC_USE_PIO))
  49. #define enable_pio_mode(host) \
  50. (host->flags |= (1 << JZMMC_USE_PIO))
  51. #define disable_pio_mode(host) \
  52. (host->flags &= ~(1 << JZMMC_USE_PIO))
  53. /*-------------------End structure and macro define------------------------*/
  54. #ifdef DMA_BUFFER
  55. ALIGN(32)
  56. uint8_t _dma_buffer_0[32 * 1024];
  57. ALIGN(32)
  58. uint8_t _dma_buffer_1[32 * 1024];
  59. #endif
  60. struct jzmmc_host *jz_host1 = RT_NULL;
  61. volatile static int stopping_clock = 0;
  62. volatile static int sdio_log = 0;
  63. /*
  64. * Functional functions.
  65. *
  66. * These small function will be called frequently.
  67. */
  68. rt_inline void enable_msc_irq(struct jzmmc_host *host, unsigned long bits)
  69. {
  70. unsigned long imsk;
  71. imsk = msc_readl(host, MSC_IMASK_OFFSET);
  72. imsk &= ~bits;
  73. msc_writel(host, MSC_IMASK_OFFSET, imsk);
  74. }
  75. rt_inline void clear_msc_irq(struct jzmmc_host *host, unsigned long bits)
  76. {
  77. msc_writel(host, MSC_IREG_OFFSET, bits);
  78. }
  79. rt_inline void disable_msc_irq(struct jzmmc_host *host, unsigned long bits)
  80. {
  81. unsigned long imsk;
  82. imsk = msc_readl(host, MSC_IMASK_OFFSET);
  83. imsk |= bits;
  84. msc_writel(host, MSC_IMASK_OFFSET, imsk);
  85. }
  86. static inline int check_error_status(struct jzmmc_host *host, unsigned int status)
  87. {
  88. if (status & ERROR_STAT)
  89. {
  90. dbg_log(DBG_LOG, "Error status->0x%08X: cmd=%d\n", status, host->cmd->cmd_code);
  91. return -1;
  92. }
  93. return 0;
  94. }
  95. /* Stop the MMC clock and wait while it happens */
  96. rt_inline rt_err_t jzmmc_stop_clock(uint32_t hw_base)
  97. {
  98. uint16_t value;
  99. int timeout = 10000;
  100. stopping_clock = 1;
  101. value = readw(hw_base + MSC_CTRL_OFFSET);
  102. value &= ~MSC_CTRL_CLOCK_CONTROL_MASK;
  103. value |= MSC_CTRL_CLOCK_STOP;
  104. writew(value, hw_base + MSC_CTRL_OFFSET);
  105. while (timeout && (readl(hw_base + MSC_STAT_OFFSET) & MSC_STAT_CLK_EN))
  106. {
  107. timeout--;
  108. if (timeout == 0)
  109. {
  110. rt_kprintf("stop clock timeout!\n");
  111. stopping_clock = 0;
  112. return -RT_ETIMEOUT;
  113. }
  114. rt_thread_delay(1);
  115. }
  116. stopping_clock = 0;
  117. return RT_EOK;
  118. }
  119. /* Start the MMC clock and operation */
  120. rt_inline void jzmmc_start_clock(uint32_t hw_base)
  121. {
  122. uint16_t value;
  123. value = readw(hw_base + MSC_CTRL_OFFSET);
  124. value |= (MSC_CTRL_CLOCK_START | MSC_CTRL_START_OP);
  125. writew(value, hw_base + MSC_CTRL_OFFSET);
  126. }
  127. static int jzmmc_polling_status(struct jzmmc_host *host, unsigned int status)
  128. {
  129. unsigned int cnt = 100 * 1000 * 1000;
  130. while(!(msc_readl(host, MSC_STAT_OFFSET) & (status | ERROR_STAT)) \
  131. && (--cnt));
  132. if (!cnt)
  133. {
  134. dbg_log(DBG_LOG, "polling status(0x%08X) time out, "
  135. "op=%d, status=0x%08X\n", status,
  136. host->cmd->cmd_code, msc_readl(host, MSC_STAT_OFFSET));
  137. return -1;
  138. }
  139. if (msc_readl(host, MSC_STAT_OFFSET) & ERROR_STAT)
  140. {
  141. dbg_log(DBG_LOG, "polling status(0x%08X) error, "
  142. "op=%d, status=0x%08X\n", status,
  143. host->cmd->cmd_code, msc_readl(host, MSC_STAT_OFFSET));
  144. return -1;
  145. }
  146. return 0;
  147. }
  148. rt_inline void jzmmc_stop_dma(struct jzmmc_host *host)
  149. {
  150. /*
  151. * Theoretically, DMA can't be stopped when transfering, so we can only
  152. * diable it when it is out of DMA request.
  153. */
  154. msc_writel(host, MSC_DMAC_OFFSET, 0);
  155. }
  156. static void jzmmc_command_done(struct jzmmc_host *host, struct rt_mmcsd_cmd *cmd)
  157. {
  158. int i;
  159. unsigned long res;
  160. uint8_t buf[16];
  161. uint32_t data;
  162. memset(cmd->resp, 0x0, sizeof(cmd->resp));
  163. if ((host->cmdat & MSC_CMDAT_RESP_FORMAT_MASK) == MSC_CMDAT_RESPONSE_R2)
  164. {
  165. res = msc_readl(host, MSC_RES_OFFSET);
  166. for (i = 0 ; i < 4 ; i++) {
  167. cmd->resp[i] = res << 24;
  168. res = msc_readl(host, MSC_RES_OFFSET);
  169. cmd->resp[i] |= res << 8;
  170. res = msc_readl(host, MSC_RES_OFFSET);
  171. cmd->resp[i] |= res >> 8;
  172. }
  173. }
  174. else if ((host->cmdat & MSC_CMDAT_RESP_FORMAT_MASK) == MSC_CMDAT_RESPONSE_NONE)
  175. {
  176. }
  177. else
  178. {
  179. res = msc_readl(host, MSC_RES_OFFSET);
  180. cmd->resp[0] = res << 24;
  181. res = msc_readl(host, MSC_RES_OFFSET);
  182. cmd->resp[0] |= res << 8;
  183. res = msc_readl(host, MSC_RES_OFFSET);
  184. cmd->resp[0] |= res & 0xff;
  185. }
  186. dbg_log(DBG_LOG, "error:%d cmd->resp [%08X, %08X, %08X, %08X]\r\n\r\n",
  187. cmd->err,
  188. cmd->resp[0],
  189. cmd->resp[1],
  190. cmd->resp[2],
  191. cmd->resp[3]
  192. );
  193. clear_msc_irq(host, IFLG_END_CMD_RES);
  194. }
  195. static void jzmmc_data_done(struct jzmmc_host *host)
  196. {
  197. struct rt_mmcsd_data *data = host->data;
  198. if (host->cmd->err == RT_EOK)
  199. {
  200. data->bytes_xfered = (data->blks * data->blksize);
  201. jzmmc_stop_dma(host);
  202. }
  203. else
  204. {
  205. jzmmc_stop_dma(host);
  206. data->bytes_xfered = 0;
  207. dbg_log(DBG_LOG, "error when request done\n");
  208. }
  209. }
  210. #define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
  211. static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
  212. {
  213. unsigned char *buf = (unsigned char*)ptr;
  214. int i, j;
  215. for (i=0; i<buflen; i+=16)
  216. {
  217. rt_kprintf("%08X: ", i);
  218. for (j=0; j<16; j++)
  219. if (i+j < buflen)
  220. rt_kprintf("%02X ", buf[i+j]);
  221. else
  222. rt_kprintf(" ");
  223. rt_kprintf(" ");
  224. for (j=0; j<16; j++)
  225. if (i+j < buflen)
  226. rt_kprintf("%c", __is_print(buf[i+j]) ? buf[i+j] : '.');
  227. rt_kprintf("\n");
  228. }
  229. }
  230. /*------------------------End functional functions-------------------------*/
  231. rt_inline void jzmmc_submit_dma(struct jzmmc_host *host, struct rt_mmcsd_data *data)
  232. {
  233. host->dma_desc.nda = 0;
  234. host->dma_desc.len = data->blks * data->blksize;
  235. host->dma_desc.da = virt_to_phys(data->buf);
  236. host->dma_desc.dcmd = DMACMD_ENDI | DMACMD_LINK; /* only one DMA descriptor */
  237. #ifdef DMA_BUFFER
  238. if ((uint32_t)(data->buf) & (DMA_ALIGN - 1))
  239. {
  240. /* not align */
  241. host->dma_desc.da = virt_to_phys(host->_dma_buffer);
  242. if (data->flags & DATA_DIR_WRITE)
  243. {
  244. dbg_log(DBG_LOG, "%d ->", data->blks * data->blksize);
  245. memcpy(host->_dma_buffer, data->buf, data->blks * data->blksize);
  246. rt_hw_dcache_flush_range((rt_ubase_t)(host->_dma_buffer), data->blks * data->blksize);
  247. dbg_log(DBG_LOG, "| 0x%08x\n", data->buf);
  248. }
  249. }
  250. else
  251. {
  252. if (data->flags & DATA_DIR_WRITE)
  253. {
  254. rt_hw_dcache_flush_range((rt_ubase_t)(data->buf), data->blks * data->blksize);
  255. }
  256. }
  257. #endif
  258. }
  259. // #define PERFORMANCE_DMA
  260. rt_inline void jzmmc_dma_start(struct jzmmc_host *host, struct rt_mmcsd_data *data)
  261. {
  262. volatile int i = 120;
  263. uint32_t dma_addr = virt_to_phys(data->buf);
  264. unsigned int dma_len = data->blks * data->blksize;
  265. unsigned int dmac;
  266. #ifdef PERFORMANCE_DMA
  267. dmac = (0x01 << DMAC_INCR_SHF) | DMAC_DMAEN | DMAC_MODE_SEL;
  268. #else
  269. dmac = (0x01 << DMAC_INCR_SHF) | DMAC_DMAEN;
  270. #endif
  271. #ifndef DMA_BUFFER
  272. if ((dma_addr & (DMA_ALIGN - 1)) || (dma_len & (DMA_ALIGN - 1)))
  273. {
  274. dbg_log(DBG_LOG, "DMA align, addr=0x%08x\n", dma_addr);
  275. dmac |= DMAC_ALIGNEN;
  276. if (dma_addr & (DMA_ALIGN - 1))
  277. {
  278. dmac |= (dma_addr & (DMA_ALIGN - 1)) << DMAC_AOFST_SHF;
  279. }
  280. }
  281. #endif
  282. dbg_log(DBG_LOG, "DMA start: nda 0x%08x, da 0x%08x, len 0x%04x, cmd 0x%08x\n", virt_to_phys(&(host->dma_desc)),
  283. host->dma_desc.da, host->dma_desc.len, host->dma_desc.dcmd);
  284. rt_hw_dcache_flush_range((rt_ubase_t)(&(host->dma_desc)), 32);
  285. while(i--); //TODO:短暂延时,不延时会发生错误
  286. msc_writel(host, MSC_DMANDA_OFFSET, virt_to_phys(&(host->dma_desc)));
  287. msc_writel(host, MSC_DMAC_OFFSET, dmac);
  288. }
  289. /*----------------------------End DMA handler------------------------------*/
  290. /*
  291. * PIO transfer mode.
  292. *
  293. * Functions of PIO read/write mode that can handle 1, 2 or 3 bytes transfer
  294. * even though the FIFO register is 32-bits width.
  295. * It's better just used for test.
  296. */
  297. static int wait_cmd_response(struct jzmmc_host *host)
  298. {
  299. if (!(msc_readl(host, MSC_IREG_OFFSET) & IFLG_END_CMD_RES))
  300. {
  301. rt_err_t ret;
  302. rt_completion_init(&host->completion);
  303. enable_msc_irq(host, IMASK_TIME_OUT_RES | IMASK_END_CMD_RES);
  304. rt_hw_interrupt_umask(host->irqno);
  305. ret = rt_completion_wait(&host->completion, RT_TICK_PER_SECOND);
  306. clear_msc_irq(host, IFLG_TIMEOUT_RES | IFLG_END_CMD_RES);
  307. disable_msc_irq(host, IFLG_TIMEOUT_RES | IFLG_END_CMD_RES);
  308. if(ret == RT_EOK)
  309. {
  310. dbg_log(DBG_LOG, "wait response OK!\r\n");
  311. }
  312. else
  313. {
  314. uint32_t value;
  315. value = msc_readl(host, MSC_STAT_OFFSET);
  316. dbg_log(DBG_LOG, "stat=0x%08x\n", value);
  317. value = msc_readl(host, MSC_IREG_OFFSET);
  318. dbg_log(DBG_LOG, "iflag=0x%08x\n", value);
  319. host->cmd->err = ret;
  320. dbg_log(DBG_LOG, "wait END_CMD_RES timeout[uncompletion]\r\n");
  321. return -1;
  322. }
  323. }
  324. msc_writel(host, MSC_IREG_OFFSET, IFLG_END_CMD_RES);
  325. return 0;
  326. }
  327. static void do_pio_read(struct jzmmc_host *host,
  328. unsigned int *addr, unsigned int cnt)
  329. {
  330. int i = 0;
  331. unsigned int status = 0;
  332. for (i = 0; i < cnt / 4; i++)
  333. {
  334. while (((status = msc_readl(host, MSC_STAT_OFFSET))
  335. & MSC_STAT_DATA_FIFO_EMPTY));
  336. if (check_error_status(host, status))
  337. {
  338. host->cmd->err = -RT_EIO;
  339. return;
  340. }
  341. *addr++ = msc_readl(host, MSC_RXFIFO_OFFSET);
  342. }
  343. /*
  344. * These codes handle the last 1, 2 or 3 bytes transfer.
  345. */
  346. if (cnt & 3)
  347. {
  348. uint32_t n = cnt & 3;
  349. uint32_t data = msc_readl(host, MSC_RXFIFO_OFFSET);
  350. uint8_t *p = (u8 *)addr;
  351. while (n--)
  352. {
  353. *p++ = data;
  354. data >>= 8;
  355. }
  356. }
  357. }
  358. static void do_pio_write(struct jzmmc_host *host,
  359. unsigned int *addr, unsigned int cnt)
  360. {
  361. int i = 0;
  362. unsigned int status = 0;
  363. for (i = 0; i < (cnt / 4); i++)
  364. {
  365. while (((status = msc_readl(host, MSC_STAT_OFFSET))
  366. & MSC_STAT_DATA_FIFO_FULL));
  367. if (check_error_status(host, status))
  368. {
  369. host->cmd->err = -RT_EIO;
  370. return;
  371. }
  372. msc_writel(host, MSC_TXFIFO_OFFSET, *addr++);
  373. }
  374. /*
  375. * These codes handle the last 1, 2 or 3 bytes transfer.
  376. */
  377. if (cnt & 3)
  378. {
  379. uint32_t data = 0;
  380. uint8_t *p = (uint8_t *)addr;
  381. for (i = 0; i < (cnt & 3); i++)
  382. data |= *p++ << (8 * i);
  383. msc_writel(host, MSC_TXFIFO_OFFSET, data);
  384. }
  385. }
  386. static inline void pio_trans_start(struct jzmmc_host *host, struct rt_mmcsd_data *data)
  387. {
  388. unsigned int *addr = (unsigned int *)data->buf;
  389. unsigned int cnt = data->blks * data->blksize;
  390. if (data->flags & DATA_DIR_WRITE)
  391. do_pio_write(host, addr, cnt);
  392. else
  393. do_pio_read(host, addr, cnt);
  394. }
  395. static void pio_trans_done(struct jzmmc_host *host, struct rt_mmcsd_data *data)
  396. {
  397. if (host->cmd->err == RT_EOK)
  398. data->bytes_xfered = data->blks * data->blksize;
  399. else
  400. data->bytes_xfered = 0;
  401. if (host->req->stop)
  402. {
  403. if (jzmmc_polling_status(host, MSC_STAT_AUTO_CMD_DONE) < 0)
  404. host->cmd->err = -RT_EIO;
  405. }
  406. if (data->flags & DATA_DIR_WRITE)
  407. {
  408. if (jzmmc_polling_status(host, MSC_STAT_PRG_DONE) < 0)
  409. {
  410. host->cmd->err = -RT_EIO;
  411. }
  412. clear_msc_irq(host, IFLG_PRG_DONE);
  413. }
  414. else
  415. {
  416. if (jzmmc_polling_status(host, MSC_STAT_DATA_TRAN_DONE) < 0)
  417. {
  418. host->cmd->err = -RT_EIO;
  419. }
  420. clear_msc_irq(host, IFLG_DATA_TRAN_DONE);
  421. }
  422. }
  423. /*-------------------------End PIO transfer mode---------------------------*/
  424. /*
  425. * Achieve mmc_request here.
  426. */
  427. static void jzmmc_data_pre(struct jzmmc_host *host, struct rt_mmcsd_data *data)
  428. {
  429. unsigned int nob = data->blks;
  430. unsigned long cmdat,imsk;
  431. msc_writel(host, MSC_RDTO_OFFSET, 0xffffff);
  432. msc_writel(host, MSC_NOB_OFFSET, nob);
  433. msc_writel(host, MSC_BLKLEN_OFFSET, data->blksize);
  434. cmdat = MSC_CMDAT_DATA_EN;
  435. msc_writel(host, MSC_CMDAT_OFFSET, MSC_CMDAT_DATA_EN);
  436. if (data->flags & DATA_DIR_WRITE)
  437. {
  438. cmdat |= MSC_CMDAT_WRITE;
  439. imsk = IMASK_WR_ALL_DONE | IMASK_CRC_WRITE_ERR;
  440. }
  441. else if (data->flags & DATA_DIR_READ)
  442. {
  443. cmdat &= ~MSC_CMDAT_WRITE;
  444. imsk = IMASK_DMA_DATA_DONE | IMASK_TIME_OUT_READ | IMASK_CRC_READ_ERR;
  445. }
  446. else
  447. {
  448. rt_kprintf("data direction confused\n");
  449. }
  450. host->cmdat |= cmdat;
  451. if (!is_pio_mode(host))
  452. {
  453. jzmmc_submit_dma(host, data);
  454. clear_msc_irq(host, IFLG_PRG_DONE);
  455. enable_msc_irq(host, imsk);
  456. }
  457. }
  458. static void jzmmc_data_start(struct jzmmc_host *host, struct rt_mmcsd_data *data)
  459. {
  460. if (is_pio_mode(host))
  461. {
  462. pio_trans_start(host, data);
  463. pio_trans_done(host, data);
  464. disable_pio_mode(host);
  465. }
  466. else
  467. {
  468. rt_err_t ret;
  469. rt_completion_init(&host->completion);
  470. /* start DMA */
  471. disable_msc_irq(host, IFLG_END_CMD_RES);
  472. jzmmc_dma_start(host, data);
  473. rt_hw_interrupt_umask(host->irqno);
  474. ret = rt_completion_wait(&host->completion, RT_TICK_PER_SECOND);
  475. if (ret != RT_EOK)
  476. {
  477. rt_kprintf("warning: msc dma timeout\n");
  478. }
  479. else
  480. {
  481. dbg_log(DBG_LOG, "msc status: 0x%08x\n", msc_readl(host, MSC_STAT_OFFSET));
  482. clear_msc_irq(host, IFLG_DATA_TRAN_DONE | IFLG_DMAEND | IFLG_DMA_DATA_DONE | IFLG_TIMEOUT_RES);
  483. disable_msc_irq(host, IMASK_DMA_DATA_DONE | IMASK_CRC_READ_ERR);
  484. #ifdef DMA_BUFFER
  485. if ((data->flags & DATA_DIR_READ))
  486. {
  487. if((uint32_t)data->buf & (DMA_ALIGN - 1))
  488. {
  489. rt_hw_dcache_invalidate_range((rt_ubase_t)(host->_dma_buffer), data->blks * data->blksize);
  490. memcpy(data->buf, host->_dma_buffer, data->blks * data->blksize);
  491. dbg_log(DBG_LOG, "0x%08x <-| %d\n", data->buf, data->blks * data->blksize);
  492. }
  493. else
  494. {
  495. rt_hw_dcache_invalidate_range((rt_ubase_t)(data->buf), data->blks * data->blksize);
  496. }
  497. }
  498. #endif
  499. }
  500. jzmmc_data_done(host);
  501. }
  502. }
  503. static void jzmmc_command_start(struct jzmmc_host *host, struct rt_mmcsd_cmd *cmd)
  504. {
  505. unsigned long cmdat = 0;
  506. unsigned long imsk;
  507. /* auto send stop */
  508. if (host->req->stop) cmdat |= MSC_CMDAT_SEND_AS_STOP;
  509. /* handle response type */
  510. switch (cmd->flags & RESP_MASK)
  511. {
  512. #define _CASE(S,D) case RESP_##S: cmdat |= MSC_CMDAT_RESPONSE_##D; break
  513. _CASE(R1, R1); /* r1 */
  514. _CASE(R2, R2);
  515. _CASE(R3, R3); /* r3 */
  516. _CASE(R4, R4); /* r4 */
  517. _CASE(R5, R5);
  518. _CASE(R6, R6);
  519. _CASE(R7, R7);
  520. default:
  521. break;
  522. #undef _CASE
  523. }
  524. if ((cmd->flags & RESP_MASK) == RESP_R1B) cmdat |= MSC_CMDAT_BUSY;
  525. host->cmdat |= cmdat;
  526. if (!is_pio_mode(host))
  527. {
  528. imsk = IMASK_TIME_OUT_RES | IMASK_END_CMD_RES;
  529. enable_msc_irq(host, imsk);
  530. }
  531. dbg_log(DBG_LOG, "dat: 0x%08x\n", host->cmdat);
  532. dbg_log(DBG_LOG, "resp type: %d\n", cmd->flags & RESP_MASK);
  533. writel(0xFF, host->hw_base + MSC_RESTO_OFFSET);
  534. writel(0xFFFFFFFF, host->hw_base + MSC_RDTO_OFFSET);
  535. msc_writel(host, MSC_CMD_OFFSET, cmd->cmd_code);
  536. msc_writel(host, MSC_ARG_OFFSET, cmd->arg);
  537. msc_writel(host, MSC_CMDAT_OFFSET, host->cmdat);
  538. msc_writel(host, MSC_CTRL_OFFSET, MSC_CTRL_START_OP);
  539. jzmmc_start_clock(host->hw_base);
  540. cmd->err = RT_EOK;
  541. if (is_pio_mode(host))
  542. {
  543. wait_cmd_response(host);
  544. jzmmc_command_done(host, host->cmd);
  545. }
  546. }
  547. static void jzmmc_sdio_request(struct rt_mmcsd_host *mmc, struct rt_mmcsd_req *req)
  548. {
  549. struct jzmmc_host *host = mmc->private_data;
  550. char direction = '\0';
  551. host->req = req;
  552. host->data = req->data;
  553. host->cmd = req->cmd;
  554. host->cmdat = 0;
  555. dbg_log(DBG_LOG, "CMD: %d ARG: %08X\n", req->cmd->cmd_code, req->cmd->arg);
  556. if (host->data)
  557. {
  558. direction = (host->data->flags & DATA_DIR_WRITE)? 'w' : 'r';
  559. }
  560. jzmmc_stop_clock(host->hw_base);
  561. /* disable pio mode firstly */
  562. disable_pio_mode(host);
  563. /* clear status */
  564. writew(0xFFFF, host->hw_base + MSC_IREG_OFFSET);
  565. disable_msc_irq(host, 0xffffffff);
  566. if (host->flags & MSC_CMDAT_BUS_WIDTH_4BIT)
  567. {
  568. host->cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT;
  569. }
  570. if(req->cmd->cmd_code == GO_IDLE_STATE)
  571. {
  572. host->cmdat |= MSC_CMDAT_INIT;
  573. }
  574. if(host->data)
  575. {
  576. dbg_log(DBG_LOG, "with data, datalen = %d\n", host->data->blksize * host->data->blks);
  577. if (host->data->blksize * host->data->blks < PIO_THRESHOLD)
  578. {
  579. dbg_log(DBG_LOG, " pio mode!\n");
  580. enable_pio_mode(host);
  581. }
  582. jzmmc_data_pre(host, host->data);
  583. }
  584. else
  585. {
  586. writew(0, host->hw_base + MSC_BLKLEN_OFFSET);
  587. writew(0, host->hw_base + MSC_NOB_OFFSET);
  588. enable_pio_mode(host);
  589. }
  590. jzmmc_command_start(host, host->cmd);
  591. if (host->data)
  592. {
  593. jzmmc_data_start(host, host->data);
  594. }
  595. mmcsd_req_complete(mmc);
  596. }
  597. static void jzmmc_isr(int irqno, void* param)
  598. {
  599. uint32_t pending;
  600. uint32_t pending_;
  601. struct jzmmc_host * host = (struct jzmmc_host *)param;
  602. pending_ = msc_readl(host, MSC_IREG_OFFSET);
  603. pending = msc_readl(host, MSC_IREG_OFFSET) & (~ msc_readl(host, MSC_IMASK_OFFSET));
  604. if(pending_ & IFLG_CRC_RES_ERR)
  605. {
  606. dbg_log(DBG_WARNING, "RES CRC err\n");
  607. }
  608. if(pending_ & IFLG_CRC_READ_ERR)
  609. {
  610. dbg_log(DBG_WARNING, "READ CRC err\n");
  611. }
  612. if(pending_ & IFLG_CRC_WRITE_ERR)
  613. {
  614. dbg_log(DBG_WARNING, "WRITE CRC err\n");
  615. }
  616. if (pending & IFLG_TIMEOUT_RES)
  617. {
  618. host->cmd->err = -RT_ETIMEOUT;
  619. dbg_log(DBG_LOG, "TIMEOUT\n");
  620. }
  621. else if (pending & IFLG_CRC_READ_ERR)
  622. {
  623. host->cmd->err = -RT_EIO;
  624. dbg_log(DBG_WARNING, "CRC READ\n");
  625. }
  626. else if (pending & (IFLG_CRC_RES_ERR | IFLG_CRC_WRITE_ERR | IFLG_TIMEOUT_READ))
  627. {
  628. dbg_log(DBG_ERROR, "MSC ERROR, pending=0x%08x\n", pending);
  629. }
  630. if (pending & (IFLG_DMA_DATA_DONE | IFLG_WR_ALL_DONE))
  631. {
  632. dbg_log(DBG_LOG, "msc DMA end!\n");
  633. /* disable interrupt */
  634. rt_hw_interrupt_mask(host->irqno);
  635. rt_completion_done(&host->completion);
  636. }
  637. else if (pending & (MSC_TIME_OUT_RES | MSC_END_CMD_RES))
  638. {
  639. /* disable interrupt */
  640. rt_hw_interrupt_mask(host->irqno);
  641. rt_completion_done(&host->completion);
  642. }
  643. }
  644. rt_inline void jzmmc_clk_autoctrl(struct jzmmc_host *host, unsigned int on)
  645. {
  646. if(on)
  647. {
  648. if(!clk_is_enabled(host->clock))
  649. clk_enable(host->clock);
  650. if(!clk_is_enabled(host->clock_gate))
  651. clk_enable(host->clock_gate);
  652. }
  653. else
  654. {
  655. if(clk_is_enabled(host->clock_gate))
  656. clk_disable(host->clock_gate);
  657. if(clk_is_enabled(host->clock))
  658. clk_disable(host->clock);
  659. }
  660. }
  661. static int jzmmc_hardware_init(struct jzmmc_host *jz_sdio)
  662. {
  663. uint32_t hw_base = jz_sdio->hw_base;
  664. uint32_t value;
  665. /* reset mmc/sd controller */
  666. value = readl(hw_base + MSC_CTRL_OFFSET);
  667. value |= MSC_CTRL_RESET;
  668. writel(value, hw_base + MSC_CTRL_OFFSET);
  669. rt_thread_delay(1);
  670. value &= ~MSC_CTRL_RESET;
  671. writel(value, hw_base + MSC_CTRL_OFFSET);
  672. while(readl(hw_base + MSC_STAT_OFFSET) & MSC_STAT_IS_RESETTING);
  673. /* mask all IRQs */
  674. writel(0xffffffff, hw_base + MSC_IMASK_OFFSET);
  675. writel(0xffffffff, hw_base + MSC_IREG_OFFSET);
  676. /* set timeout */
  677. writel(0x100, hw_base + MSC_RESTO_OFFSET);
  678. writel(0x1ffffff, hw_base + MSC_RDTO_OFFSET);
  679. /* stop MMC/SD clock */
  680. jzmmc_stop_clock(hw_base);
  681. return 0;
  682. }
  683. /* RT-Thread SDIO interface */
  684. static void jzmmc_sdio_set_iocfg(struct rt_mmcsd_host *host,
  685. struct rt_mmcsd_io_cfg *io_cfg)
  686. {
  687. struct jzmmc_host * jz_sdio = host->private_data;
  688. rt_uint32_t clkdiv;
  689. dbg_log(DBG_LOG, "set_iocfg clock: %d\n", io_cfg->clock);
  690. if (io_cfg->bus_width == MMCSD_BUS_WIDTH_4)
  691. {
  692. dbg_log(DBG_LOG, "MMC: Setting controller bus width to 4\n");
  693. jz_sdio->flags |= MSC_CMDAT_BUS_WIDTH_4BIT;
  694. }
  695. else
  696. {
  697. jz_sdio->flags &= ~(MSC_CMDAT_BUS_WIDTH_4BIT);
  698. dbg_log(DBG_LOG, "MMC: Setting controller bus width to 1\n");
  699. }
  700. if (io_cfg->clock)
  701. {
  702. unsigned int clk_set = 0, clkrt = 0;
  703. unsigned int clk_want = io_cfg->clock;
  704. unsigned int lpm = 0;
  705. if (io_cfg->clock > 1 * 1000 * 1000)
  706. {
  707. io_cfg->clock = 1000 * 1000;
  708. }
  709. jzmmc_clk_autoctrl(jz_sdio, 1);
  710. if (clk_want > 3000000)
  711. {
  712. clk_set_rate(jz_sdio->clock, io_cfg->clock);
  713. }
  714. else
  715. {
  716. clk_set_rate(jz_sdio->clock, 24000000);
  717. }
  718. clk_set = clk_get_rate(jz_sdio->clock);
  719. while (clk_want < clk_set)
  720. {
  721. clkrt++;
  722. clk_set >>= 1;
  723. }
  724. if (clkrt > 7)
  725. {
  726. dbg_log(DBG_ERROR, "invalid value of CLKRT: "
  727. "ios->clock=%d clk_want=%d "
  728. "clk_set=%d clkrt=%X,\n",
  729. io_cfg->clock, clk_want, clk_set, clkrt);
  730. return;
  731. }
  732. if (!clkrt)
  733. {
  734. dbg_log(DBG_LOG, "clk_want: %u, clk_set: %luHz\n", io_cfg->clock, clk_get_rate(jz_sdio->clock));
  735. }
  736. writel(clkrt, jz_sdio->hw_base + MSC_CLKRT_OFFSET);
  737. if (clk_set > 25000000)
  738. {
  739. lpm = (0x2 << LPM_DRV_SEL_SHF) | LPM_SMP_SEL;
  740. }
  741. if(jz_sdio->sdio_clk)
  742. {
  743. writel(lpm, jz_sdio->hw_base + MSC_LPM_OFFSET);
  744. writel(MSC_CTRL_CLOCK_START, jz_sdio->hw_base + MSC_CTRL_OFFSET);
  745. }
  746. else
  747. {
  748. lpm |= LPM_LPM;
  749. writel(lpm, jz_sdio->hw_base + MSC_LPM_OFFSET);
  750. }
  751. }
  752. else
  753. {
  754. jzmmc_clk_autoctrl(jz_sdio, 0);
  755. }
  756. /* maybe switch power to the card */
  757. switch (io_cfg->power_mode)
  758. {
  759. case MMCSD_POWER_OFF:
  760. dbg_log(DBG_LOG, "MMCSD_POWER_OFF\r\n");
  761. break;
  762. case MMCSD_POWER_UP:
  763. dbg_log(DBG_LOG, "MMCSD_POWER_UP\r\n");
  764. break;
  765. case MMCSD_POWER_ON:
  766. dbg_log(DBG_LOG, "MMCSD_POWER_ON\r\n");
  767. jzmmc_hardware_init(jz_sdio);
  768. // jz_mmc_set_clock(jz_sdio, io_cfg->clock);
  769. break;
  770. default:
  771. dbg_log(DBG_LOG, "unknown power_mode %d\n", io_cfg->power_mode);
  772. break;
  773. }
  774. }
  775. static rt_int32_t jzmmc_sdio_detect(struct rt_mmcsd_host *host)
  776. {
  777. dbg_log(DBG_LOG, "jz47xx_SD_Detect\n");
  778. return 0;
  779. }
  780. static void jzmmc_sdio_enable_sdio_irq(struct rt_mmcsd_host *host,
  781. rt_int32_t enable)
  782. {
  783. dbg_log(DBG_LOG, "jz47xx_sdio_enable_sdio_irq, enable:%d\n", enable);
  784. }
  785. static const struct rt_mmcsd_host_ops ops =
  786. {
  787. jzmmc_sdio_request,
  788. jzmmc_sdio_set_iocfg,
  789. jzmmc_sdio_detect,
  790. jzmmc_sdio_enable_sdio_irq,
  791. };
  792. int jzmmc_sdio_init(void)
  793. {
  794. struct rt_mmcsd_host *host = RT_NULL;
  795. struct jzmmc_host *jz_host = RT_NULL;
  796. #ifdef RT_USING_MSC0
  797. host = mmcsd_alloc_host();
  798. jz_host = rt_malloc_align(sizeof(struct jzmmc_host), 32);
  799. if(!(host && jz_host))
  800. {
  801. goto err;
  802. }
  803. rt_memset(jz_host, 0, sizeof(struct jzmmc_host));
  804. /* set hardware base firstly */
  805. jz_host->hw_base = MSC0_BASE;
  806. jz_host->clock = clk_get("cgu_msc0");
  807. jz_host->clock_gate = clk_get("msc0");
  808. #ifdef DMA_BUFFER
  809. jz_host->_dma_buffer = _dma_buffer_0;
  810. #endif
  811. /* init GPIO (msc0 boot)
  812. * name pin fun
  813. * X1000 MSC0_D0: PA23 1
  814. * X1000 MSC0_D1: PA22 1
  815. * X1000 MSC0_D2: PA21 1
  816. * X1000 MSC0_D3: PA20 1
  817. * X1000 MSC0_CMD: PA25 1
  818. * X1000 MSC0_CLK: PA24 1
  819. */
  820. {
  821. gpio_set_func(GPIO_PORT_A, GPIO_Pin_20, GPIO_FUNC_1);
  822. gpio_set_func(GPIO_PORT_A, GPIO_Pin_21, GPIO_FUNC_1);
  823. gpio_set_func(GPIO_PORT_A, GPIO_Pin_22, GPIO_FUNC_1);
  824. gpio_set_func(GPIO_PORT_A, GPIO_Pin_23, GPIO_FUNC_1);
  825. gpio_set_func(GPIO_PORT_A, GPIO_Pin_24, GPIO_FUNC_1);
  826. gpio_set_func(GPIO_PORT_A, GPIO_Pin_25, GPIO_FUNC_1);
  827. }
  828. /* enable MSC0 clock gate. */
  829. clk_enable(jz_host->clock_gate);
  830. jz_host->msc_clock = 25UL * 1000 * 1000; /* 25Mhz */
  831. host->freq_min = 400 * 1000; /* min 400Khz. */
  832. host->freq_max = 25 * 1000 * 1000; /* max 25Mhz. */
  833. // jz_host->msc_clock = 400 * 1000; /* 25Mhz */
  834. // host->freq_min = 400 * 1000; /* min 400Khz. */
  835. // host->freq_max = 400 * 1000; /* max 25Mhz. */
  836. /* set clock */
  837. clk_set_rate(jz_host->clock, 50000000);
  838. host->ops = &ops;
  839. host->valid_ocr = VDD_27_28 | VDD_28_29 | VDD_29_30 | VDD_30_31 | VDD_31_32 |
  840. VDD_32_33 | VDD_33_34 | VDD_34_35 | VDD_35_36;
  841. // host->flags = MMCSD_BUSWIDTH_4 | MMCSD_MUTBLKWRITE | MMCSD_SUP_SDIO_IRQ | MMCSD_SUP_HIGHSPEED;
  842. host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_SDIO_IRQ | MMCSD_SUP_HIGHSPEED;
  843. host->max_seg_size = 65535;
  844. host->max_dma_segs = 2;
  845. host->max_blk_size = 512;
  846. host->max_blk_count = 4096;
  847. host->private_data = jz_host;
  848. jz_host->host = host;
  849. jz_host->irqno = IRQ_MSC0;
  850. rt_hw_interrupt_install(jz_host->irqno, jzmmc_isr, jz_host, "msc0");
  851. rt_hw_interrupt_mask(jz_host->irqno);
  852. mmcsd_change(host);
  853. #endif // RT_USING_MSC0
  854. #ifdef RT_USING_MSC1
  855. host = mmcsd_alloc_host();
  856. jz_host = rt_malloc(sizeof(struct jzmmc_host));
  857. if(!(host && jz_host))
  858. {
  859. goto err;
  860. }
  861. jz_host1 = jz_host; // for debug
  862. rt_memset(jz_host, 0, sizeof(struct jzmmc_host));
  863. jz_host->hw_base = MSC1_BASE;
  864. jz_host->clock = clk_get("cgu_msc1");
  865. jz_host->clock_gate = clk_get("msc1");
  866. #ifdef DMA_BUFFER
  867. jz_host->_dma_buffer = _dma_buffer_1;
  868. #endif
  869. /* init GPIO (paladin msc1 SDIO wifi)
  870. * name pin fun
  871. * X1000 MSC1_D0: PC02 0
  872. * X1000 MSC1_D1: PC03 0
  873. * X1000 MSC1_D2: PC04 0
  874. * X1000 MSC1_D3: PC05 0
  875. * X1000 MSC1_CMD: PC01 0
  876. * X1000 MSC1_CLK: PC00 0
  877. *
  878. */
  879. {
  880. gpio_set_func(GPIO_PORT_C, GPIO_Pin_0, GPIO_FUNC_0);
  881. gpio_set_func(GPIO_PORT_C, GPIO_Pin_1, GPIO_FUNC_0);
  882. gpio_set_func(GPIO_PORT_C, GPIO_Pin_2, GPIO_FUNC_0);
  883. gpio_set_func(GPIO_PORT_C, GPIO_Pin_3, GPIO_FUNC_0);
  884. gpio_set_func(GPIO_PORT_C, GPIO_Pin_4, GPIO_FUNC_0);
  885. gpio_set_func(GPIO_PORT_C, GPIO_Pin_5, GPIO_FUNC_0);
  886. }
  887. /* enable MSC1 clock gate. */
  888. clk_enable(jz_host->clock_gate);
  889. jz_host->msc_clock = 25UL * 1000 * 1000; /* 25Mhz */
  890. host->freq_min = 400 * 1000; /* min 400Khz. */
  891. host->freq_max = 25 * 1000 * 1000; /* max 25Mhz. */
  892. /* set clock */
  893. clk_set_rate(jz_host->clock, BOARD_EXTAL_CLK);
  894. host->ops = &ops;
  895. host->valid_ocr = VDD_27_28 | VDD_28_29 | VDD_29_30 | VDD_30_31 | VDD_31_32 |
  896. VDD_32_33 | VDD_33_34 | VDD_34_35 | VDD_35_36;
  897. host->flags = MMCSD_BUSWIDTH_4 | MMCSD_MUTBLKWRITE | MMCSD_SUP_SDIO_IRQ | MMCSD_SUP_HIGHSPEED;
  898. host->max_seg_size = 65535;
  899. host->max_dma_segs = 2;
  900. host->max_blk_size = 512;
  901. host->max_blk_count = 4096;
  902. host->private_data = jz_host;
  903. jz_host->host = host;
  904. jz_host->irqno = IRQ_MSC1;
  905. rt_hw_interrupt_install(jz_host->irqno, jzmmc_isr, jz_host, "msc1");
  906. rt_hw_interrupt_mask(jz_host->irqno);
  907. mmcsd_change(host);
  908. #endif // RT_USING_MSC1
  909. return RT_EOK;
  910. err:
  911. if(host)
  912. {
  913. mmcsd_free_host(host);
  914. }
  915. if(jz_host)
  916. {
  917. rt_free(jz_host);
  918. }
  919. return -RT_ENOMEM;
  920. }
  921. INIT_DEVICE_EXPORT(jzmmc_sdio_init);
  922. #include <finsh.h>
  923. int msc_status(void)
  924. {
  925. uint32_t value;
  926. if (jz_host1)
  927. {
  928. value = msc_readl(jz_host1, MSC_STAT_OFFSET);
  929. rt_kprintf("status: 0x%08x\n", value);
  930. value = msc_readl(jz_host1, MSC_IMASK_OFFSET);
  931. rt_kprintf("mask : 0x%08x -> 0x%08x\n", value, ~value);
  932. value = msc_readl(jz_host1, MSC_IREG_OFFSET);
  933. rt_kprintf("iflag : 0x%08x\n", value);
  934. rt_kprintf("dma : nda 0x%08x, da 0x%08x, len 0x%04x, cmd 0x%08x\n", msc_readl(jz_host1, MSC_DMANDA_OFFSET),
  935. msc_readl(jz_host1, MSC_DMADA_OFFSET),
  936. msc_readl(jz_host1, MSC_DMALEN_OFFSET),
  937. msc_readl(jz_host1, MSC_DMACMD_OFFSET));
  938. rt_kprintf("clock : %s\n", (stopping_clock == 1)? "stopping" : "none stopping");
  939. }
  940. return 0;
  941. }
  942. MSH_CMD_EXPORT(msc_status, dump msc status);
  943. int msc_log(int argc, char** argv)
  944. {
  945. if (argc == 2)
  946. sdio_log = atoi(argv[1]);
  947. return 0;
  948. }
  949. MSH_CMD_EXPORT(msc_log, set msc log enable);