]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
mmc: sdhci-esdhc-imx: add delay line setting support
authorDong Aisheng <b29396@freescale.com>
Mon, 21 Oct 2013 08:54:40 +0000 (16:54 +0800)
committerJason Liu <r64343@freescale.com>
Wed, 30 Oct 2013 01:56:03 +0000 (09:56 +0800)
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 <chris@printf.net>
Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
drivers/mmc/host/sdhci-esdhc-imx.c
include/linux/platform_data/mmc-esdhc-imx.h

index 1dd622546d06b711bf262358b387b4bb9af3f68a..9046ba06c47ab63570f99769455dcfeeea020e10 100644 (file)
@@ -12,6 +12,11 @@ Required properties:
 Optional properties:
 - fsl,cd-controller : Indicate to use controller internal card detection
 - fsl,wp-controller : Indicate to use controller internal write protection
+- fsl,delay-line : Specify the number of delay cells for override mode.
+  This is used to set the clock delay for DLL(Delay Line) on override mode
+  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.
 
 Examples:
 
index 4b6cd9fa4808c70a41ebffdf33bfff1e26511faa..1537e87abe39d1e612d989d7f41c36e8354b449a 100644 (file)
 /* 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
@@ -842,6 +847,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:
@@ -862,6 +868,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;
        }
 
@@ -924,6 +939,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
index 4bcb73d57c69c89ff624bbb0f3af4b3ceaa57512..e1571efa3f2b28e01642e08f6709d7c7c8dc141a 100644 (file)
@@ -44,5 +44,6 @@ struct esdhc_platform_data {
        enum cd_types cd_type;
        int max_bus_width;
        bool support_vsel;
+       unsigned int delay_line;
 };
 #endif /* __ASM_ARCH_IMX_ESDHC_H */