uboot/drivers/mmc/sh_sdhi.c
<<
>>
Prefs
   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
  31struct 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
  42static 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
  47static inline u64 sh_sdhi_readq(struct sh_sdhi_host *host, int reg)
  48{
  49        return readq(host->addr + (reg << host->bus_shift));
  50}
  51
  52static 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
  57static inline u16 sh_sdhi_readw(struct sh_sdhi_host *host, int reg)
  58{
  59        return readw(host->addr + (reg << host->bus_shift));
  60}
  61
  62static 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
  70static 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
 156static 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
 176static 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
 214static 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
 238static 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
 274static 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
 315static 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
 354static 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
 400static 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
 433static 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
 481static 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
 504static 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
 537static 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
 647static 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
 655static 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
 681static 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
 699static void *mmc_priv(struct mmc *mmc)
 700{
 701        return (void *)mmc->priv;
 702}
 703
 704static 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
 712static 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
 719static 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
 726static 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
 733static 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
 745static 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
 757int 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;
 786error:
 787        if (host)
 788                free(host);
 789        return ret;
 790}
 791
 792#else
 793
 794struct sh_sdhi_plat {
 795        struct mmc_config cfg;
 796        struct mmc mmc;
 797};
 798
 799int 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
 807int 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
 815static 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
 820static 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
 827static 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
 894static 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
 900U_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
 911