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