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