#include <asm/mach/irq.h>
#include <asm/mach-types.h>
-#include <asm/arch/irqs.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/sram.h>
-#include <asm/arch/control.h>
-#include <asm/arch/gpio.h>
-#include <asm/arch/pm.h>
-#include <asm/arch/mux.h>
-#include <asm/arch/dma.h>
-#include <asm/arch/board.h>
+#include <mach/irqs.h>
+#include <mach/clock.h>
+#include <mach/sram.h>
+#include <mach/control.h>
+#include <mach/gpio.h>
+#include <mach/pm.h>
+#include <mach/mux.h>
+#include <mach/dma.h>
+#include <mach/board.h>
#include "prm.h"
#include "prm-regbits-24xx.h"
#include "sdrc.h"
#include "pm.h"
-/* These addrs are in assembly language code to be patched at runtime */
-extern void *omap2_ocs_sdrc_power;
-extern void *omap2_ocs_sdrc_dlla_ctrl;
+#include <mach/powerdomain.h>
+#include <mach/clockdomain.h>
static void (*omap2_sram_idle)(void);
-static void (*omap2_sram_suspend)(void __iomem *dllctrl);
+static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl,
+ void __iomem *sdrc_power);
static void (*saved_idle)(void);
+static struct powerdomain *mpu_pwrdm;
+static struct powerdomain *core_pwrdm;
+
+static struct clockdomain *dsp_clkdm;
+static struct clockdomain *gfx_clkdm;
+
static struct clk *osc_ck, *emul_ck;
static int omap2_fclks_active(void)
prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);
- /* Try to enter retention */
- prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) | OMAP_LOGICRETSTATE,
- MPU_MOD, PM_PWSTCTRL);
+ /*
+ * Set MPU powerdomain's next power state to RETENTION;
+ * preserve logic state during retention
+ */
+ pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
+ pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
/* Workaround to kill USB */
l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL;
serial_console_sleep(1);
/* Jump to SRAM suspend code */
- omap2_sram_suspend(OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL));
+ omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL),
+ OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL),
+ OMAP_SDRC_REGADDR(SDRC_POWER));
no_sleep:
serial_console_sleep(0);
prm_clear_mod_reg_bits(0x4 | 0x1, WKUP_MOD, PM_WKST);
/* MPU domain wake events */
- l = __raw_readl(OMAP24XX_PRCM_IRQSTATUS_MPU);
+ l = prm_read_mod_reg(OCP_MOD, OMAP2_PRM_IRQSTATUS_MPU_OFFSET);
if (l & 0x01)
- __raw_writel(0x01, OMAP24XX_PRCM_IRQSTATUS_MPU);
+ prm_write_mod_reg(0x01, OCP_MOD,
+ OMAP2_PRM_IRQSTATUS_MPU_OFFSET);
if (l & 0x20)
- __raw_writel(0x20, OMAP24XX_PRCM_IRQSTATUS_MPU);
+ prm_write_mod_reg(0x20, OCP_MOD,
+ OMAP2_PRM_IRQSTATUS_MPU_OFFSET);
/* Mask future PRCM-to-MPU interrupts */
- __raw_writel(0x0, OMAP24XX_PRCM_IRQSTATUS_MPU);
+ prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRM_IRQSTATUS_MPU_OFFSET);
}
static int omap2_i2c_active(void)
.valid = suspend_valid_only_mem,
};
+static int _pm_clkdm_enable_hwsup(struct clockdomain *clkdm)
+{
+ omap2_clkdm_allow_idle(clkdm);
+ return 0;
+}
+
static void __init prcm_setup_regs(void)
{
- u32 l;
+ int i, num_mem_banks;
+ struct powerdomain *pwrdm;
/* Enable autoidle */
- __raw_writel(OMAP24XX_AUTOIDLE, OMAP24XX_PRCM_SYSCONFIG);
+ prm_write_mod_reg(OMAP24XX_AUTOIDLE, OCP_MOD,
+ OMAP24XX_PRM_SYSCONFIG_OFFSET);
/* Set all domain wakeup dependencies */
prm_write_mod_reg(OMAP_EN_WKUP_MASK, MPU_MOD, PM_WKDEP);
if (cpu_is_omap2430())
prm_write_mod_reg(0, OMAP2430_MDM_MOD, PM_WKDEP);
- l = prm_read_mod_reg(CORE_MOD, PM_PWSTCTRL);
- /* Enable retention for all memory blocks */
- l |= OMAP24XX_MEM3RETSTATE | OMAP24XX_MEM2RETSTATE |
- OMAP24XX_MEM1RETSTATE;
-
- /* Set power state to RETENTION */
- l &= ~OMAP_POWERSTATE_MASK;
- l |= 0x01 << OMAP_POWERSTATE_SHIFT;
- prm_write_mod_reg(l, CORE_MOD, PM_PWSTCTRL);
-
- prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) |
- OMAP_LOGICRETSTATE,
- MPU_MOD, PM_PWSTCTRL);
-
- /* Power down DSP and GFX */
- prm_write_mod_reg(OMAP24XX_FORCESTATE | (0x3 << OMAP_POWERSTATE_SHIFT),
- OMAP24XX_DSP_MOD, PM_PWSTCTRL);
- prm_write_mod_reg(OMAP24XX_FORCESTATE | (0x3 << OMAP_POWERSTATE_SHIFT),
- GFX_MOD, PM_PWSTCTRL);
-
- /* Enable clock auto control for all domains */
- cm_write_mod_reg(OMAP24XX_AUTOSTATE_MPU_MASK, MPU_MOD, CM_CLKSTCTRL);
- cm_write_mod_reg(OMAP24XX_AUTOSTATE_DSS_MASK |
- OMAP24XX_AUTOSTATE_L4_MASK |
- OMAP24XX_AUTOSTATE_L3_MASK,
- CORE_MOD, CM_CLKSTCTRL);
- cm_write_mod_reg(OMAP24XX_AUTOSTATE_GFX_MASK, GFX_MOD, CM_CLKSTCTRL);
- cm_write_mod_reg(OMAP2420_AUTOSTATE_IVA_MASK |
- OMAP24XX_AUTOSTATE_DSP_MASK,
- OMAP24XX_DSP_MOD, CM_CLKSTCTRL);
+ /*
+ * Set CORE powerdomain memory banks to retain their contents
+ * during RETENTION
+ */
+ num_mem_banks = pwrdm_get_mem_bank_count(core_pwrdm);
+ for (i = 0; i < num_mem_banks; i++)
+ pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET);
+
+ /* Set CORE powerdomain's next power state to RETENTION */
+ pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET);
+
+ /*
+ * Set MPU powerdomain's next power state to RETENTION;
+ * preserve logic state during retention
+ */
+ pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
+ pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
+
+ /* Force-power down DSP, GFX powerdomains */
+
+ pwrdm = clkdm_get_pwrdm(dsp_clkdm);
+ pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
+ omap2_clkdm_sleep(dsp_clkdm);
+
+ pwrdm = clkdm_get_pwrdm(gfx_clkdm);
+ pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
+ omap2_clkdm_sleep(gfx_clkdm);
+
+ /* Enable clockdomain hardware-supervised control for all clkdms */
+ clkdm_for_each(_pm_clkdm_enable_hwsup);
/* Enable clock autoidle for all domains */
cm_write_mod_reg(OMAP24XX_AUTO_CAM |
/* REVISIT: Configure number of 32 kHz clock cycles for sys_clk
* stabilisation */
- __raw_writel(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_PRCM_CLKSSETUP);
+ prm_write_mod_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
+ OMAP24XX_PRCM_CLKSSETUP_OFFSET);
/* Configure automatic voltage transition */
- __raw_writel(2 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_PRCM_VOLTSETUP);
- __raw_writel(OMAP24XX_AUTO_EXTVOLT |
+ prm_write_mod_reg(2 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
+ OMAP24XX_PRCM_VOLTSETUP_OFFSET);
+ prm_write_mod_reg(OMAP24XX_AUTO_EXTVOLT |
(0x1 << OMAP24XX_SETOFF_LEVEL_SHIFT) |
OMAP24XX_MEMRETCTRL |
(0x1 << OMAP24XX_SETRET_LEVEL_SHIFT) |
(0x0 << OMAP24XX_VOLT_LEVEL_SHIFT),
- OMAP24XX_PRCM_VOLTCTRL);
+ OMAP24XX_GR_MOD, OMAP24XX_PRCM_VOLTCTRL_OFFSET);
/* Enable wake-up events */
prm_write_mod_reg(OMAP24XX_EN_GPIOS | OMAP24XX_EN_GPT1,
u32 l;
printk(KERN_INFO "Power Management for OMAP2 initializing\n");
- l = __raw_readl(OMAP24XX_PRCM_REVISION);
+ l = prm_read_mod_reg(OCP_MOD, OMAP24XX_PRM_REVISION_OFFSET);
printk(KERN_INFO "PRCM revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
+ /* Look up important powerdomains, clockdomains */
+
+ mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
+ if (!mpu_pwrdm)
+ pr_err("PM: mpu_pwrdm not found\n");
+
+ core_pwrdm = pwrdm_lookup("core_pwrdm");
+ if (!core_pwrdm)
+ pr_err("PM: core_pwrdm not found\n");
+
+ dsp_clkdm = clkdm_lookup("dsp_clkdm");
+ if (!dsp_clkdm)
+ pr_err("PM: mpu_clkdm not found\n");
+
+ gfx_clkdm = clkdm_lookup("gfx_clkdm");
+ if (!gfx_clkdm)
+ pr_err("PM: gfx_clkdm not found\n");
+
+
osc_ck = clk_get(NULL, "osc_ck");
if (IS_ERR(osc_ck)) {
printk(KERN_ERR "could not get osc_ck\n");
* These routines need to be in SRAM as that's the only
* memory the MPU can see when it wakes up.
*/
- omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend,
- omap24xx_idle_loop_suspend_sz);
-
- omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
- omap24xx_cpu_suspend_sz);
-
- /* Patch in the correct register addresses for multiboot */
- omap_sram_patch_va(omap24xx_cpu_suspend, &omap2_ocs_sdrc_power,
- omap2_sram_suspend,
- OMAP_SDRC_REGADDR(SDRC_POWER));
- omap_sram_patch_va(omap24xx_cpu_suspend, &omap2_ocs_sdrc_dlla_ctrl,
- omap2_sram_suspend,
- OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL));
+ if (cpu_is_omap24xx()) {
+ omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend,
+ omap24xx_idle_loop_suspend_sz);
+
+ omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
+ omap24xx_cpu_suspend_sz);
+ }
suspend_set_ops(&omap_pm_ops);
pm_idle = omap2_pm_idle;