drv_sdio.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794
  1. /*
  2. * File : drv_sdio.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2017, 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. * 2018-02-08 RT-Thread the first version
  23. */
  24. #include <rtthread.h>
  25. #include <rthw.h>
  26. #include <rtdevice.h>
  27. #include <string.h>
  28. #include "drv_sdio.h"
  29. #include "interrupt.h"
  30. #include "mmu.h"
  31. #include "drv_gpio.h"
  32. #include "drv_clock.h"
  33. #define DBG_TAG "MMC"
  34. // #define DBG_LVL DBG_LOG
  35. // #define DBG_LVL DBG_INFO
  36. #define DBG_LVL DBG_WARNING
  37. // #define DBG_LVL DBG_ERROR
  38. #include <rtdbg.h>
  39. #ifdef RT_USING_SDIO
  40. #define CONFIG_MMC_USE_DMA
  41. #define DMA_ALIGN (32U)
  42. struct mmc_xfe_des
  43. {
  44. rt_uint32_t size; /* block size */
  45. rt_uint32_t num; /* block num */
  46. rt_uint8_t *buff; /* buff addr */
  47. rt_uint32_t flag; /* write or read or stream */
  48. #define MMC_DATA_WRITE (1 << 0)
  49. #define MMC_DATA_READ (1 << 1)
  50. #define MMC_DATA_STREAM (1 << 2)
  51. };
  52. struct mmc_flag
  53. {
  54. volatile rt_uint32_t risr;
  55. volatile rt_uint32_t idst;
  56. };
  57. struct sdio_drv
  58. {
  59. struct rt_mmcsd_host *host;
  60. struct rt_mmcsd_req *req;
  61. struct rt_semaphore rt_sem;
  62. struct mmc_xfe_des xfe;
  63. struct mmc_flag flag;
  64. tina_mmc_t mmc_des;
  65. rt_uint8_t *mmc_buf;
  66. rt_uint8_t usedma;
  67. };
  68. #ifdef CONFIG_MMC_USE_DMA
  69. #ifdef TINA_USING_SDIO0
  70. ALIGN(32) static rt_uint8_t dma_buffer[64 * 1024];
  71. #endif
  72. #endif
  73. static void mmc_request_end(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req);
  74. static void mmc_delay_us(int us)
  75. {
  76. volatile unsigned int temp;
  77. while (us--)
  78. {
  79. temp = 0x2f;
  80. while (temp--)
  81. {
  82. temp = temp;
  83. };
  84. }
  85. }
  86. static void mmc_dump_errinfo(unsigned int err)
  87. {
  88. LOG_E("[err]:0x%08x, %s%s%s%s%s%s%s%s%s%s%s",
  89. err,
  90. err & SDXC_RespErr ? " RE" : "",
  91. err & SDXC_RespCRCErr ? " RCE" : "",
  92. err & SDXC_DataCRCErr ? " DCE" : "",
  93. err & SDXC_RespTimeout ? " RTO" : "",
  94. err & SDXC_DataTimeout ? " DTO" : "",
  95. err & SDXC_DataStarve ? " DS" : "",
  96. err & SDXC_FIFORunErr ? " FE" : "",
  97. err & SDXC_HardWLocked ? " HL" : "",
  98. err & SDXC_StartBitErr ? " SBE" : "",
  99. err & SDXC_EndBitErr ? " EBE" : "",
  100. err == 0 ? " STO" : ""
  101. );
  102. }
  103. static int mmc_update_clk(tina_mmc_t mmc)
  104. {
  105. rt_uint32_t cmd;
  106. rt_uint32_t timeout = 2000000;
  107. /* cmd load */
  108. cmd = SDXC_LOAD_CMD | SDXC_UPDATE_CLOCK_CMD | SDXC_WAIT_OVER_CMD;
  109. mmc->cmdr_reg = cmd;
  110. /* while load success */
  111. while ((mmc->cmdr_reg & SDXC_LOAD_CMD) && (--timeout))
  112. {
  113. mmc_delay_us(1);
  114. }
  115. if (!timeout)
  116. {
  117. LOG_E("mmc update clk failed");
  118. return -RT_ERROR;
  119. }
  120. /* clean interrupt */
  121. mmc->risr_reg = mmc->risr_reg;
  122. return RT_EOK;
  123. }
  124. static rt_err_t mmc_trans_data_by_dma(tina_mmc_t mmc, struct mmc_xfe_des *xfe)
  125. {
  126. ALIGN(32) static struct mmc_des_v4p1 pdes[128]; // mast ALIGN(32)
  127. unsigned i, rval;
  128. unsigned des_idx;
  129. unsigned length = xfe->size * xfe->num;
  130. unsigned buff_frag_num = length >> SDXC_DES_NUM_SHIFT;
  131. unsigned remain = length & (SDXC_DES_BUFFER_MAX_LEN - 1);
  132. if (remain)
  133. {
  134. buff_frag_num ++;
  135. }
  136. else
  137. {
  138. remain = SDXC_DES_BUFFER_MAX_LEN;
  139. }
  140. memset(pdes, 0, sizeof(pdes));
  141. mmu_clean_dcache((rt_uint32_t)(xfe->buff), length);
  142. for (i = 0, des_idx = 0; i < buff_frag_num; i++, des_idx++)
  143. {
  144. // memset((void*)&pdes[des_idx], 0, sizeof(struct mmc_v4p1));
  145. pdes[des_idx].des_chain = 1;
  146. pdes[des_idx].own = 1;
  147. pdes[des_idx].dic = 1;
  148. if ((buff_frag_num > 1) && (i != buff_frag_num - 1))
  149. {
  150. pdes[des_idx].data_buf1_sz = SDXC_DES_BUFFER_MAX_LEN;
  151. }
  152. else
  153. {
  154. pdes[des_idx].data_buf1_sz = remain;
  155. }
  156. pdes[des_idx].buf_addr_ptr1 = (unsigned long)(xfe->buff) + i * SDXC_DES_BUFFER_MAX_LEN;
  157. if (i == 0)
  158. {
  159. pdes[des_idx].first_des = 1;
  160. }
  161. if (i == (buff_frag_num - 1))
  162. {
  163. pdes[des_idx].dic = 0;
  164. pdes[des_idx].last_des = 1;
  165. pdes[des_idx].end_of_ring = 1;
  166. pdes[des_idx].buf_addr_ptr2 = 0;
  167. }
  168. else
  169. {
  170. pdes[des_idx].buf_addr_ptr2 = (unsigned long)&pdes[des_idx+1];
  171. }
  172. LOG_D("frag %d, remain %d, des[%d](%08x): " \
  173. "[0] = %08x, [1] = %08x, [2] = %08x, [3] = %08x", \
  174. i, remain, des_idx, (unsigned int)&pdes[des_idx],
  175. (unsigned int)((unsigned int*)&pdes[des_idx])[0], (unsigned int)((unsigned int*)&pdes[des_idx])[1],
  176. (unsigned int)((unsigned int*)&pdes[des_idx])[2], (unsigned int)((unsigned int*)&pdes[des_idx])[3]);
  177. }
  178. mmu_clean_dcache((rt_uint32_t)pdes, sizeof(struct mmc_des_v4p1) * (des_idx + 1));
  179. /*
  180. * GCTRLREG
  181. * GCTRL[2] : DMA reset
  182. * GCTRL[5] : DMA enable
  183. *
  184. * IDMACREG
  185. * IDMAC[0] : IDMA soft reset
  186. * IDMAC[1] : IDMA fix burst flag
  187. * IDMAC[7] : IDMA on
  188. *
  189. * IDIECREG
  190. * IDIE[0] : IDMA transmit interrupt flag
  191. * IDIE[1] : IDMA receive interrupt flag
  192. */
  193. rval = mmc->gctl_reg;
  194. mmc->gctl_reg = rval | (1 << 5) | (1 << 2); /* dma enable */
  195. mmc->dmac_reg = (1 << 0); /* idma reset */
  196. while(mmc->dmac_reg & 0x1) {}; /* wait idma reset done */
  197. mmc->dmac_reg = (1 << 1) | (1 << 7); /* idma on */
  198. rval = mmc->idie_reg & (~3);
  199. if (xfe->flag == MMC_DATA_WRITE)
  200. rval |= (1 << 0);
  201. else
  202. rval |= (1 << 1);
  203. mmc->idie_reg = rval;
  204. mmc->dlba_reg = (unsigned long)pdes;
  205. mmc->fwlr_reg = (2U << 28) | (7U << 16) | 8;
  206. return 0;
  207. }
  208. static rt_err_t mmc_trans_data_by_cpu(tina_mmc_t mmc, struct mmc_xfe_des *xfe)
  209. {
  210. unsigned i;
  211. unsigned byte_cnt = xfe->size * xfe->num;
  212. unsigned *buff = (unsigned *)(xfe->buff);
  213. volatile unsigned timeout = 2000000;
  214. if (xfe->flag == MMC_DATA_WRITE)
  215. {
  216. for (i = 0; i < (byte_cnt >> 2); i++)
  217. {
  218. while(--timeout && (mmc->star_reg & (1 << 3)));
  219. if (timeout <= 0)
  220. {
  221. LOG_E("write data by cpu failed status:0x%08x", mmc->star_reg);
  222. return -RT_ERROR;
  223. }
  224. mmc->fifo_reg = buff[i];
  225. timeout = 2000000;
  226. }
  227. }
  228. else
  229. {
  230. for (i = 0; i < (byte_cnt >> 2); i++)
  231. {
  232. while(--timeout && (mmc->star_reg & (1 << 2)));
  233. if (timeout <= 0)
  234. {
  235. LOG_E("read data by cpu failed status:0x%08x", mmc->star_reg);
  236. return -RT_ERROR;
  237. }
  238. buff[i] = mmc->fifo_reg;
  239. timeout = 2000000;
  240. }
  241. }
  242. return RT_EOK;
  243. }
  244. static rt_err_t mmc_config_clock(tina_mmc_t mmc, int clk)
  245. {
  246. rt_uint32_t rval = 0;
  247. /* disable card clock */
  248. rval = mmc->ckcr_reg;
  249. rval &= ~(1 << 16);
  250. mmc->ckcr_reg = rval;
  251. if (mmc_update_clk(mmc) != RT_EOK)
  252. {
  253. LOG_E("clk update fail line:%d", __LINE__);
  254. return -RT_ERROR;
  255. }
  256. if (mmc == MMC0)
  257. {
  258. mmc_set_clk(SDMMC0, clk);
  259. }
  260. else
  261. {
  262. mmc_set_clk(SDMMC1, clk);
  263. }
  264. /* Re-enable card clock */
  265. rval = mmc->ckcr_reg;
  266. rval |= (0x1 << 16); //(3 << 16);
  267. mmc->ckcr_reg = rval;
  268. if(mmc_update_clk(mmc) != RT_EOK)
  269. {
  270. LOG_E("clk update fail line:%d", __LINE__);
  271. return -RT_ERROR;
  272. }
  273. return RT_EOK;
  274. }
  275. static rt_err_t mmc_set_ios(tina_mmc_t mmc, int clk, int bus_width)
  276. {
  277. LOG_D("mmc set io bus width:%d clock:%d", \
  278. (bus_width == MMCSD_BUS_WIDTH_8 ? 8 : (bus_width == MMCSD_BUS_WIDTH_4 ? 4 : 1)), clk);
  279. /* change clock */
  280. if (clk && (mmc_config_clock(mmc, clk) != RT_EOK))
  281. {
  282. LOG_E("update clock failed");
  283. return -RT_ERROR;
  284. }
  285. /* Change bus width */
  286. if (bus_width == MMCSD_BUS_WIDTH_8)
  287. {
  288. mmc->bwdr_reg = 2;
  289. }
  290. else if (bus_width == MMCSD_BUS_WIDTH_4)
  291. {
  292. mmc->bwdr_reg = 1;
  293. }
  294. else
  295. {
  296. mmc->bwdr_reg = 0;
  297. }
  298. return RT_EOK;
  299. }
  300. static int mmc_send_cmd(struct rt_mmcsd_host *host, struct rt_mmcsd_cmd *cmd)
  301. {
  302. unsigned int cmdval = 0x80000000;
  303. signed int timeout = 0;
  304. int err = 0;
  305. unsigned int status = 0;
  306. struct rt_mmcsd_data *data = cmd->data;
  307. unsigned int bytecnt = 0;
  308. struct sdio_drv *sdio_des = (struct sdio_drv *)host->private_data;
  309. tina_mmc_t mmc = sdio_des->mmc_des;
  310. timeout = 5000 * 1000;
  311. status = mmc->star_reg;
  312. while (status & (1 << 9))
  313. {
  314. LOG_D("note: check card busy");
  315. status = mmc->star_reg;
  316. if (!timeout--)
  317. {
  318. err = -1;
  319. LOG_E("mmc cmd12 busy timeout data:0x%08x", status);
  320. return err;
  321. }
  322. mmc_delay_us(1);
  323. }
  324. /*
  325. * CMDREG
  326. * CMD[5:0] : Command index
  327. * CMD[6] : Has response
  328. * CMD[7] : Long response
  329. * CMD[8] : Check response CRC
  330. * CMD[9] : Has data
  331. * CMD[10] : Write
  332. * CMD[11] : Steam mode
  333. * CMD[12] : Auto stop
  334. * CMD[13] : Wait previous over
  335. * CMD[14] : About cmd
  336. * CMD[15] : Send initialization
  337. * CMD[21] : Update clock
  338. * CMD[31] : Load cmd
  339. */
  340. if (!cmd->cmd_code)
  341. cmdval |= (1 << 15);
  342. if (resp_type(cmd) != RESP_NONE)
  343. cmdval |= (1 << 6);
  344. if (resp_type(cmd) == RESP_R2)
  345. cmdval |= (1 << 7);
  346. if ((resp_type(cmd) != RESP_R3) && (resp_type(cmd) != RESP_R4))
  347. cmdval |= (1 << 8);
  348. if (data)
  349. {
  350. cmdval |= (1 << 9) | (1 << 13);
  351. if (data->flags & DATA_DIR_WRITE)
  352. cmdval |= (1 << 10);
  353. if (data->blks > 1)
  354. cmdval |= (1 << 12);
  355. mmc->bksr_reg = data->blksize;
  356. bytecnt = data->blksize * data->blks;
  357. mmc->bycr_reg = bytecnt;
  358. }
  359. LOG_D("cmd %d(0x%08x), arg 0x%08x", cmd->cmd_code, cmdval | cmd->cmd_code, cmd->arg);
  360. mmc->cagr_reg = cmd->arg;
  361. if (!data)
  362. {
  363. mmc->cmdr_reg = cmdval | cmd->cmd_code;
  364. mmc->imkr_reg |= 0x1 << 2;
  365. }
  366. /*
  367. * transfer data and check status
  368. * STATREG[2] : FIFO empty
  369. * STATREG[3] : FIFO full
  370. */
  371. if (data)
  372. {
  373. LOG_D("mmc trans data %d bytes addr:0x%08x", bytecnt, data);
  374. #ifdef CONFIG_MMC_USE_DMA
  375. if (bytecnt > 64)
  376. {
  377. #else
  378. if (0)
  379. {
  380. #endif
  381. sdio_des->usedma = 1;
  382. mmc->gctl_reg = mmc->gctl_reg & (~0x80000000);
  383. mmc_trans_data_by_dma(mmc, &sdio_des->xfe);
  384. mmc->cmdr_reg = cmdval | cmd->cmd_code;
  385. }
  386. else
  387. {
  388. sdio_des->usedma = 0;
  389. mmc->gctl_reg = mmc->gctl_reg | 0x80000000;
  390. mmc->cmdr_reg = cmdval | cmd->cmd_code;
  391. mmc_trans_data_by_cpu(mmc, &sdio_des->xfe);
  392. }
  393. if (data->blks > 1)
  394. {
  395. mmc->imkr_reg |= (0x1 << 14);
  396. }
  397. else
  398. {
  399. mmc->imkr_reg |= (0x1 << 3);
  400. }
  401. }
  402. mmc->imkr_reg |= 0xbfc2;
  403. if (data)
  404. {
  405. //TODO:2 * bytecnt * 4?
  406. timeout = sdio_des->usedma ? (2 * bytecnt * 4) : 100; //0.04us(25M)*2(4bit width)*25()
  407. if (timeout < 10)
  408. {
  409. timeout = 10;
  410. }
  411. }
  412. else
  413. {
  414. timeout = 200;
  415. }
  416. if (rt_sem_take(&sdio_des->rt_sem, timeout) != RT_EOK)
  417. {
  418. err = (mmc->risr_reg | sdio_des->flag.risr) & 0xbfc2;
  419. goto out;
  420. }
  421. err = (mmc->risr_reg | sdio_des->flag.risr) & 0xbfc2;
  422. if (err)
  423. {
  424. cmd->err = -RT_ETIMEOUT;
  425. goto out;
  426. }
  427. if (resp_type(cmd) == RESP_R2)
  428. {
  429. cmd->resp[3] = mmc->resp0_reg;
  430. cmd->resp[2] = mmc->resp1_reg;
  431. cmd->resp[1] = mmc->resp2_reg;
  432. cmd->resp[0] = mmc->resp3_reg;
  433. LOG_D("mmc resp 0x%08x 0x%08x 0x%08x 0x%08x",
  434. cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
  435. }
  436. else
  437. {
  438. cmd->resp[0] = mmc->resp0_reg;
  439. LOG_D("mmc resp 0x%08x", cmd->resp[0]);
  440. }
  441. out:
  442. if (err)
  443. {
  444. mmc_dump_errinfo(err & 0xbfc2);
  445. }
  446. if (data && sdio_des->usedma)
  447. {
  448. /* IDMASTAREG
  449. * IDST[0] : idma tx int
  450. * IDST[1] : idma rx int
  451. * IDST[2] : idma fatal bus error
  452. * IDST[4] : idma descriptor invalid
  453. * IDST[5] : idma error summary
  454. * IDST[8] : idma normal interrupt sumary
  455. * IDST[9] : idma abnormal interrupt sumary
  456. */
  457. status = mmc->idst_reg;
  458. mmc->idst_reg = status;
  459. mmc->idie_reg = 0;
  460. mmc->dmac_reg = 0;
  461. mmc->gctl_reg = mmc->gctl_reg & (~(1 << 5));
  462. }
  463. if (err)
  464. {
  465. if (data && (data->flags & DATA_DIR_READ) && (bytecnt == 512))
  466. {
  467. mmc->gctl_reg = mmc->gctl_reg | 0x80000000;
  468. mmc->dbgc_reg = 0xdeb;
  469. timeout = 1000;
  470. LOG_D("Read remain data");
  471. while (mmc->bbcr_reg < 512)
  472. {
  473. unsigned int tmp = mmc->fifo_reg;
  474. tmp = tmp;
  475. LOG_D("Read data 0x%08x, bbcr 0x%04x", tmp, mmc->bbcr_reg);
  476. mmc_delay_us(1);
  477. if (!(timeout--))
  478. {
  479. LOG_E("Read remain data timeout");
  480. break;
  481. }
  482. }
  483. }
  484. mmc->gctl_reg = 0x7;
  485. while (mmc->gctl_reg & 0x7) { };
  486. mmc_update_clk(mmc);
  487. cmd->err = -RT_ETIMEOUT;
  488. LOG_E("mmc cmd %d err", cmd->cmd_code);
  489. }
  490. mmc->gctl_reg &= ~(0x1 << 4);
  491. mmc->imkr_reg &= ~0xffff;
  492. mmc->risr_reg = 0xffffffff;
  493. mmc->gctl_reg |= 0x1 << 4;
  494. while (!rt_sem_take(&sdio_des->rt_sem, 0)) {}
  495. mmc_request_end(sdio_des->host, sdio_des->req);
  496. return err;
  497. }
  498. static void mmc_request_end(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
  499. {
  500. struct rt_mmcsd_data *data;
  501. unsigned byte_cnt;
  502. struct sdio_drv *sdio = (struct sdio_drv *)host->private_data;
  503. #ifdef CONFIG_MMC_USE_DMA
  504. data = req->cmd->data;
  505. if (data)
  506. {
  507. byte_cnt = data->blksize * data->blks;
  508. if ((byte_cnt > 64) && (data->flags & DATA_DIR_READ))
  509. {
  510. mmu_invalidate_dcache((rt_uint32_t)sdio->xfe.buff, (rt_uint32_t)byte_cnt);
  511. if (((rt_uint32_t)data->buf) & (DMA_ALIGN - 1))
  512. {
  513. memcpy(data->buf, sdio->xfe.buff, byte_cnt);
  514. }
  515. }
  516. }
  517. #endif
  518. mmcsd_req_complete(host);
  519. }
  520. static void sdio_request_send(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
  521. {
  522. struct rt_mmcsd_data *data;
  523. int byte_cnt;
  524. struct sdio_drv *sdio;
  525. sdio = (struct sdio_drv *)host->private_data;
  526. sdio->req = req;
  527. data = req->cmd->data;
  528. if (data)
  529. {
  530. sdio->xfe.size = data->blksize;
  531. sdio->xfe.num = data->blks;
  532. sdio->xfe.buff = (rt_uint8_t *)data->buf;
  533. sdio->xfe.flag = (data->flags & DATA_DIR_WRITE) ? \
  534. MMC_DATA_WRITE : MMC_DATA_READ;
  535. #ifdef CONFIG_MMC_USE_DMA
  536. byte_cnt = data->blksize * data->blks;
  537. if ((byte_cnt > 64) && (((rt_uint32_t)data->buf) & (DMA_ALIGN - 1)))
  538. {
  539. sdio->xfe.buff = (rt_uint8_t *)sdio->mmc_buf;
  540. if (data->flags & DATA_DIR_WRITE)
  541. {
  542. memcpy(sdio->mmc_buf, data->buf, byte_cnt);
  543. mmu_clean_dcache((rt_uint32_t)sdio->mmc_buf, (rt_uint32_t)byte_cnt);
  544. }
  545. }
  546. #endif
  547. }
  548. memset(&sdio->flag, 0, sizeof(struct mmc_flag));
  549. mmc_send_cmd(host, req->cmd);
  550. return;
  551. }
  552. static void sdio_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
  553. {
  554. int clk = io_cfg->clock;
  555. int width = io_cfg->bus_width;
  556. struct sdio_drv *sdio_des = (struct sdio_drv *)host->private_data;
  557. tina_mmc_t mmc = sdio_des->mmc_des;
  558. mmc_set_ios(mmc, clk, width);
  559. }
  560. static const struct rt_mmcsd_host_ops ops =
  561. {
  562. sdio_request_send,
  563. sdio_set_iocfg,
  564. RT_NULL,
  565. RT_NULL,
  566. };
  567. static void sdio_interrupt_handle(int irqno, void *param)
  568. {
  569. rt_uint32_t risr, idst;
  570. rt_uint32_t status;
  571. struct sdio_drv *sdio_des = (struct sdio_drv *)param;
  572. struct rt_mmcsd_data *data = sdio_des->req->cmd->data;
  573. tina_mmc_t mmc = sdio_des->mmc_des;
  574. risr = mmc->risr_reg;
  575. idst = mmc->idst_reg;
  576. mmc->risr_reg = risr & mmc->imkr_reg;
  577. mmc->idst_reg = idst & mmc->idie_reg;
  578. sdio_des->flag.risr |= risr;
  579. sdio_des->flag.idst |= idst;
  580. if (data)
  581. {
  582. int done = 0;
  583. status = sdio_des->flag.risr | mmc->risr_reg;
  584. if (data->blks > 1)//not wait auto stop when MMC_CMD_MANUAL is set
  585. {
  586. if (sdio_des->usedma)
  587. done = ((status & (1 << 14)) && (sdio_des->flag.idst & 0x3)) ? 1 : 0;
  588. else
  589. done = status & (1 << 14);
  590. }
  591. else
  592. {
  593. if (sdio_des->usedma)
  594. done = ((status & (1 << 3)) && (sdio_des->flag.idst & 0x3)) ? 1 : 0;
  595. else
  596. done = status & (1 << 3);
  597. }
  598. if (done)
  599. {
  600. rt_sem_release(&sdio_des->rt_sem);
  601. }
  602. }
  603. else
  604. {
  605. rt_sem_release(&sdio_des->rt_sem);
  606. }
  607. }
  608. static void sdio_gpio_init(struct sdio_drv *sdio_des)
  609. {
  610. int pin;
  611. if ((rt_uint32_t)sdio_des->mmc_des == MMC0_BASE_ADDR)
  612. {
  613. /* SDC0: PF0-PF5 */
  614. for (pin = GPIO_PIN_0; pin <= GPIO_PIN_5; pin++)
  615. {
  616. gpio_set_func(GPIO_PORT_F, pin, IO_FUN_1);
  617. gpio_set_pull_mode(GPIO_PORT_F, pin, PULL_UP);
  618. gpio_set_drive_level(GPIO_PORT_F, pin, DRV_LEVEL_2);
  619. }
  620. }
  621. else if ((rt_uint32_t)sdio_des->mmc_des == MMC1_BASE_ADDR)
  622. {
  623. //todo: config gpio port
  624. RT_ASSERT(0);
  625. }
  626. }
  627. static void sdio_clk_io_on(struct sdio_drv *sdio_des)
  628. {
  629. if ((rt_uint32_t)sdio_des->mmc_des == MMC0_BASE_ADDR)
  630. {
  631. CCU->bus_clk_gating0 |= 0x1 << 8;
  632. CCU->bus_soft_rst0 |= 0x1 << 8;
  633. }
  634. else if ((rt_uint32_t)sdio_des->mmc_des == MMC1_BASE_ADDR)
  635. {
  636. CCU->bus_clk_gating0 |= 0x1 << 9;
  637. CCU->bus_soft_rst0 |= 0x1 << 9;
  638. }
  639. mmc_set_clk(SDMMC0, 24000000);
  640. }
  641. static void sdio_irq_init(void *param)
  642. {
  643. struct sdio_drv *sdio_des = (struct sdio_drv *)param;
  644. if ((rt_uint32_t)sdio_des->mmc_des == MMC0_BASE_ADDR)
  645. {
  646. rt_hw_interrupt_install(SDC0_INTERRUPT, sdio_interrupt_handle, param, "mmc0_irq");
  647. rt_hw_interrupt_umask(SDC0_INTERRUPT);
  648. }
  649. else if ((rt_uint32_t)sdio_des->mmc_des == MMC1_BASE_ADDR)
  650. {
  651. rt_hw_interrupt_install(SDC1_INTERRUPT, sdio_interrupt_handle, param, "mmc1_irq");
  652. rt_hw_interrupt_umask(SDC1_INTERRUPT);
  653. }
  654. sdio_des->mmc_des->gctl_reg |= (0x1 << 4);
  655. }
  656. int tina_sdio_init(void)
  657. {
  658. struct rt_mmcsd_host *host;
  659. #ifdef TINA_USING_SDIO0
  660. {
  661. static struct sdio_drv _sdio_drv;
  662. host = mmcsd_alloc_host();
  663. if (!host)
  664. {
  665. LOG_E("alloc host failed");
  666. goto err;
  667. }
  668. if (rt_sem_init(&_sdio_drv.rt_sem, "sdio_sem", RT_NULL, RT_IPC_FLAG_FIFO))
  669. {
  670. LOG_E("sem init failed");
  671. goto err;
  672. }
  673. _sdio_drv.mmc_des = (tina_mmc_t)MMC0_BASE_ADDR;
  674. _sdio_drv.mmc_buf = dma_buffer;
  675. //init gpio pin
  676. sdio_gpio_init(&_sdio_drv);
  677. //clk is on
  678. sdio_clk_io_on(&_sdio_drv);
  679. //irq init
  680. sdio_irq_init(&_sdio_drv);
  681. host->ops = &ops;
  682. host->freq_min = 400 * 1000;
  683. host->freq_max = 50 * 1000 * 1000;
  684. host->valid_ocr = VDD_26_27 | VDD_27_28 | VDD_28_29 | VDD_29_30 | VDD_30_31 | VDD_31_32 |
  685. VDD_32_33 | VDD_33_34 | VDD_34_35 | VDD_35_36;
  686. host->flags = MMCSD_BUSWIDTH_4 | MMCSD_MUTBLKWRITE | MMCSD_SUP_SDIO_IRQ | MMCSD_SUP_HIGHSPEED;
  687. host->max_seg_size = 2048;
  688. host->max_dma_segs = 10;
  689. host->max_blk_size = 512;
  690. host->max_blk_count = 4096;
  691. host->private_data = &_sdio_drv;
  692. _sdio_drv.host = host;
  693. mmcsd_change(host);
  694. }
  695. #endif
  696. return RT_EOK;
  697. err:
  698. if (host)
  699. {
  700. rt_free(host);
  701. }
  702. return RT_ERROR;
  703. }
  704. INIT_APP_EXPORT(tina_sdio_init);
  705. #endif