[U-Boot] [PATCH v2] mmc: dcache: Replace ext_csd buffer with cache aligned one
Lukasz Majewski
l.majewski at samsung.com
Wed Aug 17 11:33:47 CEST 2011
This commit replaces the ext_csd buffer allocated as an automatic
variable with one cache aligned. The ext_csd might be allocated with
alignment not equal to the L1 D cache alignment.
The memalign from common/dlmalloc.c is allowing for buffer allocation
with proper cache alignment.
The common/dlmalloc.c [c|m]alloc alignment is hardwired to 8 bytes,
so out of the box functions cannot be safely used with L1 D cache.
Signed-off-by: Lukasz Majewski <l.majewski at samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
CC: Andy Fleming <afleming at gmail.com>
CC: Albert ARIBAUD <albert.u.boot at aribaud.net>
---
Changes for v2:
- Code cleanup - "out" label instead of "error"
---
drivers/mmc/mmc.c | 56 ++++++++++++++++++++++++++++++++--------------------
1 files changed, 34 insertions(+), 22 deletions(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 7e703c0..5f79a17 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -29,6 +29,7 @@
#include <mmc.h>
#include <part.h>
#include <malloc.h>
+#include <errno.h>
#include <linux/list.h>
#include <div64.h>
@@ -617,42 +618,45 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
int mmc_change_freq(struct mmc *mmc)
{
- char ext_csd[512];
char cardtype;
- int err;
+ int err = 0;
+ char *ext_csd = memalign(get_dcache_line_size(), mmc->read_bl_len);
+
+ if (!ext_csd)
+ return -ENOMEM;
mmc->card_caps = 0;
if (mmc_host_is_spi(mmc))
- return 0;
+ goto out;
/* 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 out;
cardtype = ext_csd[196] & 0xf;
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
if (err)
- return err;
+ goto out;
/* Now check to see that it worked */
err = mmc_send_ext_csd(mmc, ext_csd);
if (err)
- return err;
+ goto out;
/* 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)
@@ -660,7 +664,9 @@ int mmc_change_freq(struct mmc *mmc)
else
mmc->card_caps |= MMC_MODE_HS;
- return 0;
+ out:
+ free(ext_csd);
+ return err;
}
int mmc_switch_part(int dev_num, unsigned int part_num)
@@ -855,11 +861,15 @@ void mmc_set_bus_width(struct mmc *mmc, uint width)
int mmc_startup(struct mmc *mmc)
{
- int err;
+ int err = 0;
uint mult, freq;
u64 cmult, csize, capacity;
struct mmc_cmd cmd;
- char ext_csd[512];
+ char *ext_csd = memalign(get_dcache_line_size(), mmc->read_bl_len);
+
+ if (!ext_csd)
+ return -ENOMEM;
+
int timeout = 1000;
#ifdef CONFIG_MMC_SPI_CRC_ON
@@ -871,7 +881,7 @@ int mmc_startup(struct mmc *mmc)
err = mmc_send_cmd(mmc, &cmd, NULL);
if (err)
- return err;
+ goto out;
}
#endif
@@ -885,7 +895,7 @@ int mmc_startup(struct mmc *mmc)
err = mmc_send_cmd(mmc, &cmd, NULL);
if (err)
- return err;
+ goto out;
memcpy(mmc->cid, cmd.response, 16);
@@ -903,7 +913,7 @@ int mmc_startup(struct mmc *mmc)
err = mmc_send_cmd(mmc, &cmd, NULL);
if (err)
- return err;
+ goto out;
if (IS_SD(mmc))
mmc->rca = (cmd.response[0] >> 16) & 0xffff;
@@ -921,7 +931,7 @@ int mmc_startup(struct mmc *mmc)
mmc_send_status(mmc, timeout);
if (err)
- return err;
+ goto out;
mmc->csd[0] = cmd.response[0];
mmc->csd[1] = cmd.response[1];
@@ -994,7 +1004,7 @@ int mmc_startup(struct mmc *mmc)
err = mmc_send_cmd(mmc, &cmd, NULL);
if (err)
- return err;
+ goto out;
}
/*
@@ -1044,7 +1054,7 @@ int mmc_startup(struct mmc *mmc)
err = mmc_change_freq(mmc);
if (err)
- return err;
+ goto out;
/* Restrict card's capabilities by what the host can do */
mmc->card_caps &= mmc->host_caps;
@@ -1058,7 +1068,7 @@ int mmc_startup(struct mmc *mmc)
err = mmc_send_cmd(mmc, &cmd, NULL);
if (err)
- return err;
+ goto out;
cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
cmd.resp_type = MMC_RSP_R1;
@@ -1066,7 +1076,7 @@ int mmc_startup(struct mmc *mmc)
cmd.flags = 0;
err = mmc_send_cmd(mmc, &cmd, NULL);
if (err)
- return err;
+ goto out;
mmc_set_bus_width(mmc, 4);
}
@@ -1083,7 +1093,7 @@ int mmc_startup(struct mmc *mmc)
EXT_CSD_BUS_WIDTH_4);
if (err)
- return err;
+ goto out;
mmc_set_bus_width(mmc, 4);
} else if (mmc->card_caps & MMC_MODE_8BIT) {
@@ -1093,7 +1103,7 @@ int mmc_startup(struct mmc *mmc)
EXT_CSD_BUS_WIDTH_8);
if (err)
- return err;
+ goto out;
mmc_set_bus_width(mmc, 8);
}
@@ -1121,7 +1131,9 @@ int mmc_startup(struct mmc *mmc)
(mmc->cid[2] >> 24) & 0xf);
init_part(&mmc->block_dev);
- return 0;
+ out:
+ free(ext_csd);
+ return err;
}
int mmc_send_if_cond(struct mmc *mmc)
--
1.7.2.3
More information about the U-Boot
mailing list