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 <mmc.h>
  14#include <part.h>
  15#include <malloc.h>
  16#include <asm/io.h>
  17#include <asm/errno.h>
  18#include <asm/byteorder.h>
  19#include <asm/arch/clk.h>
  20#include <asm/arch/hardware.h>
  21#include "atmel_mci.h"
  22
  23#ifndef CONFIG_SYS_MMC_CLK_OD
  24# define CONFIG_SYS_MMC_CLK_OD  150000
  25#endif
  26
  27#define MMC_DEFAULT_BLKLEN      512
  28
  29#if defined(CONFIG_ATMEL_MCI_PORTB)
  30# define MCI_BUS 1
  31#else
  32# define MCI_BUS 0
  33#endif
  34
  35static int initialized = 0;
  36
  37/* Read Atmel MCI IP version */
  38static unsigned int atmel_mci_get_version(struct atmel_mci *mci)
  39{
  40        return readl(&mci->version) & 0x00000fff;
  41}
  42
  43/*
  44 * Print command and status:
  45 *
  46 * - always when DEBUG is defined
  47 * - on command errors
  48 */
  49static void dump_cmd(u32 cmdr, u32 arg, u32 status, const char* msg)
  50{
  51        printf("gen_atmel_mci: CMDR %08x (%2u) ARGR %08x (SR: %08x) %s\n",
  52                cmdr, cmdr&0x3F, arg, status, msg);
  53}
  54
  55/* Setup for MCI Clock and Block Size */
  56static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen)
  57{
  58        atmel_mci_t *mci = mmc->priv;
  59        u32 bus_hz = get_mci_clk_rate();
  60        u32 clkdiv = 255;
  61        unsigned int version = atmel_mci_get_version(mci);
  62        u32 clkodd = 0;
  63        u32 mr;
  64
  65        debug("mci: bus_hz is %u, setting clock %u Hz, block size %u\n",
  66                bus_hz, hz, blklen);
  67        if (hz > 0) {
  68                if (version >= 0x500) {
  69                        clkdiv = DIV_ROUND_UP(bus_hz, hz) - 2;
  70                        if (clkdiv > 511)
  71                                clkdiv = 511;
  72
  73                        clkodd = clkdiv & 1;
  74                        clkdiv >>= 1;
  75
  76                        printf("mci: setting clock %u Hz, block size %u\n",
  77                               bus_hz / (clkdiv * 2 + clkodd + 2), blklen);
  78                } else {
  79                        /* find clkdiv yielding a rate <= than requested */
  80                        for (clkdiv = 0; clkdiv < 255; clkdiv++) {
  81                                if ((bus_hz / (clkdiv + 1) / 2) <= hz)
  82                                        break;
  83                        }
  84                        printf("mci: setting clock %u Hz, block size %u\n",
  85                               (bus_hz / (clkdiv + 1)) / 2, blklen);
  86
  87                }
  88        }
  89
  90        blklen &= 0xfffc;
  91
  92        mr = MMCI_BF(CLKDIV, clkdiv);
  93
  94        /* MCI IP version >= 0x200 has R/WPROOF */
  95        if (version >= 0x200)
  96                mr |= MMCI_BIT(RDPROOF) | MMCI_BIT(WRPROOF);
  97
  98        /*
  99         * MCI IP version >= 0x500 use bit 16 as clkodd.
 100         * MCI IP version < 0x500 use upper 16 bits for blklen.
 101         */
 102        if (version >= 0x500)
 103                mr |= MMCI_BF(CLKODD, clkodd);
 104        else
 105                mr |= MMCI_BF(BLKLEN, blklen);
 106
 107        writel(mr, &mci->mr);
 108
 109        /* MCI IP version >= 0x200 has blkr */
 110        if (version >= 0x200)
 111                writel(MMCI_BF(BLKLEN, blklen), &mci->blkr);
 112
 113        if (mmc->card_caps & mmc->cfg->host_caps & MMC_MODE_HS)
 114                writel(MMCI_BIT(HSMODE), &mci->cfg);
 115
 116        initialized = 1;
 117}
 118
 119/* Return the CMDR with flags for a given command and data packet */
 120static u32 mci_encode_cmd(
 121        struct mmc_cmd *cmd, struct mmc_data *data, u32* error_flags)
 122{
 123        u32 cmdr = 0;
 124
 125        /* Default Flags for Errors */
 126        *error_flags |= (MMCI_BIT(DTOE) | MMCI_BIT(RDIRE) | MMCI_BIT(RENDE) |
 127                MMCI_BIT(RINDE) | MMCI_BIT(RTOE));
 128
 129        /* Default Flags for the Command */
 130        cmdr |= MMCI_BIT(MAXLAT);
 131
 132        if (data) {
 133                cmdr |= MMCI_BF(TRCMD, 1);
 134                if (data->blocks > 1)
 135                        cmdr |= MMCI_BF(TRTYP, 1);
 136                if (data->flags & MMC_DATA_READ)
 137                        cmdr |= MMCI_BIT(TRDIR);
 138        }
 139
 140        if (cmd->resp_type & MMC_RSP_CRC)
 141                *error_flags |= MMCI_BIT(RCRCE);
 142        if (cmd->resp_type & MMC_RSP_136)
 143                cmdr |= MMCI_BF(RSPTYP, 2);
 144        else if (cmd->resp_type & MMC_RSP_BUSY)
 145                cmdr |= MMCI_BF(RSPTYP, 3);
 146        else if (cmd->resp_type & MMC_RSP_PRESENT)
 147                cmdr |= MMCI_BF(RSPTYP, 1);
 148
 149        return cmdr | MMCI_BF(CMDNB, cmd->cmdidx);
 150}
 151
 152/* Entered into function pointer in mci_send_cmd */
 153static u32 mci_data_read(atmel_mci_t *mci, u32* data, u32 error_flags)
 154{
 155        u32 status;
 156
 157        do {
 158                status = readl(&mci->sr);
 159                if (status & (error_flags | MMCI_BIT(OVRE)))
 160                        goto io_fail;
 161        } while (!(status & MMCI_BIT(RXRDY)));
 162
 163        if (status & MMCI_BIT(RXRDY)) {
 164                *data = readl(&mci->rdr);
 165                status = 0;
 166        }
 167io_fail:
 168        return status;
 169}
 170
 171/* Entered into function pointer in mci_send_cmd */
 172static u32 mci_data_write(atmel_mci_t *mci, u32* data, u32 error_flags)
 173{
 174        u32 status;
 175
 176        do {
 177                status = readl(&mci->sr);
 178                if (status & (error_flags | MMCI_BIT(UNRE)))
 179                        goto io_fail;
 180        } while (!(status & MMCI_BIT(TXRDY)));
 181
 182        if (status & MMCI_BIT(TXRDY)) {
 183                writel(*data, &mci->tdr);
 184                status = 0;
 185        }
 186io_fail:
 187        return status;
 188}
 189
 190/*
 191 * Entered into mmc structure during driver init
 192 *
 193 * Sends a command out on the bus and deals with the block data.
 194 * Takes the mmc pointer, a command pointer, and an optional data pointer.
 195 */
 196static int
 197mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 198{
 199        atmel_mci_t *mci = mmc->priv;
 200        u32 cmdr;
 201        u32 error_flags = 0;
 202        u32 status;
 203
 204        if (!initialized) {
 205                puts ("MCI not initialized!\n");
 206                return COMM_ERR;
 207        }
 208
 209        /* Figure out the transfer arguments */
 210        cmdr = mci_encode_cmd(cmd, data, &error_flags);
 211
 212        /* For multi blocks read/write, set the block register */
 213        if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK)
 214                        || (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK))
 215                writel(data->blocks | MMCI_BF(BLKLEN, mmc->read_bl_len),
 216                        &mci->blkr);
 217
 218        /* Send the command */
 219        writel(cmd->cmdarg, &mci->argr);
 220        writel(cmdr, &mci->cmdr);
 221
 222#ifdef DEBUG
 223        dump_cmd(cmdr, cmd->cmdarg, 0, "DEBUG");
 224#endif
 225
 226        /* Wait for the command to complete */
 227        while (!((status = readl(&mci->sr)) & MMCI_BIT(CMDRDY)));
 228
 229        if ((status & error_flags) & MMCI_BIT(RTOE)) {
 230                dump_cmd(cmdr, cmd->cmdarg, status, "Command Time Out");
 231                return TIMEOUT;
 232        } else if (status & error_flags) {
 233                dump_cmd(cmdr, cmd->cmdarg, status, "Command Failed");
 234                return COMM_ERR;
 235        }
 236
 237        /* Copy the response to the response buffer */
 238        if (cmd->resp_type & MMC_RSP_136) {
 239                cmd->response[0] = readl(&mci->rspr);
 240                cmd->response[1] = readl(&mci->rspr1);
 241                cmd->response[2] = readl(&mci->rspr2);
 242                cmd->response[3] = readl(&mci->rspr3);
 243        } else
 244                cmd->response[0] = readl(&mci->rspr);
 245
 246        /* transfer all of the blocks */
 247        if (data) {
 248                u32 word_count, block_count;
 249                u32* ioptr;
 250                u32 sys_blocksize, dummy, i;
 251                u32 (*mci_data_op)
 252                        (atmel_mci_t *mci, u32* data, u32 error_flags);
 253
 254                if (data->flags & MMC_DATA_READ) {
 255                        mci_data_op = mci_data_read;
 256                        sys_blocksize = mmc->read_bl_len;
 257                        ioptr = (u32*)data->dest;
 258                } else {
 259                        mci_data_op = mci_data_write;
 260                        sys_blocksize = mmc->write_bl_len;
 261                        ioptr = (u32*)data->src;
 262                }
 263
 264                status = 0;
 265                for (block_count = 0;
 266                                block_count < data->blocks && !status;
 267                                block_count++) {
 268                        word_count = 0;
 269                        do {
 270                                status = mci_data_op(mci, ioptr, error_flags);
 271                                word_count++;
 272                                ioptr++;
 273                        } while (!status && word_count < (data->blocksize/4));
 274#ifdef DEBUG
 275                        if (data->flags & MMC_DATA_READ)
 276                        {
 277                                u32 cnt = word_count * 4;
 278                                printf("Read Data:\n");
 279                                print_buffer(0, data->dest + cnt * block_count,
 280                                             1, cnt, 0);
 281                        }
 282#endif
 283#ifdef DEBUG
 284                        if (!status && word_count < (sys_blocksize / 4))
 285                                printf("filling rest of block...\n");
 286#endif
 287                        /* fill the rest of a full block */
 288                        while (!status && word_count < (sys_blocksize / 4)) {
 289                                status = mci_data_op(mci, &dummy,
 290                                        error_flags);
 291                                word_count++;
 292                        }
 293                        if (status) {
 294                                dump_cmd(cmdr, cmd->cmdarg, status,
 295                                        "Data Transfer Failed");
 296                                return COMM_ERR;
 297                        }
 298                }
 299
 300                /* Wait for Transfer End */
 301                i = 0;
 302                do {
 303                        status = readl(&mci->sr);
 304
 305                        if (status & error_flags) {
 306                                dump_cmd(cmdr, cmd->cmdarg, status,
 307                                        "DTIP Wait Failed");
 308                                return COMM_ERR;
 309                        }
 310                        i++;
 311                } while ((status & MMCI_BIT(DTIP)) && i < 10000);
 312                if (status & MMCI_BIT(DTIP)) {
 313                        dump_cmd(cmdr, cmd->cmdarg, status,
 314                                "XFER DTIP never unset, ignoring");
 315                }
 316        }
 317
 318        return 0;
 319}
 320
 321/* Entered into mmc structure during driver init */
 322static void mci_set_ios(struct mmc *mmc)
 323{
 324        atmel_mci_t *mci = mmc->priv;
 325        int bus_width = mmc->bus_width;
 326        unsigned int version = atmel_mci_get_version(mci);
 327        int busw;
 328
 329        /* Set the clock speed */
 330        mci_set_mode(mmc, mmc->clock, MMC_DEFAULT_BLKLEN);
 331
 332        /*
 333         * set the bus width and select slot for this interface
 334         * there is no capability for multiple slots on the same interface yet
 335         */
 336        if ((version & 0xf00) >= 0x300) {
 337                switch (bus_width) {
 338                case 8:
 339                        busw = 3;
 340                        break;
 341                case 4:
 342                        busw = 2;
 343                        break;
 344                default:
 345                        busw = 0;
 346                        break;
 347                }
 348
 349                writel(busw << 6 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);
 350        } else {
 351                busw = (bus_width == 4) ? 1 : 0;
 352
 353                writel(busw << 7 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);
 354        }
 355}
 356
 357/* Entered into mmc structure during driver init */
 358static int mci_init(struct mmc *mmc)
 359{
 360        atmel_mci_t *mci = mmc->priv;
 361
 362        /* Initialize controller */
 363        writel(MMCI_BIT(SWRST), &mci->cr);      /* soft reset */
 364        writel(MMCI_BIT(PWSDIS), &mci->cr);     /* disable power save */
 365        writel(MMCI_BIT(MCIEN), &mci->cr);      /* enable mci */
 366        writel(MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);   /* select port */
 367
 368        /* This delay can be optimized, but stick with max value */
 369        writel(0x7f, &mci->dtor);
 370        /* Disable Interrupts */
 371        writel(~0UL, &mci->idr);
 372
 373        /* Set default clocks and blocklen */
 374        mci_set_mode(mmc, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN);
 375
 376        return 0;
 377}
 378
 379static const struct mmc_ops atmel_mci_ops = {
 380        .send_cmd       = mci_send_cmd,
 381        .set_ios        = mci_set_ios,
 382        .init           = mci_init,
 383};
 384
 385/*
 386 * This is the only exported function
 387 *
 388 * Call it with the MCI register base address
 389 */
 390int atmel_mci_init(void *regs)
 391{
 392        struct mmc *mmc;
 393        struct mmc_config *cfg;
 394        struct atmel_mci *mci;
 395        unsigned int version;
 396
 397        cfg = malloc(sizeof(*cfg));
 398        if (cfg == NULL)
 399                return -1;
 400        memset(cfg, 0, sizeof(*cfg));
 401
 402        mci = (struct atmel_mci *)regs;
 403
 404        cfg->name = "mci";
 405        cfg->ops = &atmel_mci_ops;
 406
 407        /* need to be able to pass these in on a board by board basis */
 408        cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 409        version = atmel_mci_get_version(mci);
 410        if ((version & 0xf00) >= 0x300) {
 411                cfg->host_caps = MMC_MODE_8BIT;
 412                cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
 413        }
 414
 415        cfg->host_caps |= MMC_MODE_4BIT;
 416
 417        /*
 418         * min and max frequencies determined by
 419         * max and min of clock divider
 420         */
 421        cfg->f_min = get_mci_clk_rate() / (2*256);
 422        cfg->f_max = get_mci_clk_rate() / (2*1);
 423
 424        cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 425
 426        mmc = mmc_create(cfg, regs);
 427
 428        if (mmc == NULL) {
 429                free(cfg);
 430                return -1;
 431        }
 432        /* NOTE: possibly leaking the cfg structure */
 433
 434        return 0;
 435}
 436