mmcsd.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2011-01-13 weety first version
  9. */
  10. #include <rtthread.h>
  11. #include <rthw.h>
  12. #include <string.h>
  13. #include <drivers/mmcsd_core.h>
  14. #include <dm36x.h>
  15. #include "mmcsd.h"
  16. #include "edma.h"
  17. #define RT_USING_MMCSD0
  18. #define MMCSD_DEBUG 0
  19. #if MMCSD_DEBUG
  20. #define mmc_dbg(fmt, ...) rt_kprintf(fmt, ##__VA_ARGS__)
  21. #else
  22. #define mmc_dbg(fmt, ...)
  23. #endif
  24. #define MMU_NOCACHE_ADDR(a) ((rt_uint32_t)a | (1UL<<29))
  25. #define CACHE_LINE_SIZE 32
  26. extern void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size);
  27. extern void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size);
  28. #define EVT_QUEUE_NUM 0 /* EDMA3 Event queue number. */
  29. static unsigned rw_threshold = 32;
  30. static rt_bool_t use_dma = RT_TRUE;
  31. enum DATA_DIR_TYPE
  32. {
  33. DM365_MMC_DATADIR_NONE = 0,
  34. DM365_MMC_DATADIR_READ,
  35. DM365_MMC_DATADIR_WRITE,
  36. };
  37. struct mmc_dm365_host
  38. {
  39. struct rt_mmcsd_host *mmc;
  40. struct rt_mmcsd_req *req;
  41. struct rt_mmcsd_data *data;
  42. struct rt_mmcsd_cmd *cmd;
  43. struct edmacc_param tx_template;
  44. struct edmacc_param rx_template;
  45. rt_uint32_t mmc_input_clk;
  46. rt_uint32_t ns_in_one_cycle; /* for ns in one cycle calculation */
  47. mmcsd_regs_t *mmcsd_regs;
  48. rt_uint8_t bus_mode;
  49. enum DATA_DIR_TYPE data_dir;
  50. rt_uint32_t rxdma;
  51. rt_uint32_t txdma;
  52. rt_bool_t use_dma;
  53. rt_bool_t do_dma;
  54. rt_uint8_t *buffer;
  55. rt_uint32_t buffer_bytes_left;
  56. rt_uint32_t bytes_left;
  57. rt_uint8_t *dma_buffer;
  58. rt_bool_t use_dma_buffer;
  59. rt_bool_t sdio_int;
  60. };
  61. void *mmc_priv(struct rt_mmcsd_host *host)
  62. {
  63. return (void *)host->private_data;
  64. }
  65. static void delay_us(rt_uint32_t us)
  66. {
  67. rt_uint32_t len;
  68. for (;us > 0; us --)
  69. for (len = 0; len < 10; len++ );
  70. }
  71. /*******************************************************************************************************
  72. ** 函数名称: calculate_freq_for_card()
  73. ** 功能描述: 此函数用于计算设置SD卡频率所需的分频数
  74. **
  75. ** 输 入: host -> DM365 MMC host句柄
  76. ** mmc_req_freq -> MMC工作频率
  77. **
  78. ** 输 出: 分频值
  79. **
  80. ** 全局变量:
  81. ** 调用模块: 无
  82. **
  83. ********************************************************************************************************/
  84. static rt_uint32_t calculate_freq_for_card(struct mmc_dm365_host *host, rt_uint32_t mmc_req_freq)
  85. {
  86. rt_uint32_t mmc_freq = 0;
  87. rt_uint32_t mmc_pclk = 0;
  88. rt_uint32_t mmc_push_pull_divisor = 0;
  89. mmc_pclk = host->mmc_input_clk;
  90. if (mmc_req_freq && mmc_pclk > (2 * mmc_req_freq))
  91. mmc_push_pull_divisor = ((rt_uint32_t)mmc_pclk / (2 * mmc_req_freq)) - 1;
  92. else
  93. mmc_push_pull_divisor = 0;
  94. mmc_freq = (rt_uint32_t)mmc_pclk / (2 * (mmc_push_pull_divisor + 1));
  95. if (mmc_freq > mmc_req_freq)
  96. mmc_push_pull_divisor = mmc_push_pull_divisor + 1;
  97. /* Convert ns to clock cycles */
  98. if (mmc_req_freq <= 400000)
  99. host->ns_in_one_cycle = (1000000)/(((mmc_pclk/(2*(mmc_push_pull_divisor+1)))/1000));
  100. else
  101. host->ns_in_one_cycle = (1000000)/(((mmc_pclk/(2*(mmc_push_pull_divisor+1)))/1000000));
  102. return mmc_push_pull_divisor;
  103. }
  104. /*******************************************************************************************************
  105. ** 函数名称: calculate_freq_for_card()
  106. ** 功能描述: 此函数用于计算MMC clock分频数
  107. **
  108. ** 输 入: host -> DM365 MMC host句柄
  109. ** ios -> MMC 操作句柄
  110. **
  111. ** 输 出: 读取到的PHY寄存器值
  112. **
  113. ** 全局变量:
  114. ** 调用模块: 无
  115. **
  116. ********************************************************************************************************/
  117. static void calculate_clk_divider(struct rt_mmcsd_host *mmc, struct rt_mmcsd_io_cfg *ios)
  118. {
  119. rt_uint32_t temp = 0;
  120. rt_uint32_t mmc_pclk = 0;
  121. rt_uint32_t open_drain_freq = 0;
  122. rt_uint32_t mmc_push_pull_freq = 0;
  123. struct mmc_dm365_host *host = mmc_priv(mmc);
  124. mmc_pclk = host->mmc_input_clk;
  125. if (ios->bus_mode == MMCSD_BUSMODE_OPENDRAIN)
  126. {
  127. /* Ignoring the init clock value passed for fixing the inter
  128. * operability with different cards.
  129. */
  130. open_drain_freq = ((rt_uint32_t)mmc_pclk / (2 * MMCSD_INIT_CLOCK)) - 1;
  131. if (open_drain_freq > 0xFF)
  132. open_drain_freq = 0xFF;
  133. temp = host->mmcsd_regs->MMCCLK & ~MMCCLK_CLKRT_MASK;
  134. temp |= open_drain_freq;
  135. host->mmcsd_regs->MMCCLK = temp;
  136. /* Convert ns to clock cycles */
  137. host->ns_in_one_cycle = (1000000) / (MMCSD_INIT_CLOCK / 1000);
  138. }
  139. else
  140. {
  141. mmc_push_pull_freq = calculate_freq_for_card(host, ios->clock);
  142. if (mmc_push_pull_freq > 0xFF)
  143. mmc_push_pull_freq = 0xFF;
  144. temp = host->mmcsd_regs->MMCCLK & ~MMCCLK_CLKEN;
  145. host->mmcsd_regs->MMCCLK = temp;
  146. delay_us(10);
  147. temp = host->mmcsd_regs->MMCCLK & ~MMCCLK_CLKRT_MASK;
  148. temp |= mmc_push_pull_freq;
  149. host->mmcsd_regs->MMCCLK = temp;
  150. host->mmcsd_regs->MMCCLK = temp | MMCCLK_CLKEN;
  151. delay_us(10);
  152. }
  153. }
  154. /*******************************************************************************************************
  155. ** 函数名称: mmc_dm365_set_ios()
  156. ** 功能描述: 此函数是mmc设置设置
  157. **
  158. ** 输 入: mmc -> mmc host 句柄
  159. ** ios -> mmc 操作句柄
  160. **
  161. ** 输 出: 无
  162. **
  163. ** 全局变量:
  164. ** 调用模块: 无
  165. **
  166. ********************************************************************************************************/
  167. static void mmc_dm365_set_ios(struct rt_mmcsd_host *mmc, struct rt_mmcsd_io_cfg *ios)
  168. {
  169. struct mmc_dm365_host *host = mmc_priv(mmc);
  170. mmc_dbg("clock %dHz busmode %d powermode %d Vdd %04x\n", ios->clock, ios->bus_mode, ios->power_mode, ios->vdd);
  171. switch (ios->bus_width)
  172. {
  173. case MMCSD_BUS_WIDTH_8:
  174. mmc_dbg("Enabling 8 bit mode\n");
  175. host->mmcsd_regs->MMCCTL = (host->mmcsd_regs->MMCCTL & ~MMCCTL_WIDTH_4_BIT) | MMCCTL_WIDTH_8_BIT;
  176. break;
  177. case MMCSD_BUS_WIDTH_4:
  178. mmc_dbg("Enabling 4 bit mode\n");
  179. host->mmcsd_regs->MMCCTL = (host->mmcsd_regs->MMCCTL & ~MMCCTL_WIDTH_8_BIT) | MMCCTL_WIDTH_4_BIT;
  180. break;
  181. case MMCSD_BUS_WIDTH_1:
  182. mmc_dbg("Enabling 1 bit mode\n");
  183. host->mmcsd_regs->MMCCTL = host->mmcsd_regs->MMCCTL & ~(MMCCTL_WIDTH_8_BIT | MMCCTL_WIDTH_4_BIT);
  184. break;
  185. }
  186. calculate_clk_divider(mmc, ios);
  187. host->bus_mode = ios->bus_mode;
  188. if (ios->power_mode == MMCSD_POWER_UP)
  189. {
  190. unsigned long timeout = rt_tick_get() + 500;
  191. rt_bool_t lose = 1;
  192. host->mmcsd_regs->MMCARGHL = 0;
  193. host->mmcsd_regs->MMCCMD = MMCCMD_INITCK;
  194. while (rt_tick_get() < timeout)
  195. {
  196. rt_uint32_t tmp = host->mmcsd_regs->MMCST0;
  197. if (tmp & MMCST0_RSPDNE)
  198. {
  199. lose = 0;
  200. break;
  201. }
  202. }
  203. if (lose)
  204. mmc_dbg("powerup timeout\n");
  205. }
  206. }
  207. /*******************************************************************************************************
  208. ** 函数名称: dm365_fifo_data_trans()
  209. ** 功能描述: 此函数是fifo模式传输
  210. **
  211. ** 输 入: host -> DM365 mmc host 句柄
  212. ** n -> 传输字节数
  213. **
  214. ** 输 出: 无
  215. **
  216. ** 全局变量:
  217. ** 调用模块: 无
  218. **
  219. ********************************************************************************************************/
  220. static void dm365_fifo_data_trans(struct mmc_dm365_host *host, rt_uint32_t n)
  221. {
  222. rt_uint8_t *p;
  223. rt_uint32_t i;
  224. p = host->buffer;
  225. if (host->bytes_left < n)
  226. n = host->bytes_left;
  227. host->bytes_left -= n;
  228. /* NOTE: we never transfer more than rw_threshold bytes
  229. * to/from the fifo here; there's no I/O overlap.
  230. * This also assumes that access width( i.e. ACCWD) is 4 bytes
  231. */
  232. if (host->data_dir == DM365_MMC_DATADIR_WRITE)
  233. {
  234. for (i = 0; i < (n >> 2); i++)
  235. {
  236. host->mmcsd_regs->MMCDXR = *((rt_uint32_t *)p);
  237. p = p + 4;
  238. }
  239. if (n & 3)
  240. {
  241. rt_kprintf("to do ... \n");
  242. // iowrite8_rep(host->base + MMCSD_MMCDXR, p, (n & 3));
  243. p = p + (n & 3);
  244. }
  245. }
  246. else
  247. {
  248. for (i = 0; i < (n >> 2); i++)
  249. {
  250. *((rt_uint32_t *)p) = host->mmcsd_regs->MMCDRR;
  251. p = p + 4;
  252. }
  253. if (n & 3)
  254. {
  255. rt_kprintf("to do ... \n");
  256. // ioread8_rep(host->base + MMCSD_MMCDRR, p, (n & 3));
  257. p = p + (n & 3);
  258. }
  259. }
  260. host->buffer = p;
  261. }
  262. /*******************************************************************************************************
  263. ** 函数名称: mmc_dm365_start_command()
  264. ** 功能描述: 此函数是开始发送SD命令
  265. **
  266. ** 输 入: host -> DM365 mmc host 句柄
  267. ** cmd -> SD命令句柄
  268. **
  269. ** 输 出: 无
  270. **
  271. ** 全局变量:
  272. ** 调用模块: 无
  273. **
  274. ********************************************************************************************************/
  275. static void mmc_dm365_start_command(struct mmc_dm365_host *host, struct rt_mmcsd_cmd *cmd)
  276. {
  277. rt_uint32_t cmd_reg = 0;
  278. rt_uint32_t im_val;
  279. host->cmd = cmd;
  280. switch (resp_type(cmd))
  281. {
  282. case RESP_R1B:
  283. /* There's some spec confusion about when R1B is
  284. * allowed, but if the card doesn't issue a BUSY
  285. * then it's harmless for us to allow it.
  286. */
  287. cmd_reg |= MMCCMD_BSYEXP;
  288. /* FALLTHROUGH */
  289. case RESP_R1: /* 48 bits, CRC */
  290. case RESP_R4:
  291. case RESP_R5:
  292. case RESP_R6:
  293. case RESP_R7:
  294. cmd_reg |= MMCCMD_RSPFMT_R1456;
  295. break;
  296. case RESP_R2: /* 136 bits, CRC */
  297. cmd_reg |= MMCCMD_RSPFMT_R2;
  298. break;
  299. case RESP_R3: /* 48 bits, no CRC */
  300. cmd_reg |= MMCCMD_RSPFMT_R3;
  301. break;
  302. default:
  303. cmd_reg |= MMCCMD_RSPFMT_NONE;
  304. mmc_dbg("unknown resp_type %04x\n", resp_type(cmd));
  305. break;
  306. }
  307. /* Set command index */
  308. cmd_reg |= cmd->cmd_code;
  309. /* Enable EDMA transfer triggers */
  310. if (host->do_dma == RT_TRUE)
  311. cmd_reg |= MMCCMD_DMATRIG;
  312. if (host->data != RT_NULL && host->data_dir == DM365_MMC_DATADIR_READ)
  313. cmd_reg |= MMCCMD_DMATRIG;
  314. /* Setting whether command involves data transfer or not */
  315. if (cmd->data)
  316. cmd_reg |= MMCCMD_WDATX;
  317. /* Setting whether stream or block transfer */
  318. if (cmd->flags & MMC_DATA_STREAM)
  319. {
  320. mmc_dbg("to do\n");
  321. cmd_reg |= MMCCMD_STRMTP;
  322. }
  323. /* Setting whether data read or write */
  324. if (host->data_dir == DM365_MMC_DATADIR_WRITE)
  325. cmd_reg |= MMCCMD_DTRW;
  326. if (host->bus_mode == MMCSD_BUSMODE_PUSHPULL)
  327. {
  328. cmd_reg |= MMCCMD_PPLEN;
  329. }
  330. /* set Command timeout */
  331. host->mmcsd_regs->MMCTOR = 0x1FFF;
  332. /* Enable interrupt (calculate here, defer until FIFO is stuffed). */
  333. im_val = MMCST0_RSPDNE | MMCST0_CRCRS | MMCST0_TOUTRS;
  334. if (host->data_dir == DM365_MMC_DATADIR_WRITE)
  335. {
  336. im_val |= MMCST0_DATDNE | MMCST0_CRCWR;
  337. if (host->do_dma == RT_FALSE)
  338. im_val |= MMCST0_DXRDY;
  339. }
  340. else if (host->data_dir == DM365_MMC_DATADIR_READ)
  341. {
  342. im_val |= MMCST0_DATDNE | MMCST0_CRCRD | MMCST0_TOUTRD;
  343. if (host->do_dma == RT_FALSE)
  344. im_val |= MMCST0_DRRDY;
  345. }
  346. /*
  347. * Before non-DMA WRITE commands the controller needs priming:
  348. * FIFO should be populated with 32 bytes i.e. whatever is the FIFO size
  349. */
  350. if ((host->do_dma == RT_FALSE) && (host->data_dir == DM365_MMC_DATADIR_WRITE))
  351. dm365_fifo_data_trans(host, rw_threshold);
  352. host->mmcsd_regs->MMCARGHL = cmd->arg;
  353. host->mmcsd_regs->MMCCMD = cmd_reg;
  354. host->mmcsd_regs->MMCIM = im_val;
  355. }
  356. /*******************************************************************************************************
  357. ** 函数名称: dm365_abort_dma()
  358. ** 功能描述: 此函数终止DMA传输
  359. **
  360. ** 输 入: host -> DM365 mmc host 句柄
  361. **
  362. ** 输 出: 无
  363. **
  364. ** 全局变量:
  365. ** 调用模块: 无
  366. **
  367. ********************************************************************************************************/
  368. static void dm365_abort_dma(struct mmc_dm365_host *host)
  369. {
  370. int sync_dev;
  371. if (host->data_dir == DM365_MMC_DATADIR_READ)
  372. sync_dev = host->rxdma;
  373. else
  374. sync_dev = host->txdma;
  375. //EDMA3DisableTransfer(EDMA0CC0_REG_BASE, sync_dev, EDMA3_TRIG_MODE_EVENT);
  376. edma_stop(sync_dev);
  377. edma_clean_channel(sync_dev);
  378. }
  379. /*******************************************************************************************************
  380. ** 函数名称: mmc_request_done()
  381. ** 功能描述: 此函数用于结束处理一个MMC请求
  382. **
  383. ** 输 入: host -> DM365 mmc host 句柄
  384. ** mrq -> request 句柄
  385. **
  386. ** 输 出: 无
  387. **
  388. ** 全局变量:
  389. ** 调用模块: 无
  390. **
  391. ********************************************************************************************************/
  392. void mmc_request_done(struct rt_mmcsd_host *host, struct rt_mmcsd_req *mrq)
  393. {
  394. struct rt_mmcsd_cmd *cmd = mrq->cmd;
  395. int err = cmd->err;
  396. if (err && cmd->retries)
  397. {
  398. mmc_dbg("req failed (CMD%u): %d, retrying...\n", cmd->cmd_code, err);
  399. cmd->retries--;
  400. cmd->err = 0;
  401. host->ops->request(host, mrq);
  402. }
  403. else
  404. {
  405. mmc_dbg("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n",
  406. "dm365 host", cmd->cmd_code, err,
  407. cmd->resp[0], cmd->resp[1],
  408. cmd->resp[2], cmd->resp[3]);
  409. if (mrq->data)
  410. {
  411. mmc_dbg("%s: %d bytes transferred: %d\n",
  412. "dm365 host",
  413. mrq->data->bytes_xfered, mrq->data->err);
  414. }
  415. if (mrq->stop)
  416. {
  417. mmc_dbg("%s: (CMD%u): %d: %08x %08x %08x %08x\n",
  418. "dm365 host", mrq->stop->cmd_code,
  419. mrq->stop->err,
  420. mrq->stop->resp[0], mrq->stop->resp[1],
  421. mrq->stop->resp[2], mrq->stop->resp[3]);
  422. }
  423. mmcsd_req_complete(host);
  424. }
  425. }
  426. /*******************************************************************************************************
  427. ** 函数名称: mmc_dm365_xfer_done()
  428. ** 功能描述: 数据传送结束调用此函数
  429. **
  430. ** 输 入: host -> DM365 mmc host 句柄
  431. ** data -> data 句柄
  432. **
  433. ** 输 出: 无
  434. **
  435. ** 全局变量:
  436. ** 调用模块: 无
  437. **
  438. ********************************************************************************************************/
  439. static void mmc_dm365_xfer_done(struct mmc_dm365_host *host, struct rt_mmcsd_data *data)
  440. {
  441. host->data = RT_NULL;
  442. if (host->mmc->flags & MMCSD_SUP_SDIO_IRQ) {
  443. /*
  444. * SDIO Interrupt Detection work-around as suggested by
  445. * Davinci Errata (TMS320DM355 Silicon Revision 1.1 Errata
  446. * 2.1.6): Signal SDIO interrupt only if it is enabled by core
  447. */
  448. if (host->sdio_int && !(host->mmcsd_regs->SDIOST0 &
  449. SDIOST0_DAT1_HI)) {
  450. host->mmcsd_regs->SDIOIST = SDIOIST_IOINT;
  451. sdio_irq_wakeup(host->mmc);
  452. }
  453. }
  454. if (host->do_dma == RT_TRUE)
  455. {
  456. dm365_abort_dma(host);
  457. if (data->flags & DATA_DIR_READ)
  458. {
  459. /* read operation */
  460. if (host->use_dma_buffer == RT_TRUE)
  461. {
  462. /* copy DMA buffer to read buffer */
  463. memcpy(data->buf, (void*)MMU_NOCACHE_ADDR(host->dma_buffer), data->blks * data->blksize);
  464. }
  465. /*else
  466. {
  467. mmu_invalidate_dcache((rt_uint32_t)data->buf, data->blks * data->blksize);
  468. }*/
  469. }
  470. host->do_dma = RT_FALSE;
  471. }
  472. host->data_dir = DM365_MMC_DATADIR_NONE;
  473. if (!data->stop || (host->cmd && host->cmd->err))
  474. {
  475. mmc_request_done(host->mmc, data->mrq);
  476. host->mmcsd_regs->MMCIM = 0;
  477. }
  478. else
  479. mmc_dm365_start_command(host, data->stop);
  480. }
  481. static void mmc_dm365_dma_cb(unsigned channel, rt_uint16_t ch_status, void *data)
  482. {
  483. if (DMA_COMPLETE != ch_status) {
  484. struct mmc_dm365_host *host = data;
  485. /* Currently means: DMA Event Missed, or "null" transfer
  486. * request was seen. In the future, TC errors (like bad
  487. * addresses) might be presented too.
  488. */
  489. mmc_dbg("DMA %s error\n",
  490. (host->data->flags & MMC_DATA_WRITE)
  491. ? "write" : "read");
  492. host->data->err = -RT_EIO;
  493. mmc_dm365_xfer_done(host, host->data);
  494. }
  495. }
  496. /*******************************************************************************************************
  497. ** 函数名称: mmc_dm365_dma_setup()
  498. ** 功能描述: DMA 设置函数
  499. **
  500. ** 输 入: host -> DM365 mmc host 句柄
  501. ** tx -> 布尔变量,用于判断Tx或者是Rx
  502. ** template -> 用于保存EDMA3CCPaRAMEntry机构数据
  503. **
  504. ** 输 出: 无
  505. **
  506. ** 全局变量:
  507. ** 调用模块: 无
  508. **
  509. ********************************************************************************************************/
  510. static void mmc_dm365_dma_setup(struct mmc_dm365_host *host, rt_bool_t tx, struct edmacc_param *template)
  511. {
  512. rt_uint32_t sync_dev;
  513. const rt_uint16_t acnt = 4;
  514. const rt_uint16_t bcnt = rw_threshold >> 2;
  515. const rt_uint16_t ccnt = 0;
  516. rt_uint32_t src_port = 0;
  517. rt_uint32_t dst_port = 0;
  518. rt_int16_t src_bidx, dst_bidx;
  519. rt_int16_t src_cidx, dst_cidx;
  520. //edmacc_param paramSet;
  521. /*
  522. * A-B Sync transfer: each DMA request is for one "frame" of
  523. * rw_threshold bytes, broken into "acnt"-size chunks repeated
  524. * "bcnt" times. Each segment needs "ccnt" such frames; since
  525. * we tell the block layer our mmc->max_seg_size limit, we can
  526. * trust (later) that it's within bounds.
  527. *
  528. * The FIFOs are read/written in 4-byte chunks (acnt == 4) and
  529. * EDMA will optimize memory operations to use larger bursts.
  530. */
  531. if (tx)
  532. {
  533. sync_dev = host->txdma;
  534. /* src_prt, ccnt, and link to be set up later */
  535. /*paramSet.srcBIdx = acnt;
  536. paramSet.srcCIdx = acnt * bcnt;
  537. paramSet.destAddr = (rt_uint32_t)&(host->mmcsd_regs->MMCDXR);
  538. paramSet.destBIdx = 0;
  539. paramSet.destCIdx = 0;*/
  540. /* src_prt, ccnt, and link to be set up later */
  541. src_bidx = acnt;
  542. src_cidx = acnt * bcnt;
  543. dst_port = (rt_uint32_t)&(host->mmcsd_regs->MMCDXR);
  544. dst_bidx = 0;
  545. dst_cidx = 0;
  546. }
  547. else
  548. {
  549. sync_dev = host->rxdma;
  550. /* dst_prt, ccnt, and link to be set up later */
  551. /*paramSet.srcAddr = (rt_uint32_t)&(host->mmcsd_regs->MMCDRR);
  552. paramSet.srcBIdx = 0;
  553. paramSet.srcCIdx = 0;
  554. paramSet.destBIdx = acnt;
  555. paramSet.destCIdx = acnt * bcnt;*/
  556. src_port = (rt_uint32_t)&(host->mmcsd_regs->MMCDRR);
  557. src_bidx = 0;
  558. src_cidx = 0;
  559. /* dst_prt, ccnt, and link to be set up later */
  560. dst_bidx = acnt;
  561. dst_cidx = acnt * bcnt;
  562. }
  563. /*
  564. * We can't use FIFO mode for the FIFOs because MMC FIFO addresses
  565. * are not 256-bit (32-byte) aligned. So we use INCR, and the W8BIT
  566. * parameter is ignored.
  567. */
  568. edma_set_src(sync_dev, src_port, INCR, W8BIT);
  569. edma_set_dest(sync_dev, dst_port, INCR, W8BIT);
  570. edma_set_src_index(sync_dev, src_bidx, src_cidx);
  571. edma_set_dest_index(sync_dev, dst_bidx, dst_cidx);
  572. edma_set_transfer_params(sync_dev, acnt, bcnt, ccnt, 8, ABSYNC);
  573. edma_read_slot(sync_dev, template);
  574. /* don't bother with irqs or chaining */
  575. template->opt |= EDMA_CHAN_SLOT(sync_dev) << 12;
  576. #if 0
  577. paramSet.opt = 0u;
  578. /* Src & Dest are in INCR modes */
  579. paramSet.opt &= 0xFFFFFFFCu;
  580. /* Program the TCC */
  581. paramSet.opt |= ((sync_dev << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
  582. paramSet.aCnt = acnt;
  583. paramSet.bCnt = bcnt;
  584. /* AB Sync Transfer Mode */
  585. paramSet.opt |= (1 << EDMA3CC_OPT_SYNCDIM_SHIFT);
  586. /* Now, write the PaRAM Set. */
  587. EDMA3SetPaRAM(EDMA0CC0_REG_BASE, sync_dev, &paramSet);
  588. EDMA3GetPaRAM(EDMA0CC0_REG_BASE, sync_dev, template);
  589. #endif
  590. }
  591. /*******************************************************************************************************
  592. ** 函数名称: mmc_dm365_send_dma_request()
  593. ** 功能描述: 发送DMA请求
  594. **
  595. ** 输 入: host -> DM365 mmc host 句柄
  596. ** data -> DMA传送数据结构句柄
  597. **
  598. ** 输 出: 无
  599. **
  600. ** 全局变量:
  601. ** 调用模块: 无
  602. **
  603. ********************************************************************************************************/
  604. static void mmc_dm365_send_dma_request(struct mmc_dm365_host *host, struct rt_mmcsd_data *data)
  605. {
  606. //struct EDMA3CCPaRAMEntry *template;
  607. struct edmacc_param *template;
  608. rt_uint32_t buf_ptr;
  609. rt_uint32_t channel;
  610. rt_uint32_t bytes_left = host->bytes_left;
  611. rt_uint32_t count = host->bytes_left;
  612. const rt_uint32_t shift = ffs(rw_threshold) - 1;
  613. if (host->use_dma_buffer == RT_TRUE)
  614. buf_ptr = host->dma_buffer;//MMU_NOCACHE_ADDR(host->dma_buffer);
  615. else
  616. buf_ptr = (rt_uint32_t)data->buf;
  617. if (host->data_dir == DM365_MMC_DATADIR_WRITE)
  618. {
  619. template = &host->tx_template;
  620. channel = host->txdma;
  621. }
  622. else
  623. {
  624. template = &host->rx_template;
  625. channel = host->rxdma;
  626. }
  627. template->link_bcntrld = 0xffff;
  628. //template->bCntReload = 0x0;
  629. if (count > bytes_left)
  630. count = bytes_left;
  631. bytes_left -= count;
  632. if (host->data_dir == DM365_MMC_DATADIR_WRITE)
  633. template->src = buf_ptr;
  634. else
  635. template->dst = buf_ptr;
  636. template->ccnt = count >> shift;
  637. edma_write_slot(channel, template);
  638. edma_clear_event(channel);
  639. /*EDMA3SetPaRAM(EDMA0CC0_REG_BASE, channel, template);
  640. EDMA3ClrEvt(EDMA0CC0_REG_BASE, channel);
  641. EDMA3EnableTransfer(EDMA0CC0_REG_BASE, channel, EDMA3_TRIG_MODE_EVENT);*/
  642. edma_start(channel);
  643. }
  644. /*******************************************************************************************************
  645. ** 函数名称: mmc_dm365_start_dma_transfer()
  646. ** 功能描述: 开始DMA传输
  647. **
  648. ** 输 入: host -> DM365 mmc host 句柄
  649. ** data -> DMA传送数据结构句柄
  650. **
  651. ** 输 出: DMA传输字节数
  652. **
  653. ** 全局变量:
  654. ** 调用模块: 无
  655. **
  656. ********************************************************************************************************/
  657. static int mmc_dm365_start_dma_transfer(struct mmc_dm365_host *host, struct rt_mmcsd_data *data)
  658. {
  659. /* set initial value */
  660. host->use_dma_buffer = RT_FALSE;
  661. if (!(data->flags & DATA_DIR_READ))
  662. {
  663. if ((rt_uint32_t)data->buf & (RT_ALIGN_SIZE - 1))
  664. {
  665. /* not align to basic size, use DMA buffer */
  666. host->use_dma_buffer = RT_TRUE;
  667. memcpy((void*)MMU_NOCACHE_ADDR(host->dma_buffer), data->buf, data->blks * data->blksize);
  668. }
  669. else
  670. {
  671. rt_uint32_t addr;
  672. addr = ((rt_uint32_t)data->buf & ~(CACHE_LINE_SIZE - 1));
  673. /* write data case, always clean DCache */
  674. mmu_clean_dcache(addr, (data->blks + 1)* data->blksize);
  675. }
  676. }
  677. else
  678. {
  679. /* whether align to cache line in read operation */
  680. if (((rt_uint32_t)data->buf) & (CACHE_LINE_SIZE - 1))
  681. host->use_dma_buffer = RT_TRUE;
  682. else
  683. mmu_invalidate_dcache((rt_uint32_t)data->buf, data->blks * data->blksize);
  684. }
  685. host->do_dma = RT_TRUE;
  686. mmc_dm365_send_dma_request(host, data);
  687. return 0;
  688. }
  689. #if 0
  690. /*******************************************************************************************************
  691. ** 函数名称: acquire_dma_channels()
  692. ** 功能描述: 获取DMA channel
  693. **
  694. ** 输 入: host -> DM365 mmc host 句柄
  695. **
  696. ** 输 出: DMA 通道号
  697. **
  698. ** 全局变量:
  699. ** 调用模块: 无
  700. **
  701. ********************************************************************************************************/
  702. static int acquire_dma_channels(struct mmc_dm365_host *host)
  703. {
  704. int r;
  705. /* Acquire master DMA write channel */
  706. r = EDMA3RequestChannel(EDMA0CC0_REG_BASE, EDMA3_CHANNEL_TYPE_DMA, host->txdma, host->txdma, EVT_QUEUE_NUM);
  707. if (r < 0)
  708. {
  709. rt_kprintf("alloc %s channel err %d\n", "tx", r);
  710. return r;
  711. }
  712. mmc_dm365_dma_setup(host, RT_TRUE, &host->tx_template);
  713. /* Acquire master DMA read channel */
  714. r = EDMA3RequestChannel(EDMA0CC0_REG_BASE, EDMA3_CHANNEL_TYPE_DMA, host->rxdma, host->rxdma, EVT_QUEUE_NUM);
  715. if (r < 0)
  716. {
  717. rt_kprintf("alloc %s channel err %d\n", "rx", r);
  718. goto free_master_write;
  719. }
  720. mmc_dm365_dma_setup(host, RT_FALSE, &host->rx_template);
  721. return 0;
  722. free_master_write:
  723. EDMA3FreeChannel(EDMA0CC0_REG_BASE, EDMA3_CHANNEL_TYPE_DMA, host->txdma, EDMA3_TRIG_MODE_EVENT, host->txdma, EVT_QUEUE_NUM);
  724. return r;
  725. }
  726. #endif
  727. static int acquire_dma_channels(struct mmc_dm365_host *host)
  728. {
  729. //u32 link_size;
  730. int r, i;
  731. /* Acquire master DMA write channel */
  732. r = edma_alloc_channel(host->txdma, mmc_dm365_dma_cb, host,
  733. EVENTQ_DEFAULT);
  734. if (r < 0) {
  735. mmc_dbg("alloc %s channel err %d\n",
  736. "tx", r);
  737. return r;
  738. }
  739. mmc_dm365_dma_setup(host, RT_TRUE, &host->tx_template);
  740. /* Acquire master DMA read channel */
  741. r = edma_alloc_channel(host->rxdma, mmc_dm365_dma_cb, host,
  742. EVENTQ_DEFAULT);
  743. if (r < 0) {
  744. mmc_dbg("alloc %s channel err %d\n",
  745. "rx", r);
  746. goto free_master_write;
  747. }
  748. mmc_dm365_dma_setup(host, RT_FALSE, &host->rx_template);
  749. /* Allocate parameter RAM slots, which will later be bound to a
  750. * channel as needed to handle a scatterlist.
  751. */
  752. #if 0
  753. link_size = min_t(unsigned, host->nr_sg, ARRAY_SIZE(host->links));
  754. for (i = 0; i < link_size; i++) {
  755. r = edma_alloc_slot(EDMA_CTLR(host->txdma), EDMA_SLOT_ANY);
  756. if (r < 0) {
  757. mmc_dbg("dma PaRAM alloc --> %d\n",
  758. r);
  759. break;
  760. }
  761. host->links[i] = r;
  762. }
  763. host->n_link = i;
  764. #endif
  765. return 0;
  766. free_master_write:
  767. edma_free_channel(host->txdma);
  768. return r;
  769. }
  770. /*******************************************************************************************************
  771. ** 函数名称: mmc_dm365_prepare_data()
  772. ** 功能描述: 准备 DMA 数据
  773. **
  774. ** 输 入: host -> DM365 mmc host 句柄
  775. ** req -> SD request 结构句柄
  776. **
  777. ** 输 出: 无
  778. **
  779. ** 全局变量:
  780. ** 调用模块: 无
  781. **
  782. ********************************************************************************************************/
  783. static void mmc_dm365_prepare_data(struct mmc_dm365_host *host, struct rt_mmcsd_req *req)
  784. {
  785. int timeout;
  786. int fifo_lev;
  787. struct rt_mmcsd_data *data = req->data;
  788. fifo_lev = (rw_threshold == 64) ? MMCFIFOCTL_FIFOLEV : 0;
  789. host->data = data;
  790. if (data == RT_NULL)
  791. {
  792. host->data_dir = DM365_MMC_DATADIR_NONE;
  793. host->mmcsd_regs->MMCBLEN = 0;
  794. host->mmcsd_regs->MMCNBLK = 0;
  795. return;
  796. }
  797. mmc_dbg("%s %s, %d blocks of %d bytes\n",
  798. (data->flags & DATA_STREAM) ? "stream" : "block",
  799. (data->flags & DATA_DIR_WRITE) ? "write" : "read",
  800. data->blks, data->blksize);
  801. mmc_dbg(" DTO %d cycles + %d ns\n",
  802. data->timeout_clks, data->timeout_ns);
  803. timeout = data->timeout_clks + (data->timeout_ns / host->ns_in_one_cycle);
  804. if (timeout > 0xffff)
  805. timeout = 0xffff;
  806. host->mmcsd_regs->MMCTOD = timeout;
  807. host->mmcsd_regs->MMCNBLK = data->blks;
  808. host->mmcsd_regs->MMCBLEN = data->blksize;
  809. /* Configure the FIFO */
  810. switch (data->flags & DATA_DIR_WRITE)
  811. {
  812. case DATA_DIR_WRITE:
  813. host->data_dir = DM365_MMC_DATADIR_WRITE;
  814. host->mmcsd_regs->MMCFIFOCTL = fifo_lev | MMCFIFOCTL_FIFODIR_WR | MMCFIFOCTL_FIFORST;
  815. host->mmcsd_regs->MMCFIFOCTL = fifo_lev | MMCFIFOCTL_FIFODIR_WR;
  816. break;
  817. default:
  818. host->data_dir = DM365_MMC_DATADIR_READ;
  819. host->mmcsd_regs->MMCFIFOCTL = fifo_lev | MMCFIFOCTL_FIFODIR_RD | MMCFIFOCTL_FIFORST;
  820. host->mmcsd_regs->MMCFIFOCTL = fifo_lev | MMCFIFOCTL_FIFODIR_RD;
  821. break;
  822. }
  823. host->buffer = RT_NULL;
  824. host->bytes_left = data->blks * data->blksize;
  825. /* For now we try to use DMA whenever we won't need partial FIFO
  826. * reads or writes, either for the whole transfer (as tested here)
  827. * or for any individual scatterlist segment (tested when we call
  828. * start_dma_transfer).
  829. *
  830. * While we *could* change that, unusual block sizes are rarely
  831. * used. The occasional fallback to PIO should't hurt.
  832. */
  833. if ((host->use_dma == RT_TRUE) && (host->bytes_left & (rw_threshold - 1)) == 0 &&
  834. mmc_dm365_start_dma_transfer(host, data) == 0)
  835. {
  836. /* zero this to ensure we take no PIO paths */
  837. host->bytes_left = 0;
  838. }
  839. else
  840. {
  841. /* Revert to CPU Copy */
  842. host->buffer = (rt_uint8_t*)req->data->buf;
  843. }
  844. }
  845. /*******************************************************************************************************
  846. ** 函数名称: mmc_dm365_request()
  847. ** 功能描述: 此函数实现SD request操作
  848. **
  849. ** 输 入: host -> DM365 mmc host 句柄
  850. ** req -> SD request 结构句柄
  851. **
  852. ** 输 出: 无
  853. **
  854. ** 全局变量:
  855. ** 调用模块: 无
  856. **
  857. ********************************************************************************************************/
  858. static void mmc_dm365_request(struct rt_mmcsd_host *mmc, struct rt_mmcsd_req *req)
  859. {
  860. struct mmc_dm365_host *host = mmc_priv(mmc);
  861. unsigned long timeout = rt_tick_get() + 900;
  862. rt_uint32_t mmcst1 = 0;
  863. /* Card may still be sending BUSY after a previous operation,
  864. * typically some kind of write. If so, we can't proceed yet.
  865. */
  866. while (rt_tick_get() < timeout)
  867. {
  868. mmcst1 = host->mmcsd_regs->MMCST1;
  869. if (!(mmcst1 & MMCST1_BUSY))
  870. break;
  871. }
  872. if (mmcst1 & MMCST1_BUSY)
  873. {
  874. mmc_dbg("still BUSY? bad ... \n");
  875. req->cmd->err = -RT_ETIMEOUT;
  876. mmc_request_done(mmc, req);
  877. return;
  878. }
  879. host->do_dma = RT_FALSE;
  880. mmc_dm365_prepare_data(host, req);
  881. mmc_dm365_start_command(host, req->cmd);
  882. }
  883. static void mmc_dm365_enable_sdio_irq(struct rt_mmcsd_host *mmc, rt_int32_t enable)
  884. {
  885. struct mmc_dm365_host *host = mmc_priv(mmc);
  886. if (enable)
  887. {
  888. if (!(host->mmcsd_regs->SDIOST0 & SDIOST0_DAT1_HI))
  889. {
  890. host->mmcsd_regs->SDIOIST = SDIOIST_IOINT;
  891. sdio_irq_wakeup(host->mmc);
  892. }
  893. else
  894. {
  895. host->sdio_int = RT_TRUE;
  896. host->mmcsd_regs->SDIOIEN |= SDIOIEN_IOINTEN;
  897. }
  898. }
  899. else
  900. {
  901. host->sdio_int = RT_FALSE;
  902. host->mmcsd_regs->SDIOIEN &= ~SDIOIEN_IOINTEN;
  903. }
  904. }
  905. static const struct rt_mmcsd_host_ops mmc_dm365_ops =
  906. {
  907. mmc_dm365_request,
  908. mmc_dm365_set_ios,
  909. RT_NULL,
  910. mmc_dm365_enable_sdio_irq
  911. };
  912. /*******************************************************************************************************
  913. ** 函数名称: mmc_dm365_reset_ctrl()
  914. ** 功能描述: 此函数用于reset mmc控制器
  915. **
  916. ** 输 入: host -> DM365 mmc host 句柄
  917. ** val -> 判断做reset还是enable
  918. **
  919. ** 输 出: 无
  920. **
  921. ** 全局变量:
  922. ** 调用模块: 无
  923. **
  924. ********************************************************************************************************/
  925. static void mmc_dm365_reset_ctrl(struct mmc_dm365_host *host, int val)
  926. {
  927. rt_uint32_t temp;
  928. temp = host->mmcsd_regs->MMCCTL;
  929. if (val) /* reset */
  930. temp |= MMCCTL_CMDRST | MMCCTL_DATRST;
  931. else /* enable */
  932. temp &= ~(MMCCTL_CMDRST | MMCCTL_DATRST);
  933. host->mmcsd_regs->MMCCTL = temp;
  934. delay_us(10);
  935. }
  936. /*******************************************************************************************************
  937. ** 函数名称: init_mmcsd_host()
  938. ** 功能描述: 此函数用于初始化DM365 MMCSD控制器
  939. **
  940. ** 输 入: host -> DM365 mmc host 句柄
  941. **
  942. ** 输 出: 无
  943. **
  944. ** 全局变量:
  945. ** 调用模块: 无
  946. **
  947. ********************************************************************************************************/
  948. static void init_mmcsd_host(struct mmc_dm365_host *host)
  949. {
  950. mmc_dm365_reset_ctrl(host, 1);
  951. host->mmcsd_regs->MMCCLK = 0;
  952. host->mmcsd_regs->MMCCLK = MMCCLK_CLKEN;
  953. host->mmcsd_regs->MMCTOR = 0x1FFF;
  954. host->mmcsd_regs->MMCTOD = 0xFFFF;
  955. mmc_dm365_reset_ctrl(host, 0);
  956. }
  957. /*******************************************************************************************************
  958. ** 函数名称: mmc_dm365_cmd_done()
  959. ** 功能描述: 结束SD 命令后调用此函数
  960. **
  961. ** 输 入: host -> DM365 mmc host 句柄
  962. ** cmd -> SD 命令结构句柄
  963. **
  964. ** 输 出: 无
  965. **
  966. ** 全局变量:
  967. ** 调用模块: 无
  968. **
  969. ********************************************************************************************************/
  970. static void mmc_dm365_cmd_done(struct mmc_dm365_host *host, struct rt_mmcsd_cmd *cmd)
  971. {
  972. host->cmd = RT_NULL;
  973. if (resp_type(cmd) != RESP_NONE)
  974. {
  975. if (resp_type(cmd) == RESP_R2)
  976. {
  977. /* response type 2 */
  978. cmd->resp[3] = host->mmcsd_regs->MMCRSP01;
  979. cmd->resp[2] = host->mmcsd_regs->MMCRSP23;
  980. cmd->resp[1] = host->mmcsd_regs->MMCRSP45;
  981. cmd->resp[0] = host->mmcsd_regs->MMCRSP67;
  982. }
  983. else
  984. {
  985. /* response types 1, 1b, 3, 4, 5, 6 */
  986. cmd->resp[0] = host->mmcsd_regs->MMCRSP67;
  987. }
  988. }
  989. if (host->data == RT_NULL || cmd->err)
  990. {
  991. if (cmd->err == -RT_ETIMEOUT)
  992. cmd->mrq->cmd->retries = 0;
  993. mmc_request_done(host->mmc, cmd->mrq);
  994. host->mmcsd_regs->MMCIM = 0;
  995. }
  996. }
  997. /*******************************************************************************************************
  998. ** 函数名称: dm365_abort_data()
  999. ** 功能描述: 此函数用于终止数据传输
  1000. **
  1001. ** 输 入: host -> DM365 mmc host 句柄
  1002. ** data -> data 结构句柄
  1003. **
  1004. ** 输 出: 无
  1005. **
  1006. ** 全局变量:
  1007. ** 调用模块: 无
  1008. **
  1009. ********************************************************************************************************/
  1010. static void dm365_abort_data(struct mmc_dm365_host *host, struct rt_mmcsd_data *data)
  1011. {
  1012. mmc_dm365_reset_ctrl(host, 1);
  1013. mmc_dm365_reset_ctrl(host, 0);
  1014. }
  1015. static void mmc_dm365_sdio_irq(int irq, void *param)
  1016. {
  1017. struct mmc_dm365_host *host = (struct mmc_dm365_host *)param;
  1018. rt_uint32_t status;
  1019. status = host->mmcsd_regs->SDIOIST;//readl(host->base + DAVINCI_SDIOIST);
  1020. if (status & SDIOIST_IOINT) {
  1021. mmc_dbg("SDIO interrupt status %x\n", status);
  1022. //writel(status | SDIOIST_IOINT, host->base + DAVINCI_SDIOIST);
  1023. host->mmcsd_regs->SDIOIST = status | SDIOIST_IOINT;
  1024. sdio_irq_wakeup(host->mmc);
  1025. }
  1026. }
  1027. /*******************************************************************************************************
  1028. ** 函数名称: mmc_dm365_irq()
  1029. ** 功能描述: MMCSD的中断处理程序
  1030. **
  1031. ** 输 入: irq ->中断向量号
  1032. **
  1033. ** 输 出: 无
  1034. **
  1035. ** 全局变量:
  1036. ** 调用模块: 无
  1037. **
  1038. ********************************************************************************************************/
  1039. static void mmc_dm365_irq(int irq, void *param)
  1040. {
  1041. struct mmc_dm365_host *host = (struct mmc_dm365_host *)param;
  1042. rt_uint32_t status, qstatus;
  1043. int end_command = 0;
  1044. int end_transfer = 0;
  1045. struct rt_mmcsd_data *data = host->data;
  1046. if (host->cmd == RT_NULL && host->data == RT_NULL)
  1047. {
  1048. status = host->mmcsd_regs->MMCST0;
  1049. mmc_dbg("Spurious interrupt 0x%04x\n", status);
  1050. /* Disable the interrupt from mmcsd */
  1051. host->mmcsd_regs->MMCIM = 0;
  1052. return;
  1053. }
  1054. status = host->mmcsd_regs->MMCST0;
  1055. qstatus = status;
  1056. /* handle FIFO first when using PIO for data.
  1057. * bytes_left will decrease to zero as I/O progress and status will
  1058. * read zero over iteration because this controller status
  1059. * register(MMCST0) reports any status only once and it is cleared
  1060. * by read. So, it is not unbouned loop even in the case of
  1061. * non-dma.
  1062. */
  1063. while (host->bytes_left && (status & (MMCST0_DXRDY | MMCST0_DRRDY)))
  1064. {
  1065. dm365_fifo_data_trans(host, rw_threshold);
  1066. status = host->mmcsd_regs->MMCST0;
  1067. if (!status)
  1068. break;
  1069. qstatus |= status;
  1070. }
  1071. if (qstatus & MMCST0_DATDNE)
  1072. {
  1073. /* All blocks sent/received, and CRC checks passed */
  1074. if (data != RT_NULL)
  1075. {
  1076. if ((host->do_dma == RT_FALSE) && (host->bytes_left > 0))
  1077. {
  1078. /* if datasize < rw_threshold
  1079. * no RX ints are generated
  1080. */
  1081. rt_kprintf("to do! host->bytes_left=0x%x\n", host->bytes_left);
  1082. dm365_fifo_data_trans(host, host->bytes_left);
  1083. }
  1084. end_transfer = 1;
  1085. data->bytes_xfered = data->blks* data->blksize;
  1086. }
  1087. else
  1088. {
  1089. mmc_dbg("DATDNE with no host->data\n");
  1090. }
  1091. }
  1092. if (qstatus & MMCST0_TOUTRD)
  1093. {
  1094. /* Read data timeout */
  1095. data->err = -RT_ETIMEOUT;
  1096. end_transfer = 1;
  1097. mmc_dbg("read data timeout, status %x\n", qstatus);
  1098. rt_kprintf("read data timeout, status %x\n", qstatus);
  1099. dm365_abort_data(host, data);
  1100. }
  1101. if (qstatus & (MMCST0_CRCWR | MMCST0_CRCRD))
  1102. {
  1103. /* Data CRC error */
  1104. data->err = -RT_ERROR;
  1105. end_transfer = 1;
  1106. /* NOTE: this controller uses CRCWR to report both CRC
  1107. * errors and timeouts (on writes). MMCDRSP values are
  1108. * only weakly documented, but 0x9f was clearly a timeout
  1109. * case and the two three-bit patterns in various SD specs
  1110. * (101, 010) aren't part of it ...
  1111. */
  1112. if (qstatus & MMCST0_CRCWR)
  1113. {
  1114. rt_uint32_t temp = host->mmcsd_regs->MMCDRSP;
  1115. if (temp == 0x9f)
  1116. data->err = -RT_ETIMEOUT;
  1117. }
  1118. mmc_dbg("data %s %s error\n", (qstatus & MMCST0_CRCWR) ? "write" : "read", (data->err == -110) ? "timeout" : "CRC");
  1119. rt_kprintf("data %s %s error\n", (qstatus & MMCST0_CRCWR) ? "write" : "read", (data->err == -110) ? "timeout" : "CRC");
  1120. dm365_abort_data(host, data);
  1121. }
  1122. if (qstatus & MMCST0_TOUTRS)
  1123. {
  1124. /* Command timeout */
  1125. if (host->cmd)
  1126. {
  1127. mmc_dbg("CMD%d timeout, status %x\n", host->cmd->cmd_code, qstatus);
  1128. host->cmd->err = -RT_ETIMEOUT;
  1129. if (data)
  1130. {
  1131. end_transfer = 1;
  1132. dm365_abort_data(host, data);
  1133. }
  1134. else
  1135. end_command = 1;
  1136. }
  1137. }
  1138. if (qstatus & MMCST0_CRCRS)
  1139. {
  1140. /* Command CRC error */
  1141. mmc_dbg("Command CRC error\n");
  1142. if (host->cmd)
  1143. {
  1144. host->cmd->err = -RT_ERROR;
  1145. end_command = 1;
  1146. }
  1147. }
  1148. if (qstatus & MMCST0_RSPDNE)
  1149. {
  1150. /* End of command phase */
  1151. end_command = (int) host->cmd;
  1152. }
  1153. if (end_command)
  1154. mmc_dm365_cmd_done(host, host->cmd);
  1155. if (end_transfer)
  1156. mmc_dm365_xfer_done(host, data);
  1157. return;
  1158. }
  1159. #if 0
  1160. /*******************************************************************************************************
  1161. ** 函数名称: rt_hw_edma_init()
  1162. ** 功能描述: 此函数用于初始化EDMA3
  1163. **
  1164. ** 输 入: 无
  1165. **
  1166. ** 输 出: 无
  1167. **
  1168. ** 全局变量:
  1169. ** 调用模块: 无
  1170. **
  1171. ********************************************************************************************************/
  1172. static void rt_hw_edma_init(void)
  1173. {
  1174. psc_transition(PSC0, DOMAIN0, LPSC_TPCC, PSC_ENABLE);
  1175. psc_transition(PSC0, DOMAIN0, LPSC_TPTC0, PSC_ENABLE);
  1176. /* Initialization of EDMA3 */
  1177. edma3_init(EDMA0CC0_REG_BASE, EVT_QUEUE_NUM);
  1178. /* Register EDMA3 Interrupts */
  1179. // ConfigureAINTCIntEDMA3();
  1180. }
  1181. #endif
  1182. /*******************************************************************************************************
  1183. ** 函数名称: rt_hw_mmcsd_init()
  1184. ** 功能描述: 此函数用于初始化MMC驱动模块
  1185. **
  1186. ** 输 入: 无
  1187. **
  1188. ** 输 出: 如果初始化成功,返回0;如果初始化失败,返回-RT_ENOMEM
  1189. **
  1190. ** 全局变量:
  1191. ** 调用模块: 无
  1192. **
  1193. ********************************************************************************************************/
  1194. int rt_hw_mmcsd_init(void)
  1195. {
  1196. struct clk *clk;
  1197. struct mmc_dm365_host *dm365_host;
  1198. struct rt_mmcsd_host *mmc = RT_NULL;
  1199. mmc = mmcsd_alloc_host();
  1200. if (!mmc)
  1201. {
  1202. mmc_dbg("alloc mmc failed\n");
  1203. return -RT_ERROR;
  1204. }
  1205. dm365_host = rt_malloc(sizeof(struct mmc_dm365_host));
  1206. if (!dm365_host)
  1207. {
  1208. mmc_dbg("alloc mci failed\n");
  1209. goto err;
  1210. }
  1211. rt_memset(dm365_host, 0, sizeof(struct mmc_dm365_host));
  1212. #ifdef RT_USING_MMCSD0
  1213. //psc_transition(PSC0, DOMAIN0, LPSC_MMCSD0, PSC_ENABLE);
  1214. //pinmux_config(PINMUX_MMCSD0_REG, PINMUX_MMCSD0_MASK, PINMUX_MMCSD0_VAL);
  1215. psc_change_state(DAVINCI_DM365_LPSC_MMC_SD0, PSC_ENABLE);
  1216. dm365_host->mmcsd_regs = (mmcsd_regs_t *)DM365_MMC_SD0_BASE;
  1217. #else
  1218. #ifdef RT_USING_MMCSD1
  1219. psc_transition(PSC1, DOMAIN0, LPSC_MMCSD1, PSC_ENABLE);
  1220. pinmux_config(PINMUX_MMCSD1_REG, PINMUX_MMCSD1_MASK, PINMUX_MMCSD1_VAL);
  1221. dm365_host->mmcsd_regs = MMCSD1;
  1222. #endif
  1223. #endif
  1224. //rt_hw_edma_init();
  1225. clk = clk_get("MMCSDCLK0");
  1226. dm365_host->mmc_input_clk = clk_get_rate(clk);
  1227. dm365_host->rxdma = DM365_DMA_MMC0RXEVT;
  1228. dm365_host->txdma = DM365_DMA_MMC0TXEVT;
  1229. dm365_host->use_dma = use_dma;
  1230. if ((dm365_host->use_dma == RT_TRUE)&& acquire_dma_channels(dm365_host) != 0)
  1231. {
  1232. dm365_host->use_dma = RT_FALSE;
  1233. }
  1234. else
  1235. {
  1236. dm365_host->dma_buffer = (rt_uint8_t*)rt_malloc_align(64*1024, 32);
  1237. if (dm365_host->dma_buffer == RT_NULL)
  1238. dm365_host->use_dma = RT_FALSE;
  1239. }
  1240. mmc->ops = &mmc_dm365_ops;
  1241. mmc->freq_min = 312500;
  1242. mmc->freq_max = 25000000;
  1243. mmc->valid_ocr = VDD_32_33 | VDD_33_34;
  1244. mmc->flags = MMCSD_BUSWIDTH_4 | MMCSD_MUTBLKWRITE;
  1245. mmc->flags |= MMCSD_SUP_SDIO_IRQ;
  1246. dm365_host->mmc = mmc;
  1247. mmc->private_data = dm365_host;
  1248. /* install interrupt */
  1249. #ifdef RT_USING_MMCSD0
  1250. rt_hw_interrupt_install(IRQ_DM3XX_MMCINT0, mmc_dm365_irq,
  1251. (void *)dm365_host, "MMC0");
  1252. rt_hw_interrupt_umask(IRQ_DM3XX_MMCINT0);
  1253. rt_hw_interrupt_install(IRQ_DM3XX_SDIOINT0, mmc_dm365_sdio_irq,
  1254. (void *)dm365_host, "SDIO0");
  1255. rt_hw_interrupt_umask(IRQ_DM3XX_SDIOINT0);
  1256. #endif
  1257. #ifdef RT_USING_MMCSD1
  1258. rt_hw_interrupt_install(MMCSD_INT1, mmc_dm365_irq,
  1259. (void *)dm365_host, "MMC1");
  1260. rt_hw_interrupt_umask(MMCSD_INT1);
  1261. #endif
  1262. init_mmcsd_host(dm365_host);
  1263. mmcsd_change(mmc);
  1264. return 0;
  1265. err:
  1266. mmcsd_free_host(mmc);
  1267. return -RT_ENOMEM;
  1268. }
  1269. INIT_DEVICE_EXPORT(rt_hw_mmcsd_init);