mmcsd.c 38 KB

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