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