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>
25 #define DRIVER_NAME "sh-sdhi"
32 unsigned char wait_int
;
33 unsigned char sd_error
;
34 unsigned char detect_waiting
;
35 unsigned char app_cmd
;
38 static inline void sh_sdhi_writeq(struct sh_sdhi_host
*host
, int reg
, u64 val
)
40 writeq(val
, host
->addr
+ (reg
<< host
->bus_shift
));
43 static inline u64
sh_sdhi_readq(struct sh_sdhi_host
*host
, int reg
)
45 return readq(host
->addr
+ (reg
<< host
->bus_shift
));
48 static inline void sh_sdhi_writew(struct sh_sdhi_host
*host
, int reg
, u16 val
)
50 writew(val
, host
->addr
+ (reg
<< host
->bus_shift
));
53 static inline u16
sh_sdhi_readw(struct sh_sdhi_host
*host
, int reg
)
55 return readw(host
->addr
+ (reg
<< host
->bus_shift
));
58 static void sh_sdhi_detect(struct sh_sdhi_host
*host
)
60 sh_sdhi_writew(host
, SDHI_OPTION
,
61 OPT_BUS_WIDTH_1
| sh_sdhi_readw(host
, SDHI_OPTION
));
63 host
->detect_waiting
= 0;
66 static int sh_sdhi_intr(void *dev_id
)
68 struct sh_sdhi_host
*host
= dev_id
;
69 int state1
= 0, state2
= 0;
71 state1
= sh_sdhi_readw(host
, SDHI_INFO1
);
72 state2
= sh_sdhi_readw(host
, SDHI_INFO2
);
74 debug("%s: state1 = %x, state2 = %x\n", __func__
, state1
, state2
);
77 if (state1
& INFO1_CARD_IN
) {
78 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_CARD_IN
);
79 if (!host
->detect_waiting
) {
80 host
->detect_waiting
= 1;
83 sh_sdhi_writew(host
, SDHI_INFO1_MASK
, INFO1M_RESP_END
|
84 INFO1M_ACCESS_END
| INFO1M_CARD_IN
|
85 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
89 if (state1
& INFO1_CARD_RE
) {
90 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_CARD_RE
);
91 if (!host
->detect_waiting
) {
92 host
->detect_waiting
= 1;
95 sh_sdhi_writew(host
, SDHI_INFO1_MASK
, INFO1M_RESP_END
|
96 INFO1M_ACCESS_END
| INFO1M_CARD_RE
|
97 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
98 sh_sdhi_writew(host
, SDHI_SDIO_INFO1_MASK
, SDIO_INFO1M_ON
);
99 sh_sdhi_writew(host
, SDHI_SDIO_MODE
, SDIO_MODE_OFF
);
103 if (state2
& INFO2_ALL_ERR
) {
104 sh_sdhi_writew(host
, SDHI_INFO2
,
105 (unsigned short)~(INFO2_ALL_ERR
));
106 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
108 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
114 if (state1
& INFO1_RESP_END
) {
115 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_RESP_END
);
116 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
118 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
122 /* SD_BUF Read Enable */
123 if (state2
& INFO2_BRE_ENABLE
) {
124 sh_sdhi_writew(host
, SDHI_INFO2
, ~INFO2_BRE_ENABLE
);
125 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
126 INFO2M_BRE_ENABLE
| INFO2M_BUF_ILL_READ
|
127 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
131 /* SD_BUF Write Enable */
132 if (state2
& INFO2_BWE_ENABLE
) {
133 sh_sdhi_writew(host
, SDHI_INFO2
, ~INFO2_BWE_ENABLE
);
134 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
135 INFO2_BWE_ENABLE
| INFO2M_BUF_ILL_WRITE
|
136 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
141 if (state1
& INFO1_ACCESS_END
) {
142 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_ACCESS_END
);
143 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
145 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
152 static int sh_sdhi_wait_interrupt_flag(struct sh_sdhi_host
*host
)
154 int timeout
= 10000000;
159 debug(DRIVER_NAME
": %s timeout\n", __func__
);
163 if (!sh_sdhi_intr(host
))
166 udelay(1); /* 1 usec */
169 return 1; /* Return value: NOT 0 = complete waiting */
172 static int sh_sdhi_clock_control(struct sh_sdhi_host
*host
, unsigned long clk
)
174 u32 clkdiv
, i
, timeout
;
176 if (sh_sdhi_readw(host
, SDHI_INFO2
) & (1 << 14)) {
177 printf(DRIVER_NAME
": Busy state ! Cannot change the clock\n");
181 sh_sdhi_writew(host
, SDHI_CLK_CTRL
,
182 ~CLK_ENABLE
& sh_sdhi_readw(host
, SDHI_CLK_CTRL
));
188 i
= CONFIG_SH_SDHI_FREQ
>> (0x8 + 1);
189 for (; clkdiv
&& clk
>= (i
<< 1); (clkdiv
>>= 1))
192 sh_sdhi_writew(host
, SDHI_CLK_CTRL
, clkdiv
);
195 /* Waiting for SD Bus busy to be cleared */
197 if ((sh_sdhi_readw(host
, SDHI_INFO2
) & 0x2000))
202 sh_sdhi_writew(host
, SDHI_CLK_CTRL
,
203 CLK_ENABLE
| sh_sdhi_readw(host
, SDHI_CLK_CTRL
));
210 static int sh_sdhi_sync_reset(struct sh_sdhi_host
*host
)
213 sh_sdhi_writew(host
, SDHI_SOFT_RST
, SOFT_RST_ON
);
214 sh_sdhi_writew(host
, SDHI_SOFT_RST
, SOFT_RST_OFF
);
215 sh_sdhi_writew(host
, SDHI_CLK_CTRL
,
216 CLK_ENABLE
| sh_sdhi_readw(host
, SDHI_CLK_CTRL
));
220 if (!(sh_sdhi_readw(host
, SDHI_INFO2
) & INFO2_CBUSY
))
228 if (host
->quirks
& SH_SDHI_QUIRK_16BIT_BUF
)
229 sh_sdhi_writew(host
, SDHI_HOST_MODE
, 1);
234 static int sh_sdhi_error_manage(struct sh_sdhi_host
*host
)
236 unsigned short e_state1
, e_state2
;
242 e_state1
= sh_sdhi_readw(host
, SDHI_ERR_STS1
);
243 e_state2
= sh_sdhi_readw(host
, SDHI_ERR_STS2
);
244 if (e_state2
& ERR_STS2_SYS_ERROR
) {
245 if (e_state2
& ERR_STS2_RES_STOP_TIMEOUT
)
249 debug("%s: ERR_STS2 = %04x\n",
250 DRIVER_NAME
, sh_sdhi_readw(host
, SDHI_ERR_STS2
));
251 sh_sdhi_sync_reset(host
);
253 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
254 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
257 if (e_state1
& ERR_STS1_CRC_ERROR
|| e_state1
& ERR_STS1_CMD_ERROR
)
262 debug("%s: ERR_STS1 = %04x\n",
263 DRIVER_NAME
, sh_sdhi_readw(host
, SDHI_ERR_STS1
));
264 sh_sdhi_sync_reset(host
);
265 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
266 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
270 static int sh_sdhi_single_read(struct sh_sdhi_host
*host
, struct mmc_data
*data
)
273 unsigned short blocksize
, i
;
274 unsigned short *p
= (unsigned short *)data
->dest
;
275 u64
*q
= (u64
*)data
->dest
;
277 if ((unsigned long)p
& 0x00000001) {
278 debug(DRIVER_NAME
": %s: The data pointer is unaligned.",
284 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
285 ~(INFO2M_BRE_ENABLE
| INFO2M_BUF_ILL_READ
) &
286 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
287 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
289 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
290 time
= sh_sdhi_wait_interrupt_flag(host
);
291 if (time
== 0 || host
->sd_error
!= 0)
292 return sh_sdhi_error_manage(host
);
295 blocksize
= sh_sdhi_readw(host
, SDHI_SIZE
);
296 if (host
->quirks
& SH_SDHI_QUIRK_64BIT_BUF
)
297 for (i
= 0; i
< blocksize
/ 8; i
++)
298 *q
++ = sh_sdhi_readq(host
, SDHI_BUF0
);
300 for (i
= 0; i
< blocksize
/ 2; i
++)
301 *p
++ = sh_sdhi_readw(host
, SDHI_BUF0
);
303 time
= sh_sdhi_wait_interrupt_flag(host
);
304 if (time
== 0 || host
->sd_error
!= 0)
305 return sh_sdhi_error_manage(host
);
311 static int sh_sdhi_multi_read(struct sh_sdhi_host
*host
, struct mmc_data
*data
)
314 unsigned short blocksize
, i
, sec
;
315 unsigned short *p
= (unsigned short *)data
->dest
;
316 u64
*q
= (u64
*)data
->dest
;
318 if ((unsigned long)p
& 0x00000001) {
319 debug(DRIVER_NAME
": %s: The data pointer is unaligned.",
324 debug("%s: blocks = %d, blocksize = %d\n",
325 __func__
, data
->blocks
, data
->blocksize
);
328 for (sec
= 0; sec
< data
->blocks
; sec
++) {
329 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
330 ~(INFO2M_BRE_ENABLE
| INFO2M_BUF_ILL_READ
) &
331 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
333 time
= sh_sdhi_wait_interrupt_flag(host
);
334 if (time
== 0 || host
->sd_error
!= 0)
335 return sh_sdhi_error_manage(host
);
338 blocksize
= sh_sdhi_readw(host
, SDHI_SIZE
);
339 if (host
->quirks
& SH_SDHI_QUIRK_64BIT_BUF
)
340 for (i
= 0; i
< blocksize
/ 8; i
++)
341 *q
++ = sh_sdhi_readq(host
, SDHI_BUF0
);
343 for (i
= 0; i
< blocksize
/ 2; i
++)
344 *p
++ = sh_sdhi_readw(host
, SDHI_BUF0
);
350 static int sh_sdhi_single_write(struct sh_sdhi_host
*host
,
351 struct mmc_data
*data
)
354 unsigned short blocksize
, i
;
355 const unsigned short *p
= (const unsigned short *)data
->src
;
356 const u64
*q
= (const u64
*)data
->src
;
358 if ((unsigned long)p
& 0x00000001) {
359 debug(DRIVER_NAME
": %s: The data pointer is unaligned.",
364 debug("%s: blocks = %d, blocksize = %d\n",
365 __func__
, data
->blocks
, data
->blocksize
);
368 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
369 ~(INFO2M_BWE_ENABLE
| INFO2M_BUF_ILL_WRITE
) &
370 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
371 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
373 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
375 time
= sh_sdhi_wait_interrupt_flag(host
);
376 if (time
== 0 || host
->sd_error
!= 0)
377 return sh_sdhi_error_manage(host
);
380 blocksize
= sh_sdhi_readw(host
, SDHI_SIZE
);
381 if (host
->quirks
& SH_SDHI_QUIRK_64BIT_BUF
)
382 for (i
= 0; i
< blocksize
/ 8; i
++)
383 sh_sdhi_writeq(host
, SDHI_BUF0
, *q
++);
385 for (i
= 0; i
< blocksize
/ 2; i
++)
386 sh_sdhi_writew(host
, SDHI_BUF0
, *p
++);
388 time
= sh_sdhi_wait_interrupt_flag(host
);
389 if (time
== 0 || host
->sd_error
!= 0)
390 return sh_sdhi_error_manage(host
);
396 static int sh_sdhi_multi_write(struct sh_sdhi_host
*host
, struct mmc_data
*data
)
399 unsigned short i
, sec
, blocksize
;
400 const unsigned short *p
= (const unsigned short *)data
->src
;
401 const u64
*q
= (const u64
*)data
->src
;
403 debug("%s: blocks = %d, blocksize = %d\n",
404 __func__
, data
->blocks
, data
->blocksize
);
407 for (sec
= 0; sec
< data
->blocks
; sec
++) {
408 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
409 ~(INFO2M_BWE_ENABLE
| INFO2M_BUF_ILL_WRITE
) &
410 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
412 time
= sh_sdhi_wait_interrupt_flag(host
);
413 if (time
== 0 || host
->sd_error
!= 0)
414 return sh_sdhi_error_manage(host
);
417 blocksize
= sh_sdhi_readw(host
, SDHI_SIZE
);
418 if (host
->quirks
& SH_SDHI_QUIRK_64BIT_BUF
)
419 for (i
= 0; i
< blocksize
/ 8; i
++)
420 sh_sdhi_writeq(host
, SDHI_BUF0
, *q
++);
422 for (i
= 0; i
< blocksize
/ 2; i
++)
423 sh_sdhi_writew(host
, SDHI_BUF0
, *p
++);
429 static void sh_sdhi_get_response(struct sh_sdhi_host
*host
, struct mmc_cmd
*cmd
)
431 unsigned short i
, j
, cnt
= 1;
432 unsigned short resp
[8];
434 if (cmd
->resp_type
& MMC_RSP_136
) {
436 resp
[0] = sh_sdhi_readw(host
, SDHI_RSP00
);
437 resp
[1] = sh_sdhi_readw(host
, SDHI_RSP01
);
438 resp
[2] = sh_sdhi_readw(host
, SDHI_RSP02
);
439 resp
[3] = sh_sdhi_readw(host
, SDHI_RSP03
);
440 resp
[4] = sh_sdhi_readw(host
, SDHI_RSP04
);
441 resp
[5] = sh_sdhi_readw(host
, SDHI_RSP05
);
442 resp
[6] = sh_sdhi_readw(host
, SDHI_RSP06
);
443 resp
[7] = sh_sdhi_readw(host
, SDHI_RSP07
);
445 /* SDHI REGISTER SPECIFICATION */
446 for (i
= 7, j
= 6; i
> 0; i
--) {
447 resp
[i
] = (resp
[i
] << 8) & 0xff00;
448 resp
[i
] |= (resp
[j
--] >> 8) & 0x00ff;
450 resp
[0] = (resp
[0] << 8) & 0xff00;
452 resp
[0] = sh_sdhi_readw(host
, SDHI_RSP00
);
453 resp
[1] = sh_sdhi_readw(host
, SDHI_RSP01
);
456 #if defined(__BIG_ENDIAN_BITFIELD)
458 cmd
->response
[0] = (resp
[6] << 16) | resp
[7];
459 cmd
->response
[1] = (resp
[4] << 16) | resp
[5];
460 cmd
->response
[2] = (resp
[2] << 16) | resp
[3];
461 cmd
->response
[3] = (resp
[0] << 16) | resp
[1];
463 cmd
->response
[0] = (resp
[0] << 16) | resp
[1];
467 cmd
->response
[0] = (resp
[7] << 16) | resp
[6];
468 cmd
->response
[1] = (resp
[5] << 16) | resp
[4];
469 cmd
->response
[2] = (resp
[3] << 16) | resp
[2];
470 cmd
->response
[3] = (resp
[1] << 16) | resp
[0];
472 cmd
->response
[0] = (resp
[1] << 16) | resp
[0];
474 #endif /* __BIG_ENDIAN_BITFIELD */
477 static unsigned short sh_sdhi_set_cmd(struct sh_sdhi_host
*host
,
478 struct mmc_data
*data
, unsigned short opc
)
488 return opc
| (data
? 0x1c00 : 0x40);
489 case MMC_CMD_SEND_EXT_CSD
:
490 return opc
| (data
? 0x1c00 : 0);
491 case MMC_CMD_SEND_OP_COND
:
493 case MMC_CMD_APP_CMD
:
500 static unsigned short sh_sdhi_data_trans(struct sh_sdhi_host
*host
,
501 struct mmc_data
*data
, unsigned short opc
)
506 case SD_CMD_APP_SEND_SCR
:
507 case SD_CMD_APP_SD_STATUS
:
508 return sh_sdhi_single_read(host
, data
);
510 printf(DRIVER_NAME
": SD: NOT SUPPORT APP CMD = d'%04d\n",
516 case MMC_CMD_WRITE_MULTIPLE_BLOCK
:
517 return sh_sdhi_multi_write(host
, data
);
518 case MMC_CMD_READ_MULTIPLE_BLOCK
:
519 return sh_sdhi_multi_read(host
, data
);
520 case MMC_CMD_WRITE_SINGLE_BLOCK
:
521 return sh_sdhi_single_write(host
, data
);
522 case MMC_CMD_READ_SINGLE_BLOCK
:
524 case MMC_CMD_SEND_EXT_CSD
:;
525 return sh_sdhi_single_read(host
, data
);
527 printf(DRIVER_NAME
": SD: NOT SUPPORT CMD = d'%04d\n", opc
);
533 static int sh_sdhi_start_cmd(struct sh_sdhi_host
*host
,
534 struct mmc_data
*data
, struct mmc_cmd
*cmd
)
537 unsigned short shcmd
, opc
= cmd
->cmdidx
;
539 unsigned long timeout
;
541 debug("opc = %d, arg = %x, resp_type = %x\n",
542 opc
, cmd
->cmdarg
, cmd
->resp_type
);
544 if (opc
== MMC_CMD_STOP_TRANSMISSION
) {
545 /* SDHI sends the STOP command automatically by STOP reg */
546 sh_sdhi_writew(host
, SDHI_INFO1_MASK
, ~INFO1M_ACCESS_END
&
547 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
549 time
= sh_sdhi_wait_interrupt_flag(host
);
550 if (time
== 0 || host
->sd_error
!= 0)
551 return sh_sdhi_error_manage(host
);
553 sh_sdhi_get_response(host
, cmd
);
558 if ((opc
== MMC_CMD_READ_MULTIPLE_BLOCK
) ||
559 opc
== MMC_CMD_WRITE_MULTIPLE_BLOCK
) {
560 sh_sdhi_writew(host
, SDHI_STOP
, STOP_SEC_ENABLE
);
561 sh_sdhi_writew(host
, SDHI_SECCNT
, data
->blocks
);
563 sh_sdhi_writew(host
, SDHI_SIZE
, data
->blocksize
);
566 shcmd
= sh_sdhi_set_cmd(host
, data
, opc
);
569 * U-Boot cannot use interrupt.
570 * So this flag may not be clear by timing
572 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_RESP_END
);
574 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
575 INFO1M_RESP_END
| sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
576 sh_sdhi_writew(host
, SDHI_ARG0
,
577 (unsigned short)(cmd
->cmdarg
& ARG0_MASK
));
578 sh_sdhi_writew(host
, SDHI_ARG1
,
579 (unsigned short)((cmd
->cmdarg
>> 16) & ARG1_MASK
));
582 /* Waiting for SD Bus busy to be cleared */
584 if ((sh_sdhi_readw(host
, SDHI_INFO2
) & 0x2000))
589 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
590 ~INFO1M_RESP_END
& sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
591 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
592 ~(INFO2M_CMD_ERROR
| INFO2M_CRC_ERROR
|
593 INFO2M_END_ERROR
| INFO2M_TIMEOUT
|
594 INFO2M_RESP_TIMEOUT
| INFO2M_ILA
) &
595 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
597 sh_sdhi_writew(host
, SDHI_CMD
, (unsigned short)(shcmd
& CMD_MASK
));
598 time
= sh_sdhi_wait_interrupt_flag(host
);
601 return sh_sdhi_error_manage(host
);
604 if (host
->sd_error
) {
605 switch (cmd
->cmdidx
) {
606 case MMC_CMD_ALL_SEND_CID
:
607 case MMC_CMD_SELECT_CARD
:
608 case SD_CMD_SEND_IF_COND
:
609 case MMC_CMD_APP_CMD
:
613 debug(DRIVER_NAME
": Cmd(d'%d) err\n", opc
);
614 debug(DRIVER_NAME
": cmdidx = %d\n", cmd
->cmdidx
);
615 ret
= sh_sdhi_error_manage(host
);
624 if (sh_sdhi_readw(host
, SDHI_INFO1
) & INFO1_RESP_END
) {
629 if (host
->wait_int
) {
630 sh_sdhi_get_response(host
, cmd
);
635 ret
= sh_sdhi_data_trans(host
, data
, opc
);
637 debug("ret = %d, resp = %08x, %08x, %08x, %08x\n",
638 ret
, cmd
->response
[0], cmd
->response
[1],
639 cmd
->response
[2], cmd
->response
[3]);
643 static int sh_sdhi_send_cmd_common(struct sh_sdhi_host
*host
,
644 struct mmc_cmd
*cmd
, struct mmc_data
*data
)
648 return sh_sdhi_start_cmd(host
, data
, cmd
);
651 static int sh_sdhi_set_ios_common(struct sh_sdhi_host
*host
, struct mmc
*mmc
)
655 ret
= sh_sdhi_clock_control(host
, mmc
->clock
);
659 if (mmc
->bus_width
== 8)
660 sh_sdhi_writew(host
, SDHI_OPTION
,
661 OPT_BUS_WIDTH_8
| (~OPT_BUS_WIDTH_M
&
662 sh_sdhi_readw(host
, SDHI_OPTION
)));
663 else if (mmc
->bus_width
== 4)
664 sh_sdhi_writew(host
, SDHI_OPTION
,
665 OPT_BUS_WIDTH_4
| (~OPT_BUS_WIDTH_M
&
666 sh_sdhi_readw(host
, SDHI_OPTION
)));
668 sh_sdhi_writew(host
, SDHI_OPTION
,
669 OPT_BUS_WIDTH_1
| (~OPT_BUS_WIDTH_M
&
670 sh_sdhi_readw(host
, SDHI_OPTION
)));
672 debug("clock = %d, buswidth = %d\n", mmc
->clock
, mmc
->bus_width
);
677 static int sh_sdhi_initialize_common(struct sh_sdhi_host
*host
)
679 int ret
= sh_sdhi_sync_reset(host
);
681 sh_sdhi_writew(host
, SDHI_PORTSEL
, USE_1PORT
);
683 #if defined(__BIG_ENDIAN_BITFIELD)
684 sh_sdhi_writew(host
, SDHI_EXT_SWAP
, SET_SWAP
);
687 sh_sdhi_writew(host
, SDHI_INFO1_MASK
, INFO1M_RESP_END
|
688 INFO1M_ACCESS_END
| INFO1M_CARD_RE
|
689 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
694 #ifndef CONFIG_DM_MMC
695 static void *mmc_priv(struct mmc
*mmc
)
697 return (void *)mmc
->priv
;
700 static int sh_sdhi_send_cmd(struct mmc
*mmc
, struct mmc_cmd
*cmd
,
701 struct mmc_data
*data
)
703 struct sh_sdhi_host
*host
= mmc_priv(mmc
);
705 return sh_sdhi_send_cmd_common(host
, cmd
, data
);
708 static int sh_sdhi_set_ios(struct mmc
*mmc
)
710 struct sh_sdhi_host
*host
= mmc_priv(mmc
);
712 return sh_sdhi_set_ios_common(host
, mmc
);
715 static int sh_sdhi_initialize(struct mmc
*mmc
)
717 struct sh_sdhi_host
*host
= mmc_priv(mmc
);
719 return sh_sdhi_initialize_common(host
);
722 static const struct mmc_ops sh_sdhi_ops
= {
723 .send_cmd
= sh_sdhi_send_cmd
,
724 .set_ios
= sh_sdhi_set_ios
,
725 .init
= sh_sdhi_initialize
,
728 #ifdef CONFIG_RCAR_GEN3
729 static struct mmc_config sh_sdhi_cfg
= {
732 .f_min
= CLKDEV_INIT
,
733 .f_max
= CLKDEV_HS_DATA
,
734 .voltages
= MMC_VDD_165_195
| MMC_VDD_32_33
| MMC_VDD_33_34
,
735 .host_caps
= MMC_MODE_4BIT
| MMC_MODE_8BIT
| MMC_MODE_HS
|
737 .part_type
= PART_TYPE_DOS
,
738 .b_max
= CONFIG_SYS_MMC_MAX_BLK_COUNT
,
741 static struct mmc_config sh_sdhi_cfg
= {
744 .f_min
= CLKDEV_INIT
,
745 .f_max
= CLKDEV_HS_DATA
,
746 .voltages
= MMC_VDD_32_33
| MMC_VDD_33_34
,
747 .host_caps
= MMC_MODE_4BIT
| MMC_MODE_HS
,
748 .part_type
= PART_TYPE_DOS
,
749 .b_max
= CONFIG_SYS_MMC_MAX_BLK_COUNT
,
753 int sh_sdhi_init(unsigned long addr
, int ch
, unsigned long quirks
)
757 struct sh_sdhi_host
*host
= NULL
;
759 if (ch
>= CONFIG_SYS_SH_SDHI_NR_CHANNEL
)
762 host
= malloc(sizeof(struct sh_sdhi_host
));
766 mmc
= mmc_create(&sh_sdhi_cfg
, host
);
773 host
->addr
= (void __iomem
*)addr
;
774 host
->quirks
= quirks
;
776 if (host
->quirks
& SH_SDHI_QUIRK_64BIT_BUF
)
778 else if (host
->quirks
& SH_SDHI_QUIRK_16BIT_BUF
)
790 struct sh_sdhi_plat
{
791 struct mmc_config cfg
;
795 int sh_sdhi_dm_send_cmd(struct udevice
*dev
, struct mmc_cmd
*cmd
,
796 struct mmc_data
*data
)
798 struct sh_sdhi_host
*host
= dev_get_priv(dev
);
800 return sh_sdhi_send_cmd_common(host
, cmd
, data
);
803 int sh_sdhi_dm_set_ios(struct udevice
*dev
)
805 struct sh_sdhi_host
*host
= dev_get_priv(dev
);
806 struct mmc
*mmc
= mmc_get_mmc_dev(dev
);
808 return sh_sdhi_set_ios_common(host
, mmc
);
811 static const struct dm_mmc_ops sh_sdhi_dm_ops
= {
812 .send_cmd
= sh_sdhi_dm_send_cmd
,
813 .set_ios
= sh_sdhi_dm_set_ios
,
816 static int sh_sdhi_dm_bind(struct udevice
*dev
)
818 struct sh_sdhi_plat
*plat
= dev_get_platdata(dev
);
820 return mmc_bind(dev
, &plat
->mmc
, &plat
->cfg
);
823 static int sh_sdhi_dm_probe(struct udevice
*dev
)
825 struct sh_sdhi_plat
*plat
= dev_get_platdata(dev
);
826 struct sh_sdhi_host
*host
= dev_get_priv(dev
);
827 struct mmc_uclass_priv
*upriv
= dev_get_uclass_priv(dev
);
828 struct clk sh_sdhi_clk
;
829 const u32 quirks
= dev_get_driver_data(dev
);
833 base
= devfdt_get_addr(dev
);
834 if (base
== FDT_ADDR_T_NONE
)
837 host
->addr
= devm_ioremap(dev
, base
, SZ_2K
);
841 ret
= clk_get_by_index(dev
, 0, &sh_sdhi_clk
);
843 debug("failed to get clock, ret=%d\n", ret
);
847 ret
= clk_enable(&sh_sdhi_clk
);
849 debug("failed to enable clock, ret=%d\n", ret
);
853 host
->quirks
= quirks
;
855 if (host
->quirks
& SH_SDHI_QUIRK_64BIT_BUF
)
857 else if (host
->quirks
& SH_SDHI_QUIRK_16BIT_BUF
)
860 plat
->cfg
.name
= dev
->name
;
861 plat
->cfg
.host_caps
= MMC_MODE_HS_52MHz
| MMC_MODE_HS
;
863 switch (fdtdec_get_int(gd
->fdt_blob
, dev_of_offset(dev
), "bus-width",
866 plat
->cfg
.host_caps
|= MMC_MODE_8BIT
;
869 plat
->cfg
.host_caps
|= MMC_MODE_4BIT
;
874 dev_err(dev
, "Invalid \"bus-width\" value\n");
878 sh_sdhi_initialize_common(host
);
880 plat
->cfg
.voltages
= MMC_VDD_165_195
| MMC_VDD_32_33
| MMC_VDD_33_34
;
881 plat
->cfg
.f_min
= CLKDEV_INIT
;
882 plat
->cfg
.f_max
= CLKDEV_HS_DATA
;
883 plat
->cfg
.b_max
= CONFIG_SYS_MMC_MAX_BLK_COUNT
;
885 upriv
->mmc
= &plat
->mmc
;
890 static const struct udevice_id sh_sdhi_sd_match
[] = {
891 { .compatible
= "renesas,sdhi-r8a7795", .data
= SH_SDHI_QUIRK_64BIT_BUF
},
892 { .compatible
= "renesas,sdhi-r8a7796", .data
= SH_SDHI_QUIRK_64BIT_BUF
},
896 U_BOOT_DRIVER(sh_sdhi_mmc
) = {
897 .name
= "sh-sdhi-mmc",
899 .of_match
= sh_sdhi_sd_match
,
900 .bind
= sh_sdhi_dm_bind
,
901 .probe
= sh_sdhi_dm_probe
,
902 .priv_auto_alloc_size
= sizeof(struct sh_sdhi_host
),
903 .platdata_auto_alloc_size
= sizeof(struct sh_sdhi_plat
),
904 .ops
= &sh_sdhi_dm_ops
,