]> git.sur5r.net Git - u-boot/blobdiff - cpu/pxa/mmc.c
* Patches by Robert Whaley, 29 Nov 2004:
[u-boot] / cpu / pxa / mmc.c
index 4495962976b917c61f3dca24eda459bd53e1e00e..f7020eec951398fadc349d4e40df67c93ee19d3d 100644 (file)
@@ -72,13 +72,11 @@ mmc_cmd(ushort cmd, ushort argh, ushort argl, ushort cmdat)
 
        status = MMC_STAT;
        debug("MMC status %x\n", status);
-       if (status & MMC_STAT_TIME_OUT_RESPONSE)
-       {
+       if (status & MMC_STAT_TIME_OUT_RESPONSE) {
                return 0;
        }
 
-       switch (cmdat & 0x3)
-       {
+       switch (cmdat & 0x3) {
                case MMC_CMDAT_R1:
                case MMC_CMDAT_R3:
                        words = 3;
@@ -91,8 +89,7 @@ mmc_cmd(ushort cmd, ushort argh, ushort argl, ushort cmdat)
                default:
                        return 0;
        }
-       for (i = words-1; i >= 0; i--)
-       {
+       for (i = words-1; i >= 0; i--) {
                ulong res_fifo = MMC_RES;
                int offset = i << 1;
 
@@ -100,8 +97,7 @@ mmc_cmd(ushort cmd, ushort argh, ushort argl, ushort cmdat)
                resp[offset+1] = ((uchar *)&res_fifo)[1];
        }
 #ifdef MMC_DEBUG
-       for (i=0; i<words*2; i += 2)
-       {
+       for (i=0; i<words*2; i += 2) {
                printf("MMC resp[%d] = %02x\n", i, resp[i]);
                printf("MMC resp[%d] = %02x\n", i+1, resp[i+1]);
        }
@@ -118,8 +114,7 @@ mmc_block_read(uchar *dst, ulong src, ulong len)
        ushort argh, argl;
        ulong status;
 
-       if (len == 0)
-       {
+       if (len == 0) {
                return 0;
        }
 
@@ -143,16 +138,21 @@ mmc_block_read(uchar *dst, ulong src, ulong len)
 
 
        MMC_I_MASK = ~MMC_I_MASK_RXFIFO_RD_REQ;
-       while (len)
-       {
-               if (MMC_I_REG & MMC_I_REG_RXFIFO_RD_REQ)
-               {
+       while (len) {
+               if (MMC_I_REG & MMC_I_REG_RXFIFO_RD_REQ) {
+#ifdef CONFIG_PXA27X
+                       int i;
+                       for (i=min(len,32); i; i--) {
+                               *dst++ = * ((volatile uchar *) &MMC_RXFIFO);
+                               len--;
+                       }
+#else
                        *dst++ = MMC_RXFIFO;
                        len--;
+#endif
                }
                status = MMC_STAT;
-               if (status & MMC_STAT_ERRORS)
-               {
+               if (status & MMC_STAT_ERRORS) {
                        printf("MMC_STAT error %lx\n", status);
                        return -1;
                }
@@ -160,8 +160,7 @@ mmc_block_read(uchar *dst, ulong src, ulong len)
        MMC_I_MASK = ~MMC_I_MASK_DATA_TRAN_DONE;
        while (!(MMC_I_REG & MMC_I_REG_DATA_TRAN_DONE));
        status = MMC_STAT;
-       if (status & MMC_STAT_ERRORS)
-       {
+       if (status & MMC_STAT_ERRORS) {
                printf("MMC_STAT error %lx\n", status);
                return -1;
        }
@@ -177,8 +176,7 @@ mmc_block_write(ulong dst, uchar *src, int len)
        ushort argh, argl;
        ulong status;
 
-       if (len == 0)
-       {
+       if (len == 0) {
                return 0;
        }
 
@@ -200,25 +198,20 @@ mmc_block_write(ulong dst, uchar *src, int len)
                        MMC_CMDAT_R1|MMC_CMDAT_WRITE|MMC_CMDAT_BLOCK|MMC_CMDAT_DATA_EN);
 
        MMC_I_MASK = ~MMC_I_MASK_TXFIFO_WR_REQ;
-       while (len)
-       {
-               if (MMC_I_REG & MMC_I_REG_TXFIFO_WR_REQ)
-               {
+       while (len) {
+               if (MMC_I_REG & MMC_I_REG_TXFIFO_WR_REQ) {
                        int i, bytes = min(32,len);
 
-                       for (i=0; i<bytes; i++)
-                       {
+                       for (i=0; i<bytes; i++) {
                                MMC_TXFIFO = *src++;
                        }
-                       if (bytes < 32)
-                       {
+                       if (bytes < 32) {
                                MMC_PRTBUF = MMC_PRTBUF_BUF_PART_FULL;
                        }
                        len -= bytes;
                }
                status = MMC_STAT;
-               if (status & MMC_STAT_ERRORS)
-               {
+               if (status & MMC_STAT_ERRORS) {
                        printf("MMC_STAT error %lx\n", status);
                        return -1;
                }
@@ -228,8 +221,7 @@ mmc_block_write(ulong dst, uchar *src, int len)
        MMC_I_MASK = ~MMC_I_MASK_PRG_DONE;
        while (!(MMC_I_REG & MMC_I_REG_PRG_DONE));
        status = MMC_STAT;
-       if (status & MMC_STAT_ERRORS)
-       {
+       if (status & MMC_STAT_ERRORS) {
                printf("MMC_STAT error %lx\n", status);
                return -1;
        }
@@ -245,13 +237,11 @@ mmc_read(ulong src, uchar *dst, int size)
        ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
        ulong mmc_block_size, mmc_block_address;
 
-       if (size == 0)
-       {
+       if (size == 0) {
                return 0;
        }
 
-       if (!mmc_ready)
-       {
+       if (!mmc_ready) {
                printf("Please initial the MMC first\n");
                return -1;
        }
@@ -269,13 +259,11 @@ mmc_read(ulong src, uchar *dst, int size)
        /* all block aligned accesses */
        debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
-       if (part_start)
-       {
+       if (part_start) {
                part_len = mmc_block_size - part_start;
                debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
                src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
-               if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
-               {
+               if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
                        return -1;
                }
                memcpy(dst, mmc_buf+part_start, part_len);
@@ -284,23 +272,19 @@ mmc_read(ulong src, uchar *dst, int size)
        }
        debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
-       for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size)
-       {
+       for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
                debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
                src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
-               if ((mmc_block_read((uchar *)(dst), src, mmc_block_size)) < 0)
-               {
+               if ((mmc_block_read((uchar *)(dst), src, mmc_block_size)) < 0) {
                        return -1;
                }
        }
        debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
-       if (part_end && src < end)
-       {
+       if (part_end && src < end) {
                debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
                src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
-               if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
-               {
+               if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
                        return -1;
                }
                memcpy(dst, mmc_buf, part_end);
@@ -316,13 +300,11 @@ mmc_write(uchar *src, ulong dst, int size)
        ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
        ulong mmc_block_size, mmc_block_address;
 
-       if (size == 0)
-       {
+       if (size == 0) {
                return 0;
        }
 
-       if (!mmc_ready)
-       {
+       if (!mmc_ready) {
                printf("Please initial the MMC first\n");
                return -1;
        }
@@ -340,18 +322,15 @@ mmc_write(uchar *src, ulong dst, int size)
        /* all block aligned accesses */
        debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
-       if (part_start)
-       {
+       if (part_start) {
                part_len = mmc_block_size - part_start;
                debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
                (ulong)src, dst, end, part_start, part_end, aligned_start, aligned_end);
-               if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
-               {
+               if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
                        return -1;
                }
                memcpy(mmc_buf+part_start, src, part_len);
-               if ((mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) < 0)
-               {
+               if ((mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) < 0) {
                        return -1;
                }
                dst += part_len;
@@ -359,28 +338,23 @@ mmc_write(uchar *src, ulong dst, int size)
        }
        debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
-       for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size)
-       {
+       for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
                debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
                src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
-               if ((mmc_block_write(dst, (uchar *)src, mmc_block_size)) < 0)
-               {
+               if ((mmc_block_write(dst, (uchar *)src, mmc_block_size)) < 0) {
                        return -1;
                }
        }
        debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
-       if (part_end && dst < end)
-       {
+       if (part_end && dst < end) {
                debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
                src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
-               if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
-               {
+               if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
                        return -1;
                }
                memcpy(mmc_buf, src, part_end);
-               if ((mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0)
-               {
+               if ((mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0) {
                        return -1;
                }
        }
@@ -412,6 +386,11 @@ mmc_init(int verbose)
        set_GPIO_mode( GPIO8_MMCCS0_MD );
 #endif
        CKEN |= CKEN12_MMC; /* enable MMC unit clock */
+#if defined(CONFIG_ADSVIX)
+       /* turn on the power */
+       GPCR(114) = GPIO_bit(114);
+       udelay(1000);
+#endif
 
        mmc_csd.c_size = 0;
 
@@ -423,21 +402,22 @@ mmc_init(int verbose)
        retries = 10;
        resp = mmc_cmd(0, 0, 0, 0);
        resp = mmc_cmd(1, 0x00ff, 0xc000, MMC_CMDAT_INIT|MMC_CMDAT_BUSY|MMC_CMDAT_R3);
-       while (retries-- && resp && !(resp[4] & 0x80))
-       {
+       while (retries-- && resp && !(resp[4] & 0x80)) {
                debug("resp %x %x\n", resp[0], resp[1]);
+#ifdef CONFIG_PXA27X
+               udelay(10000);
+#else
                udelay(50);
+#endif
                resp = mmc_cmd(1, 0x00ff, 0xff00, MMC_CMDAT_BUSY|MMC_CMDAT_R3);
        }
 
        /* try to get card id */
        resp = mmc_cmd(2, 0, 0, MMC_CMDAT_R2);
-       if (resp)
-       {
+       if (resp) {
                /* TODO configure mmc driver depending on card attributes */
                mmc_cid_t *cid = (mmc_cid_t *)resp;
-               if (verbose)
-               {
+               if (verbose) {
                        printf("MMC found. Card desciption is:\n");
                        printf("Manufacturer ID = %02x%02x%02x\n",
                                                        cid->id[0], cid->id[1], cid->id[2]);
@@ -451,6 +431,7 @@ mmc_init(int verbose)
                }
                /* fill in device description */
                mmc_dev.if_type = IF_TYPE_MMC;
+               mmc_dev.part_type = PART_TYPE_DOS;
                mmc_dev.dev = 0;
                mmc_dev.lun = 0;
                mmc_dev.type = 0;
@@ -468,8 +449,7 @@ mmc_init(int verbose)
                /* MMC exists, get CSD too */
                resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
                resp = mmc_cmd(MMC_CMD_SEND_CSD, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R2);
-               if (resp)
-               {
+               if (resp) {
                        mmc_csd_t *csd = (mmc_csd_t *)resp;
                        memcpy(&mmc_csd, csd, sizeof(csd));
                        rc = 0;
@@ -478,7 +458,11 @@ mmc_init(int verbose)
                }
        }
 
+#ifdef CONFIG_PXA27X
+       MMC_CLKRT = 1;  /* 10 MHz - see Intel errata */
+#else
        MMC_CLKRT = 0;  /* 20 MHz */
+#endif
        resp = mmc_cmd(7, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
 
        fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
@@ -496,11 +480,10 @@ int
 mmc2info(ulong addr)
 {
        /* FIXME hard codes to 32 MB device */
-       if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000)
-       {
+       if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000) {
                return 1;
        }
        return 0;
 }
 
-#endif
+#endif /* CONFIG_MMC */