summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorAnton Staaf <robotboy@chromium.org>2011-06-08 15:09:19 -0700
committerSimon Glass <sjg@chromium.org>2011-08-29 10:39:19 -0700
commit765e76db107dbaa22e08b32cfd36dbe1b44071ac (patch)
tree3c2bbca6bbdf8af6ef09e8cc1bac34d7d71c4818 /drivers/mmc
parentd62fa9e34bf6db994ec7054412e7239aaec77259 (diff)
mmc: Cache line align buffers
This is required to avoid bounce buffers on ARM. BUG=chromium-os:16317 TEST=run "mmc part 0" and "ext2ls mmc 0:3" on Seaboard Change-Id: I75fd03140d8b36f8e2816d180d915676fe2cc612 Reviewed-on: http://gerrit.chromium.org/gerrit/2326 Tested-by: Anton Staaf <robotboy@chromium.org> Reviewed-by: Tom Warren <twarren@nvidia.com> Reviewed-by: Anton Staaf <robotboy@chromium.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/mmc.c76
1 files changed, 48 insertions, 28 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 21aedbaa3fe..5d161b21717 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -36,6 +36,9 @@
#ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
#define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535
#endif
+#ifndef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE __BIGGEST_ALIGNMENT__
+#endif
static struct list_head mmc_devices;
static int cur_dev_num = -1;
@@ -531,9 +534,12 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
int mmc_change_freq(struct mmc *mmc)
{
- char ext_csd[512];
+ char *ext_csd = memalign(CACHE_LINE_SIZE, 512);
char cardtype;
- int err;
+ int err = 0;
+
+ if (ext_csd == NULL)
+ return -1;
mmc->card_caps = 0;
@@ -542,31 +548,31 @@ int mmc_change_freq(struct mmc *mmc)
/* Only version 4 supports high-speed */
if (mmc->version < MMC_VERSION_4)
- return 0;
+ goto out;
mmc->card_caps |= MMC_MODE_4BIT;
err = mmc_send_ext_csd(mmc, ext_csd);
if (err)
- return err;
+ goto failure;
cardtype = ext_csd[196] & 0xf;
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
if (err)
- return err;
+ goto failure;
/* Now check to see that it worked */
err = mmc_send_ext_csd(mmc, ext_csd);
if (err)
- return err;
+ goto failure;
/* No high-speed support */
if (!ext_csd[185])
- return 0;
+ goto out;
/* High Speed is set, there are two types: 52MHz and 26MHz */
if (cardtype & MMC_HS_52MHZ)
@@ -574,7 +580,11 @@ int mmc_change_freq(struct mmc *mmc)
else
mmc->card_caps |= MMC_MODE_HS;
- return 0;
+out:
+failure:
+ free(ext_csd);
+
+ return err;
}
int mmc_switch_part(int dev_num, unsigned int part_num)
@@ -613,13 +623,15 @@ int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
int sd_change_freq(struct mmc *mmc)
{
- int err;
+ int err = 0;
struct mmc_cmd cmd;
- uint scr[2];
- uint switch_status[16];
+ uint *buffer = memalign(CACHE_LINE_SIZE, 64);
struct mmc_data data;
int timeout;
+ if (buffer == NULL)
+ return -1;
+
mmc->card_caps = 0;
if (mmc_host_is_spi(mmc))
@@ -634,7 +646,7 @@ int sd_change_freq(struct mmc *mmc)
err = mmc_send_cmd(mmc, &cmd, NULL);
if (err)
- return err;
+ goto failure;
cmd.cmdidx = SD_CMD_APP_SEND_SCR;
cmd.resp_type = MMC_RSP_R1;
@@ -644,7 +656,7 @@ int sd_change_freq(struct mmc *mmc)
timeout = 3;
retry_scr:
- data.dest = (char *)&scr;
+ data.dest = (char *) buffer;
data.blocksize = 8;
data.blocks = 1;
data.flags = MMC_DATA_READ;
@@ -655,11 +667,11 @@ retry_scr:
if (timeout--)
goto retry_scr;
- return err;
+ goto failure;
}
- mmc->scr[0] = __be32_to_cpu(scr[0]);
- mmc->scr[1] = __be32_to_cpu(scr[1]);
+ mmc->scr[0] = __be32_to_cpu(buffer[0]);
+ mmc->scr[1] = __be32_to_cpu(buffer[1]);
switch ((mmc->scr[0] >> 24) & 0xf) {
case 0:
@@ -681,34 +693,37 @@ retry_scr:
/* Version 1.0 doesn't support switching */
if (mmc->version == SD_VERSION_1_0)
- return 0;
+ goto out;
timeout = 4;
while (timeout--) {
- err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
- (u8 *)&switch_status);
+ err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1, (u8 *)buffer);
if (err)
- return err;
+ goto failure;
/* The high-speed function is busy. Try again */
- if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
+ if (!(__be32_to_cpu(buffer[7]) & SD_HIGHSPEED_BUSY))
break;
}
/* If high-speed isn't supported, we return */
- if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
- return 0;
+ if (!(__be32_to_cpu(buffer[3]) & SD_HIGHSPEED_SUPPORTED))
+ goto out;
- err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)&switch_status);
+ err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)&buffer);
if (err)
- return err;
+ goto failure;
- if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
+ if ((__be32_to_cpu(buffer[4]) & 0x0f000000) == 0x01000000)
mmc->card_caps |= MMC_MODE_HS;
- return 0;
+out:
+failure:
+ free(buffer);
+
+ return err;
}
/* frequency bases */
@@ -773,7 +788,6 @@ int mmc_startup(struct mmc *mmc)
uint mult, freq;
u64 cmult, csize;
struct mmc_cmd cmd;
- char ext_csd[512];
int timeout = 1000;
#ifdef CONFIG_MMC_SPI_CRC_ON
@@ -913,6 +927,11 @@ int mmc_startup(struct mmc *mmc)
mmc->part_config = MMCPART_NOAVAILABLE;
if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
+ char *ext_csd = memalign(CACHE_LINE_SIZE, 512);
+
+ if (ext_csd == NULL)
+ return -1;
+
/* check ext_csd version and capacity */
err = mmc_send_ext_csd(mmc, ext_csd);
if (!err & (ext_csd[192] >= 2)) {
@@ -924,6 +943,7 @@ int mmc_startup(struct mmc *mmc)
/* store the partition info of emmc */
if (ext_csd[160] & PART_SUPPORT)
mmc->part_config = ext_csd[179];
+ free(ext_csd);
}
if (IS_SD(mmc))