ARM: OMAP2+: CM/hwmod: split CM functions into OMAP2, OMAP3-specific files
authorPaul Walmsley <paul@pwsan.com>
Sun, 21 Oct 2012 07:01:11 +0000 (01:01 -0600)
committerPaul Walmsley <paul@pwsan.com>
Sun, 21 Oct 2012 07:01:11 +0000 (01:01 -0600)
Move OMAP3xxx-specific CM functions & macros into cm3xxx.[ch] and
OMAP2xxx-specific macros into cm2xxx.[ch].  Move basic CM register
access functions into static inline functions in cm2xxx_3xxx.h,
leaving only OMAP2/3 hardreset functions in cm2xxx_3xxx.c.

As part of this, split the CM and hwmod code that waits for devices to
become ready into SoC-specific functions.

This is in preparation for the upcoming move of this code to drivers/.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Reviewed-by: Russ Dill <Russ.Dill@ti.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
25 files changed:
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/clkt2xxx_apll.c
arch/arm/mach-omap2/clkt2xxx_dpll.c
arch/arm/mach-omap2/clock.c
arch/arm/mach-omap2/clock2420_data.c
arch/arm/mach-omap2/clock2430.c
arch/arm/mach-omap2/clock2430_data.c
arch/arm/mach-omap2/clock34xx.c
arch/arm/mach-omap2/clock3517.c
arch/arm/mach-omap2/clock3xxx_data.c
arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
arch/arm/mach-omap2/cm2xxx.c [new file with mode: 0644]
arch/arm/mach-omap2/cm2xxx.h [new file with mode: 0644]
arch/arm/mach-omap2/cm2xxx_3xxx.c [deleted file]
arch/arm/mach-omap2/cm2xxx_3xxx.h
arch/arm/mach-omap2/cm3xxx.c [new file with mode: 0644]
arch/arm/mach-omap2/cm3xxx.h [new file with mode: 0644]
arch/arm/mach-omap2/control.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/pm24xx.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/sleep34xx.S
arch/arm/mach-omap2/sram242x.S
arch/arm/mach-omap2/sram243x.S
arch/arm/mach-omap2/sram34xx.S

index 7404e3d48cea4cd52edb95a7248e3396aaba88a1..56a33869c8b2364826d54ca9b53bd6c8243e4fd0 100644 (file)
@@ -94,10 +94,8 @@ endif
 
 # PRCM
 obj-y                                  += prcm.o prm_common.o
-obj-$(CONFIG_ARCH_OMAP2)               += cm2xxx_3xxx.o prm2xxx_3xxx.o
-obj-$(CONFIG_ARCH_OMAP2)               += prm2xxx.o
-obj-$(CONFIG_ARCH_OMAP3)               += cm2xxx_3xxx.o prm2xxx_3xxx.o
-obj-$(CONFIG_ARCH_OMAP3)               += prm3xxx.o
+obj-$(CONFIG_ARCH_OMAP2)               += prm2xxx_3xxx.o prm2xxx.o cm2xxx.o
+obj-$(CONFIG_ARCH_OMAP3)               += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o
 obj-$(CONFIG_ARCH_OMAP3)               += vc3xxx_data.o vp3xxx_data.o
 obj-$(CONFIG_SOC_AM33XX)               += prm33xx.o cm33xx.o
 omap-prcm-4-5-common                   =  cminst44xx.o cm44xx.o prm44xx.o \
index c2d15212d64d768530e1b94b9d8cf4ad0ff8cec9..3d2f67ea9b10748cbff35c01980056cb9e0e5c76 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "clock.h"
 #include "clock2xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
 #include "cm-regbits-24xx.h"
 
 /* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
index 1502a7bc20bb2dbaa67a129c1aa5e18cb1d389f3..0f587794f00775e352e7ed0f6547926f3024148d 100644 (file)
@@ -17,7 +17,7 @@
 #include <plat/clock.h>
 
 #include "clock.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
 #include "cm-regbits-24xx.h"
 
 /* Private functions */
index 961ac8f7e13d8c84a1cbb4587255ea685520bd18..d0c6d9b066da083e4d1d42af4da23fdafa5adcfb 100644 (file)
@@ -33,7 +33,8 @@
 #include "soc.h"
 #include "clockdomain.h"
 #include "clock.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
+#include "cm3xxx.h"
 #include "cm-regbits-24xx.h"
 #include "cm-regbits-34xx.h"
 
index c3cde1a2b6de6d71956043cbd72054b6f3052438..969bc5805f92744b15f0cacd76c12f1d115237e1 100644 (file)
@@ -25,7 +25,7 @@
 #include "clock.h"
 #include "clock2xxx.h"
 #include "opp2xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
 #include "prm2xxx_3xxx.h"
 #include "prm-regbits-24xx.h"
 #include "cm-regbits-24xx.h"
index a8e326177466dbf9bb7a23a44c2082ad4c37c081..e786733e78bc4c6c75048ac842921465a39b65b6 100644 (file)
@@ -27,7 +27,7 @@
 #include "iomap.h"
 #include "clock.h"
 #include "clock2xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
 #include "cm-regbits-24xx.h"
 
 /**
index 22404fe435e75369e288937b4b4e5d2e1969fd45..186f06a97fb108f2ebcc9f031b953b5e2682612d 100644 (file)
@@ -24,7 +24,7 @@
 #include "clock.h"
 #include "clock2xxx.h"
 #include "opp2xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
 #include "prm2xxx_3xxx.h"
 #include "prm-regbits-24xx.h"
 #include "cm-regbits-24xx.h"
index 1fc96b9ee330062171ae9e3ef81e32838ef99bae..150f42bd22b7f8c89a38f9a8dd12d9a0a419ea6d 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "clock.h"
 #include "clock34xx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm3xxx.h"
 #include "cm-regbits-34xx.h"
 
 /**
index 2e97d08f0e567a1af1a3b7ee2cd1db1cdcb9098c..3e610c81bf8e508bd8693b11f17f3f3e5b0069d2 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "clock.h"
 #include "clock3517.h"
-#include "cm2xxx_3xxx.h"
+#include "cm3xxx.h"
 #include "cm-regbits-34xx.h"
 
 /*
index 1f42c9d5ecf3131b5f55fd6d2152912d44b2d9ff..7879c84d2472cc179de07880c366e8ba4aecd757 100644 (file)
@@ -30,7 +30,7 @@
 #include "clock34xx.h"
 #include "clock36xx.h"
 #include "clock3517.h"
-#include "cm2xxx_3xxx.h"
+#include "cm3xxx.h"
 #include "cm-regbits-34xx.h"
 #include "prm2xxx_3xxx.h"
 #include "prm-regbits-34xx.h"
index 70294f54e35af2b656cacaf10543612511d2d584..658487c34cb24dcdcac73b1878bae9f0c8605c94 100644 (file)
@@ -17,7 +17,8 @@
 #include "prm.h"
 #include "prm2xxx_3xxx.h"
 #include "cm.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
+#include "cm3xxx.h"
 #include "cm-regbits-24xx.h"
 #include "cm-regbits-34xx.h"
 #include "prm-regbits-24xx.h"
@@ -176,15 +177,15 @@ static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
        return 0;
 }
 
-static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
+static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
 {
        bool hwsup = false;
 
        if (!clkdm->clktrctrl_mask)
                return 0;
 
-       hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-                               clkdm->clktrctrl_mask);
+       hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+                                             clkdm->clktrctrl_mask);
 
        if (hwsup) {
                /* Disable HW transitions when we are changing deps */
@@ -199,15 +200,15 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
        return 0;
 }
 
-static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
+static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)
 {
        bool hwsup = false;
 
        if (!clkdm->clktrctrl_mask)
                return 0;
 
-       hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-                               clkdm->clktrctrl_mask);
+       hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+                                             clkdm->clktrctrl_mask);
 
        if (hwsup) {
                /* Disable HW transitions when we are changing deps */
@@ -258,8 +259,8 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
                return 0;
        }
 
-       hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-                               clkdm->clktrctrl_mask);
+       hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+                                             clkdm->clktrctrl_mask);
 
        if (hwsup) {
                /* Disable HW transitions when we are changing deps */
@@ -292,8 +293,8 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
                return 0;
        }
 
