aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChaotian Jing <chaotian.jing@mediatek.com>2016-06-29 22:00:59 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2016-07-25 04:34:31 -0400
commit86beac370481882550e1f3904a5af44a5f9ea395 (patch)
tree963c6166d42152bf0b52dbebd016b009ce3a1c50
parent5462ff39c4538b33e70a3c3fffa980c3acb27642 (diff)
mmc: mediatek: fix CRC error when calling mmc_select_hs400()
the tune result of hs200 mode at 200Mhz is not suitable for 50Mhz, mmc_select_hs400() will set clock frequency to 50Mhz, use defalut tune setting for 50Mhz to avoid CRC error. Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r--drivers/mmc/host/mtk-sd.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 4d7ce6586e57..4b175a634e36 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -287,6 +287,11 @@ struct msdc_save_para {
287 u32 emmc50_cfg0; 287 u32 emmc50_cfg0;
288}; 288};
289 289
290struct msdc_tune_para {
291 u32 iocon;
292 u32 pad_tune;
293};
294
290struct msdc_delay_phase { 295struct msdc_delay_phase {
291 u8 maxlen; 296 u8 maxlen;
292 u8 start; 297 u8 start;
@@ -328,6 +333,8 @@ struct msdc_host {
328 u32 hs400_ds_delay; 333 u32 hs400_ds_delay;
329 bool hs400_mode; /* current eMMC will run at hs400 mode */ 334 bool hs400_mode; /* current eMMC will run at hs400 mode */
330 struct msdc_save_para save_para; /* used when gate HCLK */ 335 struct msdc_save_para save_para; /* used when gate HCLK */
336 struct msdc_tune_para def_tune_para; /* default tune setting */
337 struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
331}; 338};
332 339
333static void sdr_set_bits(void __iomem *reg, u32 bs) 340static void sdr_set_bits(void __iomem *reg, u32 bs)
@@ -583,6 +590,18 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
583 msdc_set_timeout(host, host->timeout_ns, host->timeout_clks); 590 msdc_set_timeout(host, host->timeout_ns, host->timeout_clks);
584 sdr_set_bits(host->base + MSDC_INTEN, flags); 591 sdr_set_bits(host->base + MSDC_INTEN, flags);
585 592
593 /*
594 * mmc_select_hs400() will drop to 50Mhz and High speed mode,
595 * tune result of hs200/200Mhz is not suitable for 50Mhz
596 */
597 if (host->sclk <= 52000000) {
598 writel(host->def_tune_para.iocon, host->base + MSDC_IOCON);
599 writel(host->def_tune_para.pad_tune, host->base + MSDC_PAD_TUNE);
600 } else {
601 writel(host->saved_tune_para.iocon, host->base + MSDC_IOCON);
602 writel(host->saved_tune_para.pad_tune, host->base + MSDC_PAD_TUNE);
603 }
604
586 dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing); 605 dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
587} 606}
588 607
@@ -1159,6 +1178,8 @@ static void msdc_init_hw(struct msdc_host *host)
1159 /* Configure to default data timeout */ 1178 /* Configure to default data timeout */
1160 sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3); 1179 sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3);
1161 1180
1181 host->def_tune_para.iocon = readl(host->base + MSDC_IOCON);
1182 host->def_tune_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
1162 dev_dbg(host->dev, "init hardware done!"); 1183 dev_dbg(host->dev, "init hardware done!");
1163} 1184}
1164 1185
@@ -1409,6 +1430,8 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
1409 dev_err(host->dev, "Tune data fail!\n"); 1430 dev_err(host->dev, "Tune data fail!\n");
1410 } 1431 }
1411 1432
1433 host->saved_tune_para.iocon = readl(host->base + MSDC_IOCON);
1434 host->saved_tune_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
1412 return ret; 1435 return ret;
1413} 1436}
1414 1437