mirror of https://gitee.com/openkylin/linux.git
OMAP PM cleanups for v3.10
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJRZJmAAAoJEFk3GJrT+8ZlZ5IQAIXNen7upyNtYSeDUtrc1FXR GiDv03QB92IKSh+PB4t8PhTsngwipv7gVY790q1GneULU4rzY65o2EOlGhc5qGop PgCcuWrIcjf8YCD9KB07iwYZ2ovCZXpsc/IeV3OYvJYSptpXMPZD1+jP7XuaBIHN 3+oPmDtTRH0vqZXskN+MhNkDB59yZWQ1HjfWfZsS872T5TEUpg8A6kaBC6JmELYh ZEY1cydt6650RIM2jARznN1X4AfO+2WpA3e8fvvNJ9g9tAckb3Sr5SM9QVtjiRtM LCRJejYkP3EzrywBrhWRHPRd+Sz6HQk46YPbY8H5y1cMPWORP21E+xTwOEAzYibj cRZfK++OmrVaPKem2HKsZI6Xok1Mhw7/dP913b6RtZNxSRcnh8xFKhvG0y5xVmkV S/p39bvbIo6kUQrsuxVPbm2yjZ4d/UzY4dsov0fNKpa2FEfHPgE+WDKAHABIVZdj QZDA+uQvybwaiisW3DO80C9I05diAXfXEphepQHc02Mzkmci967aOKHRvNGE5/f4 XCWeNyLSC6HXHdoxZ98DZb+TdTWQz6Fl+28LdBCgDVBr6R1SLQn8ShKYjqTpnwNo fq07DGEC98igrfQ7RTFDKKFoOGyy8+oShJMQZbub/kUgbcjqhvqIis88ZAmtTZHB mkRGeA34zdfcFkfTLFxv =wNGR -----END PGP SIGNATURE----- Merge tag 'omap-pm-v3.10/cleanup/pm' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into omap-for-v3.11/pm OMAP PM cleanups for v3.10
This commit is contained in:
commit
49a34fd538
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
@ -158,11 +191,12 @@ static void save_l2x0_context(void)
|
|||
{
|
||||
u32 val;
|
||||
void __iomem *l2x0_base = omap4_get_l2cache_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);
|
||||
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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
@ -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();
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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>
|
||||
*
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -188,9 +192,42 @@ 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;
|
||||
}
|
||||
|
||||
ret = omap4_mpuss_init();
|
||||
if (ret) {
|
||||
pr_err("Failed to initialise OMAP4 MPUSS\n");
|
||||
|
@ -206,7 +243,8 @@ int __init omap4_pm_init(void)
|
|||
/* Overwrite the default cpu_do_idle() */
|
||||
arm_pm_idle = omap_default_idle;
|
||||
|
||||
omap4_idle_init();
|
||||
if (cpu_is_omap44xx())
|
||||
omap4_idle_init();
|
||||
|
||||
err2:
|
||||
return ret;
|
||||
|
|
Loading…
Reference in New Issue