-       hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-                               clkdm->clktrctrl_mask);
+       hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+                                             clkdm->clktrctrl_mask);
 
        if (hwsup) {
                /* Disable HW transitions when we are changing deps */
@@ -317,8 +318,8 @@ struct clkdm_ops omap2_clkdm_operations = {
        .clkdm_wakeup           = omap2_clkdm_wakeup,
        .clkdm_allow_idle       = omap2_clkdm_allow_idle,
        .clkdm_deny_idle        = omap2_clkdm_deny_idle,
-       .clkdm_clk_enable       = omap2_clkdm_clk_enable,
-       .clkdm_clk_disable      = omap2_clkdm_clk_disable,
+       .clkdm_clk_enable       = omap2xxx_clkdm_clk_enable,
+       .clkdm_clk_disable      = omap2xxx_clkdm_clk_disable,
 };
 
 struct clkdm_ops omap3_clkdm_operations = {
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
new file mode 100644 (file)
index 0000000..0513493
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * OMAP2xxx CM module functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include "soc.h"
+#include "iomap.h"
+#include "common.h"
+#include "cm.h"
+#include "cm2xxx.h"
+#include "cm-regbits-24xx.h"
+
+/* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */
+#define DPLL_AUTOIDLE_DISABLE                          0x0
+#define OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP          0x3
+
+/* CM_AUTOIDLE_PLL.AUTO_* bit values for APLLs (OMAP2xxx only) */
+#define OMAP2XXX_APLL_AUTOIDLE_DISABLE                 0x0
+#define OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP          0x3
+
+static const u8 omap2xxx_cm_idlest_offs[] = {
+       CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3, OMAP24XX_CM_IDLEST4
+};
+
+/*
+ *
+ */
+
+static void _write_clktrctrl(u8 c, s16 module, u32 mask)
+{
+       u32 v;
+
+       v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
+       v &= ~mask;
+       v |= c << __ffs(mask);
+       omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
+}
+
+bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
+{
+       u32 v;
+
+       v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
+       v &= mask;
+       v >>= __ffs(mask);
+
+       return (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
+}
+
+void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
+{
+       _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
+}
+
+void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
+{
+       _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
+}
+
+/*
+ * DPLL autoidle control
+ */
+
+static void _omap2xxx_set_dpll_autoidle(u8 m)
+{
+       u32 v;
+
+       v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
+       v &= ~OMAP24XX_AUTO_DPLL_MASK;
+       v |= m << OMAP24XX_AUTO_DPLL_SHIFT;
+       omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
+}
+
+void omap2xxx_cm_set_dpll_disable_autoidle(void)
+{
+       _omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP);
+}
+
+void omap2xxx_cm_set_dpll_auto_low_power_stop(void)
+{
+       _omap2xxx_set_dpll_autoidle(DPLL_AUTOIDLE_DISABLE);
+}
+
+/*
+ * APLL autoidle control
+ */
+
+static void _omap2xxx_set_apll_autoidle(u8 m, u32 mask)
+{
+       u32 v;
+
+       v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
+       v &= ~mask;
+       v |= m << __ffs(mask);
+       omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
+}
+
+void omap2xxx_cm_set_apll54_disable_autoidle(void)
+{
+       _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
+                                   OMAP24XX_AUTO_54M_MASK);
+}
+
+void omap2xxx_cm_set_apll54_auto_low_power_stop(void)
+{
+       _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
+                                   OMAP24XX_AUTO_54M_MASK);
+}
+
+void omap2xxx_cm_set_apll96_disable_autoidle(void)
+{
+       _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
+                                   OMAP24XX_AUTO_96M_MASK);
+}
+
+void omap2xxx_cm_set_apll96_auto_low_power_stop(void)
+{
+       _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
+                                   OMAP24XX_AUTO_96M_MASK);
+}
+
+/*
+ *
+ */
+
+/**
+ * omap2xxx_cm_wait_module_ready - wait for a module to leave idle or standby
+ * @prcm_mod: PRCM module offset
+ * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
+ * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
+ *
+ * Wait for the PRCM to indicate that the module identified by
+ * (@prcm_mod, @idlest_id, @idlest_shift) is clocked.  Return 0 upon
+ * success or -EBUSY if the module doesn't enable in time.
+ */
+int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
+{
+       int ena = 0, i = 0;
+       u8 cm_idlest_reg;
+       u32 mask;
+
+       if (!idlest_id || (idlest_id > ARRAY_SIZE(omap2xxx_cm_idlest_offs)))
+               return -EINVAL;
+
+       cm_idlest_reg = omap2xxx_cm_idlest_offs[idlest_id - 1];
+
+       mask = 1 << idlest_shift;
+       ena = mask;
+
+       omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) &
+                           mask) == ena), MAX_MODULE_READY_TIME, i);
+
+       return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+}
diff --git a/arch/arm/mach-omap2/cm2xxx.h b/arch/arm/mach-omap2/cm2xxx.h
new file mode 100644 (file)
index 0000000..bce3c4b
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * OMAP2xxx Clock Management (CM) register definitions
+ *
+ * Copyright (C) 2007-2009, 2012 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The CM hardware modules on the OMAP2/3 are quite similar to each
+ * other.  The CM modules/instances on OMAP4 are quite different, so
+ * they are handled in a separate file.
+ */
+#ifndef __ARCH_ASM_MACH_OMAP2_CM2XXX_H
+#define __ARCH_ASM_MACH_OMAP2_CM2XXX_H
+
+#include "prcm-common.h"
+#include "cm2xxx_3xxx.h"
+
+#define OMAP2420_CM_REGADDR(module, reg)                               \
+                       OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
+#define OMAP2430_CM_REGADDR(module, reg)                               \
+                       OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
+
+/*
+ * Module specific CM register offsets from CM_BASE + domain offset
+ * Use cm_{read,write}_mod_reg() with these registers.
+ * These register offsets generally appear in more than one PRCM submodule.
+ */
+
+/* OMAP2-specific register offsets */
+
+#define OMAP24XX_CM_FCLKEN2                            0x0004
+#define OMAP24XX_CM_ICLKEN4                            0x001c
+#define OMAP24XX_CM_AUTOIDLE4                          0x003c
+#define OMAP24XX_CM_IDLEST4                            0x002c
+
+/* CM_IDLEST bit field values to indicate deasserted IdleReq */
+
+#define OMAP24XX_CM_IDLEST_VAL                         0
+
+
+/* Clock management domain register get/set */
+
+#ifndef __ASSEMBLER__
+
+extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
+extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
+
+extern void omap2xxx_cm_set_dpll_disable_autoidle(void);
+extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void);
+
+extern void omap2xxx_cm_set_apll54_disable_autoidle(void);
+extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void);
+extern void omap2xxx_cm_set_apll96_disable_autoidle(void);
+extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
+
+extern bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask);
+extern int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
+                                        u8 idlest_shift);
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.c b/arch/arm/mach-omap2/cm2xxx_3xxx.c
deleted file mode 100644 (file)
index 7f07ab0..0000000
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * OMAP2/3 CM module functions
- *
- * Copyright (C) 2009 Nokia Corporation
- * Paul Walmsley
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include "soc.h"
-#include "iomap.h"
-#include "common.h"
-#include "cm.h"
-#include "cm2xxx_3xxx.h"
-#include "cm-regbits-24xx.h"
-#include "cm-regbits-34xx.h"
-
-/* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */
-#define DPLL_AUTOIDLE_DISABLE                          0x0
-#define OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP          0x3
-
-/* CM_AUTOIDLE_PLL.AUTO_* bit values for APLLs (OMAP2xxx only) */
-#define OMAP2XXX_APLL_AUTOIDLE_DISABLE                 0x0
-#define OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP          0x3
-
-static const u8 cm_idlest_offs[] = {
-       CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3, OMAP24XX_CM_IDLEST4
-};
-
-u32 omap2_cm_read_mod_reg(s16 module, u16 idx)
-{
-       return __raw_readl(cm_base + module + idx);
-}
-
-void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx)
-{
-       __raw_writel(val, cm_base + module + idx);
-}
-
-/* Read-modify-write a register in a CM module. Caller must lock */
-u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
-{
-       u32 v;
-
-       v = omap2_cm_read_mod_reg(module, idx);
-       v &= ~mask;
-       v |= bits;
-       omap2_cm_write_mod_reg(v, module, idx);
-
-       return v;
-}
-
-u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
-{
-       return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx);
-}
-
-u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
-{
-       return omap2_cm_rmw_mod_reg_bits(bits, 0x0, module, idx);
-}
-
-/*
- *
- */
-
-static void _write_clktrctrl(u8 c, s16 module, u32 mask)
-{
-       u32 v;
-
-       v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
-       v &= ~mask;
-       v |= c << __ffs(mask);
-       omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
-}
-
-bool omap2_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
-{
-       u32 v;
-       bool ret = 0;
-
-       BUG_ON(!cpu_is_omap24xx() && !cpu_is_omap34xx());
-
-       v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
-       v &= mask;
-       v >>= __ffs(mask);
-
-       if (cpu_is_omap24xx())
-               ret = (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
-       else
-               ret = (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
-
-       return ret;
-}
-
-void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
-{
-       _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
-}
-
-void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
-{
-       _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
-}
-
-void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
-{
-       _write_clktrctrl(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
-}
-
-void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
-{
-       _write_clktrctrl(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
-}
-
-void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask)
-{
-       _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, module, mask);
-}
-
-void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
-{
-       _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask);
-}
-
-/*
- * DPLL autoidle control
- */
-
-static void _omap2xxx_set_dpll_autoidle(u8 m)
-{
-       u32 v;
-
-       v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
-       v &= ~OMAP24XX_AUTO_DPLL_MASK;
-       v |= m << OMAP24XX_AUTO_DPLL_SHIFT;
-       omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
-}
-
-void omap2xxx_cm_set_dpll_disable_autoidle(void)
-{
-       _omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP);
-}
-
-void omap2xxx_cm_set_dpll_auto_low_power_stop(void)
-{
-       _omap2xxx_set_dpll_autoidle(DPLL_AUTOIDLE_DISABLE);
-}
-
-/*
- * APLL autoidle control
- */
-
-static void _omap2xxx_set_apll_autoidle(u8 m, u32 mask)
-{
-       u32 v;
-
-       v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
-       v &= ~mask;
-       v |= m << __ffs(mask);
-       omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
-}
-
-void omap2xxx_cm_set_apll54_disable_autoidle(void)
-{
-       _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
-                                   OMAP24XX_AUTO_54M_MASK);
-}
-
-void omap2xxx_cm_set_apll54_auto_low_power_stop(void)
-{
-       _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
-                                   OMAP24XX_AUTO_54M_MASK);
-}
-
-void omap2xxx_cm_set_apll96_disable_autoidle(void)
-{
-       _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
-                                   OMAP24XX_AUTO_96M_MASK);
-}
-
-void omap2xxx_cm_set_apll96_auto_low_power_stop(void)
-{
-       _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
-                                   OMAP24XX_AUTO_96M_MASK);
-}
-
-/*
- *
- */
-
-/**
- * omap2_cm_wait_idlest_ready - wait for a module to leave idle or standby
- * @prcm_mod: PRCM module offset
- * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
- * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
- *
- * XXX document
- */
-int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
-{
-       int ena = 0, i = 0;
-       u8 cm_idlest_reg;
-       u32 mask;
-
-       if (!idlest_id || (idlest_id > ARRAY_SIZE(cm_idlest_offs)))
-               return -EINVAL;
-
-       cm_idlest_reg = cm_idlest_offs[idlest_id - 1];
-
-       mask = 1 << idlest_shift;
-
-       if (cpu_is_omap24xx())
-               ena = mask;
-       else if (cpu_is_omap34xx())
-               ena = 0;
-       else
-               BUG();
-
-       omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena),
-                         MAX_MODULE_READY_TIME, i);
-
-       return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
-}
-
-/*
- * Context save/restore code - OMAP3 only
- */
-#ifdef CONFIG_ARCH_OMAP3
-struct omap3_cm_regs {
-       u32 iva2_cm_clksel1;
-       u32 iva2_cm_clksel2;
-       u32 cm_sysconfig;
-       u32 sgx_cm_clksel;
-       u32 dss_cm_clksel;
-       u32 cam_cm_clksel;
-       u32 per_cm_clksel;
-       u32 emu_cm_clksel;
-       u32 emu_cm_clkstctrl;
-       u32 pll_cm_autoidle;
-       u32 pll_cm_autoidle2;
-       u32 pll_cm_clksel4;
-       u32 pll_cm_clksel5;
-       u32 pll_cm_clken2;
-       u32 cm_polctrl;
-       u32 iva2_cm_fclken;
-       u32 iva2_cm_clken_pll;
-       u32 core_cm_fclken1;
-       u32 core_cm_fclken3;
-       u32 sgx_cm_fclken;
-       u32 wkup_cm_fclken;
-       u32 dss_cm_fclken;
-       u32 cam_cm_fclken;
-       u32 per_cm_fclken;
-       u32 usbhost_cm_fclken;
-       u32 core_cm_iclken1;
-       u32 core_cm_iclken2;
-       u32 core_cm_iclken3;
-       u32 sgx_cm_iclken;
-       u32 wkup_cm_iclken;
-       u32 dss_cm_iclken;
-       u32 cam_cm_iclken;
-       u32 per_cm_iclken;
-       u32 usbhost_cm_iclken;
-       u32 iva2_cm_autoidle2;
-       u32 mpu_cm_autoidle2;
-       u32 iva2_cm_clkstctrl;
-       u32 mpu_cm_clkstctrl;
-       u32 core_cm_clkstctrl;
-       u32 sgx_cm_clkstctrl;
-       u32 dss_cm_clkstctrl;
-       u32 cam_cm_clkstctrl;
-       u32 per_cm_clkstctrl;
-       u32 neon_cm_clkstctrl;
-       u32 usbhost_cm_clkstctrl;
-       u32 core_cm_autoidle1;
-       u32 core_cm_autoidle2;
-       u32 core_cm_autoidle3;
-       u32 wkup_cm_autoidle;
-       u32 dss_cm_autoidle;
-       u32 cam_cm_autoidle;
-       u32 per_cm_autoidle;
-       u32 usbhost_cm_autoidle;
-       u32 sgx_cm_sleepdep;
-       u32 dss_cm_sleepdep;
-       u32 cam_cm_sleepdep;
-       u32 per_cm_sleepdep;
-       u32 usbhost_cm_sleepdep;
-       u32 cm_clkout_ctrl;
-};
-
-static struct omap3_cm_regs cm_context;
-
-void omap3_cm_save_context(void)
-{
-       cm_context.iva2_cm_clksel1 =
-               omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
-       cm_context.iva2_cm_clksel2 =
-               omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2);
-       cm_context.cm_sysconfig = __raw_readl(OMAP3430_CM_SYSCONFIG);
-       cm_context.sgx_cm_clksel =
-               omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL);
-       cm_context.dss_cm_clksel =
-               omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL);
-       cm_context.cam_cm_clksel =
-               omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSEL);
-       cm_context.per_cm_clksel =
-               omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSEL);
-       cm_context.emu_cm_clksel =
-               omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
-       cm_context.emu_cm_clkstctrl =
-               omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL);
-       /*
-        * As per erratum i671, ROM code does not respect the PER DPLL
-        * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1.
-        * In this case, even though this register has been saved in
-        * scratchpad contents, we need to restore AUTO_PERIPH_DPLL
-        * by ourselves. So, we need to save it anyway.
-        */
-       cm_context.pll_cm_autoidle =
-               omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
-       cm_context.pll_cm_autoidle2 =
-               omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
-       cm_context.pll_cm_clksel4 =
-               omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL4);
-       cm_context.pll_cm_clksel5 =
-               omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5);
-       cm_context.pll_cm_clken2 =
-               omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2);
-       cm_context.cm_polctrl = __raw_readl(OMAP3430_CM_POLCTRL);
-       cm_context.iva2_cm_fclken =
-               omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN);
-       cm_context.iva2_cm_clken_pll =
-               omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL);
-       cm_context.core_cm_fclken1 =
-               omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
-       cm_context.core_cm_fclken3 =
-               omap2_cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
-       cm_context.sgx_cm_fclken =
-               omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_FCLKEN);
-       cm_context.wkup_cm_fclken =
-               omap2_cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
-       cm_context.dss_cm_fclken =
-               omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_FCLKEN);
-       cm_context.cam_cm_fclken =
-               omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_FCLKEN);
-       cm_context.per_cm_fclken =
-               omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
-       cm_context.usbhost_cm_fclken =
-               omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
-       cm_context.core_cm_iclken1 =
-               omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
-       cm_context.core_cm_iclken2 =
-               omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN2);
-       cm_context.core_cm_iclken3 =
-               omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
-       cm_context.sgx_cm_iclken =
-               omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_ICLKEN);
-       cm_context.wkup_cm_iclken =
-               omap2_cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
-       cm_context.dss_cm_iclken =
-               omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_ICLKEN);
-       cm_context.cam_cm_iclken =
-               omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_ICLKEN);
-       cm_context.per_cm_iclken =
-               omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
-       cm_context.usbhost_cm_iclken =
-               omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
-       cm_context.iva2_cm_autoidle2 =
-               omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
-       cm_context.mpu_cm_autoidle2 =
-               omap2_cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
-       cm_context.iva2_cm_clkstctrl =
-               omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
-       cm_context.mpu_cm_clkstctrl =
-               omap2_cm_read_mod_reg(MPU_MOD, OMAP2_CM_CLKSTCTRL);
-       cm_context.core_cm_clkstctrl =
-               omap2_cm_read_mod_reg(CORE_MOD, OMAP2_CM_CLKSTCTRL);
-       cm_context.sgx_cm_clkstctrl =
-               omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, OMAP2_CM_CLKSTCTRL);
-       cm_context.dss_cm_clkstctrl =
-               omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP2_CM_CLKSTCTRL);
-       cm_context.cam_cm_clkstctrl =
-               omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP2_CM_CLKSTCTRL);
-       cm_context.per_cm_clkstctrl =
-               omap2_cm_read_mod_reg(OMAP3430_PER_MOD, OMAP2_CM_CLKSTCTRL);
-       cm_context.neon_cm_clkstctrl =
-               omap2_cm_read_mod_reg(OMAP3430_NEON_MOD, OMAP2_CM_CLKSTCTRL);
-       cm_context.usbhost_cm_clkstctrl =
-               omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
-                                     OMAP2_CM_CLKSTCTRL);
-       cm_context.core_cm_autoidle1 =
-               omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1);
-       cm_context.core_cm_autoidle2 =
-               omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE2);
-       cm_context.core_cm_autoidle3 =
-               omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE3);
-       cm_context.wkup_cm_autoidle =
-               omap2_cm_read_mod_reg(WKUP_MOD, CM_AUTOIDLE);
-       cm_context.dss_cm_autoidle =
-               omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_AUTOIDLE);
-       cm_context.cam_cm_autoidle =
-               omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_AUTOIDLE);
-       cm_context.per_cm_autoidle =
-               omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
-       cm_context.usbhost_cm_autoidle =
-               omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
-       cm_context.sgx_cm_sleepdep =
-               omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
-                                     OMAP3430_CM_SLEEPDEP);
-       cm_context.dss_cm_sleepdep =
-               omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP3430_CM_SLEEPDEP);
-       cm_context.cam_cm_sleepdep =
-               omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP3430_CM_SLEEPDEP);
-       cm_context.per_cm_sleepdep =
-               omap2_cm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_CM_SLEEPDEP);
-       cm_context.usbhost_cm_sleepdep =
-               omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
-                                     OMAP3430_CM_SLEEPDEP);
-       cm_context.cm_clkout_ctrl =
-               omap2_cm_read_mod_reg(OMAP3430_CCR_MOD,
-                                     OMAP3_CM_CLKOUT_CTRL_OFFSET);
-}
-
-void omap3_cm_restore_context(void)
-{
-       omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel1, OMAP3430_IVA2_MOD,
-                              CM_CLKSEL1);
-       omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD,
-                              CM_CLKSEL2);
-       __raw_writel(cm_context.cm_sysconfig, OMAP3430_CM_SYSCONFIG);
-       omap2_cm_write_mod_reg(cm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD,
-                              CM_CLKSEL);
-       omap2_cm_write_mod_reg(cm_context.dss_cm_clksel, OMAP3430_DSS_MOD,
-                              CM_CLKSEL);
-       omap2_cm_write_mod_reg(cm_context.cam_cm_clksel, OMAP3430_CAM_MOD,
-                              CM_CLKSEL);
-       omap2_cm_write_mod_reg(cm_context.per_cm_clksel, OMAP3430_PER_MOD,
-                              CM_CLKSEL);
-       omap2_cm_write_mod_reg(cm_context.emu_cm_clksel, OMAP3430_EMU_MOD,
-                              CM_CLKSEL1);
-       omap2_cm_write_mod_reg(cm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
-                              OMAP2_CM_CLKSTCTRL);
-       /*
-        * As per erratum i671, ROM code does not respect the PER DPLL
-        * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1.
-        * In this case, we need to restore AUTO_PERIPH_DPLL by ourselves.
-        */
-       omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle, PLL_MOD,
-                              CM_AUTOIDLE);
-       omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle2, PLL_MOD,
-                              CM_AUTOIDLE2);
-       omap2_cm_write_mod_reg(cm_context.pll_cm_clksel4, PLL_MOD,
-                              OMAP3430ES2_CM_CLKSEL4);
-       omap2_cm_write_mod_reg(cm_context.pll_cm_clksel5, PLL_MOD,
-                              OMAP3430ES2_CM_CLKSEL5);
-       omap2_cm_write_mod_reg(cm_context.pll_cm_clken2, PLL_MOD,
-                              OMAP3430ES2_CM_CLKEN2);
-       __raw_writel(cm_context.cm_polctrl, OMAP3430_CM_POLCTRL);
-       omap2_cm_write_mod_reg(cm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD,
-                              CM_FCLKEN);
-       omap2_cm_write_mod_reg(cm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD,
-                              OMAP3430_CM_CLKEN_PLL);
-       omap2_cm_write_mod_reg(cm_context.core_cm_fclken1, CORE_MOD,
-                              CM_FCLKEN1);
-       omap2_cm_write_mod_reg(cm_context.core_cm_fclken3, CORE_MOD,
-                              OMAP3430ES2_CM_FCLKEN3);
-       omap2_cm_write_mod_reg(cm_context.sgx_cm_fclken, OMAP3430ES2_SGX_MOD,
-                              CM_FCLKEN);
-       omap2_cm_write_mod_reg(cm_context.wkup_cm_fclken, WKUP_MOD, CM_FCLKEN);
-       omap2_cm_write_mod_reg(cm_context.dss_cm_fclken, OMAP3430_DSS_MOD,
-                              CM_FCLKEN);
-       omap2_cm_write_mod_reg(cm_context.cam_cm_fclken, OMAP3430_CAM_MOD,
-                              CM_FCLKEN);
-       omap2_cm_write_mod_reg(cm_context.per_cm_fclken, OMAP3430_PER_MOD,
-                              CM_FCLKEN);
-       omap2_cm_write_mod_reg(cm_context.usbhost_cm_fclken,
-                              OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
-       omap2_cm_write_mod_reg(cm_context.core_cm_iclken1, CORE_MOD,
-                              CM_ICLKEN1);
-       omap2_cm_write_mod_reg(cm_context.core_cm_iclken2, CORE_MOD,
-                              CM_ICLKEN2);
-       omap2_cm_write_mod_reg(cm_context.core_cm_iclken3, CORE_MOD,
-                              CM_ICLKEN3);
-       omap2_cm_write_mod_reg(cm_context.sgx_cm_iclken, OMAP3430ES2_SGX_MOD,
-                              CM_ICLKEN);
-       omap2_cm_write_mod_reg(cm_context.wkup_cm_iclken, WKUP_MOD, CM_ICLKEN);
-       omap2_cm_write_mod_reg(cm_context.dss_cm_iclken, OMAP3430_DSS_MOD,
-                              CM_ICLKEN);
-       omap2_cm_write_mod_reg(cm_context.cam_cm_iclken, OMAP3430_CAM_MOD,
-                              CM_ICLKEN);
-       omap2_cm_write_mod_reg(cm_context.per_cm_iclken, OMAP3430_PER_MOD,
-                              CM_ICLKEN);
-       omap2_cm_write_mod_reg(cm_context.usbhost_cm_iclken,
-                              OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
-       omap2_cm_write_mod_reg(cm_context.iva2_cm_autoidle2, OMAP3430_IVA2_MOD,
-                              CM_AUTOIDLE2);
-       omap2_cm_write_mod_reg(cm_context.mpu_cm_autoidle2, MPU_MOD,
-                              CM_AUTOIDLE2);
-       omap2_cm_write_mod_reg(cm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
-                              OMAP2_CM_CLKSTCTRL);
-       omap2_cm_write_mod_reg(cm_context.mpu_cm_clkstctrl, MPU_MOD,
-                              OMAP2_CM_CLKSTCTRL);
-       omap2_cm_write_mod_reg(cm_context.core_cm_clkstctrl, CORE_MOD,
-                              OMAP2_CM_CLKSTCTRL);
-       omap2_cm_write_mod_reg(cm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD,
-                              OMAP2_CM_CLKSTCTRL);
-       omap2_cm_write_mod_reg(cm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD,
-                              OMAP2_CM_CLKSTCTRL);
-       omap2_cm_write_mod_reg(cm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD,
-                              OMAP2_CM_CLKSTCTRL);
-       omap2_cm_write_mod_reg(cm_context.per_cm_clkstctrl, OMAP3430_PER_MOD,
-                              OMAP2_CM_CLKSTCTRL);
-       omap2_cm_write_mod_reg(cm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD,
-                              OMAP2_CM_CLKSTCTRL);
-       omap2_cm_write_mod_reg(cm_context.usbhost_cm_clkstctrl,
-                              OMAP3430ES2_USBHOST_MOD, OMAP2_CM_CLKSTCTRL);
-       omap2_cm_write_mod_reg(cm_context.core_cm_autoidle1, CORE_MOD,
-                              CM_AUTOIDLE1);
-       omap2_cm_write_mod_reg(cm_context.core_cm_autoidle2, CORE_MOD,
-                              CM_AUTOIDLE2);
-       omap2_cm_write_mod_reg(cm_context.core_cm_autoidle3, CORE_MOD,
-                              CM_AUTOIDLE3);
-       omap2_cm_write_mod_reg(cm_context.wkup_cm_autoidle, WKUP_MOD,
-                              CM_AUTOIDLE);
-       omap2_cm_write_mod_reg(cm_context.dss_cm_autoidle, OMAP3430_DSS_MOD,
-                              CM_AUTOIDLE);
-       omap2_cm_write_mod_reg(cm_context.cam_cm_autoidle, OMAP3430_CAM_MOD,
-                              CM_AUTOIDLE);
-       omap2_cm_write_mod_reg(cm_context.per_cm_autoidle, OMAP3430_PER_MOD,
-                              CM_AUTOIDLE);
-       omap2_cm_write_mod_reg(cm_context.usbhost_cm_autoidle,
-                              OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
-       omap2_cm_write_mod_reg(cm_context.sgx_cm_sleepdep, OMAP3430ES2_SGX_MOD,
-                              OMAP3430_CM_SLEEPDEP);
-       omap2_cm_write_mod_reg(cm_context.dss_cm_sleepdep, OMAP3430_DSS_MOD,
-                              OMAP3430_CM_SLEEPDEP);
-       omap2_cm_write_mod_reg(cm_context.cam_cm_sleepdep, OMAP3430_CAM_MOD,
-                              OMAP3430_CM_SLEEPDEP);
-       omap2_cm_write_mod_reg(cm_context.per_cm_sleepdep, OMAP3430_PER_MOD,
-                              OMAP3430_CM_SLEEPDEP);
-       omap2_cm_write_mod_reg(cm_context.usbhost_cm_sleepdep,
-                              OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
-       omap2_cm_write_mod_reg(cm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
-                              OMAP3_CM_CLKOUT_CTRL_OFFSET);
-}
-#endif
index 57b2f3c2fbf3469c6c99d9b72658c43d0207e819..865d332f6fb1e407876d2e180b7b4e32de9318dc 100644 (file)
 
 #include "prcm-common.h"
 
-#define OMAP2420_CM_REGADDR(module, reg)                               \
-                       OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
-#define OMAP2430_CM_REGADDR(module, reg)                               \
-                       OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
-#define OMAP34XX_CM_REGADDR(module, reg)                               \
-                       OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
-
-
-/*
- * OMAP3-specific global CM registers
- * Use cm_{read,write}_reg() with these registers.
- * These registers appear once per CM module.
- */
-
-#define OMAP3430_CM_REVISION           OMAP34XX_CM_REGADDR(OCP_MOD, 0x0000)
-#define OMAP3430_CM_SYSCONFIG          OMAP34XX_CM_REGADDR(OCP_MOD, 0x0010)
-#define OMAP3430_CM_POLCTRL            OMAP34XX_CM_REGADDR(OCP_MOD, 0x009c)
-
-#define OMAP3_CM_CLKOUT_CTRL_OFFSET    0x0070
-#define OMAP3430_CM_CLKOUT_CTRL                OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
-
 /*
  * Module specific CM register offsets from CM_BASE + domain offset
  * Use cm_{read,write}_mod_reg() with these registers.
@@ -57,6 +36,7 @@
 #define CM_IDLEST                                      0x0020
 #define CM_IDLEST1                                     CM_IDLEST
 #define CM_IDLEST2                                     0x0024
+#define OMAP2430_CM_IDLEST3                            0x0028
 #define CM_AUTOIDLE                                    0x0030
 #define CM_AUTOIDLE1                                   CM_AUTOIDLE
 #define CM_AUTOIDLE2                                   0x0034
 #define CM_CLKSEL2                                     0x0044
 #define OMAP2_CM_CLKSTCTRL                             0x0048
 
-/* OMAP2-specific register offsets */
-
-#define OMAP24XX_CM_FCLKEN2                            0x0004
-#define OMAP24XX_CM_ICLKEN4                            0x001c
-#define OMAP24XX_CM_AUTOIDLE4                          0x003c
-#define OMAP24XX_CM_IDLEST4                            0x002c
-
-#define OMAP2430_CM_IDLEST3                            0x0028
-
-/* OMAP3-specific register offsets */
-
-#define OMAP3430_CM_CLKEN_PLL                          0x0004
-#define OMAP3430ES2_CM_CLKEN2                          0x0004
-#define OMAP3430ES2_CM_FCLKEN3                         0x0008
-#define OMAP3430_CM_IDLEST_PLL                         CM_IDLEST2
-#define OMAP3430_CM_AUTOIDLE_PLL                       CM_AUTOIDLE2
-#define OMAP3430ES2_CM_AUTOIDLE2_PLL                   CM_AUTOIDLE2
-#define OMAP3430_CM_CLKSEL1                            CM_CLKSEL
-#define OMAP3430_CM_CLKSEL1_PLL                                CM_CLKSEL
-#define OMAP3430_CM_CLKSEL2_PLL                                CM_CLKSEL2
-#define OMAP3430_CM_SLEEPDEP                           CM_CLKSEL2
-#define OMAP3430_CM_CLKSEL3                            OMAP2_CM_CLKSTCTRL
-#define OMAP3430_CM_CLKSTST                            0x004c
-#define OMAP3430ES2_CM_CLKSEL4                         0x004c
-#define OMAP3430ES2_CM_CLKSEL5                         0x0050
-#define OMAP3430_CM_CLKSEL2_EMU                                0x0050
-#define OMAP3430_CM_CLKSEL3_EMU                                0x0054
-
-
-/* CM_IDLEST bit field values to indicate deasserted IdleReq */
-
-#define OMAP24XX_CM_IDLEST_VAL                         0
-#define OMAP34XX_CM_IDLEST_VAL                         1
+#ifndef __ASSEMBLER__
 
+#include <linux/io.h>
 
-/* Clock management domain register get/set */
+static inline u32 omap2_cm_read_mod_reg(s16 module, u16 idx)
+{
+       return __raw_readl(cm_base + module + idx);
+}
 
-#ifndef __ASSEMBLER__
+static inline void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx)
+{
+       __raw_writel(val, cm_base + module + idx);
+}
 
-extern u32 omap2_cm_read_mod_reg(s16 module, u16 idx);
-extern void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx);
-extern u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
+/* Read-modify-write a register in a CM module. Caller must lock */
+static inline u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module,
+                                           s16 idx)
+{
+       u32 v;
 
-extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
-                                     u8 idlest_shift);
-extern u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx);
-extern u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx);
+       v = omap2_cm_read_mod_reg(module, idx);
+       v &= ~mask;
+       v |= bits;
+       omap2_cm_write_mod_reg(v, module, idx);
 
