[PATCH] DT: mmc: sh_mmcif: fix compatible property text

2015-07-30 Thread Sergei Shtylyov
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

2015-07-30 Thread Sergei Shtylyov
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

2015-07-30 Thread Dong Aisheng
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

2015-07-30 Thread Magnus Damm
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

2015-07-30 Thread Yangbo Lu
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

2015-07-30 Thread Yangbo Lu
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

2015-07-30 Thread Yangbo Lu
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

2015-07-30 Thread Yangbo Lu
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

2015-07-30 Thread Yangbo Lu
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

2015-07-30 Thread Yangbo Lu
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

2015-07-30 Thread Fu, Zhonghui
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Kishon Vijay Abraham I
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

2015-07-30 Thread Bjorn Helgaas
[+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

2015-07-30 Thread Jiri Slaby
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

2015-07-30 Thread Holger Schurig
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