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