Skip to content

Commit

Permalink
mmc: core: add support for eMMC Dual Data Rate
Browse files Browse the repository at this point in the history
eMMC voltage change not required for 1.8V.  3.3V and 1.8V vcc
are capable of doing DDR. vccq of 1.8v is not required.

Signed-off-by: Philip Rakity <prakity@marvell.com>
Reviewed-by: Arindam Nath <arindam.nath@amd.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
  • Loading branch information
Philip Rakity authored and Chris Ball committed May 25, 2011
1 parent 261bbd4 commit 4c4cb17
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 19 deletions.
14 changes: 2 additions & 12 deletions drivers/mmc/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -717,23 +717,13 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
mmc_set_ios(host);
}

/*
* Change data bus width and DDR mode of a host.
*/
void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width,
unsigned int ddr)
{
host->ios.bus_width = width;
host->ios.ddr = ddr;
mmc_set_ios(host);
}

/*
* Change data bus width of a host.
*/
void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
{
mmc_set_bus_width_ddr(host, width, MMC_SDR_MODE);
host->ios.bus_width = width;
mmc_set_ios(host);
}

/**
Expand Down
2 changes: 0 additions & 2 deletions drivers/mmc/core/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ void mmc_ungate_clock(struct mmc_host *host);
void mmc_set_ungated(struct mmc_host *host);
void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode);
void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width,
unsigned int ddr);
u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage,
bool cmd11);
Expand Down
35 changes: 30 additions & 5 deletions drivers/mmc/core/mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "core.h"
#include "bus.h"
#include "mmc_ops.h"
#include "sd_ops.h"

static const unsigned int tran_exp[] = {
10000, 100000, 1000000, 10000000,
Expand Down Expand Up @@ -633,10 +634,14 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
*/
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)))
&& ((host->caps & (MMC_CAP_1_8V_DDR |
MMC_CAP_UHS_DDR50))
== (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50)))
ddr = MMC_1_8V_DDR_MODE;
else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V)
&& (host->caps & (MMC_CAP_1_2V_DDR)))
&& ((host->caps & (MMC_CAP_1_2V_DDR |
MMC_CAP_UHS_DDR50))
== (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50)))
ddr = MMC_1_2V_DDR_MODE;
}

Expand Down Expand Up @@ -670,8 +675,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
ext_csd_bits[idx][0],
0);
if (!err) {
mmc_set_bus_width_ddr(card->host,
bus_width, MMC_SDR_MODE);
mmc_set_bus_width(card->host, bus_width);
/*
* If controller can't handle bus width test,
* use the highest bus width to maintain
Expand All @@ -697,8 +701,29 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
1 << bus_width, ddr);
goto free_card;
} else if (ddr) {
/*
* eMMC cards can support 3.3V to 1.2V i/o (vccq)
* signaling.
*
* EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq.
*
* 1.8V vccq at 3.3V core voltage (vcc) is not required
* in the JEDEC spec for DDR.
*
* Do not force change in vccq since we are obviously
* working and no change to vccq is needed.
*
* WARNING: eMMC rules are NOT the same as SD DDR
*/
if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) {
err = mmc_set_signal_voltage(host,
MMC_SIGNAL_VOLTAGE_120, 0);
if (err)
goto err;
}
mmc_card_set_ddr_mode(card);
mmc_set_bus_width_ddr(card->host, bus_width, ddr);
mmc_set_timing(card->host, MMC_TIMING_UHS_DDR50);
mmc_set_bus_width(card->host, bus_width);
}
}

Expand Down
1 change: 1 addition & 0 deletions include/linux/mmc/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ struct mmc_ios {

#define MMC_SIGNAL_VOLTAGE_330 0
#define MMC_SIGNAL_VOLTAGE_180 1
#define MMC_SIGNAL_VOLTAGE_120 2

unsigned char drv_type; /* driver type (A, B, C, D) */

Expand Down

0 comments on commit 4c4cb17

Please sign in to comment.