xref: /openbmc/u-boot/drivers/mmc/sh_sdhi.c (revision 9d466f2f)
1 /*
2  * drivers/mmc/sh_sdhi.c
3  *
4  * SD/MMC driver for Renesas rmobile ARM SoCs.
5  *
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.
9  *
10  * SPDX-License-Identifier:	GPL-2.0
11  */
12 
13 #include <common.h>
14 #include <malloc.h>
15 #include <mmc.h>
16 #include <dm.h>
17 #include <linux/errno.h>
18 #include <linux/compat.h>
19 #include <linux/io.h>
20 #include <linux/sizes.h>
21 #include <asm/arch/rmobile.h>
22 #include <asm/arch/sh_sdhi.h>
23 #include <clk.h>
24 
25 #define DRIVER_NAME "sh-sdhi"
26 
27 struct sh_sdhi_host {
28 	void __iomem *addr;
29 	int ch;
30 	int bus_shift;
31 	unsigned long quirks;
32 	unsigned char wait_int;
33 	unsigned char sd_error;
34 	unsigned char detect_waiting;
35 	unsigned char app_cmd;
36 };
37 
38 static inline void sh_sdhi_writeq(struct sh_sdhi_host *host, int reg, u64 val)
39 {
40 	writeq(val, host->addr + (reg << host->bus_shift));
41 }
42 
43 static inline u64 sh_sdhi_readq(struct sh_sdhi_host *host, int reg)
44 {
45 	return readq(host->addr + (reg << host->bus_shift));
46 }
47 
48 static inline void sh_sdhi_writew(struct sh_sdhi_host *host, int reg, u16 val)
49 {
50 	writew(val, host->addr + (reg << host->bus_shift));
51 }
52 
53 static inline u16 sh_sdhi_readw(struct sh_sdhi_host *host, int reg)
54 {
55 	return readw(host->addr + (reg << host->bus_shift));
56 }
57 
58 static void sh_sdhi_detect(struct sh_sdhi_host *host)
59 {
60 	sh_sdhi_writew(host, SDHI_OPTION,
61 		       OPT_BUS_WIDTH_1 | sh_sdhi_readw(host, SDHI_OPTION));
62 
63 	host->detect_waiting = 0;
64 }
65 
66 static int sh_sdhi_intr(void *dev_id)
67 {
68 	struct sh_sdhi_host *host = dev_id;
69 	int state1 = 0, state2 = 0;
70 
71 	state1 = sh_sdhi_readw(host, SDHI_INFO1);
72 	state2 = sh_sdhi_readw(host, SDHI_INFO2);
73 
74 	debug("%s: state1 = %x, state2 = %x\n", __func__, state1, state2);
75 
76 	/* CARD Insert */
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;
81 			sh_sdhi_detect(host);
82 		}
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);
86 		return -EAGAIN;
87 	}
88 	/* CARD Removal */
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;
93 			sh_sdhi_detect(host);
94 		}
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);
100 		return -EAGAIN;
101 	}
102 
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,
107 			       INFO2M_ALL_ERR |
108 			       sh_sdhi_readw(host, SDHI_INFO2_MASK));
109 		host->sd_error = 1;
110 		host->wait_int = 1;
111 		return 0;
112 	}
113 	/* Respons End */
114 	if (state1 & INFO1_RESP_END) {
115 		sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_RESP_END);
116 		sh_sdhi_writew(host, SDHI_INFO1_MASK,
117 			       INFO1M_RESP_END |
118 			       sh_sdhi_readw(host, SDHI_INFO1_MASK));
119 		host->wait_int = 1;
120 		return 0;
121 	}
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));
128 		host->wait_int = 1;
129 		return 0;
130 	}
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));
137 		host->wait_int = 1;
138 		return 0;
139 	}
140 	/* Access End */
141 	if (state1 & INFO1_ACCESS_END) {
142 		sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_ACCESS_END);
143 		sh_sdhi_writew(host, SDHI_INFO1_MASK,
144 			       INFO1_ACCESS_END |
145 			       sh_sdhi_readw(host, SDHI_INFO1_MASK));
146 		host->wait_int = 1;
147 		return 0;
148 	}
149 	return -EAGAIN;
150 }
151 
152 static int sh_sdhi_wait_interrupt_flag(struct sh_sdhi_host *host)
153 {
154 	int timeout = 10000000;
155 
156 	while (1) {
157 		timeout--;
158 		if (timeout < 0) {
159 			debug(DRIVER_NAME": %s timeout\n", __func__);
160 			return 0;
161 		}
162 
163 		if (!sh_sdhi_intr(host))
164 			break;
165 
166 		udelay(1);	/* 1 usec */
167 	}
168 
169 	return 1; /* Return value: NOT 0 = complete waiting */
170 }
171 
172 static int sh_sdhi_clock_control(struct sh_sdhi_host *host, unsigned long clk)
173 {
174 	u32 clkdiv, i, timeout;
175 
176 	if (sh_sdhi_readw(host, SDHI_INFO2) & (1 << 14)) {
177 		printf(DRIVER_NAME": Busy state ! Cannot change the clock\n");
178 		return -EBUSY;
179 	}
180 
181 	sh_sdhi_writew(host, SDHI_CLK_CTRL,
182 		       ~CLK_ENABLE & sh_sdhi_readw(host, SDHI_CLK_CTRL));
183 
184 	if (clk == 0)
185 		return -EIO;
186 
187 	clkdiv = 0x80;
188 	i = CONFIG_SH_SDHI_FREQ >> (0x8 + 1);
189 	for (; clkdiv && clk >= (i << 1); (clkdiv >>= 1))
190 		i <<= 1;
191 
192 	sh_sdhi_writew(host, SDHI_CLK_CTRL, clkdiv);
193 
194 	timeout = 100000;
195 	/* Waiting for SD Bus busy to be cleared */
196 	while (timeout--) {
197 		if ((sh_sdhi_readw(host, SDHI_INFO2) & 0x2000))
198 			break;
199 	}
200 
201 	if (timeout)
202 		sh_sdhi_writew(host, SDHI_CLK_CTRL,
203 			       CLK_ENABLE | sh_sdhi_readw(host, SDHI_CLK_CTRL));
204 	else
205 		return -EBUSY;
206 
207 	return 0;
208 }
209 
210 static int sh_sdhi_sync_reset(struct sh_sdhi_host *host)
211 {
212 	u32 timeout;
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));
217 
218 	timeout = 100000;
219 	while (timeout--) {
220 		if (!(sh_sdhi_readw(host, SDHI_INFO2) & INFO2_CBUSY))
221 			break;
222 		udelay(100);
223 	}
224 
225 	if (!timeout)
226 		return -EBUSY;
227 
228 	if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
229 		sh_sdhi_writew(host, SDHI_HOST_MODE, 1);
230 
231 	return 0;
232 }
233 
234 static int sh_sdhi_error_manage(struct sh_sdhi_host *host)
235 {
236 	unsigned short e_state1, e_state2;
237 	int ret;
238 
239 	host->sd_error = 0;
240 	host->wait_int = 0;
241 
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)
246 			ret = -ETIMEDOUT;
247 		else
248 			ret = -EILSEQ;
249 		debug("%s: ERR_STS2 = %04x\n",
250 		      DRIVER_NAME, sh_sdhi_readw(host, SDHI_ERR_STS2));
251 		sh_sdhi_sync_reset(host);
252 
253 		sh_sdhi_writew(host, SDHI_INFO1_MASK,
254 			       INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
255 		return ret;
256 	}
257 	if (e_state1 & ERR_STS1_CRC_ERROR || e_state1 & ERR_STS1_CMD_ERROR)
258 		ret = -EILSEQ;
259 	else
260 		ret = -ETIMEDOUT;
261 
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);
267 	return ret;
268 }
269 
270 static int sh_sdhi_single_read(struct sh_sdhi_host *host, struct mmc_data *data)
271 {
272 	long time;
273 	unsigned short blocksize, i;
274 	unsigned short *p = (unsigned short *)data->dest;
275 	u64 *q = (u64 *)data->dest;
276 
277 	if ((unsigned long)p & 0x00000001) {
278 		debug(DRIVER_NAME": %s: The data pointer is unaligned.",
279 		      __func__);
280 		return -EIO;
281 	}
282 
283 	host->wait_int = 0;
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,
288 		       ~INFO1M_ACCESS_END &
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);
293 
294 	host->wait_int = 0;
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);
299 	else
300 		for (i = 0; i < blocksize / 2; i++)
301 			*p++ = sh_sdhi_readw(host, SDHI_BUF0);
302 
303 	time = sh_sdhi_wait_interrupt_flag(host);
304 	if (time == 0 || host->sd_error != 0)
305 		return sh_sdhi_error_manage(host);
306 
307 	host->wait_int = 0;
308 	return 0;
309 }
310 
311 static int sh_sdhi_multi_read(struct sh_sdhi_host *host, struct mmc_data *data)
312 {
313 	long time;
314 	unsigned short blocksize, i, sec;
315 	unsigned short *p = (unsigned short *)data->dest;
316 	u64 *q = (u64 *)data->dest;
317 
318 	if ((unsigned long)p & 0x00000001) {
319 		debug(DRIVER_NAME": %s: The data pointer is unaligned.",
320 		      __func__);
321 		return -EIO;
322 	}
323 
324 	debug("%s: blocks = %d, blocksize = %d\n",
325 	      __func__, data->blocks, data->blocksize);
326 
327 	host->wait_int = 0;
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));
332 
333 		time = sh_sdhi_wait_interrupt_flag(host);
334 		if (time == 0 || host->sd_error != 0)
335 			return sh_sdhi_error_manage(host);
336 
337 		host->wait_int = 0;
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);
342 		else
343 			for (i = 0; i < blocksize / 2; i++)
344 				*p++ = sh_sdhi_readw(host, SDHI_BUF0);
345 	}
346 
347 	return 0;
348 }
349 
350 static int sh_sdhi_single_write(struct sh_sdhi_host *host,
351 		struct mmc_data *data)
352 {
353 	long time;
354 	unsigned short blocksize, i;
355 	const unsigned short *p = (const unsigned short *)data->src;
356 	const u64 *q = (const u64 *)data->src;
357 
358 	if ((unsigned long)p & 0x00000001) {
359 		debug(DRIVER_NAME": %s: The data pointer is unaligned.",
360 		      __func__);
361 		return -EIO;
362 	}
363 
364 	debug("%s: blocks = %d, blocksize = %d\n",
365 	      __func__, data->blocks, data->blocksize);
366 
367 	host->wait_int = 0;
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,
372 		       ~INFO1M_ACCESS_END &
373 		       sh_sdhi_readw(host, SDHI_INFO1_MASK));
374 
375 	time = sh_sdhi_wait_interrupt_flag(host);
376 	if (time == 0 || host->sd_error != 0)
377 		return sh_sdhi_error_manage(host);
378 
379 	host->wait_int = 0;
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++);
384 	else
385 		for (i = 0; i < blocksize / 2; i++)
386 			sh_sdhi_writew(host, SDHI_BUF0, *p++);
387 
388 	time = sh_sdhi_wait_interrupt_flag(host);
389 	if (time == 0 || host->sd_error != 0)
390 		return sh_sdhi_error_manage(host);
391 
392 	host->wait_int = 0;
393 	return 0;
394 }
395 
396 static int sh_sdhi_multi_write(struct sh_sdhi_host *host, struct mmc_data *data)
397 {
398 	long time;
399 	unsigned short i, sec, blocksize;
400 	const unsigned short *p = (const unsigned short *)data->src;
401 	const u64 *q = (const u64 *)data->src;
402 
403 	debug("%s: blocks = %d, blocksize = %d\n",
404 	      __func__, data->blocks, data->blocksize);
405 
406 	host->wait_int = 0;
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));
411 
412 		time = sh_sdhi_wait_interrupt_flag(host);
413 		if (time == 0 || host->sd_error != 0)
414 			return sh_sdhi_error_manage(host);
415 
416 		host->wait_int = 0;
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++);
421 		else
422 			for (i = 0; i < blocksize / 2; i++)
423 				sh_sdhi_writew(host, SDHI_BUF0, *p++);
424 	}
425 
426 	return 0;
427 }
428 
429 static void sh_sdhi_get_response(struct sh_sdhi_host *host, struct mmc_cmd *cmd)
430 {
431 	unsigned short i, j, cnt = 1;
432 	unsigned short resp[8];
433 
434 	if (cmd->resp_type & MMC_RSP_136) {
435 		cnt = 4;
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);
444 
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;
449 		}
450 		resp[0] = (resp[0] << 8) & 0xff00;
451 	} else {
452 		resp[0] = sh_sdhi_readw(host, SDHI_RSP00);
453 		resp[1] = sh_sdhi_readw(host, SDHI_RSP01);
454 	}
455 
456 #if defined(__BIG_ENDIAN_BITFIELD)
457 	if (cnt == 4) {
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];
462 	} else {
463 		cmd->response[0] = (resp[0] << 16) | resp[1];
464 	}
465 #else
466 	if (cnt == 4) {
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];
471 	} else {
472 		cmd->response[0] = (resp[1] << 16) | resp[0];
473 	}
474 #endif /* __BIG_ENDIAN_BITFIELD */
475 }
476 
477 static unsigned short sh_sdhi_set_cmd(struct sh_sdhi_host *host,
478 			struct mmc_data *data, unsigned short opc)
479 {
480 	if (host->app_cmd) {
481 		if (!data)
482 			host->app_cmd = 0;
483 		return opc | BIT(6);
484 	}
485 
486 	switch (opc) {
487 	case MMC_CMD_SWITCH:
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:
492 		return opc | 0x0700;
493 	case MMC_CMD_APP_CMD:
494 		host->app_cmd = 1;
495 	default:
496 		return opc;
497 	}
498 }
499 
500 static unsigned short sh_sdhi_data_trans(struct sh_sdhi_host *host,
501 			struct mmc_data *data, unsigned short opc)
502 {
503 	if (host->app_cmd) {
504 		host->app_cmd = 0;
505 		switch (opc) {
506 		case SD_CMD_APP_SEND_SCR:
507 		case SD_CMD_APP_SD_STATUS:
508 			return sh_sdhi_single_read(host, data);
509 		default:
510 			printf(DRIVER_NAME": SD: NOT SUPPORT APP CMD = d'%04d\n",
511 				opc);
512 			return -EINVAL;
513 		}
514 	} else {
515 		switch (opc) {
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:
523 		case MMC_CMD_SWITCH:
524 		case MMC_CMD_SEND_EXT_CSD:;
525 			return sh_sdhi_single_read(host, data);
526 		default:
527 			printf(DRIVER_NAME": SD: NOT SUPPORT CMD = d'%04d\n", opc);
528 			return -EINVAL;
529 		}
530 	}
531 }
532 
533 static int sh_sdhi_start_cmd(struct sh_sdhi_host *host,
534 			struct mmc_data *data, struct mmc_cmd *cmd)
535 {
536 	long time;
537 	unsigned short shcmd, opc = cmd->cmdidx;
538 	int ret = 0;
539 	unsigned long timeout;
540 
541 	debug("opc = %d, arg = %x, resp_type = %x\n",
542 	      opc, cmd->cmdarg, cmd->resp_type);
543 
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));
548 
549 		time = sh_sdhi_wait_interrupt_flag(host);
550 		if (time == 0 || host->sd_error != 0)
551 			return sh_sdhi_error_manage(host);
552 
553 		sh_sdhi_get_response(host, cmd);
554 		return 0;
555 	}
556 
557 	if (data) {
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);
562 		}
563 		sh_sdhi_writew(host, SDHI_SIZE, data->blocksize);
564 	}
565 
566 	shcmd = sh_sdhi_set_cmd(host, data, opc);
567 
568 	/*
569 	 *  U-Boot cannot use interrupt.
570 	 *  So this flag may not be clear by timing
571 	 */
572 	sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_RESP_END);
573 
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));
580 
581 	timeout = 100000;
582 	/* Waiting for SD Bus busy to be cleared */
583 	while (timeout--) {
584 		if ((sh_sdhi_readw(host, SDHI_INFO2) & 0x2000))
585 			break;
586 	}
587 
588 	host->wait_int = 0;
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));
596 
597 	sh_sdhi_writew(host, SDHI_CMD, (unsigned short)(shcmd & CMD_MASK));
598 	time = sh_sdhi_wait_interrupt_flag(host);
599 	if (!time) {
600 		host->app_cmd = 0;
601 		return sh_sdhi_error_manage(host);
602 	}
603 
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:
610 			ret = -ETIMEDOUT;
611 			break;
612 		default:
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);
616 			break;
617 		}
618 		host->sd_error = 0;
619 		host->wait_int = 0;
620 		host->app_cmd = 0;
621 		return ret;
622 	}
623 
624 	if (sh_sdhi_readw(host, SDHI_INFO1) & INFO1_RESP_END) {
625 		host->app_cmd = 0;
626 		return -EINVAL;
627 	}
628 
629 	if (host->wait_int) {
630 		sh_sdhi_get_response(host, cmd);
631 		host->wait_int = 0;
632 	}
633 
634 	if (data)
635 		ret = sh_sdhi_data_trans(host, data, opc);
636 
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]);
640 	return ret;
641 }
642 
643 static int sh_sdhi_send_cmd_common(struct sh_sdhi_host *host,
644 				   struct mmc_cmd *cmd, struct mmc_data *data)
645 {
646 	host->sd_error = 0;
647 
648 	return sh_sdhi_start_cmd(host, data, cmd);
649 }
650 
651 static int sh_sdhi_set_ios_common(struct sh_sdhi_host *host, struct mmc *mmc)
652 {
653 	int ret;
654 
655 	ret = sh_sdhi_clock_control(host, mmc->clock);
656 	if (ret)
657 		return -EINVAL;
658 
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)));
667 	else
668 		sh_sdhi_writew(host, SDHI_OPTION,
669 			       OPT_BUS_WIDTH_1 | (~OPT_BUS_WIDTH_M &
670 			       sh_sdhi_readw(host, SDHI_OPTION)));
671 
672 	debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width);
673 
674 	return 0;
675 }
676 
677 static int sh_sdhi_initialize_common(struct sh_sdhi_host *host)
678 {
679 	int ret = sh_sdhi_sync_reset(host);
680 
681 	sh_sdhi_writew(host, SDHI_PORTSEL, USE_1PORT);
682 
683 #if defined(__BIG_ENDIAN_BITFIELD)
684 	sh_sdhi_writew(host, SDHI_EXT_SWAP, SET_SWAP);
685 #endif
686 
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);
690 
691 	return ret;
692 }
693 
694 #ifndef CONFIG_DM_MMC
695 static void *mmc_priv(struct mmc *mmc)
696 {
697 	return (void *)mmc->priv;
698 }
699 
700 static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
701 			    struct mmc_data *data)
702 {
703 	struct sh_sdhi_host *host = mmc_priv(mmc);
704 
705 	return sh_sdhi_send_cmd_common(host, cmd, data);
706 }
707 
708 static int sh_sdhi_set_ios(struct mmc *mmc)
709 {
710 	struct sh_sdhi_host *host = mmc_priv(mmc);
711 
712 	return sh_sdhi_set_ios_common(host, mmc);
713 }
714 
715 static int sh_sdhi_initialize(struct mmc *mmc)
716 {
717 	struct sh_sdhi_host *host = mmc_priv(mmc);
718 
719 	return sh_sdhi_initialize_common(host);
720 }
721 
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,
726 };
727 
728 #ifdef CONFIG_RCAR_GEN3
729 static struct mmc_config sh_sdhi_cfg = {
730 	.name           = DRIVER_NAME,
731 	.ops            = &sh_sdhi_ops,
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 |
736 			  MMC_MODE_HS_52MHz,
737 	.part_type      = PART_TYPE_DOS,
738 	.b_max          = CONFIG_SYS_MMC_MAX_BLK_COUNT,
739 };
740 #else
741 static struct mmc_config sh_sdhi_cfg = {
742 	.name           = DRIVER_NAME,
743 	.ops            = &sh_sdhi_ops,
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,
750 };
751 #endif
752 
753 int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks)
754 {
755 	int ret = 0;
756 	struct mmc *mmc;
757 	struct sh_sdhi_host *host = NULL;
758 
759 	if (ch >= CONFIG_SYS_SH_SDHI_NR_CHANNEL)
760 		return -ENODEV;
761 
762 	host = malloc(sizeof(struct sh_sdhi_host));
763 	if (!host)
764 		return -ENOMEM;
765 
766 	mmc = mmc_create(&sh_sdhi_cfg, host);
767 	if (!mmc) {
768 		ret = -1;
769 		goto error;
770 	}
771 
772 	host->ch = ch;
773 	host->addr = (void __iomem *)addr;
774 	host->quirks = quirks;
775 
776 	if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
777 		host->bus_shift = 2;
778 	else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
779 		host->bus_shift = 1;
780 
781 	return ret;
782 error:
783 	if (host)
784 		free(host);
785 	return ret;
786 }
787 
788 #else
789 
790 struct sh_sdhi_plat {
791 	struct mmc_config cfg;
792 	struct mmc mmc;
793 };
794 
795 int sh_sdhi_dm_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
796 			struct mmc_data *data)
797 {
798 	struct sh_sdhi_host *host = dev_get_priv(dev);
799 
800 	return sh_sdhi_send_cmd_common(host, cmd, data);
801 }
802 
803 int sh_sdhi_dm_set_ios(struct udevice *dev)
804 {
805 	struct sh_sdhi_host *host = dev_get_priv(dev);
806 	struct mmc *mmc = mmc_get_mmc_dev(dev);
807 
808 	return sh_sdhi_set_ios_common(host, mmc);
809 }
810 
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,
814 };
815 
816 static int sh_sdhi_dm_bind(struct udevice *dev)
817 {
818 	struct sh_sdhi_plat *plat = dev_get_platdata(dev);
819 
820 	return mmc_bind(dev, &plat->mmc, &plat->cfg);
821 }
822 
823 static int sh_sdhi_dm_probe(struct udevice *dev)
824 {
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);
830 	fdt_addr_t base;
831 	int ret;
832 
833 	base = devfdt_get_addr(dev);
834 	if (base == FDT_ADDR_T_NONE)
835 		return -EINVAL;
836 
837 	host->addr = devm_ioremap(dev, base, SZ_2K);
838 	if (!host->addr)
839 		return -ENOMEM;
840 
841 	ret = clk_get_by_index(dev, 0, &sh_sdhi_clk);
842 	if (ret) {
843 		debug("failed to get clock, ret=%d\n", ret);
844 		return ret;
845 	}
846 
847 	ret = clk_enable(&sh_sdhi_clk);
848 	if (ret) {
849 		debug("failed to enable clock, ret=%d\n", ret);
850 		return ret;
851 	}
852 
853 	host->quirks = quirks;
854 
855 	if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
856 		host->bus_shift = 2;
857 	else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
858 		host->bus_shift = 1;
859 
860 	plat->cfg.name = dev->name;
861 	plat->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
862 
863 	switch (fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width",
864 			       1)) {
865 	case 8:
866 		plat->cfg.host_caps |= MMC_MODE_8BIT;
867 		break;
868 	case 4:
869 		plat->cfg.host_caps |= MMC_MODE_4BIT;
870 		break;
871 	case 1:
872 		break;
873 	default:
874 		dev_err(dev, "Invalid \"bus-width\" value\n");
875 		return -EINVAL;
876 	}
877 
878 	sh_sdhi_initialize_common(host);
879 
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;
884 
885 	upriv->mmc = &plat->mmc;
886 
887 	return 0;
888 }
889 
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 },
893 	{ /* sentinel */ }
894 };
895 
896 U_BOOT_DRIVER(sh_sdhi_mmc) = {
897 	.name			= "sh-sdhi-mmc",
898 	.id			= UCLASS_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,
905 };
906 #endif
907