summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/cmd_mmc.c3
-rw-r--r--drivers/mmc/mmc.c52
-rw-r--r--include/mmc.h1
3 files changed, 34 insertions, 22 deletions
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
index 4286e26963..96478e45c1 100644
--- a/common/cmd_mmc.c
+++ b/common/cmd_mmc.c
@@ -90,7 +90,8 @@ static void print_mmcinfo(struct mmc *mmc)
puts("Capacity: ");
print_size(mmc->capacity, "\n");
- printf("Bus Width: %d-bit\n", mmc->bus_width);
+ printf("Bus Width: %d-bit%s\n", mmc->bus_width,
+ mmc->ddr_mode ? " DDR" : "");
}
static struct mmc *init_mmc_device(int dev, bool force_init)
{
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 99f03c9101..a290031d17 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -159,7 +159,7 @@ int mmc_set_blocklen(struct mmc *mmc, int len)
{
struct mmc_cmd cmd;
- if (mmc->card_caps & MMC_MODE_DDR_52MHz)
+ if (mmc->ddr_mode)
return 0;
cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
@@ -486,7 +486,7 @@ static int mmc_change_freq(struct mmc *mmc)
char cardtype;
int err;
- mmc->card_caps = 0;
+ mmc->card_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
if (mmc_host_is_spi(mmc))
return 0;
@@ -1121,8 +1121,10 @@ static int mmc_startup(struct mmc *mmc)
/* An array to map CSD bus widths to host cap bits */
static unsigned ext_to_hostcaps[] = {
- [EXT_CSD_DDR_BUS_WIDTH_4] = MMC_MODE_DDR_52MHz,
- [EXT_CSD_DDR_BUS_WIDTH_8] = MMC_MODE_DDR_52MHz,
+ [EXT_CSD_DDR_BUS_WIDTH_4] =
+ MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
+ [EXT_CSD_DDR_BUS_WIDTH_8] =
+ MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
[EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
[EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
};
@@ -1134,13 +1136,13 @@ static int mmc_startup(struct mmc *mmc)
for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
unsigned int extw = ext_csd_bits[idx];
+ unsigned int caps = ext_to_hostcaps[extw];
/*
- * Check to make sure the controller supports
- * this bus width, if it's more than 1
+ * Check to make sure the card and controller support
+ * these capabilities
*/
- if (extw != EXT_CSD_BUS_WIDTH_1 &&
- !(mmc->cfg->host_caps & ext_to_hostcaps[extw]))
+ if ((mmc->card_caps & caps) != caps)
continue;
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
@@ -1149,26 +1151,33 @@ static int mmc_startup(struct mmc *mmc)
if (err)
continue;
+ mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
mmc_set_bus_width(mmc, widths[idx]);
err = mmc_send_ext_csd(mmc, test_csd);
+
+ if (err)
+ continue;
+
/* Only compare read only fields */
- if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
- == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
- && ext_csd[EXT_CSD_HC_WP_GRP_SIZE] \
- == test_csd[EXT_CSD_HC_WP_GRP_SIZE] \
- && ext_csd[EXT_CSD_REV] \
- == test_csd[EXT_CSD_REV]
- && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
- == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
- && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
- &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
-
- mmc->card_caps |= ext_to_hostcaps[extw];
+ if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
+ == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
+ ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
+ == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
+ ext_csd[EXT_CSD_REV]
+ == test_csd[EXT_CSD_REV] &&
+ ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
+ == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
+ memcmp(&ext_csd[EXT_CSD_SEC_CNT],
+ &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
break;
- }
+ else
+ err = SWITCH_ERR;
}
+ if (err)
+ return err;
+
if (mmc->card_caps & MMC_MODE_HS) {
if (mmc->card_caps & MMC_MODE_HS_52MHz)
mmc->tran_speed = 52000000;
@@ -1324,6 +1333,7 @@ int mmc_start_init(struct mmc *mmc)
if (err)
return err;
+ mmc->ddr_mode = 0;
mmc_set_bus_width(mmc, 1);
mmc_set_clock(mmc, 1);
diff --git a/include/mmc.h b/include/mmc.h
index fcea195ea5..7ec255d882 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -318,6 +318,7 @@ struct mmc {
char init_in_progress; /* 1 if we have done mmc_start_init() */
char preinit; /* start init as early as possible */
uint op_cond_response; /* the response byte from the last op_cond */
+ int ddr_mode;
};
int mmc_register(struct mmc *mmc);
OpenPOWER on IntegriCloud