summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorRyan QIAN <b32804@freescale.com>2012-01-31 11:01:52 +0800
committerRyan QIAN <b32804@freescale.com>2012-02-06 13:05:25 +0800
commit17b260c58639af59b9d18fceb59d58c71188a980 (patch)
tree562fb287d047eabee4c39f2239b4abb7150e2494 /drivers/mmc
parente0522dae7f84b7636c6719d67da24a1bca5acc74 (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.h1
-rw-r--r--drivers/mmc/core/sd.c34
-rw-r--r--drivers/mmc/core/sd_ops.c43
-rw-r--r--drivers/mmc/core/sd_ops.h1
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