summaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/cm2xxx_3xxx.c
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2010-12-22 01:30:56 +0300
committerPaul Walmsley <paul@pwsan.com>2010-12-22 06:56:50 +0300
commitf0611a5c220e50dec65041b10bd2fe9484f061a6 (patch)
treef94ba2787f721a38ad57d22638c5561318d31f26 /arch/arm/mach-omap2/cm2xxx_3xxx.c
parent59fb659b065f52fcc2deed293cfbfc58f890376c (diff)
downloadlinux-f0611a5c220e50dec65041b10bd2fe9484f061a6.tar.xz
OMAP3: PRM/CM: separate CM context save/restore; remove PRM context save/restore
The OMAP3 PRM module is in the WKUP powerdomain, which is always powered when the chip is powered, so it shouldn't be necessary to save and restore those PRM registers. Remove the PRM register save/restore code, which should save several microseconds during off-mode entry/exit, since PRM register accesses are relatively slow. While doing so, move the CM register save/restore code into CM-specific code. The CM module has been distinct from the PRM module since 2430. This patch includes some minor changes to pm34xx.c. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Kevin Hilman <khilman@deeprootsystems.com> Cc: Rajendra Nayak <rnayak@ti.com> Cc: Tero Kristo <tero.kristo@nokia.com> Cc: Kalle Jokiniemi <kalle.jokiniemi@digia.com> Reviewed-by: Kevin Hilman <khilman@deeprootsystems.com> Tested-by: Kevin Hilman <khilman@deeprootsystems.com> Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Tested-by: Rajendra Nayak <rnayak@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/cm2xxx_3xxx.c')
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.c296
1 files changed, 295 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.c b/arch/arm/mach-omap2/cm2xxx_3xxx.c
index 5978ce426ec5..1c98dfc93a83 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.c
@@ -29,7 +29,6 @@ static const u8 cm_idlest_offs[] = {
CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
};
-
u32 cm_read_mod_reg(s16 module, u16 idx)
{
return __raw_readl(cm_base + module + idx);
@@ -97,3 +96,298 @@ int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
}
+/*
+ * Context save/restore code - OMAP3 only
+ */
+#ifdef CONFIG_ARCH_OMAP3
+struct omap3_cm_regs {
+ u32 iva2_cm_clksel1;
+ u32 iva2_cm_clksel2;
+ u32 cm_sysconfig;
+ u32 sgx_cm_clksel;
+ u32 dss_cm_clksel;
+ u32 cam_cm_clksel;
+ u32 per_cm_clksel;
+ u32 emu_cm_clksel;
+ u32 emu_cm_clkstctrl;
+ u32 pll_cm_autoidle2;
+ u32 pll_cm_clksel4;
+ u32 pll_cm_clksel5;
+ u32 pll_cm_clken2;
+ u32 cm_polctrl;
+ u32 iva2_cm_fclken;
+ u32 iva2_cm_clken_pll;
+ u32 core_cm_fclken1;
+ u32 core_cm_fclken3;
+ u32 sgx_cm_fclken;
+ u32 wkup_cm_fclken;
+ u32 dss_cm_fclken;
+ u32 cam_cm_fclken;
+ u32 per_cm_fclken;
+ u32 usbhost_cm_fclken;
+ u32 core_cm_iclken1;
+ u32 core_cm_iclken2;
+ u32 core_cm_iclken3;
+ u32 sgx_cm_iclken;
+ u32 wkup_cm_iclken;
+ u32 dss_cm_iclken;
+ u32 cam_cm_iclken;
+ u32 per_cm_iclken;
+ u32 usbhost_cm_iclken;
+ u32 iva2_cm_autoidle2;
+ u32 mpu_cm_autoidle2;
+ u32 iva2_cm_clkstctrl;
+ u32 mpu_cm_clkstctrl;
+ u32 core_cm_clkstctrl;
+ u32 sgx_cm_clkstctrl;
+ u32 dss_cm_clkstctrl;
+ u32 cam_cm_clkstctrl;
+ u32 per_cm_clkstctrl;
+ u32 neon_cm_clkstctrl;
+ u32 usbhost_cm_clkstctrl;
+ u32 core_cm_autoidle1;
+ u32 core_cm_autoidle2;
+ u32 core_cm_autoidle3;
+ u32 wkup_cm_autoidle;
+ u32 dss_cm_autoidle;
+ u32 cam_cm_autoidle;
+ u32 per_cm_autoidle;
+ u32 usbhost_cm_autoidle;
+ u32 sgx_cm_sleepdep;
+ u32 dss_cm_sleepdep;
+ u32 cam_cm_sleepdep;
+ u32 per_cm_sleepdep;
+ u32 usbhost_cm_sleepdep;
+ u32 cm_clkout_ctrl;
+};
+
+static struct omap3_cm_regs cm_context;
+
+void omap3_cm_save_context(void)
+{
+ cm_context.iva2_cm_clksel1 =
+ cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
+ cm_context.iva2_cm_clksel2 =
+ cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2);
+ cm_context.cm_sysconfig = __raw_readl(OMAP3430_CM_SYSCONFIG);
+ cm_context.sgx_cm_clksel =
+ cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL);
+ cm_context.dss_cm_clksel =
+ cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL);
+ cm_context.cam_cm_clksel =
+ cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSEL);
+ cm_context.per_cm_clksel =
+ cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSEL);
+ cm_context.emu_cm_clksel =
+ cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
+ cm_context.emu_cm_clkstctrl =
+ cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.pll_cm_autoidle2 =
+ cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
+ cm_context.pll_cm_clksel4 =
+ cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL4);
+ cm_context.pll_cm_clksel5 =
+ cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5);
+ cm_context.pll_cm_clken2 =
+ cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2);
+ cm_context.cm_polctrl = __raw_readl(OMAP3430_CM_POLCTRL);
+ cm_context.iva2_cm_fclken =
+ cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN);
+ cm_context.iva2_cm_clken_pll = cm_read_mod_reg(OMAP3430_IVA2_MOD,
+ OMAP3430_CM_CLKEN_PLL);
+ cm_context.core_cm_fclken1 =
+ cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+ cm_context.core_cm_fclken3 =
+ cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
+ cm_context.sgx_cm_fclken =
+ cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_FCLKEN);
+ cm_context.wkup_cm_fclken =
+ cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
+ cm_context.dss_cm_fclken =
+ cm_read_mod_reg(OMAP3430_DSS_MOD, CM_FCLKEN);
+ cm_context.cam_cm_fclken =
+ cm_read_mod_reg(OMAP3430_CAM_MOD, CM_FCLKEN);
+ cm_context.per_cm_fclken =
+ cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
+ cm_context.usbhost_cm_fclken =
+ cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
+ cm_context.core_cm_iclken1 =
+ cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
+ cm_context.core_cm_iclken2 =
+ cm_read_mod_reg(CORE_MOD, CM_ICLKEN2);
+ cm_context.core_cm_iclken3 =
+ cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
+ cm_context.sgx_cm_iclken =
+ cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_ICLKEN);
+ cm_context.wkup_cm_iclken =
+ cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
+ cm_context.dss_cm_iclken =
+ cm_read_mod_reg(OMAP3430_DSS_MOD, CM_ICLKEN);
+ cm_context.cam_cm_iclken =
+ cm_read_mod_reg(OMAP3430_CAM_MOD, CM_ICLKEN);
+ cm_context.per_cm_iclken =
+ cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
+ cm_context.usbhost_cm_iclken =
+ cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
+ cm_context.iva2_cm_autoidle2 =
+ cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
+ cm_context.mpu_cm_autoidle2 =
+ cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
+ cm_context.iva2_cm_clkstctrl =
+ cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.mpu_cm_clkstctrl =
+ cm_read_mod_reg(MPU_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.core_cm_clkstctrl =
+ cm_read_mod_reg(CORE_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.sgx_cm_clkstctrl =
+ cm_read_mod_reg(OMAP3430ES2_SGX_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.dss_cm_clkstctrl =
+ cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.cam_cm_clkstctrl =
+ cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.per_cm_clkstctrl =
+ cm_read_mod_reg(OMAP3430_PER_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.neon_cm_clkstctrl =
+ cm_read_mod_reg(OMAP3430_NEON_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.usbhost_cm_clkstctrl =
+ cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.core_cm_autoidle1 =
+ cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1);
+ cm_context.core_cm_autoidle2 =
+ cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE2);
+ cm_context.core_cm_autoidle3 =
+ cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE3);
+ cm_context.wkup_cm_autoidle =
+ cm_read_mod_reg(WKUP_MOD, CM_AUTOIDLE);
+ cm_context.dss_cm_autoidle =
+ cm_read_mod_reg(OMAP3430_DSS_MOD, CM_AUTOIDLE);
+ cm_context.cam_cm_autoidle =
+ cm_read_mod_reg(OMAP3430_CAM_MOD, CM_AUTOIDLE);
+ cm_context.per_cm_autoidle =
+ cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
+ cm_context.usbhost_cm_autoidle =
+ cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
+ cm_context.sgx_cm_sleepdep =
+ cm_read_mod_reg(OMAP3430ES2_SGX_MOD, OMAP3430_CM_SLEEPDEP);
+ cm_context.dss_cm_sleepdep =
+ cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP3430_CM_SLEEPDEP);
+ cm_context.cam_cm_sleepdep =
+ cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP3430_CM_SLEEPDEP);
+ cm_context.per_cm_sleepdep =
+ cm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_CM_SLEEPDEP);
+ cm_context.usbhost_cm_sleepdep =
+ cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
+ cm_context.cm_clkout_ctrl =
+ cm_read_mod_reg(OMAP3430_CCR_MOD, OMAP3_CM_CLKOUT_CTRL_OFFSET);
+}
+
+void omap3_cm_restore_context(void)
+{
+ cm_write_mod_reg(cm_context.iva2_cm_clksel1, OMAP3430_IVA2_MOD,
+ CM_CLKSEL1);
+ cm_write_mod_reg(cm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD,
+ CM_CLKSEL2);
+ __raw_writel(cm_context.cm_sysconfig, OMAP3430_CM_SYSCONFIG);
+ cm_write_mod_reg(cm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD,
+ CM_CLKSEL);
+ cm_write_mod_reg(cm_context.dss_cm_clksel, OMAP3430_DSS_MOD,
+ CM_CLKSEL);
+ cm_write_mod_reg(cm_context.cam_cm_clksel, OMAP3430_CAM_MOD,
+ CM_CLKSEL);
+ cm_write_mod_reg(cm_context.per_cm_clksel, OMAP3430_PER_MOD,
+ CM_CLKSEL);
+ cm_write_mod_reg(cm_context.emu_cm_clksel, OMAP3430_EMU_MOD,
+ CM_CLKSEL1);
+ cm_write_mod_reg(cm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ cm_write_mod_reg(cm_context.pll_cm_autoidle2, PLL_MOD,
+ CM_AUTOIDLE2);
+ cm_write_mod_reg(cm_context.pll_cm_clksel4, PLL_MOD,
+ OMAP3430ES2_CM_CLKSEL4);
+ cm_write_mod_reg(cm_context.pll_cm_clksel5, PLL_MOD,
+ OMAP3430ES2_CM_CLKSEL5);
+ cm_write_mod_reg(cm_context.pll_cm_clken2, PLL_MOD,
+ OMAP3430ES2_CM_CLKEN2);
+ __raw_writel(cm_context.cm_polctrl, OMAP3430_CM_POLCTRL);
+ cm_write_mod_reg(cm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD,
+ CM_FCLKEN);
+ cm_write_mod_reg(cm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD,
+ OMAP3430_CM_CLKEN_PLL);
+ cm_write_mod_reg(cm_context.core_cm_fclken1, CORE_MOD, CM_FCLKEN1);
+ cm_write_mod_reg(cm_context.core_cm_fclken3, CORE_MOD,
+ OMAP3430ES2_CM_FCLKEN3);
+ cm_write_mod_reg(cm_context.sgx_cm_fclken, OMAP3430ES2_SGX_MOD,
+ CM_FCLKEN);
+ cm_write_mod_reg(cm_context.wkup_cm_fclken, WKUP_MOD, CM_FCLKEN);
+ cm_write_mod_reg(cm_context.dss_cm_fclken, OMAP3430_DSS_MOD,
+ CM_FCLKEN);
+ cm_write_mod_reg(cm_context.cam_cm_fclken, OMAP3430_CAM_MOD,
+ CM_FCLKEN);
+ cm_write_mod_reg(cm_context.per_cm_fclken, OMAP3430_PER_MOD,
+ CM_FCLKEN);
+ cm_write_mod_reg(cm_context.usbhost_cm_fclken,
+ OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
+ cm_write_mod_reg(cm_context.core_cm_iclken1, CORE_MOD, CM_ICLKEN1);
+ cm_write_mod_reg(cm_context.core_cm_iclken2, CORE_MOD, CM_ICLKEN2);
+ cm_write_mod_reg(cm_context.core_cm_iclken3, CORE_MOD, CM_ICLKEN3);
+ cm_write_mod_reg(cm_context.sgx_cm_iclken, OMAP3430ES2_SGX_MOD,
+ CM_ICLKEN);
+ cm_write_mod_reg(cm_context.wkup_cm_iclken, WKUP_MOD, CM_ICLKEN);
+ cm_write_mod_reg(cm_context.dss_cm_iclken, OMAP3430_DSS_MOD,
+ CM_ICLKEN);
+ cm_write_mod_reg(cm_context.cam_cm_iclken, OMAP3430_CAM_MOD,
+ CM_ICLKEN);
+ cm_write_mod_reg(cm_context.per_cm_iclken, OMAP3430_PER_MOD,
+ CM_ICLKEN);
+ cm_write_mod_reg(cm_context.usbhost_cm_iclken,
+ OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
+ cm_write_mod_reg(cm_context.iva2_cm_autoidle2, OMAP3430_IVA2_MOD,
+ CM_AUTOIDLE2);
+ cm_write_mod_reg(cm_context.mpu_cm_autoidle2, MPU_MOD, CM_AUTOIDLE2);
+ cm_write_mod_reg(cm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ cm_write_mod_reg(cm_context.mpu_cm_clkstctrl, MPU_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ cm_write_mod_reg(cm_context.core_cm_clkstctrl, CORE_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ cm_write_mod_reg(cm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ cm_write_mod_reg(cm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ cm_write_mod_reg(cm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ cm_write_mod_reg(cm_context.per_cm_clkstctrl, OMAP3430_PER_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ cm_write_mod_reg(cm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ cm_write_mod_reg(cm_context.usbhost_cm_clkstctrl,
+ OMAP3430ES2_USBHOST_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_write_mod_reg(cm_context.core_cm_autoidle1, CORE_MOD,
+ CM_AUTOIDLE1);
+ cm_write_mod_reg(cm_context.core_cm_autoidle2, CORE_MOD,
+ CM_AUTOIDLE2);
+ cm_write_mod_reg(cm_context.core_cm_autoidle3, CORE_MOD,
+ CM_AUTOIDLE3);
+ cm_write_mod_reg(cm_context.wkup_cm_autoidle, WKUP_MOD, CM_AUTOIDLE);
+ cm_write_mod_reg(cm_context.dss_cm_autoidle, OMAP3430_DSS_MOD,
+ CM_AUTOIDLE);
+ cm_write_mod_reg(cm_context.cam_cm_autoidle, OMAP3430_CAM_MOD,
+ CM_AUTOIDLE);
+ cm_write_mod_reg(cm_context.per_cm_autoidle, OMAP3430_PER_MOD,
+ CM_AUTOIDLE);
+ cm_write_mod_reg(cm_context.usbhost_cm_autoidle,
+ OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
+ cm_write_mod_reg(cm_context.sgx_cm_sleepdep, OMAP3430ES2_SGX_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ cm_write_mod_reg(cm_context.dss_cm_sleepdep, OMAP3430_DSS_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ cm_write_mod_reg(cm_context.cam_cm_sleepdep, OMAP3430_CAM_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ cm_write_mod_reg(cm_context.per_cm_sleepdep, OMAP3430_PER_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ cm_write_mod_reg(cm_context.usbhost_cm_sleepdep,
+ OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
+ cm_write_mod_reg(cm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
+ OMAP3_CM_CLKOUT_CTRL_OFFSET);
+}
+#endif