Loading arch/arm/mach-omap2/common.h +2 −2 Original line number Diff line number Diff line Loading @@ -237,8 +237,8 @@ extern void omap_do_wfi(void); #ifdef CONFIG_SMP /* Needed for secondary core boot */ extern void omap_secondary_startup(void); extern void omap_secondary_startup_4460(void); extern void omap4_secondary_startup(void); extern void omap4460_secondary_startup(void); extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); extern void omap_auxcoreboot_addr(u32 cpu_addr); extern u32 omap_read_auxcoreboot0(void); Loading arch/arm/mach-omap2/omap-headsmp.S +4 −4 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ END(omap5_secondary_startup) * The primary core will update this flag using a hardware * register AuxCoreBoot0. */ ENTRY(omap_secondary_startup) ENTRY(omap4_secondary_startup) hold: ldr r12,=0x103 dsb smc #0 @ read from AuxCoreBoot0 Loading @@ -64,9 +64,9 @@ hold: ldr r12,=0x103 * should now contain the SVC stack for this core */ b secondary_startup ENDPROC(omap_secondary_startup) ENDPROC(omap4_secondary_startup) ENTRY(omap_secondary_startup_4460) ENTRY(omap4460_secondary_startup) hold_2: ldr r12,=0x103 dsb smc #0 @ read from AuxCoreBoot0 Loading Loading @@ -101,4 +101,4 @@ hold_2: ldr r12,=0x103 * should now contain the SVC stack for this core */ b secondary_startup ENDPROC(omap_secondary_startup_4460) ENDPROC(omap4460_secondary_startup) arch/arm/mach-omap2/omap-mpuss-lowpower.c +56 −13 Original line number Diff line number Diff line Loading @@ -71,10 +71,43 @@ struct omap4_cpu_pm_info { void (*secondary_startup)(void); }; /** * struct cpu_pm_ops - CPU pm operations * @finish_suspend: CPU suspend finisher function pointer * @resume: CPU resume function pointer * @scu_prepare: CPU Snoop Control program function pointer * * Structure holds functions pointer for CPU low power operations like * suspend, resume and scu programming. */ struct cpu_pm_ops { int (*finish_suspend)(unsigned long cpu_state); void (*resume)(void); void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state); }; static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); static struct powerdomain *mpuss_pd; static void __iomem *sar_base; static int default_finish_suspend(unsigned long cpu_state) { omap_do_wfi(); return 0; } static void dummy_cpu_resume(void) {} static void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state) {} struct cpu_pm_ops omap_pm_ops = { .finish_suspend = default_finish_suspend, .resume = dummy_cpu_resume, .scu_prepare = dummy_scu_prepare, }; /* * Program the wakeup routine address for the CPU0 and CPU1 * used for OFF or DORMANT wakeup. Loading Loading @@ -158,12 +191,13 @@ static void save_l2x0_context(void) { u32 val; void __iomem *l2x0_base = omap4_get_l2cache_base(); if (l2x0_base) { val = __raw_readl(l2x0_base + L2X0_AUX_CTRL); __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET); val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL); __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET); } } #else static void save_l2x0_context(void) {} Loading Loading @@ -225,14 +259,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) cpu_clear_prev_logic_pwrst(cpu); pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); scu_pwrst_prepare(cpu, power_state); set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume)); omap_pm_ops.scu_prepare(cpu, power_state); l2x0_pwrst_prepare(cpu, save_state); /* * Call low level function with targeted low power state. */ cpu_suspend(save_state, omap4_finish_suspend); if (save_state) cpu_suspend(save_state, omap_pm_ops.finish_suspend); else omap_pm_ops.finish_suspend(save_state); /* * Restore the CPUx power state to ON otherwise CPUx Loading Loading @@ -268,14 +305,14 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); scu_pwrst_prepare(cpu, power_state); omap_pm_ops.scu_prepare(cpu, power_state); /* * CPU never retuns back if targeted power state is OFF mode. * CPU ONLINE follows normal CPU ONLINE ptah via * omap_secondary_startup(). * omap4_secondary_startup(). */ omap4_finish_suspend(cpu_state); omap_pm_ops.finish_suspend(cpu_state); pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); return 0; Loading Loading @@ -319,9 +356,9 @@ int __init omap4_mpuss_init(void) pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; if (cpu_is_omap446x()) pm_info->secondary_startup = omap_secondary_startup_4460; pm_info->secondary_startup = omap4460_secondary_startup; else pm_info->secondary_startup = omap_secondary_startup; pm_info->secondary_startup = omap4_secondary_startup; pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); if (!pm_info->pwrdm) { Loading Loading @@ -352,6 +389,12 @@ int __init omap4_mpuss_init(void) save_l2x0_context(); if (cpu_is_omap44xx()) { omap_pm_ops.finish_suspend = omap4_finish_suspend; omap_pm_ops.resume = omap4_cpu_resume; omap_pm_ops.scu_prepare = scu_pwrst_prepare; } return 0; } Loading arch/arm/mach-omap2/omap-smp.c +3 −3 Original line number Diff line number Diff line Loading @@ -87,7 +87,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * /* * Update the AuxCoreBoot0 with boot state for secondary core. * omap_secondary_startup() routine will hold the secondary core till * omap4_secondary_startup() routine will hold the secondary core till * the AuxCoreBoot1 register is updated with cpu state * A barrier is added to ensure that write buffer is drained */ Loading Loading @@ -200,7 +200,7 @@ static void __init omap4_smp_init_cpus(void) static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) { void *startup_addr = omap_secondary_startup; void *startup_addr = omap4_secondary_startup; void __iomem *base = omap_get_wakeupgen_base(); /* Loading @@ -211,7 +211,7 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) scu_enable(scu_base); if (cpu_is_omap446x()) { startup_addr = omap_secondary_startup_4460; startup_addr = omap4460_secondary_startup; pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; } Loading arch/arm/mach-omap2/pm44xx.c +48 −10 Original line number Diff line number Diff line /* * OMAP4 Power Management Routines * OMAP4+ Power Management Routines * * Copyright (C) 2010-2011 Texas Instruments, Inc. * Copyright (C) 2010-2013 Texas Instruments, Inc. * Rajendra Nayak <rnayak@ti.com> * Santosh Shilimkar <santosh.shilimkar@ti.com> * Loading Loading @@ -135,16 +135,16 @@ static void omap_default_idle(void) } /** * omap4_pm_init - Init routine for OMAP4 PM * omap4_init_static_deps - Add OMAP4 static dependencies * * Initializes all powerdomain and clockdomain target states * and all PRCM settings. * Add needed static clockdomain dependencies on OMAP4 devices. * Return: 0 on success or 'err' on failures */ int __init omap4_pm_init(void) static inline int omap4_init_static_deps(void) { int ret; struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; struct clockdomain *ducati_clkdm, *l3_2_clkdm; int ret = 0; if (omap_rev() == OMAP4430_REV_ES1_0) { WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); Loading @@ -163,7 +163,7 @@ int __init omap4_pm_init(void) ret = pwrdm_for_each(pwrdms_setup, NULL); if (ret) { pr_err("Failed to setup powerdomains\n"); goto err2; return ret; } /* Loading @@ -171,6 +171,10 @@ int __init omap4_pm_init(void) * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as * expected. The hardware recommendation is to enable static * dependencies for these to avoid system lock ups or random crashes. * The L4 wakeup depedency is added to workaround the OCP sync hardware * BUG with 32K synctimer which lead to incorrect timer value read * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which * are part of L4 wakeup clockdomain. */ mpuss_clkdm = clkdm_lookup("mpuss_clkdm"); emif_clkdm = clkdm_lookup("l3_emif_clkdm"); Loading @@ -179,7 +183,7 @@ int __init omap4_pm_init(void) ducati_clkdm = clkdm_lookup("ducati_clkdm"); if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l3_2_clkdm) || (!ducati_clkdm)) goto err2; return -EINVAL; ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm); Loading @@ -188,6 +192,39 @@ int __init omap4_pm_init(void) ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm); if (ret) { pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 wakeup dependency\n"); return -EINVAL; } return ret; } /** * omap4_pm_init - Init routine for OMAP4+ devices * * Initializes all powerdomain and clockdomain target states * and all PRCM settings. * Return: Returns the error code returned by called functions. */ int __init omap4_pm_init(void) { int ret = 0; if (omap_rev() == OMAP4430_REV_ES1_0) { WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); return -ENODEV; } pr_info("Power Management for TI OMAP4+ devices.\n"); ret = pwrdm_for_each(pwrdms_setup, NULL); if (ret) { pr_err("Failed to setup powerdomains.\n"); goto err2; } if (cpu_is_omap44xx()) { ret = omap4_init_static_deps(); if (ret) goto err2; } Loading @@ -206,6 +243,7 @@ int __init omap4_pm_init(void) /* Overwrite the default cpu_do_idle() */ arm_pm_idle = omap_default_idle; if (cpu_is_omap44xx()) omap4_idle_init(); err2: Loading Loading
arch/arm/mach-omap2/common.h +2 −2 Original line number Diff line number Diff line Loading @@ -237,8 +237,8 @@ extern void omap_do_wfi(void); #ifdef CONFIG_SMP /* Needed for secondary core boot */ extern void omap_secondary_startup(void); extern void omap_secondary_startup_4460(void); extern void omap4_secondary_startup(void); extern void omap4460_secondary_startup(void); extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); extern void omap_auxcoreboot_addr(u32 cpu_addr); extern u32 omap_read_auxcoreboot0(void); Loading
arch/arm/mach-omap2/omap-headsmp.S +4 −4 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ END(omap5_secondary_startup) * The primary core will update this flag using a hardware * register AuxCoreBoot0. */ ENTRY(omap_secondary_startup) ENTRY(omap4_secondary_startup) hold: ldr r12,=0x103 dsb smc #0 @ read from AuxCoreBoot0 Loading @@ -64,9 +64,9 @@ hold: ldr r12,=0x103 * should now contain the SVC stack for this core */ b secondary_startup ENDPROC(omap_secondary_startup) ENDPROC(omap4_secondary_startup) ENTRY(omap_secondary_startup_4460) ENTRY(omap4460_secondary_startup) hold_2: ldr r12,=0x103 dsb smc #0 @ read from AuxCoreBoot0 Loading Loading @@ -101,4 +101,4 @@ hold_2: ldr r12,=0x103 * should now contain the SVC stack for this core */ b secondary_startup ENDPROC(omap_secondary_startup_4460) ENDPROC(omap4460_secondary_startup)
arch/arm/mach-omap2/omap-mpuss-lowpower.c +56 −13 Original line number Diff line number Diff line Loading @@ -71,10 +71,43 @@ struct omap4_cpu_pm_info { void (*secondary_startup)(void); }; /** * struct cpu_pm_ops - CPU pm operations * @finish_suspend: CPU suspend finisher function pointer * @resume: CPU resume function pointer * @scu_prepare: CPU Snoop Control program function pointer * * Structure holds functions pointer for CPU low power operations like * suspend, resume and scu programming. */ struct cpu_pm_ops { int (*finish_suspend)(unsigned long cpu_state); void (*resume)(void); void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state); }; static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); static struct powerdomain *mpuss_pd; static void __iomem *sar_base; static int default_finish_suspend(unsigned long cpu_state) { omap_do_wfi(); return 0; } static void dummy_cpu_resume(void) {} static void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state) {} struct cpu_pm_ops omap_pm_ops = { .finish_suspend = default_finish_suspend, .resume = dummy_cpu_resume, .scu_prepare = dummy_scu_prepare, }; /* * Program the wakeup routine address for the CPU0 and CPU1 * used for OFF or DORMANT wakeup. Loading Loading @@ -158,12 +191,13 @@ static void save_l2x0_context(void) { u32 val; void __iomem *l2x0_base = omap4_get_l2cache_base(); if (l2x0_base) { val = __raw_readl(l2x0_base + L2X0_AUX_CTRL); __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET); val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL); __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET); } } #else static void save_l2x0_context(void) {} Loading Loading @@ -225,14 +259,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) cpu_clear_prev_logic_pwrst(cpu); pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); scu_pwrst_prepare(cpu, power_state); set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume)); omap_pm_ops.scu_prepare(cpu, power_state); l2x0_pwrst_prepare(cpu, save_state); /* * Call low level function with targeted low power state. */ cpu_suspend(save_state, omap4_finish_suspend); if (save_state) cpu_suspend(save_state, omap_pm_ops.finish_suspend); else omap_pm_ops.finish_suspend(save_state); /* * Restore the CPUx power state to ON otherwise CPUx Loading Loading @@ -268,14 +305,14 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); scu_pwrst_prepare(cpu, power_state); omap_pm_ops.scu_prepare(cpu, power_state); /* * CPU never retuns back if targeted power state is OFF mode. * CPU ONLINE follows normal CPU ONLINE ptah via * omap_secondary_startup(). * omap4_secondary_startup(). */ omap4_finish_suspend(cpu_state); omap_pm_ops.finish_suspend(cpu_state); pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); return 0; Loading Loading @@ -319,9 +356,9 @@ int __init omap4_mpuss_init(void) pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; if (cpu_is_omap446x()) pm_info->secondary_startup = omap_secondary_startup_4460; pm_info->secondary_startup = omap4460_secondary_startup; else pm_info->secondary_startup = omap_secondary_startup; pm_info->secondary_startup = omap4_secondary_startup; pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); if (!pm_info->pwrdm) { Loading Loading @@ -352,6 +389,12 @@ int __init omap4_mpuss_init(void) save_l2x0_context(); if (cpu_is_omap44xx()) { omap_pm_ops.finish_suspend = omap4_finish_suspend; omap_pm_ops.resume = omap4_cpu_resume; omap_pm_ops.scu_prepare = scu_pwrst_prepare; } return 0; } Loading
arch/arm/mach-omap2/omap-smp.c +3 −3 Original line number Diff line number Diff line Loading @@ -87,7 +87,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * /* * Update the AuxCoreBoot0 with boot state for secondary core. * omap_secondary_startup() routine will hold the secondary core till * omap4_secondary_startup() routine will hold the secondary core till * the AuxCoreBoot1 register is updated with cpu state * A barrier is added to ensure that write buffer is drained */ Loading Loading @@ -200,7 +200,7 @@ static void __init omap4_smp_init_cpus(void) static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) { void *startup_addr = omap_secondary_startup; void *startup_addr = omap4_secondary_startup; void __iomem *base = omap_get_wakeupgen_base(); /* Loading @@ -211,7 +211,7 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) scu_enable(scu_base); if (cpu_is_omap446x()) { startup_addr = omap_secondary_startup_4460; startup_addr = omap4460_secondary_startup; pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; } Loading
arch/arm/mach-omap2/pm44xx.c +48 −10 Original line number Diff line number Diff line /* * OMAP4 Power Management Routines * OMAP4+ Power Management Routines * * Copyright (C) 2010-2011 Texas Instruments, Inc. * Copyright (C) 2010-2013 Texas Instruments, Inc. * Rajendra Nayak <rnayak@ti.com> * Santosh Shilimkar <santosh.shilimkar@ti.com> * Loading Loading @@ -135,16 +135,16 @@ static void omap_default_idle(void) } /** * omap4_pm_init - Init routine for OMAP4 PM * omap4_init_static_deps - Add OMAP4 static dependencies * * Initializes all powerdomain and clockdomain target states * and all PRCM settings. * Add needed static clockdomain dependencies on OMAP4 devices. * Return: 0 on success or 'err' on failures */ int __init omap4_pm_init(void) static inline int omap4_init_static_deps(void) { int ret; struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; struct clockdomain *ducati_clkdm, *l3_2_clkdm; int ret = 0; if (omap_rev() == OMAP4430_REV_ES1_0) { WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); Loading @@ -163,7 +163,7 @@ int __init omap4_pm_init(void) ret = pwrdm_for_each(pwrdms_setup, NULL); if (ret) { pr_err("Failed to setup powerdomains\n"); goto err2; return ret; } /* Loading @@ -171,6 +171,10 @@ int __init omap4_pm_init(void) * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as * expected. The hardware recommendation is to enable static * dependencies for these to avoid system lock ups or random crashes. * The L4 wakeup depedency is added to workaround the OCP sync hardware * BUG with 32K synctimer which lead to incorrect timer value read * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which * are part of L4 wakeup clockdomain. */ mpuss_clkdm = clkdm_lookup("mpuss_clkdm"); emif_clkdm = clkdm_lookup("l3_emif_clkdm"); Loading @@ -179,7 +183,7 @@ int __init omap4_pm_init(void) ducati_clkdm = clkdm_lookup("ducati_clkdm"); if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l3_2_clkdm) || (!ducati_clkdm)) goto err2; return -EINVAL; ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm); Loading @@ -188,6 +192,39 @@ int __init omap4_pm_init(void) ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm); if (ret) { pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 wakeup dependency\n"); return -EINVAL; } return ret; } /** * omap4_pm_init - Init routine for OMAP4+ devices * * Initializes all powerdomain and clockdomain target states * and all PRCM settings. * Return: Returns the error code returned by called functions. */ int __init omap4_pm_init(void) { int ret = 0; if (omap_rev() == OMAP4430_REV_ES1_0) { WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); return -ENODEV; } pr_info("Power Management for TI OMAP4+ devices.\n"); ret = pwrdm_for_each(pwrdms_setup, NULL); if (ret) { pr_err("Failed to setup powerdomains.\n"); goto err2; } if (cpu_is_omap44xx()) { ret = omap4_init_static_deps(); if (ret) goto err2; } Loading @@ -206,6 +243,7 @@ int __init omap4_pm_init(void) /* Overwrite the default cpu_do_idle() */ arm_pm_idle = omap_default_idle; if (cpu_is_omap44xx()) omap4_idle_init(); err2: Loading