From: Gregory CLEMENT <gregory.clement@free-electrons.com>
To: Daniel Lezcano <daniel.lezcano@linaro.org>,
"Rafael J. Wysocki" <rjw@rjwysocki.net>,
linux-pm@vger.kernel.org, Jason Cooper <jason@lakedaemon.net>,
Andrew Lunn <andrew@lunn.ch>,
Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>,
Gregory CLEMENT <gregory.clement@free-electrons.com>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>,
Ezequiel Garcia <ezequiel.garcia@free-electrons.com>,
linux-arm-kernel@lists.infradead.org,
Lior Amsalem <alior@marvell.com>,
Tawfik Bayouk <tawfik@marvell.com>,
Nadav Haklai <nadavh@marvell.com>
Subject: [PATCH 15/16] ARM: mvebu: Add CPU idle support for Armada 38x
Date: Fri, 27 Jun 2014 15:22:56 +0200 [thread overview]
Message-ID: <1403875377-940-16-git-send-email-gregory.clement@free-electrons.com> (raw)
In-Reply-To: <1403875377-940-1-git-send-email-gregory.clement@free-electrons.com>
Unlike the Armada XP and the Armada 370, this SoC uses a Cortex A9
core. Beside this, the main difference for the cpu idle is the way to
handle the L2 cache and the use of SCU.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/mach-mvebu/pmsu.c | 101 +++++++++++++++++++++++++++++++++++++++++-
arch/arm/mach-mvebu/pmsu_ll.S | 14 ++++++
2 files changed, 113 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index bfd471538811..3e49fb73c3d5 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -32,6 +32,7 @@
#include <asm/cacheflush.h>
#include <asm/cpuidle.h>
#include <asm/cp15.h>
+#include <asm/smp_scu.h>
#include <asm/smp_plat.h>
#include <asm/suspend.h>
#include <asm/tlbflush.h>
@@ -66,6 +67,19 @@
#define L2C_NFABRIC_PM_CTL 0x4
#define L2C_NFABRIC_PM_CTL_PWR_DOWN BIT(20)
+/* PMSU delay registers */
+#define PMSU_POWERDOWN_DELAY 0xF04
+#define PMSU_POWERDOWN_DELAY_PMU BIT(1)
+#define PMSU_POWERDOWN_DELAY_MASK 0xFFFE
+
+#define PMSU_DFLT_ARMADA38X_DELAY 0x64
+
+/* CA9 MPcore SoC Control registers */
+
+#define MPCORE_RESET_CTL 0x64
+#define MPCORE_RESET_CTL_L2 BIT(0)
+#define MPCORE_RESET_CTL_DEBUG BIT(16)
+
#define ARMADA_370_CRYPT0_ENG_ID 0x9
#define CRYPT0_ENG_ATTR 0x1
@@ -78,10 +92,13 @@ extern void ll_disable_coherency(void);
extern void ll_enable_coherency(void);
extern void armada_370_xp_cpu_resume(void);
+extern void armada_38x_cpu_resume(void);
static unsigned long pmsu_mp_phys_base;
static void __iomem *pmsu_mp_base;
+static void __iomem *scu_base;
+
static void *mvebu_cpu_resume;
static struct platform_device mvebu_v7_cpuidle_device = {
@@ -151,6 +168,7 @@ static int __init mvebu_v7_pmsu_init(void)
np->full_name)) {
pr_err("unable to request region\n");
ret = -EBUSY;
+
goto out;
}
@@ -163,7 +181,6 @@ static int __init mvebu_v7_pmsu_init(void)
ret = -ENOMEM;
goto out;
}
-
out:
of_node_put(np);
return ret;
@@ -260,6 +277,27 @@ static int armada_xp_370_cpu_suspend(unsigned long deepidle)
return cpu_suspend(deepidle, do_armada_xp_370_cpu_suspend);
}
+static noinline int do_armada_38x_cpu_suspend(unsigned long deepidle)
+{
+ mvebu_v7_pmsu_idle_prepare(deepidle, false);
+ /*
+ * Already flushed cache, but do it again as the outer cache
+ * functions dirty the cache with spinlocks
+ */
+ v7_exit_coherency_flush(louis);
+
+ scu_power_mode(scu_base, SCU_PM_POWEROFF);
+
+ cpu_do_idle();
+
+ return 1;
+}
+
+static int armada_38x_cpu_suspend(unsigned long deepidle)
+{
+ return cpu_suspend(false, do_armada_38x_cpu_suspend);
+}
+
/* No locking is needed because we only access per-CPU registers */
static noinline void mvebu_v7_pmsu_idle_restore(void)
{
@@ -268,7 +306,6 @@ static noinline void mvebu_v7_pmsu_idle_restore(void)
if (pmsu_mp_base == NULL)
return;
-
/* cancel ask HW to power down the L2 Cache if possible */
reg = readl(pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(hw_cpu));
reg &= ~PMSU_CONTROL_AND_CONFIG_L2_PWDDN;
@@ -320,6 +357,23 @@ static struct mvebu_v7_cpuidle armada_370_cpuidle = {
.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
};
+static struct mvebu_v7_cpuidle armada_38x_cpuidle = {
+ .mvebu_v7_idle_driver = {
+ .name = "armada_38x_idle",
+ .states[0] = ARM_CPUIDLE_WFI_STATE,
+ .states[1] = {
+ .exit_latency = 10,
+ .power_usage = 5,
+ .target_residency = 100,
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .name = "Idle",
+ .desc = "CPU and SCU power down",
+ },
+ .state_count = 2,
+ },
+ .mvebu_v7_cpu_suspend = armada_38x_cpu_suspend,
+};
+
static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
.mvebu_v7_idle_driver = {
.name = "armada_xp_idle",
@@ -371,6 +425,46 @@ static __init bool armada_370_cpuidle_init(void)
return true;
}
+static __init bool armada_38x_cpuidle_init(void)
+{
+ struct device_node *np;
+ void __iomem *mpsoc_base;
+ u32 reg;
+
+ np = of_find_compatible_node(NULL, NULL,
+ "marvell,armada-380-coherency-fabric");
+ if (!np)
+ return false;
+ of_node_put(np);
+
+ np = of_find_compatible_node(NULL, NULL,
+ "marvell,armada-380-mpcore-soc-ctrl");
+ if (!np)
+ return false;
+ mpsoc_base = of_iomap(np, 0);
+ WARN_ON(!mpsoc_base);
+
+ /* Set up reset mask when powering down the cpus */
+ reg = readl(mpsoc_base + MPCORE_RESET_CTL);
+ reg |= MPCORE_RESET_CTL_L2;
+ reg |= MPCORE_RESET_CTL_DEBUG;
+ writel(reg, mpsoc_base + MPCORE_RESET_CTL);
+ iounmap(mpsoc_base);
+ of_node_put(np);
+
+ /* Set up delay */
+ reg = readl(pmsu_mp_base + PMSU_POWERDOWN_DELAY);
+ reg &= ~PMSU_POWERDOWN_DELAY_MASK;
+ reg |= PMSU_DFLT_ARMADA38X_DELAY;
+ reg |= PMSU_POWERDOWN_DELAY_PMU;
+ writel(reg, pmsu_mp_base + PMSU_POWERDOWN_DELAY);
+
+ scu_base = mvebu_get_scu_base();
+ mvebu_cpu_resume = armada_38x_cpu_resume;
+ mvebu_v7_cpuidle_device.dev.platform_data = &armada_38x_cpuidle;
+ return true;
+}
+
static __init bool armada_xp_cpuidle_init(void)
{
struct device_node *np;
@@ -391,6 +485,9 @@ static struct of_device_id of_cpuidle_table[] __initdata = {
{ .compatible = "marvell,armada370",
.data = (void *)armada_370_cpuidle_init,
},
+ { .compatible = "marvell,armada380",
+ .data = (void *)armada_38x_cpuidle_init,
+ },
{ /* end of list */ },
};
diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
index 3b702a16bd3d..15b823dff61a 100644
--- a/arch/arm/mach-mvebu/pmsu_ll.S
+++ b/arch/arm/mach-mvebu/pmsu_ll.S
@@ -23,6 +23,20 @@ ARM_BE8(setend be ) @ go BE8 if entered LE
b cpu_resume
ENDPROC(armada_370_xp_cpu_resume)
+ENTRY(armada_38x_cpu_resume)
+ /* do we need it for Armada 38x*/
+ARM_BE8(setend be ) @ go BE8 if entered LE
+ bl v7_invalidate_l1
+ mrc p15, 4, r1, c15, c0 @ get SCU base address
+ orr r1, r1, #0x8 @ SCU CPU Power Status Register
+ mrc 15, 0, r0, cr0, cr0, 5 @ get the CPU ID
+ and r0, r0, #15
+ add r1, r1, r0
+ mov r0, #0x0
+ strb r0, [r1] @ switch SCU power state to Normal mode
+ b cpu_resume
+ENDPROC(armada_38x_cpu_resume)
+
.global mvebu_boot_wa_start
.global mvebu_boot_wa_end
--
1.8.1.2
next prev parent reply other threads:[~2014-06-27 13:24 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-27 13:22 [PATCH 00/16] CPU Idle for Armada 370 and Armada 38x Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 01/16] ARM: mvebu: Sort the headers of pmsu.c in alphabetic order Gregory CLEMENT
2014-06-30 12:16 ` Thomas Petazzoni
2014-07-02 22:57 ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 02/16] ARM: mvebu: Add a common function for the boot address work around Gregory CLEMENT
2014-06-30 12:40 ` Thomas Petazzoni
2014-07-02 22:58 ` Gregory CLEMENT
2014-07-03 7:16 ` Thomas Petazzoni
2014-07-01 14:34 ` Thomas Petazzoni
2014-07-02 22:58 ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register Gregory CLEMENT
2014-06-27 14:14 ` Gregory CLEMENT
2014-06-30 12:46 ` Thomas Petazzoni
2014-07-03 8:39 ` Gregory CLEMENT
2014-07-03 9:25 ` Thomas Petazzoni
2014-07-03 10:07 ` Gregory CLEMENT
2014-07-01 11:46 ` Thomas Petazzoni
2014-07-01 15:02 ` Ezequiel Garcia
2014-06-27 13:22 ` [PATCH 04/16] ARM: mvebu: Use the common function for Armada 375 SMP workaround Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 05/16] ARM: mvebu: Add workaround for cpuidle support for Armada 370 Gregory CLEMENT
2014-06-30 12:50 ` Thomas Petazzoni
2014-07-03 8:44 ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 06/16] ARM: mvebu: Rename the armada_370_xp into mvebu_v7 in pmsu.c file Gregory CLEMENT
2014-06-30 12:57 ` Thomas Petazzoni
2014-07-03 8:47 ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 07/16] ARM: mvebu: Make the CPU idle initialization more generic Gregory CLEMENT
2014-06-27 14:15 ` Gregory CLEMENT
2014-06-28 14:56 ` Jason Cooper
2014-06-30 10:30 ` Gregory CLEMENT
2014-06-30 14:07 ` Thomas Petazzoni
2014-07-03 8:54 ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 08/16] ARM: mvebu: Use a local variable to store the resume address Gregory CLEMENT
2014-06-30 15:09 ` Thomas Petazzoni
2014-07-03 9:24 ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 09/16] ARM: mvebu: Make the snoop disable optional in mvebu_v7_pmsu_idle_prepare Gregory CLEMENT
2014-06-30 15:43 ` Thomas Petazzoni
2014-07-03 12:50 ` Gregory CLEMENT
2014-07-03 12:55 ` Thomas Petazzoni
2014-06-27 13:22 ` [PATCH 10/16] ARM: mvebu: Export the SCU address Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 11/16] ARM: mvebu: dts: Add CA9 MPcore SoC Controller node Gregory CLEMENT
2014-06-30 15:37 ` Thomas Petazzoni
2014-07-03 12:51 ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 12/16] cpuidle: mvebu: Rename the driver from armada-370-xp to mvebu-v7 Gregory CLEMENT
2014-06-30 13:28 ` Thomas Petazzoni
2014-07-03 13:08 ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 13/16] cpuidle: mvebu: Move the description of the cpuidle states in the platform part Gregory CLEMENT
2014-06-30 13:32 ` Thomas Petazzoni
2014-07-03 13:23 ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 14/16] ARM: mvebu: Add CPU idle support for Armada 370 Gregory CLEMENT
2014-06-30 13:36 ` Thomas Petazzoni
2014-07-03 15:03 ` Gregory CLEMENT
2014-06-27 13:22 ` Gregory CLEMENT [this message]
2014-06-30 15:07 ` [PATCH 15/16] ARM: mvebu: Add CPU idle support for Armada 38x Thomas Petazzoni
2014-07-03 15:29 ` Gregory CLEMENT
2014-07-01 14:35 ` Thomas Petazzoni
2014-07-03 15:09 ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 16/16] ARM: mvebu: defconfig: Enable CPU Idle support in mvebu_v7_defconfig Gregory CLEMENT
2014-06-30 15:45 ` [PATCH 00/16] CPU Idle for Armada 370 and Armada 38x Thomas Petazzoni
2014-06-30 15:51 ` Gregory CLEMENT
2014-07-01 14:38 ` Thomas Petazzoni
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1403875377-940-16-git-send-email-gregory.clement@free-electrons.com \
--to=gregory.clement@free-electrons.com \
--cc=alior@marvell.com \
--cc=andrew@lunn.ch \
--cc=daniel.lezcano@linaro.org \
--cc=ezequiel.garcia@free-electrons.com \
--cc=jason@lakedaemon.net \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-pm@vger.kernel.org \
--cc=nadavh@marvell.com \
--cc=rjw@rjwysocki.net \
--cc=sebastian.hesselbarth@gmail.com \
--cc=tawfik@marvell.com \
--cc=thomas.petazzoni@free-electrons.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox