uboot/drivers/mmc/gen_atmel_mci.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2010
   3 * Rob Emanuele <rob@emanuele.us>
   4 * Reinhard Meyer, EMK Elektronik <reinhard.meyer@emk-elektronik.de>
   5 *
   6 * Original Driver:
   7 * Copyright (C) 2004-2006 Atmel Corporation
   8 *
   9 * SPDX-License-Identifier:     GPL-2.0+
  10 */
  11
  12#include <common.h>
  13#include <clk.h>
  14#include <dm.h>
  15#include <mmc.h>
  16#include <part.h>
  17#include <malloc.h>
  18#include <asm/io.h>
  19#include <linux/errno.h>
  20#include <asm/byteorder.h>
  21#include <asm/arch/clk.h>
  22#include <asm/arch/hardware.h>
  23#include "atmel_mci.h"
  24
  25DECLARE_GLOBAL_DATA_PTR;
  26
  27#ifndef CONFIG_SYS_MMC_CLK_OD
  28# define CONFIG_SYS_MMC_CLK_OD  150000
  29#endif
  30
  31#define MMC_DEFAULT_BLKLEN      512
  32
  33#if defined(CONFIG_ATMEL_MCI_PORTB)
  34# define MCI_BUS 1
  35#else
  36# define MCI_BUS 0
  37#endif
  38
  39#ifdef CONFIG_DM_MMC
  40struct atmel_mci_plat {
  41        struct mmc              mmc;
  42        struct mmc_config       cfg;
  43        struct atmel_mci        *mci;
  44};
  45#endif
  46
  47struct atmel_mci_priv {
  48#ifndef CONFIG_DM_MMC
  49        struct mmc_config       cfg;
  50        struct atmel_mci        *mci;
  51#endif
  52        unsigned int            initialized:1;
  53        unsigned int            curr_clk;
  54#ifdef CONFIG_DM_MMC
  55        ulong           bus_clk_rate;
  56#endif
  57};
  58
  59/* Read Atmel MCI IP version */
  60static unsigned int atmel_mci_get_version(struct atmel_mci *mci)
  61{
  62        return readl(&mci->version) & 0x00000fff;
  63}
  64
  65/*
  66 * Print command and status:
  67 *
  68 * - always when DEBUG is defined
  69 * - on command errors
  70 */
  71static void dump_cmd(u32 cmdr, u32 arg, u32 status, const char* msg)
  72{
  73        debug("gen_atmel_mci: CMDR %08x (%2u) ARGR %08x (SR: %08x) %s\n",
  74              cmdr, cmdr & 0x3F, arg, status, msg);
  75}
  76
  77/* Setup for MCI Clock and Block Size */
  78#ifdef CONFIG_DM_MMC
  79static void mci_set_mode(struct udevice *dev, u32 hz, u32 blklen)
  80{
  81        struct atmel_mci_plat *plat = dev_get_platdata(dev);
  82        struct atmel_mci_priv *priv = dev_get_priv(dev);
  83        struct mmc *mmc = &plat->mmc;
  84        u32 bus_hz = priv->bus_clk_rate;
  85        atmel_mci_t *mci = plat->mci;
  86#else
  87static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen)
  88{
  89        struct atmel_mci_priv *priv = mmc->priv;
  90        u32 bus_hz = get_mci_clk_rate();
  91        atmel_mci_t *mci = priv->mci;
  92#endif
  93
  94        u32 clkdiv = 255;
  95        unsigned int version = atmel_mci_get_version(mci);
  96        u32 clkodd = 0;
  97        u32 mr;
  98
  99        debug("mci: bus_hz is %u, setting clock %u Hz, block size %u\n",
 100                bus_hz, hz, blklen);
 101        if (hz > 0) {
 102                if (version >= 0x500) {
 103                        clkdiv = DIV_ROUND_UP(bus_hz, hz) - 2;
 104                        if (clkdiv > 511)
 105                                clkdiv = 511;
 106
 107                        clkodd = clkdiv & 1;
 108                        clkdiv >>= 1;
 109
 110                        debug("mci: setting clock %u Hz, block size %u\n",
 111                              bus_hz / (clkdiv * 2 + clkodd + 2), blklen);
 112                } else {
 113                        /* find clkdiv yielding a rate <= than requested */
 114                        for (clkdiv = 0; clkdiv < 255; clkdiv++) {
 115                                if ((bus_hz / (clkdiv + 1) / 2) <= hz)
 116                                        break;
 117                        }
 118                        debug("mci: setting clock %u Hz, block size %u\n",
 119                              (bus_hz / (clkdiv + 1)) / 2, blklen);
 120
 121                }
 122        }
 123        if (version >= 0x500)
 124                priv->curr_clk = bus_hz / (clkdiv * 2 + clkodd + 2);
 125        else
 126                priv->curr_clk = (bus_hz / (clkdiv + 1)) / 2;
 127        blklen &= 0xfffc;
 128
 129        mr = MMCI_BF(CLKDIV, clkdiv);
 130
 131        /* MCI IP version >= 0x200 has R/WPROOF */
 132        if (version >= 0x200)
 133                mr |= MMCI_BIT(RDPROOF) | MMCI_BIT(WRPROOF);
 134
 135        /*
 136         * MCI IP version >= 0x500 use bit 16 as clkodd.
 137         * MCI IP version < 0x500 use upper 16 bits for blklen.
 138         */
 139        if (version >= 0x500)
 140                mr |= MMCI_BF(CLKODD, clkodd);
 141        else
 142                mr |= MMCI_BF(BLKLEN, blklen);
 143
 144        writel(mr, &mci->mr);
 145
 146        /* MCI IP version >= 0x200 has blkr */
 147        if (version >= 0x200)
 148                writel(MMCI_BF(BLKLEN, blklen), &mci->blkr);
 149
 150        if (mmc->card_caps & mmc->cfg->host_caps & MMC_MODE_HS)
 151                writel(MMCI_BIT(HSMODE), &mci->cfg);
 152
 153        priv->initialized = 1;
 154}
 155
 156/* Return the CMDR with flags for a given command and data packet */
 157static u32 mci_encode_cmd(
 158        struct mmc_cmd *cmd, struct mmc_data *data, u32* error_flags)
 159{
 160        u32 cmdr = 0;
 161
 162        /* Default Flags for Errors */
 163        *error_flags |= (MMCI_BIT(DTOE) | MMCI_BIT(RDIRE) | MMCI_BIT(RENDE) |
 164                MMCI_BIT(RINDE) | MMCI_BIT(RTOE));
 165
 166        /* Default Flags for the Command */
 167        cmdr |= MMCI_BIT(MAXLAT);
 168
 169        if (data) {
 170                cmdr |= MMCI_BF(TRCMD, 1);
 171                if (data->blocks > 1)
 172                        cmdr |= MMCI_BF(TRTYP, 1);
 173                if (data->flags & MMC_DATA_READ)
 174                        cmdr |= MMCI_BIT(TRDIR);
 175        }
 176
 177        if (cmd->resp_type & MMC_RSP_CRC)
 178                *error_flags |= MMCI_BIT(RCRCE);
 179        if (cmd->resp_type & MMC_RSP_136)
 180                cmdr |= MMCI_BF(RSPTYP, 2);
 181        else if (cmd->resp_type & MMC_RSP_BUSY)
 182                cmdr |= MMCI_BF(RSPTYP, 3);
 183        else if (cmd->resp_type & MMC_RSP_PRESENT)
 184                cmdr |= MMCI_BF(RSPTYP, 1);
 185
 186        return cmdr | MMCI_BF(CMDNB, cmd->cmdidx);
 187}
 188
 189/* Entered into function pointer in mci_send_cmd */
 190static u32 mci_data_read(atmel_mci_t *mci, u32* data, u32 error_flags)
 191{
 192        u32 status;
 193
 194        do {
 195                status = readl(&mci->sr);
 196                if (status & (error_flags | MMCI_BIT(OVRE)))
 197                        goto io_fail;
 198        } while (!(status & MMCI_BIT(RXRDY)));
 199
 200        if (status & MMCI_BIT(RXRDY)) {
 201                *data = readl(&mci->rdr);
 202                status = 0;
 203        }
 204io_fail:
 205        return status;
 206}
 207
 208/* Entered into function pointer in mci_send_cmd */
 209static u32 mci_data_write(atmel_mci_t *mci, u32* data, u32 error_flags)
 210{
 211        u32 status;
 212
 213        do {
 214                status = readl(&mci->sr);
 215                if (status & (error_flags | MMCI_BIT(UNRE)))
 216                        goto io_fail;
 217        } while (!(status & MMCI_BIT(TXRDY)));
 218
 219        if (status & MMCI_BIT(TXRDY)) {
 220                writel(*data, &mci->tdr);
 221                status = 0;
 222        }
 223io_fail:
 224        return status;
 225}
 226
 227/*
 228 * Entered into mmc structure during driver init
 229 *
 230 * Sends a command out on the bus and deals with the block data.
 231 * Takes the mmc pointer, a command pointer, and an optional data pointer.
 232 */
 233#ifdef CONFIG_DM_MMC
 234static int atmel_mci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
 235                              struct mmc_data *data)
 236{
 237        struct atmel_mci_plat *plat = dev_get_platdata(dev);
 238        struct atmel_mci_priv *priv = dev_get_priv(dev);
 239        struct mmc *mmc = mmc_get_mmc_dev(dev);
 240        atmel_mci_t *mci = plat->mci;
 241#else
 242static int
 243mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 244{
 245        struct atmel_mci_priv *priv = mmc->priv;
 246        atmel_mci_t *mci = priv->mci;
 247#endif
 248        u32 cmdr;
 249        u32 error_flags = 0;
 250        u32 status;
 251
 252        if (!priv->initialized) {
 253                puts ("MCI not initialized!\n");
 254                return -ECOMM;
 255        }
 256
 257        /* Figure out the transfer arguments */
 258        cmdr = mci_encode_cmd(cmd, data, &error_flags);
 259
 260        /* For multi blocks read/write, set the block register */
 261        if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK)
 262                        || (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK))
 263                writel(data->blocks | MMCI_BF(BLKLEN, mmc->read_bl_len),
 264                        &mci->blkr);
 265
 266        /* Send the command */
 267        writel(cmd->cmdarg, &mci->argr);
 268        writel(cmdr, &mci->cmdr);
 269
 270#ifdef DEBUG
 271        dump_cmd(cmdr, cmd->cmdarg, 0, "DEBUG");
 272#endif
 273
 274        /* Wait for the command to complete */
 275        while (!((status = readl(&mci->sr)) & MMCI_BIT(CMDRDY)));
 276
 277        if ((status & error_flags) & MMCI_BIT(RTOE)) {
 278                dump_cmd(cmdr, cmd->cmdarg, status, "Command Time Out");
 279                return -ETIMEDOUT;
 280        } else if (status & error_flags) {
 281                dump_cmd(cmdr, cmd->cmdarg, status, "Command Failed");
 282                return -ECOMM;
 283        }
 284
 285        /* Copy the response to the response buffer */
 286        if (cmd->resp_type & MMC_RSP_136) {
 287                cmd->response[0] = readl(&mci->rspr);
 288                cmd->response[1] = readl(&mci->rspr1);
 289                cmd->response[2] = readl(&mci->rspr2);
 290                cmd->response[3] = readl(&mci->rspr3);
 291        } else
 292                cmd->response[0] = readl(&mci->rspr);
 293
 294        /* transfer all of the blocks */
 295        if (data) {
 296                u32 word_count, block_count;
 297                u32* ioptr;
 298                u32 sys_blocksize, dummy, i;
 299                u32 (*mci_data_op)
 300                        (atmel_mci_t *mci, u32* data, u32 error_flags);
 301
 302                if (data->flags & MMC_DATA_READ) {
 303                        mci_data_op = mci_data_read;
 304                        sys_blocksize = mmc->read_bl_len;
 305                        ioptr = (u32*)data->dest;
 306                } else {
 307                        mci_data_op = mci_data_write;
 308                        sys_blocksize = mmc->write_bl_len;
 309                        ioptr = (u32*)data->src;
 310                }
 311
 312                status = 0;
 313                for (block_count = 0;
 314                                block_count < data->blocks && !status;
 315                                block_count++) {
 316                        word_count = 0;
 317                        do {
 318                                status = mci_data_op(mci, ioptr, error_flags);
 319                                word_count++;
 320                                ioptr++;
 321                        } while (!status && word_count < (data->blocksize/4));
 322#ifdef DEBUG
 323                        if (data->flags & MMC_DATA_READ)
 324                        {
 325                                u32 cnt = word_count * 4;
 326                                printf("Read Data:\n");
 327                                print_buffer(0, data->dest + cnt * block_count,
 328                                             1, cnt, 0);
 329                        }
 330#endif
 331#ifdef DEBUG
 332                        if (!status && word_count < (sys_blocksize / 4))
 333                                printf("filling rest of block...\n");
 334#endif
 335                        /* fill the rest of a full block */
 336                        while (!status && word_count < (sys_blocksize / 4)) {
 337                                status = mci_data_op(mci, &dummy,
 338                                        error_flags);
 339                                word_count++;
 340                        }
 341                        if (status) {
 342                                dump_cmd(cmdr, cmd->cmdarg, status,
 343                                        "Data Transfer Failed");
 344                                return -ECOMM;
 345                        }
 346                }
 347
 348                /* Wait for Transfer End */
 349                i = 0;
 350                do {
 351                        status = readl(&mci->sr);
 352
 353                        if (status & error_flags) {
 354                                dump_cmd(cmdr, cmd->cmdarg, status,
 355                                        "DTIP Wait Failed");
 356                                return -ECOMM;
 357                        }
 358                        i++;
 359                } while ((status & MMCI_BIT(DTIP)) && i < 10000);
 360                if (status & MMCI_BIT(DTIP)) {
 361                        dump_cmd(cmdr, cmd->cmdarg, status,
 362                                "XFER DTIP never unset, ignoring");
 363                }
 364        }
 365
 366        /*
 367         * After the switch command, wait for 8 clocks before the next
 368         * command
 369         */
 370        if (cmd->cmdidx == MMC_CMD_SWITCH)
 371                udelay(8*1000000 / priv->curr_clk); /* 8 clk in us */
 372
 373        return 0;
 374}
 375
 376#ifdef CONFIG_DM_MMC
 377static int atmel_mci_set_ios(struct udevice *dev)
 378{
 379        struct atmel_mci_plat *plat = dev_get_platdata(dev);
 380        struct mmc *mmc = mmc_get_mmc_dev(dev);
 381        atmel_mci_t *mci = plat->mci;
 382#else
 383/* Entered into mmc structure during driver init */
 384static int mci_set_ios(struct mmc *mmc)
 385{
 386        struct atmel_mci_priv *priv = mmc->priv;
 387        atmel_mci_t *mci = priv->mci;
 388#endif
 389        int bus_width = mmc->bus_width;
 390        unsigned int version = atmel_mci_get_version(mci);
 391        int busw;
 392
 393        /* Set the clock speed */
 394#ifdef CONFIG_DM_MMC
 395        mci_set_mode(dev, mmc->clock, MMC_DEFAULT_BLKLEN);
 396#else
 397        mci_set_mode(mmc, mmc->clock, MMC_DEFAULT_BLKLEN);
 398#endif
 399
 400        /*
 401         * set the bus width and select slot for this interface
 402         * there is no capability for multiple slots on the same interface yet
 403         */
 404        if ((version & 0xf00) >= 0x300) {
 405                switch (bus_width) {
 406                case 8:
 407                        busw = 3;
 408                        break;
 409                case 4:
 410                        busw = 2;
 411                        break;
 412                default:
 413                        busw = 0;
 414                        break;
 415                }
 416
 417                writel(busw << 6 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);
 418        } else {
 419                busw = (bus_width == 4) ? 1 : 0;
 420
 421                writel(busw << 7 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);
 422        }
 423
 424        return 0;
 425}
 426
 427#ifdef CONFIG_DM_MMC
 428static int atmel_mci_hw_init(struct udevice *dev)
 429{
 430        struct atmel_mci_plat *plat = dev_get_platdata(dev);
 431        atmel_mci_t *mci = plat->mci;
 432#else
 433/* Entered into mmc structure during driver init */
 434static int mci_init(struct mmc *mmc)
 435{
 436        struct atmel_mci_priv *priv = mmc->priv;
 437        atmel_mci_t *mci = priv->mci;
 438#endif
 439
 440        /* Initialize controller */
 441        writel(MMCI_BIT(SWRST), &mci->cr);      /* soft reset */
 442        writel(MMCI_BIT(PWSDIS), &mci->cr);     /* disable power save */
 443        writel(MMCI_BIT(MCIEN), &mci->cr);      /* enable mci */
 444        writel(MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);   /* select port */
 445
 446        /* This delay can be optimized, but stick with max value */
 447        writel(0x7f, &mci->dtor);
 448        /* Disable Interrupts */
 449        writel(~0UL, &mci->idr);
 450
 451        /* Set default clocks and blocklen */
 452#ifdef CONFIG_DM_MMC
 453        mci_set_mode(dev, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN);
 454#else
 455        mci_set_mode(mmc, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN);
 456#endif
 457
 458        return 0;
 459}
 460
 461#ifndef CONFIG_DM_MMC
 462static const struct mmc_ops atmel_mci_ops = {
 463        .send_cmd       = mci_send_cmd,
 464        .set_ios        = mci_set_ios,
 465        .init           = mci_init,
 466};
 467
 468/*
 469 * This is the only exported function
 470 *
 471 * Call it with the MCI register base address
 472 */
 473int atmel_mci_init(void *regs)
 474{
 475        struct mmc *mmc;
 476        struct mmc_config *cfg;
 477        struct atmel_mci_priv *priv;
 478        unsigned int version;
 479
 480        priv = calloc(1, sizeof(*priv));
 481        if (!priv)
 482                return -ENOMEM;
 483
 484        cfg = &priv->cfg;
 485
 486        cfg->name = "mci";
 487        cfg->ops = &atmel_mci_ops;
 488
 489        priv->mci = (struct atmel_mci *)regs;
 490        priv->initialized = 0;
 491
 492        /* need to be able to pass these in on a board by board basis */
 493        cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 494        version = atmel_mci_get_version(priv->mci);
 495        if ((version & 0xf00) >= 0x300) {
 496                cfg->host_caps = MMC_MODE_8BIT;
 497                cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
 498        }
 499
 500        cfg->host_caps |= MMC_MODE_4BIT;
 501
 502        /*
 503         * min and max frequencies determined by
 504         * max and min of clock divider
 505         */
 506        cfg->f_min = get_mci_clk_rate() / (2*256);
 507        cfg->f_max = get_mci_clk_rate() / (2*1);
 508
 509        cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 510
 511        mmc = mmc_create(cfg, priv);
 512
 513        if (mmc == NULL) {
 514                free(priv);
 515                return -ENODEV;
 516        }
 517        /* NOTE: possibly leaking the priv structure */
 518
 519        return 0;
 520}
 521#endif
 522
 523#ifdef CONFIG_DM_MMC
 524static const struct dm_mmc_ops atmel_mci_mmc_ops = {
 525        .send_cmd = atmel_mci_send_cmd,
 526        .set_ios = atmel_mci_set_ios,
 527};
 528
 529static void atmel_mci_setup_cfg(struct udevice *dev)
 530{
 531        struct atmel_mci_plat *plat = dev_get_platdata(dev);
 532        struct atmel_mci_priv *priv = dev_get_priv(dev);
 533        struct mmc_config *cfg;
 534        u32 version;
 535
 536        cfg = &plat->cfg;
 537        cfg->name = "Atmel mci";
 538        cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 539
 540        /*
 541         * If the version is above 3.0, the capabilities of the 8-bit
 542         * bus width and high speed are supported.
 543         */
 544        version = atmel_mci_get_version(plat->mci);
 545        if ((version & 0xf00) >= 0x300) {
 546                cfg->host_caps = MMC_MODE_8BIT |
 547                                 MMC_MODE_HS | MMC_MODE_HS_52MHz;
 548        }
 549
 550        cfg->host_caps |= MMC_MODE_4BIT;
 551        cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 552        cfg->f_min = priv->bus_clk_rate / (2 * 256);
 553        cfg->f_max = priv->bus_clk_rate / 2;
 554}
 555
 556static int atmel_mci_enable_clk(struct udevice *dev)
 557{
 558        struct atmel_mci_priv *priv = dev_get_priv(dev);
 559        struct clk clk;
 560        ulong clk_rate;
 561        int ret = 0;
 562
 563        ret = clk_get_by_index(dev, 0, &clk);
 564        if (ret) {
 565                ret = -EINVAL;
 566                goto failed;
 567        }
 568
 569        ret = clk_enable(&clk);
 570        if (ret)
 571                goto failed;
 572
 573        clk_rate = clk_get_rate(&clk);
 574        if (!clk_rate) {
 575                ret = -EINVAL;
 576                goto failed;
 577        }
 578
 579        priv->bus_clk_rate = clk_rate;
 580
 581failed:
 582        clk_free(&clk);
 583
 584        return ret;
 585}
 586
 587static int atmel_mci_probe(struct udevice *dev)
 588{
 589        struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
 590        struct atmel_mci_plat *plat = dev_get_platdata(dev);
 591        struct mmc *mmc;
 592        int ret;
 593
 594        ret = atmel_mci_enable_clk(dev);
 595        if (ret)
 596                return ret;
 597
 598        plat->mci = (struct atmel_mci *)devfdt_get_addr_ptr(dev);
 599
 600        atmel_mci_setup_cfg(dev);
 601
 602        mmc = &plat->mmc;
 603        mmc->cfg = &plat->cfg;
 604        mmc->dev = dev;
 605        upriv->mmc = mmc;
 606
 607        atmel_mci_hw_init(dev);
 608
 609        return 0;
 610}
 611
 612static int atmel_mci_bind(struct udevice *dev)
 613{
 614        struct atmel_mci_plat *plat = dev_get_platdata(dev);
 615
 616        return mmc_bind(dev, &plat->mmc, &plat->cfg);
 617}
 618
 619static const struct udevice_id atmel_mci_ids[] = {
 620        { .compatible = "atmel,hsmci" },
 621        { }
 622};
 623
 624U_BOOT_DRIVER(atmel_mci) = {
 625        .name = "atmel-mci",
 626        .id = UCLASS_MMC,
 627        .of_match = atmel_mci_ids,
 628        .bind = atmel_mci_bind,
 629        .probe = atmel_mci_probe,
 630        .platdata_auto_alloc_size = sizeof(struct atmel_mci_plat),
 631        .priv_auto_alloc_size = sizeof(struct atmel_mci_priv),
 632        .ops = &atmel_mci_mmc_ops,
 633};
 634#endif
 635