1 /*
2  * Copyright (c) 2006-2020, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author         Notes
8  * 2020-10-27     bigmagic       first version
9  */
10 
11 #include "mbox.h"
12 #include "raspi4.h"
13 #include "drv_sdio.h"
14 
15 static rt_uint32_t mmc_base_clock = 0;
16 
17 static rt_uint32_t sdCommandTable[] = {
18     SD_CMD_INDEX(0),
19     SD_CMD_RESERVED(1),
20     SD_CMD_INDEX(2) | SD_RESP_R2,
21     SD_CMD_INDEX(3) | SD_RESP_R1,
22     SD_CMD_INDEX(4),
23     SD_CMD_RESERVED(5), //SD_CMD_INDEX(5) | SD_RESP_R4,
24     SD_CMD_INDEX(6) | SD_RESP_R1,
25     SD_CMD_INDEX(7) | SD_RESP_R1b,
26     SD_CMD_INDEX(8) | SD_RESP_R1,
27     SD_CMD_INDEX(9) | SD_RESP_R2,
28     SD_CMD_INDEX(10) | SD_RESP_R2,
29     SD_CMD_INDEX(11) | SD_RESP_R1,
30     SD_CMD_INDEX(12) | SD_RESP_R1b | SD_CMD_TYPE_ABORT,
31     SD_CMD_INDEX(13) | SD_RESP_R1,
32     SD_CMD_RESERVED(14),
33     SD_CMD_INDEX(15),
34     SD_CMD_INDEX(16) | SD_RESP_R1,
35     SD_CMD_INDEX(17) | SD_RESP_R1 | SD_DATA_READ,
36     SD_CMD_INDEX(18) | SD_RESP_R1 | SD_DATA_READ | SD_CMD_MULTI_BLOCK | SD_CMD_BLKCNT_EN,
37     SD_CMD_INDEX(19) | SD_RESP_R1 | SD_DATA_READ,
38     SD_CMD_INDEX(20) | SD_RESP_R1b,
39     SD_CMD_RESERVED(21),
40     SD_CMD_RESERVED(22),
41     SD_CMD_INDEX(23) | SD_RESP_R1,
42     SD_CMD_INDEX(24) | SD_RESP_R1 | SD_DATA_WRITE,
43     SD_CMD_INDEX(25) | SD_RESP_R1 | SD_DATA_WRITE | SD_CMD_MULTI_BLOCK | SD_CMD_BLKCNT_EN,
44     SD_CMD_INDEX(26) | SD_RESP_R1 | SD_DATA_WRITE, //add
45     SD_CMD_INDEX(27) | SD_RESP_R1 | SD_DATA_WRITE,
46     SD_CMD_INDEX(28) | SD_RESP_R1b,
47     SD_CMD_INDEX(29) | SD_RESP_R1b,
48     SD_CMD_INDEX(30) | SD_RESP_R1 | SD_DATA_READ,
49     SD_CMD_RESERVED(31),
50     SD_CMD_INDEX(32) | SD_RESP_R1,
51     SD_CMD_INDEX(33) | SD_RESP_R1,
52     SD_CMD_RESERVED(34),
53     SD_CMD_INDEX(35) | SD_RESP_R1, //add
54     SD_CMD_INDEX(36) | SD_RESP_R1, //add
55     SD_CMD_RESERVED(37),
56     SD_CMD_INDEX(38) | SD_RESP_R1b,
57     SD_CMD_INDEX(39) | SD_RESP_R4, //add
58     SD_CMD_INDEX(40) | SD_RESP_R5, //add
59     SD_CMD_INDEX(41) | SD_RESP_R3, //add, mov from harbote
60     SD_CMD_RESERVED(42) | SD_RESP_R1,
61     SD_CMD_RESERVED(43),
62     SD_CMD_RESERVED(44),
63     SD_CMD_RESERVED(45),
64     SD_CMD_RESERVED(46),
65     SD_CMD_RESERVED(47),
66     SD_CMD_RESERVED(48),
67     SD_CMD_RESERVED(49),
68     SD_CMD_RESERVED(50),
69     SD_CMD_INDEX(51) | SD_RESP_R1 | SD_DATA_READ,
70     SD_CMD_RESERVED(52),
71     SD_CMD_RESERVED(53),
72     SD_CMD_RESERVED(54),
73     SD_CMD_INDEX(55) | SD_RESP_R3,
74     SD_CMD_INDEX(56) | SD_RESP_R1 | SD_CMD_ISDATA,
75     SD_CMD_RESERVED(57),
76     SD_CMD_RESERVED(58),
77     SD_CMD_RESERVED(59),
78     SD_CMD_RESERVED(60),
79     SD_CMD_RESERVED(61),
80     SD_CMD_RESERVED(62),
81     SD_CMD_RESERVED(63)
82 };
83 
read32(size_t addr)84 static inline rt_uint32_t read32(size_t addr)
85 {
86     return (*((volatile unsigned int*)(addr)));
87 }
88 
write32(size_t addr,rt_uint32_t value)89 static inline void write32(size_t addr, rt_uint32_t value)
90 {
91     (*((volatile unsigned int*)(addr))) = value;
92 }
93 
sd_int(struct sdhci_pdata_t * pdat,rt_uint32_t mask)94 rt_err_t sd_int(struct sdhci_pdata_t * pdat, rt_uint32_t mask)
95 {
96     rt_uint32_t r;
97     rt_uint32_t 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 
163     ret = sd_int(pdat, INT_CMD_DONE);
164     if (ret)
165     {
166         return ret;
167     }
168     if (cmd->resptype & RESP_MASK)
169     {
170 
171         if (cmd->resptype & RESP_R2)
172         {
173             rt_uint32_t resp[4];
174             resp[0] = read32(pdat->virt + EMMC_RESP0);
175             resp[1] = read32(pdat->virt + EMMC_RESP1);
176             resp[2] = read32(pdat->virt + EMMC_RESP2);
177             resp[3] = read32(pdat->virt + EMMC_RESP3);
178             if (cmd->resptype == RESP_R2)
179             {
180                 cmd->response[0] = resp[3]<<8 |((resp[2]>>24)&0xff);
181                 cmd->response[1] = resp[2]<<8 |((resp[1]>>24)&0xff);
182                 cmd->response[2] = resp[1]<<8 |((resp[0]>>24)&0xff);
183                 cmd->response[3] = resp[0]<<8 ;
184             }
185             else
186             {
187                 cmd->response[0] = resp[0];
188                 cmd->response[1] = resp[1];
189                 cmd->response[2] = resp[2];
190                 cmd->response[3] = resp[3];
191             }
192         }
193         else
194             cmd->response[0] = read32(pdat->virt + EMMC_RESP0);
195     }
196     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));
197     return ret;
198 }
199 
read_bytes(struct sdhci_pdata_t * pdat,rt_uint32_t * buf,rt_uint32_t blkcount,rt_uint32_t blksize)200 static rt_err_t read_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize)
201 {
202     int c = 0;
203     rt_err_t ret;
204     int d;
205     while (c < blkcount)
206     {
207         if ((ret = sd_int(pdat, INT_READ_RDY)))
208         {
209             rt_kprintf("timeout happens when reading block %d\n",c);
210             return ret;
211         }
212         for (d=0; d < blksize / 4; d++)
213             if (read32(pdat->virt + EMMC_STATUS) & SR_READ_AVAILABLE)
214                 buf[d] = read32(pdat->virt + EMMC_DATA);
215         c++;
216         buf += blksize / 4;
217     }
218     return RT_EOK;
219 }
220 
write_bytes(struct sdhci_pdata_t * pdat,rt_uint32_t * buf,rt_uint32_t blkcount,rt_uint32_t blksize)221 static rt_err_t write_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize)
222 {
223     int c = 0;
224     rt_err_t ret;
225     int d;
226     while (c < blkcount)
227     {
228         if ((ret = sd_int(pdat, INT_WRITE_RDY)))
229         {
230             return ret;
231         }
232         for (d=0; d < blksize / 4; d++)
233             write32(pdat->virt + EMMC_DATA, buf[d]);
234         c++;
235         buf += blksize / 4;
236     }
237 
238     if ((ret = sd_int(pdat, INT_DATA_DONE)))
239     {
240         return ret;
241     }
242     return RT_EOK;
243 }
244 
raspi_transfer_data(struct sdhci_pdata_t * pdat,struct sdhci_cmd_t * cmd,struct sdhci_data_t * dat)245 static rt_err_t raspi_transfer_data(struct sdhci_pdata_t * pdat, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat)
246 {
247     rt_uint32_t dlen = (rt_uint32_t)(dat->blkcnt * dat->blksz);
248     rt_err_t ret = sd_status(pdat, SR_DAT_INHIBIT);
249     if (ret)
250     {
251         rt_kprintf("ERROR: EMMC busy\n");
252         return ret;
253     }
254     if (dat->blkcnt > 1)
255     {
256         struct sdhci_cmd_t newcmd;
257         newcmd.cmdidx = SET_BLOCK_COUNT;
258         newcmd.cmdarg = dat->blkcnt;
259         newcmd.resptype = RESP_R1;
260         ret = raspi_transfer_command(pdat, &newcmd);
261         if (ret) return ret;
262     }
263 
264     if(dlen < 512)
265     {
266         write32(pdat->virt + EMMC_BLKSIZECNT, dlen | 1 << 16);
267     }
268     else
269     {
270         write32(pdat->virt + EMMC_BLKSIZECNT, 512 | (dat->blkcnt) << 16);
271     }
272     if (dat->flag & DATA_DIR_READ)
273     {
274         cmd->datarw = DATA_READ;
275         ret = raspi_transfer_command(pdat, cmd);
276         if (ret) return ret;
277         mmcsd_dbg("read_block %d, %d\n", dat->blkcnt, dat->blksz );
278         ret = read_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz);
279     }
280     else if (dat->flag & DATA_DIR_WRITE)
281     {
282         cmd->datarw = DATA_WRITE;
283         ret = raspi_transfer_command(pdat, cmd);
284         if (ret) return ret;
285         mmcsd_dbg("write_block %d, %d", dat->blkcnt, dat->blksz );
286         ret = write_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz);
287     }
288     return ret;
289 }
290 
sdhci_transfer(struct sdhci_t * sdhci,struct sdhci_cmd_t * cmd,struct sdhci_data_t * dat)291 static rt_err_t sdhci_transfer(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat)
292 {
293     struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)sdhci->priv;
294     if (!dat)
295         return raspi_transfer_command(pdat, cmd);
296 
297     return raspi_transfer_data(pdat, cmd, dat);
298 }
299 
mmc_request_send(struct rt_mmcsd_host * host,struct rt_mmcsd_req * req)300 static void mmc_request_send(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
301 {
302     struct sdhci_t *sdhci = (struct sdhci_t *)host->private_data;
303     struct sdhci_cmd_t cmd;
304     struct sdhci_cmd_t stop;
305     struct sdhci_data_t dat;
306     rt_memset(&cmd, 0, sizeof(struct sdhci_cmd_t));
307     rt_memset(&stop, 0, sizeof(struct sdhci_cmd_t));
308     rt_memset(&dat, 0, sizeof(struct sdhci_data_t));
309 
310     cmd.cmdidx = req->cmd->cmd_code;
311     cmd.cmdarg = req->cmd->arg;
312     cmd.resptype =resp_type(req->cmd);
313     if (req->data)
314     {
315         dat.buf = (rt_uint8_t *)req->data->buf;
316         dat.flag = req->data->flags;
317         dat.blksz = req->data->blksize;
318         dat.blkcnt = req->data->blks;
319 
320         req->cmd->err = sdhci_transfer(sdhci, &cmd, &dat);
321     }
322     else
323     {
324         req->cmd->err = sdhci_transfer(sdhci, &cmd, RT_NULL);
325     }
326 
327     req->cmd->resp[3] = cmd.response[3];
328     req->cmd->resp[2] = cmd.response[2];
329     req->cmd->resp[1] = cmd.response[1];
330     req->cmd->resp[0] = cmd.response[0];
331 
332     if (req->stop)
333     {
334         stop.cmdidx = req->stop->cmd_code;
335         stop.cmdarg = req->stop->arg;
336         cmd.resptype =resp_type(req->stop);
337         req->stop->err = sdhci_transfer(sdhci, &stop, RT_NULL);
338     }
339 
340     mmcsd_req_complete(host);
341 }
342 
mmc_card_status(struct rt_mmcsd_host * host)343 rt_int32_t mmc_card_status(struct rt_mmcsd_host *host)
344 {
345     return 0;
346 }
347 
sdhci_detect(struct sdhci_t * sdhci)348 static rt_err_t sdhci_detect(struct sdhci_t * sdhci)
349 {
350     return RT_EOK;
351 }
352 
sdhci_setwidth(struct sdhci_t * sdhci,rt_uint32_t width)353 static rt_err_t sdhci_setwidth(struct sdhci_t * sdhci, rt_uint32_t width)
354 {
355     rt_uint32_t temp = 0;
356     struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)sdhci->priv;
357     if (width == MMCSD_BUS_WIDTH_4)
358     {
359         temp = read32((pdat->virt + EMMC_CONTROL0));
360         temp |= C0_HCTL_HS_EN;
361         temp |= C0_HCTL_DWITDH;   // always use 4 data lines:
362         write32((pdat->virt + EMMC_CONTROL0), temp);
363     }
364     return RT_EOK;
365 }
366 
367 
sd_get_clock_divider(rt_uint32_t sdHostVer,rt_uint32_t base_clock,rt_uint32_t target_rate)368 static uint32_t sd_get_clock_divider(rt_uint32_t sdHostVer ,rt_uint32_t base_clock, rt_uint32_t target_rate)
369 {
370     rt_uint32_t targetted_divisor = 0;
371     rt_uint32_t freq_select = 0;
372     rt_uint32_t upper_bits = 0;
373     rt_uint32_t ret = 0;
374 
375     if(target_rate > base_clock)
376         targetted_divisor = 1;
377     else
378     {
379         targetted_divisor = base_clock / target_rate;
380         rt_uint32_t mod = base_clock % target_rate;
381         if(mod)
382             targetted_divisor--;
383     }
384 
385     // Decide on the clock mode to use
386 
387     // Currently only 10-bit divided clock mode is supported
388 
389     // HCI version 3 or greater supports 10-bit divided clock mode
390     // This requires a power-of-two divider
391 
392     // Find the first bit set
393     int divisor = -1;
394     for(int first_bit = 31; first_bit >= 0; first_bit--)
395     {
396         rt_uint32_t bit_test = (1 << first_bit);
397         if(targetted_divisor & bit_test)
398         {
399             divisor = first_bit;
400             targetted_divisor &= ~bit_test;
401             if(targetted_divisor)
402             {
403                 // The divisor is not a power-of-two, increase it
404                 divisor++;
405             }
406             break;
407         }
408     }
409 
410     if(divisor == -1)
411         divisor = 31;
412     if(divisor >= 32)
413         divisor = 31;
414 
415     if(divisor != 0)
416         divisor = (1 << (divisor - 1));
417 
418     if(divisor >= 0x400)
419         divisor = 0x3ff;
420 
421     freq_select = divisor & 0xff;
422     upper_bits = (divisor >> 8) & 0x3;
423     ret = (freq_select << 8) | (upper_bits << 6) | (0 << 5);
424 
425     return ret;
426 }
427 
sdhci_setclock(struct sdhci_t * sdhci,rt_uint32_t clock)428 static rt_err_t sdhci_setclock(struct sdhci_t * sdhci, rt_uint32_t clock)
429 {
430     rt_uint32_t temp = 0;
431     rt_uint32_t sdHostVer = 0;
432     int count = 100000;
433     struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)(sdhci->priv);
434 
435     while ((read32(pdat->virt + EMMC_STATUS) & (SR_CMD_INHIBIT | SR_DAT_INHIBIT)) && (--count))
436         DELAY_MICROS(1);
437     if (count <= 0)
438     {
439         rt_kprintf("EMMC: Set clock: timeout waiting for inhibit flags. Status %08x.\n",read32(pdat->virt + EMMC_STATUS));
440         return -RT_ERROR;
441     }
442 
443     // Switch clock off.
444     temp = read32((pdat->virt + EMMC_CONTROL1));
445     temp &= ~C1_CLK_EN;
446     write32((pdat->virt + EMMC_CONTROL1),temp);
447     DELAY_MICROS(10);
448     // Request the new clock setting and enable the clock
449     temp = read32(pdat->virt + EMMC_SLOTISR_VER);
450     sdHostVer = (temp & HOST_SPEC_NUM) >> HOST_SPEC_NUM_SHIFT;
451     int cdiv = sd_get_clock_divider(sdHostVer, mmc_base_clock, clock);
452     temp = read32((pdat->virt + EMMC_CONTROL1));
453     temp |= 1;
454     temp |= cdiv;
455     temp |= (7 << 16);
456 
457     temp = (temp & 0xffff003f) | cdiv;
458     write32((pdat->virt + EMMC_CONTROL1),temp);
459     DELAY_MICROS(10);
460 
461     // Enable the clock.
462     temp = read32(pdat->virt + EMMC_CONTROL1);
463     temp |= C1_CLK_EN;
464     write32((pdat->virt + EMMC_CONTROL1),temp);
465     DELAY_MICROS(10);
466 
467     // Wait for clock to be stable.
468     count = 10000;
469     while (!(read32(pdat->virt + EMMC_CONTROL1) & C1_CLK_STABLE) && count--)
470         DELAY_MICROS(10);
471     if (count <= 0)
472     {
473         rt_kprintf("EMMC: ERROR: failed to get stable clock %d.\n", clock);
474         return -RT_ERROR;
475     }
476 
477     mmcsd_dbg("set stable clock %d.\n", clock);
478     return RT_EOK;
479 }
480 
mmc_set_iocfg(struct rt_mmcsd_host * host,struct rt_mmcsd_io_cfg * io_cfg)481 static void mmc_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
482 {
483     struct sdhci_t * sdhci = (struct sdhci_t *)host->private_data;
484     sdhci_setclock(sdhci, io_cfg->clock);
485     sdhci_setwidth(sdhci, io_cfg->bus_width);
486 }
487 
488 static const struct rt_mmcsd_host_ops ops =
489 {
490     mmc_request_send,
491     mmc_set_iocfg,
492     RT_NULL,
493     RT_NULL,
494 };
495 
reset_emmc(struct sdhci_pdata_t * pdat)496 static rt_err_t reset_emmc(struct sdhci_pdata_t * pdat)
497 {
498     rt_uint32_t control1;
499 
500     //Reset the controller
501     control1 = read32((pdat->virt + EMMC_CONTROL1));
502     control1 |= (1 << 24);
503     // Disable clock
504     control1 &= ~(1 << 2);
505     control1 &= ~(1 << 0);
506     //temp |= C1_CLK_INTLEN | C1_TOUNIT_MAX;
507     write32((pdat->virt + EMMC_CONTROL1),control1);
508     int cnt = 10000;
509     do
510     {
511         DELAY_MICROS(10);
512         cnt = cnt - 1;
513         if(cnt == 0)
514         {
515             break;
516         }
517     } while ((read32(pdat->virt + EMMC_CONTROL1) & (0x7 << 24)) != 0);
518 
519     // Enable SD Bus Power VDD1 at 3.3V
520     rt_uint32_t control0 = read32(pdat->virt + EMMC_CONTROL0);
521     control0 |= 0x0F << 8;
522     write32(pdat->virt + EMMC_CONTROL0, control0);
523 
524     rt_thread_delay(100);
525     //usleep(2000);
526 
527 
528     // Check for a valid card
529     mmcsd_dbg("EMMC: checking for an inserted card\n");
530     cnt = 10000;
531     do
532     {
533         DELAY_MICROS(10);
534         cnt = cnt - 1;
535         if(cnt == 0)
536         {
537             break;
538         }
539     } while ((read32(pdat->virt + EMMC_STATUS) & (0x1 << 16)) == 0);
540 
541     rt_uint32_t status_reg = read32(pdat->virt + EMMC_STATUS);
542 
543     if((status_reg & (1 << 16)) == 0)
544     {
545         rt_kprintf("EMMC: no card inserted\n");
546         return -1;
547     }
548     else
549     {
550         mmcsd_dbg("EMMC: status: %08x\n", status_reg);
551     }
552 
553     // Clear control2
554     write32(pdat->virt + EMMC_CONTROL2, 0);
555     // Get the base clock rate //12
556     mmc_base_clock = bcm271x_mbox_clock_get_rate(EMMC_CLK_ID);
557     if(mmc_base_clock == 0)
558     {
559         rt_kprintf("EMMC: assuming clock rate to be 100MHz\n");
560         mmc_base_clock = 100000000;
561     }
562     mmcsd_dbg("EMMC: setting clock rate is %d\n", mmc_base_clock);
563     return RT_EOK;
564 }
565 
566 #ifdef RT_MMCSD_DBG
dump_registers(struct sdhci_pdata_t * pdat)567 void dump_registers(struct sdhci_pdata_t * pdat)
568 {
569     rt_kprintf("EMMC registers:");
570     int i = EMMC_ARG2;
571     for (; i <= EMMC_CONTROL2; i += 4)
572         rt_kprintf("\t%x:%x\n", i, read32(pdat->virt + i));
573     rt_kprintf("\t%x:%x\n", 0x50, read32(pdat->virt + 0x50));
574     rt_kprintf("\t%x:%x\n", 0x70, read32(pdat->virt + 0x70));
575     rt_kprintf("\t%x:%x\n", 0x74, read32(pdat->virt + 0x74));
576     rt_kprintf("\t%x:%x\n", 0x80, read32(pdat->virt + 0x80));
577     rt_kprintf("\t%x:%x\n", 0x84, read32(pdat->virt + 0x84));
578     rt_kprintf("\t%x:%x\n", 0x88, read32(pdat->virt + 0x88));
579     rt_kprintf("\t%x:%x\n", 0x8c, read32(pdat->virt + 0x8c));
580     rt_kprintf("\t%x:%x\n", 0x90, read32(pdat->virt + 0x90));
581     rt_kprintf("\t%x:%x\n", 0xf0, read32(pdat->virt + 0xf0));
582     rt_kprintf("\t%x:%x\n", 0xfc, read32(pdat->virt + 0xfc));
583 }
584 #endif
585 
raspi_sdmmc_init(void)586 int raspi_sdmmc_init(void)
587 {
588     size_t virt;
589     struct rt_mmcsd_host * host = RT_NULL;
590     struct sdhci_pdata_t * pdat = RT_NULL;
591     struct sdhci_t * sdhci = RT_NULL;
592 
593 #ifdef BSP_USING_SDIO0
594     host = mmcsd_alloc_host();
595     if (!host)
596     {
597         rt_kprintf("alloc host failed");
598         goto err;
599     }
600     sdhci = rt_malloc(sizeof(struct sdhci_t));
601     if (!sdhci)
602     {
603         rt_kprintf("alloc sdhci failed");
604         goto err;
605     }
606     rt_memset(sdhci, 0, sizeof(struct sdhci_t));
607 
608     virt = mmc2_base_addr;
609     pdat = (struct sdhci_pdata_t *)rt_malloc(sizeof(struct sdhci_pdata_t));
610     RT_ASSERT(pdat != RT_NULL);
611 
612     pdat->virt = virt;
613     reset_emmc(pdat);
614     sdhci->name = "sd0";
615     sdhci->voltages = VDD_33_34;
616     sdhci->width = MMCSD_BUSWIDTH_4;
617     sdhci->clock = 1000 * 1000 * 1000;
618     sdhci->removeable = RT_TRUE;
619 
620     sdhci->detect = sdhci_detect;
621     sdhci->setwidth = sdhci_setwidth;
622     sdhci->setclock = sdhci_setclock;
623     sdhci->transfer = sdhci_transfer;
624     sdhci->priv = pdat;
625     host->ops = &ops;
626     host->freq_min = 400000;
627     host->freq_max = 50000000;
628     host->valid_ocr = VDD_32_33 | VDD_33_34;
629     host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED | MMCSD_SUP_SDIO_IRQ | MMCSD_BUSWIDTH_4;
630     host->max_seg_size = 2048;
631     host->max_dma_segs = 10;
632     host->max_blk_size = 512;
633     host->max_blk_count = 1;
634 
635     host->private_data = sdhci;
636     write32((pdat->virt + EMMC_IRPT_EN),0xffffffff);
637     write32((pdat->virt + EMMC_IRPT_MASK),0xffffffff);
638 #ifdef RT_MMCSD_DBG
639     dump_registers(pdat);
640 #endif
641     mmcsd_change(host);
642 #endif
643     return RT_EOK;
644 err:
645     if (host)  rt_free(host);
646     if (sdhci) rt_free(sdhci);
647 
648     return -RT_EIO;
649 }
650 
651 INIT_DEVICE_EXPORT(raspi_sdmmc_init);
652