* [PATCH PM-0 v2] ARM: OMAP3: HSMMC: Ensure HSMMC is fully reset on boot
@ 2008-09-18 15:54 Kevin Hilman
2008-09-19 3:55 ` Madhusudhan Chikkature
2008-09-19 11:33 ` Kevin Hilman
0 siblings, 2 replies; 4+ messages in thread
From: Kevin Hilman @ 2008-09-18 15:54 UTC (permalink / raw)
To: linux-omap; +Cc: 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 <khilman@deeprootsystems.com>
---
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
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH PM-0 v2] ARM: OMAP3: HSMMC: Ensure HSMMC is fully reset on boot
2008-09-18 15:54 [PATCH PM-0 v2] ARM: OMAP3: HSMMC: Ensure HSMMC is fully reset on boot Kevin Hilman
@ 2008-09-19 3:55 ` Madhusudhan Chikkature
2008-09-19 6:41 ` Kevin Hilman
2008-09-19 11:33 ` Kevin Hilman
1 sibling, 1 reply; 4+ messages in thread
From: Madhusudhan Chikkature @ 2008-09-19 3:55 UTC (permalink / raw)
To: linux-omap; +Cc: Kevin Hilman
----- Original Message -----
From: "Kevin Hilman" <khilman@deeprootsystems.com>
To: <linux-omap@vger.kernel.org>
Cc: "Kevin Hilman" <khilman@deeprootsystems.com>
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 <khilman@deeprootsystems.com>
> ---
> 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 majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH PM-0 v2] ARM: OMAP3: HSMMC: Ensure HSMMC is fully reset on boot
2008-09-19 3:55 ` Madhusudhan Chikkature
@ 2008-09-19 6:41 ` Kevin Hilman
0 siblings, 0 replies; 4+ messages in thread
From: Kevin Hilman @ 2008-09-19 6:41 UTC (permalink / raw)
To: Madhusudhan Chikkature; +Cc: linux-omap
"Madhusudhan Chikkature" <madhu.cr@ti.com> writes:
>> This ensures that each HSMMC block is reset so it will not interfere
>> with retention or OFF-mode.
>>
>> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
[...]
> 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
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH PM-0 v2] ARM: OMAP3: HSMMC: Ensure HSMMC is fully reset on boot
2008-09-18 15:54 [PATCH PM-0 v2] ARM: OMAP3: HSMMC: Ensure HSMMC is fully reset on boot Kevin Hilman
2008-09-19 3:55 ` Madhusudhan Chikkature
@ 2008-09-19 11:33 ` Kevin Hilman
1 sibling, 0 replies; 4+ messages in thread
From: Kevin Hilman @ 2008-09-19 11:33 UTC (permalink / raw)
To: linux-omap
Kevin Hilman <khilman@deeprootsystems.com> 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
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-09-19 11:33 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-18 15:54 [PATCH PM-0 v2] ARM: OMAP3: HSMMC: Ensure HSMMC is fully reset on boot Kevin Hilman
2008-09-19 3:55 ` Madhusudhan Chikkature
2008-09-19 6:41 ` Kevin Hilman
2008-09-19 11:33 ` Kevin Hilman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox