diff options
author | Ryan QIAN <b32804@freescale.com> | 2012-01-31 11:01:52 +0800 |
---|---|---|
committer | Ryan QIAN <b32804@freescale.com> | 2012-02-06 13:05:25 +0800 |
commit | 17b260c58639af59b9d18fceb59d58c71188a980 (patch) | |
tree | 562fb287d047eabee4c39f2239b4abb7150e2494 /drivers/mmc | |
parent | e0522dae7f84b7636c6719d67da24a1bca5acc74 (diff) |
ENGR00173288-02 merge "[MX6Q]add SDHC3.0 support on uSDHC controller"
ENGR152547-03 [MX6Q]add SDHC3.0 support on uSDHC controller
add voltage switch function due to SDHC3.0 spec requirement
add tuning function due to SDHC3.0 spec requirement
extend some functions to support SDR50 & SDR104 speed mode
- adjust the sequence of current_limit and bus_speed_mode
- add FSL specific tuning procedure
Signed-off-by: Ryan QIAN <b32804@freescale.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/core.h | 1 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 34 | ||||
-rw-r--r-- | drivers/mmc/core/sd_ops.c | 43 | ||||
-rw-r--r-- | drivers/mmc/core/sd_ops.h | 1 |
4 files changed, 75 insertions, 4 deletions
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 14664f1fb16f..84370cad499d 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -33,6 +33,7 @@ void mmc_init_erase(struct mmc_card *card); void mmc_set_chip_select(struct mmc_host *host, int mode); void mmc_set_clock(struct mmc_host *host, unsigned int hz); +void mmc_set_tuning(struct mmc_host *host, unsigned int tuning); void mmc_gate_clock(struct mmc_host *host); void mmc_ungate_clock(struct mmc_host *host); void mmc_set_ungated(struct mmc_host *host); diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index bd8805c9e8af..9dafabbfa431 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -613,19 +613,45 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card) if (err) goto out; - /* Set bus speed mode of the card */ - err = sd_set_bus_speed_mode(card, status); + /* Set current limit for the card */ + err = sd_set_current_limit(card, status); if (err) goto out; - /* Set current limit for the card */ - err = sd_set_current_limit(card, status); + /* Set bus speed mode of the card */ + err = sd_set_bus_speed_mode(card, status); if (err) goto out; /* SPI mode doesn't define CMD19 */ +#ifdef CONFIG_MMC_SDHCI_ESDHC_IMX + if (!mmc_host_is_spi(card->host)) { + int min, max, avg; + + min = card->host->tuning_min; + while (min < card->host->tuning_max) { + mmc_set_tuning(card->host, min); + if (!mmc_send_tuning_cmd(card)) + break; + min += card->host->tuning_step; + } + + max = min; + while (max < card->host->tuning_max) { + mmc_set_tuning(card->host, max); + if (!mmc_send_tuning_cmd(card)) + break; + max += card->host->tuning_step; + } + + avg = (min + max) / 2; + mmc_set_tuning(card->host, avg); + mmc_send_tuning_cmd(card); + } +#else if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) err = card->host->ops->execute_tuning(card->host); +#endif out: kfree(status); diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index 021fed153804..afafc8c81d01 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c @@ -345,6 +345,49 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group, return 0; } +int mmc_send_tuning_cmd(struct mmc_card *card) +{ + struct mmc_request mrq; + struct mmc_command cmd; + struct mmc_data data; + struct scatterlist sg; + char scr[64]; + + BUG_ON(!card); + BUG_ON(!card->host); + + memset(&mrq, 0, sizeof(struct mmc_request)); + memset(&cmd, 0, sizeof(struct mmc_command)); + memset(&data, 0, sizeof(struct mmc_data)); + memset(scr, 0, 64); + + mrq.cmd = &cmd; + mrq.data = &data; + + cmd.opcode = MMC_SEND_TUNING_BLOCK; + cmd.arg = 0; + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; + + data.blksz = 64; + data.blocks = 1; + data.flags = MMC_DATA_READ; + data.sg = &sg; + data.sg_len = 1; + + sg_init_one(&sg, scr, 64); + + mmc_set_data_timeout(&data, card); + + mmc_wait_for_req(card->host, &mrq); + + if (cmd.error) + return cmd.error; + if (data.error) + return data.error; + + return 0; +} + int mmc_app_sd_status(struct mmc_card *card, void *ssr) { int err; diff --git a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h index ffc2305d905f..2142da4b611c 100644 --- a/drivers/mmc/core/sd_ops.h +++ b/drivers/mmc/core/sd_ops.h @@ -20,6 +20,7 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr); int mmc_sd_switch(struct mmc_card *card, int mode, int group, u8 value, u8 *resp); int mmc_app_sd_status(struct mmc_card *card, void *ssr); +int mmc_send_tuning_cmd(struct mmc_card *card); #endif |