uboot/drivers/mmc/mxsmmc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Freescale i.MX28 SSP MMC driver
   4 *
   5 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
   6 * on behalf of DENX Software Engineering GmbH
   7 *
   8 * Based on code from LTIB:
   9 * (C) Copyright 2008-2010 Freescale Semiconductor, Inc.
  10 * Terry Lv
  11 *
  12 * Copyright 2007, Freescale Semiconductor, Inc
  13 * Andy Fleming
  14 *
  15 * Based vaguely on the pxa mmc code:
  16 * (C) Copyright 2003
  17 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
  18 */
  19#include <common.h>
  20#include <malloc.h>
  21#include <mmc.h>
  22#include <linux/errno.h>
  23#include <asm/io.h>
  24#include <asm/arch/clock.h>
  25#include <asm/arch/imx-regs.h>
  26#include <asm/arch/sys_proto.h>
  27#include <asm/mach-imx/dma.h>
  28#include <bouncebuf.h>
  29
  30struct mxsmmc_priv {
  31        int                     id;
  32        struct mxs_ssp_regs     *regs;
  33        uint32_t                buswidth;
  34        int                     (*mmc_is_wp)(int);
  35        int                     (*mmc_cd)(int);
  36        struct mxs_dma_desc     *desc;
  37        struct mmc_config       cfg;    /* mmc configuration */
  38};
  39
  40#define MXSMMC_MAX_TIMEOUT      10000
  41#define MXSMMC_SMALL_TRANSFER   512
  42
  43static int mxsmmc_cd(struct mxsmmc_priv *priv)
  44{
  45        struct mxs_ssp_regs *ssp_regs = priv->regs;
  46
  47        if (priv->mmc_cd)
  48                return priv->mmc_cd(priv->id);
  49
  50        return !(readl(&ssp_regs->hw_ssp_status) & SSP_STATUS_CARD_DETECT);
  51}
  52
  53static int mxsmmc_send_cmd_pio(struct mxsmmc_priv *priv, struct mmc_data *data)
  54{
  55        struct mxs_ssp_regs *ssp_regs = priv->regs;
  56        uint32_t *data_ptr;
  57        int timeout = MXSMMC_MAX_TIMEOUT;
  58        uint32_t reg;
  59        uint32_t data_count = data->blocksize * data->blocks;
  60
  61        if (data->flags & MMC_DATA_READ) {
  62                data_ptr = (uint32_t *)data->dest;
  63                while (data_count && --timeout) {
  64                        reg = readl(&ssp_regs->hw_ssp_status);
  65                        if (!(reg & SSP_STATUS_FIFO_EMPTY)) {
  66                                *data_ptr++ = readl(&ssp_regs->hw_ssp_data);
  67                                data_count -= 4;
  68                                timeout = MXSMMC_MAX_TIMEOUT;
  69                        } else
  70                                udelay(1000);
  71                }
  72        } else {
  73                data_ptr = (uint32_t *)data->src;
  74                timeout *= 100;
  75                while (data_count && --timeout) {
  76                        reg = readl(&ssp_regs->hw_ssp_status);
  77                        if (!(reg & SSP_STATUS_FIFO_FULL)) {
  78                                writel(*data_ptr++, &ssp_regs->hw_ssp_data);
  79                                data_count -= 4;
  80                                timeout = MXSMMC_MAX_TIMEOUT;
  81                        } else
  82                                udelay(1000);
  83                }
  84        }
  85
  86        return timeout ? 0 : -ECOMM;
  87}
  88
  89static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data)
  90{
  91        uint32_t data_count = data->blocksize * data->blocks;
  92        int dmach;
  93        struct mxs_dma_desc *desc = priv->desc;
  94        void *addr;
  95        unsigned int flags;
  96        struct bounce_buffer bbstate;
  97
  98        memset(desc, 0, sizeof(struct mxs_dma_desc));
  99        desc->address = (dma_addr_t)desc;
 100
 101        if (data->flags & MMC_DATA_READ) {
 102                priv->desc->cmd.data = MXS_DMA_DESC_COMMAND_DMA_WRITE;
 103                addr = data->dest;
 104                flags = GEN_BB_WRITE;
 105        } else {
 106                priv->desc->cmd.data = MXS_DMA_DESC_COMMAND_DMA_READ;
 107                addr = (void *)data->src;
 108                flags = GEN_BB_READ;
 109        }
 110
 111        bounce_buffer_start(&bbstate, addr, data_count, flags);
 112
 113        priv->desc->cmd.address = (dma_addr_t)bbstate.bounce_buffer;
 114
 115        priv->desc->cmd.data |= MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM |
 116                                (data_count << MXS_DMA_DESC_BYTES_OFFSET);
 117
 118        dmach = MXS_DMA_CHANNEL_AHB_APBH_SSP0 + priv->id;
 119        mxs_dma_desc_append(dmach, priv->desc);
 120        if (mxs_dma_go(dmach)) {
 121                bounce_buffer_stop(&bbstate);
 122                return -ECOMM;
 123        }
 124
 125        bounce_buffer_stop(&bbstate);
 126
 127        return 0;
 128}
 129
 130/*
 131 * Sends a command out on the bus.  Takes the mmc pointer,
 132 * a command pointer, and an optional data pointer.
 133 */
 134static int
 135mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 136{
 137        struct mxsmmc_priv *priv = mmc->priv;
 138        struct mxs_ssp_regs *ssp_regs = priv->regs;
 139        uint32_t reg;
 140        int timeout;
 141        uint32_t ctrl0;
 142        int ret;
 143
 144        debug("MMC%d: CMD%d\n", mmc->block_dev.devnum, cmd->cmdidx);
 145
 146        /* Check bus busy */
 147        timeout = MXSMMC_MAX_TIMEOUT;
 148        while (--timeout) {
 149                udelay(1000);
 150                reg = readl(&ssp_regs->hw_ssp_status);
 151                if (!(reg &
 152                        (SSP_STATUS_BUSY | SSP_STATUS_DATA_BUSY |
 153                        SSP_STATUS_CMD_BUSY))) {
 154                        break;
 155                }
 156        }
 157
 158        if (!timeout) {
 159                printf("MMC%d: Bus busy timeout!\n", mmc->block_dev.devnum);
 160                return -ETIMEDOUT;
 161        }
 162
 163        /* See if card is present */
 164        if (!mxsmmc_cd(priv)) {
 165                printf("MMC%d: No card detected!\n", mmc->block_dev.devnum);
 166                return -ENOMEDIUM;
 167        }
 168
 169        /* Start building CTRL0 contents */
 170        ctrl0 = priv->buswidth;
 171
 172        /* Set up command */
 173        if (!(cmd->resp_type & MMC_RSP_CRC))
 174                ctrl0 |= SSP_CTRL0_IGNORE_CRC;
 175        if (cmd->resp_type & MMC_RSP_PRESENT)   /* Need to get response */
 176                ctrl0 |= SSP_CTRL0_GET_RESP;
 177        if (cmd->resp_type & MMC_RSP_136)       /* It's a 136 bits response */
 178                ctrl0 |= SSP_CTRL0_LONG_RESP;
 179
 180        if (data && (data->blocksize * data->blocks < MXSMMC_SMALL_TRANSFER))
 181                writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_clr);
 182        else
 183                writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_set);
 184
 185        /* Command index */
 186        reg = readl(&ssp_regs->hw_ssp_cmd0);
 187        reg &= ~(SSP_CMD0_CMD_MASK | SSP_CMD0_APPEND_8CYC);
 188        reg |= cmd->cmdidx << SSP_CMD0_CMD_OFFSET;
 189        if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
 190                reg |= SSP_CMD0_APPEND_8CYC;
 191        writel(reg, &ssp_regs->hw_ssp_cmd0);
 192
 193        /* Command argument */
 194        writel(cmd->cmdarg, &ssp_regs->hw_ssp_cmd1);
 195
 196        /* Set up data */
 197        if (data) {
 198                /* READ or WRITE */
 199                if (data->flags & MMC_DATA_READ) {
 200                        ctrl0 |= SSP_CTRL0_READ;
 201                } else if (priv->mmc_is_wp &&
 202                        priv->mmc_is_wp(mmc->block_dev.devnum)) {
 203                        printf("MMC%d: Can not write a locked card!\n",
 204                                mmc->block_dev.devnum);
 205                        return -EOPNOTSUPP;
 206                }
 207
 208                ctrl0 |= SSP_CTRL0_DATA_XFER;
 209
 210                reg = data->blocksize * data->blocks;
 211#if defined(CONFIG_MX23)
 212                ctrl0 |= reg & SSP_CTRL0_XFER_COUNT_MASK;
 213
 214                clrsetbits_le32(&ssp_regs->hw_ssp_cmd0,
 215                        SSP_CMD0_BLOCK_SIZE_MASK | SSP_CMD0_BLOCK_COUNT_MASK,
 216                        ((data->blocks - 1) << SSP_CMD0_BLOCK_COUNT_OFFSET) |
 217                        ((ffs(data->blocksize) - 1) <<
 218                                SSP_CMD0_BLOCK_SIZE_OFFSET));
 219#elif defined(CONFIG_MX28)
 220                writel(reg, &ssp_regs->hw_ssp_xfer_size);
 221
 222                reg = ((data->blocks - 1) <<
 223                        SSP_BLOCK_SIZE_BLOCK_COUNT_OFFSET) |
 224                        ((ffs(data->blocksize) - 1) <<
 225                        SSP_BLOCK_SIZE_BLOCK_SIZE_OFFSET);
 226                writel(reg, &ssp_regs->hw_ssp_block_size);
 227#endif
 228        }
 229
 230        /* Kick off the command */
 231        ctrl0 |= SSP_CTRL0_WAIT_FOR_IRQ | SSP_CTRL0_ENABLE | SSP_CTRL0_RUN;
 232        writel(ctrl0, &ssp_regs->hw_ssp_ctrl0);
 233
 234        /* Wait for the command to complete */
 235        timeout = MXSMMC_MAX_TIMEOUT;
 236        while (--timeout) {
 237                udelay(1000);
 238                reg = readl(&ssp_regs->hw_ssp_status);
 239                if (!(reg & SSP_STATUS_CMD_BUSY))
 240                        break;
 241        }
 242
 243        if (!timeout) {
 244                printf("MMC%d: Command %d busy\n",
 245                        mmc->block_dev.devnum, cmd->cmdidx);
 246                return -ETIMEDOUT;
 247        }
 248
 249        /* Check command timeout */
 250        if (reg & SSP_STATUS_RESP_TIMEOUT) {
 251                printf("MMC%d: Command %d timeout (status 0x%08x)\n",
 252                        mmc->block_dev.devnum, cmd->cmdidx, reg);
 253                return -ETIMEDOUT;
 254        }
 255
 256        /* Check command errors */
 257        if (reg & (SSP_STATUS_RESP_CRC_ERR | SSP_STATUS_RESP_ERR)) {
 258                printf("MMC%d: Command %d error (status 0x%08x)!\n",
 259                        mmc->block_dev.devnum, cmd->cmdidx, reg);
 260                return -ECOMM;
 261        }
 262
 263        /* Copy response to response buffer */
 264        if (cmd->resp_type & MMC_RSP_136) {
 265                cmd->response[3] = readl(&ssp_regs->hw_ssp_sdresp0);
 266                cmd->response[2] = readl(&ssp_regs->hw_ssp_sdresp1);
 267                cmd->response[1] = readl(&ssp_regs->hw_ssp_sdresp2);
 268                cmd->response[0] = readl(&ssp_regs->hw_ssp_sdresp3);
 269        } else
 270                cmd->response[0] = readl(&ssp_regs->hw_ssp_sdresp0);
 271
 272        /* Return if no data to process */
 273        if (!data)
 274                return 0;
 275
 276        if (data->blocksize * data->blocks < MXSMMC_SMALL_TRANSFER) {
 277                ret = mxsmmc_send_cmd_pio(priv, data);
 278                if (ret) {
 279                        printf("MMC%d: Data timeout with command %d "
 280                                "(status 0x%08x)!\n",
 281                                mmc->block_dev.devnum, cmd->cmdidx, reg);
 282                        return ret;
 283                }
 284        } else {
 285                ret = mxsmmc_send_cmd_dma(priv, data);
 286                if (ret) {
 287                        printf("MMC%d: DMA transfer failed\n",
 288                                mmc->block_dev.devnum);
 289                        return ret;
 290                }
 291        }
 292
 293        /* Check data errors */
 294        reg = readl(&ssp_regs->hw_ssp_status);
 295        if (reg &
 296                (SSP_STATUS_TIMEOUT | SSP_STATUS_DATA_CRC_ERR |
 297                SSP_STATUS_FIFO_OVRFLW | SSP_STATUS_FIFO_UNDRFLW)) {
 298                printf("MMC%d: Data error with command %d (status 0x%08x)!\n",
 299                        mmc->block_dev.devnum, cmd->cmdidx, reg);
 300                return -ECOMM;
 301        }
 302
 303        return 0;
 304}
 305
 306static int mxsmmc_set_ios(struct mmc *mmc)
 307{
 308        struct mxsmmc_priv *priv = mmc->priv;
 309        struct mxs_ssp_regs *ssp_regs = priv->regs;
 310
 311        /* Set the clock speed */
 312        if (mmc->clock)
 313                mxs_set_ssp_busclock(priv->id, mmc->clock / 1000);
 314
 315        switch (mmc->bus_width) {
 316        case 1:
 317                priv->buswidth = SSP_CTRL0_BUS_WIDTH_ONE_BIT;
 318                break;
 319        case 4:
 320                priv->buswidth = SSP_CTRL0_BUS_WIDTH_FOUR_BIT;
 321                break;
 322        case 8:
 323                priv->buswidth = SSP_CTRL0_BUS_WIDTH_EIGHT_BIT;
 324                break;
 325        }
 326
 327        /* Set the bus width */
 328        clrsetbits_le32(&ssp_regs->hw_ssp_ctrl0,
 329                        SSP_CTRL0_BUS_WIDTH_MASK, priv->buswidth);
 330
 331        debug("MMC%d: Set %d bits bus width\n",
 332                mmc->block_dev.devnum, mmc->bus_width);
 333
 334        return 0;
 335}
 336
 337static int mxsmmc_init(struct mmc *mmc)
 338{
 339        struct mxsmmc_priv *priv = mmc->priv;
 340        struct mxs_ssp_regs *ssp_regs = priv->regs;
 341
 342        /* Reset SSP */
 343        mxs_reset_block(&ssp_regs->hw_ssp_ctrl0_reg);
 344
 345        /* Reconfigure the SSP block for MMC operation */
 346        writel(SSP_CTRL1_SSP_MODE_SD_MMC |
 347                SSP_CTRL1_WORD_LENGTH_EIGHT_BITS |
 348                SSP_CTRL1_DMA_ENABLE |
 349                SSP_CTRL1_POLARITY |
 350                SSP_CTRL1_RECV_TIMEOUT_IRQ_EN |
 351                SSP_CTRL1_DATA_CRC_IRQ_EN |
 352                SSP_CTRL1_DATA_TIMEOUT_IRQ_EN |
 353                SSP_CTRL1_RESP_TIMEOUT_IRQ_EN |
 354                SSP_CTRL1_RESP_ERR_IRQ_EN,
 355                &ssp_regs->hw_ssp_ctrl1_set);
 356
 357        /* Set initial bit clock 400 KHz */
 358        mxs_set_ssp_busclock(priv->id, 400);
 359
 360        /* Send initial 74 clock cycles (185 us @ 400 KHz)*/
 361        writel(SSP_CMD0_CONT_CLKING_EN, &ssp_regs->hw_ssp_cmd0_set);
 362        udelay(200);
 363        writel(SSP_CMD0_CONT_CLKING_EN, &ssp_regs->hw_ssp_cmd0_clr);
 364
 365        return 0;
 366}
 367
 368static const struct mmc_ops mxsmmc_ops = {
 369        .send_cmd       = mxsmmc_send_cmd,
 370        .set_ios        = mxsmmc_set_ios,
 371        .init           = mxsmmc_init,
 372};
 373
 374int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int))
 375{
 376        struct mmc *mmc = NULL;
 377        struct mxsmmc_priv *priv = NULL;
 378        int ret;
 379        const unsigned int mxsmmc_clk_id = mxs_ssp_clock_by_bus(id);
 380
 381        if (!mxs_ssp_bus_id_valid(id))
 382                return -ENODEV;
 383
 384        priv = malloc(sizeof(struct mxsmmc_priv));
 385        if (!priv)
 386                return -ENOMEM;
 387
 388        priv->desc = mxs_dma_desc_alloc();
 389        if (!priv->desc) {
 390                free(priv);
 391                return -ENOMEM;
 392        }
 393
 394        ret = mxs_dma_init_channel(MXS_DMA_CHANNEL_AHB_APBH_SSP0 + id);
 395        if (ret)
 396                return ret;
 397
 398        priv->mmc_is_wp = wp;
 399        priv->mmc_cd = cd;
 400        priv->id = id;
 401        priv->regs = mxs_ssp_regs_by_bus(id);
 402
 403        priv->cfg.name = "MXS MMC";
 404        priv->cfg.ops = &mxsmmc_ops;
 405
 406        priv->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 407
 408        priv->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT |
 409                         MMC_MODE_HS_52MHz | MMC_MODE_HS;
 410
 411        /*
 412         * SSPCLK = 480 * 18 / 29 / 1 = 297.731 MHz
 413         * SSP bit rate = SSPCLK / (CLOCK_DIVIDE * (1 + CLOCK_RATE)),
 414         * CLOCK_DIVIDE has to be an even value from 2 to 254, and
 415         * CLOCK_RATE could be any integer from 0 to 255.
 416         */
 417        priv->cfg.f_min = 400000;
 418        priv->cfg.f_max = mxc_get_clock(MXC_SSP0_CLK + mxsmmc_clk_id) * 1000 / 2;
 419        priv->cfg.b_max = 0x20;
 420
 421        mmc = mmc_create(&priv->cfg, priv);
 422        if (mmc == NULL) {
 423                mxs_dma_desc_free(priv->desc);
 424                free(priv);
 425                return -ENOMEM;
 426        }
 427        return 0;
 428}
 429