diff options
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 */ |