[PATCH] DT: mmc: sh_mmcif: fix compatible property text
The compatible property text contradicts even the example given in the MMCIF binding document itself; moreover, the Renesas MMCIF driver only matches on the generic compatible string, and doesn't look for at SoC specific strings currently at all. Thus describe renesas,sh-mmcif string as mandatory and the others as optional. Fixes: b4c27763d749 (mmc: sh_mmcif: Document DT bindings) Signed-off-by: Sergei Shtylyov sergei.shtyl...@cogentembedded.com --- Documentation/devicetree/bindings/mmc/renesas,mmcif.txt |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) Index: renesas/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt === --- renesas.orig/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt +++ renesas/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt @@ -6,11 +6,11 @@ and the properties used by the MMCIF dev Required properties: -- compatible: must contain one of the following +- compatible: must contain renesas,sh-mmcif; may also contain one of + the following: - renesas,mmcif-r8a7740 for the MMCIF found in r8a7740 SoCs - renesas,mmcif-r8a7790 for the MMCIF found in r8a7790 SoCs - renesas,mmcif-r8a7791 for the MMCIF found in r8a7791 SoCs - - renesas,sh-mmcif for the generic MMCIF - clocks: reference to the functional clock -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] DT: mmc: sh_mmcif: document R8A779[34] support
Renesas R8A7793 and R8A7793 SoC also have the MMCIF controller... Signed-off-by: Sergei Shtylyov sergei.shtyl...@cogentembedded.com --- The patch is against Ulf Hansson's 'mmc.git' repo's 'next' branch plus the patch I posted earlier today... Documentation/devicetree/bindings/mmc/renesas,mmcif.txt |2 ++ 1 file changed, 2 insertions(+) Index: mmc/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt === --- mmc.orig/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt +++ mmc/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt @@ -11,6 +11,8 @@ Required properties: - renesas,mmcif-r8a7740 for the MMCIF found in r8a7740 SoCs - renesas,mmcif-r8a7790 for the MMCIF found in r8a7790 SoCs - renesas,mmcif-r8a7791 for the MMCIF found in r8a7791 SoCs + - renesas,mmcif-r8a7793 for the MMCIF found in r8a7793 SoCs + - renesas,mmcif-r8a7794 for the MMCIF found in r8a7794 SoCs - clocks: reference to the functional clock -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 2/6] mmc: sdhci-esdhc-imx: add tuning-step seting support
On Thu, Jul 30, 2015 at 06:25:06PM +0200, Jan Lübbe wrote: On Mi, 2015-07-29 at 17:03 +0800, Haibo Chen wrote: tuning-step is the delay cell steps in tuning procedure. The default value of tuning-step is 1. For imx6 series usdhc, tuning procedure can be passed when the tuning-step value is 1. But imx7d usdhc need the tuning-step value as 2, otherwise it can't pass the tuning procedure. So this patch add the tuning-step setting in driver, so that user can set the tuning-step value in dts. From your description, the correct tuning-step value only depends on the SoC. Why not derive it from the compatible string? 'tuning-step' actually depends on board and card. The commit message should be reformed a bit. Regards Dong Aisheng Regards, Jan Lübbe -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] DT: mmc: sh_mmcif: fix compatible property text
Hi Sergei, On Fri, Jul 31, 2015 at 4:59 AM, Sergei Shtylyov sergei.shtyl...@cogentembedded.com wrote: The compatible property text contradicts even the example given in the MMCIF binding document itself; moreover, the Renesas MMCIF driver only matches on the generic compatible string, and doesn't look for at SoC specific strings currently at all. Thus describe renesas,sh-mmcif string as mandatory and the others as optional. Fixes: b4c27763d749 (mmc: sh_mmcif: Document DT bindings) Signed-off-by: Sergei Shtylyov sergei.shtyl...@cogentembedded.com Thanks for your efforts trying to improve the DT binding documentation. --- renesas.orig/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt +++ renesas/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt @@ -6,11 +6,11 @@ and the properties used by the MMCIF dev Required properties: -- compatible: must contain one of the following +- compatible: must contain renesas,sh-mmcif; may also contain one of + the following: - renesas,mmcif-r8a7740 for the MMCIF found in r8a7740 SoCs - renesas,mmcif-r8a7790 for the MMCIF found in r8a7790 SoCs - renesas,mmcif-r8a7791 for the MMCIF found in r8a7791 SoCs - - renesas,sh-mmcif for the generic MMCIF As you know, each SoC contains a wide range of on-chip devices and the MMCIF device is just one of them. Exactly how to manage the DT bindings must be up to each maintainer and of course this needs to be aligned with the SoC maintainer and SoC vendor with policies used for SoC support and BSPs and whatnot. Changing policy like this for a single device without at least discussing this with the SoC maintainers does not help. For Renesas hardware we so far use both SoC part number and optionally a generic binding as well. As commonly expected, the DT binding is supposed to describe the hardware and if hardware devices are compatible. Unless we use SoC part number in the compatible string there is a risk that the SoC integrator simply copy-and-pastes generic bindings because it works but this will result in DT binding based on software compatibility and not hardware compatibility. Later when the driver support is extended this may result in broken software due to incorrect compatibility information through generic bindings. If anything is unclear please ask and feel free to discuss this DT topic with Simon, Laurent, Geert and/or me. Thanks, / magnus -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[v4, 6/6] mmc: esdhc: add eMMC DDR mode support
Add eMMC DDR mode support for Freescale SDHC adapter card. The u-boot should provide device tree properties 'adapter-type' and 'periperal-frequency' for this feature, if not, the card would not use DDR mode. Signed-off-by: Yangbo Lu yangbo...@freescale.com --- drivers/mmc/host/sdhci-esdhc.h| 24 +++ drivers/mmc/host/sdhci-of-esdhc.c | 132 -- 2 files changed, 152 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h index 163ac99..015ec01 100644 --- a/drivers/mmc/host/sdhci-esdhc.h +++ b/drivers/mmc/host/sdhci-esdhc.h @@ -28,10 +28,32 @@ #define ESDHC_CLOCK_MASK 0xfff0 #define ESDHC_PREDIV_SHIFT 8 #define ESDHC_DIVIDER_SHIFT4 +#define ESDHC_CLOCK_CRDEN 0x0008 #define ESDHC_CLOCK_PEREN 0x0004 #define ESDHC_CLOCK_HCKEN 0x0002 #define ESDHC_CLOCK_IPGEN 0x0001 +#define ESDHCI_PRESENT_STATE 0x24 +#define ESDHC_CLK_STABLE 0x0008 + +#define ESDHC_CAPABILITIES_1 0x114 +#define ESDHC_MODE_MASK0x0007 +#define ESDHC_MODE_DDR50_SEL 0xfffc +#define ESDHC_MODE_DDR50 0x0004 + +#define ESDHC_CLOCK_CONTROL0x144 +#define ESDHC_CLKLPBK_EXTPIN 0x8000 +#define ESDHC_CMDCLK_SHIFTED 0x8000 + +/* SDHC Adapter Card Type */ +#define ESDHC_ADAPTER_TYPE_EMMC45 0x1/* eMMC Card Rev4.5 */ +#define ESDHC_ADAPTER_TYPE_SDMMC_LEGACY 0x2/* SD/MMC Legacy Card */ +#define ESDHC_ADAPTER_TYPE_EMMC44 0x3/* eMMC Card Rev4.4 */ +#define ESDHC_ADAPTER_TYPE_RSV 0x4/* Reserved */ +#define ESDHC_ADAPTER_TYPE_MMC 0x5/* MMC Card */ +#define ESDHC_ADAPTER_TYPE_SD 0x6/* SD Card Rev2.0 Rev3.0 */ +#define ESDHC_NO_ADAPTER0x7/* No Card is Present*/ + /* pltfm-specific */ #define ESDHC_HOST_CONTROL_LE 0x20 @@ -45,6 +67,8 @@ /* OF-specific */ #define ESDHC_DMA_SYSCTL 0x40c #define ESDHC_DMA_SNOOP0x0040 +#define ESDHC_FLUSH_ASYNC_FIFO 0x0004 +#define ESDHC_USE_PERIPHERAL_CLK0x0008 #define ESDHC_HOST_CONTROL_RES 0x01 diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index f1021d8..6d7e3f9 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -24,11 +24,30 @@ #define VENDOR_V_220x12 #define VENDOR_V_230x13 + +static u32 adapter_type; +static bool peripheral_clk_available; + static u32 esdhc_readl(struct sdhci_host *host, int reg) { u32 ret; - ret = sdhci_32bs_readl(host, reg); + if (reg == SDHCI_CAPABILITIES_1) { + ret = sdhci_32bs_readl(host, ESDHC_CAPABILITIES_1); + switch (adapter_type) { + case ESDHC_ADAPTER_TYPE_EMMC44: + if (ret ESDHC_MODE_DDR50) { + ret = ESDHC_MODE_DDR50_SEL; + /* enable 1/8V DDR capable */ + host-mmc-caps |= MMC_CAP_1_8V_DDR; + } else + ret = ~ESDHC_MODE_MASK; + break; + default: + ret = ~ESDHC_MODE_MASK; + } + } else + ret = sdhci_32bs_readl(host, reg); /* * The bit of ADMA flag in eSDHC is not compatible with standard * SDHC register, so set fake flag SDHCI_CAN_DO_ADMA2 when ADMA is @@ -159,8 +178,11 @@ static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) } /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ - if (reg == SDHCI_HOST_CONTROL) + if (reg == SDHCI_HOST_CONTROL) { val = ~ESDHC_HOST_CONTROL_RES; + val = ~SDHCI_CTRL_HISPD; + val |= (sdhci_32bs_readl(host, reg) SDHCI_CTRL_HISPD); + } sdhci_clrsetbits(host, 0xff, val, reg); } @@ -307,6 +329,84 @@ static void esdhc_reset(struct sdhci_host *host, u8 mask) sdhci_writel(host, host-ier, SDHCI_SIGNAL_ENABLE); } +static void esdhc_clock_control(struct sdhci_host *host, bool enable) +{ + u32 value; + u32 time_out; + + value = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); + + if (enable) + value |= ESDHC_CLOCK_CRDEN; + else + value = ~ESDHC_CLOCK_CRDEN; + + sdhci_writel(host, value, ESDHC_SYSTEM_CONTROL); + + time_out = 20; + value = ESDHC_CLK_STABLE; + while (!(sdhci_readl(host, ESDHCI_PRESENT_STATE) value)) { + if (time_out == 0) { + pr_err(%s: Internal clock never stabilised.\n, + mmc_hostname(host-mmc)); + break; + } + time_out--; + mdelay(1); + } +} + +static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs) +{ + u16
[v4, 5/6] powerpc/85xx: specify 'big-endian' property for eSDHC in dts
Signed-off-by: Yangbo Lu yangbo...@freescale.com --- arch/powerpc/boot/dts/fsl/pq3-esdhc-0.dtsi | 1 + arch/powerpc/boot/dts/fsl/qoriq-esdhc-0.dtsi | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/powerpc/boot/dts/fsl/pq3-esdhc-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-esdhc-0.dtsi index 5743433..57f519e 100644 --- a/arch/powerpc/boot/dts/fsl/pq3-esdhc-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/pq3-esdhc-0.dtsi @@ -38,4 +38,5 @@ sdhc@2e000 { interrupts = 72 0x2 0 0; /* Filled in by U-Boot */ clock-frequency = 0; + big-endian; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-esdhc-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-esdhc-0.dtsi index 20835ae..5ba211e 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-esdhc-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-esdhc-0.dtsi @@ -37,4 +37,5 @@ sdhc: sdhc@114000 { reg = 0x114000 0x1000; interrupts = 48 2 0 0; clock-frequency = 0; + big-endian; }; -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[v4, 4/6] mmc: sdhci: apply little-endian mode support to sdhci-of-esdhc
Signed-off-by: Yangbo Lu yangbo...@freescale.com --- drivers/mmc/host/sdhci-of-esdhc.c | 105 +- 1 file changed, 69 insertions(+), 36 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 797be75..f1021d8 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -28,7 +28,7 @@ static u32 esdhc_readl(struct sdhci_host *host, int reg) { u32 ret; - ret = in_be32(host-ioaddr + reg); + ret = sdhci_32bs_readl(host, reg); /* * The bit of ADMA flag in eSDHC is not compatible with standard * SDHC register, so set fake flag SDHCI_CAN_DO_ADMA2 when ADMA is @@ -40,7 +40,7 @@ static u32 esdhc_readl(struct sdhci_host *host, int reg) * the verdor version number, oxFE is SDHCI_HOST_VERSION. */ if ((reg == SDHCI_CAPABILITIES) (ret SDHCI_CAN_DO_ADMA1)) { - u32 tmp = in_be32(host-ioaddr + SDHCI_SLOT_INT_STATUS); + u32 tmp = sdhci_32bs_readl(host, SDHCI_SLOT_INT_STATUS); tmp = (tmp SDHCI_VENDOR_VER_MASK) SDHCI_VENDOR_VER_SHIFT; if (tmp VENDOR_V_22) ret |= SDHCI_CAN_DO_ADMA2; @@ -56,9 +56,9 @@ static u16 esdhc_readw(struct sdhci_host *host, int reg) int shift = (reg 0x2) * 8; if (unlikely(reg == SDHCI_HOST_VERSION)) - ret = in_be32(host-ioaddr + base) 0x; + ret = sdhci_32bs_readl(host, base) 0x; else - ret = (in_be32(host-ioaddr + base) shift) 0x; + ret = (sdhci_32bs_readl(host, base) shift) 0x; return ret; } @@ -66,7 +66,10 @@ static u8 esdhc_readb(struct sdhci_host *host, int reg) { int base = reg ~0x3; int shift = (reg 0x3) * 8; - u8 ret = (in_be32(host-ioaddr + base) shift) 0xff; + u32 ret; + u8 val; + + ret = sdhci_32bs_readl(host, base); /* * DMA select locates at offset 0x28 in SD specification, but on @@ -75,16 +78,18 @@ static u8 esdhc_readb(struct sdhci_host *host, int reg) if (reg == SDHCI_HOST_CONTROL) { u32 dma_bits; - dma_bits = in_be32(host-ioaddr + reg); /* DMA select is 22,23 bits in Protocol Control Register */ - dma_bits = (dma_bits 5) SDHCI_CTRL_DMA_MASK; + dma_bits = (ret 5) SDHCI_CTRL_DMA_MASK; /* fixup the result */ ret = ~SDHCI_CTRL_DMA_MASK; ret |= dma_bits; + val = (ret 0xff); } - return ret; + val = (ret shift) 0xff; + + return val; } static void esdhc_writel(struct sdhci_host *host, u32 val, int reg) @@ -96,11 +101,28 @@ static void esdhc_writel(struct sdhci_host *host, u32 val, int reg) */ if (reg == SDHCI_INT_ENABLE) val |= SDHCI_INT_BLK_GAP; - sdhci_be32bs_writel(host, val, reg); + sdhci_32bs_writel(host, val, reg); } static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) { + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + + switch (reg) { + case SDHCI_TRANSFER_MODE: + /* +* Postpone this write, we must do it together with a +* command write that is down below. +*/ + pltfm_host-xfer_mode_shadow = val; + return; + case SDHCI_COMMAND: + sdhci_32bs_writel(host, val 16 | + pltfm_host-xfer_mode_shadow, + SDHCI_TRANSFER_MODE); + return; + } + if (reg == SDHCI_BLOCK_SIZE) { /* * Two last DMA bits are reserved, and first one is used for @@ -109,7 +131,7 @@ static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) */ val = ~SDHCI_MAKE_BLKSZ(0x7, 0); } - sdhci_be32bs_writew(host, val, reg); + sdhci_clrsetbits(host, 0x, val, reg); } static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) @@ -130,16 +152,16 @@ static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) /* DMA select is 22,23 bits in Protocol Control Register */ dma_bits = (val SDHCI_CTRL_DMA_MASK) 5; - clrsetbits_be32(host-ioaddr + reg , SDHCI_CTRL_DMA_MASK 5, - dma_bits); + sdhci_clrsetbits(host, SDHCI_CTRL_DMA_MASK 5, dma_bits, +SDHCI_HOST_CONTROL); val = ~SDHCI_CTRL_DMA_MASK; - val |= in_be32(host-ioaddr + reg) SDHCI_CTRL_DMA_MASK; + val |= sdhci_32bs_readl(host, reg) SDHCI_CTRL_DMA_MASK; } /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ if (reg == SDHCI_HOST_CONTROL)
[v4, 3/6] mmc: sdhci: apply little-endian mode support to sdhci-of-hwld
Signed-off-by: Yangbo Lu yangbo...@freescale.com --- drivers/mmc/host/sdhci-of-hlwd.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c index 4079a96..83d8149 100644 --- a/drivers/mmc/host/sdhci-of-hlwd.c +++ b/drivers/mmc/host/sdhci-of-hlwd.c @@ -35,26 +35,26 @@ static void sdhci_hlwd_writel(struct sdhci_host *host, u32 val, int reg) { - sdhci_be32bs_writel(host, val, reg); + sdhci_32bs_writel(host, val, reg); udelay(SDHCI_HLWD_WRITE_DELAY); } static void sdhci_hlwd_writew(struct sdhci_host *host, u16 val, int reg) { - sdhci_be32bs_writew(host, val, reg); + sdhci_32bs_writew(host, val, reg); udelay(SDHCI_HLWD_WRITE_DELAY); } static void sdhci_hlwd_writeb(struct sdhci_host *host, u8 val, int reg) { - sdhci_be32bs_writeb(host, val, reg); + sdhci_32bs_writeb(host, val, reg); udelay(SDHCI_HLWD_WRITE_DELAY); } static const struct sdhci_ops sdhci_hlwd_ops = { - .read_l = sdhci_be32bs_readl, - .read_w = sdhci_be32bs_readw, - .read_b = sdhci_be32bs_readb, + .read_l = sdhci_32bs_readl, + .read_w = sdhci_32bs_readw, + .read_b = sdhci_32bs_readb, .write_l = sdhci_hlwd_writel, .write_w = sdhci_hlwd_writew, .write_b = sdhci_hlwd_writeb, -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[v4, 2/6] mmc: sdhci-pltfm: add little-endian mode support for SDHCI platform
This patch adds little-endian mode support for little-endian host controller. To indicate the little-endian mode, we could add 'little-endian' property in device tree node. Signed-off-by: Yangbo Lu yangbo...@freescale.com --- Changes for v4: - Moved endian mode checking back to sdhci-pltfm driver Changes for v3: - Moved endian mode checking to generic mmc host driver --- drivers/mmc/host/sdhci-pltfm.c | 14 +++- drivers/mmc/host/sdhci-pltfm.h | 74 ++ 2 files changed, 66 insertions(+), 22 deletions(-) diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index a207f5a..f001e34 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c @@ -121,6 +121,8 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, size_t priv_size) { struct sdhci_host *host; + struct device_node *np = pdev-dev.of_node; + struct sdhci_pltfm_host *pltfm_host; struct resource *iomem; int ret; @@ -141,6 +143,16 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, goto err; } + pltfm_host = sdhci_priv(host); + pltfm_host-endian_mode = LITTLE_ENDIAN_MODE; + +#ifdef CONFIG_OF + if (of_device_is_big_endian(np)) + pltfm_host-endian_mode = BIG_ENDIAN_MODE; + else + pltfm_host-endian_mode = LITTLE_ENDIAN_MODE; +#endif /* CONFIG_OF */ + host-hw_name = dev_name(pdev-dev); if (pdata pdata-ops) host-ops = pdata-ops; @@ -224,7 +236,7 @@ int sdhci_pltfm_unregister(struct platform_device *pdev) { struct sdhci_host *host = platform_get_drvdata(pdev); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); - int dead = (readl(host-ioaddr + SDHCI_INT_STATUS) == 0x); + int dead = (sdhci_readl(host, SDHCI_INT_STATUS) == 0x); sdhci_remove_host(host, dead); clk_disable_unprepare(pltfm_host-clk); diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h index 04bc248..a8cf954 100644 --- a/drivers/mmc/host/sdhci-pltfm.h +++ b/drivers/mmc/host/sdhci-pltfm.h @@ -28,6 +28,10 @@ struct sdhci_pltfm_host { /* migrate from sdhci_of_host */ unsigned int clock; u16 xfer_mode_shadow; + enum endian_mode { + LITTLE_ENDIAN_MODE, + BIG_ENDIAN_MODE, + } endian_mode; unsigned long private[0] cacheline_aligned; }; @@ -37,33 +41,61 @@ struct sdhci_pltfm_host { * These accessors are designed for big endian hosts doing I/O to * little endian controllers incorporating a 32-bit hardware byte swapper. */ -static inline u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg) +static inline void sdhci_clrsetbits(struct sdhci_host *host, u32 mask, + u32 val, int reg) { - return in_be32(host-ioaddr + reg); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + void __iomem *base = host-ioaddr + (reg ~0x3); + u32 shift = (reg 0x3) * 8; + + if (pltfm_host-endian_mode == BIG_ENDIAN_MODE) + iowrite32be(((ioread32be(base) ~(mask shift)) | + (val shift)), base); + else + iowrite32(((ioread32(base) ~(mask shift)) | + (val shift)), base); } -static inline u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg) +static inline u32 sdhci_32bs_readl(struct sdhci_host *host, int reg) { - return in_be16(host-ioaddr + (reg ^ 0x2)); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + + if (pltfm_host-endian_mode == BIG_ENDIAN_MODE) + return ioread32be(host-ioaddr + reg); + else + return ioread32(host-ioaddr + reg); } -static inline u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg) +static inline u16 sdhci_32bs_readw(struct sdhci_host *host, int reg) { - return in_8(host-ioaddr + (reg ^ 0x3)); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + + if (pltfm_host-endian_mode == BIG_ENDIAN_MODE) + return ioread16be(host-ioaddr + (reg ^ 0x2)); + else + return ioread16(host-ioaddr + (reg ^ 0x2)); } -static inline void sdhci_be32bs_writel(struct sdhci_host *host, - u32 val, int reg) +static inline u8 sdhci_32bs_readb(struct sdhci_host *host, int reg) { - out_be32(host-ioaddr + reg, val); + return ioread8(host-ioaddr + (reg ^ 0x3)); } -static inline void sdhci_be32bs_writew(struct sdhci_host *host, +static inline void sdhci_32bs_writel(struct sdhci_host *host, + u32 val, int reg) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + + if (pltfm_host-endian_mode == BIG_ENDIAN_MODE) + iowrite32be(val, host-ioaddr + reg); +
[v4, 1/6] mmc: dt: add DT binding for big endian controller
Add specification of 'big-endian' property. if the controller is big endian mode, specify this property in device tree node. The default endian mode is little endian. Signed-off-by: Yangbo Lu yangbo...@freescale.com --- Documentation/devicetree/bindings/mmc/mmc.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt index 0384fc3..10d0df9f 100644 --- a/Documentation/devicetree/bindings/mmc/mmc.txt +++ b/Documentation/devicetree/bindings/mmc/mmc.txt @@ -47,6 +47,8 @@ Optional properties: - mmc-hs400-1_2v: eMMC HS400 mode(1.2V I/O) is supported - dsr: Value the card's (optional) Driver Stage Register (DSR) should be programmed with. Valid range: [0 .. 0x]. +- big-endian: If the host controller is big-endian mode, specify this property. + The default endian mode is little-endian if no 'big-endian' property specified. *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line polarity properties, we have to fix the meaning of the normal and inverted -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] MMC/SDIO: enable SDIO device to suspend/resume asynchronously
Enable SDIO card and function device to suspend/resume asynchronously. This can improve system suspend/resume speed. Signed-off-by: Zhonghui Fu zhonghui...@linux.intel.com --- drivers/mmc/core/sdio.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index b91abed..6719b77 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -1106,6 +1106,8 @@ int mmc_attach_sdio(struct mmc_host *host) pm_runtime_enable(card-dev); } + device_enable_async_suspend(card-dev); + /* * The number of functions on the card is encoded inside * the ocr. @@ -1126,6 +1128,8 @@ int mmc_attach_sdio(struct mmc_host *host) */ if (host-caps MMC_CAP_POWER_OFF_CARD) pm_runtime_enable(card-sdio_func[i]-dev); + + device_enable_async_suspend(card-sdio_func[i]-dev); } /* -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/11] mmc: host: omap_hsmmc: Support vmmc_aux to switch to 1.8v
Add support for vmmc_aux to switch to 1.8v. Also use iov instead of vdd to indicate io voltage. This is in preparation for adding support for io signal voltage switch. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 47 +++-- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 6d52873..09e949f 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -243,10 +243,11 @@ static int omap_hsmmc_get_cover_state(struct device *dev) return mmc_gpio_get_cd(host-mmc); } -static int omap_hsmmc_enable_supply(struct mmc_host *mmc) +static int omap_hsmmc_enable_supply(struct mmc_host *mmc, int iov) { int ret; struct mmc_ios *ios = mmc-ios; + int uvoltage; if (mmc-supply.vmmc) { ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, ios-vdd); @@ -255,7 +256,24 @@ static int omap_hsmmc_enable_supply(struct mmc_host *mmc) } /* Enable interface voltage rail, if needed */ - if (mmc-supply.vqmmc !regulator_is_enabled(mmc-supply.vqmmc)) { + if (mmc-supply.vqmmc) { + if (regulator_is_enabled(mmc-supply.vqmmc)) { + ret = regulator_disable(mmc-supply.vqmmc); + if (ret) { + dev_err(mmc_dev(mmc), + vmmc_aux reg disable failed\n); + goto err_vqmmc; + } + } + + uvoltage = (iov == VDD_165_195) ? VDD_1V8 : VDD_3V0; + ret = regulator_set_voltage(mmc-supply.vqmmc, uvoltage, + uvoltage); + if (ret) { + dev_err(mmc_dev(mmc), vmmc_aux set voltage failed\n); + goto err_vqmmc; + } + ret = regulator_enable(mmc-supply.vqmmc); if (ret) { dev_err(mmc_dev(mmc), vmmc_aux reg enable failed\n); @@ -304,22 +322,19 @@ err_set_ocr: } static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on, - int vdd) + int iov) { int ret; + int uvoltage; if (!host-pbias) return 0; if (power_on) { - if (vdd = VDD_165_195) - ret = regulator_set_voltage(host-pbias, VDD_1V8, - VDD_1V8); - else - ret = regulator_set_voltage(host-pbias, VDD_3V0, - VDD_3V0); - if (ret 0) { - dev_err(host-dev, pbias set voltage fail\n); + uvoltage = (iov = VDD_165_195) ? VDD_1V8 : VDD_3V0; + ret = regulator_set_voltage(host-pbias, uvoltage, uvoltage); + if (ret) { + dev_err(host-dev, pbias set voltage failed\n); return ret; } @@ -343,7 +358,7 @@ static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on, return 0; } -static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) +static int omap_hsmmc_set_power(struct device *dev, int power_on, int iov) { struct omap_hsmmc_host *host = platform_get_drvdata(to_platform_device(dev)); @@ -358,7 +373,7 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) return 0; if (mmc_pdata(host)-before_set_reg) - mmc_pdata(host)-before_set_reg(dev, power_on, vdd); + mmc_pdata(host)-before_set_reg(dev, power_on, iov); ret = omap_hsmmc_set_pbias(host, false, 0); if (ret) @@ -378,11 +393,11 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) * chips/cards need an interface voltage rail too. */ if (power_on) { - ret = omap_hsmmc_enable_supply(mmc); + ret = omap_hsmmc_enable_supply(mmc, iov); if (ret) return ret; - ret = omap_hsmmc_set_pbias(host, true, vdd); + ret = omap_hsmmc_set_pbias(host, true, iov); if (ret) goto err_set_voltage; } else { @@ -392,7 +407,7 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) } if (mmc_pdata(host)-after_set_reg) - mmc_pdata(host)-after_set_reg(dev, power_on, vdd); + mmc_pdata(host)-after_set_reg(dev, power_on, iov); return 0; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at
[PATCH 11/11] mmc: host: omap_hsmmc: add software timer when timeout greater than hardware capablility
From: Mugunthan V N mugunthan...@ti.com DRA7 Errata No i834: When using high speed HS200 and SDR104 cards, the functional clock for MMC module will be 192MHz. At this frequency, the maximum obtainable timeout (DTO =0xE) in hardware is (1/192MHz)*2^27 = 700ms. Commands taking longer than 700ms will be affected by this small window frame and will be timing out frequently even without a genune timeout from the card. Workarround for this errata is use a software timer instead of hardware timer to provide the delay requested by the upper layer So adding a software timer as a work around for the errata. Instead of using software timeout only for larger delays requested when using HS200/SDR104 cards which results in hardware and software timer race conditions, so move all the timeout request to use software timer when HS200/SDR104 card is connected and use hardware timer when other type cards are connected. Also start the software timer after queueing to DMA to ensure we are more likely to expire within correct limits. To be ever more sure that we won't expire this soft timer too early, we're adding a 100ns slack to the data timeout requested by the upper layer. Signed-off-by: Mugunthan V N mugunthan...@ti.com Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 71 +++-- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 6b02c7c..3a02f86 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -168,6 +168,7 @@ #define ACNE (1 0) #define MMC_AUTOSUSPEND_DELAY 100 +#define MMC_SOFT_TIMER_SLACK 100 /* ns */ #define MMC_TIMEOUT_MS 20 /* 20 mSec */ #define MMC_TIMEOUT_US 2 /* 2 micro Sec */ #define OMAP_MMC_MIN_CLOCK 40 @@ -245,6 +246,10 @@ struct omap_hsmmc_host { struct omap_hsmmc_next next_data; struct omap_hsmmc_platform_data*pdata; + struct timer_list timer; + unsigned long data_timeout; + unsigned intneed_i834_errata:1; + u32 *tuning_data; int tuning_size; @@ -661,8 +666,8 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host, irq_mask = ~(BRR_EN | BWR_EN); } - /* Disable timeout for erases */ - if (cmd-opcode == MMC_ERASE) + /* Disable timeout for erases or when using software timeout */ + if (cmd-opcode == MMC_ERASE || host-need_i834_errata) irq_mask = ~DTO_EN; spin_lock_irqsave(host-irq_lock, flags); @@ -752,6 +757,22 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host) OMAP_HSMMC_WRITE(host-base, HCTL, regval); } + /* +* DRA7 Errata No i834: When using high speed HS200 and SDR104 +* cards, the functional clock for MMC module will be 192MHz. +* At this frequency, the maximum obtainable timeout (DTO =0xE) +* in hardware is (1/192MHz)*2^27 = 700ms. Commands taking longer +* than 700ms will be affected by this small window frame and +* will be timing out frequently even without a genune timeout +* from the card. Workarround for this errata is use a software +* timer instead of hardware timer to provide the delay requested +* by the upper layer +*/ + if (ios-clock == 19200) + host-need_i834_errata = true; + else + host-need_i834_errata = false; + omap_hsmmc_start_clock(host); } @@ -1298,6 +1319,16 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) int status; status = OMAP_HSMMC_READ(host-base, STAT); + + /* +* During a successful bulk data transfer command-completion +* interrupt and transfer-completion interrupt will be generated, +* but software-timeout timer should be deleted only on non-CC +* interrupts (transfer complete or error) +*/ + if (host-need_i834_errata (status (~CC_EN))) + del_timer(host-timer); + while (status (INT_EN_MASK | CIRQ_EN)) { if (host-req_in_progress) omap_hsmmc_do_irq(host, status); @@ -1312,6 +1343,13 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) return IRQ_HANDLED; } +static void omap_hsmmc_soft_timeout(unsigned long data) +{ + struct omap_hsmmc_host *host = (struct omap_hsmmc_host *)data; + + hsmmc_command_incomplete(host, -ETIMEDOUT, 0); +} + static void set_sd_bus_power(struct omap_hsmmc_host *host) { unsigned long i; @@ -1513,6 +1551,22 @@ static void set_data_timeout(struct omap_hsmmc_host *host, if (clkd == 0) clkd = 1; + if (host-need_i834_errata) { + unsigned long delta; + +
[PATCH 08/11] mmc: host: omap_hsmmc: Workaround for errata id i802
According to errata i802, DCRC error interrupts (MMCHS_STAT[21] DCRC=0x1) can occur during the tuning procedure. The DCRC interrupt, occurs when the last tuning block fails (the last ratio tested). The delay from CRC check until the interrupt is asserted is bigger than the delay until assertion of the tuning end flag. Assertion of tuning end flag is what masks the interrupts. Because of this race, an erroneous DCRC interrupt occurs. The suggested workaround is to disable DCRC interrupts during the tuning procedure which is implemented here. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Signed-off-by: Sekhar Nori nsek...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index dcfa92e..96dd406 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -656,8 +656,17 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host, is_tuning = (cmd-opcode == MMC_SEND_TUNING_BLOCK) || (cmd-opcode == MMC_SEND_TUNING_BLOCK_HS200); - if (!is_tuning host-use_dma) + if (is_tuning) { + /* +* OMAP5/DRA74X/DRA72x Errata i802: +* DCRC error interrupts (MMCHS_STAT[21] DCRC=0x1) can occur +* during the tuning procedure. So disable it during the +* tuning procedure. +*/ + irq_mask = ~DCRC_EN; + } else if (host-use_dma) { irq_mask = ~(BRR_EN | BWR_EN); + } /* Disable timeout for erases */ if (cmd-opcode == MMC_ERASE) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/11] mmc: host: omap_hsmmc: remove incorrect voltage switch sequence
ios-vdd is set only in mmc_power_up and mmc_power_off and not in mmc_select_voltage as mentioned in the code comment. This seems to be legacy code that has been carried for a long time without being tested. This will be replaced with a proper voltage switch sequence and populated in start_signal_voltage_switch ops to be used by mmc core for switching voltages. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 81 - 1 file changed, 81 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 26010a3..6b02c7c 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1325,69 +1325,6 @@ static void set_sd_bus_power(struct omap_hsmmc_host *host) } } -/* - * Switch MMC interface voltage ... only relevant for MMC1. - * - * MMC2 and MMC3 use fixed 1.8V levels, and maybe a transceiver. - * The MMC2 transceiver controls are used instead of DAT4..DAT7. - * Some chips, like eMMC ones, use internal transceivers. - */ -static int omap_hsmmc_switch_opcond(struct omap_hsmmc_host *host, int vdd) -{ - u32 reg_val = 0; - int ret; - - /* Disable the clocks */ - pm_runtime_put_sync(host-dev); - if (host-dbclk) - clk_disable_unprepare(host-dbclk); - - /* Turn the power off */ - ret = mmc_pdata(host)-set_power(host-dev, 0, 0); - - /* Turn the power ON with given VDD 1.8 or 3.0v */ - if (!ret) - ret = mmc_pdata(host)-set_power(host-dev, 1, vdd); - pm_runtime_get_sync(host-dev); - if (host-dbclk) - clk_prepare_enable(host-dbclk); - - if (ret != 0) - goto err; - - OMAP_HSMMC_WRITE(host-base, HCTL, - OMAP_HSMMC_READ(host-base, HCTL) SDVSCLR); - reg_val = OMAP_HSMMC_READ(host-base, HCTL); - - /* -* If a MMC dual voltage card is detected, the set_ios fn calls -* this fn with VDD bit set for 1.8V. Upon card removal from the -* slot, omap_hsmmc_set_ios sets the VDD back to 3V on MMC_POWER_OFF. -* -* Cope with a bit of slop in the range ... per data sheets: -* - 1.8V for vdds_mmc1/vdds_mmc1a can be up to 2.45V max, -*but recommended values are 1.71V to 1.89V -* - 3.0V for vdds_mmc1/vdds_mmc1a can be up to 3.5V max, -*but recommended values are 2.7V to 3.3V -* -* Board setup code shouldn't permit anything very out-of-range. -* TWL4030-family VMMC1 and VSIM regulators are fine (avoiding the -* middle range) but VSIM can't power DAT4..DAT7 at more than 3V. -*/ - if ((1 vdd) = MMC_VDD_23_24) - reg_val |= SDVS18; - else - reg_val |= SDVS30; - - OMAP_HSMMC_WRITE(host-base, HCTL, reg_val); - set_sd_bus_power(host); - - return 0; -err: - dev_err(mmc_dev(host-mmc), Unable to switch operating voltage\n); - return ret; -} - /* Protect the card while the cover is open */ static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host) { @@ -1799,24 +1736,6 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) omap_hsmmc_set_bus_width(host); - if (host-pdata-controller_flags OMAP_HSMMC_SUPPORTS_DUAL_VOLT) { - /* Only MMC1 can interface at 3V without some flavor -* of external transceiver; but they all handle 1.8V. -*/ - if ((OMAP_HSMMC_READ(host-base, HCTL) SDVSDET) - (ios-vdd == DUAL_VOLT_OCR_BIT)) { - /* -* The mmc_select_voltage fn of the core does -* not seem to set the power_mode to -* MMC_POWER_UP upon recalculating the voltage. -* vdd 1.8v. -*/ - if (omap_hsmmc_switch_opcond(host, ios-vdd) != 0) - dev_dbg(mmc_dev(host-mmc), - Switch operation failed\n); - } - } - omap_hsmmc_set_clock(host); if (ios-timing != host-timing) { -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 06/11] mmc: host: omap_hsmmc: set timing in the UHSMS field
Add a separate function to set the UHSMS field to one of SDR104, SDR50, DDR50, SDR25 or SDR12 depending on the inserted SD card. This is required for tuning to succeed in the case of SDR104/HS200 or SDR50. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 49 + 1 file changed, 49 insertions(+) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 0452a8b..e0bd8df 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -114,6 +114,13 @@ /* AC12 */ #define AC12_V1V8_SIGEN(1 19) +#define AC12_UHSMC_MASK(7 16) +#define AC12_UHSMC_SDR12 (0 16) +#define AC12_UHSMC_SDR25 (1 16) +#define AC12_UHSMC_SDR50 (2 16) +#define AC12_UHSMC_SDR104 (3 16) +#define AC12_UHSMC_DDR50 (4 16) +#define AC12_UHSMC_RES (0x7 16) /* Interrupt masks for IE and ISE register */ #define CC_EN (1 0) @@ -198,6 +205,7 @@ struct omap_hsmmc_host { unsigned intdma_sg_idx; unsigned char bus_mode; unsigned char power_mode; + unsigned char timing; int suspended; u32 con; u32 hctl; @@ -1658,6 +1666,41 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) omap_hsmmc_start_command(host, req-cmd, req-data); } +static void omap_hsmmc_set_timing(struct omap_hsmmc_host *host) +{ + u32 val; + struct mmc_ios *ios = host-mmc-ios; + + omap_hsmmc_stop_clock(host); + + val = OMAP_HSMMC_READ(host-base, AC12); + val = ~AC12_UHSMC_MASK; + switch (ios-timing) { + case MMC_TIMING_UHS_SDR104: + case MMC_TIMING_MMC_HS200: + val |= AC12_UHSMC_SDR104; + break; + case MMC_TIMING_UHS_DDR50: + val |= AC12_UHSMC_DDR50; + break; + case MMC_TIMING_UHS_SDR50: + val |= AC12_UHSMC_SDR50; + break; + case MMC_TIMING_UHS_SDR25: + val |= AC12_UHSMC_SDR25; + break; + case MMC_TIMING_UHS_SDR12: + val |= AC12_UHSMC_SDR12; + break; + default: + val |= AC12_UHSMC_RES; + break; + } + OMAP_HSMMC_WRITE(host-base, AC12, val); + + omap_hsmmc_start_clock(host); +} + /* Routine to configure clock values. Exposed API to core */ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { @@ -1706,6 +1749,11 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) omap_hsmmc_set_clock(host); + if (ios-timing != host-timing) { + omap_hsmmc_set_timing(host); + host-timing = ios-timing; + } + if (do_send_init_stream) send_init_stream(host); @@ -2194,6 +2242,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) host-mapbase = res-start + pdata-reg_offset; host-base = base + pdata-reg_offset; host-power_mode = MMC_POWER_OFF; + host-timing= 0; host-next_data.cookie = 1; ret = omap_hsmmc_gpio_init(mmc, host, pdata); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 07/11] mmc: host: omap_hsmmc: add tuning support
From: Balaji T K balaj...@ti.com MMC tuning procedure is required to support SD card UHS1-SDR104 mode and EMMC HS200 mode. The tuning function omap_execute_tuning() will only be called by the MMC/SD core if the corresponding speed modes are supported by the OMAP silicon which is set in the mmc host caps field. Signed-off-by: Balaji T K balaj...@ti.com Signed-off-by: Viswanath Puttagunta vi...@ti.com Signed-off-by: Sourav Poddar sourav.pod...@ti.com [kis...@ti.com : cleanup the tuning sequence] Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 234 - 1 file changed, 232 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index e0bd8df..dcfa92e 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -18,6 +18,7 @@ #include linux/module.h #include linux/init.h #include linux/kernel.h +#include linux/slab.h #include linux/debugfs.h #include linux/dmaengine.h #include linux/seq_file.h @@ -49,6 +50,7 @@ /* OMAP HSMMC Host Controller Registers */ #define OMAP_HSMMC_SYSSTATUS 0x0014 #define OMAP_HSMMC_CON 0x002C +#define OMAP_HSMMC_DLL 0x0034 #define OMAP_HSMMC_SDMASA 0x0100 #define OMAP_HSMMC_BLK 0x0104 #define OMAP_HSMMC_ARG 0x0108 @@ -66,6 +68,7 @@ #define OMAP_HSMMC_ISE 0x0138 #define OMAP_HSMMC_AC120x013C #define OMAP_HSMMC_CAPA0x0140 +#define OMAP_HSMMC_CAPA2 0x0144 #define VS18 (1 26) #define VS30 (1 25) @@ -114,6 +117,7 @@ /* AC12 */ #define AC12_V1V8_SIGEN(1 19) +#define AC12_SCLK_SEL (1 23) #define AC12_UHSMC_MASK(7 16) #define AC12_UHSMC_SDR12 (0 16) #define AC12_UHSMC_SDR25 (1 16) @@ -122,6 +126,18 @@ #define AC12_UHSMC_DDR50 (4 16) #define AC12_UHSMC_RES (0x7 16) +/* DLL */ +#define DLL_SWT(1 20) +#define DLL_FORCE_SR_C_SHIFT 13 +#define DLL_FORCE_SR_C_MASK0x7f +#define DLL_FORCE_VALUE(1 12) +#define DLL_CALIB (1 1) + +#define MAX_PHASE_DELAY0x7c + +/* CAPA2 */ +#define CAPA2_TSDR50 (1 13) + /* Interrupt masks for IE and ISE register */ #define CC_EN (1 0) #define TC_EN (1 1) @@ -201,6 +217,7 @@ struct omap_hsmmc_host { void__iomem *base; resource_size_t mapbase; spinlock_t irq_lock; /* Prevent races with irq handler */ + struct completion buf_ready; unsigned intdma_len; unsigned intdma_sg_idx; unsigned char bus_mode; @@ -228,6 +245,9 @@ struct omap_hsmmc_host { struct omap_hsmmc_next next_data; struct omap_hsmmc_platform_data*pdata; + u32 *tuning_data; + int tuning_size; + /* return MMC cover switch state, can be NULL if not supported. * * possible return values: @@ -244,8 +264,39 @@ struct omap_mmc_of_data { u8 controller_flags; }; +static const u8 ref_tuning_4bits[] = { + 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, + 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, + 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, + 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, + 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, + 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, + 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, + 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, +}; + +static const u8 ref_tuning_8bits[] = { + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, + 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, + 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, + 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, + 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, + 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, + 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, + 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, + 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, + 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, + 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, + 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, + 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, + 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, +}; + static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host); static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host, int iov); +static void omap_hsmmc_disable_tuning(struct omap_hsmmc_host *host); static int omap_hsmmc_card_detect(struct device *dev) { @@ -600,8 +651,12 @@ static void
[PATCH 04/11] mmc: host: omap_hsmmc: add voltage switch support for UHS SD card
From: Balaji T K balaj...@ti.com UHS sd card i/o data line can operate at 3V and 1.8V on UHS speed modes. Add support for signal voltage switch and check for card_busy. Signed-off-by: Balaji T K balaj...@ti.com Signed-off-by: Sourav Poddar sourav.pod...@ti.com [kis...@ti.com : cleanup the voltage switch sequence] Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 129 + 1 file changed, 129 insertions(+) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 306e5c0..e960b5c 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -112,6 +112,9 @@ /* PSTATE */ #define DLEV_DAT(x)(1 (20 + (x))) +/* AC12 */ +#define AC12_V1V8_SIGEN(1 19) + /* Interrupt masks for IE and ISE register */ #define CC_EN (1 0) #define TC_EN (1 1) @@ -151,6 +154,12 @@ #define VDD_1V8180 /* 18 uV */ #define VDD_3V0300 /* 30 uV */ #define VDD_165_195(ffs(MMC_VDD_165_195) - 1) +#define VDD_30_31 (ffs(MMC_VDD_30_31) - 1) + +#define CON_CLKEXTFREE (1 16) +#define CON_PADEN (1 15) +#define PSTATE_CLEV(1 24) +#define PSTATE_DLEV(0xF 20) /* * One controller can have multiple slots, like on some omap boards using @@ -1851,6 +1860,124 @@ static int omap_hsmmc_multi_io_quirk(struct mmc_card *card, return blk_size; } +static int omap_hsmmc_start_signal_voltage_switch(struct mmc_host *mmc, + struct mmc_ios *ios) +{ + struct omap_hsmmc_host *host; + u32 val = 0; + int ret = 0; + + host = mmc_priv(mmc); + + if (ios-signal_voltage == MMC_SIGNAL_VOLTAGE_330) { + val = OMAP_HSMMC_READ(host-base, CAPA); + if (!(val VS30)) + return -EOPNOTSUPP; + + omap_hsmmc_conf_bus_power(host, ios-signal_voltage); + + val = OMAP_HSMMC_READ(host-base, AC12); + val = ~AC12_V1V8_SIGEN; + OMAP_HSMMC_WRITE(host-base, AC12, val); + + ret = mmc_pdata(host)-set_power(host-dev, 1, VDD_30_31); + if (ret) { + dev_dbg(mmc_dev(host-mmc), failed to switch to 3v\n); + return ret; + } + + dev_dbg(mmc_dev(host-mmc), i/o voltage switch to 3V\n); + } else if (ios-signal_voltage == MMC_SIGNAL_VOLTAGE_180) { + val = OMAP_HSMMC_READ(host-base, CAPA); + if (!(val VS18)) + return -EOPNOTSUPP; + + omap_hsmmc_conf_bus_power(host, ios-signal_voltage); + + val = OMAP_HSMMC_READ(host-base, AC12); + val |= AC12_V1V8_SIGEN; + OMAP_HSMMC_WRITE(host-base, AC12, val); + + ret = mmc_pdata(host)-set_power(host-dev, 1, VDD_165_195); + if (ret 0) { + dev_dbg(mmc_dev(host-mmc), failed to switch 1.8v\n); + return ret; + } + } else { + return -EOPNOTSUPP; + } + + return 0; +} + +static int omap_hsmmc_card_busy_low(struct omap_hsmmc_host *host) +{ + u32 val; + unsigned long timeout; + + val = OMAP_HSMMC_READ(host-base, CON); + val = ~CON_CLKEXTFREE; + val |= CON_PADEN; + OMAP_HSMMC_WRITE(host-base, CON, val); + + timeout = jiffies + msecs_to_jiffies(1); + do { + val = OMAP_HSMMC_READ(host-base, PSTATE); + if (!(val (PSTATE_CLEV | PSTATE_DLEV))) + return true; + + usleep_range(100, 200); + } while (!time_after(jiffies, timeout)); + + dev_err(mmc_dev(host-mmc), timeout : i/o low 0x%x\n, val); + + return false; +} + +static int omap_hsmmc_card_busy_high(struct omap_hsmmc_host *host) +{ + u32 val; + unsigned long timeout; + + val = OMAP_HSMMC_READ(host-base, CON); + val |= CLKEXTFREE; + OMAP_HSMMC_WRITE(host-base, CON, val); + + timeout = jiffies + msecs_to_jiffies(1); + do { + val = OMAP_HSMMC_READ(host-base, PSTATE); + if ((val PSTATE_CLEV) (val PSTATE_DLEV)) { + val = OMAP_HSMMC_READ(host-base, CON); + val = ~(CON_CLKEXTFREE | CON_PADEN); + OMAP_HSMMC_WRITE(host-base, CON, val); + return false; + } + + usleep_range(100, 200); + } while (!time_after(jiffies, timeout)); + + dev_err(mmc_dev(host-mmc), timeout : i/o high 0x%x\n, val); + + return true; +} + +static int omap_hsmmc_card_busy(struct mmc_host *mmc) +{ + struct omap_hsmmc_host *host; + u32 val; + int ret; + + host
[PATCH 05/11] mmc: host: omap_hsmmc: set clk rate to the max frequency
Set the clock rate of the functional clock to the max frequency that is passed to the driver either using pdata or dt. Also remove unnecessary setting of host-fclk to NULL. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c |7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index e960b5c..0452a8b 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2219,7 +2219,12 @@ static int omap_hsmmc_probe(struct platform_device *pdev) host-fclk = devm_clk_get(pdev-dev, fck); if (IS_ERR(host-fclk)) { ret = PTR_ERR(host-fclk); - host-fclk = NULL; + goto err1; + } + + ret = clk_set_rate(host-fclk, mmc-f_max); + if (ret) { + dev_err(pdev-dev, failed to set clock to %d\n, mmc-f_max); goto err1; } -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/11] mmc: host: omap_hsmmc: program HCTL based on signal_voltage set by mmc core
HCTL is now set based on ios.signal_voltage set by mmc core and not hardcoded to 3V0 if OMAP_HSMMC_SUPPORTS_DUAL_VOLT is set. If OMAP_HSMMC_SUPPORTS_DUAL_VOLT is set, it means HCTL can be set to either 3V0 or 1V8. And it should be set to 3V0 or 1V8 depending on ios.signal_voltage. Also it is now set on power mode status being changed to MMC_POWER_ON. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 16 +++- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 2dfef11..306e5c0 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -228,6 +228,7 @@ struct omap_mmc_of_data { }; static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host); +static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host, int iov); static int omap_hsmmc_card_detect(struct device *dev) { @@ -1665,6 +1666,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) mmc_pdata(host)-set_power(host-dev, 1, ios-vdd); break; case MMC_POWER_ON: + omap_hsmmc_conf_bus_power(host, ios-signal_voltage); do_send_init_stream = 1; break; } @@ -1827,17 +1829,12 @@ static void omap_hsmmc_set_capabilities(struct omap_hsmmc_host *host) OMAP_HSMMC_WRITE(host-base, CAPA, val); } -static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) +static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host, int iov) { u32 hctl, value; - /* Only MMC1 supports 3.0V */ - if (host-pdata-controller_flags OMAP_HSMMC_SUPPORTS_DUAL_VOLT) - hctl = SDVS30; - else - hctl = SDVS18; - value = OMAP_HSMMC_READ(host-base, HCTL) ~SDVS_MASK; + hctl = (iov == MMC_SIGNAL_VOLTAGE_180) ? SDVS18 : SDVS30; OMAP_HSMMC_WRITE(host-base, HCTL, value | hctl); /* Set SD bus power bit */ @@ -2143,7 +2140,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev) mmc-pm_caps |= mmc_pdata(host)-pm_caps; omap_hsmmc_set_capabilities(host); - omap_hsmmc_conf_bus_power(host); if (!pdev-dev.of_node) { res = platform_get_resource_byname(pdev, IORESOURCE_DMA, tx); @@ -2318,6 +2314,7 @@ static int omap_hsmmc_suspend(struct device *dev) static int omap_hsmmc_resume(struct device *dev) { struct omap_hsmmc_host *host = dev_get_drvdata(dev); + struct mmc_ios *ios; if (!host) return 0; @@ -2327,8 +2324,9 @@ static int omap_hsmmc_resume(struct device *dev) if (host-dbclk) clk_prepare_enable(host-dbclk); + ios = host-mmc-ios; if (!(host-mmc-pm_flags MMC_PM_KEEP_POWER)) - omap_hsmmc_conf_bus_power(host); + omap_hsmmc_conf_bus_power(host, ios-signal_voltage); omap_hsmmc_protect_card(host); pm_runtime_mark_last_busy(host-dev); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/11] mmc: host: omap_hsmmc: separate setting voltage capabilities from bus power
Added a separate function to set the voltage capabilities of the host controller. Voltage capabilities should be set only once during controller initialization but bus power can be changed every time there is a voltage switch and whenever a different card is inserted. This allows omap_hsmmc_conf_bus_power to be invoked every time there is a voltage switch. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 28 +++- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 09e949f..2dfef11 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1812,25 +1812,34 @@ err: return ret; } +static void omap_hsmmc_set_capabilities(struct omap_hsmmc_host *host) +{ + u32 val; + + val = OMAP_HSMMC_READ(host-base, CAPA); + + /* Only MMC1 supports 3.0V */ + if (host-pdata-controller_flags OMAP_HSMMC_SUPPORTS_DUAL_VOLT) + val |= (VS30 | VS18); + else + val |= VS18; + + OMAP_HSMMC_WRITE(host-base, CAPA, val); +} + static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) { - u32 hctl, capa, value; + u32 hctl, value; /* Only MMC1 supports 3.0V */ - if (host-pdata-controller_flags OMAP_HSMMC_SUPPORTS_DUAL_VOLT) { + if (host-pdata-controller_flags OMAP_HSMMC_SUPPORTS_DUAL_VOLT) hctl = SDVS30; - capa = VS30 | VS18; - } else { + else hctl = SDVS18; - capa = VS18; - } value = OMAP_HSMMC_READ(host-base, HCTL) ~SDVS_MASK; OMAP_HSMMC_WRITE(host-base, HCTL, value | hctl); - value = OMAP_HSMMC_READ(host-base, CAPA); - OMAP_HSMMC_WRITE(host-base, CAPA, value | capa); - /* Set SD bus power bit */ set_sd_bus_power(host); } @@ -2133,6 +2142,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) mmc-pm_caps |= mmc_pdata(host)-pm_caps; + omap_hsmmc_set_capabilities(host); omap_hsmmc_conf_bus_power(host); if (!pdev-dev.of_node) { -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 00/11] omap_hsmmc: voltage switching and tuning
Patch series implements voltage switching and tuning for omap_hsmmc driver. Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM, Beaglebone black, OMAP5 uEVM and OMAP4 PANDA. Balaji T K (2): mmc: host: omap_hsmmc: add voltage switch support for UHS SD card mmc: host: omap_hsmmc: add tuning support Kishon Vijay Abraham I (8): mmc: host: omap_hsmmc: Support pbias and vmmc_aux to switch to 1.8v mmc: host: omap_hsmmc: separate setting voltage capabilities from bus power mmc: host: omap_hsmmc: program HCTL based on signal_voltage set by mmc core mmc: host: omap_hsmmc: set clk rate to the max frequency mmc: host: omap_hsmmc: set timing in the UHSMS field mmc: host: omap_hsmmc: Workaround for errata id i802 mmc: host: omap_hsmmc: Allow io voltage switch even for fixed vdd mmc: host: omap_hsmmc: remove incorrect voltage switch sequence Mugunthan V N (1): mmc: host: omap_hsmmc: add software timer when timeout greater than hardware capablility drivers/mmc/host/omap_hsmmc.c | 670 + 1 file changed, 547 insertions(+), 123 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/7] ARM: dts: dra7-evm: Fix spurious card insert/removal interrupt
ldo1_reg in addition to being connected to the io lines is also connected to the card detect line. On card removal, omap_hsmmc driver does a regulator_disable causing card detect line to be pulled down. This raises a card insertion interrupt and once the MMC core detects there is no card inserted, it does a regulator disable which again raises a card insertion interrupt. This happens in a loop causing infinite MMC interrupts. Fix it by making ldo1_reg as always_on. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- arch/arm/boot/dts/dra7-evm.dts |1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index 25f0a00..a6c82e5 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -358,6 +358,7 @@ regulator-name = ldo1; regulator-min-microvolt = 180; regulator-max-microvolt = 330; + regulator-always-on; regulator-boot-on; }; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/7] ARM: dts: dra72-evm: Fix spurious card insert/removal interrupt
ldo1_reg in addition to being connected to the io lines is also connected to the card detect line. On card removal, omap_hsmmc driver does a regulator_disable causing card detect line to be pulled down. This raises a card insertion interrupt and once the MMC core detects there is no card inserted, it does a regulator disable which again raises a card insertion interrupt. This happens in a loop causing infinite MMC interrupts. Fix it by making ldo1_reg as always_on. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- arch/arm/boot/dts/dra72-evm.dts |1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts index c5d8e7d..45f11a0 100644 --- a/arch/arm/boot/dts/dra72-evm.dts +++ b/arch/arm/boot/dts/dra72-evm.dts @@ -295,6 +295,7 @@ regulator-name = ldo1; regulator-min-microvolt = 180; regulator-max-microvolt = 330; + regulator-always-on; regulator-boot-on; }; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/7] ARM: dts: dra7-evm: Add MMCSD card removal GPIO
From: Nishanth Menon n...@ti.com SDMMC Card Detect can be used over default GPIO map. Reported-by: Yan Liu yan-...@ti.com Signed-off-by: Nishanth Menon n...@ti.com Signed-off-by: Sekhar Nori nsek...@ti.com Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- arch/arm/boot/dts/dra7-evm.dts |5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index 1e0c88e..25f0a00 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -474,6 +474,11 @@ vmmc-supply = evm_3v3_sd; vmmc_aux-supply = ldo1_reg; bus-width = 4; + /* +* SDCD signal is not being used here - using the fact that GPIO mode +* is always hardwired. +*/ + cd-gpios = gpio6 27 0; }; mmc2 { -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/7] ARM: dts: MMC fixes for DRA7 based boards
Miscellaneous fixes in dts files for MMC device tree nodes. Did basic read/write test in J6, J6 Eco and Beagle-x15 Balaji T K (1): ARM: dts: dra7-evm: add evm_3v3_sd regulator Kishon Vijay Abraham I (5): ARM: dts: dra72-evm: add evm_3v3_sd regulator ARM: dts: dra72-evm: Set max clock frequency of MMC1 and MMC2 ARM: dts: am57xx-beagle-x15: mmc1: remove redundant pbias-supply property ARM: dts: dra7-evm: Fix spurious card insert/removal interrupt ARM: dts: dra72-evm: Fix spurious card insert/removal interrupt Nishanth Menon (1): ARM: dts: dra7-evm: Add MMCSD card removal GPIO arch/arm/boot/dts/am57xx-beagle-x15.dts |1 - arch/arm/boot/dts/dra7-evm.dts | 18 +- arch/arm/boot/dts/dra72-evm.dts | 16 ++-- 3 files changed, 31 insertions(+), 4 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/7] ARM: dts: dra72-evm: Set max clock frequency of MMC1 and MMC2
MMC1 supports SDR104 and MMC2 supports HS200 both of which requires 192MHz clock. Set the maximum operating clock frequency to 192 MHz. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- arch/arm/boot/dts/dra72-evm.dts |2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts index 3998d37..c5d8e7d 100644 --- a/arch/arm/boot/dts/dra72-evm.dts +++ b/arch/arm/boot/dts/dra72-evm.dts @@ -508,6 +508,7 @@ * is a viable alternative */ cd-gpios = gpio6 27 0; + max-frequency = 19200; }; mmc2 { @@ -519,6 +520,7 @@ vmmc-supply = evm_3v3; bus-width = 8; ti,non-removable; + max-frequency = 19200; }; dra7_pmx_core { -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Virtex-5 FPGA PCIE single-function device
[+cc Naveen] On Wed, Jul 29, 2015 at 05:31:59PM +0530, Muni Sekhar wrote: [ Please keep me in CC as I'm not subscribed to the list] Hello, We are using the “Virtex-5 FPGA Integrated Endpoint Block for PCI Express” in Linux platform. It supports only a single-function(Header Type, Bit 7 is zero), but actually it is having different functions in different Bar’s. It has UART hardware module implemented in the first Base Address Register and MMC host controller in other Base Address Register. This is a really screwed up device. Naveen asked about a similar device recently [1], and I answered: The PCI infrastructure is designed such that a bus/device/function address identifies a single device. To that device, we can attach a single driver, which manages all BARs on that device. There is no provision for attaching one driver to BAR0 and a different driver to BAR1. To manage the device you describe, you'd have to have a driver that claims the entire PCI device, including both BARs. That driver would internally deal with the UART, GPIO, 1-wire prom, and SD host controller modules. We are planning to develop our own pcie based uart driver for UART hardware and planning to use the MMC kernel stack for MMC host controller. By default MMC kernel stack gets attached to this device. In the pcie based uart driver, tried configuring the uart module after getting the pci_dev structure with pci_get_device(not used the pci_register_driver). After that I could able to communicate with the UART registers even though MMC stack is attached to the device. This might work, but it's an ugly hack. It's not at all how the PCI core is designed, and subverting the design like this may cause problems down the road. Now I am puzzled and stuck with how to proceed further on UART Interrupt Service Routine for this kind of device. Can I use request_irq() for uart isr, do you have any suggestion on this? You'd either have to write some kind of wrapper driver that claims the whole device and make its ISR figure out which device is interrupting and call either the UART or the MMC ISR, or hack up the MMC ISR to do something similar. If you have a choice, I suggest switching to a better-designed device. This one sounds like it's just broken, and I think it's going to be a headache to deal with it in software. Bjorn [1] http://lkml.kernel.org/r/CAG0bkv+Sve7+XWtGk-kkQU=-64CPbpE=5rmbvq-rzwngg--...@mail.gmail.com -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[SHDCI] Heavy (thousands) DMA leaks
Hi, after commit 348487cb28e66b032bae1b38424d81bf5b08 Author: Haibo Chen haibo.c...@freescale.com Date: Tue Dec 9 17:04:05 2014 +0800 mmc: sdhci: use pipeline mmc requests to improve performance I see heavy DMA leaks which result in warnings of the dma api debug code: WARNING: CPU: 0 PID: 0 at lib/dma-debug.c:509 add_dma_entry+0x138/0x150() DMA-API: exceeded 7 overlapping mappings of cacheline 0x0b20ec00 And mainly this one upon sdhci module removal. It is over 4000 leaked mappings during one card transfer. mmc0: card e624 removed [ cut here ] WARNING: CPU: 2 PID: 1263 at lib/dma-debug.c:974 dma_debug_device_change+0x158/0x1c0() pci :02:00.0: DMA-API: device driver has pending DMA allocations while released from device [count=4041] One of leaked entries details: [device address=0xddff] [size=65536 bytes] [mapped with DMA_FROM_DEVICE] [mapped as scather-gather] Modules linked in: CPU: 2 PID: 1263 Comm: bash Tainted: GW 4.2.0-rc4 #12 Hardware name: LENOVO 23252SG/23252SG, BIOS G2ET33WW (1.13 ) 07/24/2012 81cc5e32 8800d03c3b68 81820938 8800d03c3bb8 8800d03c3ba8 810b827a 000100260021 88030e50 0fc9 88030d95aeb8 88030e4ddd68 Call Trace: [81820938] dump_stack+0x4c/0x6e [810b827a] warn_slowpath_common+0x8a/0xc0 [810b82f6] warn_slowpath_fmt+0x46/0x50 [813248c8] dma_debug_device_change+0x158/0x1c0 [810d4e9d] notifier_call_chain+0x4d/0x80 [810d51fd] __blocking_notifier_call_chain+0x4d/0x70 [810d5236] blocking_notifier_call_chain+0x16/0x20 [814db395] __device_release_driver+0x105/0x130 [814db3e3] device_release_driver+0x23/0x30 [814d95ca] unbind_store+0xba/0xe0 [8123c638] ? kernfs_fop_write+0xe8/0x170 [814d8ac4] drv_attr_store+0x24/0x30 [8123ce4a] sysfs_kf_write+0x3a/0x50 [8123c670] kernfs_fop_write+0x120/0x170 [811ce9e8] __vfs_write+0x28/0xe0 [811d1209] ? __sb_start_write+0x49/0xe0 [810e3ba5] ? local_clock+0x25/0x30 [811cf041] vfs_write+0xa1/0x170 [810e43c4] ? vtime_account_user+0x54/0x60 [811cfce6] SyS_write+0x46/0xa0 [81180f83] ? context_tracking_user_exit+0x13/0x20 [8182a017] entry_SYSCALL_64_fastpath+0x12/0x6a ---[ end trace 398181ad32332b33 ]--- Mapped at: [81324492] debug_dma_map_sg+0x122/0x140 [81616dd3] sdhci_pre_dma_transfer+0xc3/0x1b0 [81616f02] sdhci_pre_req+0x42/0x70 [81601492] mmc_pre_req+0x42/0x60 [8160290e] mmc_start_req+0x3e/0x400 I already fixed one symptom -- memory corruption. Could you revisit the commit once again, as there is surely at least one more bug? thanks, -- js suse labs -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 0/6] mmc: imx: a few fixes and new feature
Can you also fix the driver to NOT use mdelay(1) while in spinlock irqsafe? A driver with such a design should have gotten a NAK in the first place ... -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html