diff options
author | wdenk <wdenk> | 2005-04-06 00:04:16 +0000 |
---|---|---|
committer | wdenk <wdenk> | 2005-04-06 00:04:16 +0000 |
commit | 20787e23b8501f11c83599d1a2e38bb1204ac961 (patch) | |
tree | fba53e6f1dd6cb3ca1f030ac47bffbdf3bdbdd1f /cpu/pxa/mmc.c | |
parent | 3c2b3d454daa6024cc20d166b2f50efde169c7fe (diff) |
* Patches by Robert Whaley, 29 Nov 2004:
- update the pxa-regs.h file for PXA27x chips
- add PXA27x based ADSVIX board
- add support for MMC on PXA27x processors
* Patch by Andrew E. Mileski, 28 Nov 2004:
Fix PPC4xx SPD SDRAM detection bug
* Patch by Hiroshi Ito, 26 Nov 2004:
Fix logic of "test -z" and "test -n" commands
Diffstat (limited to 'cpu/pxa/mmc.c')
-rw-r--r-- | cpu/pxa/mmc.c | 141 |
1 files changed, 62 insertions, 79 deletions
diff --git a/cpu/pxa/mmc.c b/cpu/pxa/mmc.c index 4495962976b..f7020eec951 100644 --- a/cpu/pxa/mmc.c +++ b/cpu/pxa/mmc.c @@ -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 */ |