drv_mmc.c 29 KB

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