-extern bool omap2_cm_is_clkdm_in_hwsup(s16 module, u32 mask);
-extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
-extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
+       return v;
+}
 
-extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
-extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
-extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask);
-extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask);
+static inline u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+       return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx);
+}
 
-extern void omap2xxx_cm_set_dpll_disable_autoidle(void);
-extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void);
-
-extern void omap2xxx_cm_set_apll54_disable_autoidle(void);
-extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void);
-extern void omap2xxx_cm_set_apll96_disable_autoidle(void);
-extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
+static inline u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+       return omap2_cm_rmw_mod_reg_bits(bits, 0x0, module, idx);
+}
 
 #endif
 
@@ -147,10 +100,4 @@ extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
 #define OMAP_ST_GFX_MASK                               (1 << 0)
 
 
-/* Function prototypes */
-# ifndef __ASSEMBLER__
-extern void omap3_cm_save_context(void);
-extern void omap3_cm_restore_context(void);
-# endif
-
 #endif
diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c
new file mode 100644 (file)
index 0000000..8f92c56
--- /dev/null
@@ -0,0 +1,429 @@
+/*
+ * OMAP2/3 CM module functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include "soc.h"
+#include "iomap.h"
+#include "common.h"
+#include "cm.h"
+#include "cm3xxx.h"
+#include "cm-regbits-34xx.h"
+
+static const u8 omap3xxx_cm_idlest_offs[] = {
+       CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
+};
+
+/*
+ *
+ */
+
+static void _write_clktrctrl(u8 c, s16 module, u32 mask)
+{
+       u32 v;
+
+       v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
+       v &= ~mask;
+       v |= c << __ffs(mask);
+       omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
+}
+
+bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
+{
+       u32 v;
+
+       v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
+       v &= mask;
+       v >>= __ffs(mask);
+
+       return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
+}
+
+void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
+{
+       _write_clktrctrl(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
+}
+
+void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
+{
+       _write_clktrctrl(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
+}
+
+void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask)
+{
+       _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, module, mask);
+}
+
+void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
+{
+       _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask);
+}
+
+/*
+ *
+ */
+
+/**
+ * omap3xxx_cm_wait_module_ready - wait for a module to leave idle or standby
+ * @prcm_mod: PRCM module offset
+ * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
+ * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
+ *
+ * Wait for the PRCM to indicate that the module identified by
+ * (@prcm_mod, @idlest_id, @idlest_shift) is clocked.  Return 0 upon
+ * success or -EBUSY if the module doesn't enable in time.
+ */
+int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
+{
+       int ena = 0, i = 0;
+       u8 cm_idlest_reg;
+       u32 mask;
+
+       if (!idlest_id || (idlest_id > ARRAY_SIZE(omap3xxx_cm_idlest_offs)))
+               return -EINVAL;
+
+       cm_idlest_reg = omap3xxx_cm_idlest_offs[idlest_id - 1];
+
+       mask = 1 << idlest_shift;
+       ena = 0;
+
+       omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) &
+                           mask) == ena), MAX_MODULE_READY_TIME, i);
+
+       return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+}
+
+/*
+ * Context save/restore code - OMAP3 only
+ */
+struct omap3_cm_regs {
+       u32 iva2_cm_clksel1;
+       u32 iva2_cm_clksel2;
+       u32 cm_sysconfig;
+       u32 sgx_cm_clksel;
+       u32 dss_cm_clksel;
+       u32 cam_cm_clksel;
+       u32 per_cm_clksel;
+       u32 emu_cm_clksel;
+       u32 emu_cm_clkstctrl;
+       u32 pll_cm_autoidle;
+       u32 pll_cm_autoidle2;
+       u32 pll_cm_clksel4;
+       u32 pll_cm_clksel5;
+       u32 pll_cm_clken2;
+       u32 cm_polctrl;
+       u32 iva2_cm_fclken;
+       u32 iva2_cm_clken_pll;
+       u32 core_cm_fclken1;
+       u32 core_cm_fclken3;
+       u32 sgx_cm_fclken;
+       u32 wkup_cm_fclken;
+       u32 dss_cm_fclken;
+       u32 cam_cm_fclken;
+       u32 per_cm_fclken;
+       u32 usbhost_cm_fclken;
+       u32 core_cm_iclken1;
+       u32 core_cm_iclken2;
+       u32 core_cm_iclken3;
+       u32 sgx_cm_iclken;
+       u32 wkup_cm_iclken;
+       u32 dss_cm_iclken;
+       u32 cam_cm_iclken;
+       u32 per_cm_iclken;
+       u32 usbhost_cm_iclken;
+       u32 iva2_cm_autoidle2;
+       u32 mpu_cm_autoidle2;
+       u32 iva2_cm_clkstctrl;
+       u32 mpu_cm_clkstctrl;
+       u32 core_cm_clkstctrl;
+       u32 sgx_cm_clkstctrl;
+       u32 dss_cm_clkstctrl;
+       u32 cam_cm_clkstctrl;
+       u32 per_cm_clkstctrl;
+       u32 neon_cm_clkstctrl;
+       u32 usbhost_cm_clkstctrl;
+       u32 core_cm_autoidle1;
+       u32 core_cm_autoidle2;
+       u32 core_cm_autoidle3;
+       u32 wkup_cm_autoidle;
+       u32 dss_cm_autoidle;
+       u32 cam_cm_autoidle;
+       u32 per_cm_autoidle;
+       u32 usbhost_cm_autoidle;
+       u32 sgx_cm_sleepdep;
+       u32 dss_cm_sleepdep;
+       u32 cam_cm_sleepdep;
+       u32 per_cm_sleepdep;
+       u32 usbhost_cm_sleepdep;
+       u32 cm_clkout_ctrl;
+};
+
+static struct omap3_cm_regs cm_context;
+
+void omap3_cm_save_context(void)
+{
+       cm_context.iva2_cm_clksel1 =
+               omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
+       cm_context.iva2_cm_clksel2 =
+               omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2);
+       cm_context.cm_sysconfig = __raw_readl(OMAP3430_CM_SYSCONFIG);
+       cm_context.sgx_cm_clksel =
+               omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL);
+       cm_context.dss_cm_clksel =
+               omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL);
+       cm_context.cam_cm_clksel =
+               omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSEL);
+       cm_context.per_cm_clksel =
+               omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSEL);
+       cm_context.emu_cm_clksel =
+               omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
+       cm_context.emu_cm_clkstctrl =
+               omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL);
+       /*
+        * As per erratum i671, ROM code does not respect the PER DPLL
+        * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1.
+        * In this case, even though this register has been saved in
+        * scratchpad contents, we need to restore AUTO_PERIPH_DPLL
+        * by ourselves. So, we need to save it anyway.
+        */
+       cm_context.pll_cm_autoidle =
+               omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
+       cm_context.pll_cm_autoidle2 =
+               omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
+       cm_context.pll_cm_clksel4 =
+               omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL4);
+       cm_context.pll_cm_clksel5 =
+               omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5);
+       cm_context.pll_cm_clken2 =
+               omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2);
+       cm_context.cm_polctrl = __raw_readl(OMAP3430_CM_POLCTRL);
+       cm_context.iva2_cm_fclken =
+               omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN);
+       cm_context.iva2_cm_clken_pll =
+               omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL);
+       cm_context.core_cm_fclken1 =
+               omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+       cm_context.core_cm_fclken3 =
+               omap2_cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
+       cm_context.sgx_cm_fclken =
+               omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_FCLKEN);
+       cm_context.wkup_cm_fclken =
+               omap2_cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
+       cm_context.dss_cm_fclken =
+               omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_FCLKEN);
+       cm_context.cam_cm_fclken =
+               omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_FCLKEN);
+       cm_context.per_cm_fclken =
+               omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
+       cm_context.usbhost_cm_fclken =
+               omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
+       cm_context.core_cm_iclken1 =
+               omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
+       cm_context.core_cm_iclken2 =
+               omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN2);
+       cm_context.core_cm_iclken3 =
+               omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
+       cm_context.sgx_cm_iclken =
+               omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_ICLKEN);
+       cm_context.wkup_cm_iclken =
+               omap2_cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
+       cm_context.dss_cm_iclken =
+               omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_ICLKEN);
+       cm_context.cam_cm_iclken =
+               omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_ICLKEN);
+       cm_context.per_cm_iclken =
+               omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
+       cm_context.usbhost_cm_iclken =
+               omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
+       cm_context.iva2_cm_autoidle2 =
+               omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
+       cm_context.mpu_cm_autoidle2 =
+               omap2_cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
+       cm_context.iva2_cm_clkstctrl =
+               omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
+       cm_context.mpu_cm_clkstctrl =
+               omap2_cm_read_mod_reg(MPU_MOD, OMAP2_CM_CLKSTCTRL);
+       cm_context.core_cm_clkstctrl =
+               omap2_cm_read_mod_reg(CORE_MOD, OMAP2_CM_CLKSTCTRL);
+       cm_context.sgx_cm_clkstctrl =
+               omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, OMAP2_CM_CLKSTCTRL);
+       cm_context.dss_cm_clkstctrl =
+               omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP2_CM_CLKSTCTRL);
+       cm_context.cam_cm_clkstctrl =
+               omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP2_CM_CLKSTCTRL);
+       cm_context.per_cm_clkstctrl =
+               omap2_cm_read_mod_reg(OMAP3430_PER_MOD, OMAP2_CM_CLKSTCTRL);
+       cm_context.neon_cm_clkstctrl =
+               omap2_cm_read_mod_reg(OMAP3430_NEON_MOD, OMAP2_CM_CLKSTCTRL);
+       cm_context.usbhost_cm_clkstctrl =
+               omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
+                                     OMAP2_CM_CLKSTCTRL);
+       cm_context.core_cm_autoidle1 =
+               omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1);
+       cm_context.core_cm_autoidle2 =
+               omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE2);
+       cm_context.core_cm_autoidle3 =
+               omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE3);
+       cm_context.wkup_cm_autoidle =
+               omap2_cm_read_mod_reg(WKUP_MOD, CM_AUTOIDLE);
+       cm_context.dss_cm_autoidle =
+               omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_AUTOIDLE);
+       cm_context.cam_cm_autoidle =
+               omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_AUTOIDLE);
+       cm_context.per_cm_autoidle =
+               omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
+       cm_context.usbhost_cm_autoidle =
+               omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
+       cm_context.sgx_cm_sleepdep =
+               omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
+                                     OMAP3430_CM_SLEEPDEP);
+       cm_context.dss_cm_sleepdep =
+               omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP3430_CM_SLEEPDEP);
+       cm_context.cam_cm_sleepdep =
+               omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP3430_CM_SLEEPDEP);
+       cm_context.per_cm_sleepdep =
+               omap2_cm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_CM_SLEEPDEP);
+       cm_context.usbhost_cm_sleepdep =
+               omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
+                                     OMAP3430_CM_SLEEPDEP);
+       cm_context.cm_clkout_ctrl =
+               omap2_cm_read_mod_reg(OMAP3430_CCR_MOD,
+                                     OMAP3_CM_CLKOUT_CTRL_OFFSET);
+}
+
+void omap3_cm_restore_context(void)
+{
+       omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel1, OMAP3430_IVA2_MOD,
+                              CM_CLKSEL1);
+       omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD,
+                              CM_CLKSEL2);
+       __raw_writel(cm_context.cm_sysconfig, OMAP3430_CM_SYSCONFIG);
+       omap2_cm_write_mod_reg(cm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD,
+                              CM_CLKSEL);
+       omap2_cm_write_mod_reg(cm_context.dss_cm_clksel, OMAP3430_DSS_MOD,
+                              CM_CLKSEL);
+       omap2_cm_write_mod_reg(cm_context.cam_cm_clksel, OMAP3430_CAM_MOD,
+                              CM_CLKSEL);
+       omap2_cm_write_mod_reg(cm_context.per_cm_clksel, OMAP3430_PER_MOD,
+                              CM_CLKSEL);
+       omap2_cm_write_mod_reg(cm_context.emu_cm_clksel, OMAP3430_EMU_MOD,
+                              CM_CLKSEL1);
+       omap2_cm_write_mod_reg(cm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
+                              OMAP2_CM_CLKSTCTRL);
+       /*
+        * As per erratum i671, ROM code does not respect the PER DPLL
+        * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1.
+        * In this case, we need to restore AUTO_PERIPH_DPLL by ourselves.
+        */
+       omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle, PLL_MOD,
+                              CM_AUTOIDLE);
+       omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle2, PLL_MOD,
+                              CM_AUTOIDLE2);
+       omap2_cm_write_mod_reg(cm_context.pll_cm_clksel4, PLL_MOD,
+                              OMAP3430ES2_CM_CLKSEL4);
+       omap2_cm_write_mod_reg(cm_context.pll_cm_clksel5, PLL_MOD,
+                              OMAP3430ES2_CM_CLKSEL5);
+       omap2_cm_write_mod_reg(cm_context.pll_cm_clken2, PLL_MOD,
+                              OMAP3430ES2_CM_CLKEN2);
+       __raw_writel(cm_context.cm_polctrl, OMAP3430_CM_POLCTRL);
+       omap2_cm_write_mod_reg(cm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD,
+                              CM_FCLKEN);
+       omap2_cm_write_mod_reg(cm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD,
+                              OMAP3430_CM_CLKEN_PLL);
+       omap2_cm_write_mod_reg(cm_context.core_cm_fclken1, CORE_MOD,
+                              CM_FCLKEN1);
+       omap2_cm_write_mod_reg(cm_context.core_cm_fclken3, CORE_MOD,
+                              OMAP3430ES2_CM_FCLKEN3);
+       omap2_cm_write_mod_reg(cm_context.sgx_cm_fclken, OMAP3430ES2_SGX_MOD,
+                              CM_FCLKEN);
+       omap2_cm_write_mod_reg(cm_context.wkup_cm_fclken, WKUP_MOD, CM_FCLKEN);
+       omap2_cm_write_mod_reg(cm_context.dss_cm_fclken, OMAP3430_DSS_MOD,
+                              CM_FCLKEN);
+       omap2_cm_write_mod_reg(cm_context.cam_cm_fclken, OMAP3430_CAM_MOD,
+                              CM_FCLKEN);
+       omap2_cm_write_mod_reg(cm_context.per_cm_fclken, OMAP3430_PER_MOD,
+                              CM_FCLKEN);
+       omap2_cm_write_mod_reg(cm_context.usbhost_cm_fclken,
+                              OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
+       omap2_cm_write_mod_reg(cm_context.core_cm_iclken1, CORE_MOD,
+                              CM_ICLKEN1);
+       omap2_cm_write_mod_reg(cm_context.core_cm_iclken2, CORE_MOD,
+                              CM_ICLKEN2);
+       omap2_cm_write_mod_reg(cm_context.core_cm_iclken3, CORE_MOD,
+                              CM_ICLKEN3);
+       omap2_cm_write_mod_reg(cm_context.sgx_cm_iclken, OMAP3430ES2_SGX_MOD,
+                              CM_ICLKEN);
+       omap2_cm_write_mod_reg(cm_context.wkup_cm_iclken, WKUP_MOD, CM_ICLKEN);
+       omap2_cm_write_mod_reg(cm_context.dss_cm_iclken, OMAP3430_DSS_MOD,
+                              CM_ICLKEN);
+       omap2_cm_write_mod_reg(cm_context.cam_cm_iclken, OMAP3430_CAM_MOD,
+                              CM_ICLKEN);
+       omap2_cm_write_mod_reg(cm_context.per_cm_iclken, OMAP3430_PER_MOD,
+                              CM_ICLKEN);
+       omap2_cm_write_mod_reg(cm_context.usbhost_cm_iclken,
+                              OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
+       omap2_cm_write_mod_reg(cm_context.iva2_cm_autoidle2, OMAP3430_IVA2_MOD,
+                              CM_AUTOIDLE2);
+       omap2_cm_write_mod_reg(cm_context.mpu_cm_autoidle2, MPU_MOD,
+                              CM_AUTOIDLE2);
+       omap2_cm_write_mod_reg(cm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
+                              OMAP2_CM_CLKSTCTRL);
+       omap2_cm_write_mod_reg(cm_context.mpu_cm_clkstctrl, MPU_MOD,
+                              OMAP2_CM_CLKSTCTRL);
+       omap2_cm_write_mod_reg(cm_context.core_cm_clkstctrl, CORE_MOD,
+                              OMAP2_CM_CLKSTCTRL);
+       omap2_cm_write_mod_reg(cm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD,
+                              OMAP2_CM_CLKSTCTRL);
+       omap2_cm_write_mod_reg(cm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD,
+                              OMAP2_CM_CLKSTCTRL);
+       omap2_cm_write_mod_reg(cm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD,
+                              OMAP2_CM_CLKSTCTRL);
+       omap2_cm_write_mod_reg(cm_context.per_cm_clkstctrl, OMAP3430_PER_MOD,
+                              OMAP2_CM_CLKSTCTRL);
+       omap2_cm_write_mod_reg(cm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD,
+                              OMAP2_CM_CLKSTCTRL);
+       omap2_cm_write_mod_reg(cm_context.usbhost_cm_clkstctrl,
+                              OMAP3430ES2_USBHOST_MOD, OMAP2_CM_CLKSTCTRL);
+       omap2_cm_write_mod_reg(cm_context.core_cm_autoidle1, CORE_MOD,
+                              CM_AUTOIDLE1);
+       omap2_cm_write_mod_reg(cm_context.core_cm_autoidle2, CORE_MOD,
+                              CM_AUTOIDLE2);
+       omap2_cm_write_mod_reg(cm_context.core_cm_autoidle3, CORE_MOD,
+                              CM_AUTOIDLE3);
+       omap2_cm_write_mod_reg(cm_context.wkup_cm_autoidle, WKUP_MOD,
+                              CM_AUTOIDLE);
+       omap2_cm_write_mod_reg(cm_context.dss_cm_autoidle, OMAP3430_DSS_MOD,
+                              CM_AUTOIDLE);
+       omap2_cm_write_mod_reg(cm_context.cam_cm_autoidle, OMAP3430_CAM_MOD,
+                              CM_AUTOIDLE);
+       omap2_cm_write_mod_reg(cm_context.per_cm_autoidle, OMAP3430_PER_MOD,
+                              CM_AUTOIDLE);
+       omap2_cm_write_mod_reg(cm_context.usbhost_cm_autoidle,
+                              OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
+       omap2_cm_write_mod_reg(cm_context.sgx_cm_sleepdep, OMAP3430ES2_SGX_MOD,
+                              OMAP3430_CM_SLEEPDEP);
+       omap2_cm_write_mod_reg(cm_context.dss_cm_sleepdep, OMAP3430_DSS_MOD,
+                              OMAP3430_CM_SLEEPDEP);
+       omap2_cm_write_mod_reg(cm_context.cam_cm_sleepdep, OMAP3430_CAM_MOD,
+                              OMAP3430_CM_SLEEPDEP);
+       omap2_cm_write_mod_reg(cm_context.per_cm_sleepdep, OMAP3430_PER_MOD,
+                              OMAP3430_CM_SLEEPDEP);
+       omap2_cm_write_mod_reg(cm_context.usbhost_cm_sleepdep,
+                              OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
+       omap2_cm_write_mod_reg(cm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
+                              OMAP3_CM_CLKOUT_CTRL_OFFSET);
+}
diff --git a/arch/arm/mach-omap2/cm3xxx.h b/arch/arm/mach-omap2/cm3xxx.h
new file mode 100644 (file)
index 0000000..4a6ac81
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * OMAP2/3 Clock Management (CM) register definitions
+ *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The CM hardware modules on the OMAP2/3 are quite similar to each
+ * other.  The CM modules/instances on OMAP4 are quite different, so
+ * they are handled in a separate file.
+ */
+#ifndef __ARCH_ASM_MACH_OMAP2_CM3XXX_H
+#define __ARCH_ASM_MACH_OMAP2_CM3XXX_H
+
+#include "prcm-common.h"
+#include "cm2xxx_3xxx.h"
+
+#define OMAP34XX_CM_REGADDR(module, reg)                               \
+                       OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
+
+
+/*
+ * OMAP3-specific global CM registers
+ * Use cm_{read,write}_reg() with these registers.
+ * These registers appear once per CM module.
+ */
+
+#define OMAP3430_CM_REVISION           OMAP34XX_CM_REGADDR(OCP_MOD, 0x0000)
+#define OMAP3430_CM_SYSCONFIG          OMAP34XX_CM_REGADDR(OCP_MOD, 0x0010)
+#define OMAP3430_CM_POLCTRL            OMAP34XX_CM_REGADDR(OCP_MOD, 0x009c)
+
+#define OMAP3_CM_CLKOUT_CTRL_OFFSET    0x0070
+#define OMAP3430_CM_CLKOUT_CTRL                OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
+
+/*
+ * Module specific CM register offsets from CM_BASE + domain offset
+ * Use cm_{read,write}_mod_reg() with these registers.
+ * These register offsets generally appear in more than one PRCM submodule.
+ */
+
+/* OMAP3-specific register offsets */
+
+#define OMAP3430_CM_CLKEN_PLL                          0x0004
+#define OMAP3430ES2_CM_CLKEN2                          0x0004
+#define OMAP3430ES2_CM_FCLKEN3                         0x0008
+#define OMAP3430_CM_IDLEST_PLL                         CM_IDLEST2
+#define OMAP3430_CM_AUTOIDLE_PLL                       CM_AUTOIDLE2
+#define OMAP3430ES2_CM_AUTOIDLE2_PLL                   CM_AUTOIDLE2
+#define OMAP3430_CM_CLKSEL1                            CM_CLKSEL
+#define OMAP3430_CM_CLKSEL1_PLL                                CM_CLKSEL
+#define OMAP3430_CM_CLKSEL2_PLL                                CM_CLKSEL2
+#define OMAP3430_CM_SLEEPDEP                           CM_CLKSEL2
+#define OMAP3430_CM_CLKSEL3                            OMAP2_CM_CLKSTCTRL
+#define OMAP3430_CM_CLKSTST                            0x004c
+#define OMAP3430ES2_CM_CLKSEL4                         0x004c
+#define OMAP3430ES2_CM_CLKSEL5                         0x0050
+#define OMAP3430_CM_CLKSEL2_EMU                                0x0050
+#define OMAP3430_CM_CLKSEL3_EMU                                0x0054
+
+
+/* CM_IDLEST bit field values to indicate deasserted IdleReq */
+
+#define OMAP34XX_CM_IDLEST_VAL                         1
+
+
+#ifndef __ASSEMBLER__
+
+extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
+extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
+extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask);
+extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask);
+
+extern bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask);
+extern int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
+                                        u8 idlest_shift);
+
+extern void omap3_cm_save_context(void);
+extern void omap3_cm_restore_context(void);
+
+#endif
+
+#endif
index 1220e0ef0b865ba9ff4ed22d78d55b992ab6b8ef..a7d1eb8fb57cf5379c737cb75f452ef2a6ae4431 100644 (file)
@@ -23,7 +23,7 @@
 #include "cm-regbits-34xx.h"
 #include "prm-regbits-34xx.h"
 #include "prm3xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm3xxx.h"
 #include "sdrc.h"
 #include "pm.h"
 #include "control.h"
