Skip to content

Commit

Permalink
OMAP3: PRM/CM: separate CM context save/restore; remove PRM context s…
Browse files Browse the repository at this point in the history
…ave/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>
  • Loading branch information
Paul Walmsley committed Dec 22, 2010
1 parent 59fb659 commit f0611a5
Show file tree
Hide file tree
Showing 6 changed files with 304 additions and 382 deletions.
296 changes: 295 additions & 1 deletion arch/arm/mach-omap2/cm2xxx_3xxx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
7 changes: 7 additions & 0 deletions arch/arm/mach-omap2/cm2xxx_3xxx.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,11 @@ extern u32 cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx);
/* CM_IDLEST_GFX */
#define OMAP_ST_GFX_MASK (1 << 0)


/* Function prototypes */
# ifndef __ASSEMBLER__
extern void omap3_cm_save_context(void);
extern void omap3_cm_restore_context(void);
# endif

#endif
4 changes: 2 additions & 2 deletions arch/arm/mach-omap2/pm34xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ void omap_sram_idle(void)
omap_uart_prepare_idle(1);
if (core_next_state == PWRDM_POWER_OFF) {
omap3_core_save_context();
omap3_prcm_save_context();
omap3_cm_save_context();
}
}

Expand Down Expand Up @@ -464,7 +464,7 @@ void omap_sram_idle(void)
core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm);
if (core_prev_state == PWRDM_POWER_OFF) {
omap3_core_restore_context();
omap3_prcm_restore_context();
omap3_cm_restore_context();
omap3_sram_restore_context();
omap2_sms_restore_context();
}
Expand Down
Loading

0 comments on commit f0611a5

Please sign in to comment.