diff options
author | Adrian Hunter <adrian.hunter@nokia.com> | 2010-08-24 13:20:26 +0300 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2010-10-23 21:11:16 +0800 |
commit | 0f8d8ea64ec7c77ca5beb59534d386fe0235961a (patch) | |
tree | 8d6aebd250897aa33cb166994720497f40a9aaa6 /drivers/mmc/core/mmc.c | |
parent | dfc13e8402c75e7c2e0a52e123c0500a3259866b (diff) | |
download | lwn-0f8d8ea64ec7c77ca5beb59534d386fe0235961a.tar.gz lwn-0f8d8ea64ec7c77ca5beb59534d386fe0235961a.zip |
mmc: Fixes for Dual Data Rate (DDR) support
The DDR support patch needs the following fixes:
- The block driver does not need to know about DDR, any more
than it needs to know about bus width.
- Not only the card must be switched to DDR mode. The host
controller must also be configured, which is done through
the 'set_ios()' function.
- Do not set the DDR mode state until after the switch command
is successful.
- Setting block length is not supported in DDR mode. Make that
a core function and change the other place it is used (mmc_test)
also.
Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/core/mmc.c')
-rw-r--r-- | drivers/mmc/core/mmc.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 66c4a59fee5f..3ea58ce773ff 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -375,7 +375,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; - int err; + int err, ddr = 0; u32 cid[4]; unsigned int max_dtr; @@ -518,32 +518,32 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, mmc_set_clock(host, max_dtr); /* - * Activate DDR50 mode (if supported). + * Indicate DDR mode (if supported). */ if (mmc_card_highspeed(card)) { if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) && (host->caps & (MMC_CAP_1_8V_DDR))) - mmc_card_set_ddr_mode(card); + ddr = 1; else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) && (host->caps & (MMC_CAP_1_2V_DDR))) - mmc_card_set_ddr_mode(card); + ddr = 1; } /* - * Activate wide bus (if supported). + * Activate wide bus and DDR (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { unsigned ext_csd_bit, bus_width; if (host->caps & MMC_CAP_8_BIT_DATA) { - if (mmc_card_ddr_mode(card)) + if (ddr) ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_8; else ext_csd_bit = EXT_CSD_BUS_WIDTH_8; bus_width = MMC_BUS_WIDTH_8; } else { - if (mmc_card_ddr_mode(card)) + if (ddr) ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_4; else ext_csd_bit = EXT_CSD_BUS_WIDTH_4; @@ -557,12 +557,13 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, goto free_card; if (err) { - printk(KERN_WARNING "%s: switch to bus width %d " + printk(KERN_WARNING "%s: switch to bus width %d ddr %d " "failed\n", mmc_hostname(card->host), - 1 << bus_width); + 1 << bus_width, ddr); err = 0; } else { - mmc_set_bus_width(card->host, bus_width); + mmc_card_set_ddr_mode(card); + mmc_set_bus_width_ddr(card->host, bus_width, ddr); } } |