2 * drivers/mmc/sh_sdhi.c
4 * SD/MMC driver for Renesas rmobile ARM SoCs.
6 * Copyright (C) 2011,2013-2014 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
16 #include <asm/errno.h>
18 #include <asm/arch/rmobile.h>
19 #include <asm/arch/sh_sdhi.h>
21 #define DRIVER_NAME "sh-sdhi"
28 unsigned char wait_int
;
29 unsigned char sd_error
;
30 unsigned char detect_waiting
;
32 static inline void sh_sdhi_writew(struct sh_sdhi_host
*host
, int reg
, u16 val
)
34 writew(val
, host
->addr
+ (reg
<< host
->bus_shift
));
37 static inline u16
sh_sdhi_readw(struct sh_sdhi_host
*host
, int reg
)
39 return readw(host
->addr
+ (reg
<< host
->bus_shift
));
42 static void *mmc_priv(struct mmc
*mmc
)
44 return (void *)mmc
->priv
;
47 static void sh_sdhi_detect(struct sh_sdhi_host
*host
)
49 sh_sdhi_writew(host
, SDHI_OPTION
,
50 OPT_BUS_WIDTH_1
| sh_sdhi_readw(host
, SDHI_OPTION
));
52 host
->detect_waiting
= 0;
55 static int sh_sdhi_intr(void *dev_id
)
57 struct sh_sdhi_host
*host
= dev_id
;
58 int state1
= 0, state2
= 0;
60 state1
= sh_sdhi_readw(host
, SDHI_INFO1
);
61 state2
= sh_sdhi_readw(host
, SDHI_INFO2
);
63 debug("%s: state1 = %x, state2 = %x\n", __func__
, state1
, state2
);
66 if (state1
& INFO1_CARD_IN
) {
67 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_CARD_IN
);
68 if (!host
->detect_waiting
) {
69 host
->detect_waiting
= 1;
72 sh_sdhi_writew(host
, SDHI_INFO1_MASK
, INFO1M_RESP_END
|
73 INFO1M_ACCESS_END
| INFO1M_CARD_IN
|
74 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
78 if (state1
& INFO1_CARD_RE
) {
79 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_CARD_RE
);
80 if (!host
->detect_waiting
) {
81 host
->detect_waiting
= 1;
84 sh_sdhi_writew(host
, SDHI_INFO1_MASK
, INFO1M_RESP_END
|
85 INFO1M_ACCESS_END
| INFO1M_CARD_RE
|
86 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
87 sh_sdhi_writew(host
, SDHI_SDIO_INFO1_MASK
, SDIO_INFO1M_ON
);
88 sh_sdhi_writew(host
, SDHI_SDIO_MODE
, SDIO_MODE_OFF
);
92 if (state2
& INFO2_ALL_ERR
) {
93 sh_sdhi_writew(host
, SDHI_INFO2
,
94 (unsigned short)~(INFO2_ALL_ERR
));
95 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
97 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
103 if (state1
& INFO1_RESP_END
) {
104 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_RESP_END
);
105 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
107 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
111 /* SD_BUF Read Enable */
112 if (state2
& INFO2_BRE_ENABLE
) {
113 sh_sdhi_writew(host
, SDHI_INFO2
, ~INFO2_BRE_ENABLE
);
114 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
115 INFO2M_BRE_ENABLE
| INFO2M_BUF_ILL_READ
|
116 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
120 /* SD_BUF Write Enable */
121 if (state2
& INFO2_BWE_ENABLE
) {
122 sh_sdhi_writew(host
, SDHI_INFO2
, ~INFO2_BWE_ENABLE
);
123 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
124 INFO2_BWE_ENABLE
| INFO2M_BUF_ILL_WRITE
|
125 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
130 if (state1
& INFO1_ACCESS_END
) {
131 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_ACCESS_END
);
132 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
134 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
141 static int sh_sdhi_wait_interrupt_flag(struct sh_sdhi_host
*host
)
143 int timeout
= 10000000;
148 debug(DRIVER_NAME
": %s timeout\n", __func__
);
152 if (!sh_sdhi_intr(host
))
155 udelay(1); /* 1 usec */
158 return 1; /* Return value: NOT 0 = complete waiting */
161 static int sh_sdhi_clock_control(struct sh_sdhi_host
*host
, unsigned long clk
)
163 u32 clkdiv
, i
, timeout
;
165 if (sh_sdhi_readw(host
, SDHI_INFO2
) & (1 << 14)) {
166 printf(DRIVER_NAME
": Busy state ! Cannot change the clock\n");
170 sh_sdhi_writew(host
, SDHI_CLK_CTRL
,
171 ~CLK_ENABLE
& sh_sdhi_readw(host
, SDHI_CLK_CTRL
));
177 i
= CONFIG_SH_SDHI_FREQ
>> (0x8 + 1);
178 for (; clkdiv
&& clk
>= (i
<< 1); (clkdiv
>>= 1))
181 sh_sdhi_writew(host
, SDHI_CLK_CTRL
, clkdiv
);
184 /* Waiting for SD Bus busy to be cleared */
186 if ((sh_sdhi_readw(host
, SDHI_INFO2
) & 0x2000))
191 sh_sdhi_writew(host
, SDHI_CLK_CTRL
,
192 CLK_ENABLE
| sh_sdhi_readw(host
, SDHI_CLK_CTRL
));
199 static int sh_sdhi_sync_reset(struct sh_sdhi_host
*host
)
202 sh_sdhi_writew(host
, SDHI_SOFT_RST
, SOFT_RST_ON
);
203 sh_sdhi_writew(host
, SDHI_SOFT_RST
, SOFT_RST_OFF
);
204 sh_sdhi_writew(host
, SDHI_CLK_CTRL
,
205 CLK_ENABLE
| sh_sdhi_readw(host
, SDHI_CLK_CTRL
));
209 if (!(sh_sdhi_readw(host
, SDHI_INFO2
) & INFO2_CBUSY
))
217 if (host
->quirks
& SH_SDHI_QUIRK_16BIT_BUF
)
218 sh_sdhi_writew(host
, SDHI_HOST_MODE
, 1);
223 static int sh_sdhi_error_manage(struct sh_sdhi_host
*host
)
225 unsigned short e_state1
, e_state2
;
231 e_state1
= sh_sdhi_readw(host
, SDHI_ERR_STS1
);
232 e_state2
= sh_sdhi_readw(host
, SDHI_ERR_STS2
);
233 if (e_state2
& ERR_STS2_SYS_ERROR
) {
234 if (e_state2
& ERR_STS2_RES_STOP_TIMEOUT
)
238 debug("%s: ERR_STS2 = %04x\n",
239 DRIVER_NAME
, sh_sdhi_readw(host
, SDHI_ERR_STS2
));
240 sh_sdhi_sync_reset(host
);
242 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
243 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
246 if (e_state1
& ERR_STS1_CRC_ERROR
|| e_state1
& ERR_STS1_CMD_ERROR
)
251 debug("%s: ERR_STS1 = %04x\n",
252 DRIVER_NAME
, sh_sdhi_readw(host
, SDHI_ERR_STS1
));
253 sh_sdhi_sync_reset(host
);
254 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
255 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
259 static int sh_sdhi_single_read(struct sh_sdhi_host
*host
, struct mmc_data
*data
)
262 unsigned short blocksize
, i
;
263 unsigned short *p
= (unsigned short *)data
->dest
;
265 if ((unsigned long)p
& 0x00000001) {
266 debug(DRIVER_NAME
": %s: The data pointer is unaligned.",
272 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
273 ~(INFO2M_BRE_ENABLE
| INFO2M_BUF_ILL_READ
) &
274 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
275 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
277 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
278 time
= sh_sdhi_wait_interrupt_flag(host
);
279 if (time
== 0 || host
->sd_error
!= 0)
280 return sh_sdhi_error_manage(host
);
283 blocksize
= sh_sdhi_readw(host
, SDHI_SIZE
);
284 for (i
= 0; i
< blocksize
/ 2; i
++)
285 *p
++ = sh_sdhi_readw(host
, SDHI_BUF0
);
287 time
= sh_sdhi_wait_interrupt_flag(host
);
288 if (time
== 0 || host
->sd_error
!= 0)
289 return sh_sdhi_error_manage(host
);
295 static int sh_sdhi_multi_read(struct sh_sdhi_host
*host
, struct mmc_data
*data
)
298 unsigned short blocksize
, i
, sec
;
299 unsigned short *p
= (unsigned short *)data
->dest
;
301 if ((unsigned long)p
& 0x00000001) {
302 debug(DRIVER_NAME
": %s: The data pointer is unaligned.",
307 debug("%s: blocks = %d, blocksize = %d\n",
308 __func__
, data
->blocks
, data
->blocksize
);
311 for (sec
= 0; sec
< data
->blocks
; sec
++) {
312 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
313 ~(INFO2M_BRE_ENABLE
| INFO2M_BUF_ILL_READ
) &
314 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
316 time
= sh_sdhi_wait_interrupt_flag(host
);
317 if (time
== 0 || host
->sd_error
!= 0)
318 return sh_sdhi_error_manage(host
);
321 blocksize
= sh_sdhi_readw(host
, SDHI_SIZE
);
322 for (i
= 0; i
< blocksize
/ 2; i
++)
323 *p
++ = sh_sdhi_readw(host
, SDHI_BUF0
);
329 static int sh_sdhi_single_write(struct sh_sdhi_host
*host
,
330 struct mmc_data
*data
)
333 unsigned short blocksize
, i
;
334 const unsigned short *p
= (const unsigned short *)data
->src
;
336 if ((unsigned long)p
& 0x00000001) {
337 debug(DRIVER_NAME
": %s: The data pointer is unaligned.",
342 debug("%s: blocks = %d, blocksize = %d\n",
343 __func__
, data
->blocks
, data
->blocksize
);
346 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
347 ~(INFO2M_BWE_ENABLE
| INFO2M_BUF_ILL_WRITE
) &
348 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
349 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
351 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
353 time
= sh_sdhi_wait_interrupt_flag(host
);
354 if (time
== 0 || host
->sd_error
!= 0)
355 return sh_sdhi_error_manage(host
);
358 blocksize
= sh_sdhi_readw(host
, SDHI_SIZE
);
359 for (i
= 0; i
< blocksize
/ 2; i
++)
360 sh_sdhi_writew(host
, SDHI_BUF0
, *p
++);
362 time
= sh_sdhi_wait_interrupt_flag(host
);
363 if (time
== 0 || host
->sd_error
!= 0)
364 return sh_sdhi_error_manage(host
);
370 static int sh_sdhi_multi_write(struct sh_sdhi_host
*host
, struct mmc_data
*data
)
373 unsigned short i
, sec
, blocksize
;
374 const unsigned short *p
= (const unsigned short *)data
->src
;
376 debug("%s: blocks = %d, blocksize = %d\n",
377 __func__
, data
->blocks
, data
->blocksize
);
380 for (sec
= 0; sec
< data
->blocks
; sec
++) {
381 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
382 ~(INFO2M_BWE_ENABLE
| INFO2M_BUF_ILL_WRITE
) &
383 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
385 time
= sh_sdhi_wait_interrupt_flag(host
);
386 if (time
== 0 || host
->sd_error
!= 0)
387 return sh_sdhi_error_manage(host
);
390 blocksize
= sh_sdhi_readw(host
, SDHI_SIZE
);
391 for (i
= 0; i
< blocksize
/ 2; i
++)
392 sh_sdhi_writew(host
, SDHI_BUF0
, *p
++);
398 static void sh_sdhi_get_response(struct sh_sdhi_host
*host
, struct mmc_cmd
*cmd
)
400 unsigned short i
, j
, cnt
= 1;
401 unsigned short resp
[8];
402 unsigned long *p1
, *p2
;
404 if (cmd
->resp_type
& MMC_RSP_136
) {
406 resp
[0] = sh_sdhi_readw(host
, SDHI_RSP00
);
407 resp
[1] = sh_sdhi_readw(host
, SDHI_RSP01
);
408 resp
[2] = sh_sdhi_readw(host
, SDHI_RSP02
);
409 resp
[3] = sh_sdhi_readw(host
, SDHI_RSP03
);
410 resp
[4] = sh_sdhi_readw(host
, SDHI_RSP04
);
411 resp
[5] = sh_sdhi_readw(host
, SDHI_RSP05
);
412 resp
[6] = sh_sdhi_readw(host
, SDHI_RSP06
);
413 resp
[7] = sh_sdhi_readw(host
, SDHI_RSP07
);
415 /* SDHI REGISTER SPECIFICATION */
416 for (i
= 7, j
= 6; i
> 0; i
--) {
417 resp
[i
] = (resp
[i
] << 8) & 0xff00;
418 resp
[i
] |= (resp
[j
--] >> 8) & 0x00ff;
420 resp
[0] = (resp
[0] << 8) & 0xff00;
422 /* SDHI REGISTER SPECIFICATION */
423 p1
= ((unsigned long *)resp
) + 3;
426 resp
[0] = sh_sdhi_readw(host
, SDHI_RSP00
);
427 resp
[1] = sh_sdhi_readw(host
, SDHI_RSP01
);
429 p1
= ((unsigned long *)resp
);
432 p2
= (unsigned long *)cmd
->response
;
433 #if defined(__BIG_ENDIAN_BITFIELD)
434 for (i
= 0; i
< cnt
; i
++) {
435 *p2
++ = ((*p1
>> 16) & 0x0000ffff) |
436 ((*p1
<< 16) & 0xffff0000);
440 for (i
= 0; i
< cnt
; i
++)
442 #endif /* __BIG_ENDIAN_BITFIELD */
445 static unsigned short sh_sdhi_set_cmd(struct sh_sdhi_host
*host
,
446 struct mmc_data
*data
, unsigned short opc
)
449 case SD_CMD_APP_SEND_OP_COND
:
450 case SD_CMD_APP_SEND_SCR
:
453 case SD_CMD_APP_SET_BUS_WIDTH
:
454 /* SD_APP_SET_BUS_WIDTH*/
458 opc
= SDHI_SD_SWITCH
;
466 static unsigned short sh_sdhi_data_trans(struct sh_sdhi_host
*host
,
467 struct mmc_data
*data
, unsigned short opc
)
472 case MMC_CMD_READ_MULTIPLE_BLOCK
:
473 ret
= sh_sdhi_multi_read(host
, data
);
475 case MMC_CMD_WRITE_MULTIPLE_BLOCK
:
476 ret
= sh_sdhi_multi_write(host
, data
);
478 case MMC_CMD_WRITE_SINGLE_BLOCK
:
479 ret
= sh_sdhi_single_write(host
, data
);
481 case MMC_CMD_READ_SINGLE_BLOCK
:
482 case SDHI_SD_APP_SEND_SCR
:
483 case SDHI_SD_SWITCH
: /* SD_SWITCH */
484 ret
= sh_sdhi_single_read(host
, data
);
487 printf(DRIVER_NAME
": SD: NOT SUPPORT CMD = d'%04d\n", opc
);
494 static int sh_sdhi_start_cmd(struct sh_sdhi_host
*host
,
495 struct mmc_data
*data
, struct mmc_cmd
*cmd
)
498 unsigned short opc
= cmd
->cmdidx
;
500 unsigned long timeout
;
502 debug("opc = %d, arg = %x, resp_type = %x\n",
503 opc
, cmd
->cmdarg
, cmd
->resp_type
);
505 if (opc
== MMC_CMD_STOP_TRANSMISSION
) {
506 /* SDHI sends the STOP command automatically by STOP reg */
507 sh_sdhi_writew(host
, SDHI_INFO1_MASK
, ~INFO1M_ACCESS_END
&
508 sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
510 time
= sh_sdhi_wait_interrupt_flag(host
);
511 if (time
== 0 || host
->sd_error
!= 0)
512 return sh_sdhi_error_manage(host
);
514 sh_sdhi_get_response(host
, cmd
);
519 if ((opc
== MMC_CMD_READ_MULTIPLE_BLOCK
) ||
520 opc
== MMC_CMD_WRITE_MULTIPLE_BLOCK
) {
521 sh_sdhi_writew(host
, SDHI_STOP
, STOP_SEC_ENABLE
);
522 sh_sdhi_writew(host
, SDHI_SECCNT
, data
->blocks
);
524 sh_sdhi_writew(host
, SDHI_SIZE
, data
->blocksize
);
526 opc
= sh_sdhi_set_cmd(host
, data
, opc
);
529 * U-Boot cannot use interrupt.
530 * So this flag may not be clear by timing
532 sh_sdhi_writew(host
, SDHI_INFO1
, ~INFO1_RESP_END
);
534 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
535 INFO1M_RESP_END
| sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
536 sh_sdhi_writew(host
, SDHI_ARG0
,
537 (unsigned short)(cmd
->cmdarg
& ARG0_MASK
));
538 sh_sdhi_writew(host
, SDHI_ARG1
,
539 (unsigned short)((cmd
->cmdarg
>> 16) & ARG1_MASK
));
542 /* Waiting for SD Bus busy to be cleared */
544 if ((sh_sdhi_readw(host
, SDHI_INFO2
) & 0x2000))
548 sh_sdhi_writew(host
, SDHI_CMD
, (unsigned short)(opc
& CMD_MASK
));
551 sh_sdhi_writew(host
, SDHI_INFO1_MASK
,
552 ~INFO1M_RESP_END
& sh_sdhi_readw(host
, SDHI_INFO1_MASK
));
553 sh_sdhi_writew(host
, SDHI_INFO2_MASK
,
554 ~(INFO2M_CMD_ERROR
| INFO2M_CRC_ERROR
|
555 INFO2M_END_ERROR
| INFO2M_TIMEOUT
|
556 INFO2M_RESP_TIMEOUT
| INFO2M_ILA
) &
557 sh_sdhi_readw(host
, SDHI_INFO2_MASK
));
559 time
= sh_sdhi_wait_interrupt_flag(host
);
561 return sh_sdhi_error_manage(host
);
563 if (host
->sd_error
) {
564 switch (cmd
->cmdidx
) {
565 case MMC_CMD_ALL_SEND_CID
:
566 case MMC_CMD_SELECT_CARD
:
567 case SD_CMD_SEND_IF_COND
:
568 case MMC_CMD_APP_CMD
:
572 debug(DRIVER_NAME
": Cmd(d'%d) err\n", opc
);
573 debug(DRIVER_NAME
": cmdidx = %d\n", cmd
->cmdidx
);
574 ret
= sh_sdhi_error_manage(host
);
581 if (sh_sdhi_readw(host
, SDHI_INFO1
) & INFO1_RESP_END
)
584 if (host
->wait_int
) {
585 sh_sdhi_get_response(host
, cmd
);
589 ret
= sh_sdhi_data_trans(host
, data
, opc
);
591 debug("ret = %d, resp = %08x, %08x, %08x, %08x\n",
592 ret
, cmd
->response
[0], cmd
->response
[1],
593 cmd
->response
[2], cmd
->response
[3]);
597 static int sh_sdhi_send_cmd(struct mmc
*mmc
, struct mmc_cmd
*cmd
,
598 struct mmc_data
*data
)
600 struct sh_sdhi_host
*host
= mmc_priv(mmc
);
605 ret
= sh_sdhi_start_cmd(host
, data
, cmd
);
610 static void sh_sdhi_set_ios(struct mmc
*mmc
)
613 struct sh_sdhi_host
*host
= mmc_priv(mmc
);
615 ret
= sh_sdhi_clock_control(host
, mmc
->clock
);
619 if (mmc
->bus_width
== 4)
620 sh_sdhi_writew(host
, SDHI_OPTION
, ~OPT_BUS_WIDTH_1
&
621 sh_sdhi_readw(host
, SDHI_OPTION
));
623 sh_sdhi_writew(host
, SDHI_OPTION
, OPT_BUS_WIDTH_1
|
624 sh_sdhi_readw(host
, SDHI_OPTION
));
626 debug("clock = %d, buswidth = %d\n", mmc
->clock
, mmc
->bus_width
);
629 static int sh_sdhi_initialize(struct mmc
*mmc
)
631 struct sh_sdhi_host
*host
= mmc_priv(mmc
);
632 int ret
= sh_sdhi_sync_reset(host
);
634 sh_sdhi_writew(host
, SDHI_PORTSEL
, USE_1PORT
);
636 #if defined(__BIG_ENDIAN_BITFIELD)
637 sh_sdhi_writew(host
, SDHI_EXT_SWAP
, SET_SWAP
);
640 sh_sdhi_writew(host
, SDHI_INFO1_MASK
, INFO1M_RESP_END
|
641 INFO1M_ACCESS_END
| INFO1M_CARD_RE
|
642 INFO1M_DATA3_CARD_RE
| INFO1M_DATA3_CARD_IN
);
647 static const struct mmc_ops sh_sdhi_ops
= {
648 .send_cmd
= sh_sdhi_send_cmd
,
649 .set_ios
= sh_sdhi_set_ios
,
650 .init
= sh_sdhi_initialize
,
653 static struct mmc_config sh_sdhi_cfg
= {
656 .f_min
= CLKDEV_INIT
,
657 .f_max
= CLKDEV_HS_DATA
,
658 .voltages
= MMC_VDD_32_33
| MMC_VDD_33_34
,
659 .host_caps
= MMC_MODE_4BIT
| MMC_MODE_HS
,
660 .part_type
= PART_TYPE_DOS
,
661 .b_max
= CONFIG_SYS_MMC_MAX_BLK_COUNT
,
664 int sh_sdhi_init(unsigned long addr
, int ch
, unsigned long quirks
)
668 struct sh_sdhi_host
*host
= NULL
;
670 if (ch
>= CONFIG_SYS_SH_SDHI_NR_CHANNEL
)
673 host
= malloc(sizeof(struct sh_sdhi_host
));
677 mmc
= mmc_create(&sh_sdhi_cfg
, host
);
685 host
->quirks
= quirks
;
687 if (host
->quirks
& SH_SDHI_QUIRK_16BIT_BUF
)