aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorDong Aisheng <b29396@freescale.com>2013-10-18 19:48:47 +0800
committerChris Ball <chris@printf.net>2013-10-21 15:58:13 -0400
commit602519b2bd63adfdf9e24b2f94aaddcfeb464e9e (patch)
tree818c25ef9f7c6db0d89f09753896666f013bf4e6 /drivers/mmc
parentmmc: sdhci-esdhc-imx: add DDR mode support for mx6 (diff)
downloadlinux-dev-602519b2bd63adfdf9e24b2f94aaddcfeb464e9e.tar.xz
linux-dev-602519b2bd63adfdf9e24b2f94aaddcfeb464e9e.zip
mmc: sdhci-esdhc-imx: add delay line setting support
The DLL(Delay Line) is newly added to assist in sampling read data. The DLL provides the ability to programmatically select a quantized delay (in fractions of the clock period) regardless of on-chip variations such as process, voltage and temperature (PVT). This patch adds a user interface to set slave delay line via device tree. It's usually used in high speed mode like mmc DDR mode when the signal quality is not good caused by board design, e.g. the signal path is too long. User can manually set delay line to find a suitable data sampling window for card to work properly. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 915fa68e5122..260a81fde18d 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -46,6 +46,11 @@
/* Bits 3 and 6 are not SDHCI standard definitions */
#define ESDHC_MIX_CTRL_SDHCI_MASK 0xb7
+/* dll control register */
+#define ESDHC_DLL_CTRL 0x60
+#define ESDHC_DLL_OVERRIDE_VAL_SHIFT 9
+#define ESDHC_DLL_OVERRIDE_EN_SHIFT 8
+
/* tune control register */
#define ESDHC_TUNE_CTRL_STATUS 0x68
#define ESDHC_TUNE_CTRL_STEP 1
@@ -817,6 +822,7 @@ static int esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct pltfm_imx_data *imx_data = pltfm_host->priv;
+ struct esdhc_platform_data *boarddata = &imx_data->boarddata;
switch (uhs) {
case MMC_TIMING_UHS_SDR12:
@@ -837,6 +843,15 @@ static int esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
ESDHC_MIX_CTRL_DDREN,
host->ioaddr + ESDHC_MIX_CTRL);
imx_data->is_ddr = 1;
+ if (boarddata->delay_line) {
+ u32 v;
+ v = boarddata->delay_line <<
+ ESDHC_DLL_OVERRIDE_VAL_SHIFT |
+ (1 << ESDHC_DLL_OVERRIDE_EN_SHIFT);
+ if (is_imx53_esdhc(imx_data))
+ v <<= 1;
+ writel(v, host->ioaddr + ESDHC_DLL_CTRL);
+ }
break;
}
@@ -901,6 +916,9 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
else
boarddata->support_vsel = true;
+ if (of_property_read_u32(np, "fsl,delay-line", &boarddata->delay_line))
+ boarddata->delay_line = 0;
+
return 0;
}
#else