1 /*
2  * File      : drv_sdio.c
3  * Copyright (c) 2006-2021, RT-Thread Development Team
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Change Logs:
8  * Date           Author         Notes
9  * 2019-07-29     zdzn           first version
10  */
11 
12 #include "drv_sdio.h"
13 #include "raspi.h"
14 
15 static rt_uint32_t sdCommandTable[] = {
16     SD_CMD_INDEX(0),
17     SD_CMD_RESERVED(1),
18     SD_CMD_INDEX(2) | SD_RESP_R2,
19     SD_CMD_INDEX(3) | SD_RESP_R1,
20     SD_CMD_INDEX(4),
21     SD_CMD_RESERVED(5), //SD_CMD_INDEX(5) | SD_RESP_R4,
22     SD_CMD_INDEX(6) | SD_RESP_R1,
23     SD_CMD_INDEX(7) | SD_RESP_R1b,
24     SD_CMD_INDEX(8) | SD_RESP_R1,
25     SD_CMD_INDEX(9) | SD_RESP_R2,
26     SD_CMD_INDEX(10) | SD_RESP_R2,
27     SD_CMD_INDEX(11) | SD_RESP_R1,
28     SD_CMD_INDEX(12) | SD_RESP_R1b | SD_CMD_TYPE_ABORT,
29     SD_CMD_INDEX(13) | SD_RESP_R1,
30     SD_CMD_RESERVED(14),
31     SD_CMD_INDEX(15),
32     SD_CMD_INDEX(16) | SD_RESP_R1,
33     SD_CMD_INDEX(17) | SD_RESP_R1 | SD_DATA_READ,
34     SD_CMD_INDEX(18) | SD_RESP_R1 | SD_DATA_READ | SD_CMD_MULTI_BLOCK | SD_CMD_BLKCNT_EN,
35     SD_CMD_INDEX(19) | SD_RESP_R1 | SD_DATA_READ,
36     SD_CMD_INDEX(20) | SD_RESP_R1b,
37     SD_CMD_RESERVED(21),
38     SD_CMD_RESERVED(22),
39     SD_CMD_INDEX(23) | SD_RESP_R1,
40     SD_CMD_INDEX(24) | SD_RESP_R1 | SD_DATA_WRITE,
41     SD_CMD_INDEX(25) | SD_RESP_R1 | SD_DATA_WRITE | SD_CMD_MULTI_BLOCK | SD_CMD_BLKCNT_EN,
42     SD_CMD_INDEX(26) | SD_RESP_R1 | SD_DATA_WRITE, //add
43     SD_CMD_INDEX(27) | SD_RESP_R1 | SD_DATA_WRITE,
44     SD_CMD_INDEX(28) | SD_RESP_R1b,
45     SD_CMD_INDEX(29) | SD_RESP_R1b,
46     SD_CMD_INDEX(30) | SD_RESP_R1 | SD_DATA_READ,
47     SD_CMD_RESERVED(31),
48     SD_CMD_INDEX(32) | SD_RESP_R1,
49     SD_CMD_INDEX(33) | SD_RESP_R1,
50     SD_CMD_RESERVED(34),
51     SD_CMD_INDEX(35) | SD_RESP_R1, //add
52     SD_CMD_INDEX(36) | SD_RESP_R1, //add
53     SD_CMD_RESERVED(37),
54     SD_CMD_INDEX(38) | SD_RESP_R1b,
55     SD_CMD_INDEX(39) | SD_RESP_R4, //add
56     SD_CMD_INDEX(40) | SD_RESP_R5, //add
57     SD_CMD_INDEX(41) | SD_RESP_R3, //add, mov from harbote
58     SD_CMD_RESERVED(42) | SD_RESP_R1,
59     SD_CMD_RESERVED(43),
60     SD_CMD_RESERVED(44),
61     SD_CMD_RESERVED(45),
62     SD_CMD_RESERVED(46),
63     SD_CMD_RESERVED(47),
64     SD_CMD_RESERVED(48),
65     SD_CMD_RESERVED(49),
66     SD_CMD_RESERVED(50),
67     SD_CMD_INDEX(51) | SD_RESP_R1 | SD_DATA_READ,
68     SD_CMD_RESERVED(52),
69     SD_CMD_RESERVED(53),
70     SD_CMD_RESERVED(54),
71     SD_CMD_INDEX(55) | SD_RESP_R3,
72     SD_CMD_INDEX(56) | SD_RESP_R1 | SD_CMD_ISDATA,
73     SD_CMD_RESERVED(57),
74     SD_CMD_RESERVED(58),
75     SD_CMD_RESERVED(59),
76     SD_CMD_RESERVED(60),
77     SD_CMD_RESERVED(61),
78     SD_CMD_RESERVED(62),
79     SD_CMD_RESERVED(63)
80 };
81 
read32(rt_uint32_t addr)82 static inline rt_uint32_t read32(rt_uint32_t addr)
83 {
84     return (*((volatile unsigned int*)((rt_uint64_t)addr)));
85     //return (*((volatile rt_uint64_t *)(((long))addr)));
86 }
87 
write32(rt_uint32_t addr,rt_uint32_t value)88 static inline void write32(rt_uint32_t addr, rt_uint32_t value)
89 {
90     (*((volatile unsigned int*)((rt_uint64_t)addr))) = value;
91     //*((volatile rt_uint64_t *)(((long))addr)) = value;
92 }
93 
sd_int(struct sdhci_pdata_t * pdat,unsigned int mask)94 rt_err_t sd_int(struct sdhci_pdata_t * pdat, unsigned int mask)
95 {
96     unsigned int r;
97     unsigned int m = mask | INT_ERROR_MASK;
98     int cnt = 1000000;
99     while (!(read32(pdat->virt + EMMC_INTERRUPT) & (m | INT_ERROR_MASK)) && cnt--)
100         DELAY_MICROS(1);
101     r = read32(pdat->virt + EMMC_INTERRUPT);
102     if (cnt <= 0 || (r & INT_CMD_TIMEOUT) || (r & INT_DATA_TIMEOUT))
103     {
104         write32(pdat->virt + EMMC_INTERRUPT, r);
105         //qemu maybe can not use sdcard
106         //rt_kprintf("send cmd/data timeout wait for %x int: %x, status: %x\n",mask, r, read32(pdat->virt + EMMC_STATUS));
107         //return -RT_ETIMEOUT;
108     }
109     else if (r & INT_ERROR_MASK)
110     {
111         write32(pdat->virt + EMMC_INTERRUPT, r);
112         rt_kprintf("send cmd/data error %x -> %x\n",r, read32(pdat->virt + EMMC_INTERRUPT));
113         return -RT_ERROR;
114     }
115     write32(pdat->virt + EMMC_INTERRUPT, mask);
116     return RT_EOK;
117 }
118 
sd_status(struct sdhci_pdata_t * pdat,unsigned int mask)119 rt_err_t sd_status(struct sdhci_pdata_t * pdat, unsigned int mask)
120 {
121     int cnt = 500000;
122     while ((read32(pdat->virt + EMMC_STATUS) & mask) && !(read32(pdat->virt + EMMC_INTERRUPT) & INT_ERROR_MASK) && cnt--)
123         DELAY_MICROS(1);
124     if (cnt <= 0)
125     {
126         return -RT_ETIMEOUT;
127     }
128     else if (read32(pdat->virt + EMMC_INTERRUPT) & INT_ERROR_MASK)
129     {
130         return  -RT_ERROR;
131     }
132 
133     return RT_EOK;
134 }
135 
raspi_transfer_command(struct sdhci_pdata_t * pdat,struct sdhci_cmd_t * cmd)136 static rt_err_t raspi_transfer_command(struct sdhci_pdata_t * pdat, struct sdhci_cmd_t * cmd)
137 {
138     rt_uint32_t cmdidx;
139     rt_err_t ret = RT_EOK;
140     ret = sd_status(pdat, SR_CMD_INHIBIT);
141     if (ret)
142     {
143         rt_kprintf("ERROR: EMMC busy %d\n", ret);
144         return ret;
145     }
146 
147     cmdidx = sdCommandTable[cmd->cmdidx];
148     if (cmdidx == 0xFFFFFFFF)
149         return -RT_EINVAL;
150     if (cmd->datarw == DATA_READ)
151         cmdidx |= SD_DATA_READ;
152     if (cmd->datarw == DATA_WRITE)
153         cmdidx |= SD_DATA_WRITE;
154     mmcsd_dbg("transfer cmd %x(%d) %x %x\n", cmdidx, cmd->cmdidx, cmd->cmdarg, read32(pdat->virt + EMMC_INTERRUPT));
155     write32(pdat->virt + EMMC_INTERRUPT,read32(pdat->virt + EMMC_INTERRUPT));
156     write32(pdat->virt + EMMC_ARG1, cmd->cmdarg);
157     write32(pdat->virt + EMMC_CMDTM, cmdidx);
158     if (cmd->cmdidx == SD_APP_OP_COND)
159         DELAY_MICROS(1000);
160     else if ((cmd->cmdidx == SD_SEND_IF_COND) || (cmd->cmdidx == APP_CMD))
161         DELAY_MICROS(100);
162     ret = sd_int(pdat, INT_CMD_DONE);
163     if (ret)
164     {
165         return ret;
166     }
167     if (cmd->resptype & RESP_MASK)
168     {
169 
170         if (cmd->resptype & RESP_R2)
171         {
172             rt_uint32_t resp[4];
173             resp[0] = read32(pdat->virt + EMMC_RESP0);
174             resp[1] = read32(pdat->virt + EMMC_RESP1);
175             resp[2] = read32(pdat->virt + EMMC_RESP2);
176             resp[3] = read32(pdat->virt + EMMC_RESP3);
177             if (cmd->resptype == RESP_R2)
178             {
179                 cmd->response[0] = resp[3]<<8 |((resp[2]>>24)&0xff);
180                 cmd->response[1] = resp[2]<<8 |((resp[1]>>24)&0xff);
181                 cmd->response[2] = resp[1]<<8 |((resp[0]>>24)&0xff);
182                 cmd->response[3] = resp[0]<<8 ;
183             }
184             else
185             {
186                 cmd->response[0] = resp[0];
187                 cmd->response[1] = resp[1];
188                 cmd->response[2] = resp[2];
189                 cmd->response[3] = resp[3];
190             }
191         }
192         else
193             cmd->response[0] = read32(pdat->virt + EMMC_RESP0);
194     }
195     mmcsd_dbg("response: %x: %x %x %x %x (%x, %x)\n", cmd->resptype, cmd->response[0], cmd->response[1], cmd->response[2], cmd->response[3], read32(pdat->virt + EMMC_STATUS),read32(pdat->virt + EMMC_INTERRUPT));
196     return ret;
197 }
198 
read_bytes(struct sdhci_pdata_t * pdat,rt_uint32_t * buf,rt_uint32_t blkcount,rt_uint32_t blksize)199 static rt_err_t read_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize)
200 {
201     int c = 0;
202     rt_err_t ret;
203     int d;
204     while (c < blkcount)
205     {
206         if ((ret = sd_int(pdat, INT_READ_RDY)))
207         {
208             rt_kprintf("timeout happens when reading block %d\n",c);
209             return ret;
210         }
211         for (d=0; d < blksize / 4; d++)
212             if (read32(pdat->virt + EMMC_STATUS) & SR_READ_AVAILABLE)
213                 buf[d] = read32(pdat->virt + EMMC_DATA);
214         c++;
215         buf += blksize / 4;
216     }
217     return RT_EOK;
218 }
219 
write_bytes(struct sdhci_pdata_t * pdat,rt_uint32_t * buf,rt_uint32_t blkcount,rt_uint32_t blksize)220 static rt_err_t write_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize)
221 {
222     int c = 0;
223     rt_err_t ret;
224     int d;
225     while (c < blkcount)
226     {
227         if ((ret = sd_int(pdat, INT_WRITE_RDY)))
228         {
229             return ret;
230         }
231         for (d=0; d < blksize / 4; d++)
232             write32(pdat->virt + EMMC_DATA, buf[d]);
233         c++;
234         buf += blksize / 4;
235     }
236     if ((ret = sd_int(pdat, INT_DATA_DONE)))
237     {
238         return ret;
239     }
240     return RT_EOK;
241 }
242 
raspi_transfer_data(struct sdhci_pdata_t * pdat,struct sdhci_cmd_t * cmd,struct sdhci_data_t * dat)243 static rt_err_t raspi_transfer_data(struct sdhci_pdata_t * pdat, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat)
244 {
245     rt_uint32_t dlen = (rt_uint32_t)(dat->blkcnt * dat->blksz);
246     rt_err_t ret = sd_status(pdat, SR_DAT_INHIBIT);
247     if (ret)
248     {
249         rt_kprintf("ERROR: EMMC busy\n");
250         return ret;
251     }
252     if (dat->blkcnt > 1)
253     {
254         struct sdhci_cmd_t newcmd;
255         newcmd.cmdidx = SET_BLOCK_COUNT;
256         newcmd.cmdarg = dat->blkcnt;
257         newcmd.resptype = RESP_R1;
258         ret = raspi_transfer_command(pdat, &newcmd);
259         if (ret) return ret;
260     }
261 
262     if(dlen < 512)
263     {
264         write32(pdat->virt + EMMC_BLKSIZECNT, dlen | 1 << 16);
265     }
266     else
267     {
268         write32(pdat->virt + EMMC_BLKSIZECNT, 512 | (dat->blkcnt) << 16);
269     }
270     if (dat->flag & DATA_DIR_READ)
271     {
272         cmd->datarw = DATA_READ;
273         ret = raspi_transfer_command(pdat, cmd);
274         if (ret) return ret;
275         mmcsd_dbg("read_block %d, %d\n", dat->blkcnt, dat->blksz );
276         ret = read_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz);
277     }
278     else if (dat->flag & DATA_DIR_WRITE)
279     {
280         cmd->datarw = DATA_WRITE;
281         ret = raspi_transfer_command(pdat, cmd);
282         if (ret) return ret;
283         mmcsd_dbg("write_block %d, %d", dat->blkcnt, dat->blksz );
284         ret = write_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz);
285     }
286     return ret;
287 }
288 
sdhci_transfer(struct sdhci_t * sdhci,struct sdhci_cmd_t * cmd,struct sdhci_data_t * dat)289 static rt_err_t sdhci_transfer(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat)
290 {
291     struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)sdhci->priv;
292     if (!dat)
293         return raspi_transfer_command(pdat, cmd);
294 
295     return raspi_transfer_data(pdat, cmd, dat);
296 }
297 
mmc_request_send(struct rt_mmcsd_host * host,struct rt_mmcsd_req * req)298 static void mmc_request_send(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
299 {
300     struct sdhci_t *sdhci = (struct sdhci_t *)host->private_data;
301     struct sdhci_cmd_t cmd;
302     struct sdhci_cmd_t stop;
303     struct sdhci_data_t dat;
304     rt_memset(&cmd, 0, sizeof(struct sdhci_cmd_t));
305     rt_memset(&stop, 0, sizeof(struct sdhci_cmd_t));
306     rt_memset(&dat, 0, sizeof(struct sdhci_data_t));
307 
308     cmd.cmdidx = req->cmd->cmd_code;
309     cmd.cmdarg = req->cmd->arg;
310     cmd.resptype =resp_type(req->cmd);
311     if (req->data)
312     {
313         dat.buf = (rt_uint8_t *)req->data->buf;
314         dat.flag = req->data->flags;
315         dat.blksz = req->data->blksize;
316         dat.blkcnt = req->data->blks;
317 
318         req->cmd->err = sdhci_transfer(sdhci, &cmd, &dat);
319     }
320     else
321     {
322         req->cmd->err = sdhci_transfer(sdhci, &cmd, RT_NULL);
323     }
324 
325     req->cmd->resp[3] = cmd.response[3];
326     req->cmd->resp[2] = cmd.response[2];
327     req->cmd->resp[1] = cmd.response[1];
328     req->cmd->resp[0] = cmd.response[0];
329 
330     if (req->stop)
331     {
332         stop.cmdidx = req->stop->cmd_code;
333         stop.cmdarg = req->stop->arg;
334         cmd.resptype =resp_type(req->stop);
335         req->stop->err = sdhci_transfer(sdhci, &stop, RT_NULL);
336     }
337 
338     mmcsd_req_complete(host);
339 }
340 
mmc_card_status(struct rt_mmcsd_host * host)341 rt_int32_t mmc_card_status(struct rt_mmcsd_host *host)
342 {
343     return 0;
344 }
345 
mmc_enable_irq(struct rt_mmcsd_host * host,rt_int32_t en)346 void mmc_enable_irq(struct rt_mmcsd_host *host, rt_int32_t en)
347 {
348 
349 }
350 
sdhci_detect(struct sdhci_t * sdhci)351 static rt_err_t sdhci_detect(struct sdhci_t * sdhci)
352 {
353     return RT_EOK;
354 }
355 
sdhci_setwidth(struct sdhci_t * sdhci,rt_uint32_t width)356 static rt_err_t sdhci_setwidth(struct sdhci_t * sdhci, rt_uint32_t width)
357 {
358     rt_uint32_t temp = 0;
359     struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)sdhci->priv;
360     if (width == MMCSD_BUS_WIDTH_4)
361     {
362         temp = read32((pdat->virt + EMMC_CONTROL0));
363         temp |= C0_HCTL_HS_EN;
364         temp |= C0_HCTL_DWITDH;   // always use 4 data lines:
365         write32((pdat->virt + EMMC_CONTROL0), temp);
366     }
367     return RT_EOK;
368 }
369 
sdhci_getdivider(rt_uint32_t sdHostVer,rt_uint32_t freq)370 static rt_uint32_t sdhci_getdivider(rt_uint32_t sdHostVer, rt_uint32_t freq)
371 {
372     rt_uint32_t divisor;
373     rt_uint32_t closest = 41666666 / freq;
374     rt_uint32_t shiftcount = __rt_fls(closest - 1);
375 
376 
377     if (shiftcount > 0) shiftcount--;
378     if (shiftcount > 7) shiftcount = 7;
379     if (sdHostVer > HOST_SPEC_V2)
380         divisor = closest;
381     else
382         divisor = (1 << shiftcount);
383 
384     if (divisor <= 2)
385     {
386         divisor = 2;
387         shiftcount = 0;
388     }
389 
390     rt_uint32_t hi = 0;
391     if (sdHostVer > HOST_SPEC_V2)
392         hi = (divisor & 0x300) >> 2;
393     rt_uint32_t lo = (divisor & 0x0ff);
394     rt_uint32_t cdiv = (lo << 8) + hi;
395     return cdiv;
396 }
397 
sdhci_setclock(struct sdhci_t * sdhci,rt_uint32_t clock)398 static rt_err_t sdhci_setclock(struct sdhci_t * sdhci, rt_uint32_t clock)
399 {
400     rt_uint32_t temp = 0;
401     rt_uint32_t sdHostVer = 0;
402     int count = 100000;
403     struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)(sdhci->priv);
404 
405     while ((read32(pdat->virt + EMMC_STATUS) & (SR_CMD_INHIBIT | SR_DAT_INHIBIT)) && (--count))
406         DELAY_MICROS(1);
407     if (count <= 0)
408     {
409         rt_kprintf("EMMC: Set clock: timeout waiting for inhibit flags. Status %08x.\n",read32(pdat->virt + EMMC_STATUS));
410         return -RT_ERROR;
411     }
412 
413     // Switch clock off.
414     temp = read32((pdat->virt + EMMC_CONTROL1));
415     temp &= ~C1_CLK_EN;
416     write32((pdat->virt + EMMC_CONTROL1),temp);
417     DELAY_MICROS(10);
418     // Request the new clock setting and enable the clock
419     temp = read32(pdat->virt + EMMC_SLOTISR_VER);
420     sdHostVer = (temp & HOST_SPEC_NUM) >> HOST_SPEC_NUM_SHIFT;
421     int cdiv = sdhci_getdivider(sdHostVer, clock);
422     temp = read32((pdat->virt + EMMC_CONTROL1));
423     temp = (temp & 0xffff003f) | cdiv;
424     write32((pdat->virt + EMMC_CONTROL1),temp);
425     DELAY_MICROS(10);
426 
427     // Enable the clock.
428     temp = read32(pdat->virt + EMMC_CONTROL1);
429     temp |= C1_CLK_EN;
430     write32((pdat->virt + EMMC_CONTROL1),temp);
431     DELAY_MICROS(10);
432     // Wait for clock to be stable.
433     count = 10000;
434     while (!(read32(pdat->virt + EMMC_CONTROL1) & C1_CLK_STABLE) && count--)
435         DELAY_MICROS(10);
436     if (count <= 0)
437     {
438         rt_kprintf("EMMC: ERROR: failed to get stable clock %d.\n", clock);
439         return -RT_ERROR;
440     }
441     mmcsd_dbg("set stable clock %d.\n", clock);
442     return RT_EOK;
443 }
444 
mmc_set_iocfg(struct rt_mmcsd_host * host,struct rt_mmcsd_io_cfg * io_cfg)445 static void mmc_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
446 {
447     struct sdhci_t * sdhci = (struct sdhci_t *)host->private_data;
448     sdhci_setclock(sdhci, io_cfg->clock);
449     sdhci_setwidth(sdhci, io_cfg->bus_width);
450 }
451 
452 static const struct rt_mmcsd_host_ops ops =
453 {
454     mmc_request_send,
455     mmc_set_iocfg,
456     RT_NULL,
457     RT_NULL,
458 };
459 
sdmmc_gpio_init()460 static void sdmmc_gpio_init()
461 {
462 //    int pin;
463 //    bcm283x_gpio_fsel(47,BCM283X_GPIO_FSEL_INPT);
464 //    bcm283x_gpio_set_pud(47, BCM283X_GPIO_PUD_UP);
465 //    bcm283x_peri_set_bits(BCM283X_GPIO_BASE + BCM283X_GPIO_GPHEN1, 1<<15, 1<<15);
466 //    for (pin = 53; pin >= 48; pin--)
467 //    {
468 //        bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_ALT3);
469 //        bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_UP);
470 //    }
471 }
472 
reset_emmc(struct sdhci_pdata_t * pdat)473 static rt_err_t reset_emmc(struct sdhci_pdata_t * pdat){
474     rt_uint32_t temp;
475     int cnt;
476     write32((pdat->virt + EMMC_CONTROL0),0);
477     temp = read32((pdat->virt + EMMC_CONTROL1));
478     temp |= C1_SRST_HC;
479     write32((pdat->virt + EMMC_CONTROL1),temp);
480     cnt = 10000;
481     do
482     {
483         DELAY_MICROS(10);
484     }
485     while ((read32((pdat->virt + EMMC_CONTROL1)) & C1_SRST_HC) && cnt--);
486     if (cnt <= 0)
487     {
488         rt_kprintf("ERROR: failed to reset EMMC\n");
489         return -RT_ERROR;
490     }
491     temp = read32((pdat->virt + EMMC_CONTROL1));
492     temp |= C1_CLK_INTLEN | C1_TOUNIT_MAX;
493     write32((pdat->virt + EMMC_CONTROL1),temp);
494     DELAY_MICROS(10);
495     return RT_EOK;
496 }
497 
498 #ifdef RT_MMCSD_DBG
dump_registers(struct sdhci_pdata_t * pdat)499 void dump_registers(struct sdhci_pdata_t * pdat){
500     rt_kprintf("EMMC registers:");
501     int i = EMMC_ARG2;
502     for (; i <= EMMC_CONTROL2; i += 4)
503         rt_kprintf("\t%x:%x\n", i, read32(pdat->virt + i));
504     rt_kprintf("\t%x:%x\n", 0x50, read32(pdat->virt + 0x50));
505     rt_kprintf("\t%x:%x\n", 0x70, read32(pdat->virt + 0x70));
506     rt_kprintf("\t%x:%x\n", 0x74, read32(pdat->virt + 0x74));
507     rt_kprintf("\t%x:%x\n", 0x80, read32(pdat->virt + 0x80));
508     rt_kprintf("\t%x:%x\n", 0x84, read32(pdat->virt + 0x84));
509     rt_kprintf("\t%x:%x\n", 0x88, read32(pdat->virt + 0x88));
510     rt_kprintf("\t%x:%x\n", 0x8c, read32(pdat->virt + 0x8c));
511     rt_kprintf("\t%x:%x\n", 0x90, read32(pdat->virt + 0x90));
512     rt_kprintf("\t%x:%x\n", 0xf0, read32(pdat->virt + 0xf0));
513     rt_kprintf("\t%x:%x\n", 0xfc, read32(pdat->virt + 0xfc));
514 }
515 #endif
516 
raspi_sdmmc_init(void)517 int raspi_sdmmc_init(void)
518 {
519     rt_uint32_t virt;
520     struct rt_mmcsd_host * host = RT_NULL;
521     struct sdhci_pdata_t * pdat = RT_NULL;
522     struct sdhci_t * sdhci = RT_NULL;
523 #ifdef BSP_USING_SDIO0
524     host = mmcsd_alloc_host();
525     if (!host)
526     {
527         rt_kprintf("alloc host failed");
528         goto err;
529     }
530 
531     sdhci = rt_malloc(sizeof(struct sdhci_t));
532     if (!sdhci)
533     {
534         rt_kprintf("alloc sdhci failed");
535         goto err;
536     }
537     rt_memset(sdhci, 0, sizeof(struct sdhci_t));
538 
539     sdmmc_gpio_init();
540     virt = MMC0_BASE_ADDR;
541 
542     pdat = (struct sdhci_pdata_t *)rt_malloc(sizeof(struct sdhci_pdata_t));
543     RT_ASSERT(pdat != RT_NULL);
544 
545     pdat->virt = (rt_uint32_t)virt;
546     reset_emmc(pdat);
547 
548     sdhci->name = "sd0";
549     sdhci->voltages = VDD_33_34;
550     sdhci->width = MMCSD_BUSWIDTH_4;
551     sdhci->clock = 200 * 1000 * 1000;
552     sdhci->removeable = RT_TRUE;
553 
554     sdhci->detect = sdhci_detect;
555     sdhci->setwidth = sdhci_setwidth;
556     sdhci->setclock = sdhci_setclock;
557     sdhci->transfer = sdhci_transfer;
558     sdhci->priv = pdat;
559 
560     host->ops = &ops;
561     host->freq_min = 400000;
562     host->freq_max = 50000000;
563     host->valid_ocr = VDD_32_33 | VDD_33_34;
564     host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED | MMCSD_SUP_SDIO_IRQ | MMCSD_BUSWIDTH_4;
565     host->max_seg_size = 2048;
566     host->max_dma_segs = 10;
567     host->max_blk_size = 512;
568     host->max_blk_count = 4096;
569 
570     host->private_data = sdhci;
571 
572     write32((pdat->virt + EMMC_IRPT_EN),0xffffffff);
573     write32((pdat->virt + EMMC_IRPT_MASK),0xffffffff);
574 #ifdef RT_MMCSD_DBG
575     dump_registers(pdat);
576 #endif
577     mmcsd_change(host);
578 #endif
579     return RT_EOK;
580 
581 err:
582     if (host)  rt_free(host);
583     if (sdhci) rt_free(sdhci);
584 
585     return -RT_EIO;
586 }
587 
588 INIT_DEVICE_EXPORT(raspi_sdmmc_init);
589