bc94d01fab5e7a3192e5f18882658b45bada16ae
[oweals/u-boot.git] / drivers / mmc / sh_mmcif.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * MMCIF driver.
4  *
5  * Copyright (C)  2011 Renesas Solutions Corp.
6  */
7
8 #include <config.h>
9 #include <common.h>
10 #include <log.h>
11 #include <watchdog.h>
12 #include <command.h>
13 #include <mmc.h>
14 #include <clk.h>
15 #include <dm.h>
16 #include <malloc.h>
17 #include <dm/device_compat.h>
18 #include <linux/errno.h>
19 #include <linux/compat.h>
20 #include <linux/io.h>
21 #include <linux/sizes.h>
22 #include "sh_mmcif.h"
23
24 #define DRIVER_NAME     "sh_mmcif"
25
26 static int sh_mmcif_intr(void *dev_id)
27 {
28         struct sh_mmcif_host *host = dev_id;
29         u32 state = 0;
30
31         state = sh_mmcif_read(&host->regs->ce_int);
32         state &= sh_mmcif_read(&host->regs->ce_int_mask);
33
34         if (state & INT_RBSYE) {
35                 sh_mmcif_write(~(INT_RBSYE | INT_CRSPE), &host->regs->ce_int);
36                 sh_mmcif_bitclr(MASK_MRBSYE, &host->regs->ce_int_mask);
37                 goto end;
38         } else if (state & INT_CRSPE) {
39                 sh_mmcif_write(~INT_CRSPE, &host->regs->ce_int);
40                 sh_mmcif_bitclr(MASK_MCRSPE, &host->regs->ce_int_mask);
41                 /* one more interrupt (INT_RBSYE) */
42                 if (sh_mmcif_read(&host->regs->ce_cmd_set) & CMD_SET_RBSY)
43                         return -EAGAIN;
44                 goto end;
45         } else if (state & INT_BUFREN) {
46                 sh_mmcif_write(~INT_BUFREN, &host->regs->ce_int);
47                 sh_mmcif_bitclr(MASK_MBUFREN, &host->regs->ce_int_mask);
48                 goto end;
49         } else if (state & INT_BUFWEN) {
50                 sh_mmcif_write(~INT_BUFWEN, &host->regs->ce_int);
51                 sh_mmcif_bitclr(MASK_MBUFWEN, &host->regs->ce_int_mask);
52                 goto end;
53         } else if (state & INT_CMD12DRE) {
54                 sh_mmcif_write(~(INT_CMD12DRE | INT_CMD12RBE | INT_CMD12CRE |
55                                   INT_BUFRE), &host->regs->ce_int);
56                 sh_mmcif_bitclr(MASK_MCMD12DRE, &host->regs->ce_int_mask);
57                 goto end;
58         } else if (state & INT_BUFRE) {
59                 sh_mmcif_write(~INT_BUFRE, &host->regs->ce_int);
60                 sh_mmcif_bitclr(MASK_MBUFRE, &host->regs->ce_int_mask);
61                 goto end;
62         } else if (state & INT_DTRANE) {
63                 sh_mmcif_write(~INT_DTRANE, &host->regs->ce_int);
64                 sh_mmcif_bitclr(MASK_MDTRANE, &host->regs->ce_int_mask);
65                 goto end;
66         } else if (state & INT_CMD12RBE) {
67                 sh_mmcif_write(~(INT_CMD12RBE | INT_CMD12CRE),
68                                 &host->regs->ce_int);
69                 sh_mmcif_bitclr(MASK_MCMD12RBE, &host->regs->ce_int_mask);
70                 goto end;
71         } else if (state & INT_ERR_STS) {
72                 /* err interrupts */
73                 sh_mmcif_write(~state, &host->regs->ce_int);
74                 sh_mmcif_bitclr(state, &host->regs->ce_int_mask);
75                 goto err;
76         } else
77                 return -EAGAIN;
78
79 err:
80         host->sd_error = 1;
81         debug("%s: int err state = %08x\n", DRIVER_NAME, state);
82 end:
83         host->wait_int = 1;
84         return 0;
85 }
86
87 static int mmcif_wait_interrupt_flag(struct sh_mmcif_host *host)
88 {
89         int timeout = 10000000;
90
91         while (1) {
92                 timeout--;
93                 if (timeout < 0) {
94                         printf("timeout\n");
95                         return 0;
96                 }
97
98                 if (!sh_mmcif_intr(host))
99                         break;
100
101                 udelay(1);      /* 1 usec */
102         }
103
104         return 1;       /* Return value: NOT 0 = complete waiting */
105 }
106
107 static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
108 {
109         sh_mmcif_bitclr(CLK_ENABLE, &host->regs->ce_clk_ctrl);
110         sh_mmcif_bitclr(CLK_CLEAR, &host->regs->ce_clk_ctrl);
111
112         if (!clk)
113                 return;
114
115         if (clk == CLKDEV_EMMC_DATA)
116                 sh_mmcif_bitset(CLK_PCLK, &host->regs->ce_clk_ctrl);
117         else
118                 sh_mmcif_bitset((fls(DIV_ROUND_UP(host->clk,
119                                                   clk) - 1) - 1) << 16,
120                                 &host->regs->ce_clk_ctrl);
121         sh_mmcif_bitset(CLK_ENABLE, &host->regs->ce_clk_ctrl);
122 }
123
124 static void sh_mmcif_sync_reset(struct sh_mmcif_host *host)
125 {
126         u32 tmp;
127
128         tmp = sh_mmcif_read(&host->regs->ce_clk_ctrl) & (CLK_ENABLE |
129                                                          CLK_CLEAR);
130
131         sh_mmcif_write(SOFT_RST_ON, &host->regs->ce_version);
132         sh_mmcif_write(SOFT_RST_OFF, &host->regs->ce_version);
133         sh_mmcif_bitset(tmp | SRSPTO_256 | SRBSYTO_29 | SRWDTO_29 | SCCSTO_29,
134                         &host->regs->ce_clk_ctrl);
135         /* byte swap on */
136         sh_mmcif_bitset(BUF_ACC_ATYP, &host->regs->ce_buf_acc);
137 }
138
139 static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
140 {
141         u32 state1, state2;
142         int ret, timeout = 10000000;
143
144         host->sd_error = 0;
145         host->wait_int = 0;
146
147         state1 = sh_mmcif_read(&host->regs->ce_host_sts1);
148         state2 = sh_mmcif_read(&host->regs->ce_host_sts2);
149         debug("%s: ERR HOST_STS1 = %08x\n", \
150                         DRIVER_NAME, sh_mmcif_read(&host->regs->ce_host_sts1));
151         debug("%s: ERR HOST_STS2 = %08x\n", \
152                         DRIVER_NAME, sh_mmcif_read(&host->regs->ce_host_sts2));
153
154         if (state1 & STS1_CMDSEQ) {
155                 debug("%s: Forced end of command sequence\n", DRIVER_NAME);
156                 sh_mmcif_bitset(CMD_CTRL_BREAK, &host->regs->ce_cmd_ctrl);
157                 sh_mmcif_bitset(~CMD_CTRL_BREAK, &host->regs->ce_cmd_ctrl);
158                 while (1) {
159                         timeout--;
160                         if (timeout < 0) {
161                                 printf(DRIVER_NAME": Forceed end of " \
162                                         "command sequence timeout err\n");
163                                 return -EILSEQ;
164                         }
165                         if (!(sh_mmcif_read(&host->regs->ce_host_sts1)
166                                                                 & STS1_CMDSEQ))
167                                 break;
168                 }
169                 sh_mmcif_sync_reset(host);
170                 return -EILSEQ;
171         }
172
173         if (state2 & STS2_CRC_ERR)
174                 ret = -EILSEQ;
175         else if (state2 & STS2_TIMEOUT_ERR)
176                 ret = -ETIMEDOUT;
177         else
178                 ret = -EILSEQ;
179         return ret;
180 }
181
182 static int sh_mmcif_single_read(struct sh_mmcif_host *host,
183                                 struct mmc_data *data)
184 {
185         long time;
186         u32 blocksize, i;
187         unsigned long *p = (unsigned long *)data->dest;
188
189         if ((unsigned long)p & 0x00000001) {
190                 printf("%s: The data pointer is unaligned.", __func__);
191                 return -EIO;
192         }
193
194         host->wait_int = 0;
195
196         /* buf read enable */
197         sh_mmcif_bitset(MASK_MBUFREN, &host->regs->ce_int_mask);
198         time = mmcif_wait_interrupt_flag(host);
199         if (time == 0 || host->sd_error != 0)
200                 return sh_mmcif_error_manage(host);
201
202         host->wait_int = 0;
203         blocksize = (BLOCK_SIZE_MASK &
204                         sh_mmcif_read(&host->regs->ce_block_set)) + 3;
205         for (i = 0; i < blocksize / 4; i++)
206                 *p++ = sh_mmcif_read(&host->regs->ce_data);
207
208         /* buffer read end */
209         sh_mmcif_bitset(MASK_MBUFRE, &host->regs->ce_int_mask);
210         time = mmcif_wait_interrupt_flag(host);
211         if (time == 0 || host->sd_error != 0)
212                 return sh_mmcif_error_manage(host);
213
214         host->wait_int = 0;
215         return 0;
216 }
217
218 static int sh_mmcif_multi_read(struct sh_mmcif_host *host,
219                                 struct mmc_data *data)
220 {
221         long time;
222         u32 blocksize, i, j;
223         unsigned long *p = (unsigned long *)data->dest;
224
225         if ((unsigned long)p & 0x00000001) {
226                 printf("%s: The data pointer is unaligned.", __func__);
227                 return -EIO;
228         }
229
230         host->wait_int = 0;
231         blocksize = BLOCK_SIZE_MASK & sh_mmcif_read(&host->regs->ce_block_set);
232         for (j = 0; j < data->blocks; j++) {
233                 sh_mmcif_bitset(MASK_MBUFREN, &host->regs->ce_int_mask);
234                 time = mmcif_wait_interrupt_flag(host);
235                 if (time == 0 || host->sd_error != 0)
236                         return sh_mmcif_error_manage(host);
237
238                 host->wait_int = 0;
239                 for (i = 0; i < blocksize / 4; i++)
240                         *p++ = sh_mmcif_read(&host->regs->ce_data);
241
242                 WATCHDOG_RESET();
243         }
244         return 0;
245 }
246
247 static int sh_mmcif_single_write(struct sh_mmcif_host *host,
248                                  struct mmc_data *data)
249 {
250         long time;
251         u32 blocksize, i;
252         const unsigned long *p = (unsigned long *)data->dest;
253
254         if ((unsigned long)p & 0x00000001) {
255                 printf("%s: The data pointer is unaligned.", __func__);
256                 return -EIO;
257         }
258
259         host->wait_int = 0;
260         sh_mmcif_bitset(MASK_MBUFWEN, &host->regs->ce_int_mask);
261
262         time = mmcif_wait_interrupt_flag(host);
263         if (time == 0 || host->sd_error != 0)
264                 return sh_mmcif_error_manage(host);
265
266         host->wait_int = 0;
267         blocksize = (BLOCK_SIZE_MASK &
268                         sh_mmcif_read(&host->regs->ce_block_set)) + 3;
269         for (i = 0; i < blocksize / 4; i++)
270                 sh_mmcif_write(*p++, &host->regs->ce_data);
271
272         /* buffer write end */
273         sh_mmcif_bitset(MASK_MDTRANE, &host->regs->ce_int_mask);
274
275         time = mmcif_wait_interrupt_flag(host);
276         if (time == 0 || host->sd_error != 0)
277                 return sh_mmcif_error_manage(host);
278
279         host->wait_int = 0;
280         return 0;
281 }
282
283 static int sh_mmcif_multi_write(struct sh_mmcif_host *host,
284                                 struct mmc_data *data)
285 {
286         long time;
287         u32 i, j, blocksize;
288         const unsigned long *p = (unsigned long *)data->dest;
289
290         if ((unsigned long)p & 0x00000001) {
291                 printf("%s: The data pointer is unaligned.", __func__);
292                 return -EIO;
293         }
294
295         host->wait_int = 0;
296         blocksize = BLOCK_SIZE_MASK & sh_mmcif_read(&host->regs->ce_block_set);
297         for (j = 0; j < data->blocks; j++) {
298                 sh_mmcif_bitset(MASK_MBUFWEN, &host->regs->ce_int_mask);
299
300                 time = mmcif_wait_interrupt_flag(host);
301
302                 if (time == 0 || host->sd_error != 0)
303                         return sh_mmcif_error_manage(host);
304
305                 host->wait_int = 0;
306                 for (i = 0; i < blocksize / 4; i++)
307                         sh_mmcif_write(*p++, &host->regs->ce_data);
308
309                 WATCHDOG_RESET();
310         }
311         return 0;
312 }
313
314 static void sh_mmcif_get_response(struct sh_mmcif_host *host,
315                                         struct mmc_cmd *cmd)
316 {
317         if (cmd->resp_type & MMC_RSP_136) {
318                 cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp3);
319                 cmd->response[1] = sh_mmcif_read(&host->regs->ce_resp2);
320                 cmd->response[2] = sh_mmcif_read(&host->regs->ce_resp1);
321                 cmd->response[3] = sh_mmcif_read(&host->regs->ce_resp0);
322                 debug(" RESP %08x, %08x, %08x, %08x\n", cmd->response[0],
323                          cmd->response[1], cmd->response[2], cmd->response[3]);
324         } else {
325                 cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp0);
326         }
327 }
328
329 static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host,
330                                         struct mmc_cmd *cmd)
331 {
332         cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp_cmd12);
333 }
334
335 static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
336                                 struct mmc_data *data, struct mmc_cmd *cmd)
337 {
338         u32 tmp = 0;
339         u32 opc = cmd->cmdidx;
340
341         /* Response Type check */
342         switch (cmd->resp_type) {
343         case MMC_RSP_NONE:
344                 tmp |= CMD_SET_RTYP_NO;
345                 break;
346         case MMC_RSP_R1:
347         case MMC_RSP_R1b:
348         case MMC_RSP_R3:
349                 tmp |= CMD_SET_RTYP_6B;
350                 break;
351         case MMC_RSP_R2:
352                 tmp |= CMD_SET_RTYP_17B;
353                 break;
354         default:
355                 printf(DRIVER_NAME": Not support type response.\n");
356                 break;
357         }
358
359         /* RBSY */
360         if (opc == MMC_CMD_SWITCH)
361                 tmp |= CMD_SET_RBSY;
362
363         /* WDAT / DATW */
364         if (host->data) {
365                 tmp |= CMD_SET_WDAT;
366                 switch (host->bus_width) {
367                 case MMC_BUS_WIDTH_1:
368                         tmp |= CMD_SET_DATW_1;
369                         break;
370                 case MMC_BUS_WIDTH_4:
371                         tmp |= CMD_SET_DATW_4;
372                         break;
373                 case MMC_BUS_WIDTH_8:
374                         tmp |= CMD_SET_DATW_8;
375                         break;
376                 default:
377                         printf(DRIVER_NAME": Not support bus width.\n");
378                         break;
379                 }
380         }
381         /* DWEN */
382         if (opc == MMC_CMD_WRITE_SINGLE_BLOCK ||
383             opc == MMC_CMD_WRITE_MULTIPLE_BLOCK)
384                 tmp |= CMD_SET_DWEN;
385         /* CMLTE/CMD12EN */
386         if (opc == MMC_CMD_READ_MULTIPLE_BLOCK ||
387             opc == MMC_CMD_WRITE_MULTIPLE_BLOCK) {
388                 tmp |= CMD_SET_CMLTE | CMD_SET_CMD12EN;
389                 sh_mmcif_bitset(data->blocks << 16, &host->regs->ce_block_set);
390         }
391         /* RIDXC[1:0] check bits */
392         if (opc == MMC_CMD_SEND_OP_COND || opc == MMC_CMD_ALL_SEND_CID ||
393             opc == MMC_CMD_SEND_CSD || opc == MMC_CMD_SEND_CID)
394                 tmp |= CMD_SET_RIDXC_BITS;
395         /* RCRC7C[1:0] check bits */
396         if (opc == MMC_CMD_SEND_OP_COND)
397                 tmp |= CMD_SET_CRC7C_BITS;
398         /* RCRC7C[1:0] internal CRC7 */
399         if (opc == MMC_CMD_ALL_SEND_CID ||
400                 opc == MMC_CMD_SEND_CSD || opc == MMC_CMD_SEND_CID)
401                 tmp |= CMD_SET_CRC7C_INTERNAL;
402
403         return opc = ((opc << 24) | tmp);
404 }
405
406 static u32 sh_mmcif_data_trans(struct sh_mmcif_host *host,
407                                 struct mmc_data *data, u16 opc)
408 {
409         u32 ret;
410
411         switch (opc) {
412         case MMC_CMD_READ_MULTIPLE_BLOCK:
413                 ret = sh_mmcif_multi_read(host, data);
414                 break;
415         case MMC_CMD_WRITE_MULTIPLE_BLOCK:
416                 ret = sh_mmcif_multi_write(host, data);
417                 break;
418         case MMC_CMD_WRITE_SINGLE_BLOCK:
419                 ret = sh_mmcif_single_write(host, data);
420                 break;
421         case MMC_CMD_READ_SINGLE_BLOCK:
422         case MMC_CMD_SEND_EXT_CSD:
423                 ret = sh_mmcif_single_read(host, data);
424                 break;
425         default:
426                 printf(DRIVER_NAME": NOT SUPPORT CMD = d'%08d\n", opc);
427                 ret = -EINVAL;
428                 break;
429         }
430         return ret;
431 }
432
433 static int sh_mmcif_start_cmd(struct sh_mmcif_host *host,
434                                 struct mmc_data *data, struct mmc_cmd *cmd)
435 {
436         long time;
437         int ret = 0, mask = 0;
438         u32 opc = cmd->cmdidx;
439
440         if (opc == MMC_CMD_STOP_TRANSMISSION) {
441                 /* MMCIF sends the STOP command automatically */
442                 if (host->last_cmd == MMC_CMD_READ_MULTIPLE_BLOCK)
443                         sh_mmcif_bitset(MASK_MCMD12DRE,
444                                         &host->regs->ce_int_mask);
445                 else
446                         sh_mmcif_bitset(MASK_MCMD12RBE,
447                                         &host->regs->ce_int_mask);
448
449                 time = mmcif_wait_interrupt_flag(host);
450                 if (time == 0 || host->sd_error != 0)
451                         return sh_mmcif_error_manage(host);
452
453                 sh_mmcif_get_cmd12response(host, cmd);
454                 return 0;
455         }
456         if (opc == MMC_CMD_SWITCH)
457                 mask = MASK_MRBSYE;
458         else
459                 mask = MASK_MCRSPE;
460
461         mask |= MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR |
462                 MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR |
463                 MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO |
464                 MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO;
465
466         if (host->data) {
467                 sh_mmcif_write(0, &host->regs->ce_block_set);
468                 sh_mmcif_write(data->blocksize, &host->regs->ce_block_set);
469         }
470         opc = sh_mmcif_set_cmd(host, data, cmd);
471
472         sh_mmcif_write(INT_START_MAGIC, &host->regs->ce_int);
473         sh_mmcif_write(mask, &host->regs->ce_int_mask);
474
475         debug("CMD%d ARG:%08x\n", cmd->cmdidx, cmd->cmdarg);
476         /* set arg */
477         sh_mmcif_write(cmd->cmdarg, &host->regs->ce_arg);
478         host->wait_int = 0;
479         /* set cmd */
480         sh_mmcif_write(opc, &host->regs->ce_cmd_set);
481
482         time = mmcif_wait_interrupt_flag(host);
483         if (time == 0)
484                 return sh_mmcif_error_manage(host);
485
486         if (host->sd_error) {
487                 switch (cmd->cmdidx) {
488                 case MMC_CMD_ALL_SEND_CID:
489                 case MMC_CMD_SELECT_CARD:
490                 case MMC_CMD_APP_CMD:
491                         ret = -ETIMEDOUT;
492                         break;
493                 default:
494                         printf(DRIVER_NAME": Cmd(d'%d) err\n", cmd->cmdidx);
495                         ret = sh_mmcif_error_manage(host);
496                         break;
497                 }
498                 host->sd_error = 0;
499                 host->wait_int = 0;
500                 return ret;
501         }
502
503         /* if no response */
504         if (!(opc & 0x00C00000))
505                 return 0;
506
507         if (host->wait_int == 1) {
508                 sh_mmcif_get_response(host, cmd);
509                 host->wait_int = 0;
510         }
511         if (host->data)
512                 ret = sh_mmcif_data_trans(host, data, cmd->cmdidx);
513         host->last_cmd = cmd->cmdidx;
514
515         return ret;
516 }
517
518 static int sh_mmcif_send_cmd_common(struct sh_mmcif_host *host,
519                                     struct mmc_cmd *cmd, struct mmc_data *data)
520 {
521         int ret;
522
523         WATCHDOG_RESET();
524
525         switch (cmd->cmdidx) {
526         case MMC_CMD_APP_CMD:
527                 return -ETIMEDOUT;
528         case MMC_CMD_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */
529                 if (data)
530                         /* ext_csd */
531                         break;
532                 else
533                         /* send_if_cond cmd (not support) */
534                         return -ETIMEDOUT;
535         default:
536                 break;
537         }
538         host->sd_error = 0;
539         host->data = data;
540         ret = sh_mmcif_start_cmd(host, data, cmd);
541         host->data = NULL;
542
543         return ret;
544 }
545
546 static int sh_mmcif_set_ios_common(struct sh_mmcif_host *host, struct mmc *mmc)
547 {
548         if (mmc->clock)
549                 sh_mmcif_clock_control(host, mmc->clock);
550
551         if (mmc->bus_width == 8)
552                 host->bus_width = MMC_BUS_WIDTH_8;
553         else if (mmc->bus_width == 4)
554                 host->bus_width = MMC_BUS_WIDTH_4;
555         else
556                 host->bus_width = MMC_BUS_WIDTH_1;
557
558         debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width);
559
560         return 0;
561 }
562
563 static int sh_mmcif_initialize_common(struct sh_mmcif_host *host)
564 {
565         sh_mmcif_sync_reset(host);
566         sh_mmcif_write(MASK_ALL, &host->regs->ce_int_mask);
567         return 0;
568 }
569
570 #ifndef CONFIG_DM_MMC
571 static void *mmc_priv(struct mmc *mmc)
572 {
573         return (void *)mmc->priv;
574 }
575
576 static int sh_mmcif_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
577                             struct mmc_data *data)
578 {
579         struct sh_mmcif_host *host = mmc_priv(mmc);
580
581         return sh_mmcif_send_cmd_common(host, cmd, data);
582 }
583
584 static int sh_mmcif_set_ios(struct mmc *mmc)
585 {
586         struct sh_mmcif_host *host = mmc_priv(mmc);
587
588         return sh_mmcif_set_ios_common(host, mmc);
589 }
590
591 static int sh_mmcif_initialize(struct mmc *mmc)
592 {
593         struct sh_mmcif_host *host = mmc_priv(mmc);
594
595         return sh_mmcif_initialize_common(host);
596 }
597
598 static const struct mmc_ops sh_mmcif_ops = {
599         .send_cmd       = sh_mmcif_send_cmd,
600         .set_ios        = sh_mmcif_set_ios,
601         .init           = sh_mmcif_initialize,
602 };
603
604 static struct mmc_config sh_mmcif_cfg = {
605         .name           = DRIVER_NAME,
606         .ops            = &sh_mmcif_ops,
607         .host_caps      = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT |
608                           MMC_MODE_8BIT,
609         .voltages       = MMC_VDD_32_33 | MMC_VDD_33_34,
610         .b_max          = CONFIG_SYS_MMC_MAX_BLK_COUNT,
611 };
612
613 int mmcif_mmc_init(void)
614 {
615         struct mmc *mmc;
616         struct sh_mmcif_host *host = NULL;
617
618         host = malloc(sizeof(struct sh_mmcif_host));
619         if (!host)
620                 return -ENOMEM;
621         memset(host, 0, sizeof(*host));
622
623         host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR;
624         host->clk = CONFIG_SH_MMCIF_CLK;
625
626         sh_mmcif_cfg.f_min = MMC_CLK_DIV_MIN(host->clk);
627         sh_mmcif_cfg.f_max = MMC_CLK_DIV_MAX(host->clk);
628
629         mmc = mmc_create(&sh_mmcif_cfg, host);
630         if (mmc == NULL) {
631                 free(host);
632                 return -ENOMEM;
633         }
634
635         return 0;
636 }
637
638 #else
639 struct sh_mmcif_plat {
640         struct mmc_config cfg;
641         struct mmc mmc;
642 };
643
644 int sh_mmcif_dm_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
645                         struct mmc_data *data)
646 {
647         struct sh_mmcif_host *host = dev_get_priv(dev);
648
649         return sh_mmcif_send_cmd_common(host, cmd, data);
650 }
651
652 int sh_mmcif_dm_set_ios(struct udevice *dev)
653 {
654         struct sh_mmcif_host *host = dev_get_priv(dev);
655         struct mmc *mmc = mmc_get_mmc_dev(dev);
656
657         return sh_mmcif_set_ios_common(host, mmc);
658 }
659
660 static const struct dm_mmc_ops sh_mmcif_dm_ops = {
661         .send_cmd       = sh_mmcif_dm_send_cmd,
662         .set_ios        = sh_mmcif_dm_set_ios,
663 };
664
665 static int sh_mmcif_dm_bind(struct udevice *dev)
666 {
667         struct sh_mmcif_plat *plat = dev_get_platdata(dev);
668
669         return mmc_bind(dev, &plat->mmc, &plat->cfg);
670 }
671
672 static int sh_mmcif_dm_probe(struct udevice *dev)
673 {
674         struct sh_mmcif_plat *plat = dev_get_platdata(dev);
675         struct sh_mmcif_host *host = dev_get_priv(dev);
676         struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
677         struct clk sh_mmcif_clk;
678         fdt_addr_t base;
679         int ret;
680
681         base = devfdt_get_addr(dev);
682         if (base == FDT_ADDR_T_NONE)
683                 return -EINVAL;
684
685         host->regs = (struct sh_mmcif_regs *)devm_ioremap(dev, base, SZ_2K);
686         if (!host->regs)
687                 return -ENOMEM;
688
689         ret = clk_get_by_index(dev, 0, &sh_mmcif_clk);
690         if (ret) {
691                 debug("failed to get clock, ret=%d\n", ret);
692                 return ret;
693         }
694
695         ret = clk_enable(&sh_mmcif_clk);
696         if (ret) {
697                 debug("failed to enable clock, ret=%d\n", ret);
698                 return ret;
699         }
700
701         host->clk = clk_set_rate(&sh_mmcif_clk, 97500000);
702
703         plat->cfg.name = dev->name;
704         plat->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
705
706         switch (fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width",
707                                1)) {
708         case 8:
709                 plat->cfg.host_caps |= MMC_MODE_8BIT;
710                 break;
711         case 4:
712                 plat->cfg.host_caps |= MMC_MODE_4BIT;
713                 break;
714         case 1:
715                 break;
716         default:
717                 dev_err(dev, "Invalid \"bus-width\" value\n");
718                 return -EINVAL;
719         }
720
721         sh_mmcif_initialize_common(host);
722
723         plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
724         plat->cfg.f_min = MMC_CLK_DIV_MIN(host->clk);
725         plat->cfg.f_max = MMC_CLK_DIV_MAX(host->clk);
726         plat->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
727
728         upriv->mmc = &plat->mmc;
729
730         return 0;
731 }
732
733 static const struct udevice_id sh_mmcif_sd_match[] = {
734         { .compatible = "renesas,sh-mmcif" },
735         { /* sentinel */ }
736 };
737
738 U_BOOT_DRIVER(sh_mmcif_mmc) = {
739         .name                   = "sh-mmcif",
740         .id                     = UCLASS_MMC,
741         .of_match               = sh_mmcif_sd_match,
742         .bind                   = sh_mmcif_dm_bind,
743         .probe                  = sh_mmcif_dm_probe,
744         .priv_auto_alloc_size   = sizeof(struct sh_mmcif_host),
745         .platdata_auto_alloc_size = sizeof(struct sh_mmcif_plat),
746         .ops                    = &sh_mmcif_dm_ops,
747 };
748 #endif