1 // SPDX-License-Identifier: GPL-2.0
3 * drivers/mmc/sh_sdhi.c
5 * SD/MMC driver for Renesas rmobile ARM SoCs.
7 * Copyright (C) 2011,2013-2017 Renesas Electronics Corporation
8 * Copyright (C) 2014 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
9 * Copyright (C) 2008-2009 Renesas Solutions Corp.
18 #include <dm/device_compat.h>
19 #include <linux/delay.h>
20 #include <linux/errno.h>
21 #include <linux/compat.h>
23 #include <linux/sizes.h>
24 #include <asm/arch/rmobile.h>
25 #include <asm/arch/sh_sdhi.h>
28 #define DRIVER_NAME "sh-sdhi"
35 unsigned char wait_int;
36 unsigned char sd_error;
37 unsigned char detect_waiting;
38 unsigned char app_cmd;
41 static inline void sh_sdhi_writeq(struct sh_sdhi_host *host, int reg, u64 val)
43 writeq(val, host->addr + (reg << host->bus_shift));
46 static inline u64 sh_sdhi_readq(struct sh_sdhi_host *host, int reg)
48 return readq(host->addr + (reg << host->bus_shift));
51 static inline void sh_sdhi_writew(struct sh_sdhi_host *host, int reg, u16 val)
53 writew(val, host->addr + (reg << host->bus_shift));
56 static inline u16 sh_sdhi_readw(struct sh_sdhi_host *host, int reg)
58 return readw(host->addr + (reg << host->bus_shift));
61 static void sh_sdhi_detect(struct sh_sdhi_host *host)
63 sh_sdhi_writew(host, SDHI_OPTION,
64 OPT_BUS_WIDTH_1 | sh_sdhi_readw(host, SDHI_OPTION));
66 host->detect_waiting = 0;
69 static int sh_sdhi_intr(void *dev_id)
71 struct sh_sdhi_host *host = dev_id;
72 int state1 = 0, state2 = 0;
74 state1 = sh_sdhi_readw(host, SDHI_INFO1);
75 state2 = sh_sdhi_readw(host, SDHI_INFO2);
77 debug("%s: state1 = %x, state2 = %x\n", __func__, state1, state2);
80 if (state1 & INFO1_CARD_IN) {
81 sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_CARD_IN);
82 if (!host->detect_waiting) {
83 host->detect_waiting = 1;
86 sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END |
87 INFO1M_ACCESS_END | INFO1M_CARD_IN |
88 INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
92 if (state1 & INFO1_CARD_RE) {
93 sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_CARD_RE);
94 if (!host->detect_waiting) {
95 host->detect_waiting = 1;
98 sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END |
99 INFO1M_ACCESS_END | INFO1M_CARD_RE |
100 INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
101 sh_sdhi_writew(host, SDHI_SDIO_INFO1_MASK, SDIO_INFO1M_ON);
102 sh_sdhi_writew(host, SDHI_SDIO_MODE, SDIO_MODE_OFF);
106 if (state2 & INFO2_ALL_ERR) {
107 sh_sdhi_writew(host, SDHI_INFO2,
108 (unsigned short)~(INFO2_ALL_ERR));
109 sh_sdhi_writew(host, SDHI_INFO2_MASK,
111 sh_sdhi_readw(host, SDHI_INFO2_MASK));
117 if (state1 & INFO1_RESP_END) {
118 sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_RESP_END);
119 sh_sdhi_writew(host, SDHI_INFO1_MASK,
121 sh_sdhi_readw(host, SDHI_INFO1_MASK));
125 /* SD_BUF Read Enable */
126 if (state2 & INFO2_BRE_ENABLE) {
127 sh_sdhi_writew(host, SDHI_INFO2, ~INFO2_BRE_ENABLE);
128 sh_sdhi_writew(host, SDHI_INFO2_MASK,
129 INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ |
130 sh_sdhi_readw(host, SDHI_INFO2_MASK));
134 /* SD_BUF Write Enable */
135 if (state2 & INFO2_BWE_ENABLE) {
136 sh_sdhi_writew(host, SDHI_INFO2, ~INFO2_BWE_ENABLE);
137 sh_sdhi_writew(host, SDHI_INFO2_MASK,
138 INFO2_BWE_ENABLE | INFO2M_BUF_ILL_WRITE |
139 sh_sdhi_readw(host, SDHI_INFO2_MASK));
144 if (state1 & INFO1_ACCESS_END) {
145 sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_ACCESS_END);
146 sh_sdhi_writew(host, SDHI_INFO1_MASK,
148 sh_sdhi_readw(host, SDHI_INFO1_MASK));
155 static int sh_sdhi_wait_interrupt_flag(struct sh_sdhi_host *host)
157 int timeout = 10000000;
162 debug(DRIVER_NAME": %s timeout\n", __func__);
166 if (!sh_sdhi_intr(host))
169 udelay(1); /* 1 usec */
172 return 1; /* Return value: NOT 0 = complete waiting */
175 static int sh_sdhi_clock_control(struct sh_sdhi_host *host, unsigned long clk)
177 u32 clkdiv, i, timeout;
179 if (sh_sdhi_readw(host, SDHI_INFO2) & (1 << 14)) {
180 printf(DRIVER_NAME": Busy state ! Cannot change the clock\n");
184 sh_sdhi_writew(host, SDHI_CLK_CTRL,
185 ~CLK_ENABLE & sh_sdhi_readw(host, SDHI_CLK_CTRL));
191 i = CONFIG_SH_SDHI_FREQ >> (0x8 + 1);
192 for (; clkdiv && clk >= (i << 1); (clkdiv >>= 1))
195 sh_sdhi_writew(host, SDHI_CLK_CTRL, clkdiv);
198 /* Waiting for SD Bus busy to be cleared */
200 if ((sh_sdhi_readw(host, SDHI_INFO2) & 0x2000))
205 sh_sdhi_writew(host, SDHI_CLK_CTRL,
206 CLK_ENABLE | sh_sdhi_readw(host, SDHI_CLK_CTRL));
213 static int sh_sdhi_sync_reset(struct sh_sdhi_host *host)
216 sh_sdhi_writew(host, SDHI_SOFT_RST, SOFT_RST_ON);
217 sh_sdhi_writew(host, SDHI_SOFT_RST, SOFT_RST_OFF);
218 sh_sdhi_writew(host, SDHI_CLK_CTRL,
219 CLK_ENABLE | sh_sdhi_readw(host, SDHI_CLK_CTRL));
223 if (!(sh_sdhi_readw(host, SDHI_INFO2) & INFO2_CBUSY))
231 if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
232 sh_sdhi_writew(host, SDHI_HOST_MODE, 1);
237 static int sh_sdhi_error_manage(struct sh_sdhi_host *host)
239 unsigned short e_state1, e_state2;
245 e_state1 = sh_sdhi_readw(host, SDHI_ERR_STS1);
246 e_state2 = sh_sdhi_readw(host, SDHI_ERR_STS2);
247 if (e_state2 & ERR_STS2_SYS_ERROR) {
248 if (e_state2 & ERR_STS2_RES_STOP_TIMEOUT)
252 debug("%s: ERR_STS2 = %04x\n",
253 DRIVER_NAME, sh_sdhi_readw(host, SDHI_ERR_STS2));
254 sh_sdhi_sync_reset(host);
256 sh_sdhi_writew(host, SDHI_INFO1_MASK,
257 INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
260 if (e_state1 & ERR_STS1_CRC_ERROR || e_state1 & ERR_STS1_CMD_ERROR)
265 debug("%s: ERR_STS1 = %04x\n",
266 DRIVER_NAME, sh_sdhi_readw(host, SDHI_ERR_STS1));
267 sh_sdhi_sync_reset(host);
268 sh_sdhi_writew(host, SDHI_INFO1_MASK,
269 INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
273 static int sh_sdhi_single_read(struct sh_sdhi_host *host, struct mmc_data *data)
276 unsigned short blocksize, i;
277 unsigned short *p = (unsigned short *)data->dest;
278 u64 *q = (u64 *)data->dest;
280 if ((unsigned long)p & 0x00000001) {
281 debug(DRIVER_NAME": %s: The data pointer is unaligned.",
287 sh_sdhi_writew(host, SDHI_INFO2_MASK,
288 ~(INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ) &
289 sh_sdhi_readw(host, SDHI_INFO2_MASK));
290 sh_sdhi_writew(host, SDHI_INFO1_MASK,
292 sh_sdhi_readw(host, SDHI_INFO1_MASK));
293 time = sh_sdhi_wait_interrupt_flag(host);
294 if (time == 0 || host->sd_error != 0)
295 return sh_sdhi_error_manage(host);
298 blocksize = sh_sdhi_readw(host, SDHI_SIZE);
299 if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
300 for (i = 0; i < blocksize / 8; i++)
301 *q++ = sh_sdhi_readq(host, SDHI_BUF0);
303 for (i = 0; i < blocksize / 2; i++)
304 *p++ = sh_sdhi_readw(host, SDHI_BUF0);
306 time = sh_sdhi_wait_interrupt_flag(host);
307 if (time == 0 || host->sd_error != 0)
308 return sh_sdhi_error_manage(host);
314 static int sh_sdhi_multi_read(struct sh_sdhi_host *host, struct mmc_data *data)
317 unsigned short blocksize, i, sec;
318 unsigned short *p = (unsigned short *)data->dest;
319 u64 *q = (u64 *)data->dest;
321 if ((unsigned long)p & 0x00000001) {
322 debug(DRIVER_NAME": %s: The data pointer is unaligned.",
327 debug("%s: blocks = %d, blocksize = %d\n",
328 __func__, data->blocks, data->blocksize);
331 for (sec = 0; sec < data->blocks; sec++) {
332 sh_sdhi_writew(host, SDHI_INFO2_MASK,
333 ~(INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ) &
334 sh_sdhi_readw(host, SDHI_INFO2_MASK));
336 time = sh_sdhi_wait_interrupt_flag(host);
337 if (time == 0 || host->sd_error != 0)
338 return sh_sdhi_error_manage(host);
341 blocksize = sh_sdhi_readw(host, SDHI_SIZE);
342 if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
343 for (i = 0; i < blocksize / 8; i++)
344 *q++ = sh_sdhi_readq(host, SDHI_BUF0);
346 for (i = 0; i < blocksize / 2; i++)
347 *p++ = sh_sdhi_readw(host, SDHI_BUF0);
353 static int sh_sdhi_single_write(struct sh_sdhi_host *host,
354 struct mmc_data *data)
357 unsigned short blocksize, i;
358 const unsigned short *p = (const unsigned short *)data->src;
359 const u64 *q = (const u64 *)data->src;
361 if ((unsigned long)p & 0x00000001) {
362 debug(DRIVER_NAME": %s: The data pointer is unaligned.",
367 debug("%s: blocks = %d, blocksize = %d\n",
368 __func__, data->blocks, data->blocksize);
371 sh_sdhi_writew(host, SDHI_INFO2_MASK,
372 ~(INFO2M_BWE_ENABLE | INFO2M_BUF_ILL_WRITE) &
373 sh_sdhi_readw(host, SDHI_INFO2_MASK));
374 sh_sdhi_writew(host, SDHI_INFO1_MASK,
376 sh_sdhi_readw(host, SDHI_INFO1_MASK));
378 time = sh_sdhi_wait_interrupt_flag(host);
379 if (time == 0 || host->sd_error != 0)
380 return sh_sdhi_error_manage(host);
383 blocksize = sh_sdhi_readw(host, SDHI_SIZE);
384 if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
385 for (i = 0; i < blocksize / 8; i++)
386 sh_sdhi_writeq(host, SDHI_BUF0, *q++);
388 for (i = 0; i < blocksize / 2; i++)
389 sh_sdhi_writew(host, SDHI_BUF0, *p++);
391 time = sh_sdhi_wait_interrupt_flag(host);
392 if (time == 0 || host->sd_error != 0)
393 return sh_sdhi_error_manage(host);
399 static int sh_sdhi_multi_write(struct sh_sdhi_host *host, struct mmc_data *data)
402 unsigned short i, sec, blocksize;
403 const unsigned short *p = (const unsigned short *)data->src;
404 const u64 *q = (const u64 *)data->src;
406 debug("%s: blocks = %d, blocksize = %d\n",
407 __func__, data->blocks, data->blocksize);
410 for (sec = 0; sec < data->blocks; sec++) {
411 sh_sdhi_writew(host, SDHI_INFO2_MASK,
412 ~(INFO2M_BWE_ENABLE | INFO2M_BUF_ILL_WRITE) &
413 sh_sdhi_readw(host, SDHI_INFO2_MASK));
415 time = sh_sdhi_wait_interrupt_flag(host);
416 if (time == 0 || host->sd_error != 0)
417 return sh_sdhi_error_manage(host);
420 blocksize = sh_sdhi_readw(host, SDHI_SIZE);
421 if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
422 for (i = 0; i < blocksize / 8; i++)
423 sh_sdhi_writeq(host, SDHI_BUF0, *q++);
425 for (i = 0; i < blocksize / 2; i++)
426 sh_sdhi_writew(host, SDHI_BUF0, *p++);
432 static void sh_sdhi_get_response(struct sh_sdhi_host *host, struct mmc_cmd *cmd)
434 unsigned short i, j, cnt = 1;
435 unsigned short resp[8];
437 if (cmd->resp_type & MMC_RSP_136) {
439 resp[0] = sh_sdhi_readw(host, SDHI_RSP00);
440 resp[1] = sh_sdhi_readw(host, SDHI_RSP01);
441 resp[2] = sh_sdhi_readw(host, SDHI_RSP02);
442 resp[3] = sh_sdhi_readw(host, SDHI_RSP03);
443 resp[4] = sh_sdhi_readw(host, SDHI_RSP04);
444 resp[5] = sh_sdhi_readw(host, SDHI_RSP05);
445 resp[6] = sh_sdhi_readw(host, SDHI_RSP06);
446 resp[7] = sh_sdhi_readw(host, SDHI_RSP07);
448 /* SDHI REGISTER SPECIFICATION */
449 for (i = 7, j = 6; i > 0; i--) {
450 resp[i] = (resp[i] << 8) & 0xff00;
451 resp[i] |= (resp[j--] >> 8) & 0x00ff;
453 resp[0] = (resp[0] << 8) & 0xff00;
455 resp[0] = sh_sdhi_readw(host, SDHI_RSP00);
456 resp[1] = sh_sdhi_readw(host, SDHI_RSP01);
459 #if defined(__BIG_ENDIAN_BITFIELD)
461 cmd->response[0] = (resp[6] << 16) | resp[7];
462 cmd->response[1] = (resp[4] << 16) | resp[5];
463 cmd->response[2] = (resp[2] << 16) | resp[3];
464 cmd->response[3] = (resp[0] << 16) | resp[1];
466 cmd->response[0] = (resp[0] << 16) | resp[1];
470 cmd->response[0] = (resp[7] << 16) | resp[6];
471 cmd->response[1] = (resp[5] << 16) | resp[4];
472 cmd->response[2] = (resp[3] << 16) | resp[2];
473 cmd->response[3] = (resp[1] << 16) | resp[0];
475 cmd->response[0] = (resp[1] << 16) | resp[0];
477 #endif /* __BIG_ENDIAN_BITFIELD */
480 static unsigned short sh_sdhi_set_cmd(struct sh_sdhi_host *host,
481 struct mmc_data *data, unsigned short opc)
491 return opc | (data ? 0x1c00 : 0x40);
492 case MMC_CMD_SEND_EXT_CSD:
493 return opc | (data ? 0x1c00 : 0);
494 case MMC_CMD_SEND_OP_COND:
496 case MMC_CMD_APP_CMD:
503 static unsigned short sh_sdhi_data_trans(struct sh_sdhi_host *host,
504 struct mmc_data *data, unsigned short opc)
509 case SD_CMD_APP_SEND_SCR:
510 case SD_CMD_APP_SD_STATUS:
511 return sh_sdhi_single_read(host, data);
513 printf(DRIVER_NAME": SD: NOT SUPPORT APP CMD = d'%04d\n",
519 case MMC_CMD_WRITE_MULTIPLE_BLOCK:
520 return sh_sdhi_multi_write(host, data);
521 case MMC_CMD_READ_MULTIPLE_BLOCK:
522 return sh_sdhi_multi_read(host, data);
523 case MMC_CMD_WRITE_SINGLE_BLOCK:
524 return sh_sdhi_single_write(host, data);
525 case MMC_CMD_READ_SINGLE_BLOCK:
527 case MMC_CMD_SEND_EXT_CSD:;
528 return sh_sdhi_single_read(host, data);
530 printf(DRIVER_NAME": SD: NOT SUPPORT CMD = d'%04d\n", opc);
536 static int sh_sdhi_start_cmd(struct sh_sdhi_host *host,
537 struct mmc_data *data, struct mmc_cmd *cmd)
540 unsigned short shcmd, opc = cmd->cmdidx;
542 unsigned long timeout;
544 debug("opc = %d, arg = %x, resp_type = %x\n",
545 opc, cmd->cmdarg, cmd->resp_type);
547 if (opc == MMC_CMD_STOP_TRANSMISSION) {
548 /* SDHI sends the STOP command automatically by STOP reg */
549 sh_sdhi_writew(host, SDHI_INFO1_MASK, ~INFO1M_ACCESS_END &
550 sh_sdhi_readw(host, SDHI_INFO1_MASK));
552 time = sh_sdhi_wait_interrupt_flag(host);
553 if (time == 0 || host->sd_error != 0)
554 return sh_sdhi_error_manage(host);
556 sh_sdhi_get_response(host, cmd);
561 if ((opc == MMC_CMD_READ_MULTIPLE_BLOCK) ||
562 opc == MMC_CMD_WRITE_MULTIPLE_BLOCK) {
563 sh_sdhi_writew(host, SDHI_STOP, STOP_SEC_ENABLE);
564 sh_sdhi_writew(host, SDHI_SECCNT, data->blocks);
566 sh_sdhi_writew(host, SDHI_SIZE, data->blocksize);
569 shcmd = sh_sdhi_set_cmd(host, data, opc);
572 * U-Boot cannot use interrupt.
573 * So this flag may not be clear by timing
575 sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_RESP_END);
577 sh_sdhi_writew(host, SDHI_INFO1_MASK,
578 INFO1M_RESP_END | sh_sdhi_readw(host, SDHI_INFO1_MASK));
579 sh_sdhi_writew(host, SDHI_ARG0,
580 (unsigned short)(cmd->cmdarg & ARG0_MASK));
581 sh_sdhi_writew(host, SDHI_ARG1,
582 (unsigned short)((cmd->cmdarg >> 16) & ARG1_MASK));
585 /* Waiting for SD Bus busy to be cleared */
587 if ((sh_sdhi_readw(host, SDHI_INFO2) & 0x2000))
592 sh_sdhi_writew(host, SDHI_INFO1_MASK,
593 ~INFO1M_RESP_END & sh_sdhi_readw(host, SDHI_INFO1_MASK));
594 sh_sdhi_writew(host, SDHI_INFO2_MASK,
595 ~(INFO2M_CMD_ERROR | INFO2M_CRC_ERROR |
596 INFO2M_END_ERROR | INFO2M_TIMEOUT |
597 INFO2M_RESP_TIMEOUT | INFO2M_ILA) &
598 sh_sdhi_readw(host, SDHI_INFO2_MASK));
600 sh_sdhi_writew(host, SDHI_CMD, (unsigned short)(shcmd & CMD_MASK));
601 time = sh_sdhi_wait_interrupt_flag(host);
604 return sh_sdhi_error_manage(host);
607 if (host->sd_error) {
608 switch (cmd->cmdidx) {
609 case MMC_CMD_ALL_SEND_CID:
610 case MMC_CMD_SELECT_CARD:
611 case SD_CMD_SEND_IF_COND:
612 case MMC_CMD_APP_CMD:
616 debug(DRIVER_NAME": Cmd(d'%d) err\n", opc);
617 debug(DRIVER_NAME": cmdidx = %d\n", cmd->cmdidx);
618 ret = sh_sdhi_error_manage(host);
627 if (sh_sdhi_readw(host, SDHI_INFO1) & INFO1_RESP_END) {
632 if (host->wait_int) {
633 sh_sdhi_get_response(host, cmd);
638 ret = sh_sdhi_data_trans(host, data, opc);
640 debug("ret = %d, resp = %08x, %08x, %08x, %08x\n",
641 ret, cmd->response[0], cmd->response[1],
642 cmd->response[2], cmd->response[3]);
646 static int sh_sdhi_send_cmd_common(struct sh_sdhi_host *host,
647 struct mmc_cmd *cmd, struct mmc_data *data)
651 return sh_sdhi_start_cmd(host, data, cmd);
654 static int sh_sdhi_set_ios_common(struct sh_sdhi_host *host, struct mmc *mmc)
658 ret = sh_sdhi_clock_control(host, mmc->clock);
662 if (mmc->bus_width == 8)
663 sh_sdhi_writew(host, SDHI_OPTION,
664 OPT_BUS_WIDTH_8 | (~OPT_BUS_WIDTH_M &
665 sh_sdhi_readw(host, SDHI_OPTION)));
666 else if (mmc->bus_width == 4)
667 sh_sdhi_writew(host, SDHI_OPTION,
668 OPT_BUS_WIDTH_4 | (~OPT_BUS_WIDTH_M &
669 sh_sdhi_readw(host, SDHI_OPTION)));
671 sh_sdhi_writew(host, SDHI_OPTION,
672 OPT_BUS_WIDTH_1 | (~OPT_BUS_WIDTH_M &
673 sh_sdhi_readw(host, SDHI_OPTION)));
675 debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width);
680 static int sh_sdhi_initialize_common(struct sh_sdhi_host *host)
682 int ret = sh_sdhi_sync_reset(host);
684 sh_sdhi_writew(host, SDHI_PORTSEL, USE_1PORT);
686 #if defined(__BIG_ENDIAN_BITFIELD)
687 sh_sdhi_writew(host, SDHI_EXT_SWAP, SET_SWAP);
690 sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END |
691 INFO1M_ACCESS_END | INFO1M_CARD_RE |
692 INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
697 #ifndef CONFIG_DM_MMC
698 static void *mmc_priv(struct mmc *mmc)
700 return (void *)mmc->priv;
703 static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
704 struct mmc_data *data)
706 struct sh_sdhi_host *host = mmc_priv(mmc);
708 return sh_sdhi_send_cmd_common(host, cmd, data);
711 static int sh_sdhi_set_ios(struct mmc *mmc)
713 struct sh_sdhi_host *host = mmc_priv(mmc);
715 return sh_sdhi_set_ios_common(host, mmc);
718 static int sh_sdhi_initialize(struct mmc *mmc)
720 struct sh_sdhi_host *host = mmc_priv(mmc);
722 return sh_sdhi_initialize_common(host);
725 static const struct mmc_ops sh_sdhi_ops = {
726 .send_cmd = sh_sdhi_send_cmd,
727 .set_ios = sh_sdhi_set_ios,
728 .init = sh_sdhi_initialize,
731 #ifdef CONFIG_RCAR_GEN3
732 static struct mmc_config sh_sdhi_cfg = {
735 .f_min = CLKDEV_INIT,
736 .f_max = CLKDEV_HS_DATA,
737 .voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
738 .host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HS |
740 .part_type = PART_TYPE_DOS,
741 .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
744 static struct mmc_config sh_sdhi_cfg = {
747 .f_min = CLKDEV_INIT,
748 .f_max = CLKDEV_HS_DATA,
749 .voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
750 .host_caps = MMC_MODE_4BIT | MMC_MODE_HS,
751 .part_type = PART_TYPE_DOS,
752 .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
756 int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks)
760 struct sh_sdhi_host *host = NULL;
762 if (ch >= CONFIG_SYS_SH_SDHI_NR_CHANNEL)
765 host = malloc(sizeof(struct sh_sdhi_host));
769 mmc = mmc_create(&sh_sdhi_cfg, host);
776 host->addr = (void __iomem *)addr;
777 host->quirks = quirks;
779 if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
781 else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
793 struct sh_sdhi_plat {
794 struct mmc_config cfg;
798 int sh_sdhi_dm_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
799 struct mmc_data *data)
801 struct sh_sdhi_host *host = dev_get_priv(dev);
803 return sh_sdhi_send_cmd_common(host, cmd, data);
806 int sh_sdhi_dm_set_ios(struct udevice *dev)
808 struct sh_sdhi_host *host = dev_get_priv(dev);
809 struct mmc *mmc = mmc_get_mmc_dev(dev);
811 return sh_sdhi_set_ios_common(host, mmc);
814 static const struct dm_mmc_ops sh_sdhi_dm_ops = {
815 .send_cmd = sh_sdhi_dm_send_cmd,
816 .set_ios = sh_sdhi_dm_set_ios,
819 static int sh_sdhi_dm_bind(struct udevice *dev)
821 struct sh_sdhi_plat *plat = dev_get_platdata(dev);
823 return mmc_bind(dev, &plat->mmc, &plat->cfg);
826 static int sh_sdhi_dm_probe(struct udevice *dev)
828 struct sh_sdhi_plat *plat = dev_get_platdata(dev);
829 struct sh_sdhi_host *host = dev_get_priv(dev);
830 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
831 struct clk sh_sdhi_clk;
832 const u32 quirks = dev_get_driver_data(dev);
836 base = devfdt_get_addr(dev);
837 if (base == FDT_ADDR_T_NONE)
840 host->addr = devm_ioremap(dev, base, SZ_2K);
844 ret = clk_get_by_index(dev, 0, &sh_sdhi_clk);
846 debug("failed to get clock, ret=%d\n", ret);
850 ret = clk_enable(&sh_sdhi_clk);
852 debug("failed to enable clock, ret=%d\n", ret);
856 host->quirks = quirks;
858 if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
860 else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
863 plat->cfg.name = dev->name;
864 plat->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
866 switch (fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width",
869 plat->cfg.host_caps |= MMC_MODE_8BIT;
872 plat->cfg.host_caps |= MMC_MODE_4BIT;
877 dev_err(dev, "Invalid \"bus-width\" value\n");
881 sh_sdhi_initialize_common(host);
883 plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
884 plat->cfg.f_min = CLKDEV_INIT;
885 plat->cfg.f_max = CLKDEV_HS_DATA;
886 plat->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
888 upriv->mmc = &plat->mmc;
893 static const struct udevice_id sh_sdhi_sd_match[] = {
894 { .compatible = "renesas,sdhi-r8a7795", .data = SH_SDHI_QUIRK_64BIT_BUF },
895 { .compatible = "renesas,sdhi-r8a7796", .data = SH_SDHI_QUIRK_64BIT_BUF },
899 U_BOOT_DRIVER(sh_sdhi_mmc) = {
900 .name = "sh-sdhi-mmc",
902 .of_match = sh_sdhi_sd_match,
903 .bind = sh_sdhi_dm_bind,
904 .probe = sh_sdhi_dm_probe,
905 .priv_auto_alloc_size = sizeof(struct sh_sdhi_host),
906 .platdata_auto_alloc_size = sizeof(struct sh_sdhi_plat),
907 .ops = &sh_sdhi_dm_ops,