index 525c58d25730760149b0b793251952c2765533ee..504e0e0ecbbd2fda9f7d858701c08e6563f8b6a0 100644 (file)
 #include "common.h"
 #include "clockdomain.h"
 #include "powerdomain.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
+#include "cm3xxx.h"
 #include "cminst44xx.h"
 #include "cm33xx.h"
 #include "prm3xxx.h"
@@ -2668,7 +2669,7 @@ static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois)
 /* Static functions intended only for use in soc_ops field function pointers */
 
 /**
- * _omap2_wait_target_ready - wait for a module to leave slave idle
+ * _omap2xxx_wait_target_ready - wait for a module to leave slave idle
  * @oh: struct omap_hwmod *
  *
  * Wait for a module @oh to leave slave idle.  Returns 0 if the module
@@ -2676,7 +2677,7 @@ static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois)
  * slave idle; otherwise, pass along the return value of the
  * appropriate *_cm*_wait_module_ready() function.
  */
-static int _omap2_wait_target_ready(struct omap_hwmod *oh)
+static int _omap2xxx_wait_target_ready(struct omap_hwmod *oh)
 {
        if (!oh)
                return -EINVAL;
@@ -2689,9 +2690,36 @@ static int _omap2_wait_target_ready(struct omap_hwmod *oh)
 
        /* XXX check module SIDLEMODE, hardreset status, enabled clocks */
 
-       return omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs,
-                                         oh->prcm.omap2.idlest_reg_id,
-                                         oh->prcm.omap2.idlest_idle_bit);
+       return omap2xxx_cm_wait_module_ready(oh->prcm.omap2.module_offs,
+                                            oh->prcm.omap2.idlest_reg_id,
+                                            oh->prcm.omap2.idlest_idle_bit);
+}
+
+/**
+ * _omap3xxx_wait_target_ready - wait for a module to leave slave idle
+ * @oh: struct omap_hwmod *
+ *
+ * Wait for a module @oh to leave slave idle.  Returns 0 if the module
+ * does not have an IDLEST bit or if the module successfully leaves
+ * slave idle; otherwise, pass along the return value of the
+ * appropriate *_cm*_wait_module_ready() function.
+ */
+static int _omap3xxx_wait_target_ready(struct omap_hwmod *oh)
+{
+       if (!oh)
+               return -EINVAL;
+
+       if (oh->flags & HWMOD_NO_IDLEST)
+               return 0;
+
+       if (!_find_mpu_rt_port(oh))
+               return 0;
+
+       /* XXX check module SIDLEMODE, hardreset status, enabled clocks */
+
+       return omap3xxx_cm_wait_module_ready(oh->prcm.omap2.module_offs,
+                                            oh->prcm.omap2.idlest_reg_id,
+                                            oh->prcm.omap2.idlest_idle_bit);
 }
 
 /**
@@ -3959,8 +3987,13 @@ int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx)
  */
 void __init omap_hwmod_init(void)
 {
-       if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-               soc_ops.wait_target_ready = _omap2_wait_target_ready;
+       if (cpu_is_omap24xx()) {
+               soc_ops.wait_target_ready = _omap2xxx_wait_target_ready;
+               soc_ops.assert_hardreset = _omap2_assert_hardreset;
+               soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
+               soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
+       } else if (cpu_is_omap34xx()) {
+               soc_ops.wait_target_ready = _omap3xxx_wait_target_ready;
                soc_ops.assert_hardreset = _omap2_assert_hardreset;
                soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
                soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
index 78405a7fb99ec8a1db9e3642cdf85dbf3c64bf1f..02dca24ec0ab603ba4339dc559e826b8c156aadc 100644 (file)
@@ -43,7 +43,7 @@
 #include "common.h"
 #include "prm2xxx.h"
 #include "prm-regbits-24xx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
 #include "cm-regbits-24xx.h"
 #include "sdrc.h"
 #include "pm.h"
index c02c9ca9ef0519940148f8d48cb782e2ebf33bcc..c0f8a7804bf718903fc28af01276a1779b0b0984 100644 (file)
 #include <plat/dma.h>
 
 #include "common.h"
-#include "cm2xxx_3xxx.h"
+#include "cm3xxx.h"
 #include "cm-regbits-34xx.h"
 #include "prm-regbits-34xx.h"
-
 #include "prm3xxx.h"
 #include "pm.h"
 #include "sdrc.h"
index d83b9182933552758bffbe45858e5570af75d9e9..b5bc4b107565a7d6cc15b89aca24b6137230f9c5 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "omap34xx.h"
 #include "iomap.h"
-#include "cm2xxx_3xxx.h"
+#include "cm3xxx.h"
 #include "prm3xxx.h"
 #include "sdrc.h"
 #include "control.h"
index c7204439bdab9d69b00eb1db204fa4124677e70a..680a7c56cc3ec2dc454ad73e0c93ebadf360d58a 100644 (file)
@@ -35,7 +35,7 @@
 #include "soc.h"
 #include "iomap.h"
 #include "prm2xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
 #include "sdrc.h"
 
        .text
index cfdc0bcfea6d8a621153d6c8d32bf6546ea4fff5..a1e9edd673f4625cf08a2b7b7dc0c9aff6dc2212 100644 (file)
@@ -35,7 +35,7 @@
 #include "soc.h"
 #include "iomap.h"
 #include "prm2xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
 #include "sdrc.h"
 
        .text
index 2d0ceaa23fb8e8f7f1803dc4480a590805769f7e..1446331b576ae4555e091287cab4f83c114102f7 100644 (file)
@@ -32,7 +32,7 @@
 #include "soc.h"
 #include "iomap.h"
 #include "sdrc.h"
-#include "cm2xxx_3xxx.h"
+#include "cm3xxx.h"
 
 /*
  * This file needs be built unconditionally as ARM to interoperate correctly