diff mbox

[v3,08/14] ARM: mvebu: Allow to power down L2 cache controller in idle mode

Message ID 1381759106-15004-9-git-send-email-gregory.clement@free-electrons.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Gregory CLEMENT Oct. 14, 2013, 1:58 p.m. UTC
This commit adds an exported function which allows to power down the
L2 cache controller and the Coherency Fabric when the CPU goes into
deep idle mode.

This feature is part of the Power Management Service Unit of the
Armada 370 and Armada XP SoCs.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c         | 14 ++++++++++++++
 include/linux/armada-370-xp-pmsu.h | 16 ++++++++++++++++
 2 files changed, 30 insertions(+)
 create mode 100644 include/linux/armada-370-xp-pmsu.h

Comments

Thomas Petazzoni Oct. 14, 2013, 2:44 p.m. UTC | #1
Dear Gregory CLEMENT,

On Mon, 14 Oct 2013 15:58:20 +0200, Gregory CLEMENT wrote:
> This commit adds an exported function which allows to power down the
> L2 cache controller and the Coherency Fabric when the CPU goes into
> deep idle mode.

This comment is slightly misleading I believe: it explains that this
function should be called every time you want to power down the L2
cache and the coherency fabric. However, looking at the cpuidle driver
code, it seems that this function only ever gets called in the
->probe() function, and what it really does is that it adjusts the PMSU
configuration to automatically power down the L2 and coherency fabric
when we enter a certain idle state.

> This feature is part of the Power Management Service Unit of the
> Armada 370 and Armada XP SoCs.
> 
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
>  arch/arm/mach-mvebu/pmsu.c         | 14 ++++++++++++++
>  include/linux/armada-370-xp-pmsu.h | 16 ++++++++++++++++
>  2 files changed, 30 insertions(+)
>  create mode 100644 include/linux/armada-370-xp-pmsu.h
> 
> diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
> index f6b00fb..445c9a0 100644
> --- a/arch/arm/mach-mvebu/pmsu.c
> +++ b/arch/arm/mach-mvebu/pmsu.c
> @@ -30,6 +30,9 @@ static void __iomem *pmsu_fabric_base;
>  #define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu)	((cpu * 0x100) + 0x24)
>  #define PMSU_RESET_CTL_OFFSET(cpu)		(cpu * 0x8)
>  
> +#define L2C_NFABRIC_PM_CTL		    0x4
> +#define L2C_NFABRIC_PM_CTL_PWR_DOWN	    BIT(20)
> +
>  static struct of_device_id of_pmsu_table[] = {
>  	{.compatible = "marvell,armada-370-xp-pmsu"},
>  	{ /* end of list */ },
> @@ -78,4 +81,15 @@ int __init armada_370_xp_pmsu_init(void)
>  	return 0;
>  }
>  
> +void armada_370_xp_pmsu_enable_l2_powerdown_onidle(void)
> +{
> +	int reg;

u32 ?

> +
> +	/* Enable L2 & Fabric powerdown in Deep-Idle mode - Fabric */
> +	reg = readl(pmsu_fabric_base + L2C_NFABRIC_PM_CTL);
> +	reg |= L2C_NFABRIC_PM_CTL_PWR_DOWN;
> +	writel(reg, pmsu_fabric_base + L2C_NFABRIC_PM_CTL);
> +}
> +EXPORT_SYMBOL_GPL(armada_370_xp_pmsu_enable_l2_powerdown_onidle);

We don't need to have thiS EXPORT_SYMBOL_GPL. The cpuidle driver has a
'bool' Kconfig option, so it will also be built into the kernel and
never be built as a module.

I am also wondering if it is really useful to expose this function. If
it's just called at initialization, why not do it in the mach-mvebu
code directly, before registering the cpuidle driver? (I'm not sure
about this one, just proposing, it makes one less SoC-specific function
exposed to the world).

Best regards,

Thomas
diff mbox

Patch

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index f6b00fb..445c9a0 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -30,6 +30,9 @@  static void __iomem *pmsu_fabric_base;
 #define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu)	((cpu * 0x100) + 0x24)
 #define PMSU_RESET_CTL_OFFSET(cpu)		(cpu * 0x8)
 
+#define L2C_NFABRIC_PM_CTL		    0x4
+#define L2C_NFABRIC_PM_CTL_PWR_DOWN	    BIT(20)
+
 static struct of_device_id of_pmsu_table[] = {
 	{.compatible = "marvell,armada-370-xp-pmsu"},
 	{ /* end of list */ },
@@ -78,4 +81,15 @@  int __init armada_370_xp_pmsu_init(void)
 	return 0;
 }
 
+void armada_370_xp_pmsu_enable_l2_powerdown_onidle(void)
+{
+	int reg;
+
+	/* Enable L2 & Fabric powerdown in Deep-Idle mode - Fabric */
+	reg = readl(pmsu_fabric_base + L2C_NFABRIC_PM_CTL);
+	reg |= L2C_NFABRIC_PM_CTL_PWR_DOWN;
+	writel(reg, pmsu_fabric_base + L2C_NFABRIC_PM_CTL);
+}
+EXPORT_SYMBOL_GPL(armada_370_xp_pmsu_enable_l2_powerdown_onidle);
+
 early_initcall(armada_370_xp_pmsu_init);
diff --git a/include/linux/armada-370-xp-pmsu.h b/include/linux/armada-370-xp-pmsu.h
new file mode 100644
index 0000000..f85cbf7
--- /dev/null
+++ b/include/linux/armada-370-xp-pmsu.h
@@ -0,0 +1,16 @@ 
+/*
+ * Power Management Service Unit (PMSU) support for Armada 370/XP platforms.
+ *
+ * Copyright (C) 2013 Marvell
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ARMADA_370_XP__PMSU_H
+#define __ARMADA_370_XP__PMSU_H
+
+void armada_370_xp_pmsu_enable_l2_powerdown_onidle(void);
+
+#endif	/* __ARMADA_370_XP__PMSU_H */