uboot/drivers/mmc/fsl_esdhc.c
<<
>>
Prefs
   1/*
   2 * Copyright 2007, 2010-2011 Freescale Semiconductor, Inc
   3 * Andy Fleming
   4 *
   5 * Based vaguely on the pxa mmc code:
   6 * (C) Copyright 2003
   7 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
   8 *
   9 * See file CREDITS for list of people who contributed to this
  10 * project.
  11 *
  12 * This program is free software; you can redistribute it and/or
  13 * modify it under the terms of the GNU General Public License as
  14 * published by the Free Software Foundation; either version 2 of
  15 * the License, or (at your option) any later version.
  16 *
  17 * This program is distributed in the hope that it will be useful,
  18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 * GNU General Public License for more details.
  21 *
  22 * You should have received a copy of the GNU General Public License
  23 * along with this program; if not, write to the Free Software
  24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  25 * MA 02111-1307 USA
  26 */
  27
  28#include <config.h>
  29#include <common.h>
  30#include <command.h>
  31#include <hwconfig.h>
  32#include <mmc.h>
  33#include <part.h>
  34#include <malloc.h>
  35#include <mmc.h>
  36#include <fsl_esdhc.h>
  37#include <fdt_support.h>
  38#include <asm/io.h>
  39
  40DECLARE_GLOBAL_DATA_PTR;
  41
  42struct fsl_esdhc {
  43        uint    dsaddr;
  44        uint    blkattr;
  45        uint    cmdarg;
  46        uint    xfertyp;
  47        uint    cmdrsp0;
  48        uint    cmdrsp1;
  49        uint    cmdrsp2;
  50        uint    cmdrsp3;
  51        uint    datport;
  52        uint    prsstat;
  53        uint    proctl;
  54        uint    sysctl;
  55        uint    irqstat;
  56        uint    irqstaten;
  57        uint    irqsigen;
  58        uint    autoc12err;
  59        uint    hostcapblt;
  60        uint    wml;
  61        char    reserved1[8];
  62        uint    fevt;
  63        char    reserved2[168];
  64        uint    hostver;
  65        char    reserved3[780];
  66        uint    scr;
  67};
  68
  69/* Return the XFERTYP flags for a given command and data packet */
  70uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
  71{
  72        uint xfertyp = 0;
  73
  74        if (data) {
  75                xfertyp |= XFERTYP_DPSEL;
  76#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
  77                xfertyp |= XFERTYP_DMAEN;
  78#endif
  79                if (data->blocks > 1) {
  80                        xfertyp |= XFERTYP_MSBSEL;
  81                        xfertyp |= XFERTYP_BCEN;
  82#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
  83                        xfertyp |= XFERTYP_AC12EN;
  84#endif
  85                }
  86
  87                if (data->flags & MMC_DATA_READ)
  88                        xfertyp |= XFERTYP_DTDSEL;
  89        }
  90
  91        if (cmd->resp_type & MMC_RSP_CRC)
  92                xfertyp |= XFERTYP_CCCEN;
  93        if (cmd->resp_type & MMC_RSP_OPCODE)
  94                xfertyp |= XFERTYP_CICEN;
  95        if (cmd->resp_type & MMC_RSP_136)
  96                xfertyp |= XFERTYP_RSPTYP_136;
  97        else if (cmd->resp_type & MMC_RSP_BUSY)
  98                xfertyp |= XFERTYP_RSPTYP_48_BUSY;
  99        else if (cmd->resp_type & MMC_RSP_PRESENT)
 100                xfertyp |= XFERTYP_RSPTYP_48;
 101
 102#ifdef CONFIG_MX53
 103        if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
 104                xfertyp |= XFERTYP_CMDTYP_ABORT;
 105#endif
 106        return XFERTYP_CMD(cmd->cmdidx) | xfertyp;
 107}
 108
 109#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
 110/*
 111 * PIO Read/Write Mode reduce the performace as DMA is not used in this mode.
 112 */
 113static void
 114esdhc_pio_read_write(struct mmc *mmc, struct mmc_data *data)
 115{
 116        struct fsl_esdhc *regs = mmc->priv;
 117        uint blocks;
 118        char *buffer;
 119        uint databuf;
 120        uint size;
 121        uint irqstat;
 122        uint timeout;
 123
 124        if (data->flags & MMC_DATA_READ) {
 125                blocks = data->blocks;
 126                buffer = data->dest;
 127                while (blocks) {
 128                        timeout = PIO_TIMEOUT;
 129                        size = data->blocksize;
 130                        irqstat = esdhc_read32(&regs->irqstat);
 131                        while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BREN)
 132                                && --timeout);
 133                        if (timeout <= 0) {
 134                                printf("\nData Read Failed in PIO Mode.");
 135                                return;
 136                        }
 137                        while (size && (!(irqstat & IRQSTAT_TC))) {
 138                                udelay(100); /* Wait before last byte transfer complete */
 139                                irqstat = esdhc_read32(&regs->irqstat);
 140                                databuf = in_le32(&regs->datport);
 141                                *((uint *)buffer) = databuf;
 142                                buffer += 4;
 143                                size -= 4;
 144                        }
 145                        blocks--;
 146                }
 147        } else {
 148                blocks = data->blocks;
 149                buffer = (char *)data->src;
 150                while (blocks) {
 151                        timeout = PIO_TIMEOUT;
 152                        size = data->blocksize;
 153                        irqstat = esdhc_read32(&regs->irqstat);
 154                        while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BWEN)
 155                                && --timeout);
 156                        if (timeout <= 0) {
 157                                printf("\nData Write Failed in PIO Mode.");
 158                                return;
 159                        }
 160                        while (size && (!(irqstat & IRQSTAT_TC))) {
 161                                udelay(100); /* Wait before last byte transfer complete */
 162                                databuf = *((uint *)buffer);
 163                                buffer += 4;
 164                                size -= 4;
 165                                irqstat = esdhc_read32(&regs->irqstat);
 166                                out_le32(&regs->datport, databuf);
 167                        }
 168                        blocks--;
 169                }
 170        }
 171}
 172#endif
 173
 174static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
 175{
 176        int timeout;
 177        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
 178        struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
 179#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
 180        uint wml_value;
 181
 182        wml_value = data->blocksize/4;
 183
 184        if (data->flags & MMC_DATA_READ) {
 185                if (wml_value > WML_RD_WML_MAX)
 186                        wml_value = WML_RD_WML_MAX_VAL;
 187
 188                esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK, wml_value);
 189                esdhc_write32(&regs->dsaddr, (u32)data->dest);
 190        } else {
 191                if (wml_value > WML_WR_WML_MAX)
 192                        wml_value = WML_WR_WML_MAX_VAL;
 193                if ((esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
 194                        printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
 195                        return TIMEOUT;
 196                }
 197
 198                esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
 199                                        wml_value << 16);
 200                esdhc_write32(&regs->dsaddr, (u32)data->src);
 201        }
 202#else   /* CONFIG_SYS_FSL_ESDHC_USE_PIO */
 203        if (!(data->flags & MMC_DATA_READ)) {
 204                if ((esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
 205                        printf("\nThe SD card is locked. "
 206                                "Can not write to a locked card.\n\n");
 207                        return TIMEOUT;
 208                }
 209                esdhc_write32(&regs->dsaddr, (u32)data->src);
 210        } else
 211                esdhc_write32(&regs->dsaddr, (u32)data->dest);
 212#endif  /* CONFIG_SYS_FSL_ESDHC_USE_PIO */
 213
 214        esdhc_write32(&regs->blkattr, data->blocks << 16 | data->blocksize);
 215
 216        /* Calculate the timeout period for data transactions */
 217        /*
 218         * 1)Timeout period = (2^(timeout+13)) SD Clock cycles
 219         * 2)Timeout period should be minimum 0.250sec as per SD Card spec
 220         *  So, Number of SD Clock cycles for 0.25sec should be minimum
 221         *              (SD Clock/sec * 0.25 sec) SD Clock cycles
 222         *              = (mmc->tran_speed * 1/4) SD Clock cycles
 223         * As 1) >=  2)
 224         * => (2^(timeout+13)) >= mmc->tran_speed * 1/4
 225         * Taking log2 both the sides
 226         * => timeout + 13 >= log2(mmc->tran_speed/4)
 227         * Rounding up to next power of 2
 228         * => timeout + 13 = log2(mmc->tran_speed/4) + 1
 229         * => timeout + 13 = fls(mmc->tran_speed/4)
 230         */
 231        timeout = fls(mmc->tran_speed/4);
 232        timeout -= 13;
 233
 234        if (timeout > 14)
 235                timeout = 14;
 236
 237        if (timeout < 0)
 238                timeout = 0;
 239
 240#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC_A001
 241        if ((timeout == 4) || (timeout == 8) || (timeout == 12))
 242                timeout++;
 243#endif
 244
 245        esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, timeout << 16);
 246
 247        return 0;
 248}
 249
 250
 251/*
 252 * Sends a command out on the bus.  Takes the mmc pointer,
 253 * a command pointer, and an optional data pointer.
 254 */
 255static int
 256esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 257{
 258        uint    xfertyp;
 259        uint    irqstat;
 260        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
 261        volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
 262
 263#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
 264        if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
 265                return 0;
 266#endif
 267
 268        esdhc_write32(&regs->irqstat, -1);
 269
 270        sync();
 271
 272        /* Wait for the bus to be idle */
 273        while ((esdhc_read32(&regs->prsstat) & PRSSTAT_CICHB) ||
 274                        (esdhc_read32(&regs->prsstat) & PRSSTAT_CIDHB))
 275                ;
 276
 277        while (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA)
 278                ;
 279
 280        /* Wait at least 8 SD clock cycles before the next command */
 281        /*
 282         * Note: This is way more than 8 cycles, but 1ms seems to
 283         * resolve timing issues with some cards
 284         */
 285        udelay(1000);
 286
 287        /* Set up for a data transfer if we have one */
 288        if (data) {
 289                int err;
 290
 291                err = esdhc_setup_data(mmc, data);
 292                if(err)
 293                        return err;
 294        }
 295
 296        /* Figure out the transfer arguments */
 297        xfertyp = esdhc_xfertyp(cmd, data);
 298
 299        /* Send the command */
 300        esdhc_write32(&regs->cmdarg, cmd->cmdarg);
 301        esdhc_write32(&regs->xfertyp, xfertyp);
 302
 303        /* Wait for the command to complete */
 304        while (!(esdhc_read32(&regs->irqstat) & IRQSTAT_CC))
 305                ;
 306
 307        irqstat = esdhc_read32(&regs->irqstat);
 308        esdhc_write32(&regs->irqstat, irqstat);
 309
 310        if (irqstat & CMD_ERR)
 311                return COMM_ERR;
 312
 313        if (irqstat & IRQSTAT_CTOE)
 314                return TIMEOUT;
 315
 316        /* Copy the response to the response buffer */
 317        if (cmd->resp_type & MMC_RSP_136) {
 318                u32 cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0;
 319
 320                cmdrsp3 = esdhc_read32(&regs->cmdrsp3);
 321                cmdrsp2 = esdhc_read32(&regs->cmdrsp2);
 322                cmdrsp1 = esdhc_read32(&regs->cmdrsp1);
 323                cmdrsp0 = esdhc_read32(&regs->cmdrsp0);
 324                cmd->response[0] = (cmdrsp3 << 8) | (cmdrsp2 >> 24);
 325                cmd->response[1] = (cmdrsp2 << 8) | (cmdrsp1 >> 24);
 326                cmd->response[2] = (cmdrsp1 << 8) | (cmdrsp0 >> 24);
 327                cmd->response[3] = (cmdrsp0 << 8);
 328        } else
 329                cmd->response[0] = esdhc_read32(&regs->cmdrsp0);
 330
 331        /* Wait until all of the blocks are transferred */
 332        if (data) {
 333#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
 334                esdhc_pio_read_write(mmc, data);
 335#else
 336                do {
 337                        irqstat = esdhc_read32(&regs->irqstat);
 338
 339                        if (irqstat & IRQSTAT_DTOE)
 340                                return TIMEOUT;
 341
 342                        if (irqstat & DATA_ERR)
 343                                return COMM_ERR;
 344                } while (!(irqstat & IRQSTAT_TC) &&
 345                                (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA));
 346#endif
 347        }
 348
 349        esdhc_write32(&regs->irqstat, -1);
 350
 351        return 0;
 352}
 353
 354void set_sysctl(struct mmc *mmc, uint clock)
 355{
 356        int sdhc_clk = gd->sdhc_clk;
 357        int div, pre_div;
 358        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
 359        volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
 360        uint clk;
 361
 362        if (clock < mmc->f_min)
 363                clock = mmc->f_min;
 364
 365        if (sdhc_clk / 16 > clock) {
 366                for (pre_div = 2; pre_div < 256; pre_div *= 2)
 367                        if ((sdhc_clk / pre_div) <= (clock * 16))
 368                                break;
 369        } else
 370                pre_div = 2;
 371
 372        for (div = 1; div <= 16; div++)
 373                if ((sdhc_clk / (div * pre_div)) <= clock)
 374                        break;
 375
 376        pre_div >>= 1;
 377        div -= 1;
 378
 379        clk = (pre_div << 8) | (div << 4);
 380
 381        esdhc_clrbits32(&regs->sysctl, SYSCTL_CKEN);
 382
 383        esdhc_clrsetbits32(&regs->sysctl, SYSCTL_CLOCK_MASK, clk);
 384
 385        udelay(10000);
 386
 387        clk = SYSCTL_PEREN | SYSCTL_CKEN;
 388
 389        esdhc_setbits32(&regs->sysctl, clk);
 390}
 391
 392static void esdhc_set_ios(struct mmc *mmc)
 393{
 394        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
 395        struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
 396
 397        /* Set the clock speed */
 398        set_sysctl(mmc, mmc->clock);
 399
 400        /* Set the bus width */
 401        esdhc_clrbits32(&regs->proctl, PROCTL_DTW_4 | PROCTL_DTW_8);
 402
 403        if (mmc->bus_width == 4)
 404                esdhc_setbits32(&regs->proctl, PROCTL_DTW_4);
 405        else if (mmc->bus_width == 8)
 406                esdhc_setbits32(&regs->proctl, PROCTL_DTW_8);
 407
 408}
 409
 410static int esdhc_init(struct mmc *mmc)
 411{
 412        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
 413        struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
 414        int timeout = 1000;
 415        int ret = 0;
 416        u8 card_absent;
 417
 418        /* Reset the entire host controller */
 419        esdhc_write32(&regs->sysctl, SYSCTL_RSTA);
 420
 421        /* Wait until the controller is available */
 422        while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTA) && --timeout)
 423                udelay(1000);
 424
 425        /* Enable cache snooping */
 426        if (cfg && !cfg->no_snoop)
 427                esdhc_write32(&regs->scr, 0x00000040);
 428
 429        esdhc_write32(&regs->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);
 430
 431        /* Set the initial clock speed */
 432        mmc_set_clock(mmc, 400000);
 433
 434        /* Disable the BRR and BWR bits in IRQSTAT */
 435        esdhc_clrbits32(&regs->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR);
 436
 437        /* Put the PROCTL reg back to the default */
 438        esdhc_write32(&regs->proctl, PROCTL_INIT);
 439
 440        /* Set timout to the maximum value */
 441        esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
 442
 443        /* Check if there is a callback for detecting the card */
 444        if (board_mmc_getcd(&card_absent, mmc)) {
 445                timeout = 1000;
 446                while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_CINS) &&
 447                                --timeout)
 448                        udelay(1000);
 449
 450                if (timeout <= 0)
 451                        ret = NO_CARD_ERR;
 452        } else {
 453                if (card_absent)
 454                        ret = NO_CARD_ERR;
 455        }
 456
 457        return ret;
 458}
 459
 460static void esdhc_reset(struct fsl_esdhc *regs)
 461{
 462        unsigned long timeout = 100; /* wait max 100 ms */
 463
 464        /* reset the controller */
 465        esdhc_write32(&regs->sysctl, SYSCTL_RSTA);
 466
 467        /* hardware clears the bit when it is done */
 468        while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTA) && --timeout)
 469                udelay(1000);
 470        if (!timeout)
 471                printf("MMC/SD: Reset never completed.\n");
 472}
 473
 474int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
 475{
 476        struct fsl_esdhc *regs;
 477        struct mmc *mmc;
 478        u32 caps, voltage_caps;
 479
 480        if (!cfg)
 481                return -1;
 482
 483        mmc = malloc(sizeof(struct mmc));
 484
 485        sprintf(mmc->name, "FSL_ESDHC");
 486        regs = (struct fsl_esdhc *)cfg->esdhc_base;
 487
 488        /* First reset the eSDHC controller */
 489        esdhc_reset(regs);
 490
 491        mmc->priv = cfg;
 492        mmc->send_cmd = esdhc_send_cmd;
 493        mmc->set_ios = esdhc_set_ios;
 494        mmc->init = esdhc_init;
 495
 496        voltage_caps = 0;
 497        caps = regs->hostcapblt;
 498
 499#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC135
 500        caps = caps & ~(ESDHC_HOSTCAPBLT_SRS |
 501                        ESDHC_HOSTCAPBLT_VS18 | ESDHC_HOSTCAPBLT_VS30);
 502#endif
 503        if (caps & ESDHC_HOSTCAPBLT_VS18)
 504                voltage_caps |= MMC_VDD_165_195;
 505        if (caps & ESDHC_HOSTCAPBLT_VS30)
 506                voltage_caps |= MMC_VDD_29_30 | MMC_VDD_30_31;
 507        if (caps & ESDHC_HOSTCAPBLT_VS33)
 508                voltage_caps |= MMC_VDD_32_33 | MMC_VDD_33_34;
 509
 510#ifdef CONFIG_SYS_SD_VOLTAGE
 511        mmc->voltages = CONFIG_SYS_SD_VOLTAGE;
 512#else
 513        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 514#endif
 515        if ((mmc->voltages & voltage_caps) == 0) {
 516                printf("voltage not supported by controller\n");
 517                return -1;
 518        }
 519
 520        mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
 521
 522        if (caps & ESDHC_HOSTCAPBLT_HSS)
 523                mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
 524
 525        mmc->f_min = 400000;
 526        mmc->f_max = MIN(gd->sdhc_clk, 52000000);
 527
 528        mmc->b_max = 0;
 529        mmc_register(mmc);
 530
 531        return 0;
 532}
 533
 534int fsl_esdhc_mmc_init(bd_t *bis)
 535{
 536        struct fsl_esdhc_cfg *cfg;
 537
 538        cfg = malloc(sizeof(struct fsl_esdhc_cfg));
 539        memset(cfg, 0, sizeof(struct fsl_esdhc_cfg));
 540        cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR;
 541        return fsl_esdhc_initialize(bis, cfg);
 542}
 543
 544#ifdef CONFIG_OF_LIBFDT
 545void fdt_fixup_esdhc(void *blob, bd_t *bd)
 546{
 547        const char *compat = "fsl,esdhc";
 548
 549#ifdef CONFIG_FSL_ESDHC_PIN_MUX
 550        if (!hwconfig("esdhc")) {
 551                do_fixup_by_compat(blob, compat, "status", "disabled",
 552                                8 + 1, 1);
 553                return;
 554        }
 555#endif
 556
 557        do_fixup_by_compat_u32(blob, compat, "clock-frequency",
 558                               gd->sdhc_clk, 1);
 559
 560        do_fixup_by_compat(blob, compat, "status", "okay",
 561                           4 + 1, 1);
 562}
 563#endif
 564