uboot/drivers/mmc/mvebu_mmc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Marvell MMC/SD/SDIO driver
   4 *
   5 * (C) Copyright 2012-2014
   6 * Marvell Semiconductor <www.marvell.com>
   7 * Written-by: Maen Suleiman, Gerald Kerma
   8 */
   9
  10#include <common.h>
  11#include <errno.h>
  12#include <malloc.h>
  13#include <part.h>
  14#include <mmc.h>
  15#include <asm/io.h>
  16#include <asm/arch/cpu.h>
  17#include <asm/arch/soc.h>
  18#include <mvebu_mmc.h>
  19
  20DECLARE_GLOBAL_DATA_PTR;
  21
  22#define DRIVER_NAME "MVEBU_MMC"
  23
  24#define MVEBU_TARGET_DRAM 0
  25
  26#define TIMEOUT_DELAY   5*CONFIG_SYS_HZ         /* wait 5 seconds */
  27
  28static void mvebu_mmc_write(u32 offs, u32 val)
  29{
  30        writel(val, CONFIG_SYS_MMC_BASE + (offs));
  31}
  32
  33static u32 mvebu_mmc_read(u32 offs)
  34{
  35        return readl(CONFIG_SYS_MMC_BASE + (offs));
  36}
  37
  38static int mvebu_mmc_setup_data(struct mmc_data *data)
  39{
  40        u32 ctrl_reg;
  41
  42        debug("%s, data %s : blocks=%d blksz=%d\n", DRIVER_NAME,
  43              (data->flags & MMC_DATA_READ) ? "read" : "write",
  44              data->blocks, data->blocksize);
  45
  46        /* default to maximum timeout */
  47        ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL);
  48        ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX);
  49        mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg);
  50
  51        if (data->flags & MMC_DATA_READ) {
  52                mvebu_mmc_write(SDIO_SYS_ADDR_LOW, (u32)data->dest & 0xffff);
  53                mvebu_mmc_write(SDIO_SYS_ADDR_HI, (u32)data->dest >> 16);
  54        } else {
  55                mvebu_mmc_write(SDIO_SYS_ADDR_LOW, (u32)data->src & 0xffff);
  56                mvebu_mmc_write(SDIO_SYS_ADDR_HI, (u32)data->src >> 16);
  57        }
  58
  59        mvebu_mmc_write(SDIO_BLK_COUNT, data->blocks);
  60        mvebu_mmc_write(SDIO_BLK_SIZE, data->blocksize);
  61
  62        return 0;
  63}
  64
  65static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
  66                              struct mmc_data *data)
  67{
  68        ulong start;
  69        ushort waittype = 0;
  70        ushort resptype = 0;
  71        ushort xfertype = 0;
  72        ushort resp_indx = 0;
  73
  74        debug("%s: cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n",
  75              DRIVER_NAME, cmd->cmdidx, cmd->resp_type, cmd->cmdarg);
  76
  77        debug("%s: cmd %d (hw state 0x%04x)\n", DRIVER_NAME,
  78              cmd->cmdidx, mvebu_mmc_read(SDIO_HW_STATE));
  79
  80        /*
  81         * Hardware weirdness.  The FIFO_EMPTY bit of the HW_STATE
  82         * register is sometimes not set before a while when some
  83         * "unusual" data block sizes are used (such as with the SWITCH
  84         * command), even despite the fact that the XFER_DONE interrupt
  85         * was raised.  And if another data transfer starts before
  86         * this bit comes to good sense (which eventually happens by
  87         * itself) then the new transfer simply fails with a timeout.
  88         */
  89        if (!(mvebu_mmc_read(SDIO_HW_STATE) & CMD_FIFO_EMPTY)) {
  90                ushort hw_state, count = 0;
  91
  92                start = get_timer(0);
  93                do {
  94                        hw_state = mvebu_mmc_read(SDIO_HW_STATE);
  95                        if ((get_timer(0) - start) > TIMEOUT_DELAY) {
  96                                printf("%s : FIFO_EMPTY bit missing\n",
  97                                       DRIVER_NAME);
  98                                break;
  99                        }
 100                        count++;
 101                } while (!(hw_state & CMD_FIFO_EMPTY));
 102                debug("%s *** wait for FIFO_EMPTY bit (hw=0x%04x, count=%d, jiffies=%ld)\n",
 103                      DRIVER_NAME, hw_state, count, (get_timer(0) - (start)));
 104        }
 105
 106        /* Clear status */
 107        mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
 108        mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
 109
 110        resptype = SDIO_CMD_INDEX(cmd->cmdidx);
 111
 112        /* Analyzing resptype/xfertype/waittype for the command */
 113        if (cmd->resp_type & MMC_RSP_BUSY)
 114                resptype |= SDIO_CMD_RSP_48BUSY;
 115        else if (cmd->resp_type & MMC_RSP_136)
 116                resptype |= SDIO_CMD_RSP_136;
 117        else if (cmd->resp_type & MMC_RSP_PRESENT)
 118                resptype |= SDIO_CMD_RSP_48;
 119        else
 120                resptype |= SDIO_CMD_RSP_NONE;
 121
 122        if (cmd->resp_type & MMC_RSP_CRC)
 123                resptype |= SDIO_CMD_CHECK_CMDCRC;
 124
 125        if (cmd->resp_type & MMC_RSP_OPCODE)
 126                resptype |= SDIO_CMD_INDX_CHECK;
 127
 128        if (cmd->resp_type & MMC_RSP_PRESENT) {
 129                resptype |= SDIO_UNEXPECTED_RESP;
 130                waittype |= SDIO_NOR_UNEXP_RSP;
 131        }
 132
 133        if (data) {
 134                int err = mvebu_mmc_setup_data(data);
 135
 136                if (err) {
 137                        debug("%s: command DATA error :%x\n",
 138                              DRIVER_NAME, err);
 139                        return err;
 140                }
 141
 142                resptype |= SDIO_CMD_DATA_PRESENT | SDIO_CMD_CHECK_DATACRC16;
 143                xfertype |= SDIO_XFER_MODE_HW_WR_DATA_EN;
 144                if (data->flags & MMC_DATA_READ) {
 145                        xfertype |= SDIO_XFER_MODE_TO_HOST;
 146                        waittype = SDIO_NOR_DMA_INI;
 147                } else {
 148                        waittype |= SDIO_NOR_XFER_DONE;
 149                }
 150        } else {
 151                waittype |= SDIO_NOR_CMD_DONE;
 152        }
 153
 154        /* Setting cmd arguments */
 155        mvebu_mmc_write(SDIO_ARG_LOW, cmd->cmdarg & 0xffff);
 156        mvebu_mmc_write(SDIO_ARG_HI, cmd->cmdarg >> 16);
 157
 158        /* Setting Xfer mode */
 159        mvebu_mmc_write(SDIO_XFER_MODE, xfertype);
 160
 161        /* Sending command */
 162        mvebu_mmc_write(SDIO_CMD, resptype);
 163
 164        start = get_timer(0);
 165
 166        while (!((mvebu_mmc_read(SDIO_NOR_INTR_STATUS)) & waittype)) {
 167                if (mvebu_mmc_read(SDIO_NOR_INTR_STATUS) & SDIO_NOR_ERROR) {
 168                        debug("%s: error! cmdidx : %d, err reg: %04x\n",
 169                              DRIVER_NAME, cmd->cmdidx,
 170                              mvebu_mmc_read(SDIO_ERR_INTR_STATUS));
 171                        if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
 172                            (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) {
 173                                debug("%s: command READ timed out\n",
 174                                      DRIVER_NAME);
 175                                return -ETIMEDOUT;
 176                        }
 177                        debug("%s: command READ error\n", DRIVER_NAME);
 178                        return -ECOMM;
 179                }
 180
 181                if ((get_timer(0) - start) > TIMEOUT_DELAY) {
 182                        debug("%s: command timed out\n", DRIVER_NAME);
 183                        return -ETIMEDOUT;
 184                }
 185        }
 186
 187        /* Handling response */
 188        if (cmd->resp_type & MMC_RSP_136) {
 189                uint response[8];
 190
 191                for (resp_indx = 0; resp_indx < 8; resp_indx++)
 192                        response[resp_indx]
 193                                = mvebu_mmc_read(SDIO_RSP(resp_indx));
 194
 195                cmd->response[0] =      ((response[0] & 0x03ff) << 22) |
 196                                        ((response[1] & 0xffff) << 6) |
 197                                        ((response[2] & 0xfc00) >> 10);
 198                cmd->response[1] =      ((response[2] & 0x03ff) << 22) |
 199                                        ((response[3] & 0xffff) << 6) |
 200                                        ((response[4] & 0xfc00) >> 10);
 201                cmd->response[2] =      ((response[4] & 0x03ff) << 22) |
 202                                        ((response[5] & 0xffff) << 6) |
 203                                        ((response[6] & 0xfc00) >> 10);
 204                cmd->response[3] =      ((response[6] & 0x03ff) << 22) |
 205                                        ((response[7] & 0x3fff) << 8);
 206        } else if (cmd->resp_type & MMC_RSP_PRESENT) {
 207                uint response[3];
 208
 209                for (resp_indx = 0; resp_indx < 3; resp_indx++)
 210                        response[resp_indx]
 211                                = mvebu_mmc_read(SDIO_RSP(resp_indx));
 212
 213                cmd->response[0] =      ((response[2] & 0x003f) << (8 - 8)) |
 214                                        ((response[1] & 0xffff) << (14 - 8)) |
 215                                        ((response[0] & 0x03ff) << (30 - 8));
 216                cmd->response[1] =      ((response[0] & 0xfc00) >> 10);
 217                cmd->response[2] =      0;
 218                cmd->response[3] =      0;
 219        } else {
 220                cmd->response[0] =      0;
 221                cmd->response[1] =      0;
 222                cmd->response[2] =      0;
 223                cmd->response[3] =      0;
 224        }
 225
 226        debug("%s: resp[0x%x] ", DRIVER_NAME, cmd->resp_type);
 227        debug("[0x%x] ", cmd->response[0]);
 228        debug("[0x%x] ", cmd->response[1]);
 229        debug("[0x%x] ", cmd->response[2]);
 230        debug("[0x%x] ", cmd->response[3]);
 231        debug("\n");
 232
 233        if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
 234                (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT))
 235                return -ETIMEDOUT;
 236
 237        return 0;
 238}
 239
 240static void mvebu_mmc_power_up(void)
 241{
 242        debug("%s: power up\n", DRIVER_NAME);
 243
 244        /* disable interrupts */
 245        mvebu_mmc_write(SDIO_NOR_INTR_EN, 0);
 246        mvebu_mmc_write(SDIO_ERR_INTR_EN, 0);
 247
 248        /* SW reset */
 249        mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW);
 250
 251        mvebu_mmc_write(SDIO_XFER_MODE, 0);
 252
 253        /* enable status */
 254        mvebu_mmc_write(SDIO_NOR_STATUS_EN, SDIO_POLL_MASK);
 255        mvebu_mmc_write(SDIO_ERR_STATUS_EN, SDIO_POLL_MASK);
 256
 257        /* enable interrupts status */
 258        mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
 259        mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
 260}
 261
 262static void mvebu_mmc_set_clk(unsigned int clock)
 263{
 264        unsigned int m;
 265
 266        if (clock == 0) {
 267                debug("%s: clock off\n", DRIVER_NAME);
 268                mvebu_mmc_write(SDIO_XFER_MODE, SDIO_XFER_MODE_STOP_CLK);
 269                mvebu_mmc_write(SDIO_CLK_DIV, MVEBU_MMC_BASE_DIV_MAX);
 270        } else {
 271                m = MVEBU_MMC_BASE_FAST_CLOCK/(2*clock) - 1;
 272                if (m > MVEBU_MMC_BASE_DIV_MAX)
 273                        m = MVEBU_MMC_BASE_DIV_MAX;
 274                mvebu_mmc_write(SDIO_CLK_DIV, m & MVEBU_MMC_BASE_DIV_MAX);
 275                debug("%s: clock (%d) div : %d\n", DRIVER_NAME, clock, m);
 276        }
 277}
 278
 279static void mvebu_mmc_set_bus(unsigned int bus)
 280{
 281        u32 ctrl_reg = 0;
 282
 283        ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL);
 284        ctrl_reg &= ~SDIO_HOST_CTRL_DATA_WIDTH_4_BITS;
 285
 286        switch (bus) {
 287        case 4:
 288                ctrl_reg |= SDIO_HOST_CTRL_DATA_WIDTH_4_BITS;
 289                break;
 290        case 1:
 291        default:
 292                ctrl_reg |= SDIO_HOST_CTRL_DATA_WIDTH_1_BIT;
 293        }
 294
 295        /* default transfer mode */
 296        ctrl_reg |= SDIO_HOST_CTRL_BIG_ENDIAN;
 297        ctrl_reg &= ~SDIO_HOST_CTRL_LSB_FIRST;
 298
 299        /* default to maximum timeout */
 300        ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX);
 301        ctrl_reg |= SDIO_HOST_CTRL_TMOUT_EN;
 302
 303        ctrl_reg |= SDIO_HOST_CTRL_PUSH_PULL_EN;
 304
 305        ctrl_reg |= SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY;
 306
 307        debug("%s: ctrl 0x%04x: %s %s %s\n", DRIVER_NAME, ctrl_reg,
 308              (ctrl_reg & SDIO_HOST_CTRL_PUSH_PULL_EN) ?
 309              "push-pull" : "open-drain",
 310              (ctrl_reg & SDIO_HOST_CTRL_DATA_WIDTH_4_BITS) ?
 311              "4bit-width" : "1bit-width",
 312              (ctrl_reg & SDIO_HOST_CTRL_HI_SPEED_EN) ?
 313              "high-speed" : "");
 314
 315        mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg);
 316}
 317
 318static int mvebu_mmc_set_ios(struct mmc *mmc)
 319{
 320        debug("%s: bus[%d] clock[%d]\n", DRIVER_NAME,
 321              mmc->bus_width, mmc->clock);
 322        mvebu_mmc_set_bus(mmc->bus_width);
 323        mvebu_mmc_set_clk(mmc->clock);
 324
 325        return 0;
 326}
 327
 328/*
 329 * Set window register.
 330 */
 331static void mvebu_window_setup(void)
 332{
 333        int i;
 334
 335        for (i = 0; i < 4; i++) {
 336                mvebu_mmc_write(WINDOW_CTRL(i), 0);
 337                mvebu_mmc_write(WINDOW_BASE(i), 0);
 338        }
 339        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 340                u32 size, base, attrib;
 341
 342                /* Enable DRAM bank */
 343                switch (i) {
 344                case 0:
 345                        attrib = KWCPU_ATTR_DRAM_CS0;
 346                        break;
 347                case 1:
 348                        attrib = KWCPU_ATTR_DRAM_CS1;
 349                        break;
 350                case 2:
 351                        attrib = KWCPU_ATTR_DRAM_CS2;
 352                        break;
 353                case 3:
 354                        attrib = KWCPU_ATTR_DRAM_CS3;
 355                        break;
 356                default:
 357                        /* invalide bank, disable access */
 358                        attrib = 0;
 359                        break;
 360                }
 361
 362                size = gd->bd->bi_dram[i].size;
 363                base = gd->bd->bi_dram[i].start;
 364                if (size && attrib) {
 365                        mvebu_mmc_write(WINDOW_CTRL(i),
 366                                        MVCPU_WIN_CTRL_DATA(size,
 367                                                            MVEBU_TARGET_DRAM,
 368                                                            attrib,
 369                                                            MVCPU_WIN_ENABLE));
 370                } else {
 371                        mvebu_mmc_write(WINDOW_CTRL(i), MVCPU_WIN_DISABLE);
 372                }
 373                mvebu_mmc_write(WINDOW_BASE(i), base);
 374        }
 375}
 376
 377static int mvebu_mmc_initialize(struct mmc *mmc)
 378{
 379        debug("%s: mvebu_mmc_initialize\n", DRIVER_NAME);
 380
 381        /*
 382         * Setting host parameters
 383         * Initial Host Ctrl : Timeout : max , Normal Speed mode,
 384         * 4-bit data mode, Big Endian, SD memory Card, Push_pull CMD Line
 385         */
 386        mvebu_mmc_write(SDIO_HOST_CTRL,
 387                        SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX) |
 388                        SDIO_HOST_CTRL_DATA_WIDTH_4_BITS |
 389                        SDIO_HOST_CTRL_BIG_ENDIAN |
 390                        SDIO_HOST_CTRL_PUSH_PULL_EN |
 391                        SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY);
 392
 393        mvebu_mmc_write(SDIO_CLK_CTRL, 0);
 394
 395        /* enable status */
 396        mvebu_mmc_write(SDIO_NOR_STATUS_EN, SDIO_POLL_MASK);
 397        mvebu_mmc_write(SDIO_ERR_STATUS_EN, SDIO_POLL_MASK);
 398
 399        /* disable interrupts */
 400        mvebu_mmc_write(SDIO_NOR_INTR_EN, 0);
 401        mvebu_mmc_write(SDIO_ERR_INTR_EN, 0);
 402
 403        mvebu_window_setup();
 404
 405        /* SW reset */
 406        mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW);
 407
 408        return 0;
 409}
 410
 411static const struct mmc_ops mvebu_mmc_ops = {
 412        .send_cmd       = mvebu_mmc_send_cmd,
 413        .set_ios        = mvebu_mmc_set_ios,
 414        .init           = mvebu_mmc_initialize,
 415};
 416
 417static struct mmc_config mvebu_mmc_cfg = {
 418        .name           = DRIVER_NAME,
 419        .ops            = &mvebu_mmc_ops,
 420        .f_min          = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX,
 421        .f_max          = MVEBU_MMC_CLOCKRATE_MAX,
 422        .voltages       = MMC_VDD_32_33 | MMC_VDD_33_34,
 423        .host_caps      = MMC_MODE_4BIT | MMC_MODE_HS |
 424                          MMC_MODE_HS_52MHz,
 425        .part_type      = PART_TYPE_DOS,
 426        .b_max          = CONFIG_SYS_MMC_MAX_BLK_COUNT,
 427};
 428
 429int mvebu_mmc_init(bd_t *bis)
 430{
 431        struct mmc *mmc;
 432
 433        mvebu_mmc_power_up();
 434
 435        mmc = mmc_create(&mvebu_mmc_cfg, bis);
 436        if (mmc == NULL)
 437                return -1;
 438
 439        return 0;
 440}
 441