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