summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRyan QIAN <b32804@freescale.com>2012-06-26 07:39:36 +0800
committerTerry Lv <r65388@freescale.com>2012-07-25 13:10:56 +0800
commite406119f203b40485ee9282bdad69cfbba5f30fe (patch)
tree37be517b9db7b861bc4b87a7f4bc554a1f62c032 /drivers
parent3b6ff3e8590f5ad33c05bcd67e6dd1476f6e4348 (diff)
ENGR00217120 mmc: esdhc: implement std tuning for fsl sdhc ip
1. in mx6sl, it adds sd3.0 uhs mode capability indicator bits. 2. in mx6sl, exe_tune and smp_clk_sel bits for standard tuning procedure have been put in ACMD12_ERR reg Signed-off-by: Ryan QIAN <b32804@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c52
1 files changed, 41 insertions, 11 deletions
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index c1d8fb35907b..30ec9f72c6bb 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -72,6 +72,11 @@
#define SDHCI_FSL_SVN_300 0x11
+#define SDHCI_TUNE_CTRL 0xCC
+#define SDHCI_TUNE_CTRL_STD_TUNING_EN (1 << 24)
+
+#define SDHCI_HOST_CAP_UHS_MODE_MASK 0x7
+
#define SDHCI_TUNING_BLOCK_PATTERN_LEN 64
/*
* There is an INT DMA ERR mis-match between eSDHC and STD SDHC SPEC:
@@ -237,12 +242,15 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
if ((val & SDHCI_INT_DATA_END) && \
!(val & SDHCI_INT_DMA_END))
val = readl(host->ioaddr + reg);
- } else if (reg == SDHCI_CAPABILITIES_1 && cpu_is_mx6()) {
+ } else if (reg == SDHCI_CAPABILITIES_1
+ && (cpu_is_mx6q() || cpu_is_mx6dl())) {
/*
* on mx6q, no cap_1 available, fake one.
*/
val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104 | \
SDHCI_SUPPORT_SDR50;
+ } else if (reg == SDHCI_CAPABILITIES_1 && cpu_is_mx6sl()) {
+ val = readl(host->ioaddr + SDHCI_CAPABILITIES) & 0xFFFF;
} else if (reg == SDHCI_MAX_CURRENT && cpu_is_mx6()) {
/*
* on mx6q, no max current available, fake one.
@@ -369,11 +377,19 @@ static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
ret |= (val & SDHCI_VENDOR_SPEC_VSELECT)
? SDHCI_CTRL_VDD_180 : 0;
- val = readl(host->ioaddr + SDHCI_MIX_CTRL);
- ret |= (val & SDHCI_MIX_CTRL_EXE_TUNE)
- ? SDHCI_CTRL_EXEC_TUNING : 0;
- ret |= (val & SDHCI_MIX_CTRL_SMPCLK_SEL)
- ? 0 : SDHCI_CTRL_TUNED_CLK ;
+ if (cpu_is_mx6sl()) {
+ val = readl(host->ioaddr + SDHCI_ACMD12_ERR);
+ ret |= (val & SDHCI_MIX_CTRL_EXE_TUNE)
+ ? SDHCI_CTRL_EXEC_TUNING : 0;
+ ret |= (val & SDHCI_MIX_CTRL_SMPCLK_SEL)
+ ? SDHCI_CTRL_TUNED_CLK : 0;
+ } else {
+ val = readl(host->ioaddr + SDHCI_MIX_CTRL);
+ ret |= (val & SDHCI_MIX_CTRL_EXE_TUNE)
+ ? SDHCI_CTRL_EXEC_TUNING : 0;
+ ret |= (val & SDHCI_MIX_CTRL_SMPCLK_SEL)
+ ? SDHCI_CTRL_TUNED_CLK : 0;
+ }
ret |= SDHCI_CTRL_UHS_MASK & imx_data->uhs_mode;
/* no preset enable available */
ret &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
@@ -476,11 +492,25 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
* ignore exec_tuning flag written to SDHCI_HOST_CONTROL2,
* tuning will be handled differently for FSL SDHC ip.
*/
- orig_reg = readl(host->ioaddr + SDHCI_MIX_CTRL);
- orig_reg &= ~SDHCI_MIX_CTRL_SMPCLK_SEL;
-
- orig_reg |= (val & SDHCI_CTRL_TUNED_CLK)
- ? 0 : SDHCI_MIX_CTRL_SMPCLK_SEL;
+ if (cpu_is_mx6sl()) {
+ orig_reg = readl(host->ioaddr + SDHCI_TUNE_CTRL);
+ if (val & SDHCI_CTRL_EXEC_TUNING) {
+ orig_reg |= SDHCI_TUNE_CTRL_STD_TUNING_EN;
+ writel(orig_reg,
+ host->ioaddr + SDHCI_TUNE_CTRL);
+
+ orig_reg =
+ readl(host->ioaddr + SDHCI_ACMD12_ERR);
+ orig_reg |= SDHCI_MIX_CTRL_EXE_TUNE;
+ writel(orig_reg,
+ host->ioaddr + SDHCI_ACMD12_ERR);
+ }
+ } else {
+ orig_reg = readl(host->ioaddr + SDHCI_MIX_CTRL);
+ orig_reg &= ~SDHCI_MIX_CTRL_SMPCLK_SEL;
+ orig_reg |= (val & SDHCI_CTRL_TUNED_CLK)
+ ? SDHCI_MIX_CTRL_SMPCLK_SEL : 0;
+ }
if (val & SDHCI_CTRL_UHS_DDR50) {
orig_reg |= SDHCI_MIX_CTRL_DDREN;