aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/Makefile2
-rw-r--r--arch/arm/mach-omap2/cm1_44xx.h26
-rw-r--r--arch/arm/mach-omap2/cm2_44xx.h14
-rw-r--r--arch/arm/mach-omap2/cm44xx.c322
-rw-r--r--arch/arm/mach-omap2/cm44xx.h4
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c2
-rw-r--r--arch/arm/mach-omap2/dpll44xx.c209
-rw-r--r--arch/arm/mach-omap2/gpmc.c12
-rw-r--r--arch/arm/mach-omap2/include/mach/dmm-44xx.h363
-rw-r--r--arch/arm/mach-omap2/include/mach/omap4-common.h27
-rw-r--r--arch/arm/mach-omap2/omap-smp.c4
-rw-r--r--arch/arm/mach-omap2/omap4-common.c35
-rw-r--r--arch/arm/mach-omap2/omap4-mpuss-lowpower.c113
-rw-r--r--arch/arm/mach-omap2/omap4-sar-layout.h66
-rw-r--r--arch/arm/mach-omap2/omap4-sar.c1054
-rw-r--r--arch/arm/mach-omap2/omap_tps6236x.c8
-rw-r--r--arch/arm/mach-omap2/omap_twl.c4
-rw-r--r--arch/arm/mach-omap2/pm-debug.c18
-rw-r--r--arch/arm/mach-omap2/pm.h22
-rw-r--r--arch/arm/mach-omap2/pm34xx.c4
-rw-r--r--arch/arm/mach-omap2/pm44xx.c202
-rw-r--r--arch/arm/mach-omap2/powerdomain44xx.c41
-rw-r--r--arch/arm/mach-omap2/powerdomains44xx_data.c8
-rw-r--r--arch/arm/mach-omap2/sleep44xx.S110
-rw-r--r--arch/arm/mach-omap2/vc.c49
-rw-r--r--arch/arm/mach-omap2/vc.h1
-rw-r--r--arch/arm/mach-omap2/voltage.h8
-rw-r--r--arch/arm/mach-omap2/voltagedomains44xx_data.c3
-rw-r--r--arch/arm/plat-omap/include/plat/gpmc.h4
-rw-r--r--arch/arm/plat-omap/include/plat/omap-pm.h2
-rw-r--r--arch/arm/plat-omap/include/plat/omap44xx.h5
-rw-r--r--arch/arm/plat-omap/omap-pm-interface.c2
-rw-r--r--drivers/gpio/gpio-omap.c44
-rw-r--r--drivers/mfd/Kconfig12
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/twl-core.c10
-rw-r--r--drivers/mfd/twl6030-power.c146
-rw-r--r--include/linux/i2c/twl.h36
38 files changed, 2852 insertions, 141 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 6f7965d..3af3f74 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -99,7 +99,7 @@ obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \
obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \
cm44xx.o prcm_mpu44xx.o \
prminst44xx.o vc44xx_data.o \
- vp44xx_data.o dvfs.o
+ vp44xx_data.o dvfs.o omap4-sar.o
# OMAP voltage domains
ifeq ($(CONFIG_PM),y)
diff --git a/arch/arm/mach-omap2/cm1_44xx.h b/arch/arm/mach-omap2/cm1_44xx.h
index e2d7a56..6a34bed 100644
--- a/arch/arm/mach-omap2/cm1_44xx.h
+++ b/arch/arm/mach-omap2/cm1_44xx.h
@@ -82,8 +82,8 @@
#define OMAP4430_CM_DIV_M7_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0044)
#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET 0x0048
#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0048)
-#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_CORE_OFFSET 0x004c
-#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x004c)
+#define OMAP4_CM_SSC_MODFREQDIV_DPLL_CORE_OFFSET 0x004c
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x004c)
#define OMAP4_CM_EMU_OVERRIDE_DPLL_CORE_OFFSET 0x0050
#define OMAP4430_CM_EMU_OVERRIDE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0050)
#define OMAP4_CM_CLKMODE_DPLL_MPU_OFFSET 0x0060
@@ -98,8 +98,8 @@
#define OMAP4430_CM_DIV_M2_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0070)
#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET 0x0088
#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0088)
-#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_MPU_OFFSET 0x008c
-#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x008c)
+#define OMAP4_CM_SSC_MODFREQDIV_DPLL_MPU_OFFSET 0x008c
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x008c)
#define OMAP4_CM_BYPCLK_DPLL_MPU_OFFSET 0x009c
#define OMAP4430_CM_BYPCLK_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x009c)
#define OMAP4_CM_CLKMODE_DPLL_IVA_OFFSET 0x00a0
@@ -116,8 +116,8 @@
#define OMAP4430_CM_DIV_M5_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00bc)
#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_IVA_OFFSET 0x00c8
#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00c8)
-#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_IVA_OFFSET 0x00cc
-#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00cc)
+#define OMAP4_CM_SSC_MODFREQDIV_DPLL_IVA_OFFSET 0x00cc
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00cc)
#define OMAP4_CM_BYPCLK_DPLL_IVA_OFFSET 0x00dc
#define OMAP4430_CM_BYPCLK_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00dc)
#define OMAP4_CM_CLKMODE_DPLL_ABE_OFFSET 0x00e0
@@ -134,8 +134,8 @@
#define OMAP4430_CM_DIV_M3_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00f4)
#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_ABE_OFFSET 0x0108
#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0108)
-#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_ABE_OFFSET 0x010c
-#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x010c)
+#define OMAP4_CM_SSC_MODFREQDIV_DPLL_ABE_OFFSET 0x010c
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x010c)
#define OMAP4_CM_CLKMODE_DPLL_DDRPHY_OFFSET 0x0120
#define OMAP4430_CM_CLKMODE_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0120)
#define OMAP4_CM_IDLEST_DPLL_DDRPHY_OFFSET 0x0124
@@ -154,8 +154,8 @@
#define OMAP4430_CM_DIV_M6_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0140)
#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_DDRPHY_OFFSET 0x0148
#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0148)
-#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_DDRPHY_OFFSET 0x014c
-#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x014c)
+#define OMAP4_CM_SSC_MODFREQDIV_DPLL_DDRPHY_OFFSET 0x014c
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x014c)
#define OMAP4_CM_SHADOW_FREQ_CONFIG1_OFFSET 0x0160
#define OMAP4430_CM_SHADOW_FREQ_CONFIG1 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0160)
#define OMAP4_CM_SHADOW_FREQ_CONFIG2_OFFSET 0x0164
@@ -236,8 +236,8 @@
#define OMAP4430_CM_CLKSEL_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x001c)
#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE_OFFSET 0x0020
#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0020)
-#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_CORE_RESTORE_OFFSET 0x0024
-#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0024)
+#define OMAP4_CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE_OFFSET 0x0024
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0024)
#define OMAP4_CM_CLKMODE_DPLL_CORE_RESTORE_OFFSET 0x0028
#define OMAP4430_CM_CLKMODE_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0028)
#define OMAP4_CM_SHADOW_FREQ_CONFIG2_RESTORE_OFFSET 0x002c
@@ -253,9 +253,11 @@
#define OMAP4_CM_DYN_DEP_PRESCAL_RESTORE_OFFSET 0x0040
#define OMAP4430_CM_DYN_DEP_PRESCAL_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0040)
+#ifndef __ASSEMBLER__
/* Function prototypes */
extern u32 omap4_cm1_read_inst_reg(s16 inst, u16 idx);
extern void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 idx);
extern u32 omap4_cm1_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+#endif
#endif
diff --git a/arch/arm/mach-omap2/cm2_44xx.h b/arch/arm/mach-omap2/cm2_44xx.h
index aa47450..b6ed984 100644
--- a/arch/arm/mach-omap2/cm2_44xx.h
+++ b/arch/arm/mach-omap2/cm2_44xx.h
@@ -121,8 +121,8 @@
#define OMAP4430_CM_DIV_M7_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0064)
#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET 0x0068
#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0068)
-#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_PER_OFFSET 0x006c
-#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x006c)
+#define OMAP4_CM_SSC_MODFREQDIV_DPLL_PER_OFFSET 0x006c
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x006c)
#define OMAP4_CM_CLKMODE_DPLL_USB_OFFSET 0x0080
#define OMAP4430_CM_CLKMODE_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0080)
#define OMAP4_CM_IDLEST_DPLL_USB_OFFSET 0x0084
@@ -135,8 +135,8 @@
#define OMAP4430_CM_DIV_M2_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0090)
#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_USB_OFFSET 0x00a8
#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00a8)
-#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_USB_OFFSET 0x00ac
-#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00ac)
+#define OMAP4_CM_SSC_MODFREQDIV_DPLL_USB_OFFSET 0x00ac
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00ac)
#define OMAP4_CM_CLKDCOLDO_DPLL_USB_OFFSET 0x00b4
#define OMAP4430_CM_CLKDCOLDO_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00b4)
#define OMAP4_CM_CLKMODE_DPLL_UNIPRO_OFFSET 0x00c0
@@ -151,8 +151,8 @@
#define OMAP4430_CM_DIV_M2_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00d0)
#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_UNIPRO_OFFSET 0x00e8
#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00e8)
-#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_UNIPRO_OFFSET 0x00ec
-#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00ec)
+#define OMAP4_CM_SSC_MODFREQDIV_DPLL_UNIPRO_OFFSET 0x00ec
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00ec)
/* CM2.ALWAYS_ON_CM2 register offsets */
#define OMAP4_CM_ALWON_CLKSTCTRL_OFFSET 0x0000
@@ -500,9 +500,11 @@
#define OMAP4_CM_SDMA_STATICDEP_RESTORE_OFFSET 0x005c
#define OMAP4430_CM_SDMA_STATICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x005c)
+#ifndef __ASSEMBLER__
/* Function prototypes */
extern u32 omap4_cm2_read_inst_reg(s16 inst, u16 idx);
extern void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 idx);
extern u32 omap4_cm2_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+#endif
#endif
diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c
index e96f53e..16d5f3d 100644
--- a/arch/arm/mach-omap2/cm44xx.c
+++ b/arch/arm/mach-omap2/cm44xx.c
@@ -21,8 +21,11 @@
#include <plat/common.h>
#include "cm.h"
+#include "cm44xx.h"
#include "cm1_44xx.h"
#include "cm2_44xx.h"
+#include "cminst44xx.h"
+#include "prcm44xx.h"
#include "cm-regbits-44xx.h"
/* CM1 hardware module low-level functions */
@@ -50,3 +53,322 @@ void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg)
{
__raw_writel(val, OMAP44XX_CM2_REGADDR(inst, reg));
}
+
+#define MAX_CM_REGISTERS 51
+
+struct omap4_cm_tuple {
+ u16 addr;
+ u32 val;
+};
+
+struct omap4_cm_regs {
+ u32 mod_off;
+ u32 no_reg;
+ struct omap4_cm_tuple reg[MAX_CM_REGISTERS];
+};
+
+static struct omap4_cm_regs cm1_regs[] = {
+ /* OMAP4430_CM1_OCP_SOCKET_MOD */
+ { .mod_off = OMAP4430_CM1_OCP_SOCKET_INST, .no_reg = 1,
+ {{.addr = OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET} },
+ },
+ /* OMAP4430_CM1_CKGEN_MOD */
+ { .mod_off = OMAP4430_CM1_CKGEN_INST, .no_reg = 4,
+ {{.addr = OMAP4_CM_CLKSEL_CORE_OFFSET},
+ {.addr = OMAP4_CM_CLKSEL_ABE_OFFSET},
+ {.addr = OMAP4_CM_DLL_CTRL_OFFSET},
+ {.addr = OMAP4_CM_DYN_DEP_PRESCAL_OFFSET} },
+ },
+ /* OMAP4430_CM1_MPU_MOD */
+ { .mod_off = OMAP4430_CM1_MPU_INST, .no_reg = 4,
+ {{.addr = OMAP4_CM_MPU_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_MPU_STATICDEP_OFFSET},
+ {.addr = OMAP4_CM_MPU_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET} },
+ },
+ /* OMAP4430_CM1_TESLA_MOD */
+ { .mod_off = OMAP4430_CM1_TESLA_INST, .no_reg = 4,
+ {{.addr = OMAP4_CM_TESLA_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_TESLA_STATICDEP_OFFSET},
+ {.addr = OMAP4_CM_TESLA_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET} },
+ },
+ /* OMAP4430_CM1_ABE_MOD */
+ { .mod_off = OMAP4430_CM1_ABE_INST, .no_reg = 15,
+ {{.addr = OMAP4_CM1_ABE_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET} },
+ },
+};
+
+static struct omap4_cm_regs cm2_regs[] = {
+ /* OMAP4430_CM2_OCP_SOCKET_MOD */
+ {.mod_off = OMAP4430_CM2_OCP_SOCKET_INST, .no_reg = 1,
+ {{.addr = OMAP4_CM_CM2_PROFILING_CLKCTRL_OFFSET} },
+ },
+ /* OMAP4430_CM2_CKGEN_MOD */
+ {.mod_off = OMAP4430_CM2_CKGEN_INST, .no_reg = 12,
+ {{.addr = OMAP4_CM_CLKSEL_DUCATI_ISS_ROOT_OFFSET},
+ {.addr = OMAP4_CM_CLKSEL_USB_60MHZ_OFFSET},
+ {.addr = OMAP4_CM_SCALE_FCLK_OFFSET},
+ {.addr = OMAP4_CM_CORE_DVFS_PERF1_OFFSET},
+ {.addr = OMAP4_CM_CORE_DVFS_PERF2_OFFSET},
+ {.addr = OMAP4_CM_CORE_DVFS_PERF3_OFFSET},
+ {.addr = OMAP4_CM_CORE_DVFS_PERF4_OFFSET},
+ {.addr = OMAP4_CM_CORE_DVFS_CURRENT_OFFSET},
+ {.addr = OMAP4_CM_IVA_DVFS_PERF_TESLA_OFFSET},
+ {.addr = OMAP4_CM_IVA_DVFS_PERF_IVAHD_OFFSET},
+ {.addr = OMAP4_CM_IVA_DVFS_PERF_ABE_OFFSET},
+ {.addr = OMAP4_CM_IVA_DVFS_CURRENT_OFFSET} },
+ },
+ /* OMAP4430_CM2_ALWAYS_ON_MOD */
+ {.mod_off = OMAP4430_CM2_ALWAYS_ON_INST, .no_reg = 6,
+ {{.addr = OMAP4_CM_ALWON_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_ALWON_MDMINTC_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_ALWON_USBPHY_CLKCTRL_OFFSET} },
+ },
+ /* OMAP4430_CM2_CORE_MOD */
+ {.mod_off = OMAP4430_CM2_CORE_INST, .no_reg = 41,
+ {{.addr = OMAP4_CM_L3_1_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3_1_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3_2_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3_2_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_DUCATI_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_DUCATI_STATICDEP_OFFSET},
+ {.addr = OMAP4_CM_DUCATI_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_SDMA_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_SDMA_STATICDEP_OFFSET},
+ {.addr = OMAP4_CM_SDMA_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_MEMIF_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_MEMIF_EMIF_1_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_MEMIF_EMIF_2_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_MEMIF_DLL_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_MEMIF_EMIF_H1_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_MEMIF_EMIF_H2_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_MEMIF_DLL_H_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_D2D_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_D2D_STATICDEP_OFFSET},
+ {.addr = OMAP4_CM_D2D_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_D2D_INSTEM_ICR_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_D2D_SAD2D_FW_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4CFG_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4CFG_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INSTR_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_OFFSET} },
+ },
+ /* OMAP4430_CM2_IVAHD_MOD */
+ {.mod_off = OMAP4430_CM2_IVAHD_INST, .no_reg = 5,
+ {{.addr = OMAP4_CM_IVAHD_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_IVAHD_STATICDEP_OFFSET},
+ {.addr = OMAP4_CM_IVAHD_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET} },
+ },
+ /* OMAP4430_CM2_CAM_MOD */
+ {.mod_off = OMAP4430_CM2_CAM_INST, .no_reg = 5,
+ {{.addr = OMAP4_CM_CAM_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_CAM_STATICDEP_OFFSET},
+ {.addr = OMAP4_CM_CAM_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_CAM_FDIF_CLKCTRL_OFFSET} },
+ },
+ /* OMAP4430_CM2_DSS_MOD */
+ {.mod_off = OMAP4430_CM2_DSS_INST, .no_reg = 5,
+ {{.addr = OMAP4_CM_DSS_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_DSS_STATICDEP_OFFSET},
+ {.addr = OMAP4_CM_DSS_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_DSS_DEISS_CLKCTRL_OFFSET} },
+ },
+ /* OMAP4430_CM2_GFX_MOD */
+ {.mod_off = OMAP4430_CM2_GFX_INST, .no_reg = 4,
+ {{.addr = OMAP4_CM_GFX_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_GFX_STATICDEP_OFFSET},
+ {.addr = OMAP4_CM_GFX_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET} },
+ },
+ /* OMAP4430_CM2_L3INIT_MOD */
+ {.mod_off = OMAP4430_CM2_L3INIT_INST, .no_reg = 20,
+ {{.addr = OMAP4_CM_L3INIT_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_STATICDEP_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_UNIPRO1_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_P1500_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_EMAC_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_SATA_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_TPPSS_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_PCIESS_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_CCPTX_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_XHPI_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_MMC6_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_USB_HOST_FS_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET} },
+ },
+ /* OMAP4430_CM2_L4PER_MOD */
+ {.mod_off = OMAP4430_CM2_L4PER_INST, .no_reg = 51,
+ {{.addr = OMAP4_CM_L4PER_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_L4PER_ADC_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_HECC1_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_HECC2_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_MCASP2_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_MCASP3_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_MGATE_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_MSPROHG_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4PER_I2C5_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4SEC_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4SEC_STATICDEP_OFFSET},
+ {.addr = OMAP4_CM_L4SEC_DYNAMICDEP_OFFSET},
+ {.addr = OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4SEC_AES2_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4SEC_PKAEIP29_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4SEC_RNG_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET},
+ {.addr = OMAP4_CM_L4SEC_CRYPTODMA_CLKCTRL_OFFSET} },
+ },
+ /* OMAP4430_CM2_CEFUSE_MOD */
+ {.mod_off = OMAP4430_CM2_CEFUSE_INST, .no_reg = 2,
+ {{.addr = OMAP4_CM_CEFUSE_CLKSTCTRL_OFFSET},
+ {.addr = OMAP4_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET} },
+ },
+};
+
+static void omap4_cm1_prepare_off(void)
+{
+ u32 i, j;
+ struct omap4_cm_regs *cm_reg = cm1_regs;
+
+ for (i = 0; i < ARRAY_SIZE(cm1_regs); i++, cm_reg++) {
+ for (j = 0; j < cm_reg->no_reg; j++) {
+ cm_reg->reg[j].val =
+ omap4_cminst_read_inst_reg(OMAP4430_CM1_PARTITION,
+ cm_reg->mod_off,
+ cm_reg->reg[j].addr);
+ }
+ }
+}
+
+static void omap4_cm2_prepare_off(void)
+{
+ u32 i, j;
+ struct omap4_cm_regs *cm_reg = cm2_regs;
+
+ for (i = 0; i < ARRAY_SIZE(cm2_regs); i++, cm_reg++) {
+ for (j = 0; j < cm_reg->no_reg; j++) {
+ cm_reg->reg[j].val =
+ omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
+ cm_reg->mod_off,
+ cm_reg->reg[j].addr);
+ }
+ }
+}
+
+static void omap4_cm1_resume_off(void)
+{
+ u32 i, j;
+ struct omap4_cm_regs *cm_reg = cm1_regs;
+
+ for (i = 0; i < ARRAY_SIZE(cm1_regs); i++, cm_reg++) {
+ for (j = 0; j < cm_reg->no_reg; j++) {
+ omap4_cminst_write_inst_reg(cm_reg->reg[j].val,
+ OMAP4430_CM1_PARTITION,
+ cm_reg->mod_off,
+ cm_reg->reg[j].addr);
+ }
+ }
+}
+
+static void omap4_cm2_resume_off(void)
+{
+ u32 i, j;
+ struct omap4_cm_regs *cm_reg = cm2_regs;
+
+ for (i = 0; i < ARRAY_SIZE(cm2_regs); i++, cm_reg++) {
+ for (j = 0; j < cm_reg->no_reg; j++) {
+ omap4_cminst_write_inst_reg(cm_reg->reg[j].val,
+ OMAP4430_CM2_PARTITION,
+ cm_reg->mod_off,
+ cm_reg->reg[j].addr);
+ }
+ }
+}
+
+void omap4_cm_prepare_off(void)
+{
+ omap4_cm1_prepare_off();
+ omap4_cm2_prepare_off();
+}
+
+void omap4_cm_resume_off(void)
+{
+ omap4_cm1_resume_off();
+ omap4_cm2_resume_off();
+}
diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h
index 0b87ec8..4124989 100644
--- a/arch/arm/mach-omap2/cm44xx.h
+++ b/arch/arm/mach-omap2/cm44xx.h
@@ -27,6 +27,10 @@
# ifndef __ASSEMBLER__
extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg);
+extern void omap4_cm_prepare_off(void);
+extern void omap4_cm_resume_off(void);
+extern void omap4_dpll_prepare_off(void);
+extern void omap4_dpll_resume_off(void);
# endif
#endif
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 4bf6e6e..3457630 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -157,7 +157,7 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
u32 mpu_deepest_state = PWRDM_POWER_RET;
u32 core_deepest_state = PWRDM_POWER_RET;
- if (enable_off_mode) {
+ if (off_mode_enabled) {
mpu_deepest_state = PWRDM_POWER_OFF;
/*
* Erratum i583: valable for ES rev < Es1.2 on 3630.
diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c
index 6e26ba7..e4051c2 100644
--- a/arch/arm/mach-omap2/dpll44xx.c
+++ b/arch/arm/mach-omap2/dpll44xx.c
@@ -24,10 +24,15 @@
#include "clock.h"
#include "clock44xx.h"
#include "cm.h"
+#include "cm44xx.h"
#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "cminst44xx.h"
#include "clock44xx.h"
#include "clockdomain.h"
#include "cm-regbits-44xx.h"
+#include "prcm44xx.h"
+
#define MAX_FREQ_UPDATE_TIMEOUT 100000
static struct clockdomain *l3_emif_clkdm;
@@ -164,6 +169,9 @@ int omap4_prcm_freq_update(void)
return 0;
}
+/* Use a very high retry count - we should not hit this condition */
+#define MAX_DPLL_WAIT_TRIES 1000000
+
#define OMAP_1GHz 1000000000
#define OMAP_920MHz 920000000
#define OMAP_748MHz 748000000
@@ -381,3 +389,204 @@ long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate)
return clk->dpll_data->last_rounded_rate;
}
+
+struct dpll_reg_tuple {
+ u16 addr;
+ u32 val;
+};
+
+struct omap4_dpll_regs {
+ char *name;
+ u32 mod_partition;
+ u32 mod_inst;
+ struct dpll_reg_tuple clkmode;
+ struct dpll_reg_tuple autoidle;
+ struct dpll_reg_tuple idlest;
+ struct dpll_reg_tuple clksel;
+ struct dpll_reg_tuple div_m2;
+ struct dpll_reg_tuple div_m3;
+ struct dpll_reg_tuple div_m4;
+ struct dpll_reg_tuple div_m5;
+ struct dpll_reg_tuple div_m6;
+ struct dpll_reg_tuple div_m7;
+ struct dpll_reg_tuple clkdcoldo;
+};
+
+static struct omap4_dpll_regs dpll_regs[] = {
+ /* MPU DPLL */
+ { .name = "mpu",
+ .mod_partition = OMAP4430_CM1_PARTITION,
+ .mod_inst = OMAP4430_CM1_CKGEN_INST,
+ .clkmode = {.addr = OMAP4_CM_CLKMODE_DPLL_MPU_OFFSET},
+ .autoidle = {.addr = OMAP4_CM_AUTOIDLE_DPLL_MPU_OFFSET},
+ .idlest = {.addr = OMAP4_CM_IDLEST_DPLL_MPU_OFFSET},
+ .clksel = {.addr = OMAP4_CM_CLKSEL_DPLL_MPU_OFFSET},
+ .div_m2 = {.addr = OMAP4_CM_DIV_M2_DPLL_MPU_OFFSET},
+ },
+ /* IVA DPLL */
+ { .name = "iva",
+ .mod_partition = OMAP4430_CM1_PARTITION,
+ .mod_inst = OMAP4430_CM1_CKGEN_INST,
+ .clkmode = {.addr = OMAP4_CM_CLKMODE_DPLL_IVA_OFFSET},
+ .autoidle = {.addr = OMAP4_CM_AUTOIDLE_DPLL_IVA_OFFSET},
+ .idlest = {.addr = OMAP4_CM_IDLEST_DPLL_IVA_OFFSET},
+ .clksel = {.addr = OMAP4_CM_CLKSEL_DPLL_IVA_OFFSET},
+ .div_m4 = {.addr = OMAP4_CM_DIV_M4_DPLL_IVA_OFFSET},
+ .div_m5 = {.addr = OMAP4_CM_DIV_M5_DPLL_IVA_OFFSET},
+ },
+ /* ABE DPLL */
+ { .name = "abe",
+ .mod_partition = OMAP4430_CM1_PARTITION,
+ .mod_inst = OMAP4430_CM1_CKGEN_INST,
+ .clkmode = {.addr = OMAP4_CM_CLKMODE_DPLL_ABE_OFFSET},
+ .autoidle = {.addr = OMAP4_CM_AUTOIDLE_DPLL_ABE_OFFSET},
+ .idlest = {.addr = OMAP4_CM_IDLEST_DPLL_ABE_OFFSET},
+ .clksel = {.addr = OMAP4_CM_CLKSEL_DPLL_ABE_OFFSET},
+ .div_m2 = {.addr = OMAP4_CM_DIV_M2_DPLL_ABE_OFFSET},
+ .div_m3 = {.addr = OMAP4_CM_DIV_M3_DPLL_ABE_OFFSET},
+ },
+ /* USB DPLL */
+ { .name = "usb",
+ .mod_partition = OMAP4430_CM2_PARTITION,
+ .mod_inst = OMAP4430_CM2_CKGEN_INST,
+ .clkmode = {.addr = OMAP4_CM_CLKMODE_DPLL_USB_OFFSET},
+ .autoidle = {.addr = OMAP4_CM_AUTOIDLE_DPLL_USB_OFFSET},
+ .idlest = {.addr = OMAP4_CM_IDLEST_DPLL_USB_OFFSET},
+ .clksel = {.addr = OMAP4_CM_CLKSEL_DPLL_USB_OFFSET},
+ .div_m2 = {.addr = OMAP4_CM_DIV_M2_DPLL_USB_OFFSET},
+ .clkdcoldo = {.addr = OMAP4_CM_CLKDCOLDO_DPLL_USB_OFFSET},
+ },
+ /* PER DPLL */
+ { .name = "per",
+ .mod_partition = OMAP4430_CM2_PARTITION,
+ .mod_inst = OMAP4430_CM2_CKGEN_INST,
+ .clkmode = {.addr = OMAP4_CM_CLKMODE_DPLL_PER_OFFSET},
+ .autoidle = {.addr = OMAP4_CM_AUTOIDLE_DPLL_PER_OFFSET},
+ .idlest = {.addr = OMAP4_CM_IDLEST_DPLL_PER_OFFSET},
+ .clksel = {.addr = OMAP4_CM_CLKSEL_DPLL_PER_OFFSET},
+ .div_m2 = {.addr = OMAP4_CM_DIV_M2_DPLL_PER_OFFSET},
+ .div_m3 = {.addr = OMAP4_CM_DIV_M3_DPLL_PER_OFFSET},
+ .div_m4 = {.addr = OMAP4_CM_DIV_M4_DPLL_PER_OFFSET},
+ .div_m5 = {.addr = OMAP4_CM_DIV_M5_DPLL_PER_OFFSET},
+ .div_m6 = {.addr = OMAP4_CM_DIV_M6_DPLL_PER_OFFSET},
+ .div_m7 = {.addr = OMAP4_CM_DIV_M7_DPLL_PER_OFFSET},
+ },
+};
+
+static inline void omap4_dpll_store_reg(struct omap4_dpll_regs *dpll_reg,
+ struct dpll_reg_tuple *tuple)
+{
+ if (tuple->addr)
+ tuple->val =
+ omap4_cminst_read_inst_reg(dpll_reg->mod_partition,
+ dpll_reg->mod_inst, tuple->addr);
+}
+
+void omap4_dpll_prepare_off(void)
+{
+ u32 i;
+ struct omap4_dpll_regs *dpll_reg = dpll_regs;
+
+ for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
+ omap4_dpll_store_reg(dpll_reg, &dpll_reg->clkmode);
+ omap4_dpll_store_reg(dpll_reg, &dpll_reg->autoidle);
+ omap4_dpll_store_reg(dpll_reg, &dpll_reg->clksel);
+ omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m2);
+ omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m3);
+ omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m4);
+ omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m5);
+ omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m6);
+ omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m7);
+ omap4_dpll_store_reg(dpll_reg, &dpll_reg->clkdcoldo);
+ omap4_dpll_store_reg(dpll_reg, &dpll_reg->idlest);
+ }
+}
+
+static void omap4_dpll_print_reg(struct omap4_dpll_regs *dpll_reg, char *name,
+ struct dpll_reg_tuple *tuple)
+{
+ if (tuple->addr)
+ pr_warn("%s - Address offset = 0x%08x, value=0x%08x\n", name,
+ tuple->addr, tuple->val);
+}
+
+static void omap4_dpll_dump_regs(struct omap4_dpll_regs *dpll_reg)
+{
+ pr_warn("%s: Unable to lock dpll %s[part=%x inst=%x]:\n",
+ __func__, dpll_reg->name, dpll_reg->mod_partition,
+ dpll_reg->mod_inst);
+ omap4_dpll_print_reg(dpll_reg, "clksel", &dpll_reg->clksel);
+ omap4_dpll_print_reg(dpll_reg, "div_m2", &dpll_reg->div_m2);
+ omap4_dpll_print_reg(dpll_reg, "div_m3", &dpll_reg->div_m3);
+ omap4_dpll_print_reg(dpll_reg, "div_m4", &dpll_reg->div_m4);
+ omap4_dpll_print_reg(dpll_reg, "div_m5", &dpll_reg->div_m5);
+ omap4_dpll_print_reg(dpll_reg, "div_m6", &dpll_reg->div_m6);
+ omap4_dpll_print_reg(dpll_reg, "div_m7", &dpll_reg->div_m7);
+ omap4_dpll_print_reg(dpll_reg, "clkdcoldo", &dpll_reg->clkdcoldo);
+ omap4_dpll_print_reg(dpll_reg, "clkmode", &dpll_reg->clkmode);
+ omap4_dpll_print_reg(dpll_reg, "autoidle", &dpll_reg->autoidle);
+ if (dpll_reg->idlest.addr)
+ pr_warn("idlest - Address offset = 0x%08x, before val=0x%08x"
+ " after = 0x%08x\n", dpll_reg->idlest.addr,
+ dpll_reg->idlest.val,
+ omap4_cminst_read_inst_reg(dpll_reg->mod_partition,
+ dpll_reg->mod_inst,
+ dpll_reg->idlest.addr));
+}
+
+static void omap4_wait_dpll_lock(struct omap4_dpll_regs *dpll_reg)
+{
+ int j = 0;
+
+ /* Return if we dont need to lock. */
+ if ((dpll_reg->clkmode.val & OMAP4430_DPLL_EN_MASK) !=
+ DPLL_LOCKED << OMAP4430_DPLL_EN_SHIFT);
+ return;
+
+ while ((omap4_cminst_read_inst_reg(dpll_reg->mod_partition,
+ dpll_reg->mod_inst,
+ dpll_reg->idlest.addr)
+ & OMAP4430_ST_DPLL_CLK_MASK) !=
+ 0x1 << OMAP4430_ST_DPLL_CLK_SHIFT
+ && j < MAX_DPLL_WAIT_TRIES) {
+ j++;
+ udelay(1);
+ }
+
+ /* if we are unable to lock, warn and move on.. */
+ if (j == MAX_DPLL_WAIT_TRIES)
+ omap4_dpll_dump_regs(dpll_reg);
+}
+
+static inline void omap4_dpll_restore_reg(struct omap4_dpll_regs *dpll_reg,
+ struct dpll_reg_tuple *tuple)
+{
+ if (tuple->addr)
+ omap4_cminst_write_inst_reg(tuple->val, dpll_reg->mod_partition,
+ dpll_reg->mod_inst, tuple->addr);
+}
+
+void omap4_dpll_resume_off(void)
+{
+ u32 i;
+ struct omap4_dpll_regs *dpll_reg = dpll_regs;
+
+ for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
+ omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clksel);
+ omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m2);
+ omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m3);
+ omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m4);
+ omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m5);
+ omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m6);
+ omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m7);
+ omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkdcoldo);
+
+ /* Restore clkmode after the above registers are restored */
+ omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkmode);
+
+ omap4_wait_dpll_lock(dpll_reg);
+
+ /* Restore autoidle settings after the dpll is locked */
+ omap4_dpll_restore_reg(dpll_reg, &dpll_reg->autoidle);
+ }
+}
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 130034b..82e6f82 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -78,9 +78,9 @@ struct gpmc_cs_config {
/*
* Structure to save/restore gpmc context
- * to support core off on OMAP3
+ * to support core off.
*/
-struct omap3_gpmc_regs {
+struct omap_gpmc_regs {
u32 sysconfig;
u32 irqenable;
u32 timeout_ctrl;
@@ -770,10 +770,9 @@ static irqreturn_t gpmc_handle_irq(int irq, void *dev)
return IRQ_HANDLED;
}
-#ifdef CONFIG_ARCH_OMAP3
-static struct omap3_gpmc_regs gpmc_context;
+static struct omap_gpmc_regs gpmc_context;
-void omap3_gpmc_save_context(void)
+void omap_gpmc_save_context(void)
{
int i;
@@ -805,7 +804,7 @@ void omap3_gpmc_save_context(void)
}
}
-void omap3_gpmc_restore_context(void)
+void omap_gpmc_restore_context(void)
{
int i;
@@ -835,7 +834,6 @@ void omap3_gpmc_restore_context(void)
}
}
}
-#endif /* CONFIG_ARCH_OMAP3 */
/**
* gpmc_enable_hwecc - enable hardware ecc functionality
diff --git a/arch/arm/mach-omap2/include/mach/dmm-44xx.h b/arch/arm/mach-omap2/include/mach/dmm-44xx.h
new file mode 100644
index 0000000..c25dda5
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/dmm-44xx.h
@@ -0,0 +1,363 @@
+/*
+ * OMAP44xx DMM_CORE registers and bitfields
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ * Santosh Shilimkar (santosh.shilimkar@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_DMM_CORE_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_DMM_CORE_44XX_H
+
+
+/* Base address */
+#define OMAP44XX_DMM__DMM 0x4e000000
+
+/* Registers offset */
+#define OMAP44XX_DMM_REVISION 0x0000
+#define OMAP44XX_DMM_HWINFO 0x0004
+#define OMAP44XX_DMM_LISA_HWINFO 0x0008
+#define OMAP44XX_DMM_SYSCONFIG 0x0010
+#define OMAP44XX_DMM_LISA_LOCK 0x001c
+#define OMAP44XX_DMM_LISA_MAP 0x0040
+#define OMAP44XX_DMM_TILER_HWINFO 0x0208
+#define OMAP44XX_DMM_TILER_OR 0x0220
+#define OMAP44XX_DMM_PAT_HWINFO 0x0408
+#define OMAP44XX_DMM_PAT_GEOMETRY 0x040c
+#define OMAP44XX_DMM_PAT_CONFIG 0x0410
+#define OMAP44XX_DMM_PAT_VIEW 0x0420
+#define OMAP44XX_DMM_PAT_VIEW_MAP 0x0440
+#define OMAP44XX_DMM_PAT_VIEW_MAP_BASE 0x0460
+#define OMAP44XX_DMM_PAT_IRQ_EOI 0x0478
+#define OMAP44XX_DMM_PAT_IRQSTATUS_RAW 0x0480
+#define OMAP44XX_DMM_PAT_IRQSTATUS 0x0490
+#define OMAP44XX_DMM_PAT_IRQENABLE_SET 0x04a0
+#define OMAP44XX_DMM_PAT_IRQENABLE_CLR 0x04b0
+#define OMAP44XX_DMM_PAT_STATUS 0x04c0
+#define OMAP44XX_DMM_PAT_DESCR 0x0500
+#define OMAP44XX_DMM_PAT_AREA 0x0504
+#define OMAP44XX_DMM_PAT_CTRL 0x0508
+#define OMAP44XX_DMM_PAT_DATA 0x050c
+#define OMAP44XX_DMM_PEG_HWINFO 0x0608
+#define OMAP44XX_DMM_PEG_PRIO 0x0620
+#define OMAP44XX_DMM_PEG_PRIO_PAT 0x0640
+
+/* Registers shifts and masks */
+
+/* DMM_REVISION */
+#define OMAP44XX_SCHEME_SHIFT 30
+#define OMAP44XX_SCHEME_MASK (0x3 << 30)
+#define OMAP44XX_FUNC_SHIFT 16
+#define OMAP44XX_FUNC_MASK (0xfff << 16)
+#define OMAP44XX_R_RTL_SHIFT 11
+#define OMAP44XX_R_RTL_MASK (0x1f << 11)
+#define OMAP44XX_X_MAJOR_SHIFT 8
+#define OMAP44XX_X_MAJOR_MASK (0x7 << 8)
+#define OMAP44XX_CUSTOM_SHIFT 6
+#define OMAP44XX_CUSTOM_MASK (0x3 << 6)
+#define OMAP44XX_Y_MINOR_SHIFT 0
+#define OMAP44XX_Y_MINOR_MASK (0x3f << 0)
+
+/* DMM_HWINFO */
+#define OMAP44XX_ROBIN_CNT_SHIFT 16
+#define OMAP44XX_ROBIN_CNT_MASK (0xf << 16)
+#define OMAP44XX_ELLA_CNT_SHIFT 8
+#define OMAP44XX_ELLA_CNT_MASK (0xf << 8)
+#define OMAP44XX_TILER_CNT_SHIFT 0
+#define OMAP44XX_TILER_CNT_MASK (0xf << 0)
+
+/* DMM_LISA_HWINFO */
+#define OMAP44XX_SDRC_CNT_SHIFT 8
+#define OMAP44XX_SDRC_CNT_MASK (0xf << 8)
+#define OMAP44XX_SECTION_CNT_SHIFT 0
+#define OMAP44XX_SECTION_CNT_MASK (0x1f << 0)
+
+/* DMM_SYSCONFIG */
+#define OMAP44XX_IDLE_MODE_SHIFT 2
+#define OMAP44XX_IDLE_MODE_MASK (0x3 << 2)
+
+/* DMM_LISA_LOCK */
+#define OMAP44XX_LOCK_SHIFT 0
+#define OMAP44XX_LOCK_MASK (1 << 0)
+
+/* DMM_LISA_MAP */
+#define OMAP44XX_SYS_ADDR_SHIFT 24
+#define OMAP44XX_SYS_ADDR_MASK (0xff << 24)
+#define OMAP44XX_SYS_SIZE_SHIFT 20
+#define OMAP44XX_SYS_SIZE_MASK (0x7 << 20)
+#define OMAP44XX_SDRC_INTL_SHIFT 18
+#define OMAP44XX_SDRC_INTL_MASK (0x3 << 18)
+#define OMAP44XX_SDRC_ADDRSPC_SHIFT 16
+#define OMAP44XX_SDRC_ADDRSPC_MASK (0x3 << 16)
+#define OMAP44XX_SDRC_MAP_SHIFT 8
+#define OMAP44XX_SDRC_MAP_MASK (0x3 << 8)
+#define OMAP44XX_SDRC_ADDR_SHIFT 0
+#define OMAP44XX_SDRC_ADDR_MASK (0xff << 0)
+
+/* DMM_TILER_HWINFO */
+#define OMAP44XX_OR_CNT_SHIFT 0
+#define OMAP44XX_OR_CNT_MASK (0x7f << 0)
+
+/* DMM_TILER_OR */
+#define OMAP44XX_W7_SHIFT 31
+#define OMAP44XX_W7_MASK (1 << 31)
+#define OMAP44XX_OR7_SHIFT 28
+#define OMAP44XX_OR7_MASK (0x7 << 28)
+#define OMAP44XX_W6_SHIFT 27
+#define OMAP44XX_W6_MASK (1 << 27)
+#define OMAP44XX_OR6_SHIFT 24
+#define OMAP44XX_OR6_MASK (0x7 << 24)
+#define OMAP44XX_W5_SHIFT 23
+#define OMAP44XX_W5_MASK (1 << 23)
+#define OMAP44XX_OR5_SHIFT 20
+#define OMAP44XX_OR5_MASK (0x7 << 20)
+#define OMAP44XX_W4_SHIFT 19
+#define OMAP44XX_W4_MASK (1 << 19)
+#define OMAP44XX_OR4_SHIFT 16
+#define OMAP44XX_OR4_MASK (0x7 << 16)
+#define OMAP44XX_W3_SHIFT 15
+#define OMAP44XX_W3_MASK (1 << 15)
+#define OMAP44XX_OR3_SHIFT 12
+#define OMAP44XX_OR3_MASK (0x7 << 12)
+#define OMAP44XX_W2_SHIFT 11
+#define OMAP44XX_W2_MASK (1 << 11)
+#define OMAP44XX_OR2_SHIFT 8
+#define OMAP44XX_OR2_MASK (0x7 << 8)
+#define OMAP44XX_W1_SHIFT 7
+#define OMAP44XX_W1_MASK (1 << 7)
+#define OMAP44XX_OR1_SHIFT 4
+#define OMAP44XX_OR1_MASK (0x7 << 4)
+#define OMAP44XX_W0_SHIFT 3
+#define OMAP44XX_W0_MASK (1 << 3)
+#define OMAP44XX_OR0_SHIFT 0
+#define OMAP44XX_OR0_MASK (0x7 << 0)
+
+/* DMM_PAT_HWINFO */
+#define OMAP44XX_ENGINE_CNT_SHIFT 24
+#define OMAP44XX_ENGINE_CNT_MASK (0x1f << 24)
+#define OMAP44XX_LUT_CNT_SHIFT 16
+#define OMAP44XX_LUT_CNT_MASK (0x1f << 16)
+#define OMAP44XX_VIEW_MAP_CNT_SHIFT 8
+#define OMAP44XX_VIEW_MAP_CNT_MASK (0xf << 8)
+#define OMAP44XX_VIEW_CNT_SHIFT 0
+#define OMAP44XX_VIEW_CNT_MASK (0x7f << 0)
+
+/* DMM_PAT_GEOMETRY */
+#define OMAP44XX_CONT_HGHT_SHIFT 24
+#define OMAP44XX_CONT_HGHT_MASK (0x7 << 24)
+#define OMAP44XX_CONT_WDTH_SHIFT 16
+#define OMAP44XX_CONT_WDTH_MASK (0xf << 16)
+#define OMAP44XX_ADDR_RANGE_SHIFT 8
+#define OMAP44XX_ADDR_RANGE_MASK (0x3f << 8)
+#define OMAP44XX_PAGE_SZ_SHIFT 0
+#define OMAP44XX_PAGE_SZ_MASK (0x1f << 0)
+
+/* DMM_PAT_CONFIG */
+#define OMAP44XX_MODE3_SHIFT 3
+#define OMAP44XX_MODE3_MASK (1 << 3)
+#define OMAP44XX_MODE2_SHIFT 2
+#define OMAP44XX_MODE2_MASK (1 << 2)
+#define OMAP44XX_MODE1_SHIFT 1
+#define OMAP44XX_MODE1_MASK (1 << 1)
+#define OMAP44XX_MODE0_SHIFT 0
+#define OMAP44XX_MODE0_MASK (1 << 0)
+
+/* DMM_PAT_VIEW */
+#define OMAP44XX_V7_SHIFT 28
+#define OMAP44XX_V7_MASK (0x3 << 28)
+#define OMAP44XX_V6_SHIFT 24
+#define OMAP44XX_V6_MASK (0x3 << 24)
+#define OMAP44XX_V5_SHIFT 20
+#define OMAP44XX_V5_MASK (0x3 << 20)
+#define OMAP44XX_V4_SHIFT 16
+#define OMAP44XX_V4_MASK (0x3 << 16)
+#define OMAP44XX_V3_SHIFT 12
+#define OMAP44XX_V3_MASK (0x3 << 12)
+#define OMAP44XX_V2_SHIFT 8
+#define OMAP44XX_V2_MASK (0x3 << 8)
+#define OMAP44XX_V1_SHIFT 4
+#define OMAP44XX_V1_MASK (0x3 << 4)
+#define OMAP44XX_V0_SHIFT 0
+#define OMAP44XX_V0_MASK (0x3 << 0)
+
+/* DMM_PAT_VIEW_MAP */
+#define OMAP44XX_ACCESS_PAGE_SHIFT 31
+#define OMAP44XX_ACCESS_PAGE_MASK (1 << 31)
+#define OMAP44XX_CONT_PAGE_SHIFT 24
+#define OMAP44XX_CONT_PAGE_MASK (0xf << 24)
+#define OMAP44XX_ACCESS_32_SHIFT 23
+#define OMAP44XX_ACCESS_32_MASK (1 << 23)
+#define OMAP44XX_CONT_32_SHIFT 16
+#define OMAP44XX_CONT_32_MASK (0xf << 16)
+#define OMAP44XX_ACCESS_16_SHIFT 15
+#define OMAP44XX_ACCESS_16_MASK (1 << 15)
+#define OMAP44XX_CONT_16_SHIFT 8
+#define OMAP44XX_CONT_16_MASK (0xf << 8)
+#define OMAP44XX_ACCESS_8_SHIFT 7
+#define OMAP44XX_ACCESS_8_MASK (1 << 7)
+#define OMAP44XX_CONT_8_SHIFT 0
+#define OMAP44XX_CONT_8_MASK (0xf << 0)
+
+/* DMM_PAT_VIEW_MAP_BASE */
+#define OMAP44XX_BASE_ADDR_SHIFT 31
+#define OMAP44XX_BASE_ADDR_MASK (1 << 31)
+
+/* DMM_PAT_IRQ_EOI */
+#define OMAP44XX_EOI_SHIFT 0
+#define OMAP44XX_EOI_MASK (1 << 0)
+
+/* DMM_PAT_IRQSTATUS_RAW */
+#define OMAP44XX_ERR_LUT_MISS3_SHIFT 31
+#define OMAP44XX_ERR_LUT_MISS3_MASK (1 << 31)
+#define OMAP44XX_ERR_UPD_DATA3_SHIFT 30
+#define OMAP44XX_ERR_UPD_DATA3_MASK (1 << 30)
+#define OMAP44XX_ERR_UPD_CTRL3_SHIFT 29
+#define OMAP44XX_ERR_UPD_CTRL3_MASK (1 << 29)
+#define OMAP44XX_ERR_UPD_AREA3_SHIFT 28
+#define OMAP44XX_ERR_UPD_AREA3_MASK (1 << 28)
+#define OMAP44XX_ERR_INV_DATA3_SHIFT 27
+#define OMAP44XX_ERR_INV_DATA3_MASK (1 << 27)
+#define OMAP44XX_ERR_INV_DSC3_SHIFT 26
+#define OMAP44XX_ERR_INV_DSC3_MASK (1 << 26)
+#define OMAP44XX_FILL_LST3_SHIFT 25
+#define OMAP44XX_FILL_LST3_MASK (1 << 25)
+#define OMAP44XX_FILL_DSC3_SHIFT 24
+#define OMAP44XX_FILL_DSC3_MASK (1 << 24)
+#define OMAP44XX_ERR_LUT_MISS2_SHIFT 23
+#define OMAP44XX_ERR_LUT_MISS2_MASK (1 << 23)
+#define OMAP44XX_ERR_UPD_DATA2_SHIFT 22
+#define OMAP44XX_ERR_UPD_DATA2_MASK (1 << 22)
+#define OMAP44XX_ERR_UPD_CTRL2_SHIFT 21
+#define OMAP44XX_ERR_UPD_CTRL2_MASK (1 << 21)
+#define OMAP44XX_ERR_UPD_AREA2_SHIFT 20
+#define OMAP44XX_ERR_UPD_AREA2_MASK (1 << 20)
+#define OMAP44XX_ERR_INV_DATA2_SHIFT 19
+#define OMAP44XX_ERR_INV_DATA2_MASK (1 << 19)
+#define OMAP44XX_ERR_INV_DSC2_SHIFT 18
+#define OMAP44XX_ERR_INV_DSC2_MASK (1 << 18)
+#define OMAP44XX_FILL_LST2_SHIFT 17
+#define OMAP44XX_FILL_LST2_MASK (1 << 17)
+#define OMAP44XX_FILL_DSC2_SHIFT 16
+#define OMAP44XX_FILL_DSC2_MASK (1 << 16)
+#define OMAP44XX_ERR_LUT_MISS1_SHIFT 15
+#define OMAP44XX_ERR_LUT_MISS1_MASK (1 << 15)
+#define OMAP44XX_ERR_UPD_DATA1_SHIFT 14
+#define OMAP44XX_ERR_UPD_DATA1_MASK (1 << 14)
+#define OMAP44XX_ERR_UPD_CTRL1_SHIFT 13
+#define OMAP44XX_ERR_UPD_CTRL1_MASK (1 << 13)
+#define OMAP44XX_ERR_UPD_AREA1_SHIFT 12
+#define OMAP44XX_ERR_UPD_AREA1_MASK (1 << 12)
+#define OMAP44XX_ERR_INV_DATA1_SHIFT 11
+#define OMAP44XX_ERR_INV_DATA1_MASK (1 << 11)
+#define OMAP44XX_ERR_INV_DSC1_SHIFT 10
+#define OMAP44XX_ERR_INV_DSC1_MASK (1 << 10)
+#define OMAP44XX_FILL_LST1_SHIFT 9
+#define OMAP44XX_FILL_LST1_MASK (1 << 9)
+#define OMAP44XX_FILL_DSC1_SHIFT 8
+#define OMAP44XX_FILL_DSC1_MASK (1 << 8)
+#define OMAP44XX_ERR_LUT_MISS0_SHIFT 7
+#define OMAP44XX_ERR_LUT_MISS0_MASK (1 << 7)
+#define OMAP44XX_ERR_UPD_DATA0_SHIFT 6
+#define OMAP44XX_ERR_UPD_DATA0_MASK (1 << 6)
+#define OMAP44XX_ERR_UPD_CTRL0_SHIFT 5
+#define OMAP44XX_ERR_UPD_CTRL0_MASK (1 << 5)
+#define OMAP44XX_ERR_UPD_AREA0_SHIFT 4
+#define OMAP44XX_ERR_UPD_AREA0_MASK (1 << 4)
+#define OMAP44XX_ERR_INV_DATA0_SHIFT 3
+#define OMAP44XX_ERR_INV_DATA0_MASK (1 << 3)
+#define OMAP44XX_ERR_INV_DSC0_SHIFT 2
+#define OMAP44XX_ERR_INV_DSC0_MASK (1 << 2)
+#define OMAP44XX_FILL_LST0_SHIFT 1
+#define OMAP44XX_FILL_LST0_MASK (1 << 1)
+#define OMAP44XX_FILL_DSC0_SHIFT 0
+#define OMAP44XX_FILL_DSC0_MASK (1 << 0)
+
+/* DMM_PAT_IRQSTATUS */
+
+/* DMM_PAT_IRQENABLE_SET */
+
+/* DMM_PAT_IRQENABLE_CLR */
+
+/* DMM_PAT_STATUS */
+#define OMAP44XX_CNT_SHIFT 16
+#define OMAP44XX_CNT_MASK (0x1ff << 16)
+#define OMAP44XX_ERROR_SHIFT 10
+#define OMAP44XX_ERROR_MASK (0x3f << 10)
+#define OMAP44XX_BYPASSED_SHIFT 7
+#define OMAP44XX_BYPASSED_MASK (1 << 7)
+#define OMAP44XX_LINKED_SHIFT 4
+#define OMAP44XX_LINKED_MASK (1 << 4)
+#define OMAP44XX_DONE_SHIFT 3
+#define OMAP44XX_DONE_MASK (1 << 3)
+#define OMAP44XX_RUN_SHIFT 2
+#define OMAP44XX_RUN_MASK (1 << 2)
+#define OMAP44XX_VALID_SHIFT 1
+#define OMAP44XX_VALID_MASK (1 << 1)
+#define OMAP44XX_READY_SHIFT 0
+#define OMAP44XX_READY_MASK (1 << 0)
+
+/* DMM_PAT_DESCR */
+#define OMAP44XX_ADDR_SHIFT 4
+#define OMAP44XX_ADDR_MASK (0xfffffff << 4)
+
+/* DMM_PAT_AREA */
+#define OMAP44XX_Y1_SHIFT 24
+#define OMAP44XX_Y1_MASK (0x7f << 24)
+#define OMAP44XX_X1_SHIFT 16
+#define OMAP44XX_X1_MASK (0xff << 16)
+#define OMAP44XX_Y0_SHIFT 8
+#define OMAP44XX_Y0_MASK (0x7f << 8)
+#define OMAP44XX_X0_SHIFT 0
+#define OMAP44XX_X0_MASK (0xff << 0)
+
+/* DMM_PAT_CTRL */
+#define OMAP44XX_INITIATOR_SHIFT 28
+#define OMAP44XX_INITIATOR_MASK (0xf << 28)
+#define OMAP44XX_SYNC_SHIFT 16
+#define OMAP44XX_SYNC_MASK (1 << 16)
+#define OMAP44XX_DIRECTION_SHIFT 4
+#define OMAP44XX_DIRECTION_MASK (0x7 << 4)
+#define OMAP44XX_START_SHIFT 0
+#define OMAP44XX_START_MASK (1 << 0)
+
+/* DMM_PAT_DATA */
+
+/* DMM_PEG_HWINFO */
+#define OMAP44XX_PRIO_CNT_SHIFT 0
+#define OMAP44XX_PRIO_CNT_MASK (0x7f << 0)
+
+/* DMM_PEG_PRIO */
+#define OMAP44XX_P7_SHIFT 28
+#define OMAP44XX_P7_MASK (0x7 << 28)
+#define OMAP44XX_P6_SHIFT 24
+#define OMAP44XX_P6_MASK (0x7 << 24)
+#define OMAP44XX_P5_SHIFT 20
+#define OMAP44XX_P5_MASK (0x7 << 20)
+#define OMAP44XX_P4_SHIFT 16
+#define OMAP44XX_P4_MASK (0x7 << 16)
+#define OMAP44XX_P3_SHIFT 12
+#define OMAP44XX_P3_MASK (0x7 << 12)
+#define OMAP44XX_P2_SHIFT 8
+#define OMAP44XX_P2_MASK (0x7 << 8)
+#define OMAP44XX_P1_SHIFT 4
+#define OMAP44XX_P1_MASK (0x7 << 4)
+#define OMAP44XX_P0_SHIFT 0
+#define OMAP44XX_P0_MASK (0x7 << 0)
+
+/* DMM_PEG_PRIO_PAT */
+#define OMAP44XX_W_PAT_SHIFT 3
+#define OMAP44XX_W_PAT_MASK (1 << 3)
+#define OMAP44XX_P_PAT_SHIFT 0
+#define OMAP44XX_P_PAT_MASK (0x7 << 0)
+#endif
diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h
index e414ccd..0489ebe 100644
--- a/arch/arm/mach-omap2/include/mach/omap4-common.h
+++ b/arch/arm/mach-omap2/include/mach/omap4-common.h
@@ -26,7 +26,7 @@
* Secure HAL, PPA services available
*/
#define PPA_SERVICE_PL310_POR 0x23
-#define PPA_SERVICE_NS_SMP 0x25
+#define PPA_SERVICE_DEFAULT_POR_NS_SMP 0x25
/*
* Secure HAL API flags
*/
@@ -36,6 +36,15 @@
#define FLAG_FIQ_ENABLE 0x1
#define NO_FLAG 0x0
+/*
+ * SAR restore phase USB HOST static port
+ * configuration
+ */
+#define OMAP4_USBHOST_CLKSEL_UTMI_P2_INT_P1_INT 0x0
+#define OMAP4_USBHOST_CLKSEL_UTMI_P2_INT_P1_EXT 0x1
+#define OMAP4_USBHOST_CLKSEL_UTMI_P2_EXT_P1_INT 0x2
+#define OMAP4_USBHOST_CLKSEL_UTMI_P2_EXT_P1_EXT 0x3
+
#ifndef __ASSEMBLER__
#ifdef CONFIG_CACHE_L2X0
@@ -132,5 +141,21 @@ static inline u32 omap4_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
extern int omap4_prcm_freq_update(void);
+#ifdef CONFIG_PM
+extern int omap4_sar_save(void);
+extern void omap4_sar_overwrite(void);
+extern void omap4_sar_usbhost_init(u32 fck_source);
+#else
+void omap4_sar_save(void)
+{
+}
+void omap4_sar_overwrite(void)
+{
+}
+void omap4_sar_usbhost_init(u32 fck_source)
+{
+}
+#endif
+
#endif /* __ASSEMBLER__ */
#endif /* OMAP_ARCH_OMAP4_COMMON_H */
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 1509909..4fbb782 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -43,6 +43,10 @@ void __iomem *omap4_get_scu_base(void)
void __cpuinit platform_secondary_init(unsigned int cpu)
{
+ /* Enable NS access to SMP bit for this CPU on HS devices */
+ if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
+ omap4_secure_dispatcher(PPA_SERVICE_DEFAULT_POR_NS_SMP, 4, 0, 0, 0, 0, 0);
+
/*
* If any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index e8d3cab..9f040c8 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -37,7 +37,6 @@ static void __iomem *l2cache_base;
static void __iomem *gic_dist_base_addr;
static void __iomem *gic_cpu_base;
-static void __iomem *sar_ram_base;
static struct clockdomain *l4_secure_clkdm;
static void *dram_barrier_base;
@@ -274,36 +273,6 @@ static int __init omap_barriers_init(void)
}
core_initcall(omap_barriers_init);
-void __iomem *omap4_get_sar_ram_base(void)
-{
- return sar_ram_base;
-}
-
-/*
- * SAR RAM used to save and restore the HW
- * context in low power modes
- */
-static int __init omap4_sar_ram_init(void)
-{
- /*
- * To avoid code running on other OMAPs in
- * multi-omap builds
- */
- if (!cpu_is_omap44xx())
- return -ENODEV;
-
- /* Static mapping, never released */
- sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_8K);
- if (WARN_ON(!sar_ram_base))
- return -ENODEV;
-
- l4_secure_clkdm = clkdm_lookup("l4_secure_clkdm");
-
- return 0;
-}
-early_initcall(omap4_sar_ram_init);
-
-
/*
* omap4_sec_dispatcher: Routine to dispatch low power secure
* service routines
@@ -327,6 +296,10 @@ u32 omap4_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2,
param[3] = arg3;
param[4] = arg4;
+ /* Look-up Only once */
+ if (!l4_secure_clkdm)
+ l4_secure_clkdm = clkdm_lookup("l4_secure_clkdm");
+
/*
* Put l4 secure to software wakeup so that secure
* modules are accessible
diff --git a/arch/arm/mach-omap2/omap4-mpuss-lowpower.c b/arch/arm/mach-omap2/omap4-mpuss-lowpower.c
index ea14bea..69460a1 100644
--- a/arch/arm/mach-omap2/omap4-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap4-mpuss-lowpower.c
@@ -64,6 +64,10 @@
#include "prcm44xx.h"
#include "prm44xx.h"
#include "prm-regbits-44xx.h"
+#include "cm.h"
+#include "prm.h"
+#include "cm44xx.h"
+#include "prcm-common.h"
#ifdef CONFIG_SMP
@@ -93,7 +97,6 @@ static u32 max_spi_irq, max_spi_reg;
struct omap4_cpu_pm_info {
struct powerdomain *pwrdm;
void __iomem *scu_sar_addr;
- void __iomem *l1_sar_addr;
};
static void __iomem *gic_dist_base;
@@ -149,33 +152,53 @@ static inline void clear_cpu_prev_pwrst(unsigned int cpu_id)
pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
}
+struct reg_tuple {
+ void __iomem *addr;
+ u32 val;
+};
+
+static struct reg_tuple tesla_reg[] = {
+ {.addr = OMAP4430_CM_TESLA_CLKSTCTRL},
+ {.addr = OMAP4430_CM_TESLA_TESLA_CLKCTRL},
+ {.addr = OMAP4430_PM_TESLA_PWRSTCTRL},
+};
+
+static struct reg_tuple ivahd_reg[] = {
+ {.addr = OMAP4430_CM_IVAHD_CLKSTCTRL},
+ {.addr = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL},
+ {.addr = OMAP4430_CM_IVAHD_SL2_CLKCTRL},
+ {.addr = OMAP4430_PM_IVAHD_PWRSTCTRL}
+};
+
+static struct reg_tuple l3instr_reg[] = {
+ {.addr = OMAP4430_CM_L3INSTR_L3_3_CLKCTRL},
+ {.addr = OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL},
+ {.addr = OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL},
+};
+
/*
* Store the SCU power status value to scratchpad memory
*/
static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state)
{
struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
- u32 scu_pwr_st, l1_state;
+ u32 scu_pwr_st;
switch (cpu_state) {
case PWRDM_POWER_RET:
scu_pwr_st = SCU_PM_DORMANT;
- l1_state = 0x00;
break;
case PWRDM_POWER_OFF:
scu_pwr_st = SCU_PM_POWEROFF;
- l1_state = 0xff;
break;
case PWRDM_POWER_ON:
case PWRDM_POWER_INACTIVE:
default:
scu_pwr_st = SCU_PM_NORMAL;
- l1_state = 0x00;
break;
}
__raw_writel(scu_pwr_st, pm_info->scu_sar_addr);
- __raw_writel(scu_pwr_st, pm_info->l1_sar_addr);
}
/*
@@ -272,6 +295,20 @@ static void save_gic_wakeupgen_secure(void)
/*
+ * API to save Secure RAM, GIC, WakeupGen Registers using secure API
+ * for HS/EMU device
+ */
+static void save_secure_all(void)
+{
+ u32 ret;
+ ret = omap4_secure_dispatcher(HAL_SAVEALL_INDEX,
+ FLAG_START_CRITICAL,
+ 1, omap4_secure_ram_phys, 0, 0, 0);
+ if (ret)
+ pr_debug("Secure all context save failed\n");
+}
+
+/*
* API to save Secure RAM using secure API
* for HS/EMU device
*/
@@ -323,6 +360,44 @@ static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)
}
}
+static inline void save_ivahd_tesla_regs(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tesla_reg); i++)
+ tesla_reg[i].val = __raw_readl(tesla_reg[i].addr);
+
+ for (i = 0; i < ARRAY_SIZE(ivahd_reg); i++)
+ ivahd_reg[i].val = __raw_readl(ivahd_reg[i].addr);
+}
+
+static inline void restore_ivahd_tesla_regs(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tesla_reg); i++)
+ __raw_writel(tesla_reg[i].val, tesla_reg[i].addr);
+
+ for (i = 0; i < ARRAY_SIZE(ivahd_reg); i++)
+ __raw_writel(ivahd_reg[i].val, ivahd_reg[i].addr);
+}
+
+static inline void save_l3instr_regs(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(l3instr_reg); i++)
+ l3instr_reg[i].val = __raw_readl(l3instr_reg[i].addr);
+}
+
+static inline void restore_l3instr_regs(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(l3instr_reg); i++)
+ __raw_writel(l3instr_reg[i].val, l3instr_reg[i].addr);
+}
+
/*
* OMAP4 MPUSS Low Power Entry Function
*
@@ -389,6 +464,19 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
*/
pwrdm_clear_all_prev_pwrst(mpuss_pd);
mpuss_clear_prev_logic_pwrst();
+ if (omap4_device_next_state_off()) {
+ if (omap_type() == OMAP2_DEVICE_TYPE_GP) {
+ omap_wakeupgen_save();
+ gic_save_context();
+ } else {
+ save_secure_all();
+ save_ivahd_tesla_regs();
+ save_l3instr_regs();
+ }
+ save_state = 3;
+ goto cpu_prepare;
+ }
+
switch (pwrdm_read_next_pwrst(mpuss_pd)) {
case PWRDM_POWER_RET:
/*
@@ -401,6 +489,8 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
gic_save_context();
} else {
save_gic_wakeupgen_secure();
+ save_ivahd_tesla_regs();
+ save_l3instr_regs();
}
save_state = 2;
}
@@ -412,6 +502,8 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
gic_save_context();
} else {
save_gic_wakeupgen_secure();
+ save_ivahd_tesla_regs();
+ save_l3instr_regs();
save_secure_ram();
}
save_state = 3;
@@ -478,6 +570,13 @@ cpu_prepare:
gic_dist_enable();
}
+ if ((omap4_device_prev_state_off()) &&
+ (omap_type() != OMAP2_DEVICE_TYPE_GP)) {
+ omap4_secure_dispatcher(0x21, 4, 0, 0, 0, 0, 0);
+ restore_ivahd_tesla_regs();
+ restore_l3instr_regs();
+ }
+
pwrdm_post_transition();
ret:
@@ -532,7 +631,6 @@ int __init omap4_mpuss_init(void)
/* Initilaise per CPU PM information */
pm_info = &per_cpu(omap4_pm_info, 0x0);
pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
- pm_info->l1_sar_addr = sar_base + L1_OFFSET0;
pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
if (!pm_info->pwrdm) {
pr_err("Lookup failed for CPU0 pwrdm\n");
@@ -548,7 +646,6 @@ int __init omap4_mpuss_init(void)
pm_info = &per_cpu(omap4_pm_info, 0x1);
pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
- pm_info->l1_sar_addr = sar_base + L1_OFFSET1;
pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
if (!pm_info->pwrdm) {
pr_err("Lookup failed for CPU1 pwrdm\n");
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
index 424a855..851db59 100644
--- a/arch/arm/mach-omap2/omap4-sar-layout.h
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -11,6 +11,59 @@
#ifndef OMAP_ARCH_OMAP4_SAR_LAYOUT_H
#define OMAP_ARCH_OMAP4_SAR_LAYOUT_H
+#include <mach/hardware.h>
+#include <mach/omap4-common.h>
+#include <mach/emif-44xx.h>
+#include <mach/dmm-44xx.h>
+#include <mach/ctrl_module_pad_core_44xx.h>
+
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "prcm-common.h"
+
+/*
+ * The SAR RAM is maintained during Device OFF mode.
+ * It is split into 4 banks with different privilege accesses
+ *
+ * ---------------------------------------------------------------------
+ * Access mode Bank Address Range
+ * ---------------------------------------------------------------------
+ * HS/GP : Public 1 0x4A32_6000 - 0x4A32_6FFF (4kB)
+ * HS/GP : Public, Secured
+ * if padconfaccdisable=1 2 0x4A32_7000 - 0x4A32_73FF (1kB)
+ * HS/EMU : Secured
+ * GP : Public 3 0x4A32_8000 - 0x4A32_87FF (2kB)
+ * HS/GP :
+ * Secure Priviledge,
+ * write once. 4 0x4A32_9000 - 0x4A32_93FF (1kB)
+ * ---------------------------------------------------------------------
+ * The SAR RAM save regiter layout is fixed since restore is done by hardware.
+ */
+
+#define MODULE_ADDR_IDX 0
+#define MODULE_OFFSET_IDX 1
+#define MODULE_NB_REGS_IDX 2
+#define SAR_RAM_OFFSET_IDX 3
+
+/*
+ * Module Index used to lookup VA using index
+ */
+#define MAX_SAR_MODULES 14
+#define EMIF1_INDEX 0
+#define EMIF2_INDEX 1
+#define DMM_INDEX 2
+#define CM1_INDEX 3
+#define CM2_INDEX 4
+#define C2C_INDEX 5
+#define CTRL_MODULE_PAD_CORE_INDEX 6
+#define L3_CLK1_INDEX 7
+#define L3_CLK2_INDEX 8
+#define L3_CLK3_INDEX 9
+#define USBTLL_INDEX 10
+#define UHH_INDEX 11
+#define L4CORE_INDEX 12
+#define L4PER_INDEX 13
+
/*
* SAR BANK offsets from base address OMAP44XX_SAR_RAM_BASE
*/
@@ -26,13 +79,12 @@
#define MMU_OFFSET1 0xd10
#define SCU_OFFSET0 0xd20
#define SCU_OFFSET1 0xd24
-#define L2X0_OFFSET 0xd28
-#define L2X0_AUXCTRL_OFFSET 0xd2c
-#define L1_OFFSET0 0xd30
-#define L1_OFFSET1 0xd34
-#define OMAP_TYPE_OFFSET 0xd38
-#define L2X0_LOCKDOWN_OFFSET0 0xd3c
-#define L2X0_PREFETCHCTRL_OFFSET 0xd40
+#define L2X0_AUXCTRL_OFFSET 0xd28
+#define OMAP_TYPE_OFFSET 0xd2c
+#define L2X0_LOCKDOWN_OFFSET0 0xd30
+#define L2X0_PREFETCHCTRL_OFFSET 0xd34
+#define L2X0_SAVE_OFFSET0 0xd38
+#define L2X0_SAVE_OFFSET1 0xd3c
/* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */
#define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04
diff --git a/arch/arm/mach-omap2/omap4-sar.c b/arch/arm/mach-omap2/omap4-sar.c
new file mode 100644
index 0000000..85b5fe9
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4-sar.c
@@ -0,0 +1,1054 @@
+/*
+ * OMAP4 Save Restore source file
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Written by Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * 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/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <mach/omap4-common.h>
+#include <mach/ctrl_module_wkup_44xx.h>
+
+#include "clockdomain.h"
+#include "omap4-sar-layout.h"
+#include "cm-regbits-44xx.h"
+#include "prcm44xx.h"
+#include "cminst44xx.h"
+
+/*
+ * These SECURE control registers are used to work-around
+ * DDR corruption on the second chip select on OMAP443x.
+ */
+#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG 0x0114
+#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG 0x011c
+
+static void __iomem *sar_ram_base;
+static void __iomem *omap4_sar_modules[MAX_SAR_MODULES];
+static struct powerdomain *l3init_pwrdm;
+ static struct clockdomain *l3init_clkdm;
+static struct clk *usb_host_ck, *usb_tll_ck;
+
+/*
+ * SAR_RAM1 register layout consist of EMIF1, EMIF2, CM1, CM2,
+ * CONTROL_CORE efuse, DMM and USB TLL registers.
+ * The layout is arranged is a two dimentional array like
+ * below,
+ * const u32 sar_ramX_layout[nb_regs_sets][4] = {
+ * {module_index, reg_offset, size, sar_ram_offset},
+ * }
+ */
+static const u32 omap443x_sar_ram1_layout[][4] = {
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_CONFIG, 1, 0x00000000},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_CONFIG_2, 1, 0x00000004},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_REF_CTRL, 1, 0x00000008},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_REF_CTRL_SHDW, 1, 0x0000000C},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_TIM_1, 1, 0x00000010},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_TIM_1_SHDW, 1, 0x00000014},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_TIM_2, 1, 0x00000018},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_TIM_2_SHDW, 1, 0x0000001C},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_TIM_3, 1, 0x00000020},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_TIM_3_SHDW, 1, 0x00000024},
+ {EMIF1_INDEX, OMAP44XX_EMIF_LPDDR2_NVM_TIM, 1, 0x00000028},
+ {EMIF1_INDEX, OMAP44XX_EMIF_LPDDR2_NVM_TIM_SHDW, 1, 0x0000002C},
+ {EMIF1_INDEX, OMAP44XX_EMIF_PWR_MGMT_CTRL, 1, 0x00000030},
+ {EMIF1_INDEX, OMAP44XX_EMIF_PWR_MGMT_CTRL_SHDW, 1, 0x00000034},
+ {EMIF1_INDEX, OMAP44XX_EMIF_OCP_CONFIG, 1, 0x00000038},
+ {EMIF1_INDEX, OMAP44XX_EMIF_PERF_CNT_CFG, 1, 0x0000003C},
+ {EMIF1_INDEX, OMAP44XX_EMIF_PERF_CNT_SEL, 1, 0x00000040},
+ {EMIF1_INDEX, OMAP44XX_EMIF_READ_IDLE_CTRL, 1, 0x00000044},
+ {EMIF1_INDEX, OMAP44XX_EMIF_READ_IDLE_CTRL_SHDW, 1, 0x00000048},
+ {EMIF1_INDEX, OMAP44XX_EMIF_IRQENABLE_SET_SYS, 1, 0x0000004C},
+ {EMIF1_INDEX, OMAP44XX_EMIF_IRQENABLE_SET_LL, 1, 0x00000050},
+ {EMIF1_INDEX, OMAP44XX_EMIF_ZQ_CONFIG, 1, 0x00000054},
+ {EMIF1_INDEX, OMAP44XX_EMIF_TEMP_ALERT_CONFIG, 1, 0x00000058},
+ {EMIF1_INDEX, OMAP44XX_EMIF_DDR_PHY_CTRL_1, 1, 0x0000005C},
+ {EMIF1_INDEX, OMAP44XX_EMIF_DDR_PHY_CTRL_1_SHDW, 1, 0x00000060},
+ {EMIF1_INDEX, OMAP44XX_EMIF_DDR_PHY_CTRL_2, 1, 0x00000064},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_CONFIG, 1, 0x00000068},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_CONFIG_2, 1, 0x0000006C},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_REF_CTRL, 1, 0x00000070},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_REF_CTRL_SHDW, 1, 0x00000074},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_TIM_1, 1, 0x00000078},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_TIM_1_SHDW, 1, 0x0000007C},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_TIM_2, 1, 0x00000080},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_TIM_2_SHDW, 1, 0x00000084},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_TIM_3, 1, 0x00000088},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_TIM_3_SHDW, 1, 0x0000008C},
+ {EMIF2_INDEX, OMAP44XX_EMIF_LPDDR2_NVM_TIM, 1, 0x00000090},
+ {EMIF2_INDEX, OMAP44XX_EMIF_LPDDR2_NVM_TIM_SHDW, 1, 0x00000094},
+ {EMIF2_INDEX, OMAP44XX_EMIF_PWR_MGMT_CTRL, 1, 0x00000098},
+ {EMIF2_INDEX, OMAP44XX_EMIF_PWR_MGMT_CTRL_SHDW, 1, 0x0000009C},
+ {EMIF2_INDEX, OMAP44XX_EMIF_OCP_CONFIG, 1, 0x000000A0},
+ {EMIF2_INDEX, OMAP44XX_EMIF_PERF_CNT_CFG, 1, 0x000000A4},
+ {EMIF2_INDEX, OMAP44XX_EMIF_PERF_CNT_SEL, 1, 0x000000A8},
+ {EMIF2_INDEX, OMAP44XX_EMIF_READ_IDLE_CTRL, 1, 0x000000AC},
+ {EMIF2_INDEX, OMAP44XX_EMIF_READ_IDLE_CTRL_SHDW, 1, 0x000000B0},
+ {EMIF2_INDEX, OMAP44XX_EMIF_IRQENABLE_SET_SYS, 1, 0x000000B4},
+ {EMIF2_INDEX, OMAP44XX_EMIF_IRQENABLE_SET_LL, 1, 0x000000B8},
+ {EMIF2_INDEX, OMAP44XX_EMIF_ZQ_CONFIG, 1, 0x000000BC},
+ {EMIF2_INDEX, OMAP44XX_EMIF_TEMP_ALERT_CONFIG, 1, 0x000000C0},
+ {EMIF2_INDEX, OMAP44XX_EMIF_DDR_PHY_CTRL_1, 1, 0x000000C4},
+ {EMIF2_INDEX, OMAP44XX_EMIF_DDR_PHY_CTRL_1_SHDW, 1, 0x000000C8},
+ {EMIF2_INDEX, OMAP44XX_EMIF_DDR_PHY_CTRL_2, 1, 0x000000CC},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_MEMIF_CLKSTCTRL_RESTORE_OFFSET, 1, 0x000000D0},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_CLKSEL_CORE_RESTORE_OFFSET, 1, 0x000000D4},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_DIV_M2_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000D8},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_DIV_M3_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000DC},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_DIV_M4_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000E0},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_DIV_M5_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000E4},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_DIV_M6_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000E8},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_DIV_M7_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000EC},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_CLKSEL_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000F0},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000F4},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000F8},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_CLKMODE_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000FC},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_SHADOW_FREQ_CONFIG2_RESTORE_OFFSET, 1, 0x00000100},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_SHADOW_FREQ_CONFIG1_RESTORE_OFFSET, 1, 0x00000104},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_AUTOIDLE_DPLL_CORE_RESTORE_OFFSET, 1, 0x00000108},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_MPU_CLKSTCTRL_RESTORE_OFFSET, 1, 0x0000010C},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_CM1_PROFILING_CLKCTRL_RESTORE_OFFSET, 1, 0x00000110},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_DYN_DEP_PRESCAL_RESTORE_OFFSET, 1, 0x00000114},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3_1_CLKSTCTRL_RESTORE_OFFSET, 1, 0x00000118},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3_2_CLKSTCTRL_RESTORE_OFFSET, 1, 0x0000011C},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L4CFG_CLKSTCTRL_RESTORE_OFFSET, 1, 0x00000120},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_MEMIF_CLKSTCTRL_RESTORE_OFFSET, 1, 0x00000124},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L4PER_CLKSTCTRL_RESTORE_OFFSET, 1, 0x00000128},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INIT_CLKSTCTRL_RESTORE_OFFSET, 1, 0x0000012C},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INSTR_L3_3_CLKCTRL_RESTORE_OFFSET, 1, 0x00000130},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE_OFFSET, 1, 0x00000134},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE_OFFSET, 1, 0x00000138},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_CM2_PROFILING_CLKCTRL_RESTORE_OFFSET, 1, 0x0000013C},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_D2D_STATICDEP_RESTORE_OFFSET, 1, 0x00000140},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3_1_DYNAMICDEP_RESTORE_OFFSET, 1, 0x00000144},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3_2_DYNAMICDEP_RESTORE_OFFSET, 1, 0x00000148},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_D2D_DYNAMICDEP_RESTORE_OFFSET, 1, 0x0000014C},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L4CFG_DYNAMICDEP_RESTORE_OFFSET, 1, 0x00000150},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L4PER_DYNAMICDEP_RESTORE_OFFSET, 1, 0x00000154},
+ {C2C_INDEX, 0x0C, 1, 0x00000158},
+ {C2C_INDEX, 0x10, 1, 0x0000015C},
+ {C2C_INDEX, 0x28, 1, 0x00000160},
+ {C2C_INDEX, 0x40, 1, 0x00000164},
+ {C2C_INDEX, 0x44, 1, 0x00000168},
+ {C2C_INDEX, 0x70, 1, 0x0000016C},
+ {C2C_INDEX, 0x74, 1, 0x00000170},
+ {C2C_INDEX, 0x84, 1, 0x00000174},
+ {C2C_INDEX, 0x88, 1, 0x00000178},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PADCONF_GLOBAL, 15, 0x0000017C},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PBIASLITE, 14, 0x000001B8},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_0, 8, 0x000001F0},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_BUS_HOLD, 1, 0x00000210},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_C2C, 1, 0x00000214},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_1, 1, 0x00000218},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_2, 1, 0x0000021C},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_4, 1, 0x00000220},
+ {DMM_INDEX, OMAP44XX_DMM_LISA_MAP, 4, 0x000000224},
+ {DMM_INDEX, OMAP44XX_DMM_LISA_LOCK, 1, 0x00000234},
+ {DMM_INDEX, OMAP44XX_DMM_TILER_OR, 2, 0x00000238},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_VIEW, 2, 0x00000240},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_VIEW_MAP, 4, 0x00000248},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_VIEW_MAP_BASE, 1, 0x00000258},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_IRQENABLE_SET, 1, 0x0000025C},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DESCR, 1, 0x00000260},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_AREA, 1, 0x00000264},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_CTRL, 1, 0x00000268},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DATA, 1, 0x0000026C},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DESCR + 0x10, 1, 0x00000270},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_AREA + 0x10, 1, 0x00000274},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_CTRL + 0x10, 1, 0x00000278},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DATA + 0x10, 1, 0x0000027C},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DESCR + 0x20, 1, 0x00000280},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_AREA + 0x20, 1, 0x00000284},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_CTRL + 0x20, 1, 0x00000288},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DATA + 0x20, 1, 0x0000028C},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DESCR + 0x30, 1, 0x00000290},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_AREA + 0x30, 1, 0x00000294},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_CTRL + 0x30, 1, 0x00000298},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DATA + 0x30, 1, 0x0000029C},
+ {DMM_INDEX, OMAP44XX_DMM_PEG_PRIO, 2, 0x000002A0},
+ {DMM_INDEX, OMAP44XX_DMM_PEG_PRIO_PAT, 1, 0x000002A8},
+ {L3_CLK1_INDEX, 0x508, 1, 0x000002AC},
+ {L3_CLK1_INDEX, 0x510, 1, 0x000002B0},
+ {L3_CLK1_INDEX, 0x708, 1, 0x000002B4},
+ {L3_CLK1_INDEX, 0x70C, 1, 0x000002B8},
+ {L3_CLK1_INDEX, 0x808, 1, 0x000002BC},
+ {L3_CLK2_INDEX, 0x1008, 1, 0x000002C0},
+ {L3_CLK2_INDEX, 0x1010, 1, 0x000002C4},
+ {L3_CLK2_INDEX, 0x1208, 1, 0x000002C8},
+ {L3_CLK2_INDEX, 0x1308, 1, 0x000002CC},
+ {L3_CLK2_INDEX, 0x130C, 1, 0x000002D0},
+ {L3_CLK2_INDEX, 0x1408, 1, 0x000002D4},
+ {L3_CLK2_INDEX, 0x140C, 1, 0x000002D8},
+ {L3_CLK2_INDEX, 0x1508, 1, 0x000002DC},
+ {L3_CLK2_INDEX, 0x150C, 1, 0x000002E0},
+ {L3_CLK3_INDEX, 0x208, 1, 0x000002E4},
+ {L3_CLK3_INDEX, 0x210, 1, 0x000002E8},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_RESTORE_OFFSET, 1, 0x000002EC},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_RESTORE_OFFSET, 1, 0x000002F0},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_SDMA_STATICDEP_RESTORE_OFFSET, 1, 0x000002F4},
+ {USBTLL_INDEX, 0x400, 7, 0x000002F8},
+ {UHH_INDEX, 0x10, 1, 0x00000314},
+ {UHH_INDEX, 0x40, 1, 0x00000318},
+ {UHH_INDEX, 0x100, 384, 0x0000031C},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_RESTORE_OFFSET, 1, 0x0000091C},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_RESTORE_OFFSET, 1, 0x00000920},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_SDMA_STATICDEP_RESTORE_OFFSET, 1, 0x00000924},
+};
+
+/*
+ * SAR_RAM2 register layout consist of SYSCTRL_PADCONF_CORE regsiters
+ */
+static const u32 omap443x_sar_ram2_layout[][4] = {
+ {CTRL_MODULE_PAD_CORE_INDEX, 0x40, 102, 0x00000000},
+};
+
+/*
+ * SAR_RAM3 and SAR_RAM4 layout is not listed since moslty it's handle by
+ * secure software.
+ */
+static const u32 omap443x_sar_ram3_layout[][4] = {
+ {L4CORE_INDEX, 0x2140, 1, 0x00000000},
+ {L4CORE_INDEX, 0x2104, 1, 0x00000004},
+ {L4CORE_INDEX, 0x2100, 1, 0x00000008},
+ {L4CORE_INDEX, 0x2108, 1, 0x0000000C},
+ {L4CORE_INDEX, 0x210C, 1, 0x00000010},
+ {L4CORE_INDEX, 0x2110, 1, 0x00000014},
+ {L4CORE_INDEX, 0x2114, 1, 0x00000018},
+ {L4CORE_INDEX, 0x204088, 14, 0x0000001C},
+ {L4CORE_INDEX, 0x206088, 2, 0x00000054},
+ {L4CORE_INDEX, 0x20C088, 30, 0x0000005C},
+ {L4CORE_INDEX, 0x210088, 30, 0x000000D4},
+ {L4CORE_INDEX, 0x212088, 38, 0x0000014C},
+ {L4CORE_INDEX, 0x214088, 2, 0x000001E4},
+ {L4CORE_INDEX, 0x216088, 2, 0x000001EC},
+ {L4CORE_INDEX, 0x218088, 2, 0x000001F4},
+ {L4CORE_INDEX, 0x21C088, 2, 0x000001FC},
+ {L4CORE_INDEX, 0x21E088, 2, 0x00000204},
+ {L4CORE_INDEX, 0x220088, 2, 0x0000020C},
+ {L4CORE_INDEX, 0x226088, 6, 0x00000214},
+ {L4CORE_INDEX, 0x228088, 2, 0x0000022C},
+ {L4CORE_INDEX, 0x22A088, 14, 0x00000234},
+ {L4PER_INDEX, 0x218, 1, 0x0000026C},
+ {L4PER_INDEX, 0x220, 1, 0x00000270},
+ {L4PER_INDEX, 0x228, 1, 0x00000274},
+ {L4PER_INDEX, 0x230, 1, 0x00000278},
+ {L4PER_INDEX, 0x238, 1, 0x0000027C},
+ {L4PER_INDEX, 0x298, 2, 0x00000280},
+ {L4PER_INDEX, 0x2A0, 2, 0x00000288},
+ {L4PER_INDEX, 0x2A8, 2, 0x00000290},
+ {L4PER_INDEX, 0x2B0, 2, 0x00000298},
+ {L4PER_INDEX, 0x2B8, 2, 0x000002A0},
+ {L4PER_INDEX, 0x304, 1, 0x000002A8},
+ {L4PER_INDEX, 0x31C, 1, 0x000002AC},
+ {L4PER_INDEX, 0x32C, 1, 0x000002B0},
+ {L4PER_INDEX, 0x33C, 1, 0x000002B4},
+ {L4PER_INDEX, 0x34C, 1, 0x000002B8},
+ {L4PER_INDEX, 0x35C, 1, 0x000002BC},
+ {L4PER_INDEX, 0x36C, 1, 0x000002C0},
+ {L4PER_INDEX, 0x37C, 1, 0x000002C4},
+ {L4PER_INDEX, 0x38C, 1, 0x000002C8},
+ {L4PER_INDEX, 0x39C, 1, 0x000002CC},
+ {L4PER_INDEX, 0x3AC, 1, 0x000002D0},
+ {L4PER_INDEX, 0x3BC, 1, 0x000002D4},
+ {L4PER_INDEX, 0x3CC, 1, 0x000002D8},
+ {L4PER_INDEX, 0x3D4, 1, 0x000002DC},
+ {L4PER_INDEX, 0x3E4, 1, 0x000002E0},
+ {L4PER_INDEX, 0x3F4, 1, 0x000002E4},
+ {L4PER_INDEX, 0x404, 1, 0x000002E8},
+ {L4PER_INDEX, 0x414, 1, 0x000002EC},
+ {L4PER_INDEX, 0x42C, 1, 0x000002F0},
+ {L4PER_INDEX, 0x43C, 1, 0x000002F4},
+ {L4PER_INDEX, 0x44C, 1, 0x000002F8},
+ {L4PER_INDEX, 0x45C, 1, 0x000002FC},
+ {L4PER_INDEX, 0x46C, 1, 0x00000300},
+ {L4PER_INDEX, 0x47C, 1, 0x00000304},
+ {L4PER_INDEX, 0x48C, 1, 0x00000308},
+ {L4PER_INDEX, 0x49C, 1, 0x0000030C},
+ {L4PER_INDEX, 0x4AC, 1, 0x00000310},
+ {L4PER_INDEX, 0x4BC, 1, 0x00000314},
+ {L4PER_INDEX, 0x4CC, 1, 0x00000318},
+ {L4PER_INDEX, 0x4DC, 1, 0x0000031C},
+ {L4PER_INDEX, 0x4EC, 1, 0x00000320},
+ {L4PER_INDEX, 0x4FC, 1, 0x00000324},
+ {L4PER_INDEX, 0x50C, 1, 0x00000328},
+ {L4PER_INDEX, 0x51C, 1, 0x0000032C},
+ {L4PER_INDEX, 0x52C, 1, 0x00000330},
+ {L4PER_INDEX, 0x53C, 1, 0x00000334},
+ {L4PER_INDEX, 0x54C, 1, 0x00000338},
+ {L4PER_INDEX, 0x55C, 1, 0x0000033C},
+ {L4PER_INDEX, 0x56C, 1, 0x00000340},
+ {L4PER_INDEX, 0x57C, 1, 0x00000344},
+ {L4PER_INDEX, 0x5A4, 1, 0x00000348},
+ {L4CORE_INDEX, 0x230, 1, 0x0000034C},
+ {L4CORE_INDEX, 0x238, 1, 0x00000350},
+ {L4CORE_INDEX, 0x2B0, 2, 0x00000354},
+ {L4CORE_INDEX, 0x2B8, 2, 0x0000035C},
+ {L4CORE_INDEX, 0x304, 1, 0x00000364},
+ {L4CORE_INDEX, 0x31C, 1, 0x00000368},
+ {L4CORE_INDEX, 0x32C, 1, 0x0000036C},
+ {L4CORE_INDEX, 0x33C, 1, 0x00000370},
+ {L4CORE_INDEX, 0x354, 1, 0x00000374},
+ {L4CORE_INDEX, 0x35C, 1, 0x00000378},
+ {L4CORE_INDEX, 0x36C, 1, 0x0000037C},
+ {L4CORE_INDEX, 0x37C, 1, 0x00000380},
+ {L4CORE_INDEX, 0x38C, 1, 0x00000384},
+ {L4CORE_INDEX, 0x3AC, 1, 0x00000388},
+ {L4CORE_INDEX, 0x3BC, 1, 0x0000038C},
+ {L4CORE_INDEX, 0x3CC, 1, 0x00000390},
+ {L4CORE_INDEX, 0x3DC, 1, 0x00000394},
+ {L4CORE_INDEX, 0x3EC, 1, 0x00000398},
+ {L4CORE_INDEX, 0x3FC, 1, 0x0000039C},
+ {L4CORE_INDEX, 0x40C, 1, 0x000003A0},
+ {L4CORE_INDEX, 0x41C, 1, 0x000003A4},
+ {L4CORE_INDEX, 0x42C, 1, 0x000003A8},
+ {L4CORE_INDEX, 0x43C, 1, 0x000003AC},
+ {L4CORE_INDEX, 0x44C, 1, 0x000003B0},
+ {L4CORE_INDEX, 0x45C, 1, 0x000003B4},
+ {L4CORE_INDEX, 0x46C, 1, 0x000003B8},
+ {L4CORE_INDEX, 0x47C, 1, 0x000003BC},
+ {L4CORE_INDEX, 0x48C, 1, 0x000003C0},
+ {L4CORE_INDEX, 0x49C, 1, 0x000003C4},
+ {L4CORE_INDEX, 0x4AC, 1, 0x000003C8},
+ {L4CORE_INDEX, 0x4BC, 1, 0x000003CC},
+ {L4CORE_INDEX, 0x4CC, 1, 0x000003D0},
+ {L4CORE_INDEX, 0x4DC, 1, 0x000003D4},
+ {L4CORE_INDEX, 0x4EC, 1, 0x000003D8},
+ {L4CORE_INDEX, 0x4FC, 1, 0x000003DC},
+ {L4CORE_INDEX, 0x50C, 1, 0x000003E0},
+ {L4CORE_INDEX, 0x51C, 1, 0x000003E4},
+ {L4CORE_INDEX, 0x52C, 1, 0x000003E8},
+ {L4CORE_INDEX, 0x53C, 1, 0x000003EC},
+ {L4CORE_INDEX, 0x54C, 1, 0x000003F0},
+ {L4CORE_INDEX, 0x55C, 1, 0x000003F4},
+ {L4CORE_INDEX, 0x56C, 1, 0x000003F8},
+ {L4CORE_INDEX, 0x574, 1, 0x000003FC},
+ {L4CORE_INDEX, 0x584, 1, 0x00000400},
+ {L4CORE_INDEX, 0x594, 1, 0x00000404},
+ {L4CORE_INDEX, 0x5A4, 1, 0x00000408},
+ {L4CORE_INDEX, 0x5B4, 1, 0x0000040C},
+ {L4CORE_INDEX, 0x5C4, 1, 0x00000410},
+ {L4CORE_INDEX, 0x5D4, 1, 0x00000414},
+ {L4CORE_INDEX, 0x5DC, 1, 0x00000418},
+};
+
+
+static const u32 omap446x_sar_ram1_layout[][4] = {
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_CONFIG_2, 1, 0x00000000},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_CONFIG, 1, 0x00000004},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_REF_CTRL, 1, 0x00000008},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_REF_CTRL_SHDW, 1, 0x0000000C},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_TIM_1, 1, 0x00000010},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_TIM_1_SHDW, 1, 0x00000014},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_TIM_2, 1, 0x00000018},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_TIM_2_SHDW, 1, 0x0000001C},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_TIM_3, 1, 0x00000020},
+ {EMIF1_INDEX, OMAP44XX_EMIF_SDRAM_TIM_3_SHDW, 1, 0x00000024},
+ {EMIF1_INDEX, OMAP44XX_EMIF_LPDDR2_NVM_TIM, 1, 0x00000028},
+ {EMIF1_INDEX, OMAP44XX_EMIF_LPDDR2_NVM_TIM_SHDW, 1, 0x0000002C},
+ {EMIF1_INDEX, OMAP44XX_EMIF_PWR_MGMT_CTRL, 1, 0x00000030},
+ {EMIF1_INDEX, OMAP44XX_EMIF_PWR_MGMT_CTRL_SHDW, 1, 0x00000034},
+ {EMIF1_INDEX, OMAP44XX_EMIF_OCP_CONFIG, 1, 0x00000038},
+ {EMIF1_INDEX, OMAP44XX_EMIF_PERF_CNT_CFG, 1, 0x0000003C},
+ {EMIF1_INDEX, OMAP44XX_EMIF_PERF_CNT_SEL, 1, 0x00000040},
+ {EMIF1_INDEX, OMAP44XX_EMIF_READ_IDLE_CTRL, 1, 0x00000044},
+ {EMIF1_INDEX, OMAP44XX_EMIF_READ_IDLE_CTRL_SHDW, 1, 0x00000048},
+ {EMIF1_INDEX, OMAP44XX_EMIF_IRQENABLE_SET_SYS, 1, 0x0000004C},
+ {EMIF1_INDEX, OMAP44XX_EMIF_IRQENABLE_SET_LL, 1, 0x00000050},
+ {EMIF1_INDEX, OMAP44XX_EMIF_ZQ_CONFIG, 1, 0x00000054},
+ {EMIF1_INDEX, OMAP44XX_EMIF_TEMP_ALERT_CONFIG, 1, 0x00000058},
+ {EMIF1_INDEX, OMAP44XX_EMIF_DDR_PHY_CTRL_1, 1, 0x0000005C},
+ {EMIF1_INDEX, OMAP44XX_EMIF_DDR_PHY_CTRL_1_SHDW, 1, 0x00000060},
+ {EMIF1_INDEX, OMAP44XX_EMIF_DDR_PHY_CTRL_2, 1, 0x00000064},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_CONFIG_2, 1, 0x00000068},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_CONFIG, 1, 0x0000006C},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_REF_CTRL, 1, 0x00000070},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_REF_CTRL_SHDW, 1, 0x00000074},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_TIM_1, 1, 0x00000078},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_TIM_1_SHDW, 1, 0x0000007C},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_TIM_2, 1, 0x00000080},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_TIM_2_SHDW, 1, 0x00000084},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_TIM_3, 1, 0x00000088},
+ {EMIF2_INDEX, OMAP44XX_EMIF_SDRAM_TIM_3_SHDW, 1, 0x0000008C},
+ {EMIF2_INDEX, OMAP44XX_EMIF_LPDDR2_NVM_TIM, 1, 0x00000090},
+ {EMIF2_INDEX, OMAP44XX_EMIF_LPDDR2_NVM_TIM_SHDW, 1, 0x00000094},
+ {EMIF2_INDEX, OMAP44XX_EMIF_PWR_MGMT_CTRL, 1, 0x00000098},
+ {EMIF2_INDEX, OMAP44XX_EMIF_PWR_MGMT_CTRL_SHDW, 1, 0x0000009C},
+ {EMIF2_INDEX, OMAP44XX_EMIF_OCP_CONFIG, 1, 0x000000A0},
+ {EMIF2_INDEX, OMAP44XX_EMIF_PERF_CNT_CFG, 1, 0x000000A4},
+ {EMIF2_INDEX, OMAP44XX_EMIF_PERF_CNT_SEL, 1, 0x000000A8},
+ {EMIF2_INDEX, OMAP44XX_EMIF_READ_IDLE_CTRL, 1, 0x000000AC},
+ {EMIF2_INDEX, OMAP44XX_EMIF_READ_IDLE_CTRL_SHDW, 1, 0x000000B0},
+ {EMIF2_INDEX, OMAP44XX_EMIF_IRQENABLE_SET_SYS, 1, 0x000000B4},
+ {EMIF2_INDEX, OMAP44XX_EMIF_IRQENABLE_SET_LL, 1, 0x000000B8},
+ {EMIF2_INDEX, OMAP44XX_EMIF_ZQ_CONFIG, 1, 0x000000BC},
+ {EMIF2_INDEX, OMAP44XX_EMIF_TEMP_ALERT_CONFIG, 1, 0x000000C0},
+ {EMIF2_INDEX, OMAP44XX_EMIF_DDR_PHY_CTRL_1, 1, 0x000000C4},
+ {EMIF2_INDEX, OMAP44XX_EMIF_DDR_PHY_CTRL_1_SHDW, 1, 0x000000C8},
+ {EMIF2_INDEX, OMAP44XX_EMIF_DDR_PHY_CTRL_2, 1, 0x000000CC},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_MEMIF_CLKSTCTRL_RESTORE_OFFSET, 1, 0x000000D0},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_CLKSEL_CORE_RESTORE_OFFSET, 1, 0x000000D4},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_DIV_M2_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000D8},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_DIV_M3_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000DC},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_DIV_M4_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000E0},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_DIV_M5_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000E4},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_DIV_M6_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000E8},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_DIV_M7_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000EC},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_CLKSEL_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000F0},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000F4},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000F8},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_CLKMODE_DPLL_CORE_RESTORE_OFFSET, 1, 0x000000FC},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_SHADOW_FREQ_CONFIG2_RESTORE_OFFSET, 1, 0x00000100},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_SHADOW_FREQ_CONFIG1_RESTORE_OFFSET, 1, 0x00000104},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_AUTOIDLE_DPLL_CORE_RESTORE_OFFSET, 1, 0x00000108},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_MPU_CLKSTCTRL_RESTORE_OFFSET, 1, 0x0000010C},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_CM1_PROFILING_CLKCTRL_RESTORE_OFFSET, 1, 0x00000110},
+ {CM1_INDEX, OMAP4430_CM1_RESTORE_INST +
+ OMAP4_CM_DYN_DEP_PRESCAL_RESTORE_OFFSET, 1, 0x00000114},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3_1_CLKSTCTRL_RESTORE_OFFSET, 1, 0x00000118},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3_2_CLKSTCTRL_RESTORE_OFFSET, 1, 0x0000011C},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L4CFG_CLKSTCTRL_RESTORE_OFFSET, 1, 0x00000120},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_MEMIF_CLKSTCTRL_RESTORE_OFFSET, 1, 0x00000124},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L4PER_CLKSTCTRL_RESTORE_OFFSET, 1, 0x00000128},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INIT_CLKSTCTRL_RESTORE_OFFSET, 1, 0x0000012C},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INSTR_L3_3_CLKCTRL_RESTORE_OFFSET, 1, 0x00000130},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE_OFFSET, 1, 0x00000134},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE_OFFSET, 1, 0x00000138},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_CM2_PROFILING_CLKCTRL_RESTORE_OFFSET, 1, 0x0000013C},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_D2D_STATICDEP_RESTORE_OFFSET, 1, 0x00000140},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3_1_DYNAMICDEP_RESTORE_OFFSET, 1, 0x00000144},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3_2_DYNAMICDEP_RESTORE_OFFSET, 1, 0x00000148},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_D2D_DYNAMICDEP_RESTORE_OFFSET, 1, 0x0000014C},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L4CFG_DYNAMICDEP_RESTORE_OFFSET, 1, 0x00000150},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L4PER_DYNAMICDEP_RESTORE_OFFSET, 1, 0x00000154},
+ {C2C_INDEX, 0x0C, 1, 0x00000158},
+ {C2C_INDEX, 0x10, 1, 0x0000015C},
+ {C2C_INDEX, 0x28, 1, 0x00000160},
+ {C2C_INDEX, 0x40, 1, 0x00000164},
+ {C2C_INDEX, 0x44, 1, 0x00000168},
+ {C2C_INDEX, 0x70, 1, 0x0000016C},
+ {C2C_INDEX, 0x74, 1, 0x00000170},
+ {C2C_INDEX, 0x84, 1, 0x00000174},
+ {C2C_INDEX, 0x88, 1, 0x00000178},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PADCONF_GLOBAL, 15, 0x0000017C},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PBIASLITE, 14, 0x000001B8},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_0, 8, 0x000001F0},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_BUS_HOLD, 1, 0x00000210},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_C2C, 1, 0x00000214},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_1, 1, 0x00000218},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_2, 1, 0x0000021C},
+ {CTRL_MODULE_PAD_CORE_INDEX,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_4, 1, 0x00000220},
+ {L4CORE_INDEX, 0x2350, 1, 0x00000224},
+ {DMM_INDEX, OMAP44XX_DMM_LISA_MAP, 4, 0x000000228},
+ {DMM_INDEX, OMAP44XX_DMM_LISA_LOCK, 1, 0x00000238},
+ {DMM_INDEX, OMAP44XX_DMM_TILER_OR, 2, 0x0000023C},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_VIEW, 2, 0x00000244},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_VIEW_MAP, 4, 0x0000024C},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_VIEW_MAP_BASE, 1, 0x0000025C},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_IRQENABLE_SET, 1, 0x00000260},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DESCR, 1, 0x00000264},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_AREA, 1, 0x00000268},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_CTRL, 1, 0x0000026C},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DATA, 1, 0x00000270},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DESCR + 0x10, 1, 0x00000274},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_AREA + 0x10, 1, 0x00000278},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_CTRL + 0x10, 1, 0x0000027C},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DATA + 0x10, 1, 0x00000280},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DESCR + 0x20, 1, 0x00000284},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_AREA + 0x20, 1, 0x00000288},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_CTRL + 0x20, 1, 0x0000028C},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DATA + 0x20, 1, 0x00000290},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DESCR + 0x30, 1, 0x00000294},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_AREA + 0x30, 1, 0x00000298},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_CTRL + 0x30, 1, 0x0000029C},
+ {DMM_INDEX, OMAP44XX_DMM_PAT_DATA + 0x30, 1, 0x000002A0},
+ {DMM_INDEX, OMAP44XX_DMM_PEG_PRIO, 2, 0x000002A4},
+ {DMM_INDEX, OMAP44XX_DMM_PEG_PRIO_PAT, 1, 0x000002AC},
+ {L3_CLK1_INDEX, 0x508, 1, 0x000002B0},
+ {L3_CLK1_INDEX, 0x510, 1, 0x000002B4},
+ {L3_CLK1_INDEX, 0x708, 1, 0x000002B8},
+ {L3_CLK1_INDEX, 0x70C, 1, 0x000002BC},
+ {L3_CLK1_INDEX, 0x808, 1, 0x000002C0},
+ {L3_CLK2_INDEX, 0x1008, 1, 0x000002C4},
+ {L3_CLK2_INDEX, 0x1010, 1, 0x000002C8},
+ {L3_CLK2_INDEX, 0x1208, 1, 0x000002CC},
+ {L3_CLK2_INDEX, 0x1308, 1, 0x000002D0},
+ {L3_CLK2_INDEX, 0x130C, 1, 0x000002D4},
+ {L3_CLK2_INDEX, 0x1408, 1, 0x000002D8},
+ {L3_CLK2_INDEX, 0x140C, 1, 0x000002DC},
+ {L3_CLK2_INDEX, 0x1508, 1, 0x000002E0},
+ {L3_CLK2_INDEX, 0x150C, 1, 0x000002E4},
+ {L3_CLK3_INDEX, 0x208, 1, 0x000002E8},
+ {L3_CLK3_INDEX, 0x210, 1, 0x000002EC},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_RESTORE_OFFSET, 1, 0x000002F0},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_RESTORE_OFFSET, 1, 0x000002F4},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_SDMA_STATICDEP_RESTORE_OFFSET, 1, 0x000002F8},
+ {USBTLL_INDEX, 0x400, 7, 0x000002FC},
+ {UHH_INDEX, 0x10, 1, 0x00000318},
+ {UHH_INDEX, 0x40, 1, 0x0000031C},
+ {UHH_INDEX, 0x100, 384, 0x00000320},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_RESTORE_OFFSET, 1, 0x00000920},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_RESTORE_OFFSET, 1, 0x00000924},
+ {CM2_INDEX, OMAP4430_CM2_RESTORE_INST +
+ OMAP4_CM_SDMA_STATICDEP_RESTORE_OFFSET, 1, 0x00000928},
+};
+
+/*
+ * SAR_RAM2 register layout consist of SYSCTRL_PADCONF_CORE regsiters
+ */
+static const u32 omap446x_sar_ram2_layout[][4] = {
+ {CTRL_MODULE_PAD_CORE_INDEX, 0x40, 102, 0x00000000},
+ {CTRL_MODULE_PAD_CORE_INDEX, 0x1f4, 1, 0x00000198},
+};
+
+/*
+ * SAR_RAM3 and SAR_RAM4 layout is not listed since moslty it's handle by
+ * secure software.
+ */
+static const u32 omap446x_sar_ram3_layout[][4] = {
+ {L4CORE_INDEX, 0x2140, 1, 0x00000000},
+ {L4CORE_INDEX, 0x2104, 1, 0x00000004},
+ {L4CORE_INDEX, 0x2100, 1, 0x00000008},
+ {L4CORE_INDEX, 0x2108, 1, 0x0000000C},
+ {L4CORE_INDEX, 0x210C, 1, 0x00000010},
+ {L4CORE_INDEX, 0x2110, 1, 0x00000014},
+ {L4CORE_INDEX, 0x2114, 1, 0x00000018},
+ {L4CORE_INDEX, 0x204088, 14, 0x0000001C},
+ {L4CORE_INDEX, 0x206088, 2, 0x00000054},
+ {L4CORE_INDEX, 0x20C088, 30, 0x0000005C},
+ {L4CORE_INDEX, 0x210088, 30, 0x000000D4},
+ {L4CORE_INDEX, 0x212088, 38, 0x0000014C},
+ {L4CORE_INDEX, 0x214088, 2, 0x000001E4},
+ {L4CORE_INDEX, 0x216088, 2, 0x000001EC},
+ {L4CORE_INDEX, 0x218088, 2, 0x000001F4},
+ {L4CORE_INDEX, 0x21C088, 2, 0x000001FC},
+ {L4CORE_INDEX, 0x21E088, 2, 0x00000204},
+ {L4CORE_INDEX, 0x220088, 2, 0x0000020C},
+ {L4CORE_INDEX, 0x226088, 6, 0x00000214},
+ {L4CORE_INDEX, 0x228088, 2, 0x0000022C},
+ {L4CORE_INDEX, 0x22A088, 14, 0x00000234},
+ {L4CORE_INDEX, 0x20A088, 30, 0x0000026C},
+ {L4PER_INDEX, 0x218, 1, 0x000002E4},
+ {L4PER_INDEX, 0x220, 1, 0x000002E8},
+ {L4PER_INDEX, 0x228, 1, 0x000002EC},
+ {L4PER_INDEX, 0x230, 1, 0x000002F0},
+ {L4PER_INDEX, 0x238, 1, 0x000002F4},
+ {L4PER_INDEX, 0x298, 2, 0x000002F8},
+ {L4PER_INDEX, 0x2A0, 2, 0x00000300},
+ {L4PER_INDEX, 0x2A8, 2, 0x00000308},
+ {L4PER_INDEX, 0x2B0, 2, 0x00000310},
+ {L4PER_INDEX, 0x2B8, 2, 0x00000318},
+ {L4PER_INDEX, 0x304, 1, 0x00000320},
+ {L4PER_INDEX, 0x31C, 1, 0x00000324},
+ {L4PER_INDEX, 0x32C, 1, 0x00000328},
+ {L4PER_INDEX, 0x33C, 1, 0x0000032C},
+ {L4PER_INDEX, 0x34C, 1, 0x00000330},
+ {L4PER_INDEX, 0x35C, 1, 0x00000334},
+ {L4PER_INDEX, 0x36C, 1, 0x00000338},
+ {L4PER_INDEX, 0x37C, 1, 0x0000033C},
+ {L4PER_INDEX, 0x38C, 1, 0x00000340},
+ {L4PER_INDEX, 0x39C, 1, 0x00000344},
+ {L4PER_INDEX, 0x3AC, 1, 0x00000348},
+ {L4PER_INDEX, 0x3BC, 1, 0x0000034C},
+ {L4PER_INDEX, 0x3CC, 1, 0x00000350},
+ {L4PER_INDEX, 0x3D4, 1, 0x00000354},
+ {L4PER_INDEX, 0x3E4, 1, 0x00000358},
+ {L4PER_INDEX, 0x3F4, 1, 0x0000035C},
+ {L4PER_INDEX, 0x404, 1, 0x00000360},
+ {L4PER_INDEX, 0x414, 1, 0x00000364},
+ {L4PER_INDEX, 0x42C, 1, 0x00000368},
+ {L4PER_INDEX, 0x43C, 1, 0x0000036C},
+ {L4PER_INDEX, 0x44C, 1, 0x00000370},
+ {L4PER_INDEX, 0x45C, 1, 0x00000374},
+ {L4PER_INDEX, 0x46C, 1, 0x00000378},
+ {L4PER_INDEX, 0x47C, 1, 0x0000037C},
+ {L4PER_INDEX, 0x48C, 1, 0x00000380},
+ {L4PER_INDEX, 0x49C, 1, 0x00000384},
+ {L4PER_INDEX, 0x4AC, 1, 0x00000388},
+ {L4PER_INDEX, 0x4BC, 1, 0x0000038C},
+ {L4PER_INDEX, 0x4CC, 1, 0x00000390},
+ {L4PER_INDEX, 0x4DC, 1, 0x00000394},
+ {L4PER_INDEX, 0x4EC, 1, 0x00000398},
+ {L4PER_INDEX, 0x4FC, 1, 0x0000039C},
+ {L4PER_INDEX, 0x50C, 1, 0x000003A0},
+ {L4PER_INDEX, 0x51C, 1, 0x000003A4},
+ {L4PER_INDEX, 0x52C, 1, 0x000003A8},
+ {L4PER_INDEX, 0x53C, 1, 0x000003AC},
+ {L4PER_INDEX, 0x54C, 1, 0x000003B0},
+ {L4PER_INDEX, 0x55C, 1, 0x000003B4},
+ {L4PER_INDEX, 0x56C, 1, 0x000003B8},
+ {L4PER_INDEX, 0x57C, 1, 0x000003BC},
+ {L4PER_INDEX, 0x5A4, 1, 0x000003C0},
+ {L4CORE_INDEX, 0x230, 1, 0x000003C4},
+ {L4CORE_INDEX, 0x238, 1, 0x000003C8},
+ {L4CORE_INDEX, 0x2B0, 2, 0x000003CC},
+ {L4CORE_INDEX, 0x2B8, 2, 0x000003D4},
+ {L4CORE_INDEX, 0x304, 1, 0x000003DC},
+ {L4CORE_INDEX, 0x31C, 1, 0x000003E0},
+ {L4CORE_INDEX, 0x32C, 1, 0x000003E4},
+ {L4CORE_INDEX, 0x33C, 1, 0x000003E8},
+ {L4CORE_INDEX, 0x354, 1, 0x000003EC},
+ {L4CORE_INDEX, 0x35C, 1, 0x000003F0},
+ {L4CORE_INDEX, 0x36C, 1, 0x000003F4},
+ {L4CORE_INDEX, 0x37C, 1, 0x000003F8},
+ {L4CORE_INDEX, 0x38C, 1, 0x000003FC},
+ {L4CORE_INDEX, 0x3AC, 1, 0x00000400},
+ {L4CORE_INDEX, 0x3BC, 1, 0x00000404},
+ {L4CORE_INDEX, 0x3CC, 1, 0x00000408},
+ {L4CORE_INDEX, 0x3DC, 1, 0x0000040C},
+ {L4CORE_INDEX, 0x3EC, 1, 0x00000410},
+ {L4CORE_INDEX, 0x3FC, 1, 0x00000414},
+ {L4CORE_INDEX, 0x40C, 1, 0x00000418},
+ {L4CORE_INDEX, 0x41C, 1, 0x0000041C},
+ {L4CORE_INDEX, 0x42C, 1, 0x00000420},
+ {L4CORE_INDEX, 0x43C, 1, 0x00000424},
+ {L4CORE_INDEX, 0x44C, 1, 0x00000428},
+ {L4CORE_INDEX, 0x45C, 1, 0x0000042C},
+ {L4CORE_INDEX, 0x46C, 1, 0x00000430},
+ {L4CORE_INDEX, 0x47C, 1, 0x00000434},
+ {L4CORE_INDEX, 0x48C, 1, 0x00000438},
+ {L4CORE_INDEX, 0x49C, 1, 0x0000043C},
+ {L4CORE_INDEX, 0x4AC, 1, 0x00000440},
+ {L4CORE_INDEX, 0x4BC, 1, 0x00000444},
+ {L4CORE_INDEX, 0x4CC, 1, 0x00000448},
+ {L4CORE_INDEX, 0x4DC, 1, 0x0000044C},
+ {L4CORE_INDEX, 0x4EC, 1, 0x00000450},
+ {L4CORE_INDEX, 0x4FC, 1, 0x00000454},
+ {L4CORE_INDEX, 0x50C, 1, 0x00000458},
+ {L4CORE_INDEX, 0x51C, 1, 0x0000045C},
+ {L4CORE_INDEX, 0x52C, 1, 0x00000460},
+ {L4CORE_INDEX, 0x53C, 1, 0x00000464},
+ {L4CORE_INDEX, 0x54C, 1, 0x00000468},
+ {L4CORE_INDEX, 0x55C, 1, 0x0000046C},
+ {L4CORE_INDEX, 0x56C, 1, 0x00000470},
+ {L4CORE_INDEX, 0x574, 1, 0x00000474},
+ {L4CORE_INDEX, 0x584, 1, 0x00000478},
+ {L4CORE_INDEX, 0x594, 1, 0x0000047C},
+ {L4CORE_INDEX, 0x5A4, 1, 0x00000480},
+ {L4CORE_INDEX, 0x5B4, 1, 0x00000484},
+ {L4CORE_INDEX, 0x5C4, 1, 0x00000488},
+ {L4CORE_INDEX, 0x5D4, 1, 0x0000048C},
+ {L4CORE_INDEX, 0x5DC, 1, 0x00000490},
+ {L4CORE_INDEX, 0x5E4, 1, 0x00000494},
+ {L4CORE_INDEX, 0x5EC, 1, 0x00000498},
+ {L4CORE_INDEX, 0x5F4, 1, 0x0000049C},
+ {L4CORE_INDEX, 0x5FC, 1, 0x000004A0},
+};
+
+/*
+ * omap_sar_save :
+ * common routine to save the registers to SAR RAM with the
+ * given parameters
+ * @nb_regs - Number of registers to saved
+ * @sar_bank_offset - where to backup
+ * @sar_layout - constant table containing the backup info
+ */
+static void sar_save(u32 nb_regs, u32 sar_bank, const u32 sar_layout_table[][4])
+{
+ u32 reg_val, size, i, j;
+ void __iomem *reg_read_addr, *sar_wr_addr;
+
+ for (i = 0; i < nb_regs; i++) {
+ if (omap4_sar_modules[(sar_layout_table[i][MODULE_ADDR_IDX])]) {
+ size = sar_layout_table[i][MODULE_NB_REGS_IDX];
+ reg_read_addr =
+ omap4_sar_modules[sar_layout_table[i]
+ [MODULE_ADDR_IDX]]
+ + sar_layout_table[i][MODULE_OFFSET_IDX];
+ sar_wr_addr = sar_ram_base + sar_bank +
+ sar_layout_table[i][SAR_RAM_OFFSET_IDX];
+ for (j = 0; j < size; j++) {
+ reg_val = __raw_readl(reg_read_addr + j * 4);
+ __raw_writel(reg_val, sar_wr_addr + j * 4);
+ }
+ }
+ }
+}
+
+static void save_sar_bank3(void)
+{
+ struct clockdomain *l4_secure_clkdm;
+
+ /*
+ * Not supported on ES1.0 silicon
+ */
+ if (omap_rev() == OMAP4430_REV_ES1_0) {
+ WARN_ONCE(1, "omap4: SAR backup not supported on ES1.0 ..\n");
+ return;
+ }
+
+ l4_secure_clkdm = clkdm_lookup("l4_secure_clkdm");
+ clkdm_wakeup(l4_secure_clkdm);
+
+ if (cpu_is_omap446x())
+ sar_save(ARRAY_SIZE(omap446x_sar_ram3_layout), SAR_BANK3_OFFSET,
+ omap446x_sar_ram3_layout);
+ else
+ sar_save(ARRAY_SIZE(omap443x_sar_ram3_layout), SAR_BANK3_OFFSET,
+ omap443x_sar_ram3_layout);
+
+ clkdm_allow_idle(l4_secure_clkdm);
+}
+
+static int omap4_sar_not_accessible(void)
+{
+ u32 usbhost_state, usbtll_state;
+
+ /*
+ * Make sure that USB host and TLL modules are not
+ * enabled before attempting to save the context
+ * registers, otherwise this will trigger an exception.
+ */
+ usbhost_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
+ OMAP4430_CM2_L3INIT_INST,
+ OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET)
+ & (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK);
+
+ usbtll_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
+ OMAP4430_CM2_L3INIT_INST,
+ OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET)
+ & OMAP4430_IDLEST_MASK;
+
+ if ((usbhost_state == (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK)) &&
+ (usbtll_state == (OMAP4430_IDLEST_MASK)))
+ return 0;
+ else
+ return -EBUSY;
+}
+
+ /*
+ * omap4_sar_save -
+ * Save the context to SAR_RAM1 and SAR_RAM2 as per
+ * omap4xxx_sar_ram1_layout and omap4xxx_sar_ram2_layout for the device OFF
+ * mode
+ */
+int omap4_sar_save(void)
+{
+ /*
+ * Not supported on ES1.0 silicon
+ */
+ if (omap_rev() == OMAP4430_REV_ES1_0) {
+ WARN_ONCE(1, "omap4: SAR backup not supported on ES1.0 ..\n");
+ return -ENODEV;
+ }
+
+ if (omap4_sar_not_accessible()) {
+ pr_debug("%s: USB SAR CNTX registers are not accessible!\n",
+ __func__);
+ return -EBUSY;
+ }
+
+ /*
+ * SAR bits and clocks needs to be enabled
+ */
+ clkdm_wakeup(l3init_clkdm);
+ pwrdm_enable_hdwr_sar(l3init_pwrdm);
+ clk_enable(usb_host_ck);
+ clk_enable(usb_tll_ck);
+
+ /* Save SAR BANK1 */
+ if (cpu_is_omap446x())
+ sar_save(ARRAY_SIZE(omap446x_sar_ram1_layout), SAR_BANK1_OFFSET,
+ omap446x_sar_ram1_layout);
+ else
+ sar_save(ARRAY_SIZE(omap443x_sar_ram1_layout), SAR_BANK1_OFFSET,
+ omap443x_sar_ram1_layout);
+
+ clk_disable(usb_host_ck);
+ clk_disable(usb_tll_ck);
+ pwrdm_disable_hdwr_sar(l3init_pwrdm);
+ clkdm_allow_idle(l3init_clkdm);
+
+ /* Save SAR BANK2 */
+ if (cpu_is_omap446x())
+ sar_save(ARRAY_SIZE(omap446x_sar_ram2_layout), SAR_BANK2_OFFSET,
+ omap446x_sar_ram2_layout);
+ else
+ sar_save(ARRAY_SIZE(omap443x_sar_ram2_layout), SAR_BANK2_OFFSET,
+ omap443x_sar_ram2_layout);
+
+ return 0;
+}
+
+/**
+ * omap4_sar_overwrite :
+ * This API overwrite some of the SAR locations as a special cases
+ * The register content to be saved can be the register value before
+ * going into OFF-mode or a value that is required on wake up. This means
+ * that the restored register value can be different from the last value
+ * of the register before going into OFF-mode
+ * - CM1 and CM2 configuration
+ * Bits 0 of the CM_SHADOW_FREQ_CONFIG1 regiser and the
+ * CM_SHADOW_FREQ_CONFIG2 register are self-clearing and must
+ * be set at restore time. Thus, these data must always be
+ * overwritten in the SAR RAM.
+ * - Because USBHOSTHS and USBTLL restore needs a particular
+ * sequencing, the software must overwrite data read from
+ * the following registers implied in phase2a and phase 2b
+ */
+void omap4_sar_overwrite(void)
+{
+ u32 val = 0;
+ u32 offset = 0;
+
+ if (cpu_is_omap446x())
+ offset = 0x04;
+
+ /* Overwriting Phase1 data to be restored */
+ /* CM2 MEMIF_CLKTRCTRL = SW_WKUP, before FREQ UPDATE */
+ __raw_writel(0x2, sar_ram_base + SAR_BANK1_OFFSET + 0xd0);
+ /* CM1 CM_SHADOW_FREQ_CONFIG2, Enable FREQ UPDATE */
+ val = __raw_readl(OMAP4430_CM_SHADOW_FREQ_CONFIG2);
+ /*
+ * FIXME: Implement FREQ UPDATE for L#/M5 before enabling this
+ * val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
+ */
+ __raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x100);
+ /* CM1 CM_SHADOW_FREQ_CONFIG1, Enable FREQ UPDATE */
+ val = __raw_readl(OMAP4430_CM_SHADOW_FREQ_CONFIG1);
+ val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
+ val &= ~OMAP4430_DLL_OVERRIDE_MASK;
+ __raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x104);
+ /* CM2 MEMIF_CLKTRCTRL = HW_AUTO, after FREQ UPDATE */
+ __raw_writel(0x3, sar_ram_base + SAR_BANK1_OFFSET + 0x124);
+
+ /* Overwriting Phase2a data to be restored */
+ /* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */
+ __raw_writel(0x00000012,
+ sar_ram_base + SAR_BANK1_OFFSET + 0x2ec + offset);
+ /* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */
+ __raw_writel(0x00000011,
+ sar_ram_base + SAR_BANK1_OFFSET + 0x2f0 + offset);
+ /* CM2 CM_SDMA_STATICDEP : Enable static depedency for SAR modules */
+ __raw_writel(0x000090e8,
+ sar_ram_base + SAR_BANK1_OFFSET + 0x2f4 + offset);
+
+ /* Overwriting Phase2b data to be restored */
+ /* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
+ val = __raw_readl(OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL);
+ val &= (OMAP4430_CLKSEL_UTMI_P1_MASK | OMAP4430_CLKSEL_UTMI_P2_MASK);
+ __raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x91c + offset);
+ /* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
+ __raw_writel(0x0000000,
+ sar_ram_base + SAR_BANK1_OFFSET + 0x920 + offset);
+ /* CM2 CM_SDMA_STATICDEP : Clear the static depedency */
+ __raw_writel(0x00000040,
+ sar_ram_base + SAR_BANK1_OFFSET + 0x924 + offset);
+
+ /* readback to ensure data reaches to SAR RAM */
+ barrier();
+ val = __raw_readl(sar_ram_base + SAR_BANK1_OFFSET + 0x924 + offset);
+}
+
+void __iomem *omap4_get_sar_ram_base(void)
+{
+ return sar_ram_base;
+}
+
+/*
+ * SAR RAM used to save and restore the HW
+ * context in low power modes
+ */
+static int __init omap4_sar_ram_init(void)
+{
+ /*
+ * To avoid code running on other OMAPs in
+ * multi-omap builds
+ */
+ if (!cpu_is_omap44xx())
+ return -ENODEV;
+
+ /*
+ * Static mapping, never released Actual SAR area used is 8K it's
+ * spaced over 16K address with some part is reserved.
+ */
+ sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
+ BUG_ON(!sar_ram_base);
+
+ /*
+ * All these are static mappings so ioremap() will
+ * just return with mapped VA
+ */
+ omap4_sar_modules[EMIF1_INDEX] = ioremap(OMAP44XX_EMIF1, SZ_1M);
+ BUG_ON(!omap4_sar_modules[EMIF1_INDEX]);
+ omap4_sar_modules[EMIF2_INDEX] = ioremap(OMAP44XX_EMIF2, SZ_1M);
+ BUG_ON(!omap4_sar_modules[EMIF2_INDEX]);
+ omap4_sar_modules[DMM_INDEX] = ioremap(OMAP44XX_DMM_BASE, SZ_1M);
+ BUG_ON(!omap4_sar_modules[DMM_INDEX]);
+ omap4_sar_modules[CM1_INDEX] = ioremap(OMAP4430_CM1_BASE, SZ_8K);
+ BUG_ON(!omap4_sar_modules[CM1_INDEX]);
+ omap4_sar_modules[CM2_INDEX] = ioremap(OMAP4430_CM2_BASE, SZ_8K);
+ BUG_ON(!omap4_sar_modules[CM2_INDEX]);
+ omap4_sar_modules[C2C_INDEX] = ioremap(OMAP44XX_C2C_BASE, SZ_1M);
+ BUG_ON(!omap4_sar_modules[C2C_INDEX]);
+ omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX] =
+ ioremap(OMAP443X_CTRL_BASE, SZ_4K);
+ BUG_ON(!omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX]);
+ omap4_sar_modules[L3_CLK1_INDEX] = ioremap(L3_44XX_BASE_CLK1, SZ_1M);
+ BUG_ON(!omap4_sar_modules[L3_CLK1_INDEX]);
+ omap4_sar_modules[L3_CLK2_INDEX] = ioremap(L3_44XX_BASE_CLK2, SZ_1M);
+ BUG_ON(!omap4_sar_modules[L3_CLK2_INDEX]);
+ omap4_sar_modules[L3_CLK3_INDEX] = ioremap(L3_44XX_BASE_CLK3, SZ_1M);
+ BUG_ON(!omap4_sar_modules[L3_CLK3_INDEX]);
+ omap4_sar_modules[USBTLL_INDEX] = ioremap(OMAP44XX_USBTLL_BASE, SZ_1M);
+ BUG_ON(!omap4_sar_modules[USBTLL_INDEX]);
+ omap4_sar_modules[UHH_INDEX] = ioremap(OMAP44XX_UHH_CONFIG_BASE, SZ_1M);
+ BUG_ON(!omap4_sar_modules[UHH_INDEX]);
+ omap4_sar_modules[L4CORE_INDEX] = ioremap(L4_44XX_PHYS, SZ_4M);
+ BUG_ON(!omap4_sar_modules[L4CORE_INDEX]);
+ omap4_sar_modules[L4PER_INDEX] = ioremap(L4_PER_44XX_PHYS, SZ_4M);
+ BUG_ON(!omap4_sar_modules[L4PER_INDEX]);
+
+ /*
+ * SAR BANK3 contains all firewall settings and it's saved through
+ * secure API on HS device. On GP device these registers are
+ * meaningless but still needs to be saved. Otherwise Auto-restore
+ * phase DMA takes an abort. Hence save these conents only once
+ * in init to avoid the issue while waking up from device OFF
+ */
+ if (omap_type() == OMAP2_DEVICE_TYPE_GP)
+ save_sar_bank3();
+ /*
+ * Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF
+ * Mode Transition When CS1 Is Used On EMIF":
+ * Overwrite EMIF1/EMIF2
+ * SECURE_EMIF1_SDRAM_CONFIG2_REG
+ * SECURE_EMIF2_SDRAM_CONFIG2_REG
+ */
+ if (cpu_is_omap443x()) {
+ void __iomem *secure_ctrl_mod;
+
+ secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K);
+ BUG_ON(!secure_ctrl_mod);
+
+ __raw_writel(0x10, secure_ctrl_mod +
+ OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);
+ __raw_writel(0x10, secure_ctrl_mod +
+ OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);
+ wmb();
+ iounmap(secure_ctrl_mod);
+ }
+
+ /*
+ * L3INIT PD and clocks are needed for SAR save phase
+ */
+ l3init_pwrdm = pwrdm_lookup("l3init_pwrdm");
+ if (!l3init_pwrdm)
+ pr_err("Failed to get l3init_pwrdm\n");
+
+ l3init_clkdm = clkdm_lookup("l3_init_clkdm");
+ if (!l3init_clkdm)
+ pr_err("Failed to get l3_init_clkdm\n");
+
+ usb_host_ck = clk_get(NULL, "usb_host_hs_fck");
+ if (!usb_host_ck)
+ pr_err("Could not get usb_host_ck\n");
+
+ usb_tll_ck = clk_get(NULL, "usb_tll_hs_ick");
+ if (!usb_tll_ck)
+ pr_err("Could not get usb_tll_ck\n");
+
+ return 0;
+}
+early_initcall(omap4_sar_ram_init);
diff --git a/arch/arm/mach-omap2/omap_tps6236x.c b/arch/arm/mach-omap2/omap_tps6236x.c
index b93566d..36af1c3 100644
--- a/arch/arm/mach-omap2/omap_tps6236x.c
+++ b/arch/arm/mach-omap2/omap_tps6236x.c
@@ -72,6 +72,8 @@
#define TWL6030_REG_VMEM_CFG_GRP 0x64
#define TWL6030_REG_MSK_TRANSITION 0x20
#define TWL6030_BIT_APE_GRP BIT(0)
+#define TWL6030_BIT_CON_GRP BIT(1)
+#define TWL6030_BIT_MOD_GRP BIT(2)
#define TWL6030_MSK_PREQ1 BIT(5)
#define TWL6030_MSK_SYSEN_OFF (0x3 << 4)
#define TWL6030_MSK_SYSEN_SLEEP (0x3 << 2)
@@ -183,6 +185,7 @@ static struct omap_voltdm_pmic omap4_mpu_pmic = {
.ret_volt = 830000,
.off_volt = 0,
.volt_setup_time = 0,
+ .switch_on_time = 1000,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
@@ -300,7 +303,7 @@ static int __init omap4_twl_tps62361_enable(struct voltagedomain *voltdm)
pr_err("%s:Err:TWL6030: sysen sleep(%d)\n", __func__, ret1);
ret = ret1;
}
- ret1 = _twl_i2c_rmw_u8(TWL6030_MODULE_ID0, TWL6030_MSK_SYSEN_SLEEP,
+ ret1 = _twl_i2c_rmw_u8(TWL6030_MODULE_ID0, TWL6030_MSK_SYSEN_OFF,
0x00, TWL6030_REG_SYSEN_CFG_TRANS);
if (ret1) {
pr_err("%s:Err:TWL6030: sysen off(%d)\n", __func__, ret1);
@@ -308,7 +311,8 @@ static int __init omap4_twl_tps62361_enable(struct voltagedomain *voltdm)
}
/* Map up SYSEN on TWL core to control TPS */
- ret1 = _twl_i2c_rmw_u8(TWL6030_MODULE_ID0, TWL6030_BIT_APE_GRP,
+ ret1 = _twl_i2c_rmw_u8(TWL6030_MODULE_ID0, TWL6030_BIT_APE_GRP |
+ TWL6030_BIT_MOD_GRP | TWL6030_BIT_CON_GRP,
TWL6030_BIT_APE_GRP, TWL6030_REG_SYSEN_CFG_GRP);
if (ret1) {
pr_err("%s:Err:TWL6030: map APE SYEN(%d)\n", __func__, ret1);
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 0459423..baf8960 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -183,6 +183,7 @@ static struct omap_voltdm_pmic omap443x_mpu_pmic = {
.ret_volt = 830000,
.off_volt = 0,
.volt_setup_time = 0,
+ .switch_on_time = 549,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
@@ -209,6 +210,7 @@ static struct omap_voltdm_pmic omap4_iva_pmic = {
.ret_volt = 830000,
.off_volt = 0,
.volt_setup_time = 0,
+ .switch_on_time = 549,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
@@ -235,6 +237,7 @@ static struct omap_voltdm_pmic omap443x_core_pmic = {
.ret_volt = 830000,
.off_volt = 0,
.volt_setup_time = 0,
+ .switch_on_time = 549,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
@@ -262,6 +265,7 @@ static struct omap_voltdm_pmic omap446x_core_pmic = {
.ret_volt = 830000,
.off_volt = 0,
.volt_setup_time = 0,
+ .switch_on_time = 549,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 27ddf12..a1ba505 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -51,6 +51,7 @@ u32 enable_off_mode;
u32 sleep_while_idle;
u32 wakeup_timer_seconds;
u32 wakeup_timer_milliseconds;
+u32 omap4_device_off_counter = 0;
#ifdef CONFIG_PM_ADVANCED_DEBUG
static u32 saved_reg_num;
@@ -465,6 +466,8 @@ static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user)
static int pm_dbg_show_counters(struct seq_file *s, void *unused)
{
pwrdm_for_each(pwrdm_dbg_show_counter, s);
+ if (cpu_is_omap44xx())
+ seq_printf(s, "DEVICE-OFF:%d\n", omap4_device_off_counter);
clkdm_for_each(clkdm_dbg_show_counter, s);
return 0;
@@ -628,6 +631,10 @@ static int option_get(void *data, u64 *val)
{
u32 *option = data;
+ if (option == &enable_off_mode) {
+ enable_off_mode = off_mode_enabled;
+ }
+
*val = *option;
#ifdef CONFIG_PM_ADVANCED_DEBUG
if (option == &saved_reg_addr) {
@@ -648,7 +655,10 @@ static int option_set(void *data, u64 val)
if (option == &wakeup_timer_milliseconds && val >= 1000)
return -EINVAL;
- *option = val;
+ if (cpu_is_omap443x() && omap_type() == OMAP2_DEVICE_TYPE_GP)
+ *option = 0;
+ else
+ *option = val;
if (option == &enable_off_mode) {
if (val)
@@ -711,12 +721,14 @@ static int __init pm_dbg_init(void)
}
- (void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d,
- &enable_off_mode, &pm_dbg_option_fops);
(void) debugfs_create_file("sleep_while_idle", S_IRUGO | S_IWUSR, d,
&sleep_while_idle, &pm_dbg_option_fops);
skip_reg_debufs:
+#ifdef CONFIG_OMAP_ALLOW_OSWR
+ (void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d,
+ &enable_off_mode, &pm_dbg_option_fops);
+#endif
(void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUSR, d,
&wakeup_timer_seconds, &pm_dbg_option_fops);
(void) debugfs_create_file("wakeup_timer_milliseconds",
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 314999b..0571489 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -25,6 +25,26 @@ extern int omap4_idle_init(void);
extern void omap4_enter_sleep(unsigned int cpu, unsigned int power_state,
bool suspend);
extern void omap4_trigger_ioctrl(void);
+extern u32 omap4_device_off_counter;
+
+#ifdef CONFIG_PM
+extern void omap4_device_set_state_off(u8 enable);
+extern bool omap4_device_prev_state_off(void);
+extern bool omap4_device_next_state_off(void);
+extern void omap4_device_clear_prev_off_state(void);
+#else
+static inline void omap4_device_set_state_off(u8 enable)
+{
+}
+static inline bool omap4_device_prev_state_off(void)
+{
+ return false;
+}
+static inline bool omap4_device_next_state_off(void)
+{
+ return false;
+}
+#endif
#if defined(CONFIG_PM_OPP)
extern int omap3_opp_init(void);
@@ -72,13 +92,11 @@ extern struct omap_dm_timer *gptimer_wakeup;
extern void omap2_pm_dump(int mode, int resume, unsigned int us);
extern void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds);
extern int omap2_pm_debug;
-extern u32 enable_off_mode;
extern u32 sleep_while_idle;
#else
#define omap2_pm_dump(mode, resume, us) do {} while (0);
#define omap2_pm_wakeup_on_timer(seconds, milliseconds) do {} while (0);
#define omap2_pm_debug 0
-#define enable_off_mode 0
#define sleep_while_idle 0
#endif
#ifdef CONFIG_PM_ADVANCED_DEBUG
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 3f3f2d7..321a7e6 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -136,7 +136,7 @@ static void omap3_core_save_context(void)
/* Save the Interrupt controller context */
omap_intc_save_context();
/* Save the GPMC context */
- omap3_gpmc_save_context();
+ omap_gpmc_save_context();
/* Save the system control module context, padconf already save above*/
omap3_control_save_context();
omap_dma_global_context_save();
@@ -147,7 +147,7 @@ static void omap3_core_restore_context(void)
/* Restore the control module context, padconf restored by h/w */
omap3_control_restore_context();
/* Restore the GPMC context */
- omap3_gpmc_restore_context();
+ omap_gpmc_restore_context();
/* Restore the interrupt controller context */
omap_intc_restore_context();
omap_dma_global_context_restore();
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index fdc3095..7ef659d 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -28,6 +28,10 @@
#include <plat/common.h>
#include <plat/temperature_sensor.h>
#include <plat/usb.h>
+#include <plat/prcm.h>
+#include <plat/omap-pm.h>
+#include <plat/gpmc.h>
+#include <plat/dma.h>
#include "powerdomain.h"
#include "clockdomain.h"
@@ -39,6 +43,7 @@
#include "clock.h"
#include "cm2_44xx.h"
#include "cm1_44xx.h"
+#include "cm44xx.h"
#include "cm-regbits-44xx.h"
#include "cminst44xx.h"
#include "prcm-debug.h"
@@ -106,6 +111,7 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend)
pwrdm_clear_all_prev_pwrst(mpu_pwrdm);
pwrdm_clear_all_prev_pwrst(core_pwrdm);
pwrdm_clear_all_prev_pwrst(per_pwrdm);
+ omap4_device_clear_prev_off_state();
cpu0_next_state = pwrdm_read_next_pwrst(cpu0_pwrdm);
per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
@@ -146,15 +152,38 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend)
OMAP_VC_CHANNEL_AUTO_TRANSITION_RETENTION);
omap_temp_sensor_prepare_idle();
- omap2_gpio_prepare_for_idle(0);
}
}
+ if (omap4_device_next_state_off()) {
+ omap2_gpio_prepare_for_idle(true);
+ omap_gpmc_save_context();
+ omap_dma_global_context_save();
+ }
+
if (suspend && cpu_is_omap44xx())
omap4_pm_suspend_save_regs();
+ if (omap4_device_next_state_off()) {
+ /* Save the device context to SAR RAM */
+ if (omap4_sar_save())
+ goto abort_device_off;
+ omap4_sar_overwrite();
+ omap4_cm_prepare_off();
+ omap4_dpll_prepare_off();
+ }
+
omap4_enter_lowpower(cpu, power_state);
+ if (omap4_device_prev_state_off()) {
+ omap4_dpll_resume_off();
+ omap4_cm_resume_off();
+#ifdef CONFIG_PM_DEBUG
+ omap4_device_off_counter++;
+#endif
+ }
+
+abort_device_off:
if (core_next_state < PWRDM_POWER_ON) {
/* See note above */
omap_vc_set_auto_trans(core_voltdm,
@@ -163,13 +192,18 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend)
OMAP_VC_CHANNEL_AUTO_TRANSITION_DISABLE);
omap_temp_sensor_resume_idle();
- omap2_gpio_resume_after_idle();
if (!suspend) {
omap_sr_enable(iva_voltdm);
omap_sr_enable(core_voltdm);
}
}
+ if (omap4_device_prev_state_off()) {
+ omap_dma_global_context_restore();
+ omap_gpmc_restore_context();
+ omap2_gpio_resume_after_idle();
+ }
+
if (mpu_next_state < PWRDM_POWER_INACTIVE) {
omap_vc_set_auto_trans(mpu_voltdm,
OMAP_VC_CHANNEL_AUTO_TRANSITION_DISABLE);
@@ -356,6 +390,81 @@ static void omap4_print_wakeirq(void)
}
#endif
+/**
+ * get_achievable_state() - Provide achievable state
+ * @available_states: what states are available
+ * @req_min_state: what state is the minimum we'd like to hit
+ *
+ * Power domains have varied capabilities. When attempting a low power
+ * state such as OFF/RET, a specific min requested state may not be
+ * supported on the power domain, in which case, the next higher power
+ * state which is supported is returned. This is because a combination
+ * of system power states where the parent PD's state is not in line
+ * with expectation can result in system instabilities.
+ */
+static inline u8 get_achievable_state(u8 available_states, u8 req_min_state)
+{
+ u8 mask = 0xFF << req_min_state;
+
+ if (available_states & mask)
+ return __ffs(available_states & mask);
+ return PWRDM_POWER_ON;
+}
+
+/**
+ * omap4_configure_pwdm_suspend() - Program powerdomain on suspend
+ * @is_off_mode: is this an OFF mode transition?
+ *
+ * Program all powerdomain to required power domain state: This logic
+ * Takes the requested mode -OFF/RET translates it to logic and power
+ * states. This then walks down the power domain states to program
+ * each domain to the state requested. if the requested state is not
+ * available, it will check for the higher state.
+ */
+static void omap4_configure_pwdm_suspend(bool is_off_mode)
+{
+ struct power_state *pwrst;
+ u32 state;
+ u32 logic_state, als;
+
+#ifdef CONFIG_OMAP_ALLOW_OSWR
+ if (is_off_mode) {
+ state = PWRDM_POWER_OFF;
+ logic_state = PWRDM_POWER_OFF;
+ } else {
+ state = PWRDM_POWER_RET;
+ logic_state = PWRDM_POWER_OFF;
+ }
+#else
+ state = PWRDM_POWER_RET;
+ logic_state = PWRDM_POWER_RET;
+#endif
+
+ list_for_each_entry(pwrst, &pwrst_list, node) {
+ if ((!strcmp(pwrst->pwrdm->name, "cpu0_pwrdm")) ||
+ (!strcmp(pwrst->pwrdm->name, "cpu1_pwrdm")))
+ continue;
+ /*
+ * Write only to registers which are writable! Don't touch
+ * read-only/reserved registers. If pwrdm->pwrsts_logic_ret or
+ * pwrdm->pwrsts are 0, consider those power domains containing
+ * readonly/reserved registers which cannot be controlled by
+ * software.
+ */
+ if (pwrst->pwrdm->pwrsts_logic_ret) {
+ als =
+ get_achievable_state(pwrst->pwrdm->pwrsts_logic_ret,
+ logic_state);
+ pwrdm_set_logic_retst(pwrst->pwrdm, als);
+ }
+ if (pwrst->pwrdm->pwrsts) {
+ pwrst->next_state =
+ get_achievable_state(pwrst->pwrdm->pwrsts, state);
+ omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+ }
+ }
+}
+
static int omap4_pm_suspend(void)
{
struct power_state *pwrst;
@@ -372,20 +481,11 @@ static int omap4_pm_suspend(void)
pwrst->saved_logic_state = pwrdm_read_logic_retst(pwrst->pwrdm);
}
- /* Set targeted power domain states by suspend */
- list_for_each_entry(pwrst, &pwrst_list, node) {
- if ((!strcmp(pwrst->pwrdm->name, "cpu0_pwrdm")) ||
- (!strcmp(pwrst->pwrdm->name, "cpu1_pwrdm")))
- continue;
-#ifdef CONFIG_OMAP_ALLOW_OSWR
- /*OSWR is supported on silicon > ES2.0 */
- if (pwrst->pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET)
- pwrdm_set_logic_retst(pwrst->pwrdm,
- PWRDM_POWER_OFF);
-#endif
- pwrst->next_state = PWRDM_POWER_RET;
- omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
- }
+ omap4_configure_pwdm_suspend(off_mode_enabled);
+
+ /* Enable Device OFF */
+ if (off_mode_enabled)
+ omap4_device_set_state_off(1);
/*
* For MPUSS to hit power domain retention(CSWR or OSWR),
@@ -401,6 +501,10 @@ static int omap4_pm_suspend(void)
omap4_print_wakeirq();
prcmdebug_dump(PRCMDEBUG_LASTSLEEP);
+ /* Disable Device OFF state*/
+ if (off_mode_enabled)
+ omap4_device_set_state_off(0);
+
/* Restore next powerdomain state */
list_for_each_entry(pwrst, &pwrst_list, node) {
state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
@@ -582,6 +686,72 @@ static void omap_default_idle(void)
}
/**
+ * omap4_device_set_state_off() - setup device off state
+ * @enable: set to off or not.
+ *
+ * When Device OFF is enabled, Device is allowed to perform
+ * transition to off mode as soon as all power domains in MPU, IVA
+ * and CORE voltage are in OFF or OSWR state (open switch retention)
+ */
+void omap4_device_set_state_off(u8 enable)
+{
+#ifdef CONFIG_OMAP_ALLOW_OSWR
+ if (enable)
+ omap4_prminst_write_inst_reg(0x1 <<
+ OMAP4430_DEVICE_OFF_ENABLE_SHIFT,
+ OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST,
+ OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET);
+ else
+#endif
+ omap4_prminst_write_inst_reg(0x0 <<
+ OMAP4430_DEVICE_OFF_ENABLE_SHIFT,
+ OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST,
+ OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET);
+}
+
+/**
+ * omap4_device_prev_state_off:
+ * returns true if the device hit OFF mode
+ * This is API to check whether OMAP is waking up from device OFF mode.
+ * There is no other status bit available for SW to read whether last state
+ * entered was device OFF. To work around this, CORE PD, RFF context state
+ * is used which is lost only when we hit device OFF state
+ */
+bool omap4_device_prev_state_off(void)
+{
+ u32 reg;
+
+ reg = omap4_prminst_read_inst_reg(core_pwrdm->prcm_partition,
+ core_pwrdm->prcm_offs,
+ OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET)
+ & OMAP4430_LOSTCONTEXT_RFF_MASK;
+
+ return reg ? true : false;
+}
+
+void omap4_device_clear_prev_off_state(void)
+{
+ omap4_prminst_write_inst_reg(OMAP4430_LOSTCONTEXT_RFF_MASK |
+ OMAP4430_LOSTCONTEXT_DFF_MASK,
+ core_pwrdm->prcm_partition,
+ core_pwrdm->prcm_offs,
+ OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET);
+}
+
+/**
+ * omap4_device_next_state_off:
+ * returns true if the device next state is OFF
+ * This is API to check whether OMAP is programmed for device OFF
+ */
+bool omap4_device_next_state_off(void)
+{
+ return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_DEVICE_INST,
+ OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET)
+ & OMAP4430_DEVICE_OFF_ENABLE_MASK ? true : false;
+}
+
+/**
* omap4_pm_init - Init routine for OMAP4 PM
*
* Initializes all powerdomain and clockdomain target states
diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c
index a7880af..c0aab2a 100644
--- a/arch/arm/mach-omap2/powerdomain44xx.c
+++ b/arch/arm/mach-omap2/powerdomain44xx.c
@@ -19,9 +19,13 @@
#include "powerdomain.h"
#include <plat/prcm.h>
#include "prm2xxx_3xxx.h"
+#include "cminst44xx.h"
#include "prm44xx.h"
+#include "prcm44xx.h"
#include "prminst44xx.h"
#include "prm-regbits-44xx.h"
+#include "cm-regbits-44xx.h"
+#include "cm2_44xx.h"
static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
{
@@ -207,6 +211,41 @@ static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
return 0;
}
+static int omap4_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
+{
+ /*
+ * FIXME: This should be fixed right way by moving it into HWMOD
+ * or clock framework since sar control is moved to module level
+ */
+ omap4_cminst_rmw_inst_reg_bits(OMAP4430_SAR_MODE_MASK,
+ 1 << OMAP4430_SAR_MODE_SHIFT, OMAP4430_CM2_PARTITION,
+ OMAP4430_CM2_L3INIT_INST,
+ OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET);
+ omap4_cminst_rmw_inst_reg_bits(OMAP4430_SAR_MODE_MASK,
+ 1 << OMAP4430_SAR_MODE_SHIFT, OMAP4430_CM2_PARTITION,
+ OMAP4430_CM2_L3INIT_INST,
+ OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET);
+ return 0;
+}
+
+static int omap4_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
+{
+ /*
+ * FIXME: This should be fixed right way by moving it into HWMOD
+ * or clock framework since sar control is moved to module level
+ */
+ omap4_cminst_rmw_inst_reg_bits(OMAP4430_SAR_MODE_MASK,
+ 0 << OMAP4430_SAR_MODE_SHIFT, OMAP4430_CM2_PARTITION,
+ OMAP4430_CM2_L3INIT_INST,
+ OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET);
+ omap4_cminst_rmw_inst_reg_bits(OMAP4430_SAR_MODE_MASK,
+ 0 << OMAP4430_SAR_MODE_SHIFT, OMAP4430_CM2_PARTITION,
+ OMAP4430_CM2_L3INIT_INST,
+ OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET);
+
+ return 0;
+}
+
struct pwrdm_ops omap4_pwrdm_operations = {
.pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst,
.pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst,
@@ -222,4 +261,6 @@ struct pwrdm_ops omap4_pwrdm_operations = {
.pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst,
.pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst,
.pwrdm_wait_transition = omap4_pwrdm_wait_transition,
+ .pwrdm_enable_hdwr_sar = omap4_pwrdm_enable_hdwr_sar,
+ .pwrdm_disable_hdwr_sar = omap4_pwrdm_disable_hdwr_sar,
};
diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c
index ec24a39..d645d68 100644
--- a/arch/arm/mach-omap2/powerdomains44xx_data.c
+++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
@@ -95,7 +95,6 @@ static struct powerdomain abe_44xx_pwrdm = {
.prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
.pwrsts = PWRSTS_OFF_RET_INA_ON,
- .pwrsts_logic_ret = PWRSTS_OFF,
.banks = 2,
.pwrsts_mem_ret = {
[0] = PWRSTS_RET, /* aessmem */
@@ -122,7 +121,6 @@ static struct powerdomain dss_44xx_pwrdm = {
.prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
.pwrsts = PWRSTS_OFF_RET_INA_ON,
- .pwrsts_logic_ret = PWRSTS_OFF,
.banks = 1,
.pwrsts_mem_ret = {
[0] = PWRSTS_OFF, /* dss_mem */
@@ -240,7 +238,6 @@ static struct powerdomain emu_44xx_pwrdm = {
.prcm_offs = OMAP4430_PRM_EMU_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
- .pwrsts = PWRSTS_OFF_ON,
.banks = 1,
.pwrsts_mem_ret = {
[0] = PWRSTS_OFF, /* emu_bank */
@@ -311,7 +308,6 @@ static struct powerdomain ivahd_44xx_pwrdm = {
.prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
.pwrsts = PWRSTS_OFF_RET_INA_ON,
- .pwrsts_logic_ret = PWRSTS_OFF,
.banks = 4,
.pwrsts_mem_ret = {
[0] = PWRSTS_OFF, /* hwa_mem */
@@ -365,7 +361,7 @@ static struct powerdomain l3init_44xx_pwrdm = {
.prcm_offs = OMAP4430_PRM_L3INIT_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
- .pwrsts = PWRSTS_OFF_RET_INA_ON,
+ .pwrsts = PWRSTS_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 1,
.pwrsts_mem_ret = {
@@ -374,7 +370,7 @@ static struct powerdomain l3init_44xx_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* l3init_bank1 */
},
- .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE | PWRDM_HAS_HDWR_SAR,
.wakeup_lat = {
[PWRDM_FUNC_PWRST_OFF] = 1000,
[PWRDM_FUNC_PWRST_OSWR] = 600,
diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S
index 3f46180..2b37f3b 100644
--- a/arch/arm/mach-omap2/sleep44xx.S
+++ b/arch/arm/mach-omap2/sleep44xx.S
@@ -54,6 +54,9 @@ POR_params:
.word 1, 0
+ppa_zero_params:
+ .word 0x0
+
/*
* =============================
* == CPU suspend entry point ==
@@ -86,8 +89,9 @@ ENTRY(omap4_cpu_suspend)
mov r6, r1
bl omap4_get_sar_ram_base
mov r8, r0
- str r6, [r8, #L2X0_OFFSET] @ Store save state
ands r5, r5, #0x0f
+ streq r6, [r8, #L2X0_SAVE_OFFSET0] @ Store save state
+ strne r6, [r8, #L2X0_SAVE_OFFSET1]
orreq r8, r8, #CPU0_SAVE_OFFSET
orrne r8, r8, #CPU1_SAVE_OFFSET
@@ -131,6 +135,20 @@ ENTRY(omap4_cpu_suspend)
*/
bl v7_flush_dcache_all
+ bl omap4_get_sar_ram_base
+ ldr r9, [r0, #OMAP_TYPE_OFFSET]
+ cmp r9, #0x1 @ Check for HS device
+ bne skip_secure_l1_flush
+ mov r0, #SCU_PM_NORMAL
+ mov r1, #0xFF @ clean seucre L1
+ stmfd r13!, {r4-r12, r14}
+ ldr r12, =SCU_POWER_SECURE_INDEX
+ dsb
+ smc #0
+ dsb
+ ldmfd r13!, {r4-r12, r14}
+skip_secure_l1_flush:
+
/*
* Clear the SCTLR.C bit to prevent further data cache
* allocation. Clearing SCTLR.C would make all the data accesses
@@ -164,9 +182,8 @@ ENTRY(omap4_cpu_suspend)
mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
ands r0, r0, #0x0f
ldreq r0, [r8, #SCU_OFFSET0]
- ldreq r1, [r8, #L1_OFFSET0]
ldrne r0, [r8, #SCU_OFFSET1]
- ldrne r1, [r8, #L1_OFFSET0]
+ mov r1, #0x00 @ Secure L1 is clean already
stmfd r13!, {r4-r12, r14}
ldr r12, =SCU_POWER_SECURE_INDEX
dsb
@@ -185,6 +202,14 @@ skip_scu_gp_set:
isb
dsb
+ mrc p15, 0, r0, c1, c1, 2 @Read NSACR data
+ tst r0, #(1 << 18)
+ mrcne p15, 0, r0, c1, c0, 1
+ bicne r0, r0, #(1 << 6)
+ mcrne p15, 0, r0, c1, c0, 1
+ isb
+
+
#ifdef CONFIG_CACHE_L2X0
/*
* Clean and invalidate the L2 cache.
@@ -199,7 +224,10 @@ skip_scu_gp_set:
l2x_clean_inv:
bl omap4_get_sar_ram_base
mov r8, r0
- ldr r0, [r8, #L2X0_OFFSET]
+ mrc p15, 0, r5, c0, c0, 5 @ Read MPIDR
+ ands r5, r5, #0x0f
+ ldreq r0, [r8, #L2X0_SAVE_OFFSET0]
+ ldrne r0, [r8, #L2X0_SAVE_OFFSET1]
cmp r0, #3
bne do_WFI
#ifdef CONFIG_PL310_ERRATA_727915
@@ -211,11 +239,11 @@ l2x_clean_inv:
#endif
bl omap4_get_l2cache_base
mov r2, r0
- mov r0, #0xff
- str r0, [r2, #L2X0_CLEAN_WAY]
+ ldr r0, =0xffff
+ str r0, [r2, #L2X0_CLEAN_INV_WAY]
wait:
- ldr r0, [r2, #L2X0_CLEAN_WAY]
- ands r0, r0, #0xff
+ ldr r0, [r2, #L2X0_CLEAN_INV_WAY]
+ ands r0, r0, #0xff
bne wait
#ifdef CONFIG_PL310_ERRATA_727915
mov r0, #0x00
@@ -248,6 +276,13 @@ do_WFI:
mcreq p15, 0, r0, c1, c0, 0
isb
+ /* Enable SMP bit if it's being disabled */
+ mrc p15, 0, r0, c1, c0, 1
+ tst r0, #(1 << 6) @ Check SMP bit enabled?
+ orreq r0, r0, #(1 << 6)
+ mcreq p15, 0, r0, c1, c0, 1
+ isb
+
/*
* Ensure the CPU power state is set to NORMAL in
* SCU power state so that CPU is back in coherency.
@@ -292,6 +327,52 @@ ENDPROC(omap4_cpu_suspend)
*/
ENTRY(omap4_cpu_resume)
+ /*
+ * CPU1 must check if CPU0 is alive/awaken.
+ * if PL310 is OFF, MPUSS was OFF and CPU0 is still off,
+ * CPU1 must go to sleep and wait for CPU0.
+ * CPU0 is needed for any PPA API to work.
+ */
+ mrc p15, 0, r0, c0, c0, 5 @ Get cpuID
+ ands r0, r0, #0x0f @ Continue boot if CPU0
+ beq continue_boot
+ ldr r8, =OMAP44XX_SAR_RAM_BASE
+ ldr r9, [r8, #OMAP_TYPE_OFFSET]
+ cmp r9, #0x1 @ Check for HS device
+ bne continue_boot @ Continue on GP devcies
+ ldr r2, =OMAP44XX_L2CACHE_BASE
+ ldr r0, [r2, #L2X0_CTRL]
+ and r0, #0x0f
+ cmp r0, #1 @ is CPU0 already UP?
+ beq ppa_cp15_cpu1_configure @ CPU1 HS go to next stage
+ /*
+ * CPU0 and CPU1 are release together from OFF mode, however,
+ * CPU0 can be busy doing restore operations while waking
+ * from OFF mode, However, for many PPA services we need
+ * CPU0, so, we ask CPU1 to loop back to stagger CPU1 behind CPU0
+ */
+ b omap4_cpu_resume
+
+ppa_cp15_cpu1_configure:
+ /*
+ * Configure CP15 for CPU1 on HS devices:
+ * In HS devices CPU0's CP15 is configured at wakeup by PPA, CPU1 must
+ * call PPA to configure it.
+ * In 4430 devices CPU1 this call also enables the access to SMP bit,
+ * on 4460 devices, CPU1 will have SMP bit access by default.
+ */
+ mov r0, #PPA_SERVICE_DEFAULT_POR_NS_SMP
+ adr r3, ppa_zero_params @ Pointer to parameters
+ LM_CALL_PPA_SERVICE_PA
+ isb
+ dsb
+ cmp r0, #0x0 @ API returns 0 on success.
+ bne ppa_cp15_cpu1_configure @ retry if we did succeed
+
+ /* Fall through to continue with boot */
+
+continue_boot:
+
#ifdef CONFIG_CACHE_L2X0
/*
* Restore the L2 AUXCTRL and enable the L2 cache.
@@ -342,6 +423,19 @@ skip_por:
skip_l2en:
#endif
+ /* Check if we have Public access to SMP bit */
+ mrc p15, 0, r0, c1, c1, 2 @ Read NSACR data
+ tst r0, #(1 << 18)
+ beq skip_ns_smp_enable @ Skip if still no access
+
+ /* Set the SMP bit if it is not already set */
+ mrc p15, 0, r0, c1, c0, 1
+ tst r0, #(1 << 6) @ Check SMP bit enabled?
+ orreq r0, r0, #(1 << 6)
+ mcreq p15, 0, r0, c1, c0, 1
+ isb
+skip_ns_smp_enable:
+
/*
* Check the wakeup cpuid and use appropriate
* SAR BANK location for context restore.
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 2debb1f..cbf9a3b 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -199,7 +199,21 @@ void omap_vc_post_scale(struct voltagedomain *voltdm,
unsigned long target_volt,
u8 target_vsel, u8 current_vsel)
{
+ struct omap_vc_channel *vc;
u32 smps_steps = 0, smps_delay = 0;
+ u8 on_vsel, onlp_vsel;
+ u32 val;
+
+ if (IS_ERR_OR_NULL(voltdm)) {
+ pr_err("%s bad voldm\n", __func__);
+ return;
+ }
+
+ vc = voltdm->vc;
+ if (IS_ERR_OR_NULL(vc)) {
+ pr_err("%s voldm=%s bad vc\n", __func__, voltdm->name);
+ return;
+ }
smps_steps = abs(target_vsel - current_vsel);
/* SMPS slew rate / step size. 2us added as buffer. */
@@ -208,6 +222,14 @@ void omap_vc_post_scale(struct voltagedomain *voltdm,
udelay(smps_delay);
voltdm->curr_volt = target_volt;
+
+ /* Set up the on voltage for wakeup from lp and OFF */
+ on_vsel = voltdm->pmic->uv_to_vsel(target_volt);
+ onlp_vsel = voltdm->pmic->uv_to_vsel(target_volt);
+ val = (on_vsel << vc->common->cmd_on_shift) |
+ (onlp_vsel << vc->common->cmd_onlp_shift) |
+ vc->setup_voltage_common;
+ voltdm->write(val, vc->cmdval_reg);
}
static int omap_vc_bypass_send_value(struct voltagedomain *voltdm,
@@ -419,12 +441,14 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)
/**
* omap_vc_setup_lp_time() - configure the voltage ramp time for low states.
* @voltdm: voltagedomain we are interested in.
+ * @is_retention: Are we interested in retention or OFF?
*
* The ramp times are calculated based on the worst case voltage drop,
* which is the difference of on_volt and the ret_volt. This time is used
* for computing the duration necessary for low power states such as retention.
*/
-static int __init omap_vc_setup_lp_time(struct voltagedomain *voltdm)
+static int __init omap_vc_setup_lp_time(struct voltagedomain *voltdm,
+ bool is_retention)
{
u32 volt_drop = 0, volt_ramptime = 0, volt_rampcount;
u32 sys_clk_mhz = 0, sysclk_cycles = 0, max_latency_for_prescaler = 0;
@@ -464,10 +488,17 @@ static int __init omap_vc_setup_lp_time(struct voltagedomain *voltdm)
*/
max_latency_for_prescaler = (63 * sysclk_cycles) / sys_clk_mhz;
- volt_drop = pmic->on_volt - pmic->ret_volt;
+ if (is_retention)
+ volt_drop = pmic->on_volt - pmic->ret_volt;
+ else
+ volt_drop = pmic->on_volt;
volt_ramptime = DIV_ROUND_UP(volt_drop, pmic->slew_rate);
volt_ramptime += OMAP_VC_I2C_ACK_DELAY;
+ /* many PMICs need additional time to switch back on */
+ if (!is_retention)
+ volt_ramptime += pmic->switch_on_time;
+
if (volt_ramptime < max_latency_for_prescaler)
pre_scaler = 0x0;
else
@@ -524,7 +555,7 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
vc->volt_reg_addr = voltdm->pmic->volt_reg_addr;
vc->cmd_reg_addr = voltdm->pmic->cmd_reg_addr;
/* Calculate the RET voltage setup time and update volt_setup_time */
- vc->setup_time = omap_vc_setup_lp_time(voltdm);
+ vc->setup_time = omap_vc_setup_lp_time(voltdm, true);
if ((vc->flags & OMAP_VC_CHANNEL_DEFAULT) &&
((vc->i2c_slave_addr == USE_DEFAULT_CHANNEL_I2C_PARAM) ||
@@ -571,10 +602,12 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
onlp_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->onlp_volt);
ret_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->ret_volt);
off_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->off_volt);
- val = ((on_vsel << vc->common->cmd_on_shift) |
- (onlp_vsel << vc->common->cmd_onlp_shift) |
+ vc->setup_voltage_common =
(ret_vsel << vc->common->cmd_ret_shift) |
- (off_vsel << vc->common->cmd_off_shift));
+ (off_vsel << vc->common->cmd_off_shift);
+ val = (on_vsel << vc->common->cmd_on_shift) |
+ (onlp_vsel << vc->common->cmd_onlp_shift) |
+ vc->setup_voltage_common;
voltdm->write(val, vc->cmdval_reg);
vc->cfg_channel |= vc_cfg_bits->cmd;
@@ -585,6 +618,10 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
voltdm->rmw(voltdm->vfsm->voltsetup_mask,
vc->setup_time << __ffs(voltdm->vfsm->voltsetup_mask),
voltdm->vfsm->voltsetup_reg);
+ voltdm->rmw(voltdm->vfsm->voltsetup_mask,
+ omap_vc_setup_lp_time(voltdm, false) <<
+ ffs(voltdm->vfsm->voltsetup_mask),
+ voltdm->vfsm->voltsetupoff_reg);
omap_vc_i2c_init(voltdm);
diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h
index 139c04c..a5f25fa 100644
--- a/arch/arm/mach-omap2/vc.h
+++ b/arch/arm/mach-omap2/vc.h
@@ -116,6 +116,7 @@ struct omap_vc_channel {
u16 cmd_reg_addr;
u8 cfg_channel;
u32 setup_time;
+ u32 setup_voltage_common;
bool i2c_high_speed;
/* register access data */
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index 378b4bb..0a9f529 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -40,9 +40,10 @@ struct omap_vdd_info;
/**
* struct omap_vfsm_instance - per-voltage manager FSM register/bitfield
* data
- * @voltsetup_mask: SETUP_TIME* bitmask in the PRM_VOLTSETUP* register
- * @voltsetup_reg: register offset of PRM_VOLTSETUP from PRM base
+ * @voltsetup_mask: SETUP_TIME* bitmask of PRM_VOLTSETUP* register(RET/SLEEP)
+ * @voltsetup_reg: register offset of PRM_VOLTSETUP from PRM base(RET/SLEEP)
* @voltsetup_shift: SETUP_TIME* field shift in the PRM_VOLTSETUP* register
+ * @voltsetupoff_reg: register offset of PRM_VOLTSETUP*_OFF from PRM base
*
* XXX What about VOLTOFFSET/VOLTCTRL?
* XXX It is not necessary to have both a _mask and a _shift for the same
@@ -52,6 +53,7 @@ struct omap_vfsm_instance {
u32 voltsetup_mask;
u8 voltsetup_reg;
u8 voltsetup_shift;
+ u8 voltsetupoff_reg;
};
/**
@@ -188,6 +190,7 @@ struct omap_volt_data {
* @i2c_hscll_high: PMIC interface speed config for highspeed mode (T high)
* @i2c_scll_low: PMIC interface speed config for fullspeed mode (T low)
* @i2c_scll_high: PMIC interface speed config for fullspeed mode (T high)
+ * @switch_on_time: time taken for switch on the DCDC in uSec
*/
struct omap_voltdm_pmic {
int slew_rate;
@@ -197,6 +200,7 @@ struct omap_voltdm_pmic {
u32 ret_volt;
u32 off_volt;
u16 volt_setup_time;
+ u16 switch_on_time;
u8 vp_erroroffset;
u8 vp_vstepmin;
u8 vp_vstepmax;
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
index 3aa54fc..dc5026e 100644
--- a/arch/arm/mach-omap2/voltagedomains44xx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
@@ -40,6 +40,7 @@ static const struct omap_vfsm_instance omap4_vdd_mpu_vfsm = {
OMAP4430_RAMP_DOWN_COUNT_MASK |
OMAP4430_RAMP_UP_PRESCAL_MASK |
OMAP4430_RAMP_UP_COUNT_MASK,
+ .voltsetupoff_reg = OMAP4_PRM_VOLTSETUP_MPU_OFF_OFFSET,
};
static struct omap_vdd_info omap4_vdd_mpu_info;
@@ -50,6 +51,7 @@ static const struct omap_vfsm_instance omap4_vdd_iva_vfsm = {
OMAP4430_RAMP_DOWN_COUNT_MASK |
OMAP4430_RAMP_UP_PRESCAL_MASK |
OMAP4430_RAMP_UP_COUNT_MASK,
+ .voltsetupoff_reg = OMAP4_PRM_VOLTSETUP_IVA_OFF_OFFSET,
};
static struct omap_vdd_info omap4_vdd_iva_info;
@@ -60,6 +62,7 @@ static const struct omap_vfsm_instance omap4_vdd_core_vfsm = {
OMAP4430_RAMP_DOWN_COUNT_MASK |
OMAP4430_RAMP_UP_PRESCAL_MASK |
OMAP4430_RAMP_UP_COUNT_MASK,
+ .voltsetupoff_reg = OMAP4_PRM_VOLTSETUP_CORE_OFF_OFFSET,
};
static struct omap_vdd_info omap4_vdd_core_info;
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 1527929..d668790 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -148,8 +148,8 @@ extern int gpmc_cs_reserved(int cs);
extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode,
unsigned int u32_count, int is_write);
extern int gpmc_prefetch_reset(int cs);
-extern void omap3_gpmc_save_context(void);
-extern void omap3_gpmc_restore_context(void);
+extern void omap_gpmc_save_context(void);
+extern void omap_gpmc_restore_context(void);
extern int gpmc_read_status(int cmd);
extern int gpmc_cs_configure(int cs, int cmd, int wval);
extern int gpmc_nand_read(int cs, int cmd);
diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
index 1bfdf63..c57a07e 100644
--- a/arch/arm/plat-omap/include/plat/omap-pm.h
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -372,4 +372,6 @@ int omap_pm_set_min_mpu_freq(struct device *dev, unsigned long f);
void omap_pm_enable_off_mode(void);
void omap_pm_disable_off_mode(void);
+extern bool off_mode_enabled;
+
#endif
diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h
index c6d131d..f6da497 100644
--- a/arch/arm/plat-omap/include/plat/omap44xx.h
+++ b/arch/arm/plat-omap/include/plat/omap44xx.h
@@ -22,6 +22,9 @@
#define L4_PER_44XX_BASE 0x48000000
#define L4_EMU_44XX_BASE 0x54000000
#define L3_44XX_BASE 0x44000000
+#define L3_44XX_BASE_CLK1 L3_44XX_BASE
+#define L3_44XX_BASE_CLK2 0x44800000
+#define L3_44XX_BASE_CLK3 0x45000000
#define OMAP44XX_EMIF1_BASE 0x4c000000
#define OMAP44XX_EMIF2_BASE 0x4d000000
#define OMAP44XX_DMM_BASE 0x4e000000
@@ -59,5 +62,7 @@
#define OMAP44XX_HSUSB_OHCI_BASE (L4_44XX_BASE + 0x64800)
#define OMAP44XX_HSUSB_EHCI_BASE (L4_44XX_BASE + 0x64C00)
+#define OMAP44XX_C2C_BASE 0x5c000000
+
#endif /* __ASM_ARCH_OMAP44XX_H */
diff --git a/arch/arm/plat-omap/omap-pm-interface.c b/arch/arm/plat-omap/omap-pm-interface.c
index 67319a7..b47e784 100644
--- a/arch/arm/plat-omap/omap-pm-interface.c
+++ b/arch/arm/plat-omap/omap-pm-interface.c
@@ -26,7 +26,7 @@
#include "omap-pm-helper.h"
-static bool off_mode_enabled;
+bool off_mode_enabled;
/*
* Device-driver-originated constraints (via board-*.c files)
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 5aa0e19..110567e 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -41,6 +41,8 @@ struct gpio_regs {
u32 risingdetect;
u32 fallingdetect;
u32 dataout;
+ u32 debounce;
+ u32 debounce_en;
};
struct gpio_bank {
@@ -1263,9 +1265,6 @@ static int omap_gpio_pm_runtime_suspend(struct device *dev)
u32 l1 = 0, l2 = 0;
int j;
- for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
- clk_disable(bank->dbck);
-
/* If going to OFF, remove triggering for all
* non-wakeup GPIOs. Otherwise spurious IRQs will be
* generated. See OMAP2420 Errata item 1.101. */
@@ -1289,6 +1288,9 @@ save_gpio_ctx:
if (bank->get_context_loss_count)
bank->ctx_loss_count = bank->get_context_loss_count(bank->dev);
omap_gpio_save_context(bank);
+ for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
+ clk_disable(bank->dbck);
+
#endif
return 0;
}
@@ -1386,7 +1388,7 @@ void omap2_gpio_prepare_for_idle(int off_mode)
if (!bank->mod_usage || !bank->loses_context)
continue;
- if (IS_ERR_VALUE(pm_runtime_put_sync(bank->dev) < 0))
+ if (IS_ERR_VALUE(pm_runtime_put_sync_suspend(bank->dev) < 0))
dev_err(bank->dev, "%s: GPIO bank %d "
"pm_runtime_put_sync failed\n",
__func__, bank->id);
@@ -1414,7 +1416,7 @@ void omap_gpio_save_context(struct gpio_bank *bank)
bank->context.irqenable2 =
__raw_readl(bank->base + bank->regs->irqenable2);
bank->context.wake_en =
- __raw_readl(bank->base + bank->regs->wkup_status);
+ __raw_readl(bank->base + bank->regs->wkup_set);
bank->context.ctrl = __raw_readl(bank->base + bank->regs->ctrl);
bank->context.oe = __raw_readl(bank->base + bank->regs->direction);
bank->context.leveldetect0 =
@@ -1426,6 +1428,12 @@ void omap_gpio_save_context(struct gpio_bank *bank)
bank->context.fallingdetect =
__raw_readl(bank->base + bank->regs->fallingdetect);
bank->context.dataout = __raw_readl(bank->base + bank->regs->dataout);
+ if (bank->dbck_enable_mask) {
+ bank->context.debounce = __raw_readl(bank->base +
+ bank->regs->debounce);
+ bank->context.debounce_en = __raw_readl(bank->base +
+ bank->regs->debounce_en);
+ }
bank->saved_context = 1;
}
@@ -1433,14 +1441,9 @@ void omap_gpio_restore_context(struct gpio_bank *bank)
{
if(!bank->saved_context)
return;
- __raw_writel(bank->context.irqenable1,
- bank->base + bank->regs->irqenable);
- __raw_writel(bank->context.irqenable2,
- bank->base + bank->regs->irqenable2);
__raw_writel(bank->context.wake_en,
- bank->base + bank->regs->wkup_status);
+ bank->base + bank->regs->wkup_set);
__raw_writel(bank->context.ctrl, bank->base + bank->regs->ctrl);
- __raw_writel(bank->context.oe, bank->base + bank->regs->direction);
__raw_writel(bank->context.leveldetect0,
bank->base + bank->regs->leveldetect0);
__raw_writel(bank->context.leveldetect1,
@@ -1449,7 +1452,24 @@ void omap_gpio_restore_context(struct gpio_bank *bank)
bank->base + bank->regs->risingdetect);
__raw_writel(bank->context.fallingdetect,
bank->base + bank->regs->fallingdetect);
- __raw_writel(bank->context.dataout, bank->base + bank->regs->dataout);
+ if (bank->regs->set_dataout && bank->regs->clr_dataout)
+ __raw_writel(bank->context.dataout,
+ bank->base + bank->regs->set_dataout);
+ else
+ __raw_writel(bank->context.dataout,
+ bank->base + bank->regs->dataout);
+ __raw_writel(bank->context.oe, bank->base + bank->regs->direction);
+ if (bank->dbck_enable_mask) {
+ __raw_writel(bank->context.debounce, bank->base +
+ bank->regs->debounce);
+ __raw_writel(bank->context.debounce_en,
+ bank->base + bank->regs->debounce_en);
+ }
+ __raw_writel(bank->context.irqenable1,
+ bank->base + bank->regs->irqenable);
+ __raw_writel(bank->context.irqenable2,
+ bank->base + bank->regs->irqenable2);
+ bank->saved_context = 0;
}
#endif
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index adecfa2..8f83bfc 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -218,6 +218,18 @@ config TWL4030_POWER
and load scripts controlling which resources are switched off/on
or reset when a sleep, wakeup or warm reset event occurs.
+config TWL6030_POWER
+ bool "Support power resources on TWL6030 family chips"
+ depends on TWL4030_CORE
+ help
+ Say yes here if you want to use the power resources on the
+ TWL6030 family chips. Most of these resources are regulators,
+ which have a separate driver; some are control signals, such
+ as clock request handshaking.
+
+ This driver defaults to assuming only APPs processor uses
+ the resource, it can however be overridden by board file
+
config TWL4030_CODEC
bool
depends on TWL4030_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 184b4728..60f9021 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o
obj-$(CONFIG_TWL6030_MADC) += twl6030-madc.o
obj-$(CONFIG_TWL6040_CODEC) += twl6040-codec.o twl6040-irq.o
obj-$(CONFIG_TWL6030_POWEROFF) += twl6030-poweroff.o
+obj-$(CONFIG_TWL6030_POWER) += twl6030-power.o
obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 65ea354..194a674 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -83,7 +83,7 @@
#define twl_has_madc() false
#endif
-#ifdef CONFIG_TWL4030_POWER
+#if defined(CONFIG_TWL4030_POWER) || defined(CONFIG_TWL6030_POWER)
#define twl_has_power() true
#else
#define twl_has_power() false
@@ -1253,8 +1253,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
}
/* load power event scripts */
- if (twl_has_power() && pdata->power)
- twl4030_power_init(pdata->power);
+ if (twl_has_power()) {
+ if (twl_class_is_4030() && pdata->power)
+ twl4030_power_init(pdata->power);
+ if (twl_class_is_6030())
+ twl6030_power_init(pdata->power);
+ }
/* Maybe init the T2 Interrupt subsystem */
if (client->irq
diff --git a/drivers/mfd/twl6030-power.c b/drivers/mfd/twl6030-power.c
new file mode 100644
index 0000000..84a8a22
--- /dev/null
+++ b/drivers/mfd/twl6030-power.c
@@ -0,0 +1,146 @@
+/*
+ * Handling for Resource Mapping for TWL6030 Family of chips
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ *
+ * 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.
+
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/pm.h>
+#include <linux/i2c/twl.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+
+#define VREG_GRP 0
+
+/**
+ * struct twl6030_resource_map - describe the resource mapping for TWL6030
+ * @name: name of the resource
+ * @res_id: resource ID
+ * @base_addr: base address
+ * @group: which device group can control this resource?
+ */
+struct twl6030_resource_map {
+ char *name;
+ u8 res_id;
+ u8 base_addr;
+ u8 group;
+};
+
+/* list of all s/w modifiable resources in TWL6030 */
+static __initdata struct twl6030_resource_map twl6030_res_map[] = {
+ {.res_id = RES_V1V29,.name = "V1V29",.base_addr = 0x40,.group = DEV_GRP_P1,},
+ {.res_id = RES_V1V8,.name = "V1V8",.base_addr = 0x46,.group = DEV_GRP_P1,},
+ {.res_id = RES_V2V1,.name = "V2V1",.base_addr = 0x4c,.group = DEV_GRP_P1,},
+ {.res_id = RES_VDD1,.name = "CORE1",.base_addr = 0x52,.group = DEV_GRP_P1,},
+ {.res_id = RES_VDD2,.name = "CORE2",.base_addr = 0x58,.group = DEV_GRP_P1,},
+ {.res_id = RES_VDD3,.name = "CORE3",.base_addr = 0x5e,.group = DEV_GRP_P1,},
+ {.res_id = RES_VMEM,.name = "VMEM",.base_addr = 0x64,.group = DEV_GRP_P1,},
+ /* VANA cannot be modified */
+ {.res_id = RES_VUAX1,.name = "VUAX1",.base_addr = 0x84,.group = DEV_GRP_P1,},
+ {.res_id = RES_VAUX2,.name = "VAUX2",.base_addr = 0x88,.group = DEV_GRP_P1,},
+ {.res_id = RES_VAUX3,.name = "VAUX3",.base_addr = 0x8c,.group = DEV_GRP_P1,},
+ {.res_id = RES_VCXIO,.name = "VCXIO",.base_addr = 0x90,.group = DEV_GRP_P1,},
+ {.res_id = RES_VDAC,.name = "VDAC",.base_addr = 0x94,.group = DEV_GRP_P1,},
+ {.res_id = RES_VMMC1,.name = "VMMC",.base_addr = 0x98,.group = DEV_GRP_P1,},
+ {.res_id = RES_VPP,.name = "VPP",.base_addr = 0x9c,.group = DEV_GRP_P1,},
+ /* VRTC cannot be modified */
+ {.res_id = RES_VUSBCP,.name = "VUSB",.base_addr = 0xa0,.group = DEV_GRP_P1,},
+ {.res_id = RES_VSIM,.name = "VSIM",.base_addr = 0xa4,.group = DEV_GRP_P1,},
+ {.res_id = RES_REGEN,.name = "REGEN1",.base_addr = 0xad,.group = DEV_GRP_P1,},
+ {.res_id = RES_REGEN2,.name = "REGEN2",.base_addr = 0xb0,.group = DEV_GRP_P1,},
+ {.res_id = RES_SYSEN,.name = "SYSEN",.base_addr = 0xb3,.group = DEV_GRP_P1,},
+ /* NRES_PWRON cannot be modified */
+ /* 32KCLKAO cannot be modified */
+ {.res_id = RES_32KCLKG,.name = "32KCLKG",.base_addr = 0xbc,.group = DEV_GRP_P1,},
+ {.res_id = RES_32KCLKAUDIO,.name = "32KCLKAUDIO",.base_addr = 0xbf,.group = DEV_GRP_P1,},
+ /* BIAS cannot be modified */
+ /* VBATMIN_HI cannot be modified */
+ /* RC6MHZ cannot be modified */
+ /* TEMP cannot be modified */
+};
+
+/* Actual power groups that TWL understands */
+#define P3_GRP_6030 BIT(2) /* secondary processor, modem, etc */
+#define P2_GRP_6030 BIT(1) /* "peripherals" */
+#define P1_GRP_6030 BIT(0) /* CPU/Linux */
+
+static __init void twl6030_program_map(void)
+{
+ struct twl6030_resource_map *res = twl6030_res_map;
+ int r, i;
+
+ for (i = 0; i < ARRAY_SIZE(twl6030_res_map); i++) {
+ u8 grp = 0;
+
+ /* map back from generic device id to TWL6030 ID */
+ grp |= (res->group & DEV_GRP_P1) ? P1_GRP_6030 : 0;
+ grp |= (res->group & DEV_GRP_P2) ? P2_GRP_6030 : 0;
+ grp |= (res->group & DEV_GRP_P3) ? P3_GRP_6030 : 0;
+
+ r = twl_i2c_write_u8(TWL6030_MODULE_ID0, res->group,
+ res->base_addr);
+ if (r)
+ pr_err("%s: Error(%d) programming map %s {addr=0x%02x},"
+ "grp=0x%02X\n", __func__, r, res->name,
+ res->base_addr, res->group);
+ res++;
+ }
+}
+
+static __init void twl6030_update_map(struct twl4030_resconfig *res_list)
+{
+ int i, res_idx = 0;
+ struct twl6030_resource_map *res;
+
+ while (res_list->resource != TWL4030_RESCONFIG_UNDEF) {
+ res = twl6030_res_map;
+ for (i = 0; i < ARRAY_SIZE(twl6030_res_map); i++) {
+ if (res->res_id == res_list->resource) {
+ res->group = res_list->devgroup &
+ (DEV_GRP_P1 | DEV_GRP_P2 | DEV_GRP_P3);
+ break;
+ }
+ res++;
+ }
+
+ if (i == ARRAY_SIZE(twl6030_res_map)) {
+ pr_err("%s: in platform_data resource index %d, cannot"
+ " find match for resource 0x%02x. NO Update!\n",
+ __func__, res_idx, res_list->resource);
+ }
+ res_list++;
+ res_idx++;
+ }
+}
+
+/**
+ * twl6030_power_init() - Update the power map to reflect connectivity of board
+ * @power_data: power resource map to update (OPTIONAL) - use this if a resource
+ * is used by other devices other than APP (DEV_GRP_P1)
+ */
+void __init twl6030_power_init(struct twl4030_power_data *power_data)
+{
+ if (power_data && !power_data->resource_config) {
+ pr_err("%s: power data from platform without resources!\n",
+ __func__);
+ return;
+ }
+
+ if (power_data)
+ twl6030_update_map(power_data->resource_config);
+
+ twl6030_program_map();
+
+ return;
+}
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 7293884..a9bfb2a 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -522,6 +522,26 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot)
#define RES_MAIN_REF 28
#define TOTAL_RESOURCES 28
+/* 6030 extra resources */
+#define RES_V1V29 29
+#define RES_V1V8 30
+#define RES_V2V1 31
+#define RES_VDD3 32
+#define RES_VMEM 33
+#define RES_VANA 34
+#define RES_VUAX1 35
+#define RES_VCXIO 36
+#define RES_VPP 37
+#define RES_VRTC 38
+#define RES_REGEN2 39
+#define RES_32KCLKAO 40
+#define RES_32KCLKG 41
+#define RES_32KCLKAUDIO 42
+#define RES_BIAS 43
+#define RES_VBATMIN_HI 44
+#define RES_RC6MHZ 45
+#define RES_TEMP 46
+
/*
* Power Bus Message Format ... these can be sent individually by Linux,
* but are usually part of downloaded scripts that are run when various
@@ -641,6 +661,7 @@ struct twl4030_script {
struct twl4030_resconfig {
u8 resource;
u8 devgroup; /* Processor group that Power resource belongs to */
+ /* The following are used by TWL4030 only */
u8 type; /* Power resource addressed, 6 / broadcast message */
u8 type2; /* Power resource addressed, 3 / broadcast message */
u8 remap_off; /* off state remapping */
@@ -648,14 +669,25 @@ struct twl4030_resconfig {
};
struct twl4030_power_data {
- struct twl4030_script **scripts;
- unsigned num;
+ struct twl4030_script **scripts; /* used in TWL4030 only */
+ unsigned num; /* used in TWL4030 only */
struct twl4030_resconfig *resource_config;
#define TWL4030_RESCONFIG_UNDEF ((u8)-1)
};
+#ifdef CONFIG_TWL4030_POWER
extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts);
extern int twl4030_remove_script(u8 flags);
+#else
+static inline void twl4030_power_init(struct twl4030_power_data *triton2_scripts) { }
+static inline int twl4030_remove_script(u8 flags) { return -EINVAL; }
+#endif
+
+#ifdef CONFIG_TWL6030_POWER
+extern void twl6030_power_init(struct twl4030_power_data *power_data);
+#else
+extern inline void twl6030_power_init(struct twl4030_power_data *power_data) { }
+#endif
struct twl4030_codec_audio_data {
unsigned int digimic_delay; /* in ms */