Re: [PATCH PM-0 v2] ARM: OMAP3: HSMMC: Ensure HSMMC is fully reset on boot

2008-09-19 Thread Kevin Hilman
Madhusudhan Chikkature [EMAIL PROTECTED] writes:

 This ensures that each HSMMC block is reset so it will not interfere
 with retention or OFF-mode.
 
 Signed-off-by: Kevin Hilman [EMAIL PROTECTED]

[...]

 This might not be the right place to reset the controllers. You can
 avoid all the clk stuff if you do the reset in the driver probe
 function after the clocks are enabled.

The point is that this needs to be done even when the MMC driver is
NOT built into the kernel, or in the case of a module, before the MMC
driver is loaded.

 BTW, What is the issue you are facing if you dont reset the
 controllers? 

See mail from Jouni where he described it well.

 I have seen that on L-o that suspend/resume works with this driver
 enabled.

Without this patch, suspend/resume may work, but you may not hit
retention or OFF.  As Jouni also described, some boards work without
this patch, and others do not.

Kevin


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH PM-0 v2] ARM: OMAP3: HSMMC: Ensure HSMMC is fully reset on boot

2008-09-19 Thread Kevin Hilman
Kevin Hilman [EMAIL PROTECTED] writes:

 This ensures that each HSMMC block is reset so it will not interfere
 with retention or OFF-mode.


Sigh... I still didn't get this right for all the cases of MMC
built-in, module or disabled.  Stay tuned for v3.

