uboot/drivers/mmc/pxa_mmc.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2003
   3 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24#include <config.h>
  25#include <common.h>
  26#include <mmc.h>
  27#include <asm/errno.h>
  28#include <asm/arch/hardware.h>
  29#include <part.h>
  30
  31#include "pxa_mmc.h"
  32
  33extern int fat_register_device(block_dev_desc_t * dev_desc, int part_no);
  34
  35static block_dev_desc_t mmc_dev;
  36
  37block_dev_desc_t *mmc_get_dev(int dev)
  38{
  39        return ((block_dev_desc_t *) & mmc_dev);
  40}
  41
  42/*
  43 * FIXME needs to read cid and csd info to determine block size
  44 * and other parameters
  45 */
  46static uchar mmc_buf[MMC_BLOCK_SIZE];
  47static uchar spec_ver;
  48static int mmc_ready = 0;
  49static int wide = 0;
  50
  51static uint32_t *
  52/****************************************************/
  53mmc_cmd(ushort cmd, ushort argh, ushort argl, ushort cmdat)
  54/****************************************************/
  55{
  56        static uint32_t resp[4], a, b, c;
  57        ulong status;
  58        int i;
  59
  60        debug("mmc_cmd %u 0x%04x 0x%04x 0x%04x\n", cmd, argh, argl,
  61              cmdat | wide);
  62        MMC_STRPCL = MMC_STRPCL_STOP_CLK;
  63        MMC_I_MASK = ~MMC_I_MASK_CLK_IS_OFF;
  64        while (!(MMC_I_REG & MMC_I_REG_CLK_IS_OFF)) ;
  65        MMC_CMD = cmd;
  66        MMC_ARGH = argh;
  67        MMC_ARGL = argl;
  68        MMC_CMDAT = cmdat | wide;
  69        MMC_I_MASK = ~MMC_I_MASK_END_CMD_RES;
  70        MMC_STRPCL = MMC_STRPCL_START_CLK;
  71        while (!(MMC_I_REG & MMC_I_REG_END_CMD_RES)) ;
  72
  73        status = MMC_STAT;
  74        debug("MMC status 0x%08x\n", status);
  75        if (status & MMC_STAT_TIME_OUT_RESPONSE) {
  76                return 0;
  77        }
  78
  79        /* Linux says:
  80         * Did I mention this is Sick.  We always need to
  81         * discard the upper 8 bits of the first 16-bit word.
  82         */
  83        a = (MMC_RES & 0xffff);
  84        for (i = 0; i < 4; i++) {
  85                b = (MMC_RES & 0xffff);
  86                c = (MMC_RES & 0xffff);
  87                resp[i] = (a << 24) | (b << 8) | (c >> 8);
  88                a = c;
  89                debug("MMC resp[%d] = %#08x\n", i, resp[i]);
  90        }
  91
  92        return resp;
  93}
  94
  95int
  96/****************************************************/
  97mmc_block_read(uchar * dst, ulong src, ulong len)
  98/****************************************************/
  99{
 100        ushort argh, argl;
 101        ulong status;
 102
 103        if (len == 0) {
 104                return 0;
 105        }
 106
 107        debug("mmc_block_rd dst %lx src %lx len %d\n", (ulong) dst, src, len);
 108
 109        argh = len >> 16;
 110        argl = len & 0xffff;
 111
 112        /* set block len */
 113        mmc_cmd(MMC_CMD_SET_BLOCKLEN, argh, argl, MMC_CMDAT_R1);
 114
 115        /* send read command */
 116        argh = src >> 16;
 117        argl = src & 0xffff;
 118        MMC_STRPCL = MMC_STRPCL_STOP_CLK;
 119        MMC_RDTO = 0xffff;
 120        MMC_NOB = 1;
 121        MMC_BLKLEN = len;
 122        mmc_cmd(MMC_CMD_READ_SINGLE_BLOCK, argh, argl,
 123                MMC_CMDAT_R1 | MMC_CMDAT_READ | MMC_CMDAT_BLOCK |
 124                MMC_CMDAT_DATA_EN);
 125
 126        MMC_I_MASK = ~MMC_I_MASK_RXFIFO_RD_REQ;
 127        while (len) {
 128                if (MMC_I_REG & MMC_I_REG_RXFIFO_RD_REQ) {
 129#ifdef CONFIG_PXA27X
 130                        int i;
 131                        for (i = min(len, 32); i; i--) {
 132                                *dst++ = *((volatile uchar *)&MMC_RXFIFO);
 133                                len--;
 134                        }
 135#else
 136                        *dst++ = MMC_RXFIFO;
 137                        len--;
 138#endif
 139                }
 140                status = MMC_STAT;
 141                if (status & MMC_STAT_ERRORS) {
 142                        printf("MMC_STAT error %lx\n", status);
 143                        return -1;
 144                }
 145        }
 146        MMC_I_MASK = ~MMC_I_MASK_DATA_TRAN_DONE;
 147        while (!(MMC_I_REG & MMC_I_REG_DATA_TRAN_DONE)) ;
 148        status = MMC_STAT;
 149        if (status & MMC_STAT_ERRORS) {
 150                printf("MMC_STAT error %lx\n", status);
 151                return -1;
 152        }
 153        return 0;
 154}
 155
 156int
 157/****************************************************/
 158mmc_block_write(ulong dst, uchar * src, int len)
 159/****************************************************/
 160{
 161        ushort argh, argl;
 162        ulong status;
 163
 164        if (len == 0) {
 165                return 0;
 166        }
 167
 168        debug("mmc_block_wr dst %lx src %lx len %d\n", dst, (ulong) src, len);
 169
 170        argh = len >> 16;
 171        argl = len & 0xffff;
 172
 173        /* set block len */
 174        mmc_cmd(MMC_CMD_SET_BLOCKLEN, argh, argl, MMC_CMDAT_R1);
 175
 176        /* send write command */
 177        argh = dst >> 16;
 178        argl = dst & 0xffff;
 179        MMC_STRPCL = MMC_STRPCL_STOP_CLK;
 180        MMC_NOB = 1;
 181        MMC_BLKLEN = len;
 182        mmc_cmd(MMC_CMD_WRITE_SINGLE_BLOCK, argh, argl,
 183                MMC_CMDAT_R1 | MMC_CMDAT_WRITE | MMC_CMDAT_BLOCK |
 184                MMC_CMDAT_DATA_EN);
 185
 186        MMC_I_MASK = ~MMC_I_MASK_TXFIFO_WR_REQ;
 187        while (len) {
 188                if (MMC_I_REG & MMC_I_REG_TXFIFO_WR_REQ) {
 189                        int i, bytes = min(32, len);
 190
 191                        for (i = 0; i < bytes; i++) {
 192                                MMC_TXFIFO = *src++;
 193                        }
 194                        if (bytes < 32) {
 195                                MMC_PRTBUF = MMC_PRTBUF_BUF_PART_FULL;
 196                        }
 197                        len -= bytes;
 198                }
 199                status = MMC_STAT;
 200                if (status & MMC_STAT_ERRORS) {
 201                        printf("MMC_STAT error %lx\n", status);
 202                        return -1;
 203                }
 204        }
 205        MMC_I_MASK = ~MMC_I_MASK_DATA_TRAN_DONE;
 206        while (!(MMC_I_REG & MMC_I_REG_DATA_TRAN_DONE)) ;
 207        MMC_I_MASK = ~MMC_I_MASK_PRG_DONE;
 208        while (!(MMC_I_REG & MMC_I_REG_PRG_DONE)) ;
 209        status = MMC_STAT;
 210        if (status & MMC_STAT_ERRORS) {
 211                printf("MMC_STAT error %lx\n", status);
 212                return -1;
 213        }
 214        return 0;
 215}
 216
 217int
 218/****************************************************/
 219pxa_mmc_read(long src, uchar * dst, int size)
 220/****************************************************/
 221{
 222        ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
 223        ulong mmc_block_size, mmc_block_address;
 224
 225        if (size == 0) {
 226                return 0;
 227        }
 228
 229        if (!mmc_ready) {
 230                printf("Please initial the MMC first\n");
 231                return -1;
 232        }
 233
 234        mmc_block_size = MMC_BLOCK_SIZE;
 235        mmc_block_address = ~(mmc_block_size - 1);
 236
 237        src -= CONFIG_SYS_MMC_BASE;
 238        end = src + size;
 239        part_start = ~mmc_block_address & src;
 240        part_end = ~mmc_block_address & end;
 241        aligned_start = mmc_block_address & src;
 242        aligned_end = mmc_block_address & end;
 243
 244        /* all block aligned accesses */
 245        debug
 246            ("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
 247             src, (ulong) dst, end, part_start, part_end, aligned_start,
 248             aligned_end);
 249        if (part_start) {
 250                part_len = mmc_block_size - part_start;
 251                debug
 252                    ("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
 253                     src, (ulong) dst, end, part_start, part_end, aligned_start,
 254                     aligned_end);
 255                if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) <
 256                    0) {
 257                        return -1;
 258                }
 259                memcpy(dst, mmc_buf + part_start, part_len);
 260                dst += part_len;
 261                src += part_len;
 262        }
 263        debug
 264            ("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
 265             src, (ulong) dst, end, part_start, part_end, aligned_start,
 266             aligned_end);
 267        for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
 268                debug
 269                    ("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
 270                     src, (ulong) dst, end, part_start, part_end, aligned_start,
 271                     aligned_end);
 272                if ((mmc_block_read((uchar *) (dst), src, mmc_block_size)) < 0) {
 273                        return -1;
 274                }
 275        }
 276        debug
 277            ("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
 278             src, (ulong) dst, end, part_start, part_end, aligned_start,
 279             aligned_end);
 280        if (part_end && src < end) {
 281                debug
 282                    ("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
 283                     src, (ulong) dst, end, part_start, part_end, aligned_start,
 284                     aligned_end);
 285                if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
 286                        return -1;
 287                }
 288                memcpy(dst, mmc_buf, part_end);
 289        }
 290        return 0;
 291}
 292
 293int
 294/****************************************************/
 295pxa_mmc_write(uchar * src, ulong dst, int size)
 296/****************************************************/
 297{
 298        ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
 299        ulong mmc_block_size, mmc_block_address;
 300
 301        if (size == 0) {
 302                return 0;
 303        }
 304
 305        if (!mmc_ready) {
 306                printf("Please initial the MMC first\n");
 307                return -1;
 308        }
 309
 310        mmc_block_size = MMC_BLOCK_SIZE;
 311        mmc_block_address = ~(mmc_block_size - 1);
 312
 313        dst -= CONFIG_SYS_MMC_BASE;
 314        end = dst + size;
 315        part_start = ~mmc_block_address & dst;
 316        part_end = ~mmc_block_address & end;
 317        aligned_start = mmc_block_address & dst;
 318        aligned_end = mmc_block_address & end;
 319
 320        /* all block aligned accesses */
 321        debug
 322            ("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
 323             src, (ulong) dst, end, part_start, part_end, aligned_start,
 324             aligned_end);
 325        if (part_start) {
 326                part_len = mmc_block_size - part_start;
 327                debug
 328                    ("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
 329                     (ulong) src, dst, end, part_start, part_end, aligned_start,
 330                     aligned_end);
 331                if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) <
 332                    0) {
 333                        return -1;
 334                }
 335                memcpy(mmc_buf + part_start, src, part_len);
 336                if ((mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) <
 337                    0) {
 338                        return -1;
 339                }
 340                dst += part_len;
 341                src += part_len;
 342        }
 343        debug
 344            ("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
 345             src, (ulong) dst, end, part_start, part_end, aligned_start,
 346             aligned_end);
 347        for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
 348                debug
 349                    ("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
 350                     src, (ulong) dst, end, part_start, part_end, aligned_start,
 351                     aligned_end);
 352                if ((mmc_block_write(dst, (uchar *) src, mmc_block_size)) < 0) {
 353                        return -1;
 354                }
 355        }
 356        debug
 357            ("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
 358             src, (ulong) dst, end, part_start, part_end, aligned_start,
 359             aligned_end);
 360        if (part_end && dst < end) {
 361                debug
 362                    ("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
 363                     src, (ulong) dst, end, part_start, part_end, aligned_start,
 364                     aligned_end);
 365                if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
 366                        return -1;
 367                }
 368                memcpy(mmc_buf, src, part_end);
 369                if ((mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0) {
 370                        return -1;
 371                }
 372        }
 373        return 0;
 374}
 375
 376static ulong
 377/****************************************************/
 378mmc_bread(int dev_num, ulong blknr, lbaint_t blkcnt, void *dst)
 379/****************************************************/
 380{
 381        int mmc_block_size = MMC_BLOCK_SIZE;
 382        ulong src = blknr * mmc_block_size + CONFIG_SYS_MMC_BASE;
 383
 384        pxa_mmc_read(src, (uchar *) dst, blkcnt * mmc_block_size);
 385        return blkcnt;
 386}
 387
 388#ifdef __GNUC__
 389#define likely(x)       __builtin_expect(!!(x), 1)
 390#define unlikely(x)     __builtin_expect(!!(x), 0)
 391#else
 392#define likely(x)       (x)
 393#define unlikely(x)     (x)
 394#endif
 395
 396#define UNSTUFF_BITS(resp,start,size)                                   \
 397        ({                                                              \
 398                const int __size = size;                                \
 399                const uint32_t __mask = (__size < 32 ? 1 << __size : 0) - 1;    \
 400                const int32_t __off = 3 - ((start) / 32);                       \
 401                const int32_t __shft = (start) & 31;                    \
 402                uint32_t __res;                                         \
 403                                                                        \
 404                __res = resp[__off] >> __shft;                          \
 405                if (__size + __shft > 32)                               \
 406                        __res |= resp[__off-1] << ((32 - __shft) % 32); \
 407                __res & __mask;                                         \
 408        })
 409
 410/*
 411 * Given the decoded CSD structure, decode the raw CID to our CID structure.
 412 */
 413static void mmc_decode_cid(uint32_t * resp)
 414{
 415        if (IF_TYPE_SD == mmc_dev.if_type) {
 416                /*
 417                 * SD doesn't currently have a version field so we will
 418                 * have to assume we can parse this.
 419                 */
 420                sprintf((char *)mmc_dev.vendor,
 421                        "Man %02x OEM %c%c \"%c%c%c%c%c\" Date %02u/%04u",
 422                        UNSTUFF_BITS(resp, 120, 8), UNSTUFF_BITS(resp, 112, 8),
 423                        UNSTUFF_BITS(resp, 104, 8), UNSTUFF_BITS(resp, 96, 8),
 424                        UNSTUFF_BITS(resp, 88, 8), UNSTUFF_BITS(resp, 80, 8),
 425                        UNSTUFF_BITS(resp, 72, 8), UNSTUFF_BITS(resp, 64, 8),
 426                        UNSTUFF_BITS(resp, 8, 4), UNSTUFF_BITS(resp, 12,
 427                                                               8) + 2000);
 428                sprintf((char *)mmc_dev.revision, "%d.%d",
 429                        UNSTUFF_BITS(resp, 60, 4), UNSTUFF_BITS(resp, 56, 4));
 430                sprintf((char *)mmc_dev.product, "%u",
 431                        UNSTUFF_BITS(resp, 24, 32));
 432        } else {
 433                /*
 434                 * The selection of the format here is based upon published
 435                 * specs from sandisk and from what people have reported.
 436                 */
 437                switch (spec_ver) {
 438                case 0: /* MMC v1.0 - v1.2 */
 439                case 1: /* MMC v1.4 */
 440                        sprintf((char *)mmc_dev.vendor,
 441                                "Man %02x%02x%02x \"%c%c%c%c%c%c%c\" Date %02u/%04u",
 442                                UNSTUFF_BITS(resp, 120, 8), UNSTUFF_BITS(resp,
 443                                                                         112,
 444                                                                         8),
 445                                UNSTUFF_BITS(resp, 104, 8), UNSTUFF_BITS(resp,
 446                                                                         96, 8),
 447                                UNSTUFF_BITS(resp, 88, 8), UNSTUFF_BITS(resp,
 448                                                                        80, 8),
 449                                UNSTUFF_BITS(resp, 72, 8), UNSTUFF_BITS(resp,
 450                                                                        64, 8),
 451                                UNSTUFF_BITS(resp, 56, 8), UNSTUFF_BITS(resp,
 452                                                                        48, 8),
 453                                UNSTUFF_BITS(resp, 12, 4), UNSTUFF_BITS(resp, 8,
 454                                                                        4) +
 455                                1997);
 456                        sprintf((char *)mmc_dev.revision, "%d.%d",
 457                                UNSTUFF_BITS(resp, 44, 4), UNSTUFF_BITS(resp,
 458                                                                        40, 4));
 459                        sprintf((char *)mmc_dev.product, "%u",
 460                                UNSTUFF_BITS(resp, 16, 24));
 461                        break;
 462
 463                case 2: /* MMC v2.0 - v2.2 */
 464                case 3: /* MMC v3.1 - v3.3 */
 465                case 4: /* MMC v4 */
 466                        sprintf((char *)mmc_dev.vendor,
 467                                "Man %02x OEM %04x \"%c%c%c%c%c%c\" Date %02u/%04u",
 468                                UNSTUFF_BITS(resp, 120, 8), UNSTUFF_BITS(resp,
 469                                                                         104,
 470                                                                         16),
 471                                UNSTUFF_BITS(resp, 96, 8), UNSTUFF_BITS(resp,
 472                                                                        88, 8),
 473                                UNSTUFF_BITS(resp, 80, 8), UNSTUFF_BITS(resp,
 474                                                                        72, 8),
 475                                UNSTUFF_BITS(resp, 64, 8), UNSTUFF_BITS(resp,
 476                                                                        56, 8),
 477                                UNSTUFF_BITS(resp, 12, 4), UNSTUFF_BITS(resp, 8,
 478                                                                        4) +
 479                                1997);
 480                        sprintf((char *)mmc_dev.product, "%u",
 481                                UNSTUFF_BITS(resp, 16, 32));
 482                        sprintf((char *)mmc_dev.revision, "N/A");
 483                        break;
 484
 485                default:
 486                        printf("MMC card has unknown MMCA version %d\n",
 487                               spec_ver);
 488                        break;
 489                }
 490        }
 491        printf("%s card.\nVendor: %s\nProduct: %s\nRevision: %s\n",
 492               (IF_TYPE_SD == mmc_dev.if_type) ? "SD" : "MMC", mmc_dev.vendor,
 493               mmc_dev.product, mmc_dev.revision);
 494}
 495
 496/*
 497 * Given a 128-bit response, decode to our card CSD structure.
 498 */
 499static void mmc_decode_csd(uint32_t * resp)
 500{
 501        unsigned int mult, csd_struct;
 502
 503        if (IF_TYPE_SD == mmc_dev.if_type) {
 504                csd_struct = UNSTUFF_BITS(resp, 126, 2);
 505                if (csd_struct != 0) {
 506                        printf("SD: unrecognised CSD structure version %d\n",
 507                               csd_struct);
 508                        return;
 509                }
 510        } else {
 511                /*
 512                 * We only understand CSD structure v1.1 and v1.2.
 513                 * v1.2 has extra information in bits 15, 11 and 10.
 514                 */
 515                csd_struct = UNSTUFF_BITS(resp, 126, 2);
 516                if (csd_struct != 1 && csd_struct != 2) {
 517                        printf("MMC: unrecognised CSD structure version %d\n",
 518                               csd_struct);
 519                        return;
 520                }
 521
 522                spec_ver = UNSTUFF_BITS(resp, 122, 4);
 523                mmc_dev.if_type = IF_TYPE_MMC;
 524        }
 525
 526        mult = 1 << (UNSTUFF_BITS(resp, 47, 3) + 2);
 527        mmc_dev.lba = (1 + UNSTUFF_BITS(resp, 62, 12)) * mult;
 528        mmc_dev.blksz = 1 << UNSTUFF_BITS(resp, 80, 4);
 529
 530        /* FIXME: The following just makes assumes that's the partition type -- should really read it */
 531        mmc_dev.part_type = PART_TYPE_DOS;
 532        mmc_dev.dev = 0;
 533        mmc_dev.lun = 0;
 534        mmc_dev.type = DEV_TYPE_HARDDISK;
 535        mmc_dev.removable = 0;
 536        mmc_dev.block_read = mmc_bread;
 537
 538        printf("Detected: %lu blocks of %lu bytes (%luMB) ",
 539                mmc_dev.lba,
 540                mmc_dev.blksz,
 541                mmc_dev.lba * mmc_dev.blksz / (1024 * 1024));
 542}
 543
 544int
 545/****************************************************/
 546mmc_legacy_init(int verbose)
 547/****************************************************/
 548{
 549        int retries, rc = -ENODEV;
 550        uint32_t cid_resp[4];
 551        uint32_t *resp;
 552        uint16_t rca = 0;
 553
 554        /* Reset device interface type */
 555        mmc_dev.if_type = IF_TYPE_UNKNOWN;
 556
 557#if defined (CONFIG_LUBBOCK) || (defined (CONFIG_GUMSTIX) && !defined(CONFIG_PXA27X))
 558        set_GPIO_mode(GPIO6_MMCCLK_MD);
 559        set_GPIO_mode(GPIO8_MMCCS0_MD);
 560#endif
 561        CKEN |= CKEN12_MMC;     /* enable MMC unit clock */
 562
 563        MMC_CLKRT = MMC_CLKRT_0_3125MHZ;
 564        MMC_RESTO = MMC_RES_TO_MAX;
 565        MMC_SPI = MMC_SPI_DISABLE;
 566
 567        /* reset */
 568        mmc_cmd(MMC_CMD_GO_IDLE_STATE, 0, 0, MMC_CMDAT_INIT | MMC_CMDAT_R0);
 569        udelay(200000);
 570        retries = 3;
 571        while (retries--) {
 572                resp = mmc_cmd(MMC_CMD_APP_CMD, 0, 0, MMC_CMDAT_R1);
 573                if (!(resp[0] & 0x00000020)) {  /* Card does not support APP_CMD */
 574                        debug("Card does not support APP_CMD\n");
 575                        break;
 576                }
 577
 578                /* Select 3.2-3.3V and 3.3-3.4V */
 579                resp = mmc_cmd(SD_CMD_APP_SEND_OP_COND, 0x0030, 0x0000,
 580                                MMC_CMDAT_R3 | (retries < 2 ? 0
 581                                        : MMC_CMDAT_INIT));
 582                if (resp[0] & 0x80000000) {
 583                        mmc_dev.if_type = IF_TYPE_SD;
 584                        debug("Detected SD card\n");
 585                        break;
 586                }
 587#ifdef CONFIG_PXA27X
 588                udelay(10000);
 589#else
 590                udelay(200000);
 591#endif
 592        }
 593
 594        if (retries <= 0 || !(IF_TYPE_SD == mmc_dev.if_type)) {
 595                debug("Failed to detect SD Card, trying MMC\n");
 596                resp =
 597                    mmc_cmd(MMC_CMD_SEND_OP_COND, 0x00ff, 0x8000, MMC_CMDAT_R3);
 598
 599                retries = 10;
 600                while (retries-- && resp && !(resp[0] & 0x80000000)) {
 601#ifdef CONFIG_PXA27X
 602                        udelay(10000);
 603#else
 604                        udelay(200000);
 605#endif
 606                        resp =
 607                            mmc_cmd(MMC_CMD_SEND_OP_COND, 0x00ff, 0x8000,
 608                                    MMC_CMDAT_R3);
 609                }
 610        }
 611
 612        /* try to get card id */
 613        resp =
 614            mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, 0, MMC_CMDAT_R2 | MMC_CMDAT_BUSY);
 615        if (resp) {
 616                memcpy(cid_resp, resp, sizeof(cid_resp));
 617
 618                /* MMC exists, get CSD too */
 619                resp = mmc_cmd(MMC_CMD_SET_RELATIVE_ADDR, 0, 0, MMC_CMDAT_R1);
 620                if (IF_TYPE_SD == mmc_dev.if_type)
 621                        rca = ((resp[0] & 0xffff0000) >> 16);
 622                resp = mmc_cmd(MMC_CMD_SEND_CSD, rca, 0, MMC_CMDAT_R2);
 623                if (resp) {
 624                        mmc_decode_csd(resp);
 625                        rc = 0;
 626                        mmc_ready = 1;
 627                }
 628
 629                mmc_decode_cid(cid_resp);
 630        }
 631
 632        MMC_CLKRT = 0;          /* 20 MHz */
 633        resp = mmc_cmd(MMC_CMD_SELECT_CARD, rca, 0, MMC_CMDAT_R1);
 634
 635#ifdef CONFIG_PXA27X
 636        if (IF_TYPE_SD == mmc_dev.if_type) {
 637                resp = mmc_cmd(MMC_CMD_APP_CMD, rca, 0, MMC_CMDAT_R1);
 638                resp = mmc_cmd(SD_CMD_APP_SET_BUS_WIDTH, 0, 2, MMC_CMDAT_R1);
 639                wide = MMC_CMDAT_SD_4DAT;
 640        }
 641#endif
 642
 643        fat_register_device(&mmc_dev, 1);       /* partitions start counting with 1 */
 644
 645        return rc;
 646}
 647