2 * drivers/mmc/sh_sdhi.c
4 * SD/MMC driver for Renesas rmobile ARM SoCs.
6 * Copyright (C) 2011,2013-2017 Renesas Electronics Corporation
7 * Copyright (C) 2014 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
8 * Copyright (C) 2008-2009 Renesas Solutions Corp.
10 * SPDX-License-Identifier: GPL-2.0
17 #include <linux/errno.h>
18 #include <linux/compat.h>
20 #include <linux/sizes.h>
21 #include <asm/arch/rmobile.h>
22 #include <asm/arch/sh_sdhi.h>
24 #define DRIVER_NAME "sh-sdhi"
31 unsigned char wait_int
;
32 unsigned char sd_error
;
33 unsigned char detect_waiting
;
36 static inline void sh_sdhi_writeq(struct sh_sdhi_host
*host
, int reg
, u64 val
)
38 writeq(val
, host
->addr
+ (reg
<< host
->bus_shift
));
41 static inline u64
sh_sdhi_readq(struct sh_sdhi_host
*host
, int reg
)
43 return readq(host
->addr
+ (reg
<< host
->bus_shift
));
46 static inline void sh_sdhi_writew(struct sh_sdhi_host
*host
, int reg
, u16 val
)
48 writew(val
, host
->addr
+ (reg
<< host
->bus_shift
));
51 static inline u16
sh_sdhi_readw(struct sh_sdhi_host
*host
, int reg
)
53 return readw(host
->addr
+ (reg
<< host
->bus_shift
));
56 static void sh_sdhi_detect(struct sh_sdhi_host
*host
)
58 sh_sdhi_writew(host
, SDHI_OPTION
,
59 OPT_BUS_WIDTH_1
| sh_sdhi_readw(host
, SDHI_OPTION
));
61 host
->detect_waiting
= 0;
64 static int sh_sdhi_intr(void *dev_id
)
66 struct sh_sdhi_host
*host
= dev_id
;
67 int state1
= 0, state2
= 0;
69 state1
= sh_sdhi_readw(host
, SDHI_INFO1
);
70 state2
= sh_sdhi_readw(host
, SDHI_INFO2
);
72 debug("%s: state1 = %x, state2 = %x\n", __func__
, state1
, state2
);
75 if (state1
& INFO1_CARD_IN
) {
76 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_CARD_IN
);
77 if (!host
->detect_waiting
) {
78 host
->detect_waiting
= 1;
81 sh_sdhi_writew(host
, SDHI_INFO1_MASK
, INFO1M_RESP_END
|
82 INFO1M_ACCESS_END
| INFO1M_CARD_IN
|
83 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
87 if (state1
& INFO1_CARD_RE
) {
88 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_CARD_RE
);
89 if (!host
->detect_waiting
) {
90 host
->detect_waiting
= 1;
93 sh_sdhi_writew(host
, SDHI_INFO1_MASK
, INFO1M_RESP_END
|
94 INFO1M_ACCESS_END
| INFO1M_CARD_RE
|
95 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
96 sh_sdhi_writew(host
, SDHI_SDIO_INFO1_MASK
, SDIO_INFO1M_ON
);
97 sh_sdhi_writew(host
, SDHI_SDIO_MODE
, SDIO_MODE_OFF
);
101 if (state2
& INFO2_ALL_ERR
) {
102 sh_sdhi_writew(host
, SDHI_INFO2
,
103 (unsigned short)~(INFO2_ALL_ERR
));
104 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
106 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
112 if (state1
& INFO1_RESP_END
) {
113 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_RESP_END
);
114 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
116 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
120 /* SD_BUF Read Enable */
121 if (state2
& INFO2_BRE_ENABLE
) {
122 sh_sdhi_writew(host
, SDHI_INFO2
, ~INFO2_BRE_ENABLE
);
123 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
124 INFO2M_BRE_ENABLE
| INFO2M_BUF_ILL_READ
|
125 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
129 /* SD_BUF Write Enable */
130 if (state2
& INFO2_BWE_ENABLE
) {
131 sh_sdhi_writew(host
, SDHI_INFO2
, ~INFO2_BWE_ENABLE
);
132 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
133 INFO2_BWE_ENABLE
| INFO2M_BUF_ILL_WRITE
|
134 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
139 if (state1
& INFO1_ACCESS_END
) {
140 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_ACCESS_END
);
141 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
143 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
150 static int sh_sdhi_wait_interrupt_flag(struct sh_sdhi_host
*host
)
152 int timeout
= 10000000;
157 debug(DRIVER_NAME
": %s timeout\n", __func__
);
161 if (!sh_sdhi_intr(host
))
164 udelay(1); /* 1 usec */
167 return 1; /* Return value: NOT 0 = complete waiting */
170 static int sh_sdhi_clock_control(struct sh_sdhi_host
*host
, unsigned long clk
)
172 u32 clkdiv
, i
, timeout
;
174 if (sh_sdhi_readw(host
, SDHI_INFO2
) & (1 << 14)) {
175 printf(DRIVER_NAME
": Busy state ! Cannot change the clock\n");
179 sh_sdhi_writew(host
, SDHI_CLK_CTRL
,
180 ~CLK_ENABLE
& sh_sdhi_readw(host
, SDHI_CLK_CTRL
));
186 i
= CONFIG_SH_SDHI_FREQ
>> (0x8 + 1);
187 for (; clkdiv
&& clk
>= (i
<< 1); (clkdiv
>>= 1))
190 sh_sdhi_writew(host
, SDHI_CLK_CTRL
, clkdiv
);
193 /* Waiting for SD Bus busy to be cleared */
195 if ((sh_sdhi_readw(host
, SDHI_INFO2
) & 0x2000))
200 sh_sdhi_writew(host
, SDHI_CLK_CTRL
,
201 CLK_ENABLE
| sh_sdhi_readw(host
, SDHI_CLK_CTRL
));
208 static int sh_sdhi_sync_reset(struct sh_sdhi_host
*host
)
211 sh_sdhi_writew(host
, SDHI_SOFT_RST
, SOFT_RST_ON
);
212 sh_sdhi_writew(host
, SDHI_SOFT_RST
, SOFT_RST_OFF
);
213 sh_sdhi_writew(host
, SDHI_CLK_CTRL
,
214 CLK_ENABLE
| sh_sdhi_readw(host
, SDHI_CLK_CTRL
));
218 if (!(sh_sdhi_readw(host
, SDHI_INFO2
) & INFO2_CBUSY
))
226 if (host
->quirks
& SH_SDHI_QUIRK_16BIT_BUF
)
227 sh_sdhi_writew(host
, SDHI_HOST_MODE
, 1);
232 static int sh_sdhi_error_manage(struct sh_sdhi_host
*host
)
234 unsigned short e_state1
, e_state2
;
240 e_state1
= sh_sdhi_readw(host
, SDHI_ERR_STS1
);
241 e_state2
= sh_sdhi_readw(host
, SDHI_ERR_STS2
);
242 if (e_state2
& ERR_STS2_SYS_ERROR
) {
243 if (e_state2
& ERR_STS2_RES_STOP_TIMEOUT
)
247 debug("%s: ERR_STS2 = %04x\n",
248 DRIVER_NAME
, sh_sdhi_readw(host
, SDHI_ERR_STS2
));
249 sh_sdhi_sync_reset(host
);
251 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
252 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
255 if (e_state1
& ERR_STS1_CRC_ERROR
|| e_state1
& ERR_STS1_CMD_ERROR
)
260 debug("%s: ERR_STS1 = %04x\n",
261 DRIVER_NAME
, sh_sdhi_readw(host
, SDHI_ERR_STS1
));
262 sh_sdhi_sync_reset(host
);
263 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
264 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
268 static int sh_sdhi_single_read(struct sh_sdhi_host
*host
, struct mmc_data
*data
)
271 unsigned short blocksize
, i
;
272 unsigned short *p
= (unsigned short *)data
->dest
;
273 u64
*q
= (u64
*)data
->dest
;
275 if ((unsigned long)p
& 0x00000001) {
276 debug(DRIVER_NAME
": %s: The data pointer is unaligned.",
282 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
283 ~(INFO2M_BRE_ENABLE
| INFO2M_BUF_ILL_READ
) &
284 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
285 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
287 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
288 time
= sh_sdhi_wait_interrupt_flag(host
);
289 if (time
== 0 || host
->sd_error
!= 0)
290 return sh_sdhi_error_manage(host
);
293 blocksize
= sh_sdhi_readw(host
, SDHI_SIZE
);
294 if (host
->quirks
& SH_SDHI_QUIRK_64BIT_BUF
)
295 for (i
= 0; i
< blocksize
/ 8; i
++)
296 *q
++ = sh_sdhi_readq(host
, SDHI_BUF0
);
298 for (i
= 0; i
< blocksize
/ 2; i
++)
299 *p
++ = sh_sdhi_readw(host
, SDHI_BUF0
);
301 time
= sh_sdhi_wait_interrupt_flag(host
);
302 if (time
== 0 || host
->sd_error
!= 0)
303 return sh_sdhi_error_manage(host
);
309 static int sh_sdhi_multi_read(struct sh_sdhi_host
*host
, struct mmc_data
*data
)
312 unsigned short blocksize
, i
, sec
;
313 unsigned short *p
= (unsigned short *)data
->dest
;
314 u64
*q
= (u64
*)data
->dest
;
316 if ((unsigned long)p
& 0x00000001) {
317 debug(DRIVER_NAME
": %s: The data pointer is unaligned.",
322 debug("%s: blocks = %d, blocksize = %d\n",
323 __func__
, data
->blocks
, data
->blocksize
);
326 for (sec
= 0; sec
< data
->blocks
; sec
++) {
327 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
328 ~(INFO2M_BRE_ENABLE
| INFO2M_BUF_ILL_READ
) &
329 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
331 time
= sh_sdhi_wait_interrupt_flag(host
);
332 if (time
== 0 || host
->sd_error
!= 0)
333 return sh_sdhi_error_manage(host
);
336 blocksize
= sh_sdhi_readw(host
, SDHI_SIZE
);
337 if (host
->quirks
& SH_SDHI_QUIRK_64BIT_BUF
)
338 for (i
= 0; i
< blocksize
/ 8; i
++)
339 *q
++ = sh_sdhi_readq(host
, SDHI_BUF0
);
341 for (i
= 0; i
< blocksize
/ 2; i
++)
342 *p
++ = sh_sdhi_readw(host
, SDHI_BUF0
);
348 static int sh_sdhi_single_write(struct sh_sdhi_host
*host
,
349 struct mmc_data
*data
)
352 unsigned short blocksize
, i
;
353 const unsigned short *p
= (const unsigned short *)data
->src
;
354 const u64
*q
= (const u64
*)data
->src
;
356 if ((unsigned long)p
& 0x00000001) {
357 debug(DRIVER_NAME
": %s: The data pointer is unaligned.",
362 debug("%s: blocks = %d, blocksize = %d\n",
363 __func__
, data
->blocks
, data
->blocksize
);
366 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
367 ~(INFO2M_BWE_ENABLE
| INFO2M_BUF_ILL_WRITE
) &
368 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
369 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
371 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
373 time
= sh_sdhi_wait_interrupt_flag(host
);
374 if (time
== 0 || host
->sd_error
!= 0)
375 return sh_sdhi_error_manage(host
);
378 blocksize
= sh_sdhi_readw(host
, SDHI_SIZE
);
379 if (host
->quirks
& SH_SDHI_QUIRK_64BIT_BUF
)
380 for (i
= 0; i
< blocksize
/ 8; i
++)
381 sh_sdhi_writeq(host
, SDHI_BUF0
, *q
++);
383 for (i
= 0; i
< blocksize
/ 2; i
++)
384 sh_sdhi_writew(host
, SDHI_BUF0
, *p
++);
386 time
= sh_sdhi_wait_interrupt_flag(host
);
387 if (time
== 0 || host
->sd_error
!= 0)
388 return sh_sdhi_error_manage(host
);
394 static int sh_sdhi_multi_write(struct sh_sdhi_host
*host
, struct mmc_data
*data
)
397 unsigned short i
, sec
, blocksize
;
398 const unsigned short *p
= (const unsigned short *)data
->src
;
399 const u64
*q
= (const u64
*)data
->src
;
401 debug("%s: blocks = %d, blocksize = %d\n",
402 __func__
, data
->blocks
, data
->blocksize
);
405 for (sec
= 0; sec
< data
->blocks
; sec
++) {
406 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
407 ~(INFO2M_BWE_ENABLE
| INFO2M_BUF_ILL_WRITE
) &
408 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
410 time
= sh_sdhi_wait_interrupt_flag(host
);
411 if (time
== 0 || host
->sd_error
!= 0)
412 return sh_sdhi_error_manage(host
);
415 blocksize
= sh_sdhi_readw(host
, SDHI_SIZE
);
416 if (host
->quirks
& SH_SDHI_QUIRK_64BIT_BUF
)
417 for (i
= 0; i
< blocksize
/ 8; i
++)
418 sh_sdhi_writeq(host
, SDHI_BUF0
, *q
++);
420 for (i
= 0; i
< blocksize
/ 2; i
++)
421 sh_sdhi_writew(host
, SDHI_BUF0
, *p
++);
427 static void sh_sdhi_get_response(struct sh_sdhi_host
*host
, struct mmc_cmd
*cmd
)
429 unsigned short i
, j
, cnt
= 1;
430 unsigned short resp
[8];
432 if (cmd
->resp_type
& MMC_RSP_136
) {
434 resp
[0] = sh_sdhi_readw(host
, SDHI_RSP00
);
435 resp
[1] = sh_sdhi_readw(host
, SDHI_RSP01
);
436 resp
[2] = sh_sdhi_readw(host
, SDHI_RSP02
);
437 resp
[3] = sh_sdhi_readw(host
, SDHI_RSP03
);
438 resp
[4] = sh_sdhi_readw(host
, SDHI_RSP04
);
439 resp
[5] = sh_sdhi_readw(host
, SDHI_RSP05
);
440 resp
[6] = sh_sdhi_readw(host
, SDHI_RSP06
);
441 resp
[7] = sh_sdhi_readw(host
, SDHI_RSP07
);
443 /* SDHI REGISTER SPECIFICATION */
444 for (i
= 7, j
= 6; i
> 0; i
--) {
445 resp
[i
] = (resp
[i
] << 8) & 0xff00;
446 resp
[i
] |= (resp
[j
--] >> 8) & 0x00ff;
448 resp
[0] = (resp
[0] << 8) & 0xff00;
450 resp
[0] = sh_sdhi_readw(host
, SDHI_RSP00
);
451 resp
[1] = sh_sdhi_readw(host
, SDHI_RSP01
);
454 #if defined(__BIG_ENDIAN_BITFIELD)
456 cmd
->response
[0] = (resp
[6] << 16) | resp
[7];
457 cmd
->response
[1] = (resp
[4] << 16) | resp
[5];
458 cmd
->response
[2] = (resp
[2] << 16) | resp
[3];
459 cmd
->response
[3] = (resp
[0] << 16) | resp
[1];
461 cmd
->response
[0] = (resp
[0] << 16) | resp
[1];
465 cmd
->response
[0] = (resp
[7] << 16) | resp
[6];
466 cmd
->response
[1] = (resp
[5] << 16) | resp
[4];
467 cmd
->response
[2] = (resp
[3] << 16) | resp
[2];
468 cmd
->response
[3] = (resp
[1] << 16) | resp
[0];
470 cmd
->response
[0] = (resp
[1] << 16) | resp
[0];
472 #endif /* __BIG_ENDIAN_BITFIELD */
475 static unsigned short sh_sdhi_set_cmd(struct sh_sdhi_host
*host
,
476 struct mmc_data
*data
, unsigned short opc
)
479 case SD_CMD_APP_SEND_OP_COND
:
480 case SD_CMD_APP_SEND_SCR
:
483 case SD_CMD_APP_SET_BUS_WIDTH
:
484 /* SD_APP_SET_BUS_WIDTH*/
488 opc
= SDHI_SD_SWITCH
;
490 case MMC_CMD_SEND_OP_COND
:
491 opc
= SDHI_MMC_SEND_OP_COND
;
493 case MMC_CMD_SEND_EXT_CSD
:
495 opc
= SDHI_MMC_SEND_EXT_CSD
;
503 static unsigned short sh_sdhi_data_trans(struct sh_sdhi_host
*host
,
504 struct mmc_data
*data
, unsigned short opc
)
509 case MMC_CMD_READ_MULTIPLE_BLOCK
:
510 ret
= sh_sdhi_multi_read(host
, data
);
512 case MMC_CMD_WRITE_MULTIPLE_BLOCK
:
513 ret
= sh_sdhi_multi_write(host
, data
);
515 case MMC_CMD_WRITE_SINGLE_BLOCK
:
516 ret
= sh_sdhi_single_write(host
, data
);
518 case MMC_CMD_READ_SINGLE_BLOCK
:
519 case SDHI_SD_APP_SEND_SCR
:
520 case SDHI_SD_SWITCH
: /* SD_SWITCH */
521 case SDHI_MMC_SEND_EXT_CSD
:
522 ret
= sh_sdhi_single_read(host
, data
);
525 printf(DRIVER_NAME
": SD: NOT SUPPORT CMD = d'%04d\n", opc
);
532 static int sh_sdhi_start_cmd(struct sh_sdhi_host
*host
,
533 struct mmc_data
*data
, struct mmc_cmd
*cmd
)
536 unsigned short opc
= cmd
->cmdidx
;
538 unsigned long timeout
;
540 debug("opc = %d, arg = %x, resp_type = %x\n",
541 opc
, cmd
->cmdarg
, cmd
->resp_type
);
543 if (opc
== MMC_CMD_STOP_TRANSMISSION
) {
544 /* SDHI sends the STOP command automatically by STOP reg */
545 sh_sdhi_writew(host
, SDHI_INFO1_MASK
, ~INFO1M_ACCESS_END
&
546 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
548 time
= sh_sdhi_wait_interrupt_flag(host
);
549 if (time
== 0 || host
->sd_error
!= 0)
550 return sh_sdhi_error_manage(host
);
552 sh_sdhi_get_response(host
, cmd
);
557 if ((opc
== MMC_CMD_READ_MULTIPLE_BLOCK
) ||
558 opc
== MMC_CMD_WRITE_MULTIPLE_BLOCK
) {
559 sh_sdhi_writew(host
, SDHI_STOP
, STOP_SEC_ENABLE
);
560 sh_sdhi_writew(host
, SDHI_SECCNT
, data
->blocks
);
562 sh_sdhi_writew(host
, SDHI_SIZE
, data
->blocksize
);
564 opc
= sh_sdhi_set_cmd(host
, data
, opc
);
567 * U-Boot cannot use interrupt.
568 * So this flag may not be clear by timing
570 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_RESP_END
);
572 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
573 INFO1M_RESP_END
| sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
574 sh_sdhi_writew(host
, SDHI_ARG0
,
575 (unsigned short)(cmd
->cmdarg
& ARG0_MASK
));
576 sh_sdhi_writew(host
, SDHI_ARG1
,
577 (unsigned short)((cmd
->cmdarg
>> 16) & ARG1_MASK
));
580 /* Waiting for SD Bus busy to be cleared */
582 if ((sh_sdhi_readw(host
, SDHI_INFO2
) & 0x2000))
587 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
588 ~INFO1M_RESP_END
& sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
589 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
590 ~(INFO2M_CMD_ERROR
| INFO2M_CRC_ERROR
|
591 INFO2M_END_ERROR
| INFO2M_TIMEOUT
|
592 INFO2M_RESP_TIMEOUT
| INFO2M_ILA
) &
593 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
595 sh_sdhi_writew(host
, SDHI_CMD
, (unsigned short)(opc
& CMD_MASK
));
597 time
= sh_sdhi_wait_interrupt_flag(host
);
599 return sh_sdhi_error_manage(host
);
601 if (host
->sd_error
) {
602 switch (cmd
->cmdidx
) {
603 case MMC_CMD_ALL_SEND_CID
:
604 case MMC_CMD_SELECT_CARD
:
605 case SD_CMD_SEND_IF_COND
:
606 case MMC_CMD_APP_CMD
:
610 debug(DRIVER_NAME
": Cmd(d'%d) err\n", opc
);
611 debug(DRIVER_NAME
": cmdidx = %d\n", cmd
->cmdidx
);
612 ret
= sh_sdhi_error_manage(host
);
619 if (sh_sdhi_readw(host
, SDHI_INFO1
) & INFO1_RESP_END
)
622 if (host
->wait_int
) {
623 sh_sdhi_get_response(host
, cmd
);
627 ret
= sh_sdhi_data_trans(host
, data
, opc
);
629 debug("ret = %d, resp = %08x, %08x, %08x, %08x\n",
630 ret
, cmd
->response
[0], cmd
->response
[1],
631 cmd
->response
[2], cmd
->response
[3]);
635 static int sh_sdhi_send_cmd_common(struct sh_sdhi_host
*host
,
636 struct mmc_cmd
*cmd
, struct mmc_data
*data
)
640 return sh_sdhi_start_cmd(host
, data
, cmd
);
643 static int sh_sdhi_set_ios_common(struct sh_sdhi_host
*host
, struct mmc
*mmc
)
647 ret
= sh_sdhi_clock_control(host
, mmc
->clock
);
651 if (mmc
->bus_width
== 8)
652 sh_sdhi_writew(host
, SDHI_OPTION
,
653 OPT_BUS_WIDTH_8
| (~OPT_BUS_WIDTH_M
&
654 sh_sdhi_readw(host
, SDHI_OPTION
)));
655 else if (mmc
->bus_width
== 4)
656 sh_sdhi_writew(host
, SDHI_OPTION
,
657 OPT_BUS_WIDTH_4
| (~OPT_BUS_WIDTH_M
&
658 sh_sdhi_readw(host
, SDHI_OPTION
)));
660 sh_sdhi_writew(host
, SDHI_OPTION
,
661 OPT_BUS_WIDTH_1
| (~OPT_BUS_WIDTH_M
&
662 sh_sdhi_readw(host
, SDHI_OPTION
)));
664 debug("clock = %d, buswidth = %d\n", mmc
->clock
, mmc
->bus_width
);
669 static int sh_sdhi_initialize_common(struct sh_sdhi_host
*host
)
671 int ret
= sh_sdhi_sync_reset(host
);
673 sh_sdhi_writew(host
, SDHI_PORTSEL
, USE_1PORT
);
675 #if defined(__BIG_ENDIAN_BITFIELD)
676 sh_sdhi_writew(host
, SDHI_EXT_SWAP
, SET_SWAP
);
679 sh_sdhi_writew(host
, SDHI_INFO1_MASK
, INFO1M_RESP_END
|
680 INFO1M_ACCESS_END
| INFO1M_CARD_RE
|
681 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
686 #ifndef CONFIG_DM_MMC
687 static void *mmc_priv(struct mmc
*mmc
)
689 return (void *)mmc
->priv
;
692 static int sh_sdhi_send_cmd(struct mmc
*mmc
, struct mmc_cmd
*cmd
,
693 struct mmc_data
*data
)
695 struct sh_sdhi_host
*host
= mmc_priv(mmc
);
697 return sh_sdhi_send_cmd_common(host
, cmd
, data
);
700 static int sh_sdhi_set_ios(struct mmc
*mmc
)
702 struct sh_sdhi_host
*host
= mmc_priv(mmc
);
704 return sh_sdhi_set_ios_common(host
, mmc
);
707 static int sh_sdhi_initialize(struct mmc
*mmc
)
709 struct sh_sdhi_host
*host
= mmc_priv(mmc
);
711 return sh_sdhi_initialize_common(host
);
714 static const struct mmc_ops sh_sdhi_ops
= {
715 .send_cmd
= sh_sdhi_send_cmd
,
716 .set_ios
= sh_sdhi_set_ios
,
717 .init
= sh_sdhi_initialize
,
720 #ifdef CONFIG_RCAR_GEN3
721 static struct mmc_config sh_sdhi_cfg
= {
724 .f_min
= CLKDEV_INIT
,
725 .f_max
= CLKDEV_HS_DATA
,
726 .voltages
= MMC_VDD_165_195
| MMC_VDD_32_33
| MMC_VDD_33_34
,
727 .host_caps
= MMC_MODE_4BIT
| MMC_MODE_8BIT
| MMC_MODE_HS
|
729 .part_type
= PART_TYPE_DOS
,
730 .b_max
= CONFIG_SYS_MMC_MAX_BLK_COUNT
,
733 static struct mmc_config sh_sdhi_cfg
= {
736 .f_min
= CLKDEV_INIT
,
737 .f_max
= CLKDEV_HS_DATA
,
738 .voltages
= MMC_VDD_32_33
| MMC_VDD_33_34
,
739 .host_caps
= MMC_MODE_4BIT
| MMC_MODE_HS
,
740 .part_type
= PART_TYPE_DOS
,
741 .b_max
= CONFIG_SYS_MMC_MAX_BLK_COUNT
,
745 int sh_sdhi_init(unsigned long addr
, int ch
, unsigned long quirks
)
749 struct sh_sdhi_host
*host
= NULL
;
751 if (ch
>= CONFIG_SYS_SH_SDHI_NR_CHANNEL
)
754 host
= malloc(sizeof(struct sh_sdhi_host
));
758 mmc
= mmc_create(&sh_sdhi_cfg
, host
);
765 host
->addr
= (void __iomem
*)addr
;
766 host
->quirks
= quirks
;
768 if (host
->quirks
& SH_SDHI_QUIRK_64BIT_BUF
)
770 else if (host
->quirks
& SH_SDHI_QUIRK_16BIT_BUF
)
782 struct sh_sdhi_plat
{
783 struct mmc_config cfg
;
787 int sh_sdhi_dm_send_cmd(struct udevice
*dev
, struct mmc_cmd
*cmd
,
788 struct mmc_data
*data
)
790 struct sh_sdhi_host
*host
= dev_get_priv(dev
);
792 return sh_sdhi_send_cmd_common(host
, cmd
, data
);
795 int sh_sdhi_dm_set_ios(struct udevice
*dev
)
797 struct sh_sdhi_host
*host
= dev_get_priv(dev
);
798 struct mmc
*mmc
= mmc_get_mmc_dev(dev
);
800 return sh_sdhi_set_ios_common(host
, mmc
);
803 static const struct dm_mmc_ops sh_sdhi_dm_ops
= {
804 .send_cmd
= sh_sdhi_dm_send_cmd
,
805 .set_ios
= sh_sdhi_dm_set_ios
,
808 static int sh_sdhi_dm_bind(struct udevice
*dev
)
810 struct sh_sdhi_plat
*plat
= dev_get_platdata(dev
);
812 return mmc_bind(dev
, &plat
->mmc
, &plat
->cfg
);
815 static int sh_sdhi_dm_probe(struct udevice
*dev
)
817 struct sh_sdhi_plat
*plat
= dev_get_platdata(dev
);
818 struct sh_sdhi_host
*host
= dev_get_priv(dev
);
819 struct mmc_uclass_priv
*upriv
= dev_get_uclass_priv(dev
);
820 const u32 quirks
= dev_get_driver_data(dev
);
823 base
= devfdt_get_addr(dev
);
824 if (base
== FDT_ADDR_T_NONE
)
827 host
->addr
= devm_ioremap(dev
, base
, SZ_2K
);
831 host
->quirks
= quirks
;
833 if (host
->quirks
& SH_SDHI_QUIRK_64BIT_BUF
)
835 else if (host
->quirks
& SH_SDHI_QUIRK_16BIT_BUF
)
838 plat
->cfg
.name
= dev
->name
;
839 plat
->cfg
.host_caps
= MMC_MODE_HS_52MHz
| MMC_MODE_HS
;
841 switch (fdtdec_get_int(gd
->fdt_blob
, dev_of_offset(dev
), "bus-width",
844 plat
->cfg
.host_caps
|= MMC_MODE_8BIT
;
847 plat
->cfg
.host_caps
|= MMC_MODE_4BIT
;
852 dev_err(dev
, "Invalid \"bus-width\" value\n");
856 sh_sdhi_initialize_common(host
);
858 plat
->cfg
.voltages
= MMC_VDD_165_195
| MMC_VDD_32_33
| MMC_VDD_33_34
;
859 plat
->cfg
.f_min
= CLKDEV_INIT
;
860 plat
->cfg
.f_max
= CLKDEV_HS_DATA
;
861 plat
->cfg
.b_max
= CONFIG_SYS_MMC_MAX_BLK_COUNT
;
863 upriv
->mmc
= &plat
->mmc
;
868 static const struct udevice_id sh_sdhi_sd_match
[] = {
869 { .compatible
= "renesas,sdhi-r8a7795", .data
= SH_SDHI_QUIRK_64BIT_BUF
},
870 { .compatible
= "renesas,sdhi-r8a7796", .data
= SH_SDHI_QUIRK_64BIT_BUF
},
874 U_BOOT_DRIVER(sh_sdhi_mmc
) = {
875 .name
= "sh-sdhi-mmc",
877 .of_match
= sh_sdhi_sd_match
,
878 .bind
= sh_sdhi_dm_bind
,
879 .probe
= sh_sdhi_dm_probe
,
880 .priv_auto_alloc_size
= sizeof(struct sh_sdhi_host
),
881 .platdata_auto_alloc_size
= sizeof(struct sh_sdhi_plat
),
882 .ops
= &sh_sdhi_dm_ops
,