Kevin

 ---
  arch/arm/mach-omap2/hsmmc.c |   73 
 ++-
  1 files changed, 72 insertions(+), 1 deletions(-)

 diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
 index 7334d86..00fe354 100644
 --- a/arch/arm/mach-omap2/hsmmc.c
 +++ b/arch/arm/mach-omap2/hsmmc.c
 @@ -15,7 +15,9 @@
  #include linux/platform_device.h
  #include linux/interrupt.h
  #include linux/delay.h
 +#include linux/clk.h
  #include linux/i2c/twl4030.h
 +
  #include mach/hardware.h
  #include mach/mmc.h
  #include mach/board.h
 @@ -46,6 +48,74 @@
  #define OMAP2_CONTROL_PBIAS_PWRDNZ   (1  1)
  #define OMAP2_CONTROL_PBIAS_SCTRL(1  2)
  
 +#define MMCHS1   (L4_34XX_BASE + 0x9C000)
 +#define MMCHS2   (L4_34XX_BASE + 0xB4000)
 +#define MMCHS3   (L4_34XX_BASE + 0xAD000)
 +#define MAX_MMC  3
 +#define MMCHS_SYSCONFIG  0x0010
 +#define MMCHS_SYSCONFIG_SWRESET  (1  1)
 +#define MMCHS_SYSSTATUS  0x0014
 +#define MMCHS_SYSSTATUS_RESETDONE(1  0)
 +
 +static struct platform_device dummy_pdev = {
 + .dev = {
 + .bus = platform_bus_type,
 + },
 +};
 +
 +/**
 + * hsmmc_reset() - Full reset of each HS-MMC controller
 + *
 + * Ensure that each MMC controller is fully reset.  Controllers
 + * left in an unknown state (by bootloaer) may prevent retention
 + * or OFF-mode.
 + *
 + * In order for reset to work, interface, functional and debounce
 + * clocks must be enabled.  The debounce clock comes from func_32k_clk
 + * and is not under SW controle, so we only enable i- and f-clocks.
 + **/
 +static void __init hsmmc_reset(void)
 +{
 + u32 i, base[MAX_MMC] = {MMCHS1, MMCHS2, MMCHS3};
 +
 + for (i = 0; i  MAX_MMC; i++) {
 + u32 v;
 + struct clk *iclk, *fclk;
 + struct device *dev = dummy_pdev.dev;
 +
 + dummy_pdev.id = i + 1;
 + iclk = clk_get(dev, mmchs_ick);
 + if (iclk  clk_enable(iclk))
 + iclk = NULL;
 + 
 + fclk = clk_get(dev, mmchs_fck);
 + if (fclk  clk_enable(fclk))
 + fclk = NULL;
 +
 + if (!iclk || !fclk) {
 + printk(KERN_WARNING 
 +%s: Unable to enable clocks for MMC%d, 
 +cannot reset.\n,  __func__, i);
 + break;
 + }
 +
 + omap_writel(MMCHS_SYSCONFIG_SWRESET, base[i] + MMCHS_SYSCONFIG);
 + v = omap_readl(base[i] + MMCHS_SYSSTATUS);
 + while (!(omap_readl(base[i] + MMCHS_SYSSTATUS) 
 +  MMCHS_SYSSTATUS_RESETDONE))
 + cpu_relax();
 +
 + if (fclk) {
 + clk_disable(fclk);
 + clk_put(fclk);
 + }
 + if (iclk) {
 + clk_disable(iclk);
 + clk_put(iclk);
 + }
 + }
 +}
 +
  static int hsmmc_card_detect(int irq)
  {
   return twl4030_get_gpio_datain(irq - TWL4030_GPIO_IRQ_BASE);
 @@ -282,6 +352,7 @@ static struct omap_mmc_platform_data hsmmc_data = {
  
  void __init hsmmc_init(void)
  {
 + hsmmc_reset();
   omap2_init_mmc(hsmmc_data);
  }
  
 @@ -289,7 +360,7 @@ void __init hsmmc_init(void)
  
  void __init hsmmc_init(void)
  {
 -
 + hsmmc_reset();
  }
  
  #endif
 -- 
 1.6.0
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH PM-0 v2] ARM: OMAP3: HSMMC: Ensure HSMMC is fully reset on boot

2008-09-18 Thread Kevin Hilman
This ensures that each HSMMC block is reset so it will not interfere
with retention or OFF-mode.

Signed-off-by: Kevin Hilman [EMAIL PROTECTED]
---
 arch/arm/mach-omap2/hsmmc.c |   73 ++-
 1 files changed, 72 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 7334d86..00fe354 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -15,7 +15,9 @@
 #include linux/platform_device.h
 #include linux/interrupt.h
 #include linux/delay.h
+#include linux/clk.h
 #include linux/i2c/twl4030.h
+
 #include mach/hardware.h
 #include mach/mmc.h
 #include mach/board.h
@@ -46,6 +48,74 @@
 #define OMAP2_CONTROL_PBIAS_PWRDNZ (1  1)
 #define OMAP2_CONTROL_PBIAS_SCTRL  (1  2)
 
+#define MMCHS1 (L4_34XX_BASE + 0x9C000)
+#define MMCHS2 (L4_34XX_BASE + 0xB4000)
+#define MMCHS3 (L4_34XX_BASE + 0xAD000)
+#define MAX_MMC3
+#define MMCHS_SYSCONFIG0x0010
+#define MMCHS_SYSCONFIG_SWRESET(1  1)
+#define MMCHS_SYSSTATUS0x0014
+#define MMCHS_SYSSTATUS_RESETDONE  (1  0)
+
+static struct platform_device dummy_pdev = {
+   .dev = {
+   .bus = platform_bus_type,
+   },
+};
+
+/**
+ * hsmmc_reset() - Full reset of each HS-MMC controller
+ *
+ * Ensure that each MMC controller is fully reset.  Controllers
+ * left in an unknown state (by bootloaer) may prevent retention
+ * or OFF-mode.
+ *
+ * In order for reset to work, interface, functional and debounce
+ * clocks must be enabled.  The debounce clock comes from func_32k_clk
+ * and is not under SW controle, so we only enable i- and f-clocks.
+ **/
+static void __init hsmmc_reset(void)
+{
+   u32 i, base[MAX_MMC] = {MMCHS1, MMCHS2, MMCHS3};
+
+   for (i = 0; i  MAX_MMC; i++) {
+   u32 v;
+   struct clk *iclk, *fclk;
+   struct device *dev = dummy_pdev.dev;
+
+   dummy_pdev.id = i + 1;
+   iclk = clk_get(dev, mmchs_ick);
+   if (iclk  clk_enable(iclk))
+   iclk = NULL;
+   
+   fclk = clk_get(dev, mmchs_fck);
+   if (fclk  clk_enable(fclk))
+   fclk = NULL;
+
+   if (!iclk || !fclk) {
+   printk(KERN_WARNING 
+  %s: Unable to enable clocks for MMC%d, 
+  cannot reset.\n,  __func__, i);
+   break;
+   }
+
+   omap_writel(MMCHS_SYSCONFIG_SWRESET, base[i] + MMCHS_SYSCONFIG);
+   v = omap_readl(base[i] + MMCHS_SYSSTATUS);
+   while (!(omap_readl(base[i] + MMCHS_SYSSTATUS) 
+MMCHS_SYSSTATUS_RESETDONE))
+   cpu_relax();
+
+   if (fclk) {
+   clk_disable(fclk);
+   clk_put(fclk);
+   }
+   if (iclk) {
+   clk_disable(iclk);
+   clk_put(iclk);
+   }
+   }
+}
+
 static int hsmmc_card_detect(int irq)
 {
return twl4030_get_gpio_datain(irq - TWL4030_GPIO_IRQ_BASE);
@@ -282,6 +352,7 @@ static struct omap_mmc_platform_data hsmmc_data = {
 
 void __init hsmmc_init(void)
 {
+   hsmmc_reset();
omap2_init_mmc(hsmmc_data);
 }
 
@@ -289,7 +360,7 @@ void __init hsmmc_init(void)
 
 void __init hsmmc_init(void)
 {
-
+   hsmmc_reset();
 }
 
 #endif
-- 
1.6.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH PM-0 v2] ARM: OMAP3: HSMMC: Ensure HSMMC is fully reset on boot

2008-09-18 Thread Madhusudhan Chikkature

- Original Message - 
From: Kevin Hilman [EMAIL PROTECTED]
To: linux-omap@vger.kernel.org
Cc: Kevin Hilman [EMAIL PROTECTED]
Sent: Thursday, September 18, 2008 9:24 PM
Subject: [PATCH PM-0 v2] ARM: OMAP3: HSMMC: Ensure HSMMC is fully reset on boot


 This ensures that each HSMMC block is reset so it will not interfere
 with retention or OFF-mode.
 
 Signed-off-by: Kevin Hilman [EMAIL PROTECTED]
 ---
 arch/arm/mach-omap2/hsmmc.c |   73 ++-
 1 files changed, 72 insertions(+), 1 deletions(-)
 
 diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
 index 7334d86..00fe354 100644
 --- a/arch/arm/mach-omap2/hsmmc.c
 +++ b/arch/arm/mach-omap2/hsmmc.c
 @@ -15,7 +15,9 @@
 #include linux/platform_device.h
 #include linux/interrupt.h
 #include linux/delay.h
 +#include linux/clk.h
 #include linux/i2c/twl4030.h
 +
 #include mach/hardware.h
 #include mach/mmc.h
 #include mach/board.h
 @@ -46,6 +48,74 @@
 #define OMAP2_CONTROL_PBIAS_PWRDNZ (1  1)
 #define OMAP2_CONTROL_PBIAS_SCTRL (1  2)
 
 +#define MMCHS1 (L4_34XX_BASE + 0x9C000)
 +#define MMCHS2 (L4_34XX_BASE + 0xB4000)
 +#define MMCHS3 (L4_34XX_BASE + 0xAD000)
 +#define MAX_MMC 3
 +#define MMCHS_SYSCONFIG 0x0010
 +#define MMCHS_SYSCONFIG_SWRESET (1  1)
 +#define MMCHS_SYSSTATUS 0x0014
 +#define MMCHS_SYSSTATUS_RESETDONE (1  0)
 +
 +static struct platform_device dummy_pdev = {
 + .dev = {
 + .bus = platform_bus_type,
 + },
 +};
 +
 +/**
 + * hsmmc_reset() - Full reset of each HS-MMC controller
 + *
 + * Ensure that each MMC controller is fully reset.  Controllers
 + * left in an unknown state (by bootloaer) may prevent retention
 + * or OFF-mode.
 + *
 + * In order for reset to work, interface, functional and debounce
 + * clocks must be enabled.  The debounce clock comes from func_32k_clk
 + * and is not under SW controle, so we only enable i- and f-clocks.
 + **/
 +static void __init hsmmc_reset(void)
 +{
 + u32 i, base[MAX_MMC] = {MMCHS1, MMCHS2, MMCHS3};
 +
 + for (i = 0; i  MAX_MMC; i++) {
 + u32 v;
 + struct clk *iclk, *fclk;
 + struct device *dev = dummy_pdev.dev;
 +
 + dummy_pdev.id = i + 1;
 + iclk = clk_get(dev, mmchs_ick);
 + if (iclk  clk_enable(iclk))
 + iclk = NULL;
 + 
 + fclk = clk_get(dev, mmchs_fck);
 + if (fclk  clk_enable(fclk))
 + fclk = NULL;
 +
 + if (!iclk || !fclk) {
 + printk(KERN_WARNING 
 +%s: Unable to enable clocks for MMC%d, 
 +cannot reset.\n,  __func__, i);
 + break;
 + }
 +
 + omap_writel(MMCHS_SYSCONFIG_SWRESET, base[i] + MMCHS_SYSCONFIG);
 + v = omap_readl(base[i] + MMCHS_SYSSTATUS);
 + while (!(omap_readl(base[i] + MMCHS_SYSSTATUS) 
 + MMCHS_SYSSTATUS_RESETDONE))
 + cpu_relax();
 +
 + if (fclk) {
 + clk_disable(fclk);
 + clk_put(fclk);
 + }
 + if (iclk) {
 + clk_disable(iclk);
 + clk_put(iclk);
 + }
 + }
 +}
 +
 static int hsmmc_card_detect(int irq)
 {
  return twl4030_get_gpio_datain(irq - TWL4030_GPIO_IRQ_BASE);
 @@ -282,6 +352,7 @@ static struct omap_mmc_platform_data hsmmc_data = {
 
 void __init hsmmc_init(void)
 {
 + hsmmc_reset();
This might not be the right place to reset the controllers. You can avoid all 
the clk stuff if you do the reset in the driver probe function after the clocks 
are enabled.

BTW,
What is the issue you are facing if you dont reset the controllers? I have seen 
that on L-o that suspend/resume works with this driver enabled.

Regards,
Madhu

  omap2_init_mmc(hsmmc_data);
 }
 
 @@ -289,7 +360,7 @@ void __init hsmmc_init(void)
 
 void __init hsmmc_init(void)
 {
 -
 + hsmmc_reset();
 }
 
 #endif
 -- 
 1.6.0
 
 --
 To unsubscribe from this list: send the line unsubscribe linux-omap in
 the body of a message to [EMAIL PROTECTED]
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html