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