summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGregory CLEMENT <gregory.clement@free-electrons.com>2014-07-23 15:00:45 +0200
committerJason Cooper <jason@lakedaemon.net>2014-07-24 13:46:35 +0200
commit5da964e0fae05fd96a97a0fcc6bc53dad655f61d (patch)
tree0b9e00f1759ae36ed92fee7a279a2fd41c3bd560 /arch
parentARM: mvebu: use a local variable to store the resume address (diff)
downloadlinux-5da964e0fae05fd96a97a0fcc6bc53dad655f61d.tar.xz
linux-5da964e0fae05fd96a97a0fcc6bc53dad655f61d.zip
ARM: mvebu: make the snoop disabling optional in mvebu_v7_pmsu_idle_prepare()
On some mvebu v7 SoCs (the ones using a Cortex-A9 core and not a PJ4B core), the snoop disabling feature does not exist as the hardware coherency is handled in a different way. Therefore, in preparation to the introduction of the cpuidle support for those SoCs, this commit modifies the mvebu_v7_psmu_idle_prepare() function to take several flags, which allow to decide whether snooping should be disabled, and whether we should use the deep idle mode or not. Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Link: https://lkml.kernel.org/r/1406120453-29291-9-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-mvebu/pmsu.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index ab525b7bfc03..15e67bf67c1c 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -191,8 +191,14 @@ static void mvebu_v7_pmsu_enable_l2_powerdown_onidle(void)
writel(reg, pmsu_mp_base + L2C_NFABRIC_PM_CTL);
}
+enum pmsu_idle_prepare_flags {
+ PMSU_PREPARE_NORMAL = 0,
+ PMSU_PREPARE_DEEP_IDLE = BIT(0),
+ PMSU_PREPARE_SNOOP_DISABLE = BIT(1),
+};
+
/* No locking is needed because we only access per-CPU registers */
-static int mvebu_v7_pmsu_idle_prepare(bool deepidle)
+static int mvebu_v7_pmsu_idle_prepare(unsigned long flags)
{
unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
u32 reg;
@@ -216,26 +222,32 @@ static int mvebu_v7_pmsu_idle_prepare(bool deepidle)
reg = readl(pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(hw_cpu));
/* ask HW to power down the L2 Cache if needed */
- if (deepidle)
+ if (flags & PMSU_PREPARE_DEEP_IDLE)
reg |= PMSU_CONTROL_AND_CONFIG_L2_PWDDN;
/* request power down */
reg |= PMSU_CONTROL_AND_CONFIG_PWDDN_REQ;
writel(reg, pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(hw_cpu));
- /* Disable snoop disable by HW - SW is taking care of it */
- reg = readl(pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
- reg |= PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP;
- writel(reg, pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
+ if (flags & PMSU_PREPARE_SNOOP_DISABLE) {
+ /* Disable snoop disable by HW - SW is taking care of it */
+ reg = readl(pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
+ reg |= PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP;
+ writel(reg, pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
+ }
return 0;
}
int armada_370_xp_pmsu_idle_enter(unsigned long deepidle)
{
+ unsigned long flags = PMSU_PREPARE_SNOOP_DISABLE;
int ret;
- ret = mvebu_v7_pmsu_idle_prepare(deepidle);
+ if (deepidle)
+ flags |= PMSU_PREPARE_DEEP_IDLE;
+
+ ret = mvebu_v7_pmsu_idle_prepare(flags);
if (ret)
return ret;