summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt3
-rw-r--r--arch/arm/boot/dts/imx7d-12x12-arm2.dts2
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c13
-rw-r--r--include/linux/platform_data/mmc-esdhc-imx.h1
4 files changed, 15 insertions, 4 deletions
diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
index 9046ba06c47a..aa470163902c 100644
--- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
+++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
@@ -17,6 +17,8 @@ Optional properties:
to select a proper data sampling window in case the clock quality is not good
due to signal path is too long on the board. Please refer to eSDHC/uSDHC
chapter, DLL (Delay Line) section in RM for details.
+- tuning-step : The delay cell steps in tuning procedure.
+ Some boards need to set the tuning-step to make sure it can pass tuning procedure.
Examples:
@@ -26,6 +28,7 @@ esdhc@70004000 {
interrupts = <1>;
fsl,cd-controller;
fsl,wp-controller;
+ tuning-step = <2>;
};
esdhc@70008000 {
diff --git a/arch/arm/boot/dts/imx7d-12x12-arm2.dts b/arch/arm/boot/dts/imx7d-12x12-arm2.dts
index 06325ecb342a..6209482c4820 100644
--- a/arch/arm/boot/dts/imx7d-12x12-arm2.dts
+++ b/arch/arm/boot/dts/imx7d-12x12-arm2.dts
@@ -257,6 +257,7 @@
wp-gpios = <&gpio5 10 0>;
keep-power-in-suspend;
enable-sdio-wakeup;
+ tuning-step = <2>;
vmmc-supply = <&reg_sd2_vmmc>;
status = "okay";
};
@@ -267,6 +268,7 @@
pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
bus-width = <8>;
+ tuning-step = <2>;
non-removable;
keep-power-in-suspend;
status = "okay";
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 10d3a1561b1e..7628c0b7be46 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -76,6 +76,7 @@
#define ESDHC_STD_TUNING_EN (1 << 24)
/* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
#define ESDHC_TUNING_START_TAP 0x1
+#define ESDHC_TUNING_STEP_SHIFT 16
#define ESDHC_TUNING_BLOCK_PATTERN_LEN 64
@@ -479,6 +480,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
} else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
u32 v = readl(host->ioaddr + SDHCI_ACMD12_ERR);
u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+ u32 tmp;
if (val & SDHCI_CTRL_TUNED_CLK) {
v |= ESDHC_MIX_CTRL_SMPCLK_SEL;
} else {
@@ -489,10 +491,11 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
if (val & SDHCI_CTRL_EXEC_TUNING) {
v |= ESDHC_MIX_CTRL_EXE_TUNE;
m |= ESDHC_MIX_CTRL_FBCLK_SEL;
- writel(readl(host->ioaddr + ESDHC_TUNING_CTRL) |
- ESDHC_STD_TUNING_EN |
- ESDHC_TUNING_START_TAP,
- host->ioaddr + ESDHC_TUNING_CTRL);
+ tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL);
+ tmp |= ESDHC_STD_TUNING_EN | ESDHC_TUNING_START_TAP;
+ if (imx_data->boarddata.tuning_step)
+ tmp |= imx_data->boarddata.tuning_step << ESDHC_TUNING_STEP_SHIFT;
+ writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL);
} else {
v &= ~ESDHC_MIX_CTRL_EXE_TUNE;
}
@@ -1011,6 +1014,8 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
of_property_read_u32(np, "max-frequency", &boarddata->f_max);
+ of_property_read_u32(np, "tuning-step", &boarddata->tuning_step);
+
if (of_find_property(np, "no-1-8-v", NULL))
boarddata->support_vsel = false;
else
diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h
index 75f70f6ac137..cedbf8e63e09 100644
--- a/include/linux/platform_data/mmc-esdhc-imx.h
+++ b/include/linux/platform_data/mmc-esdhc-imx.h
@@ -46,5 +46,6 @@ struct esdhc_platform_data {
unsigned int f_max;
bool support_vsel;
unsigned int delay_line;
+ unsigned int tuning_step; /* The delay cell steps in tuning procedure */
};
#endif /* __ASM_ARCH_IMX_ESDHC_H */