public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [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

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