Home | History | Annotate | Download | only in mmc
      1 // SPDX-License-Identifier: GPL-2.0
      2 /*
      3  * drivers/mmc/sh_sdhi.c
      4  *
      5  * SD/MMC driver for Renesas rmobile ARM SoCs.
      6  *
      7  * Copyright (C) 2011,2013-2017 Renesas Electronics Corporation
      8  * Copyright (C) 2014 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj (at) renesas.com>
      9  * Copyright (C) 2008-2009 Renesas Solutions Corp.
     10  */
     11 
     12 #include <common.h>
     13 #include <malloc.h>
     14 #include <mmc.h>
     15 #include <dm.h>
     16 #include <linux/errno.h>
     17 #include <linux/compat.h>
     18 #include <linux/io.h>
     19 #include <linux/sizes.h>
     20 #include <asm/arch/rmobile.h>
     21 #include <asm/arch/sh_sdhi.h>
     22 #include <clk.h>
     23 
     24 #define DRIVER_NAME "sh-sdhi"
     25 
     26 struct sh_sdhi_host {
     27 	void __iomem *addr;
     28 	int ch;
     29 	int bus_shift;
     30 	unsigned long quirks;
     31 	unsigned char wait_int;
     32 	unsigned char sd_error;
     33 	unsigned char detect_waiting;
     34 	unsigned char app_cmd;
     35 };
     36 
     37 static inline void sh_sdhi_writeq(struct sh_sdhi_host *host, int reg, u64 val)
     38 {
     39 	writeq(val, host->addr + (reg << host->bus_shift));
     40 }
     41 
     42 static inline u64 sh_sdhi_readq(struct sh_sdhi_host *host, int reg)
     43 {
     44 	return readq(host->addr + (reg << host->bus_shift));
     45 }
     46 
     47 static inline void sh_sdhi_writew(struct sh_sdhi_host *host, int reg, u16 val)
     48 {
     49 	writew(val, host->addr + (reg << host->bus_shift));
     50 }
     51 
     52 static inline u16 sh_sdhi_readw(struct sh_sdhi_host *host, int reg)
     53 {
     54 	return readw(host->addr + (reg << host->bus_shift));
     55 }
     56 
     57 static void sh_sdhi_detect(struct sh_sdhi_host *host)
     58 {
     59 	sh_sdhi_writew(host, SDHI_OPTION,
     60 		       OPT_BUS_WIDTH_1 | sh_sdhi_readw(host, SDHI_OPTION));
     61 
     62 	host->detect_waiting = 0;
     63 }
     64 
     65 static int sh_sdhi_intr(void *dev_id)
     66 {
     67 	struct sh_sdhi_host *host = dev_id;
     68 	int state1 = 0, state2 = 0;
     69 
     70 	state1 = sh_sdhi_readw(host, SDHI_INFO1);
     71 	state2 = sh_sdhi_readw(host, SDHI_INFO2);
     72 
     73 	debug("%s: state1 = %x, state2 = %x\n", __func__, state1, state2);
     74 
     75 	/* CARD Insert */
     76 	if (state1 & INFO1_CARD_IN) {
     77 		sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_CARD_IN);
     78 		if (!host->detect_waiting) {
     79 			host->detect_waiting = 1;
     80 			sh_sdhi_detect(host);
     81 		}
     82 		sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END |
     83 			       INFO1M_ACCESS_END | INFO1M_CARD_IN |
     84 			       INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
     85 		return -EAGAIN;
     86 	}
     87 	/* CARD Removal */
     88 	if (state1 & INFO1_CARD_RE) {
     89 		sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_CARD_RE);
     90 		if (!host->detect_waiting) {
     91 			host->detect_waiting = 1;
     92 			sh_sdhi_detect(host);
     93 		}
     94 		sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END |
     95 			       INFO1M_ACCESS_END | INFO1M_CARD_RE |
     96 			       INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
     97 		sh_sdhi_writew(host, SDHI_SDIO_INFO1_MASK, SDIO_INFO1M_ON);
     98 		sh_sdhi_writew(host, SDHI_SDIO_MODE, SDIO_MODE_OFF);
     99 		return -EAGAIN;
    100 	}
    101 
    102 	if (state2 & INFO2_ALL_ERR) {
    103 		sh_sdhi_writew(host, SDHI_INFO2,
    104 			       (unsigned short)~(INFO2_ALL_ERR));
    105 		sh_sdhi_writew(host, SDHI_INFO2_MASK,
    106 			       INFO2M_ALL_ERR |
    107 			       sh_sdhi_readw(host, SDHI_INFO2_MASK));
    108 		host->sd_error = 1;
    109 		host->wait_int = 1;
    110 		return 0;
    111 	}
    112 	/* Respons End */
    113 	if (state1 & INFO1_RESP_END) {
    114 		sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_RESP_END);
    115 		sh_sdhi_writew(host, SDHI_INFO1_MASK,
    116 			       INFO1M_RESP_END |
    117 			       sh_sdhi_readw(host, SDHI_INFO1_MASK));
    118 		host->wait_int = 1;
    119 		return 0;
    120 	}
    121 	/* SD_BUF Read Enable */
    122 	if (state2 & INFO2_BRE_ENABLE) {
    123 		sh_sdhi_writew(host, SDHI_INFO2, ~INFO2_BRE_ENABLE);
    124 		sh_sdhi_writew(host, SDHI_INFO2_MASK,
    125 			       INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ |
    126 			       sh_sdhi_readw(host, SDHI_INFO2_MASK));
    127 		host->wait_int = 1;
    128 		return 0;
    129 	}
    130 	/* SD_BUF Write Enable */
    131 	if (state2 & INFO2_BWE_ENABLE) {
    132 		sh_sdhi_writew(host, SDHI_INFO2, ~INFO2_BWE_ENABLE);
    133 		sh_sdhi_writew(host, SDHI_INFO2_MASK,
    134 			       INFO2_BWE_ENABLE | INFO2M_BUF_ILL_WRITE |
    135 			       sh_sdhi_readw(host, SDHI_INFO2_MASK));
    136 		host->wait_int = 1;
    137 		return 0;
    138 	}
    139 	/* Access End */
    140 	if (state1 & INFO1_ACCESS_END) {
    141 		sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_ACCESS_END);
    142 		sh_sdhi_writew(host, SDHI_INFO1_MASK,
    143 			       INFO1_ACCESS_END |
    144 			       sh_sdhi_readw(host, SDHI_INFO1_MASK));
    145 		host->wait_int = 1;
    146 		return 0;
    147 	}
    148 	return -EAGAIN;
    149 }
    150 
    151 static int sh_sdhi_wait_interrupt_flag(struct sh_sdhi_host *host)
    152 {
    153 	int timeout = 10000000;
    154 
    155 	while (1) {
    156 		timeout--;
    157 		if (timeout < 0) {
    158 			debug(DRIVER_NAME": %s timeout\n", __func__);
    159 			return 0;
    160 		}
    161 
    162 		if (!sh_sdhi_intr(host))
    163 			break;
    164 
    165 		udelay(1);	/* 1 usec */
    166 	}
    167 
    168 	return 1; /* Return value: NOT 0 = complete waiting */
    169 }
    170 
    171 static int sh_sdhi_clock_control(struct sh_sdhi_host *host, unsigned long clk)
    172 {
    173 	u32 clkdiv, i, timeout;
    174 
    175 	if (sh_sdhi_readw(host, SDHI_INFO2) & (1 << 14)) {
    176 		printf(DRIVER_NAME": Busy state ! Cannot change the clock\n");
    177 		return -EBUSY;
    178 	}
    179 
    180 	sh_sdhi_writew(host, SDHI_CLK_CTRL,
    181 		       ~CLK_ENABLE & sh_sdhi_readw(host, SDHI_CLK_CTRL));
    182 
    183 	if (clk == 0)
    184 		return -EIO;
    185 
    186 	clkdiv = 0x80;
    187 	i = CONFIG_SH_SDHI_FREQ >> (0x8 + 1);
    188 	for (; clkdiv && clk >= (i << 1); (clkdiv >>= 1))
    189 		i <<= 1;
    190 
    191 	sh_sdhi_writew(host, SDHI_CLK_CTRL, clkdiv);
    192 
    193 	timeout = 100000;
    194 	/* Waiting for SD Bus busy to be cleared */
    195 	while (timeout--) {
    196 		if ((sh_sdhi_readw(host, SDHI_INFO2) & 0x2000))
    197 			break;
    198 	}
    199 
    200 	if (timeout)
    201 		sh_sdhi_writew(host, SDHI_CLK_CTRL,
    202 			       CLK_ENABLE | sh_sdhi_readw(host, SDHI_CLK_CTRL));
    203 	else
    204 		return -EBUSY;
    205 
    206 	return 0;
    207 }
    208 
    209 static int sh_sdhi_sync_reset(struct sh_sdhi_host *host)
    210 {
    211 	u32 timeout;
    212 	sh_sdhi_writew(host, SDHI_SOFT_RST, SOFT_RST_ON);
    213 	sh_sdhi_writew(host, SDHI_SOFT_RST, SOFT_RST_OFF);
    214 	sh_sdhi_writew(host, SDHI_CLK_CTRL,
    215 		       CLK_ENABLE | sh_sdhi_readw(host, SDHI_CLK_CTRL));
    216 
    217 	timeout = 100000;
    218 	while (timeout--) {
    219 		if (!(sh_sdhi_readw(host, SDHI_INFO2) & INFO2_CBUSY))
    220 			break;
    221 		udelay(100);
    222 	}
    223 
    224 	if (!timeout)
    225 		return -EBUSY;
    226 
    227 	if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
    228 		sh_sdhi_writew(host, SDHI_HOST_MODE, 1);
    229 
    230 	return 0;
    231 }
    232 
    233 static int sh_sdhi_error_manage(struct sh_sdhi_host *host)
    234 {
    235 	unsigned short e_state1, e_state2;
    236 	int ret;
    237 
    238 	host->sd_error = 0;
    239 	host->wait_int = 0;
    240 
    241 	e_state1 = sh_sdhi_readw(host, SDHI_ERR_STS1);
    242 	e_state2 = sh_sdhi_readw(host, SDHI_ERR_STS2);
    243 	if (e_state2 & ERR_STS2_SYS_ERROR) {
    244 		if (e_state2 & ERR_STS2_RES_STOP_TIMEOUT)
    245 			ret = -ETIMEDOUT;
    246 		else
    247 			ret = -EILSEQ;
    248 		debug("%s: ERR_STS2 = %04x\n",
    249 		      DRIVER_NAME, sh_sdhi_readw(host, SDHI_ERR_STS2));
    250 		sh_sdhi_sync_reset(host);
    251 
    252 		sh_sdhi_writew(host, SDHI_INFO1_MASK,
    253 			       INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
    254 		return ret;
    255 	}
    256 	if (e_state1 & ERR_STS1_CRC_ERROR || e_state1 & ERR_STS1_CMD_ERROR)
    257 		ret = -EILSEQ;
    258 	else
    259 		ret = -ETIMEDOUT;
    260 
    261 	debug("%s: ERR_STS1 = %04x\n",
    262 	      DRIVER_NAME, sh_sdhi_readw(host, SDHI_ERR_STS1));
    263 	sh_sdhi_sync_reset(host);
    264 	sh_sdhi_writew(host, SDHI_INFO1_MASK,
    265 		       INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
    266 	return ret;
    267 }
    268 
    269 static int sh_sdhi_single_read(struct sh_sdhi_host *host, struct mmc_data *data)
    270 {
    271 	long time;
    272 	unsigned short blocksize, i;
    273 	unsigned short *p = (unsigned short *)data->dest;
    274 	u64 *q = (u64 *)data->dest;
    275 
    276 	if ((unsigned long)p & 0x00000001) {
    277 		debug(DRIVER_NAME": %s: The data pointer is unaligned.",
    278 		      __func__);
    279 		return -EIO;
    280 	}
    281 
    282 	host->wait_int = 0;
    283 	sh_sdhi_writew(host, SDHI_INFO2_MASK,
    284 		       ~(INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ) &
    285 		       sh_sdhi_readw(host, SDHI_INFO2_MASK));
    286 	sh_sdhi_writew(host, SDHI_INFO1_MASK,
    287 		       ~INFO1M_ACCESS_END &
    288 		       sh_sdhi_readw(host, SDHI_INFO1_MASK));
    289 	time = sh_sdhi_wait_interrupt_flag(host);
    290 	if (time == 0 || host->sd_error != 0)
    291 		return sh_sdhi_error_manage(host);
    292 
    293 	host->wait_int = 0;
    294 	blocksize = sh_sdhi_readw(host, SDHI_SIZE);
    295 	if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
    296 		for (i = 0; i < blocksize / 8; i++)
    297 			*q++ = sh_sdhi_readq(host, SDHI_BUF0);
    298 	else
    299 		for (i = 0; i < blocksize / 2; i++)
    300 			*p++ = sh_sdhi_readw(host, SDHI_BUF0);
    301 
    302 	time = sh_sdhi_wait_interrupt_flag(host);
    303 	if (time == 0 || host->sd_error != 0)
    304 		return sh_sdhi_error_manage(host);
    305 
    306 	host->wait_int = 0;
    307 	return 0;
    308 }
    309 
    310 static int sh_sdhi_multi_read(struct sh_sdhi_host *host, struct mmc_data *data)
    311 {
    312 	long time;
    313 	unsigned short blocksize, i, sec;
    314 	unsigned short *p = (unsigned short *)data->dest;
    315 	u64 *q = (u64 *)data->dest;
    316 
    317 	if ((unsigned long)p & 0x00000001) {
    318 		debug(DRIVER_NAME": %s: The data pointer is unaligned.",
    319 		      __func__);
    320 		return -EIO;
    321 	}
    322 
    323 	debug("%s: blocks = %d, blocksize = %d\n",
    324 	      __func__, data->blocks, data->blocksize);
    325 
    326 	host->wait_int = 0;
    327 	for (sec = 0; sec < data->blocks; sec++) {
    328 		sh_sdhi_writew(host, SDHI_INFO2_MASK,
    329 			       ~(INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ) &
    330 			       sh_sdhi_readw(host, SDHI_INFO2_MASK));
    331 
    332 		time = sh_sdhi_wait_interrupt_flag(host);
    333 		if (time == 0 || host->sd_error != 0)
    334 			return sh_sdhi_error_manage(host);
    335 
    336 		host->wait_int = 0;
    337 		blocksize = sh_sdhi_readw(host, SDHI_SIZE);
    338 		if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
    339 			for (i = 0; i < blocksize / 8; i++)
    340 				*q++ = sh_sdhi_readq(host, SDHI_BUF0);
    341 		else
    342 			for (i = 0; i < blocksize / 2; i++)
    343 				*p++ = sh_sdhi_readw(host, SDHI_BUF0);
    344 	}
    345 
    346 	return 0;
    347 }
    348 
    349 static int sh_sdhi_single_write(struct sh_sdhi_host *host,
    350 		struct mmc_data *data)
    351 {
    352 	long time;
    353 	unsigned short blocksize, i;
    354 	const unsigned short *p = (const unsigned short *)data->src;
    355 	const u64 *q = (const u64 *)data->src;
    356 
    357 	if ((unsigned long)p & 0x00000001) {
    358 		debug(DRIVER_NAME": %s: The data pointer is unaligned.",
    359 		      __func__);
    360 		return -EIO;
    361 	}
    362 
    363 	debug("%s: blocks = %d, blocksize = %d\n",
    364 	      __func__, data->blocks, data->blocksize);
    365 
    366 	host->wait_int = 0;
    367 	sh_sdhi_writew(host, SDHI_INFO2_MASK,
    368 		       ~(INFO2M_BWE_ENABLE | INFO2M_BUF_ILL_WRITE) &
    369 		       sh_sdhi_readw(host, SDHI_INFO2_MASK));
    370 	sh_sdhi_writew(host, SDHI_INFO1_MASK,
    371 		       ~INFO1M_ACCESS_END &
    372 		       sh_sdhi_readw(host, SDHI_INFO1_MASK));
    373 
    374 	time = sh_sdhi_wait_interrupt_flag(host);
    375 	if (time == 0 || host->sd_error != 0)
    376 		return sh_sdhi_error_manage(host);
    377 
    378 	host->wait_int = 0;
    379 	blocksize = sh_sdhi_readw(host, SDHI_SIZE);
    380 	if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
    381 		for (i = 0; i < blocksize / 8; i++)
    382 			sh_sdhi_writeq(host, SDHI_BUF0, *q++);
    383 	else
    384 		for (i = 0; i < blocksize / 2; i++)
    385 			sh_sdhi_writew(host, SDHI_BUF0, *p++);
    386 
    387 	time = sh_sdhi_wait_interrupt_flag(host);
    388 	if (time == 0 || host->sd_error != 0)
    389 		return sh_sdhi_error_manage(host);
    390 
    391 	host->wait_int = 0;
    392 	return 0;
    393 }
    394 
    395 static int sh_sdhi_multi_write(struct sh_sdhi_host *host, struct mmc_data *data)
    396 {
    397 	long time;
    398 	unsigned short i, sec, blocksize;
    399 	const unsigned short *p = (const unsigned short *)data->src;
    400 	const u64 *q = (const u64 *)data->src;
    401 
    402 	debug("%s: blocks = %d, blocksize = %d\n",
    403 	      __func__, data->blocks, data->blocksize);
    404 
    405 	host->wait_int = 0;
    406 	for (sec = 0; sec < data->blocks; sec++) {
    407 		sh_sdhi_writew(host, SDHI_INFO2_MASK,
    408 			       ~(INFO2M_BWE_ENABLE | INFO2M_BUF_ILL_WRITE) &
    409 			       sh_sdhi_readw(host, SDHI_INFO2_MASK));
    410 
    411 		time = sh_sdhi_wait_interrupt_flag(host);
    412 		if (time == 0 || host->sd_error != 0)
    413 			return sh_sdhi_error_manage(host);
    414 
    415 		host->wait_int = 0;
    416 		blocksize = sh_sdhi_readw(host, SDHI_SIZE);
    417 		if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
    418 			for (i = 0; i < blocksize / 8; i++)
    419 				sh_sdhi_writeq(host, SDHI_BUF0, *q++);
    420 		else
    421 			for (i = 0; i < blocksize / 2; i++)
    422 				sh_sdhi_writew(host, SDHI_BUF0, *p++);
    423 	}
    424 
    425 	return 0;
    426 }
    427 
    428 static void sh_sdhi_get_response(struct sh_sdhi_host *host, struct mmc_cmd *cmd)
    429 {
    430 	unsigned short i, j, cnt = 1;
    431 	unsigned short resp[8];
    432 
    433 	if (cmd->resp_type & MMC_RSP_136) {
    434 		cnt = 4;
    435 		resp[0] = sh_sdhi_readw(host, SDHI_RSP00);
    436 		resp[1] = sh_sdhi_readw(host, SDHI_RSP01);
    437 		resp[2] = sh_sdhi_readw(host, SDHI_RSP02);
    438 		resp[3] = sh_sdhi_readw(host, SDHI_RSP03);
    439 		resp[4] = sh_sdhi_readw(host, SDHI_RSP04);
    440 		resp[5] = sh_sdhi_readw(host, SDHI_RSP05);
    441 		resp[6] = sh_sdhi_readw(host, SDHI_RSP06);
    442 		resp[7] = sh_sdhi_readw(host, SDHI_RSP07);
    443 
    444 		/* SDHI REGISTER SPECIFICATION */
    445 		for (i = 7, j = 6; i > 0; i--) {
    446 			resp[i] = (resp[i] << 8) & 0xff00;
    447 			resp[i] |= (resp[j--] >> 8) & 0x00ff;
    448 		}
    449 		resp[0] = (resp[0] << 8) & 0xff00;
    450 	} else {
    451 		resp[0] = sh_sdhi_readw(host, SDHI_RSP00);
    452 		resp[1] = sh_sdhi_readw(host, SDHI_RSP01);
    453 	}
    454 
    455 #if defined(__BIG_ENDIAN_BITFIELD)
    456 	if (cnt == 4) {
    457 		cmd->response[0] = (resp[6] << 16) | resp[7];
    458 		cmd->response[1] = (resp[4] << 16) | resp[5];
    459 		cmd->response[2] = (resp[2] << 16) | resp[3];
    460 		cmd->response[3] = (resp[0] << 16) | resp[1];
    461 	} else {
    462 		cmd->response[0] = (resp[0] << 16) | resp[1];
    463 	}
    464 #else
    465 	if (cnt == 4) {
    466 		cmd->response[0] = (resp[7] << 16) | resp[6];
    467 		cmd->response[1] = (resp[5] << 16) | resp[4];
    468 		cmd->response[2] = (resp[3] << 16) | resp[2];
    469 		cmd->response[3] = (resp[1] << 16) | resp[0];
    470 	} else {
    471 		cmd->response[0] = (resp[1] << 16) | resp[0];
    472 	}
    473 #endif /* __BIG_ENDIAN_BITFIELD */
    474 }
    475 
    476 static unsigned short sh_sdhi_set_cmd(struct sh_sdhi_host *host,
    477 			struct mmc_data *data, unsigned short opc)
    478 {
    479 	if (host->app_cmd) {
    480 		if (!data)
    481 			host->app_cmd = 0;
    482 		return opc | BIT(6);
    483 	}
    484 
    485 	switch (opc) {
    486 	case MMC_CMD_SWITCH:
    487 		return opc | (data ? 0x1c00 : 0x40);
    488 	case MMC_CMD_SEND_EXT_CSD:
    489 		return opc | (data ? 0x1c00 : 0);
    490 	case MMC_CMD_SEND_OP_COND:
    491 		return opc | 0x0700;
    492 	case MMC_CMD_APP_CMD:
    493 		host->app_cmd = 1;
    494 	default:
    495 		return opc;
    496 	}
    497 }
    498 
    499 static unsigned short sh_sdhi_data_trans(struct sh_sdhi_host *host,
    500 			struct mmc_data *data, unsigned short opc)
    501 {
    502 	if (host->app_cmd) {
    503 		host->app_cmd = 0;
    504 		switch (opc) {
    505 		case SD_CMD_APP_SEND_SCR:
    506 		case SD_CMD_APP_SD_STATUS:
    507 			return sh_sdhi_single_read(host, data);
    508 		default:
    509 			printf(DRIVER_NAME": SD: NOT SUPPORT APP CMD = d'%04d\n",
    510 				opc);
    511 			return -EINVAL;
    512 		}
    513 	} else {
    514 		switch (opc) {
    515 		case MMC_CMD_WRITE_MULTIPLE_BLOCK:
    516 			return sh_sdhi_multi_write(host, data);
    517 		case MMC_CMD_READ_MULTIPLE_BLOCK:
    518 			return sh_sdhi_multi_read(host, data);
    519 		case MMC_CMD_WRITE_SINGLE_BLOCK:
    520 			return sh_sdhi_single_write(host, data);
    521 		case MMC_CMD_READ_SINGLE_BLOCK:
    522 		case MMC_CMD_SWITCH:
    523 		case MMC_CMD_SEND_EXT_CSD:;
    524 			return sh_sdhi_single_read(host, data);
    525 		default:
    526 			printf(DRIVER_NAME": SD: NOT SUPPORT CMD = d'%04d\n", opc);
    527 			return -EINVAL;
    528 		}
    529 	}
    530 }
    531 
    532 static int sh_sdhi_start_cmd(struct sh_sdhi_host *host,
    533 			struct mmc_data *data, struct mmc_cmd *cmd)
    534 {
    535 	long time;
    536 	unsigned short shcmd, opc = cmd->cmdidx;
    537 	int ret = 0;
    538 	unsigned long timeout;
    539 
    540 	debug("opc = %d, arg = %x, resp_type = %x\n",
    541 	      opc, cmd->cmdarg, cmd->resp_type);
    542 
    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));
    547 
    548 		time = sh_sdhi_wait_interrupt_flag(host);
    549 		if (time == 0 || host->sd_error != 0)
    550 			return sh_sdhi_error_manage(host);
    551 
    552 		sh_sdhi_get_response(host, cmd);
    553 		return 0;
    554 	}
    555 
    556 	if (data) {
    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);
    561 		}
    562 		sh_sdhi_writew(host, SDHI_SIZE, data->blocksize);
    563 	}
    564 
    565 	shcmd = sh_sdhi_set_cmd(host, data, opc);
    566 
    567 	/*
    568 	 *  U-Boot cannot use interrupt.
    569 	 *  So this flag may not be clear by timing
    570 	 */
    571 	sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_RESP_END);
    572 
    573 	sh_sdhi_writew(host, SDHI_INFO1_MASK,
    574 		       INFO1M_RESP_END | sh_sdhi_readw(host, SDHI_INFO1_MASK));
    575 	sh_sdhi_writew(host, SDHI_ARG0,
    576 		       (unsigned short)(cmd->cmdarg & ARG0_MASK));
    577 	sh_sdhi_writew(host, SDHI_ARG1,
    578 		       (unsigned short)((cmd->cmdarg >> 16) & ARG1_MASK));
    579 
    580 	timeout = 100000;
    581 	/* Waiting for SD Bus busy to be cleared */
    582 	while (timeout--) {
    583 		if ((sh_sdhi_readw(host, SDHI_INFO2) & 0x2000))
    584 			break;
    585 	}
    586 
    587 	host->wait_int = 0;
    588 	sh_sdhi_writew(host, SDHI_INFO1_MASK,
    589 		       ~INFO1M_RESP_END & sh_sdhi_readw(host, SDHI_INFO1_MASK));
    590 	sh_sdhi_writew(host, SDHI_INFO2_MASK,
    591 		       ~(INFO2M_CMD_ERROR | INFO2M_CRC_ERROR |
    592 		       INFO2M_END_ERROR | INFO2M_TIMEOUT |
    593 		       INFO2M_RESP_TIMEOUT | INFO2M_ILA) &
    594 		       sh_sdhi_readw(host, SDHI_INFO2_MASK));
    595 
    596 	sh_sdhi_writew(host, SDHI_CMD, (unsigned short)(shcmd & CMD_MASK));
    597 	time = sh_sdhi_wait_interrupt_flag(host);
    598 	if (!time) {
    599 		host->app_cmd = 0;
    600 		return sh_sdhi_error_manage(host);
    601 	}
    602 
    603 	if (host->sd_error) {
    604 		switch (cmd->cmdidx) {
    605 		case MMC_CMD_ALL_SEND_CID:
    606 		case MMC_CMD_SELECT_CARD:
    607 		case SD_CMD_SEND_IF_COND:
    608 		case MMC_CMD_APP_CMD:
    609 			ret = -ETIMEDOUT;
    610 			break;
    611 		default:
    612 			debug(DRIVER_NAME": Cmd(d'%d) err\n", opc);
    613 			debug(DRIVER_NAME": cmdidx = %d\n", cmd->cmdidx);
    614 			ret = sh_sdhi_error_manage(host);
    615 			break;
    616 		}
    617 		host->sd_error = 0;
    618 		host->wait_int = 0;
    619 		host->app_cmd = 0;
    620 		return ret;
    621 	}
    622 
    623 	if (sh_sdhi_readw(host, SDHI_INFO1) & INFO1_RESP_END) {
    624 		host->app_cmd = 0;
    625 		return -EINVAL;
    626 	}
    627 
    628 	if (host->wait_int) {
    629 		sh_sdhi_get_response(host, cmd);
    630 		host->wait_int = 0;
    631 	}
    632 
    633 	if (data)
    634 		ret = sh_sdhi_data_trans(host, data, opc);
    635 
    636 	debug("ret = %d, resp = %08x, %08x, %08x, %08x\n",
    637 	      ret, cmd->response[0], cmd->response[1],
    638 	      cmd->response[2], cmd->response[3]);
    639 	return ret;
    640 }
    641 
    642 static int sh_sdhi_send_cmd_common(struct sh_sdhi_host *host,
    643 				   struct mmc_cmd *cmd, struct mmc_data *data)
    644 {
    645 	host->sd_error = 0;
    646 
    647 	return sh_sdhi_start_cmd(host, data, cmd);
    648 }
    649 
    650 static int sh_sdhi_set_ios_common(struct sh_sdhi_host *host, struct mmc *mmc)
    651 {
    652 	int ret;
    653 
    654 	ret = sh_sdhi_clock_control(host, mmc->clock);
    655 	if (ret)
    656 		return -EINVAL;
    657 
    658 	if (mmc->bus_width == 8)
    659 		sh_sdhi_writew(host, SDHI_OPTION,
    660 			       OPT_BUS_WIDTH_8 | (~OPT_BUS_WIDTH_M &
    661 			       sh_sdhi_readw(host, SDHI_OPTION)));
    662 	else if (mmc->bus_width == 4)
    663 		sh_sdhi_writew(host, SDHI_OPTION,
    664 			       OPT_BUS_WIDTH_4 | (~OPT_BUS_WIDTH_M &
    665 			       sh_sdhi_readw(host, SDHI_OPTION)));
    666 	else
    667 		sh_sdhi_writew(host, SDHI_OPTION,
    668 			       OPT_BUS_WIDTH_1 | (~OPT_BUS_WIDTH_M &
    669 			       sh_sdhi_readw(host, SDHI_OPTION)));
    670 
    671 	debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width);
    672 
    673 	return 0;
    674 }
    675 
    676 static int sh_sdhi_initialize_common(struct sh_sdhi_host *host)
    677 {
    678 	int ret = sh_sdhi_sync_reset(host);
    679 
    680 	sh_sdhi_writew(host, SDHI_PORTSEL, USE_1PORT);
    681 
    682 #if defined(__BIG_ENDIAN_BITFIELD)
    683 	sh_sdhi_writew(host, SDHI_EXT_SWAP, SET_SWAP);
    684 #endif
    685 
    686 	sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END |
    687 		       INFO1M_ACCESS_END | INFO1M_CARD_RE |
    688 		       INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
    689 
    690 	return ret;
    691 }
    692 
    693 #ifndef CONFIG_DM_MMC
    694 static void *mmc_priv(struct mmc *mmc)
    695 {
    696 	return (void *)mmc->priv;
    697 }
    698 
    699 static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
    700 			    struct mmc_data *data)
    701 {
    702 	struct sh_sdhi_host *host = mmc_priv(mmc);
    703 
    704 	return sh_sdhi_send_cmd_common(host, cmd, data);
    705 }
    706 
    707 static int sh_sdhi_set_ios(struct mmc *mmc)
    708 {
    709 	struct sh_sdhi_host *host = mmc_priv(mmc);
    710 
    711 	return sh_sdhi_set_ios_common(host, mmc);
    712 }
    713 
    714 static int sh_sdhi_initialize(struct mmc *mmc)
    715 {
    716 	struct sh_sdhi_host *host = mmc_priv(mmc);
    717 
    718 	return sh_sdhi_initialize_common(host);
    719 }
    720 
    721 static const struct mmc_ops sh_sdhi_ops = {
    722 	.send_cmd       = sh_sdhi_send_cmd,
    723 	.set_ios        = sh_sdhi_set_ios,
    724 	.init           = sh_sdhi_initialize,
    725 };
    726 
    727 #ifdef CONFIG_RCAR_GEN3
    728 static struct mmc_config sh_sdhi_cfg = {
    729 	.name           = DRIVER_NAME,
    730 	.ops            = &sh_sdhi_ops,
    731 	.f_min          = CLKDEV_INIT,
    732 	.f_max          = CLKDEV_HS_DATA,
    733 	.voltages       = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
    734 	.host_caps      = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HS |
    735 			  MMC_MODE_HS_52MHz,
    736 	.part_type      = PART_TYPE_DOS,
    737 	.b_max          = CONFIG_SYS_MMC_MAX_BLK_COUNT,
    738 };
    739 #else
    740 static struct mmc_config sh_sdhi_cfg = {
    741 	.name           = DRIVER_NAME,
    742 	.ops            = &sh_sdhi_ops,
    743 	.f_min          = CLKDEV_INIT,
    744 	.f_max          = CLKDEV_HS_DATA,
    745 	.voltages       = MMC_VDD_32_33 | MMC_VDD_33_34,
    746 	.host_caps      = MMC_MODE_4BIT | MMC_MODE_HS,
    747 	.part_type      = PART_TYPE_DOS,
    748 	.b_max          = CONFIG_SYS_MMC_MAX_BLK_COUNT,
    749 };
    750 #endif
    751 
    752 int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks)
    753 {
    754 	int ret = 0;
    755 	struct mmc *mmc;
    756 	struct sh_sdhi_host *host = NULL;
    757 
    758 	if (ch >= CONFIG_SYS_SH_SDHI_NR_CHANNEL)
    759 		return -ENODEV;
    760 
    761 	host = malloc(sizeof(struct sh_sdhi_host));
    762 	if (!host)
    763 		return -ENOMEM;
    764 
    765 	mmc = mmc_create(&sh_sdhi_cfg, host);
    766 	if (!mmc) {
    767 		ret = -1;
    768 		goto error;
    769 	}
    770 
    771 	host->ch = ch;
    772 	host->addr = (void __iomem *)addr;
    773 	host->quirks = quirks;
    774 
    775 	if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
    776 		host->bus_shift = 2;
    777 	else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
    778 		host->bus_shift = 1;
    779 
    780 	return ret;
    781 error:
    782 	if (host)
    783 		free(host);
    784 	return ret;
    785 }
    786 
    787 #else
    788 
    789 struct sh_sdhi_plat {
    790 	struct mmc_config cfg;
    791 	struct mmc mmc;
    792 };
    793 
    794 int sh_sdhi_dm_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
    795 			struct mmc_data *data)
    796 {
    797 	struct sh_sdhi_host *host = dev_get_priv(dev);
    798 
    799 	return sh_sdhi_send_cmd_common(host, cmd, data);
    800 }
    801 
    802 int sh_sdhi_dm_set_ios(struct udevice *dev)
    803 {
    804 	struct sh_sdhi_host *host = dev_get_priv(dev);
    805 	struct mmc *mmc = mmc_get_mmc_dev(dev);
    806 
    807 	return sh_sdhi_set_ios_common(host, mmc);
    808 }
    809 
    810 static const struct dm_mmc_ops sh_sdhi_dm_ops = {
    811 	.send_cmd	= sh_sdhi_dm_send_cmd,
    812 	.set_ios	= sh_sdhi_dm_set_ios,
    813 };
    814 
    815 static int sh_sdhi_dm_bind(struct udevice *dev)
    816 {
    817 	struct sh_sdhi_plat *plat = dev_get_platdata(dev);
    818 
    819 	return mmc_bind(dev, &plat->mmc, &plat->cfg);
    820 }
    821 
    822 static int sh_sdhi_dm_probe(struct udevice *dev)
    823 {
    824 	struct sh_sdhi_plat *plat = dev_get_platdata(dev);
    825 	struct sh_sdhi_host *host = dev_get_priv(dev);
    826 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
    827 	struct clk sh_sdhi_clk;
    828 	const u32 quirks = dev_get_driver_data(dev);
    829 	fdt_addr_t base;
    830 	int ret;
    831 
    832 	base = devfdt_get_addr(dev);
    833 	if (base == FDT_ADDR_T_NONE)
    834 		return -EINVAL;
    835 
    836 	host->addr = devm_ioremap(dev, base, SZ_2K);
    837 	if (!host->addr)
    838 		return -ENOMEM;
    839 
    840 	ret = clk_get_by_index(dev, 0, &sh_sdhi_clk);
    841 	if (ret) {
    842 		debug("failed to get clock, ret=%d\n", ret);
    843 		return ret;
    844 	}
    845 
    846 	ret = clk_enable(&sh_sdhi_clk);
    847 	if (ret) {
    848 		debug("failed to enable clock, ret=%d\n", ret);
    849 		return ret;
    850 	}
    851 
    852 	host->quirks = quirks;
    853 
    854 	if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
    855 		host->bus_shift = 2;
    856 	else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
    857 		host->bus_shift = 1;
    858 
    859 	plat->cfg.name = dev->name;
    860 	plat->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
    861 
    862 	switch (fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width",
    863 			       1)) {
    864 	case 8:
    865 		plat->cfg.host_caps |= MMC_MODE_8BIT;
    866 		break;
    867 	case 4:
    868 		plat->cfg.host_caps |= MMC_MODE_4BIT;
    869 		break;
    870 	case 1:
    871 		break;
    872 	default:
    873 		dev_err(dev, "Invalid \"bus-width\" value\n");
    874 		return -EINVAL;
    875 	}
    876 
    877 	sh_sdhi_initialize_common(host);
    878 
    879 	plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
    880 	plat->cfg.f_min = CLKDEV_INIT;
    881 	plat->cfg.f_max = CLKDEV_HS_DATA;
    882 	plat->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
    883 
    884 	upriv->mmc = &plat->mmc;
    885 
    886 	return 0;
    887 }
    888 
    889 static const struct udevice_id sh_sdhi_sd_match[] = {
    890 	{ .compatible = "renesas,sdhi-r8a7795", .data = SH_SDHI_QUIRK_64BIT_BUF },
    891 	{ .compatible = "renesas,sdhi-r8a7796", .data = SH_SDHI_QUIRK_64BIT_BUF },
    892 	{ /* sentinel */ }
    893 };
    894 
    895 U_BOOT_DRIVER(sh_sdhi_mmc) = {
    896 	.name			= "sh-sdhi-mmc",
    897 	.id			= UCLASS_MMC,
    898 	.of_match		= sh_sdhi_sd_match,
    899 	.bind			= sh_sdhi_dm_bind,
    900 	.probe			= sh_sdhi_dm_probe,
    901 	.priv_auto_alloc_size	= sizeof(struct sh_sdhi_host),
    902 	.platdata_auto_alloc_size = sizeof(struct sh_sdhi_plat),
    903 	.ops			= &sh_sdhi_dm_ops,
    904 };
    905 #endif
    906