All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/44] outer cache changes
@ 2014-03-17  0:13 Russell King - ARM Linux
  2014-03-17  0:13 ` [PATCH 01/44] ARM: l2c: remove outer_inv_all() method Russell King
                   ` (45 more replies)
  0 siblings, 46 replies; 52+ messages in thread
From: Russell King - ARM Linux @ 2014-03-17  0:13 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series is where I'm currently at with the total mess which
is L2 cache support.  That's putting it mildly.  This isn't intended
for anyone to pick up - this is still mostly in development.

I need help with the Aurora/Tauros3/Broadcom stuff, as that remains
addicted to the old buggy code that we used to have (eg, if you build
a v6+v7 kernel, all PL310 errata get disabled.  If CONFIG_CACHE_PL310
is enabled and you actually have a L2C-220, the necessary waits will
be omitted.  If you enable erratum 588369 and set the .set_debug
method to NULL or have a PL310 later than R3P0, you're opening a
race condition. etc.)

One of the potentially explosive issues is the utter crap and fscked
state of DT implementation here, much of which /can't/ now be fixed
without breaking existing DT based booting with existing files,
because we have a mixture of DT properties combined with platform
specific code setting various L2C configuration parameters (sometimes
writing directly to the registers.)

For example, I've made a start at trying to prevent any further additions
of platform code writing to the L2C-310's power control register by
adding a couple of properties - but we can't delete the direct register
write in iMX6 code without breaking existing DT descriptions.

The same goes for the mess which is the auxillary control register,
or now the prefetch control register.  Or the erratum 752271 which
iMX6 implements in their own SoC specific code.

Here's the *big* explosive question: how have we ended up in this mess?
A bigger question: why was none of this caught at review time?  An even
bigger question (which I believe is at the root of much of the pain that
people feel with DT): why aren't device properties being thought out
better - by that I mean, why isn't the question "are the properties you
are proposing for device X sufficient to describe all it's configurable
parameters, and if not, what are you omitting?" being asked when new
device bindings are being proposed.

You can see the extent of the L2C crap from the diffstat below - every
arch/arm/mach-* file touched here is a symptom of failing to adequately
describe the properties that platforms need to specify.  It's a failing
of DT process.  It's a failing of review of SoC code.

Anyway, here's the diffstat so far.  Not Cc'ing anyone this time around
(the Cc list is huge), so it's all on LAKML.

 Documentation/devicetree/bindings/arm/l2cc.txt |    2 +
 arch/arm/Kconfig                               |   51 -
 arch/arm/boot/dts/imx6qdl.dtsi                 |    2 +
 arch/arm/boot/dts/imx6sl.dtsi                  |    2 +
 arch/arm/include/asm/hardware/cache-l2x0.h     |   63 +-
 arch/arm/include/asm/outercache.h              |   67 +-
 arch/arm/mach-cns3xxx/core.c                   |    8 +-
 arch/arm/mach-highbank/highbank.c              |   12 +-
 arch/arm/mach-imx/system.c                     |    8 +-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c      |    2 +-
 arch/arm/mach-omap2/omap4-common.c             |   58 +-
 arch/arm/mach-prima2/l2x0.c                    |    5 +-
 arch/arm/mach-prima2/pm.c                      |    1 -
 arch/arm/mach-realview/realview_pbx.c          |    4 +-
 arch/arm/mach-spear/platsmp.c                  |   19 +-
 arch/arm/mach-spear/spear13xx.c                |    6 +-
 arch/arm/mach-sti/board-dt.c                   |    8 +-
 arch/arm/mach-tegra/sleep.h                    |    8 +-
 arch/arm/mach-ux500/cache-l2x0.c               |   23 +-
 arch/arm/mach-vexpress/ct-ca9x4.c              |    4 +-
 arch/arm/mm/Kconfig                            |   51 +
 arch/arm/mm/Makefile                           |    1 +
 arch/arm/mm/cache-feroceon-l2.c                |    1 -
 arch/arm/mm/cache-l2x0.c                       | 1354 +++++++++++++++++-------
 arch/arm/mm/l2c-common.c                       |   20 +
 arch/arm/plat-samsung/s5p-sleep.S              |    8 +-
 26 files changed, 1221 insertions(+), 567 deletions(-)

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 01/44] ARM: l2c: remove outer_inv_all() method
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
@ 2014-03-17  0:13 ` Russell King
  2014-03-17  0:13 ` [PATCH 02/44] ARM: l2c: remove unnecessary call to outer_flush_all() Russell King
                   ` (44 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:13 UTC (permalink / raw)
  To: linux-arm-kernel

No one ever calls this function anywhere in the kernel, so let's
completely remove it from the outer cache API and turn it into an
internal-only thing.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/outercache.h | 8 --------
 arch/arm/mm/cache-feroceon-l2.c   | 1 -
 arch/arm/mm/cache-l2x0.c          | 5 -----
 3 files changed, 14 deletions(-)

diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
index f94784f0e3a6..0e4420858990 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -28,7 +28,6 @@ struct outer_cache_fns {
 	void (*clean_range)(unsigned long, unsigned long);
 	void (*flush_range)(unsigned long, unsigned long);
 	void (*flush_all)(void);
-	void (*inv_all)(void);
 	void (*disable)(void);
 #ifdef CONFIG_OUTER_CACHE_SYNC
 	void (*sync)(void);
@@ -63,12 +62,6 @@ static inline void outer_flush_all(void)
 		outer_cache.flush_all();
 }
 
-static inline void outer_inv_all(void)
-{
-	if (outer_cache.inv_all)
-		outer_cache.inv_all();
-}
-
 static inline void outer_disable(void)
 {
 	if (outer_cache.disable)
@@ -90,7 +83,6 @@ static inline void outer_clean_range(phys_addr_t start, phys_addr_t end)
 static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
 { }
 static inline void outer_flush_all(void) { }
-static inline void outer_inv_all(void) { }
 static inline void outer_disable(void) { }
 static inline void outer_resume(void) { }
 
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
index aae891820f8f..901a0f7280dc 100644
--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -345,7 +345,6 @@ void __init feroceon_l2_init(int __l2_wt_override)
 	outer_cache.inv_range = feroceon_l2_inv_range;
 	outer_cache.clean_range = feroceon_l2_clean_range;
 	outer_cache.flush_range = feroceon_l2_flush_range;
-	outer_cache.inv_all = l2_inv_all;
 
 	enable_l2();
 
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 7abde2ce8973..f9985e5a208c 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -414,7 +414,6 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 		outer_cache.flush_range = l2x0_flush_range;
 		outer_cache.sync = l2x0_cache_sync;
 		outer_cache.flush_all = l2x0_flush_all;
-		outer_cache.inv_all = l2x0_inv_all;
 		outer_cache.disable = l2x0_disable;
 	}
 
@@ -884,7 +883,6 @@ static const struct l2x0_of_data pl310_data = {
 		.flush_range = l2x0_flush_range,
 		.sync        = l2x0_cache_sync,
 		.flush_all   = l2x0_flush_all,
-		.inv_all     = l2x0_inv_all,
 		.disable     = l2x0_disable,
 	},
 };
@@ -899,7 +897,6 @@ static const struct l2x0_of_data l2x0_data = {
 		.flush_range = l2x0_flush_range,
 		.sync        = l2x0_cache_sync,
 		.flush_all   = l2x0_flush_all,
-		.inv_all     = l2x0_inv_all,
 		.disable     = l2x0_disable,
 	},
 };
@@ -914,7 +911,6 @@ static const struct l2x0_of_data aurora_with_outer_data = {
 		.flush_range = aurora_flush_range,
 		.sync        = l2x0_cache_sync,
 		.flush_all   = l2x0_flush_all,
-		.inv_all     = l2x0_inv_all,
 		.disable     = l2x0_disable,
 	},
 };
@@ -946,7 +942,6 @@ static const struct l2x0_of_data bcm_l2x0_data = {
 		.flush_range = bcm_flush_range,
 		.sync        = l2x0_cache_sync,
 		.flush_all   = l2x0_flush_all,
-		.inv_all     = l2x0_inv_all,
 		.disable     = l2x0_disable,
 	},
 };
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 02/44] ARM: l2c: remove unnecessary call to outer_flush_all()
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
  2014-03-17  0:13 ` [PATCH 01/44] ARM: l2c: remove outer_inv_all() method Russell King
@ 2014-03-17  0:13 ` Russell King
  2014-03-17  0:13 ` [PATCH 03/44] ARM: l2c: avoid calling outer_flush_all() unnecessarily (Spear) Russell King
                   ` (43 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:13 UTC (permalink / raw)
  To: linux-arm-kernel

outer_disable() is defined to safely turn the L2 cache off without data
loss: this means that outer_flush_all() should never be called unless
you need to implement some special L2 cache disabling, and even then
only from your replacement L2 cache disable function.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mach-prima2/pm.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-prima2/pm.c b/arch/arm/mach-prima2/pm.c
index c4525a88e5da..96e9bc102117 100644
--- a/arch/arm/mach-prima2/pm.c
+++ b/arch/arm/mach-prima2/pm.c
@@ -71,7 +71,6 @@ static int sirfsoc_pm_enter(suspend_state_t state)
 	case PM_SUSPEND_MEM:
 		sirfsoc_pre_suspend_power_off();
 
-		outer_flush_all();
 		outer_disable();
 		/* go zzz */
 		cpu_suspend(0, sirfsoc_finish_suspend);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 03/44] ARM: l2c: avoid calling outer_flush_all() unnecessarily (Spear)
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
  2014-03-17  0:13 ` [PATCH 01/44] ARM: l2c: remove outer_inv_all() method Russell King
  2014-03-17  0:13 ` [PATCH 02/44] ARM: l2c: remove unnecessary call to outer_flush_all() Russell King
@ 2014-03-17  0:13 ` Russell King
  2014-03-17  0:13 ` [PATCH 04/44] ARM: l2c: add helper for L2 cache controller DT IDs Russell King
                   ` (42 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:13 UTC (permalink / raw)
  To: linux-arm-kernel

Spear calls outer_flush_all() from it's SMP bringup function.  This
is potentially dangerous as the L2C set/way operations which implement
this don't take kindly to concurrent operations.  Besides, there's
better solutions to this, as implemented on other platforms.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mach-spear/platsmp.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-spear/platsmp.c b/arch/arm/mach-spear/platsmp.c
index 5c4a19887b2b..eb9f2ef1e974 100644
--- a/arch/arm/mach-spear/platsmp.c
+++ b/arch/arm/mach-spear/platsmp.c
@@ -20,6 +20,18 @@
 #include <mach/spear.h>
 #include "generic.h"
 
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not.  This is necessary for the hotplug code to work reliably.
+ */
+static void write_pen_release(int val)
+{
+	pen_release = val;
+	smp_wmb();
+	sync_cache_w(&pen_release);
+}
+
 static DEFINE_SPINLOCK(boot_lock);
 
 static void __iomem *scu_base = IOMEM(VA_SCU_BASE);
@@ -30,8 +42,7 @@ static void spear13xx_secondary_init(unsigned int cpu)
 	 * let the primary processor know we're out of the
 	 * pen, then head off into the C entry point
 	 */
-	pen_release = -1;
-	smp_wmb();
+	write_pen_release(-1);
 
 	/*
 	 * Synchronise with the boot thread.
@@ -58,9 +69,7 @@ static int spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle)
 	 * Note that "pen_release" is the hardware CPU ID, whereas
 	 * "cpu" is Linux's internal ID.
 	 */
-	pen_release = cpu;
-	flush_cache_all();
-	outer_flush_all();
+	write_pen_release(cpu);
 
 	timeout = jiffies + (1 * HZ);
 	while (time_before(jiffies, timeout)) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 04/44] ARM: l2c: add helper for L2 cache controller DT IDs
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (2 preceding siblings ...)
  2014-03-17  0:13 ` [PATCH 03/44] ARM: l2c: avoid calling outer_flush_all() unnecessarily (Spear) Russell King
@ 2014-03-17  0:13 ` Russell King
  2014-03-26 20:30   ` Rob Herring
  2014-03-17  0:13 ` [PATCH 05/44] ARM: l2c: tidy up l2x0_of_data declarations Russell King
                   ` (41 subsequent siblings)
  45 siblings, 1 reply; 52+ messages in thread
From: Russell King @ 2014-03-17  0:13 UTC (permalink / raw)
  To: linux-arm-kernel

Make it easier to declare L2 cache controller DT IDs by using a macro.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index f9985e5a208c..ac410b21edfb 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -946,20 +946,17 @@ static const struct l2x0_of_data bcm_l2x0_data = {
 	},
 };
 
+#define L2C_ID(name, fns) { .compatible = name, .data = (void *)&fns }
 static const struct of_device_id l2x0_ids[] __initconst = {
-	{ .compatible = "arm,l210-cache", .data = (void *)&l2x0_data },
-	{ .compatible = "arm,l220-cache", .data = (void *)&l2x0_data },
-	{ .compatible = "arm,pl310-cache", .data = (void *)&pl310_data },
-	{ .compatible = "bcm,bcm11351-a2-pl310-cache", /* deprecated name */
-	  .data = (void *)&bcm_l2x0_data},
-	{ .compatible = "brcm,bcm11351-a2-pl310-cache",
-	  .data = (void *)&bcm_l2x0_data},
-	{ .compatible = "marvell,aurora-outer-cache",
-	  .data = (void *)&aurora_with_outer_data},
-	{ .compatible = "marvell,aurora-system-cache",
-	  .data = (void *)&aurora_no_outer_data},
-	{ .compatible = "marvell,tauros3-cache",
-	  .data = (void *)&tauros3_data },
+	L2C_ID("arm,l210-cache", l2x0_data),
+	L2C_ID("arm,l220-cache", l2x0_data),
+	L2C_ID("arm,pl310-cache", pl310_data),
+	L2C_ID("brcm,bcm11351-a2-pl310-cache", bcm_l2x0_data),
+	L2C_ID("marvell,aurora-outer-cache", aurora_with_outer_data),
+	L2C_ID("marvell,aurora-system-cache", aurora_no_outer_data),
+	L2C_ID("marvell,tauros3-cache", tauros3_data),
+	/* Deprecated IDs */
+	L2C_ID("bcm,bcm11351-a2-pl310-cache", bcm_l2x0_data),
 	{}
 };
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 05/44] ARM: l2c: tidy up l2x0_of_data declarations
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (3 preceding siblings ...)
  2014-03-17  0:13 ` [PATCH 04/44] ARM: l2c: add helper for L2 cache controller DT IDs Russell King
@ 2014-03-17  0:13 ` Russell King
  2014-03-17  0:14 ` [PATCH 06/44] ARM: l2c: rename OF specific things, making l2x0_of_data available to all Russell King
                   ` (40 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:13 UTC (permalink / raw)
  To: linux-arm-kernel

Remove NULL initialisers, make these all __initconst structures, and
order their members in the same order as the structure declaration.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index ac410b21edfb..063e1787e8c3 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -873,49 +873,48 @@ static void __init aurora_of_setup(const struct device_node *np,
 	*aux_mask &= ~mask;
 }
 
-static const struct l2x0_of_data pl310_data = {
+static const struct l2x0_of_data pl310_data __initconst = {
 	.setup = pl310_of_setup,
 	.save  = pl310_save,
 	.outer_cache = {
-		.resume      = pl310_resume,
 		.inv_range   = l2x0_inv_range,
 		.clean_range = l2x0_clean_range,
 		.flush_range = l2x0_flush_range,
-		.sync        = l2x0_cache_sync,
 		.flush_all   = l2x0_flush_all,
 		.disable     = l2x0_disable,
+		.sync        = l2x0_cache_sync,
+		.resume      = pl310_resume,
 	},
 };
 
-static const struct l2x0_of_data l2x0_data = {
+static const struct l2x0_of_data l2x0_data __initconst = {
 	.setup = l2x0_of_setup,
-	.save  = NULL,
 	.outer_cache = {
-		.resume      = l2x0_resume,
 		.inv_range   = l2x0_inv_range,
 		.clean_range = l2x0_clean_range,
 		.flush_range = l2x0_flush_range,
-		.sync        = l2x0_cache_sync,
 		.flush_all   = l2x0_flush_all,
 		.disable     = l2x0_disable,
+		.sync        = l2x0_cache_sync,
+		.resume      = l2x0_resume,
 	},
 };
 
-static const struct l2x0_of_data aurora_with_outer_data = {
+static const struct l2x0_of_data aurora_with_outer_data __initconst = {
 	.setup = aurora_of_setup,
 	.save  = aurora_save,
 	.outer_cache = {
-		.resume      = aurora_resume,
 		.inv_range   = aurora_inv_range,
 		.clean_range = aurora_clean_range,
 		.flush_range = aurora_flush_range,
-		.sync        = l2x0_cache_sync,
 		.flush_all   = l2x0_flush_all,
 		.disable     = l2x0_disable,
+		.sync        = l2x0_cache_sync,
+		.resume      = aurora_resume,
 	},
 };
 
-static const struct l2x0_of_data aurora_no_outer_data = {
+static const struct l2x0_of_data aurora_no_outer_data __initconst = {
 	.setup = aurora_of_setup,
 	.save  = aurora_save,
 	.outer_cache = {
@@ -923,8 +922,7 @@ static const struct l2x0_of_data aurora_no_outer_data = {
 	},
 };
 
-static const struct l2x0_of_data tauros3_data = {
-	.setup = NULL,
+static const struct l2x0_of_data tauros3_data __initconst = {
 	.save  = tauros3_save,
 	/* Tauros3 broadcasts L1 cache operations to L2 */
 	.outer_cache = {
@@ -932,17 +930,17 @@ static const struct l2x0_of_data tauros3_data = {
 	},
 };
 
-static const struct l2x0_of_data bcm_l2x0_data = {
+static const struct l2x0_of_data bcm_l2x0_data __initconst = {
 	.setup = pl310_of_setup,
 	.save  = pl310_save,
 	.outer_cache = {
-		.resume      = pl310_resume,
 		.inv_range   = bcm_inv_range,
 		.clean_range = bcm_clean_range,
 		.flush_range = bcm_flush_range,
-		.sync        = l2x0_cache_sync,
 		.flush_all   = l2x0_flush_all,
 		.disable     = l2x0_disable,
+		.sync        = l2x0_cache_sync,
+		.resume      = pl310_resume,
 	},
 };
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 06/44] ARM: l2c: rename OF specific things, making l2x0_of_data available to all
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (4 preceding siblings ...)
  2014-03-17  0:13 ` [PATCH 05/44] ARM: l2c: tidy up l2x0_of_data declarations Russell King
@ 2014-03-17  0:14 ` Russell King
  2014-03-17  0:14 ` [PATCH 07/44] ARM: l2c: provide generic function for calling set_debug method Russell King
                   ` (39 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

Rename a few things to help distinguish their function(s):
 l2x0_of_data -> l2c_init_data
 setup -> of_parse
 add of_ prefix to OF specific data

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 64 ++++++++++++++++++++++++------------------------
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 063e1787e8c3..d659c4ca46bb 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -28,6 +28,12 @@
 #include "cache-tauros3.h"
 #include "cache-aurora-l2.h"
 
+struct l2c_init_data {
+	void (*of_parse)(const struct device_node *, u32 *, u32 *);
+	void (*save)(void);
+	struct outer_cache_fns outer_cache;
+};
+
 #define CACHE_LINE_SIZE		32
 
 static void __iomem *l2x0_base;
@@ -42,12 +48,6 @@ static u32  cache_id_part_number_from_dt;
 
 struct l2x0_regs l2x0_saved_regs;
 
-struct l2x0_of_data {
-	void (*setup)(const struct device_node *, u32 *, u32 *);
-	void (*save)(void);
-	struct outer_cache_fns outer_cache;
-};
-
 static bool of_init = false;
 
 static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
@@ -664,7 +664,7 @@ static void bcm_flush_range(unsigned long start, unsigned long end)
 		new_end);
 }
 
-static void __init l2x0_of_setup(const struct device_node *np,
+static void __init l2x0_of_parse(const struct device_node *np,
 				 u32 *aux_val, u32 *aux_mask)
 {
 	u32 data[2] = { 0, 0 };
@@ -698,7 +698,7 @@ static void __init l2x0_of_setup(const struct device_node *np,
 	*aux_mask &= ~mask;
 }
 
-static void __init pl310_of_setup(const struct device_node *np,
+static void __init pl310_of_parse(const struct device_node *np,
 				  u32 *aux_val, u32 *aux_mask)
 {
 	u32 data[3] = { 0, 0, 0 };
@@ -851,7 +851,7 @@ static void __init aurora_broadcast_l2_commands(void)
 	isb();
 }
 
-static void __init aurora_of_setup(const struct device_node *np,
+static void __init aurora_of_parse(const struct device_node *np,
 				u32 *aux_val, u32 *aux_mask)
 {
 	u32 val = AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU;
@@ -873,8 +873,8 @@ static void __init aurora_of_setup(const struct device_node *np,
 	*aux_mask &= ~mask;
 }
 
-static const struct l2x0_of_data pl310_data __initconst = {
-	.setup = pl310_of_setup,
+static const struct l2c_init_data of_pl310_data __initconst = {
+	.of_parse = pl310_of_parse,
 	.save  = pl310_save,
 	.outer_cache = {
 		.inv_range   = l2x0_inv_range,
@@ -887,8 +887,8 @@ static const struct l2x0_of_data pl310_data __initconst = {
 	},
 };
 
-static const struct l2x0_of_data l2x0_data __initconst = {
-	.setup = l2x0_of_setup,
+static const struct l2c_init_data of_l2x0_data __initconst = {
+	.of_parse = l2x0_of_parse,
 	.outer_cache = {
 		.inv_range   = l2x0_inv_range,
 		.clean_range = l2x0_clean_range,
@@ -900,8 +900,8 @@ static const struct l2x0_of_data l2x0_data __initconst = {
 	},
 };
 
-static const struct l2x0_of_data aurora_with_outer_data __initconst = {
-	.setup = aurora_of_setup,
+static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
+	.of_parse = aurora_of_parse,
 	.save  = aurora_save,
 	.outer_cache = {
 		.inv_range   = aurora_inv_range,
@@ -914,15 +914,15 @@ static const struct l2x0_of_data aurora_with_outer_data __initconst = {
 	},
 };
 
-static const struct l2x0_of_data aurora_no_outer_data __initconst = {
-	.setup = aurora_of_setup,
+static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
+	.of_parse = aurora_of_parse,
 	.save  = aurora_save,
 	.outer_cache = {
 		.resume      = aurora_resume,
 	},
 };
 
-static const struct l2x0_of_data tauros3_data __initconst = {
+static const struct l2c_init_data of_tauros3_data __initconst = {
 	.save  = tauros3_save,
 	/* Tauros3 broadcasts L1 cache operations to L2 */
 	.outer_cache = {
@@ -930,8 +930,8 @@ static const struct l2x0_of_data tauros3_data __initconst = {
 	},
 };
 
-static const struct l2x0_of_data bcm_l2x0_data __initconst = {
-	.setup = pl310_of_setup,
+static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
+	.of_parse = pl310_of_parse,
 	.save  = pl310_save,
 	.outer_cache = {
 		.inv_range   = bcm_inv_range,
@@ -946,22 +946,22 @@ static const struct l2x0_of_data bcm_l2x0_data __initconst = {
 
 #define L2C_ID(name, fns) { .compatible = name, .data = (void *)&fns }
 static const struct of_device_id l2x0_ids[] __initconst = {
-	L2C_ID("arm,l210-cache", l2x0_data),
-	L2C_ID("arm,l220-cache", l2x0_data),
-	L2C_ID("arm,pl310-cache", pl310_data),
-	L2C_ID("brcm,bcm11351-a2-pl310-cache", bcm_l2x0_data),
-	L2C_ID("marvell,aurora-outer-cache", aurora_with_outer_data),
-	L2C_ID("marvell,aurora-system-cache", aurora_no_outer_data),
-	L2C_ID("marvell,tauros3-cache", tauros3_data),
+	L2C_ID("arm,l210-cache", of_l2x0_data),
+	L2C_ID("arm,l220-cache", of_l2x0_data),
+	L2C_ID("arm,pl310-cache", of_pl310_data),
+	L2C_ID("brcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data),
+	L2C_ID("marvell,aurora-outer-cache", of_aurora_with_outer_data),
+	L2C_ID("marvell,aurora-system-cache", of_aurora_no_outer_data),
+	L2C_ID("marvell,tauros3-cache", of_tauros3_data),
 	/* Deprecated IDs */
-	L2C_ID("bcm,bcm11351-a2-pl310-cache", bcm_l2x0_data),
+	L2C_ID("bcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data),
 	{}
 };
 
 int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 {
+	const struct l2c_init_data *data;
 	struct device_node *np;
-	const struct l2x0_of_data *data;
 	struct resource res;
 
 	np = of_find_matching_node(NULL, l2x0_ids);
@@ -981,12 +981,12 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 
 	/* L2 configuration can only be changed if the cache is disabled */
 	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
-		if (data->setup)
-			data->setup(np, &aux_val, &aux_mask);
+		if (data->of_parse)
+			data->of_parse(np, &aux_val, &aux_mask);
 
 		/* For aurora cache in no outer mode select the
 		 * correct mode using the coprocessor*/
-		if (data == &aurora_no_outer_data)
+		if (data == &of_aurora_no_outer_data)
 			aurora_broadcast_l2_commands();
 	}
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 07/44] ARM: l2c: provide generic function for calling set_debug method
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (5 preceding siblings ...)
  2014-03-17  0:14 ` [PATCH 06/44] ARM: l2c: rename OF specific things, making l2x0_of_data available to all Russell King
@ 2014-03-17  0:14 ` Russell King
  2014-03-17  0:14 ` [PATCH 08/44] ARM: l2c: split out cache unlock code Russell King
                   ` (38 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

Provide a generic function which always calls the set_debug method.
This will be used later in the series as some work-arounds require
that the debug register be written.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index d659c4ca46bb..595c50519e41 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -57,6 +57,16 @@ static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
 		cpu_relax();
 }
 
+/*
+ * This should only be called when we have a requirement that the
+ * register be written due to a work-around, as platforms running
+ * in non-secure mode may not be able to access this register.
+ */
+static inline void l2c_set_debug(void __iomem *base, unsigned long val)
+{
+	outer_cache.set_debug(val);
+}
+
 #ifdef CONFIG_CACHE_PL310
 static inline void cache_wait(void __iomem *reg, unsigned long mask)
 {
@@ -92,7 +102,7 @@ static inline void l2x0_inv_line(unsigned long addr)
 static inline void debug_writel(unsigned long val)
 {
 	if (outer_cache.set_debug)
-		outer_cache.set_debug(val);
+		l2c_set_debug(l2x0_base, val);
 }
 
 static void pl310_set_debug(unsigned long val)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 08/44] ARM: l2c: split out cache unlock code
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (6 preceding siblings ...)
  2014-03-17  0:14 ` [PATCH 07/44] ARM: l2c: provide generic function for calling set_debug method Russell King
@ 2014-03-17  0:14 ` Russell King
  2014-03-17  0:14 ` [PATCH 09/44] ARM: l2c: provide generic helper for way-based operations Russell King
                   ` (37 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

Split the cache unlock code out of l2x0_unlock().  We want to be able
to re-use this functionality later.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 595c50519e41..a1313d20f205 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -50,6 +50,9 @@ struct l2x0_regs l2x0_saved_regs;
 
 static bool of_init = false;
 
+/*
+ * Common code for all cache controllers.
+ */
 static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
 {
 	/* wait for cache operation by line or way to complete */
@@ -67,6 +70,18 @@ static inline void l2c_set_debug(void __iomem *base, unsigned long val)
 	outer_cache.set_debug(val);
 }
 
+static inline void l2c_unlock(void __iomem *base, unsigned num)
+{
+	unsigned i;
+
+	for (i = 0; i < num; i++) {
+		writel_relaxed(0, base + L2X0_LOCKDOWN_WAY_D_BASE +
+			       i * L2X0_LOCKDOWN_STRIDE);
+		writel_relaxed(0, base + L2X0_LOCKDOWN_WAY_I_BASE +
+			       i * L2X0_LOCKDOWN_STRIDE);
+	}
+}
+
 #ifdef CONFIG_CACHE_PL310
 static inline void cache_wait(void __iomem *reg, unsigned long mask)
 {
@@ -308,7 +323,6 @@ static void l2x0_disable(void)
 static void l2x0_unlock(u32 cache_id)
 {
 	int lockregs;
-	int i;
 
 	switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
 	case L2X0_CACHE_ID_PART_L310:
@@ -323,12 +337,7 @@ static void l2x0_unlock(u32 cache_id)
 		break;
 	}
 
-	for (i = 0; i < lockregs; i++) {
-		writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE +
-			       i * L2X0_LOCKDOWN_STRIDE);
-		writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE +
-			       i * L2X0_LOCKDOWN_STRIDE);
-	}
+	l2c_unlock(l2x0_base, lockregs);
 }
 
 void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 09/44] ARM: l2c: provide generic helper for way-based operations
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (7 preceding siblings ...)
  2014-03-17  0:14 ` [PATCH 08/44] ARM: l2c: split out cache unlock code Russell King
@ 2014-03-17  0:14 ` Russell King
  2014-03-17  0:14 ` [PATCH 10/44] ARM: l2c: rename cache_wait_way() Russell King
                   ` (36 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

Provide a generic helper function for way based operations.  These are
always background operations, and thus have to be waited for before a
new operation is commenced.  This helper extracts that requirement from
several locations in the code.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index a1313d20f205..1c3a23318f53 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -70,6 +70,12 @@ static inline void l2c_set_debug(void __iomem *base, unsigned long val)
 	outer_cache.set_debug(val);
 }
 
+static void __l2c_op_way(void __iomem *reg)
+{
+	writel_relaxed(l2x0_way_mask, reg);
+	cache_wait_way(reg, l2x0_way_mask);
+}
+
 static inline void l2c_unlock(void __iomem *base, unsigned num)
 {
 	unsigned i;
@@ -166,8 +172,7 @@ static void l2x0_cache_sync(void)
 static void __l2x0_flush_all(void)
 {
 	debug_writel(0x03);
-	writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY);
-	cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask);
+	__l2c_op_way(l2x0_base + L2X0_CLEAN_INV_WAY);
 	cache_sync();
 	debug_writel(0x00);
 }
@@ -188,8 +193,7 @@ static void l2x0_clean_all(void)
 
 	/* clean all ways */
 	raw_spin_lock_irqsave(&l2x0_lock, flags);
-	writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY);
-	cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask);
+	__l2c_op_way(l2x0_base + L2X0_CLEAN_WAY);
 	cache_sync();
 	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
@@ -202,8 +206,7 @@ static void l2x0_inv_all(void)
 	raw_spin_lock_irqsave(&l2x0_lock, flags);
 	/* Invalidating when L2 is enabled is a nono */
 	BUG_ON(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN);
-	writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
-	cache_wait_way(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
+	__l2c_op_way(l2x0_base + L2X0_INV_WAY);
 	cache_sync();
 	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 10/44] ARM: l2c: rename cache_wait_way()
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (8 preceding siblings ...)
  2014-03-17  0:14 ` [PATCH 09/44] ARM: l2c: provide generic helper for way-based operations Russell King
@ 2014-03-17  0:14 ` Russell King
  2014-03-17  0:14 ` [PATCH 11/44] ARM: l2c: use add L2C revision constants Russell King
                   ` (35 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

cache_wait_way() is actually used to wait for a particular mask to
report clear; it's not really got much to do with cache ways at all.
Indeed, it gets used to wait for the C bit to clear on older caches.
Rename this with a more generic function name which better reflects
its purpose: l2c_wait_mask().

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 1c3a23318f53..29ee7f692801 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -53,7 +53,7 @@ static bool of_init = false;
 /*
  * Common code for all cache controllers.
  */
-static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
+static inline void l2c_wait_mask(void __iomem *reg, unsigned long mask)
 {
 	/* wait for cache operation by line or way to complete */
 	while (readl_relaxed(reg) & mask)
@@ -73,7 +73,7 @@ static inline void l2c_set_debug(void __iomem *base, unsigned long val)
 static void __l2c_op_way(void __iomem *reg)
 {
 	writel_relaxed(l2x0_way_mask, reg);
-	cache_wait_way(reg, l2x0_way_mask);
+	l2c_wait_mask(reg, l2x0_way_mask);
 }
 
 static inline void l2c_unlock(void __iomem *base, unsigned num)
@@ -94,7 +94,7 @@ static inline void cache_wait(void __iomem *reg, unsigned long mask)
 	/* cache operations by line are atomic on PL310 */
 }
 #else
-#define cache_wait	cache_wait_way
+#define cache_wait	l2c_wait_mask
 #endif
 
 static inline void cache_sync(void)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 11/44] ARM: l2c: use add L2C revision constants
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (9 preceding siblings ...)
  2014-03-17  0:14 ` [PATCH 10/44] ARM: l2c: rename cache_wait_way() Russell King
@ 2014-03-17  0:14 ` Russell King
  2014-03-17  0:14 ` [PATCH 12/44] ARM: l2c: clean up OF initialisation a bit Russell King
                   ` (34 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

The revision namespace is specific to the L2 cache part, so don't name
these with generic identifiers, use a part specific identifier.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/hardware/cache-l2x0.h | 22 ++++++++++++++++------
 arch/arm/mm/cache-l2x0.c                   | 10 +++++-----
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 6795ff743b3d..94fbcec216ae 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -68,14 +68,24 @@
 /* Registers shifts and masks */
 #define L2X0_CACHE_ID_PART_MASK		(0xf << 6)
 #define L2X0_CACHE_ID_PART_L210		(1 << 6)
+#define L2X0_CACHE_ID_PART_L220		(2 << 6)
 #define L2X0_CACHE_ID_PART_L310		(3 << 6)
 #define L2X0_CACHE_ID_RTL_MASK          0x3f
-#define L2X0_CACHE_ID_RTL_R0P0          0x0
-#define L2X0_CACHE_ID_RTL_R1P0          0x2
-#define L2X0_CACHE_ID_RTL_R2P0          0x4
-#define L2X0_CACHE_ID_RTL_R3P0          0x5
-#define L2X0_CACHE_ID_RTL_R3P1          0x6
-#define L2X0_CACHE_ID_RTL_R3P2          0x8
+#define L210_CACHE_ID_RTL_R0P2_02	0x00
+#define L210_CACHE_ID_RTL_R0P1		0x01
+#define L210_CACHE_ID_RTL_R0P2_01	0x02
+#define L210_CACHE_ID_RTL_R0P3		0x03
+#define L210_CACHE_ID_RTL_R0P4		0x0b
+#define L210_CACHE_ID_RTL_R0P5		0x0f
+#define L220_CACHE_ID_RTL_R1P7_01REL0	0x06
+#define L310_CACHE_ID_RTL_R0P0          0x00
+#define L310_CACHE_ID_RTL_R1P0          0x02
+#define L310_CACHE_ID_RTL_R2P0          0x04
+#define L310_CACHE_ID_RTL_R3P0          0x05
+#define L310_CACHE_ID_RTL_R3P1          0x06
+#define L310_CACHE_ID_RTL_R3P1_50REL0	0x07
+#define L310_CACHE_ID_RTL_R3P2          0x08
+#define L310_CACHE_ID_RTL_R3P3		0x09
 
 #define L2X0_AUX_CTRL_MASK			0xc0000fff
 #define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT	0
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 29ee7f692801..c39602ef2cdd 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -374,7 +374,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 		/* Unmapped register. */
 		sync_reg_offset = L2X0_DUMMY_REG;
 #endif
-		if ((cache_id & L2X0_CACHE_ID_RTL_MASK) <= L2X0_CACHE_ID_RTL_R3P0)
+		if ((cache_id & L2X0_CACHE_ID_RTL_MASK) <= L310_CACHE_ID_RTL_R3P0)
 			outer_cache.set_debug = pl310_set_debug;
 		break;
 	case L2X0_CACHE_ID_PART_L210:
@@ -768,7 +768,7 @@ static void __init pl310_save(void)
 	l2x0_saved_regs.filter_start = readl_relaxed(l2x0_base +
 		L2X0_ADDR_FILTER_START);
 
-	if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) {
+	if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) {
 		/*
 		 * From r2p0, there is Prefetch offset/control register
 		 */
@@ -777,7 +777,7 @@ static void __init pl310_save(void)
 		/*
 		 * From r3p0, there is Power control register
 		 */
-		if (l2x0_revision >= L2X0_CACHE_ID_RTL_R3P0)
+		if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0)
 			l2x0_saved_regs.pwr_ctrl = readl_relaxed(l2x0_base +
 				L2X0_POWER_CTRL);
 	}
@@ -830,10 +830,10 @@ static void pl310_resume(void)
 		l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
 			L2X0_CACHE_ID_RTL_MASK;
 
-		if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) {
+		if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) {
 			writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
 				l2x0_base + L2X0_PREFETCH_CTRL);
-			if (l2x0_revision >= L2X0_CACHE_ID_RTL_R3P0)
+			if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0)
 				writel_relaxed(l2x0_saved_regs.pwr_ctrl,
 					l2x0_base + L2X0_POWER_CTRL);
 		}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 12/44] ARM: l2c: clean up OF initialisation a bit
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (10 preceding siblings ...)
  2014-03-17  0:14 ` [PATCH 11/44] ARM: l2c: use add L2C revision constants Russell King
@ 2014-03-17  0:14 ` Russell King
  2014-03-17  0:14 ` [PATCH 13/44] ARM: l2c: pass iomem address into data->save function Russell King
                   ` (33 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

Rather than having a boolean and other tricks to disable some bits of
l2x0_init(), split this function into two parts: a common part shared
between OF and non-OF, and the non-OF part.

The common part can take a block of function pointers, and the cache
ID (to cope with Aurora's DT specified ID.)  Eliminate the redundant
setting of l2x0_base in the OF case, moving it to the non-OF init
function.

This allows us to localise the OF-specific initialisation handling
from the non-OF handling.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 66 +++++++++++++++++++++++++++++-------------------
 1 file changed, 40 insertions(+), 26 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index c39602ef2cdd..0d83b24b7971 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -42,14 +42,8 @@ static u32 l2x0_way_mask;	/* Bitmask of active ways */
 static u32 l2x0_size;
 static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
 
-/* Aurora don't have the cache ID register available, so we have to
- * pass it though the device tree */
-static u32  cache_id_part_number_from_dt;
-
 struct l2x0_regs l2x0_saved_regs;
 
-static bool of_init = false;
-
 /*
  * Common code for all cache controllers.
  */
@@ -343,20 +337,26 @@ static void l2x0_unlock(u32 cache_id)
 	l2c_unlock(l2x0_base, lockregs);
 }
 
-void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
+static const struct l2c_init_data l2x0_init_fns __initconst = {
+	.outer_cache = {
+		.inv_range = l2x0_inv_range,
+		.clean_range = l2x0_clean_range,
+		.flush_range = l2x0_flush_range,
+		.flush_all = l2x0_flush_all,
+		.disable = l2x0_disable,
+		.sync = l2x0_cache_sync,
+	},
+};
+
+static void __init __l2c_init(const struct l2c_init_data *data,
+	u32 aux_val, u32 aux_mask, u32 cache_id)
 {
 	u32 aux;
-	u32 cache_id;
 	u32 way_size = 0;
 	int ways;
 	int way_size_shift = L2X0_WAY_SIZE_SHIFT;
 	const char *type;
 
-	l2x0_base = base;
-	if (cache_id_part_number_from_dt)
-		cache_id = cache_id_part_number_from_dt;
-	else
-		cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
 	aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
 
 	aux &= aux_mask;
@@ -374,8 +374,6 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 		/* Unmapped register. */
 		sync_reg_offset = L2X0_DUMMY_REG;
 #endif
-		if ((cache_id & L2X0_CACHE_ID_RTL_MASK) <= L310_CACHE_ID_RTL_R3P0)
-			outer_cache.set_debug = pl310_set_debug;
 		break;
 	case L2X0_CACHE_ID_PART_L210:
 		ways = (aux >> 13) & 0xf;
@@ -430,23 +428,35 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 	/* Save the value for resuming. */
 	l2x0_saved_regs.aux_ctrl = aux;
 
-	if (!of_init) {
-		outer_cache.inv_range = l2x0_inv_range;
-		outer_cache.clean_range = l2x0_clean_range;
-		outer_cache.flush_range = l2x0_flush_range;
-		outer_cache.sync = l2x0_cache_sync;
-		outer_cache.flush_all = l2x0_flush_all;
-		outer_cache.disable = l2x0_disable;
-	}
+	outer_cache = data->outer_cache;
+
+	if ((cache_id & L2X0_CACHE_ID_PART_MASK) == L2X0_CACHE_ID_PART_L310 &&
+	    (cache_id & L2X0_CACHE_ID_RTL_MASK) <= L310_CACHE_ID_RTL_R3P0)
+		outer_cache.set_debug = pl310_set_debug;
 
 	pr_info("%s cache controller enabled\n", type);
 	pr_info("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d kB\n",
 		ways, cache_id, aux, l2x0_size >> 10);
 }
 
+void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
+{
+	u32 cache_id;
+
+	l2x0_base = base;
+
+	cache_id = readl_relaxed(base + L2X0_CACHE_ID);
+
+	__l2c_init(&l2x0_init_fns, aux_val, aux_mask, cache_id);
+}
+
 #ifdef CONFIG_OF
 static int l2_wt_override;
 
+/* Aurora don't have the cache ID register available, so we have to
+ * pass it though the device tree */
+static u32 cache_id_part_number_from_dt;
+
 /*
  * Note that the end addresses passed to Linux primitives are
  * noninclusive, while the hardware cache range operations use
@@ -985,6 +995,7 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 	const struct l2c_init_data *data;
 	struct device_node *np;
 	struct resource res;
+	u32 cache_id;
 
 	np = of_find_matching_node(NULL, l2x0_ids);
 	if (!np)
@@ -1015,9 +1026,12 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 	if (data->save)
 		data->save();
 
-	of_init = true;
-	memcpy(&outer_cache, &data->outer_cache, sizeof(outer_cache));
-	l2x0_init(l2x0_base, aux_val, aux_mask);
+	if (cache_id_part_number_from_dt)
+		cache_id = cache_id_part_number_from_dt;
+	else
+		cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
+
+	__l2c_init(data, aux_val, aux_mask, cache_id);
 
 	return 0;
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 13/44] ARM: l2c: pass iomem address into data->save function
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (11 preceding siblings ...)
  2014-03-17  0:14 ` [PATCH 12/44] ARM: l2c: clean up OF initialisation a bit Russell King
@ 2014-03-17  0:14 ` Russell King
  2014-03-17  0:14 ` [PATCH 14/44] ARM: l2c: move l2c save function to __l2c_init() Russell King
                   ` (32 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

Pass the iomem address into this function so we don't have to keep
accessing it from a global.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 0d83b24b7971..08f9cade028a 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -30,7 +30,7 @@
 
 struct l2c_init_data {
 	void (*of_parse)(const struct device_node *, u32 *, u32 *);
-	void (*save)(void);
+	void (*save)(void __iomem *);
 	struct outer_cache_fns outer_cache;
 };
 
@@ -764,47 +764,47 @@ static void __init pl310_of_parse(const struct device_node *np,
 	}
 }
 
-static void __init pl310_save(void)
+static void __init pl310_save(void __iomem *base)
 {
-	u32 l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
+	u32 l2x0_revision = readl_relaxed(base + L2X0_CACHE_ID) &
 		L2X0_CACHE_ID_RTL_MASK;
 
-	l2x0_saved_regs.tag_latency = readl_relaxed(l2x0_base +
+	l2x0_saved_regs.tag_latency = readl_relaxed(base +
 		L2X0_TAG_LATENCY_CTRL);
-	l2x0_saved_regs.data_latency = readl_relaxed(l2x0_base +
+	l2x0_saved_regs.data_latency = readl_relaxed(base +
 		L2X0_DATA_LATENCY_CTRL);
-	l2x0_saved_regs.filter_end = readl_relaxed(l2x0_base +
+	l2x0_saved_regs.filter_end = readl_relaxed(base +
 		L2X0_ADDR_FILTER_END);
-	l2x0_saved_regs.filter_start = readl_relaxed(l2x0_base +
+	l2x0_saved_regs.filter_start = readl_relaxed(base +
 		L2X0_ADDR_FILTER_START);
 
 	if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) {
 		/*
 		 * From r2p0, there is Prefetch offset/control register
 		 */
-		l2x0_saved_regs.prefetch_ctrl = readl_relaxed(l2x0_base +
+		l2x0_saved_regs.prefetch_ctrl = readl_relaxed(base +
 			L2X0_PREFETCH_CTRL);
 		/*
 		 * From r3p0, there is Power control register
 		 */
 		if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0)
-			l2x0_saved_regs.pwr_ctrl = readl_relaxed(l2x0_base +
+			l2x0_saved_regs.pwr_ctrl = readl_relaxed(base +
 				L2X0_POWER_CTRL);
 	}
 }
 
-static void aurora_save(void)
+static void aurora_save(void __iomem *base)
 {
-	l2x0_saved_regs.ctrl = readl_relaxed(l2x0_base + L2X0_CTRL);
-	l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
+	l2x0_saved_regs.ctrl = readl_relaxed(base + L2X0_CTRL);
+	l2x0_saved_regs.aux_ctrl = readl_relaxed(base + L2X0_AUX_CTRL);
 }
 
-static void __init tauros3_save(void)
+static void __init tauros3_save(void __iomem *base)
 {
 	l2x0_saved_regs.aux2_ctrl =
-		readl_relaxed(l2x0_base + TAUROS3_AUX2_CTRL);
+		readl_relaxed(base + TAUROS3_AUX2_CTRL);
 	l2x0_saved_regs.prefetch_ctrl =
-		readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL);
+		readl_relaxed(base + L2X0_PREFETCH_CTRL);
 }
 
 static void l2x0_resume(void)
@@ -1024,7 +1024,7 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 	}
 
 	if (data->save)
-		data->save();
+		data->save(l2x0_base);
 
 	if (cache_id_part_number_from_dt)
 		cache_id = cache_id_part_number_from_dt;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 14/44] ARM: l2c: move l2c save function to __l2c_init()
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (12 preceding siblings ...)
  2014-03-17  0:14 ` [PATCH 13/44] ARM: l2c: pass iomem address into data->save function Russell King
@ 2014-03-17  0:14 ` Russell King
  2014-03-17  0:14 ` [PATCH 15/44] ARM: l2c: provide enable method Russell King
                   ` (31 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

There's no reason this functionality should be specific to DT, so move
it into the common initialisation function.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 08f9cade028a..3b6213838054 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -357,6 +357,13 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	int way_size_shift = L2X0_WAY_SIZE_SHIFT;
 	const char *type;
 
+	/*
+	 * It is strange to save the register state before initialisation,
+	 * but hey, this is what the DT implementations decided to do.
+	 */
+	if (data->save)
+		data->save(l2x0_base);
+
 	aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
 
 	aux &= aux_mask;
@@ -1023,9 +1030,6 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 			aurora_broadcast_l2_commands();
 	}
 
-	if (data->save)
-		data->save(l2x0_base);
-
 	if (cache_id_part_number_from_dt)
 		cache_id = cache_id_part_number_from_dt;
 	else
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 15/44] ARM: l2c: provide enable method
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (13 preceding siblings ...)
  2014-03-17  0:14 ` [PATCH 14/44] ARM: l2c: move l2c save function to __l2c_init() Russell King
@ 2014-03-17  0:14 ` Russell King
  2014-03-17  0:14 ` [PATCH 16/44] ARM: l2c: move aurora broadcast setup to enable function Russell King
                   ` (30 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

Providing an enable method gives L2 cache controllers a chance to do
special handling at enable time.  This allows us to remove a hack in
l2x0_unlock() for Marvell Aurora L2 caches.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 70 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 52 insertions(+), 18 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 3b6213838054..ee60a53357d9 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -30,6 +30,7 @@
 
 struct l2c_init_data {
 	void (*of_parse)(const struct device_node *, u32 *, u32 *);
+	void (*enable)(void __iomem *, u32);
 	void (*save)(void __iomem *);
 	struct outer_cache_fns outer_cache;
 };
@@ -82,6 +83,27 @@ static inline void l2c_unlock(void __iomem *base, unsigned num)
 	}
 }
 
+/*
+ * Enable the L2 cache controller.  This function must only be
+ * called when the cache controller is known to be disabled.
+ */
+static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
+{
+	unsigned long flags;
+
+	l2c_unlock(base, num_lock);
+
+	writel_relaxed(aux, base + L2X0_AUX_CTRL);
+
+	local_irq_save(flags);
+	__l2c_op_way(base + L2X0_INV_WAY);
+	writel_relaxed(0, base + sync_reg_offset);
+	l2c_wait_mask(base + sync_reg_offset, 1);
+	local_irq_restore(flags);
+
+	writel_relaxed(L2X0_CTRL_EN, base + L2X0_CTRL);
+}
+
 #ifdef CONFIG_CACHE_PL310
 static inline void cache_wait(void __iomem *reg, unsigned long mask)
 {
@@ -325,9 +347,6 @@ static void l2x0_unlock(u32 cache_id)
 	case L2X0_CACHE_ID_PART_L310:
 		lockregs = 8;
 		break;
-	case AURORA_CACHE_ID:
-		lockregs = 4;
-		break;
 	default:
 		/* L210 and unknown types */
 		lockregs = 1;
@@ -337,7 +356,22 @@ static void l2x0_unlock(u32 cache_id)
 	l2c_unlock(l2x0_base, lockregs);
 }
 
+static void l2x0_enable(void __iomem *base, u32 aux)
+{
+	/* Make sure that I&D is not locked down when starting */
+	l2x0_unlock(readl_relaxed(base + L2X0_CACHE_ID));
+
+	/* l2x0 controller is disabled */
+	writel_relaxed(aux, base + L2X0_AUX_CTRL);
+
+	l2x0_inv_all();
+
+	/* enable L2X0 */
+	writel_relaxed(L2X0_CTRL_EN, base + L2X0_CTRL);
+}
+
 static const struct l2c_init_data l2x0_init_fns __initconst = {
+	.enable = l2x0_enable,
 	.outer_cache = {
 		.inv_range = l2x0_inv_range,
 		.clean_range = l2x0_clean_range,
@@ -412,22 +446,11 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	l2x0_size = ways * way_size * SZ_1K;
 
 	/*
-	 * Check if l2x0 controller is already enabled.
-	 * If you are booting from non-secure mode
-	 * accessing the below registers will fault.
+	 * Check if l2x0 controller is already enabled.  If we are booting
+	 * in non-secure mode accessing the below registers will fault.
 	 */
-	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
-		/* Make sure that I&D is not locked down when starting */
-		l2x0_unlock(cache_id);
-
-		/* l2x0 controller is disabled */
-		writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
-
-		l2x0_inv_all();
-
-		/* enable L2X0 */
-		writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
-	}
+	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
+		data->enable(l2x0_base, aux);
 
 	/* Re-read it in case some bits are reserved. */
 	aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
@@ -880,6 +903,11 @@ static void tauros3_resume(void)
 	l2x0_resume();
 }
 
+static void aurora_enable(void __iomem *base, u32 aux)
+{
+	l2c_enable(base, aux, 4);
+}
+
 static void __init aurora_broadcast_l2_commands(void)
 {
 	__u32 u;
@@ -914,6 +942,7 @@ static void __init aurora_of_parse(const struct device_node *np,
 
 static const struct l2c_init_data of_pl310_data __initconst = {
 	.of_parse = pl310_of_parse,
+	.enable = l2x0_enable,
 	.save  = pl310_save,
 	.outer_cache = {
 		.inv_range   = l2x0_inv_range,
@@ -928,6 +957,7 @@ static const struct l2c_init_data of_pl310_data __initconst = {
 
 static const struct l2c_init_data of_l2x0_data __initconst = {
 	.of_parse = l2x0_of_parse,
+	.enable = l2x0_enable,
 	.outer_cache = {
 		.inv_range   = l2x0_inv_range,
 		.clean_range = l2x0_clean_range,
@@ -941,6 +971,7 @@ static const struct l2c_init_data of_l2x0_data __initconst = {
 
 static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
 	.of_parse = aurora_of_parse,
+	.enable = aurora_enable,
 	.save  = aurora_save,
 	.outer_cache = {
 		.inv_range   = aurora_inv_range,
@@ -955,6 +986,7 @@ static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
 
 static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
 	.of_parse = aurora_of_parse,
+	.enable = aurora_enable,
 	.save  = aurora_save,
 	.outer_cache = {
 		.resume      = aurora_resume,
@@ -962,6 +994,7 @@ static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
 };
 
 static const struct l2c_init_data of_tauros3_data __initconst = {
+	.enable = l2x0_enable,
 	.save  = tauros3_save,
 	/* Tauros3 broadcasts L1 cache operations to L2 */
 	.outer_cache = {
@@ -971,6 +1004,7 @@ static const struct l2c_init_data of_tauros3_data __initconst = {
 
 static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
 	.of_parse = pl310_of_parse,
+	.enable = l2x0_enable,
 	.save  = pl310_save,
 	.outer_cache = {
 		.inv_range   = bcm_inv_range,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 16/44] ARM: l2c: move aurora broadcast setup to enable function
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (14 preceding siblings ...)
  2014-03-17  0:14 ` [PATCH 15/44] ARM: l2c: provide enable method Russell King
@ 2014-03-17  0:14 ` Russell King
  2014-03-17  0:14 ` [PATCH 17/44] ARM: l2c: group implementation specific code together Russell King
                   ` (29 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

Rather than having this hacked into the OF initialiation function, we
can handle this via the enable function instead.  While here, clean
up that code and comments a little.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index ee60a53357d9..d38591aabb35 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -908,14 +908,21 @@ static void aurora_enable(void __iomem *base, u32 aux)
 	l2c_enable(base, aux, 4);
 }
 
-static void __init aurora_broadcast_l2_commands(void)
+/*
+ * For Aurora cache in no outer mode, enable via the CP15 coprocessor
+ * broadcasting of cache commands to L2.
+ */
+static void __init aurora_enable_no_outer(void __iomem *base, u32 aux)
 {
-	__u32 u;
-	/* Enable Broadcasting of cache commands to L2*/
-	__asm__ __volatile__("mrc p15, 1, %0, c15, c2, 0" : "=r"(u));
+	u32 u;
+
+	asm volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (u));
 	u |= AURORA_CTRL_FW;		/* Set the FW bit */
-	__asm__ __volatile__("mcr p15, 1, %0, c15, c2, 0\n" : : "r"(u));
+	asm volatile("mcr p15, 1, %0, c15, c2, 0" : : "r" (u));
+
 	isb();
+
+	aurora_enable(base, aux);
 }
 
 static void __init aurora_of_parse(const struct device_node *np,
@@ -986,7 +993,7 @@ static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
 
 static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
 	.of_parse = aurora_of_parse,
-	.enable = aurora_enable,
+	.enable = aurora_enable_no_outer,
 	.save  = aurora_save,
 	.outer_cache = {
 		.resume      = aurora_resume,
@@ -1054,16 +1061,10 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 	data = of_match_node(l2x0_ids, np)->data;
 
 	/* L2 configuration can only be changed if the cache is disabled */
-	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
 		if (data->of_parse)
 			data->of_parse(np, &aux_val, &aux_mask);
 
-		/* For aurora cache in no outer mode select the
-		 * correct mode using the coprocessor*/
-		if (data == &of_aurora_no_outer_data)
-			aurora_broadcast_l2_commands();
-	}
-
 	if (cache_id_part_number_from_dt)
 		cache_id = cache_id_part_number_from_dt;
 	else
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 17/44] ARM: l2c: group implementation specific code together
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (15 preceding siblings ...)
  2014-03-17  0:14 ` [PATCH 16/44] ARM: l2c: move aurora broadcast setup to enable function Russell King
@ 2014-03-17  0:14 ` Russell King
  2014-03-17  0:15 ` [PATCH 18/44] ARM: l2c: implement fixups for L2 cache controller quirks/errata Russell King
                   ` (28 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

Back in the mists of time, someone decided that it would be a good idea
to group like functions together - so all the save functions in one
place, all the resume functions in another, all the OF parsing functions
some place else.

This makes it difficult to get an overview on what a particular
implementation is doing - grouping an implementations specific functions
together makes more sense, because you can see what it's doing without
the clutter of other implementations.

Organise it according to implementation.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 536 +++++++++++++++++++++++------------------------
 1 file changed, 268 insertions(+), 268 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index d38591aabb35..9bd41f0e3b8a 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -487,6 +487,177 @@ static int l2_wt_override;
  * pass it though the device tree */
 static u32 cache_id_part_number_from_dt;
 
+static void __init l2x0_of_parse(const struct device_node *np,
+				 u32 *aux_val, u32 *aux_mask)
+{
+	u32 data[2] = { 0, 0 };
+	u32 tag = 0;
+	u32 dirty = 0;
+	u32 val = 0, mask = 0;
+
+	of_property_read_u32(np, "arm,tag-latency", &tag);
+	if (tag) {
+		mask |= L2X0_AUX_CTRL_TAG_LATENCY_MASK;
+		val |= (tag - 1) << L2X0_AUX_CTRL_TAG_LATENCY_SHIFT;
+	}
+
+	of_property_read_u32_array(np, "arm,data-latency",
+				   data, ARRAY_SIZE(data));
+	if (data[0] && data[1]) {
+		mask |= L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK |
+			L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK;
+		val |= ((data[0] - 1) << L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT) |
+		       ((data[1] - 1) << L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT);
+	}
+
+	of_property_read_u32(np, "arm,dirty-latency", &dirty);
+	if (dirty) {
+		mask |= L2X0_AUX_CTRL_DIRTY_LATENCY_MASK;
+		val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT;
+	}
+
+	*aux_val &= ~mask;
+	*aux_val |= val;
+	*aux_mask &= ~mask;
+}
+
+static void l2x0_resume(void)
+{
+	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+		/* restore aux ctrl and enable l2 */
+		l2x0_unlock(readl_relaxed(l2x0_base + L2X0_CACHE_ID));
+
+		writel_relaxed(l2x0_saved_regs.aux_ctrl, l2x0_base +
+			L2X0_AUX_CTRL);
+
+		l2x0_inv_all();
+
+		writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
+	}
+}
+
+static const struct l2c_init_data of_l2x0_data __initconst = {
+	.of_parse = l2x0_of_parse,
+	.enable = l2x0_enable,
+	.outer_cache = {
+		.inv_range   = l2x0_inv_range,
+		.clean_range = l2x0_clean_range,
+		.flush_range = l2x0_flush_range,
+		.flush_all   = l2x0_flush_all,
+		.disable     = l2x0_disable,
+		.sync        = l2x0_cache_sync,
+		.resume      = l2x0_resume,
+	},
+};
+
+static void __init pl310_of_parse(const struct device_node *np,
+				  u32 *aux_val, u32 *aux_mask)
+{
+	u32 data[3] = { 0, 0, 0 };
+	u32 tag[3] = { 0, 0, 0 };
+	u32 filter[2] = { 0, 0 };
+
+	of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
+	if (tag[0] && tag[1] && tag[2])
+		writel_relaxed(
+			((tag[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
+			((tag[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
+			((tag[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
+			l2x0_base + L2X0_TAG_LATENCY_CTRL);
+
+	of_property_read_u32_array(np, "arm,data-latency",
+				   data, ARRAY_SIZE(data));
+	if (data[0] && data[1] && data[2])
+		writel_relaxed(
+			((data[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
+			((data[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
+			((data[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
+			l2x0_base + L2X0_DATA_LATENCY_CTRL);
+
+	of_property_read_u32_array(np, "arm,filter-ranges",
+				   filter, ARRAY_SIZE(filter));
+	if (filter[1]) {
+		writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M),
+			       l2x0_base + L2X0_ADDR_FILTER_END);
+		writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L2X0_ADDR_FILTER_EN,
+			       l2x0_base + L2X0_ADDR_FILTER_START);
+	}
+}
+
+static void __init pl310_save(void __iomem *base)
+{
+	u32 l2x0_revision = readl_relaxed(base + L2X0_CACHE_ID) &
+		L2X0_CACHE_ID_RTL_MASK;
+
+	l2x0_saved_regs.tag_latency = readl_relaxed(base +
+		L2X0_TAG_LATENCY_CTRL);
+	l2x0_saved_regs.data_latency = readl_relaxed(base +
+		L2X0_DATA_LATENCY_CTRL);
+	l2x0_saved_regs.filter_end = readl_relaxed(base +
+		L2X0_ADDR_FILTER_END);
+	l2x0_saved_regs.filter_start = readl_relaxed(base +
+		L2X0_ADDR_FILTER_START);
+
+	if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) {
+		/*
+		 * From r2p0, there is Prefetch offset/control register
+		 */
+		l2x0_saved_regs.prefetch_ctrl = readl_relaxed(base +
+			L2X0_PREFETCH_CTRL);
+		/*
+		 * From r3p0, there is Power control register
+		 */
+		if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0)
+			l2x0_saved_regs.pwr_ctrl = readl_relaxed(base +
+				L2X0_POWER_CTRL);
+	}
+}
+
+static void pl310_resume(void)
+{
+	u32 l2x0_revision;
+
+	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+		/* restore pl310 setup */
+		writel_relaxed(l2x0_saved_regs.tag_latency,
+			l2x0_base + L2X0_TAG_LATENCY_CTRL);
+		writel_relaxed(l2x0_saved_regs.data_latency,
+			l2x0_base + L2X0_DATA_LATENCY_CTRL);
+		writel_relaxed(l2x0_saved_regs.filter_end,
+			l2x0_base + L2X0_ADDR_FILTER_END);
+		writel_relaxed(l2x0_saved_regs.filter_start,
+			l2x0_base + L2X0_ADDR_FILTER_START);
+
+		l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
+			L2X0_CACHE_ID_RTL_MASK;
+
+		if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) {
+			writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
+				l2x0_base + L2X0_PREFETCH_CTRL);
+			if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0)
+				writel_relaxed(l2x0_saved_regs.pwr_ctrl,
+					l2x0_base + L2X0_POWER_CTRL);
+		}
+	}
+
+	l2x0_resume();
+}
+
+static const struct l2c_init_data of_pl310_data __initconst = {
+	.of_parse = pl310_of_parse,
+	.enable = l2x0_enable,
+	.save  = pl310_save,
+	.outer_cache = {
+		.inv_range   = l2x0_inv_range,
+		.clean_range = l2x0_clean_range,
+		.flush_range = l2x0_flush_range,
+		.flush_all   = l2x0_flush_all,
+		.disable     = l2x0_disable,
+		.sync        = l2x0_cache_sync,
+		.resume      = pl310_resume,
+	},
+};
+
 /*
  * Note that the end addresses passed to Linux primitives are
  * noninclusive, while the hardware cache range operations use
@@ -585,6 +756,89 @@ static void aurora_flush_range(unsigned long start, unsigned long end)
 	}
 }
 
+static void aurora_save(void __iomem *base)
+{
+	l2x0_saved_regs.ctrl = readl_relaxed(base + L2X0_CTRL);
+	l2x0_saved_regs.aux_ctrl = readl_relaxed(base + L2X0_AUX_CTRL);
+}
+
+static void aurora_resume(void)
+{
+	if (!(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+		writel_relaxed(l2x0_saved_regs.aux_ctrl,
+				l2x0_base + L2X0_AUX_CTRL);
+		writel_relaxed(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL);
+	}
+}
+
+static void aurora_enable(void __iomem *base, u32 aux)
+{
+	l2c_enable(base, aux, 4);
+}
+
+/*
+ * For Aurora cache in no outer mode, enable via the CP15 coprocessor
+ * broadcasting of cache commands to L2.
+ */
+static void __init aurora_enable_no_outer(void __iomem *base, u32 aux)
+{
+	u32 u;
+
+	asm volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (u));
+	u |= AURORA_CTRL_FW;		/* Set the FW bit */
+	asm volatile("mcr p15, 1, %0, c15, c2, 0" : : "r" (u));
+
+	isb();
+
+	aurora_enable(base, aux);
+}
+
+static void __init aurora_of_parse(const struct device_node *np,
+				u32 *aux_val, u32 *aux_mask)
+{
+	u32 val = AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU;
+	u32 mask =  AURORA_ACR_REPLACEMENT_MASK;
+
+	of_property_read_u32(np, "cache-id-part",
+			&cache_id_part_number_from_dt);
+
+	/* Determine and save the write policy */
+	l2_wt_override = of_property_read_bool(np, "wt-override");
+
+	if (l2_wt_override) {
+		val |= AURORA_ACR_FORCE_WRITE_THRO_POLICY;
+		mask |= AURORA_ACR_FORCE_WRITE_POLICY_MASK;
+	}
+
+	*aux_val &= ~mask;
+	*aux_val |= val;
+	*aux_mask &= ~mask;
+}
+
+static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
+	.of_parse = aurora_of_parse,
+	.enable = aurora_enable,
+	.save  = aurora_save,
+	.outer_cache = {
+		.inv_range   = aurora_inv_range,
+		.clean_range = aurora_clean_range,
+		.flush_range = aurora_flush_range,
+		.flush_all   = l2x0_flush_all,
+		.disable     = l2x0_disable,
+		.sync        = l2x0_cache_sync,
+		.resume      = aurora_resume,
+	},
+};
+
+static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
+	.of_parse = aurora_of_parse,
+	.enable = aurora_enable_no_outer,
+	.save  = aurora_save,
+	.outer_cache = {
+		.resume      = aurora_resume,
+	},
+};
+
 /*
  * For certain Broadcom SoCs, depending on the address range, different offsets
  * need to be added to the address before passing it to L2 for
@@ -726,108 +980,20 @@ static void bcm_flush_range(unsigned long start, unsigned long end)
 		new_end);
 }
 
-static void __init l2x0_of_parse(const struct device_node *np,
-				 u32 *aux_val, u32 *aux_mask)
-{
-	u32 data[2] = { 0, 0 };
-	u32 tag = 0;
-	u32 dirty = 0;
-	u32 val = 0, mask = 0;
-
-	of_property_read_u32(np, "arm,tag-latency", &tag);
-	if (tag) {
-		mask |= L2X0_AUX_CTRL_TAG_LATENCY_MASK;
-		val |= (tag - 1) << L2X0_AUX_CTRL_TAG_LATENCY_SHIFT;
-	}
-
-	of_property_read_u32_array(np, "arm,data-latency",
-				   data, ARRAY_SIZE(data));
-	if (data[0] && data[1]) {
-		mask |= L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK |
-			L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK;
-		val |= ((data[0] - 1) << L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT) |
-		       ((data[1] - 1) << L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT);
-	}
-
-	of_property_read_u32(np, "arm,dirty-latency", &dirty);
-	if (dirty) {
-		mask |= L2X0_AUX_CTRL_DIRTY_LATENCY_MASK;
-		val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT;
-	}
-
-	*aux_val &= ~mask;
-	*aux_val |= val;
-	*aux_mask &= ~mask;
-}
-
-static void __init pl310_of_parse(const struct device_node *np,
-				  u32 *aux_val, u32 *aux_mask)
-{
-	u32 data[3] = { 0, 0, 0 };
-	u32 tag[3] = { 0, 0, 0 };
-	u32 filter[2] = { 0, 0 };
-
-	of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
-	if (tag[0] && tag[1] && tag[2])
-		writel_relaxed(
-			((tag[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
-			((tag[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
-			((tag[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
-			l2x0_base + L2X0_TAG_LATENCY_CTRL);
-
-	of_property_read_u32_array(np, "arm,data-latency",
-				   data, ARRAY_SIZE(data));
-	if (data[0] && data[1] && data[2])
-		writel_relaxed(
-			((data[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
-			((data[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
-			((data[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
-			l2x0_base + L2X0_DATA_LATENCY_CTRL);
-
-	of_property_read_u32_array(np, "arm,filter-ranges",
-				   filter, ARRAY_SIZE(filter));
-	if (filter[1]) {
-		writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M),
-			       l2x0_base + L2X0_ADDR_FILTER_END);
-		writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L2X0_ADDR_FILTER_EN,
-			       l2x0_base + L2X0_ADDR_FILTER_START);
-	}
-}
-
-static void __init pl310_save(void __iomem *base)
-{
-	u32 l2x0_revision = readl_relaxed(base + L2X0_CACHE_ID) &
-		L2X0_CACHE_ID_RTL_MASK;
-
-	l2x0_saved_regs.tag_latency = readl_relaxed(base +
-		L2X0_TAG_LATENCY_CTRL);
-	l2x0_saved_regs.data_latency = readl_relaxed(base +
-		L2X0_DATA_LATENCY_CTRL);
-	l2x0_saved_regs.filter_end = readl_relaxed(base +
-		L2X0_ADDR_FILTER_END);
-	l2x0_saved_regs.filter_start = readl_relaxed(base +
-		L2X0_ADDR_FILTER_START);
-
-	if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) {
-		/*
-		 * From r2p0, there is Prefetch offset/control register
-		 */
-		l2x0_saved_regs.prefetch_ctrl = readl_relaxed(base +
-			L2X0_PREFETCH_CTRL);
-		/*
-		 * From r3p0, there is Power control register
-		 */
-		if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0)
-			l2x0_saved_regs.pwr_ctrl = readl_relaxed(base +
-				L2X0_POWER_CTRL);
-	}
-}
-
-static void aurora_save(void __iomem *base)
-{
-	l2x0_saved_regs.ctrl = readl_relaxed(base + L2X0_CTRL);
-	l2x0_saved_regs.aux_ctrl = readl_relaxed(base + L2X0_AUX_CTRL);
-}
+static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
+	.of_parse = pl310_of_parse,
+	.enable = l2x0_enable,
+	.save  = pl310_save,
+	.outer_cache = {
+		.inv_range   = bcm_inv_range,
+		.clean_range = bcm_clean_range,
+		.flush_range = bcm_flush_range,
+		.flush_all   = l2x0_flush_all,
+		.disable     = l2x0_disable,
+		.sync        = l2x0_cache_sync,
+		.resume      = pl310_resume,
+	},
+};
 
 static void __init tauros3_save(void __iomem *base)
 {
@@ -837,60 +1003,6 @@ static void __init tauros3_save(void __iomem *base)
 		readl_relaxed(base + L2X0_PREFETCH_CTRL);
 }
 
-static void l2x0_resume(void)
-{
-	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
-		/* restore aux ctrl and enable l2 */
-		l2x0_unlock(readl_relaxed(l2x0_base + L2X0_CACHE_ID));
-
-		writel_relaxed(l2x0_saved_regs.aux_ctrl, l2x0_base +
-			L2X0_AUX_CTRL);
-
-		l2x0_inv_all();
-
-		writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
-	}
-}
-
-static void pl310_resume(void)
-{
-	u32 l2x0_revision;
-
-	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
-		/* restore pl310 setup */
-		writel_relaxed(l2x0_saved_regs.tag_latency,
-			l2x0_base + L2X0_TAG_LATENCY_CTRL);
-		writel_relaxed(l2x0_saved_regs.data_latency,
-			l2x0_base + L2X0_DATA_LATENCY_CTRL);
-		writel_relaxed(l2x0_saved_regs.filter_end,
-			l2x0_base + L2X0_ADDR_FILTER_END);
-		writel_relaxed(l2x0_saved_regs.filter_start,
-			l2x0_base + L2X0_ADDR_FILTER_START);
-
-		l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
-			L2X0_CACHE_ID_RTL_MASK;
-
-		if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) {
-			writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
-				l2x0_base + L2X0_PREFETCH_CTRL);
-			if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0)
-				writel_relaxed(l2x0_saved_regs.pwr_ctrl,
-					l2x0_base + L2X0_POWER_CTRL);
-		}
-	}
-
-	l2x0_resume();
-}
-
-static void aurora_resume(void)
-{
-	if (!(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
-		writel_relaxed(l2x0_saved_regs.aux_ctrl,
-				l2x0_base + L2X0_AUX_CTRL);
-		writel_relaxed(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL);
-	}
-}
-
 static void tauros3_resume(void)
 {
 	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
@@ -903,103 +1015,6 @@ static void tauros3_resume(void)
 	l2x0_resume();
 }
 
-static void aurora_enable(void __iomem *base, u32 aux)
-{
-	l2c_enable(base, aux, 4);
-}
-
-/*
- * For Aurora cache in no outer mode, enable via the CP15 coprocessor
- * broadcasting of cache commands to L2.
- */
-static void __init aurora_enable_no_outer(void __iomem *base, u32 aux)
-{
-	u32 u;
-
-	asm volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (u));
-	u |= AURORA_CTRL_FW;		/* Set the FW bit */
-	asm volatile("mcr p15, 1, %0, c15, c2, 0" : : "r" (u));
-
-	isb();
-
-	aurora_enable(base, aux);
-}
-
-static void __init aurora_of_parse(const struct device_node *np,
-				u32 *aux_val, u32 *aux_mask)
-{
-	u32 val = AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU;
-	u32 mask =  AURORA_ACR_REPLACEMENT_MASK;
-
-	of_property_read_u32(np, "cache-id-part",
-			&cache_id_part_number_from_dt);
-
-	/* Determine and save the write policy */
-	l2_wt_override = of_property_read_bool(np, "wt-override");
-
-	if (l2_wt_override) {
-		val |= AURORA_ACR_FORCE_WRITE_THRO_POLICY;
-		mask |= AURORA_ACR_FORCE_WRITE_POLICY_MASK;
-	}
-
-	*aux_val &= ~mask;
-	*aux_val |= val;
-	*aux_mask &= ~mask;
-}
-
-static const struct l2c_init_data of_pl310_data __initconst = {
-	.of_parse = pl310_of_parse,
-	.enable = l2x0_enable,
-	.save  = pl310_save,
-	.outer_cache = {
-		.inv_range   = l2x0_inv_range,
-		.clean_range = l2x0_clean_range,
-		.flush_range = l2x0_flush_range,
-		.flush_all   = l2x0_flush_all,
-		.disable     = l2x0_disable,
-		.sync        = l2x0_cache_sync,
-		.resume      = pl310_resume,
-	},
-};
-
-static const struct l2c_init_data of_l2x0_data __initconst = {
-	.of_parse = l2x0_of_parse,
-	.enable = l2x0_enable,
-	.outer_cache = {
-		.inv_range   = l2x0_inv_range,
-		.clean_range = l2x0_clean_range,
-		.flush_range = l2x0_flush_range,
-		.flush_all   = l2x0_flush_all,
-		.disable     = l2x0_disable,
-		.sync        = l2x0_cache_sync,
-		.resume      = l2x0_resume,
-	},
-};
-
-static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
-	.of_parse = aurora_of_parse,
-	.enable = aurora_enable,
-	.save  = aurora_save,
-	.outer_cache = {
-		.inv_range   = aurora_inv_range,
-		.clean_range = aurora_clean_range,
-		.flush_range = aurora_flush_range,
-		.flush_all   = l2x0_flush_all,
-		.disable     = l2x0_disable,
-		.sync        = l2x0_cache_sync,
-		.resume      = aurora_resume,
-	},
-};
-
-static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
-	.of_parse = aurora_of_parse,
-	.enable = aurora_enable_no_outer,
-	.save  = aurora_save,
-	.outer_cache = {
-		.resume      = aurora_resume,
-	},
-};
-
 static const struct l2c_init_data of_tauros3_data __initconst = {
 	.enable = l2x0_enable,
 	.save  = tauros3_save,
@@ -1009,21 +1024,6 @@ static const struct l2c_init_data of_tauros3_data __initconst = {
 	},
 };
 
-static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
-	.of_parse = pl310_of_parse,
-	.enable = l2x0_enable,
-	.save  = pl310_save,
-	.outer_cache = {
-		.inv_range   = bcm_inv_range,
-		.clean_range = bcm_clean_range,
-		.flush_range = bcm_flush_range,
-		.flush_all   = l2x0_flush_all,
-		.disable     = l2x0_disable,
-		.sync        = l2x0_cache_sync,
-		.resume      = pl310_resume,
-	},
-};
-
 #define L2C_ID(name, fns) { .compatible = name, .data = (void *)&fns }
 static const struct of_device_id l2x0_ids[] __initconst = {
 	L2C_ID("arm,l210-cache", of_l2x0_data),
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 18/44] ARM: l2c: implement fixups for L2 cache controller quirks/errata
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (16 preceding siblings ...)
  2014-03-17  0:14 ` [PATCH 17/44] ARM: l2c: group implementation specific code together Russell King
@ 2014-03-17  0:15 ` Russell King
  2014-03-17  0:15 ` [PATCH 19/44] ARM: l2c: clean up L2 cache initialisation messages Russell King
                   ` (27 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:15 UTC (permalink / raw)
  To: linux-arm-kernel

Rather than putting quirk handling in __l2c_init(), move it out to a
separate function which individual implementations can specify.  This
helps to localise the quirks to those implementations which require
them.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 111 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 100 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 9bd41f0e3b8a..9d2b55b05f71 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -31,6 +31,7 @@
 struct l2c_init_data {
 	void (*of_parse)(const struct device_node *, u32 *, u32 *);
 	void (*enable)(void __iomem *, u32);
+	void (*fixup)(void __iomem *, u32, struct outer_cache_fns *);
 	void (*save)(void __iomem *);
 	struct outer_cache_fns outer_cache;
 };
@@ -382,9 +383,79 @@ static const struct l2c_init_data l2x0_init_fns __initconst = {
 	},
 };
 
+/*
+ * L2C-310 specific code.
+ *
+ * Errata:
+ * 588369: PL310 R0P0->R1P0, fixed R2P0.
+ *	Affects: all clean+invalidate operations
+ *	clean and invalidate skips the invalidate step, so we need to issue
+ *	separate operations.  We also require the above debug workaround
+ *	enclosing this code fragment on affected parts.  On unaffected parts,
+ *	we must not use this workaround without the debug register writes
+ *	to avoid exposing a problem similar to 727915.
+ *
+ * 727915: PL310 R2P0->R3P0, fixed R3P1.
+ *	Affects: clean+invalidate by way
+ *	clean and invalidate by way runs in the background, and a store can
+ *	hit the line between the clean operation and invalidate operation,
+ *	resulting in the store being lost.
+ *
+ * 753970: PL310 R3P0, fixed R3P1.
+ *	Affects: sync
+ *	prevents merging writes after the sync operation, until another L2C
+ *	operation is performed (or a number of other conditions.)
+ *
+ * 769419: PL310 R0P0->R3P1, fixed R3P2.
+ *	Affects: store buffer
+ *	store buffer is not automatically drained.
+ */
+static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
+	struct outer_cache_fns *fns)
+{
+	unsigned revision = cache_id & L2X0_CACHE_ID_RTL_MASK;
+	const char *errata[4];
+	unsigned n = 0;
+
+	if (revision <= L310_CACHE_ID_RTL_R3P0)
+		fns->set_debug = pl310_set_debug;
+
+	if (IS_ENABLED(CONFIG_PL310_ERRATA_753970) &&
+	    revision == L310_CACHE_ID_RTL_R3P0) {
+		sync_reg_offset = L2X0_DUMMY_REG;
+		errata[n++] = "753970";
+	}
+
+	if (IS_ENABLED(CONFIG_PL310_ERRATA_769419))
+		errata[n++] = "769419";
+
+	if (n) {
+		unsigned i;
+
+		pr_info("L2C-310 errat%s", n > 1 ? "a" : "um");
+		for (i = 0; i < n; i++)
+			pr_cont(" %s", errata[i]);
+		pr_cont(" enabled\n");
+	}
+}
+
+static const struct l2c_init_data l2c310_init_fns __initconst = {
+	.enable = l2x0_enable,
+	.fixup = l2c310_fixup,
+	.outer_cache = {
+		.inv_range = l2x0_inv_range,
+		.clean_range = l2x0_clean_range,
+		.flush_range = l2x0_flush_range,
+		.flush_all = l2x0_flush_all,
+		.disable = l2x0_disable,
+		.sync = l2x0_cache_sync,
+	},
+};
+
 static void __init __l2c_init(const struct l2c_init_data *data,
 	u32 aux_val, u32 aux_mask, u32 cache_id)
 {
+	struct outer_cache_fns fns;
 	u32 aux;
 	u32 way_size = 0;
 	int ways;
@@ -411,23 +482,20 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 		else
 			ways = 8;
 		type = "L310";
-#ifdef CONFIG_PL310_ERRATA_753970
-		/* Unmapped register. */
-		sync_reg_offset = L2X0_DUMMY_REG;
-#endif
 		break;
+
 	case L2X0_CACHE_ID_PART_L210:
 		ways = (aux >> 13) & 0xf;
 		type = "L210";
 		break;
 
 	case AURORA_CACHE_ID:
-		sync_reg_offset = AURORA_SYNC_REG;
 		ways = (aux >> 13) & 0xf;
 		ways = 2 << ((ways + 1) >> 2);
 		way_size_shift = AURORA_WAY_SIZE_SHIFT;
 		type = "Aurora";
 		break;
+
 	default:
 		/* Assume unknown chips have 8 ways */
 		ways = 8;
@@ -445,6 +513,10 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 
 	l2x0_size = ways * way_size * SZ_1K;
 
+	fns = data->outer_cache;
+	if (data->fixup)
+		data->fixup(l2x0_base, cache_id, &fns);
+
 	/*
 	 * Check if l2x0 controller is already enabled.  If we are booting
 	 * in non-secure mode accessing the below registers will fault.
@@ -458,11 +530,7 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	/* Save the value for resuming. */
 	l2x0_saved_regs.aux_ctrl = aux;
 
-	outer_cache = data->outer_cache;
-
-	if ((cache_id & L2X0_CACHE_ID_PART_MASK) == L2X0_CACHE_ID_PART_L310 &&
-	    (cache_id & L2X0_CACHE_ID_RTL_MASK) <= L310_CACHE_ID_RTL_R3P0)
-		outer_cache.set_debug = pl310_set_debug;
+	outer_cache = fns;
 
 	pr_info("%s cache controller enabled\n", type);
 	pr_info("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d kB\n",
@@ -471,13 +539,24 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 
 void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 {
+	const struct l2c_init_data *data;
 	u32 cache_id;
 
 	l2x0_base = base;
 
 	cache_id = readl_relaxed(base + L2X0_CACHE_ID);
 
-	__l2c_init(&l2x0_init_fns, aux_val, aux_mask, cache_id);
+	switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
+	default:
+		data = &l2x0_init_fns;
+		break;
+
+	case L2X0_CACHE_ID_PART_L310:
+		data = &l2c310_init_fns;
+		break;
+	}
+
+	__l2c_init(data, aux_val, aux_mask, cache_id);
 }
 
 #ifdef CONFIG_OF
@@ -646,6 +725,7 @@ static void pl310_resume(void)
 static const struct l2c_init_data of_pl310_data __initconst = {
 	.of_parse = pl310_of_parse,
 	.enable = l2x0_enable,
+	.fixup = l2c310_fixup,
 	.save  = pl310_save,
 	.outer_cache = {
 		.inv_range   = l2x0_inv_range,
@@ -793,6 +873,12 @@ static void __init aurora_enable_no_outer(void __iomem *base, u32 aux)
 	aurora_enable(base, aux);
 }
 
+static void __init aurora_fixup(void __iomem *base, u32 cache_id,
+	struct outer_cache_fns *fns)
+{
+	sync_reg_offset = AURORA_SYNC_REG;
+}
+
 static void __init aurora_of_parse(const struct device_node *np,
 				u32 *aux_val, u32 *aux_mask)
 {
@@ -818,6 +904,7 @@ static void __init aurora_of_parse(const struct device_node *np,
 static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
 	.of_parse = aurora_of_parse,
 	.enable = aurora_enable,
+	.fixup = aurora_fixup,
 	.save  = aurora_save,
 	.outer_cache = {
 		.inv_range   = aurora_inv_range,
@@ -833,6 +920,7 @@ static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
 static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
 	.of_parse = aurora_of_parse,
 	.enable = aurora_enable_no_outer,
+	.fixup = aurora_fixup,
 	.save  = aurora_save,
 	.outer_cache = {
 		.resume      = aurora_resume,
@@ -983,6 +1071,7 @@ static void bcm_flush_range(unsigned long start, unsigned long end)
 static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
 	.of_parse = pl310_of_parse,
 	.enable = l2x0_enable,
+	.fixup = l2c310_fixup,
 	.save  = pl310_save,
 	.outer_cache = {
 		.inv_range   = bcm_inv_range,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 19/44] ARM: l2c: clean up L2 cache initialisation messages
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (17 preceding siblings ...)
  2014-03-17  0:15 ` [PATCH 18/44] ARM: l2c: implement fixups for L2 cache controller quirks/errata Russell King
@ 2014-03-17  0:15 ` Russell King
  2014-03-17  0:15 ` [PATCH 20/44] ARM: l2c: split L2C-310 enable function from l2x0 code Russell King
                   ` (26 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:15 UTC (permalink / raw)
  To: linux-arm-kernel

Make one of them purely "English", and the other purely technical.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 9d2b55b05f71..37dd74c9e61a 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -532,9 +532,10 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 
 	outer_cache = fns;
 
-	pr_info("%s cache controller enabled\n", type);
-	pr_info("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d kB\n",
-		ways, cache_id, aux, l2x0_size >> 10);
+	pr_info("%s cache controller enabled, %d ways, %d kB\n",
+		type, ways, l2x0_size >> 10);
+	pr_info("%s: CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
+		type, cache_id, aux);
 }
 
 void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 20/44] ARM: l2c: split L2C-310 enable function from l2x0 code
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (18 preceding siblings ...)
  2014-03-17  0:15 ` [PATCH 19/44] ARM: l2c: clean up L2 cache initialisation messages Russell King
@ 2014-03-17  0:15 ` Russell King
  2014-03-17  0:15 ` [PATCH 21/44] ARM: l2c: move and add ARM L2C-2x0/L2C-310 save/resume code to non-OF Russell King
                   ` (25 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:15 UTC (permalink / raw)
  To: linux-arm-kernel

Provide a L2C-310 specific enable function.  The L2C-310 has 8 unlock
registers.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 37dd74c9e61a..e6913bc67c34 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -410,6 +410,12 @@ static const struct l2c_init_data l2x0_init_fns __initconst = {
  *	Affects: store buffer
  *	store buffer is not automatically drained.
  */
+static void l2c310_enable(void __iomem *base, u32 aux)
+{
+	/* PL310 has 8 lock registers */
+	l2c_enable(base, aux, 8);
+}
+
 static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 	struct outer_cache_fns *fns)
 {
@@ -440,7 +446,7 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 }
 
 static const struct l2c_init_data l2c310_init_fns __initconst = {
-	.enable = l2x0_enable,
+	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
 	.outer_cache = {
 		.inv_range = l2x0_inv_range,
@@ -725,7 +731,7 @@ static void pl310_resume(void)
 
 static const struct l2c_init_data of_pl310_data __initconst = {
 	.of_parse = pl310_of_parse,
-	.enable = l2x0_enable,
+	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
 	.save  = pl310_save,
 	.outer_cache = {
@@ -1071,7 +1077,7 @@ static void bcm_flush_range(unsigned long start, unsigned long end)
 
 static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
 	.of_parse = pl310_of_parse,
-	.enable = l2x0_enable,
+	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
 	.save  = pl310_save,
 	.outer_cache = {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 21/44] ARM: l2c: move and add ARM L2C-2x0/L2C-310 save/resume code to non-OF
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (19 preceding siblings ...)
  2014-03-17  0:15 ` [PATCH 20/44] ARM: l2c: split L2C-310 enable function from l2x0 code Russell King
@ 2014-03-17  0:15 ` Russell King
  2014-03-17  0:15 ` [PATCH 22/44] ARM: l2c: clean up save/resume functions Russell King
                   ` (24 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:15 UTC (permalink / raw)
  To: linux-arm-kernel

Add the save/resume code hooks to the non-OF implementations as well.
There's no reason for the non-OF implementations to be any different
from the OF implementations.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 151 ++++++++++++++++++++++++-----------------------
 1 file changed, 77 insertions(+), 74 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index e6913bc67c34..e4e7dd4ab9b5 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -371,6 +371,21 @@ static void l2x0_enable(void __iomem *base, u32 aux)
 	writel_relaxed(L2X0_CTRL_EN, base + L2X0_CTRL);
 }
 
+static void l2x0_resume(void)
+{
+	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+		/* restore aux ctrl and enable l2 */
+		l2x0_unlock(readl_relaxed(l2x0_base + L2X0_CACHE_ID));
+
+		writel_relaxed(l2x0_saved_regs.aux_ctrl, l2x0_base +
+			L2X0_AUX_CTRL);
+
+		l2x0_inv_all();
+
+		writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
+	}
+}
+
 static const struct l2c_init_data l2x0_init_fns __initconst = {
 	.enable = l2x0_enable,
 	.outer_cache = {
@@ -380,6 +395,7 @@ static const struct l2c_init_data l2x0_init_fns __initconst = {
 		.flush_all = l2x0_flush_all,
 		.disable = l2x0_disable,
 		.sync = l2x0_cache_sync,
+		.resume = l2x0_resume,
 	},
 };
 
@@ -416,6 +432,65 @@ static void l2c310_enable(void __iomem *base, u32 aux)
 	l2c_enable(base, aux, 8);
 }
 
+static void __init pl310_save(void __iomem *base)
+{
+	u32 l2x0_revision = readl_relaxed(base + L2X0_CACHE_ID) &
+		L2X0_CACHE_ID_RTL_MASK;
+
+	l2x0_saved_regs.tag_latency = readl_relaxed(base +
+		L2X0_TAG_LATENCY_CTRL);
+	l2x0_saved_regs.data_latency = readl_relaxed(base +
+		L2X0_DATA_LATENCY_CTRL);
+	l2x0_saved_regs.filter_end = readl_relaxed(base +
+		L2X0_ADDR_FILTER_END);
+	l2x0_saved_regs.filter_start = readl_relaxed(base +
+		L2X0_ADDR_FILTER_START);
+
+	if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) {
+		/*
+		 * From r2p0, there is Prefetch offset/control register
+		 */
+		l2x0_saved_regs.prefetch_ctrl = readl_relaxed(base +
+			L2X0_PREFETCH_CTRL);
+		/*
+		 * From r3p0, there is Power control register
+		 */
+		if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0)
+			l2x0_saved_regs.pwr_ctrl = readl_relaxed(base +
+				L2X0_POWER_CTRL);
+	}
+}
+
+static void pl310_resume(void)
+{
+	u32 l2x0_revision;
+
+	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+		/* restore pl310 setup */
+		writel_relaxed(l2x0_saved_regs.tag_latency,
+			l2x0_base + L2X0_TAG_LATENCY_CTRL);
+		writel_relaxed(l2x0_saved_regs.data_latency,
+			l2x0_base + L2X0_DATA_LATENCY_CTRL);
+		writel_relaxed(l2x0_saved_regs.filter_end,
+			l2x0_base + L2X0_ADDR_FILTER_END);
+		writel_relaxed(l2x0_saved_regs.filter_start,
+			l2x0_base + L2X0_ADDR_FILTER_START);
+
+		l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
+			L2X0_CACHE_ID_RTL_MASK;
+
+		if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) {
+			writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
+				l2x0_base + L2X0_PREFETCH_CTRL);
+			if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0)
+				writel_relaxed(l2x0_saved_regs.pwr_ctrl,
+					l2x0_base + L2X0_POWER_CTRL);
+		}
+	}
+
+	l2x0_resume();
+}
+
 static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 	struct outer_cache_fns *fns)
 {
@@ -448,6 +523,7 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 static const struct l2c_init_data l2c310_init_fns __initconst = {
 	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
+	.save = pl310_save,
 	.outer_cache = {
 		.inv_range = l2x0_inv_range,
 		.clean_range = l2x0_clean_range,
@@ -455,6 +531,7 @@ static const struct l2c_init_data l2c310_init_fns __initconst = {
 		.flush_all = l2x0_flush_all,
 		.disable = l2x0_disable,
 		.sync = l2x0_cache_sync,
+		.resume = pl310_resume,
 	},
 };
 
@@ -607,21 +684,6 @@ static void __init l2x0_of_parse(const struct device_node *np,
 	*aux_mask &= ~mask;
 }
 
-static void l2x0_resume(void)
-{
-	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
-		/* restore aux ctrl and enable l2 */
-		l2x0_unlock(readl_relaxed(l2x0_base + L2X0_CACHE_ID));
-
-		writel_relaxed(l2x0_saved_regs.aux_ctrl, l2x0_base +
-			L2X0_AUX_CTRL);
-
-		l2x0_inv_all();
-
-		writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
-	}
-}
-
 static const struct l2c_init_data of_l2x0_data __initconst = {
 	.of_parse = l2x0_of_parse,
 	.enable = l2x0_enable,
@@ -670,65 +732,6 @@ static void __init pl310_of_parse(const struct device_node *np,
 	}
 }
 
-static void __init pl310_save(void __iomem *base)
-{
-	u32 l2x0_revision = readl_relaxed(base + L2X0_CACHE_ID) &
-		L2X0_CACHE_ID_RTL_MASK;
-
-	l2x0_saved_regs.tag_latency = readl_relaxed(base +
-		L2X0_TAG_LATENCY_CTRL);
-	l2x0_saved_regs.data_latency = readl_relaxed(base +
-		L2X0_DATA_LATENCY_CTRL);
-	l2x0_saved_regs.filter_end = readl_relaxed(base +
-		L2X0_ADDR_FILTER_END);
-	l2x0_saved_regs.filter_start = readl_relaxed(base +
-		L2X0_ADDR_FILTER_START);
-
-	if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) {
-		/*
-		 * From r2p0, there is Prefetch offset/control register
-		 */
-		l2x0_saved_regs.prefetch_ctrl = readl_relaxed(base +
-			L2X0_PREFETCH_CTRL);
-		/*
-		 * From r3p0, there is Power control register
-		 */
-		if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0)
-			l2x0_saved_regs.pwr_ctrl = readl_relaxed(base +
-				L2X0_POWER_CTRL);
-	}
-}
-
-static void pl310_resume(void)
-{
-	u32 l2x0_revision;
-
-	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
-		/* restore pl310 setup */
-		writel_relaxed(l2x0_saved_regs.tag_latency,
-			l2x0_base + L2X0_TAG_LATENCY_CTRL);
-		writel_relaxed(l2x0_saved_regs.data_latency,
-			l2x0_base + L2X0_DATA_LATENCY_CTRL);
-		writel_relaxed(l2x0_saved_regs.filter_end,
-			l2x0_base + L2X0_ADDR_FILTER_END);
-		writel_relaxed(l2x0_saved_regs.filter_start,
-			l2x0_base + L2X0_ADDR_FILTER_START);
-
-		l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
-			L2X0_CACHE_ID_RTL_MASK;
-
-		if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) {
-			writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
-				l2x0_base + L2X0_PREFETCH_CTRL);
-			if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0)
-				writel_relaxed(l2x0_saved_regs.pwr_ctrl,
-					l2x0_base + L2X0_POWER_CTRL);
-		}
-	}
-
-	l2x0_resume();
-}
-
 static const struct l2c_init_data of_pl310_data __initconst = {
 	.of_parse = pl310_of_parse,
 	.enable = l2c310_enable,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 22/44] ARM: l2c: clean up save/resume functions
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (20 preceding siblings ...)
  2014-03-17  0:15 ` [PATCH 21/44] ARM: l2c: move and add ARM L2C-2x0/L2C-310 save/resume code to non-OF Russell King
@ 2014-03-17  0:15 ` Russell King
  2014-03-17  0:15 ` [PATCH 23/44] ARM: l2c: simplify l2x0 unlocking code Russell King
                   ` (23 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:15 UTC (permalink / raw)
  To: linux-arm-kernel

Rename the pl310 save/resume functions to have a l2c310 prefix - this
is it's official name.  Use a local cached copy of the l2x0_base
virtual address, and also realise that many of the resume function
tails are the same as the enable functions, so make a call to the
enable function instead of duplicating that code.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 105 ++++++++++++++++++++++-------------------------
 1 file changed, 50 insertions(+), 55 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index e4e7dd4ab9b5..9243f55ab06d 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -373,17 +373,10 @@ static void l2x0_enable(void __iomem *base, u32 aux)
 
 static void l2x0_resume(void)
 {
-	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
-		/* restore aux ctrl and enable l2 */
-		l2x0_unlock(readl_relaxed(l2x0_base + L2X0_CACHE_ID));
-
-		writel_relaxed(l2x0_saved_regs.aux_ctrl, l2x0_base +
-			L2X0_AUX_CTRL);
-
-		l2x0_inv_all();
+	void __iomem *base = l2x0_base;
 
-		writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
-	}
+	if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN))
+		l2x0_enable(base, l2x0_saved_regs.aux_ctrl);
 }
 
 static const struct l2c_init_data l2x0_init_fns __initconst = {
@@ -432,10 +425,9 @@ static void l2c310_enable(void __iomem *base, u32 aux)
 	l2c_enable(base, aux, 8);
 }
 
-static void __init pl310_save(void __iomem *base)
+static void __init l2c310_save(void __iomem *base)
 {
-	u32 l2x0_revision = readl_relaxed(base + L2X0_CACHE_ID) &
-		L2X0_CACHE_ID_RTL_MASK;
+	unsigned revision;
 
 	l2x0_saved_regs.tag_latency = readl_relaxed(base +
 		L2X0_TAG_LATENCY_CTRL);
@@ -446,49 +438,49 @@ static void __init pl310_save(void __iomem *base)
 	l2x0_saved_regs.filter_start = readl_relaxed(base +
 		L2X0_ADDR_FILTER_START);
 
-	if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) {
-		/*
-		 * From r2p0, there is Prefetch offset/control register
-		 */
+	revision = readl_relaxed(base + L2X0_CACHE_ID) &
+			L2X0_CACHE_ID_RTL_MASK;
+
+	/* From r2p0, there is Prefetch offset/control register */
+	if (revision >= L310_CACHE_ID_RTL_R2P0)
 		l2x0_saved_regs.prefetch_ctrl = readl_relaxed(base +
-			L2X0_PREFETCH_CTRL);
-		/*
-		 * From r3p0, there is Power control register
-		 */
-		if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0)
-			l2x0_saved_regs.pwr_ctrl = readl_relaxed(base +
-				L2X0_POWER_CTRL);
-	}
+							L2X0_PREFETCH_CTRL);
+
+	/* From r3p0, there is Power control register */
+	if (revision >= L310_CACHE_ID_RTL_R3P0)
+		l2x0_saved_regs.pwr_ctrl = readl_relaxed(base +
+							L2X0_POWER_CTRL);
 }
 
-static void pl310_resume(void)
+static void l2c310_resume(void)
 {
-	u32 l2x0_revision;
+	void __iomem *base = l2x0_base;
+
+	if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+		unsigned revision;
 
-	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
 		/* restore pl310 setup */
 		writel_relaxed(l2x0_saved_regs.tag_latency,
-			l2x0_base + L2X0_TAG_LATENCY_CTRL);
+			       base + L2X0_TAG_LATENCY_CTRL);
 		writel_relaxed(l2x0_saved_regs.data_latency,
-			l2x0_base + L2X0_DATA_LATENCY_CTRL);
+			       base + L2X0_DATA_LATENCY_CTRL);
 		writel_relaxed(l2x0_saved_regs.filter_end,
-			l2x0_base + L2X0_ADDR_FILTER_END);
+			       base + L2X0_ADDR_FILTER_END);
 		writel_relaxed(l2x0_saved_regs.filter_start,
-			l2x0_base + L2X0_ADDR_FILTER_START);
+			       base + L2X0_ADDR_FILTER_START);
 
-		l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
-			L2X0_CACHE_ID_RTL_MASK;
+		revision = readl_relaxed(base + L2X0_CACHE_ID) &
+				L2X0_CACHE_ID_RTL_MASK;
 
-		if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) {
+		if (revision >= L310_CACHE_ID_RTL_R2P0)
 			writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
-				l2x0_base + L2X0_PREFETCH_CTRL);
-			if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0)
-				writel_relaxed(l2x0_saved_regs.pwr_ctrl,
-					l2x0_base + L2X0_POWER_CTRL);
-		}
-	}
+				       base + L2X0_PREFETCH_CTRL);
+		if (revision >= L310_CACHE_ID_RTL_R3P0)
+			writel_relaxed(l2x0_saved_regs.pwr_ctrl,
+				       base + L2X0_POWER_CTRL);
 
-	l2x0_resume();
+		l2c310_enable(base, l2x0_saved_regs.aux_ctrl);
+	}
 }
 
 static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
@@ -523,7 +515,7 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 static const struct l2c_init_data l2c310_init_fns __initconst = {
 	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
-	.save = pl310_save,
+	.save = l2c310_save,
 	.outer_cache = {
 		.inv_range = l2x0_inv_range,
 		.clean_range = l2x0_clean_range,
@@ -531,7 +523,7 @@ static const struct l2c_init_data l2c310_init_fns __initconst = {
 		.flush_all = l2x0_flush_all,
 		.disable = l2x0_disable,
 		.sync = l2x0_cache_sync,
-		.resume = pl310_resume,
+		.resume = l2c310_resume,
 	},
 };
 
@@ -736,7 +728,7 @@ static const struct l2c_init_data of_pl310_data __initconst = {
 	.of_parse = pl310_of_parse,
 	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
-	.save  = pl310_save,
+	.save  = l2c310_save,
 	.outer_cache = {
 		.inv_range   = l2x0_inv_range,
 		.clean_range = l2x0_clean_range,
@@ -744,7 +736,7 @@ static const struct l2c_init_data of_pl310_data __initconst = {
 		.flush_all   = l2x0_flush_all,
 		.disable     = l2x0_disable,
 		.sync        = l2x0_cache_sync,
-		.resume      = pl310_resume,
+		.resume      = l2c310_resume,
 	},
 };
 
@@ -854,10 +846,11 @@ static void aurora_save(void __iomem *base)
 
 static void aurora_resume(void)
 {
-	if (!(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
-		writel_relaxed(l2x0_saved_regs.aux_ctrl,
-				l2x0_base + L2X0_AUX_CTRL);
-		writel_relaxed(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL);
+	void __iomem *base = l2x0_base;
+
+	if (!(readl(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+		writel_relaxed(l2x0_saved_regs.aux_ctrl, base + L2X0_AUX_CTRL);
+		writel_relaxed(l2x0_saved_regs.ctrl, base + L2X0_CTRL);
 	}
 }
 
@@ -1082,7 +1075,7 @@ static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
 	.of_parse = pl310_of_parse,
 	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
-	.save  = pl310_save,
+	.save  = l2c310_save,
 	.outer_cache = {
 		.inv_range   = bcm_inv_range,
 		.clean_range = bcm_clean_range,
@@ -1090,7 +1083,7 @@ static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
 		.flush_all   = l2x0_flush_all,
 		.disable     = l2x0_disable,
 		.sync        = l2x0_cache_sync,
-		.resume      = pl310_resume,
+		.resume      = l2c310_resume,
 	},
 };
 
@@ -1104,11 +1097,13 @@ static void __init tauros3_save(void __iomem *base)
 
 static void tauros3_resume(void)
 {
-	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+	void __iomem *base = l2x0_base;
+
+	if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
 		writel_relaxed(l2x0_saved_regs.aux2_ctrl,
-			       l2x0_base + TAUROS3_AUX2_CTRL);
+			       base + TAUROS3_AUX2_CTRL);
 		writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
-			       l2x0_base + L2X0_PREFETCH_CTRL);
+			       base + L2X0_PREFETCH_CTRL);
 	}
 
 	l2x0_resume();
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 23/44] ARM: l2c: simplify l2x0 unlocking code
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (21 preceding siblings ...)
  2014-03-17  0:15 ` [PATCH 22/44] ARM: l2c: clean up save/resume functions Russell King
@ 2014-03-17  0:15 ` Russell King
  2014-03-17  0:15 ` [PATCH 24/44] ARM: l2c: move pl310_set_debug() into l2c-310 code Russell King
                   ` (22 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:15 UTC (permalink / raw)
  To: linux-arm-kernel

The l2x0 unlocking code is only called from l2x0_enable() now, so move
the logic entirely into that function and simplify it.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 9243f55ab06d..146865fa0dde 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -340,27 +340,18 @@ static void l2x0_disable(void)
 	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
-static void l2x0_unlock(u32 cache_id)
+static void l2x0_enable(void __iomem *base, u32 aux)
 {
-	int lockregs;
+	unsigned id, num_lock;
 
-	switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
-	case L2X0_CACHE_ID_PART_L310:
-		lockregs = 8;
-		break;
-	default:
-		/* L210 and unknown types */
-		lockregs = 1;
-		break;
-	}
-
-	l2c_unlock(l2x0_base, lockregs);
-}
+	id = readl_relaxed(base + L2X0_CACHE_ID) & L2X0_CACHE_ID_PART_MASK;
+	if (id == L2X0_CACHE_ID_PART_L310)
+		num_lock = 8;
+	else
+		num_lock = 1;
 
-static void l2x0_enable(void __iomem *base, u32 aux)
-{
 	/* Make sure that I&D is not locked down when starting */
-	l2x0_unlock(readl_relaxed(base + L2X0_CACHE_ID));
+	l2c_unlock(base, num_lock);
 
 	/* l2x0 controller is disabled */
 	writel_relaxed(aux, base + L2X0_AUX_CTRL);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 24/44] ARM: l2c: move pl310_set_debug() into l2c-310 code
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (22 preceding siblings ...)
  2014-03-17  0:15 ` [PATCH 23/44] ARM: l2c: simplify l2x0 unlocking code Russell King
@ 2014-03-17  0:15 ` Russell King
  2014-03-17  0:15 ` [PATCH 25/44] ARM: l2c: add L2C-210 specific handlers Russell King
                   ` (21 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:15 UTC (permalink / raw)
  To: linux-arm-kernel

Move the pl310_set_debug() into the l2c-310 code area, and don't hide
it with ifdefs.  Rename it to l2c310_set_debug().

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 146865fa0dde..4e12fad497b2 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -142,18 +142,11 @@ static inline void debug_writel(unsigned long val)
 	if (outer_cache.set_debug)
 		l2c_set_debug(l2x0_base, val);
 }
-
-static void pl310_set_debug(unsigned long val)
-{
-	writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL);
-}
 #else
 /* Optimised out for non-errata case */
 static inline void debug_writel(unsigned long val)
 {
 }
-
-#define pl310_set_debug	NULL
 #endif
 
 #ifdef CONFIG_PL310_ERRATA_588369
@@ -410,6 +403,11 @@ static const struct l2c_init_data l2x0_init_fns __initconst = {
  *	Affects: store buffer
  *	store buffer is not automatically drained.
  */
+static void l2c310_set_debug(unsigned long val)
+{
+	writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL);
+}
+
 static void l2c310_enable(void __iomem *base, u32 aux)
 {
 	/* PL310 has 8 lock registers */
@@ -482,7 +480,7 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 	unsigned n = 0;
 
 	if (revision <= L310_CACHE_ID_RTL_R3P0)
-		fns->set_debug = pl310_set_debug;
+		fns->set_debug = l2c310_set_debug;
 
 	if (IS_ENABLED(CONFIG_PL310_ERRATA_753970) &&
 	    revision == L310_CACHE_ID_RTL_R3P0) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 25/44] ARM: l2c: add L2C-210 specific handlers
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (23 preceding siblings ...)
  2014-03-17  0:15 ` [PATCH 24/44] ARM: l2c: move pl310_set_debug() into l2c-310 code Russell King
@ 2014-03-17  0:15 ` Russell King
  2014-03-17  0:15 ` [PATCH 26/44] ARM: l2c: implement L2C-310 erratum 727915 as a method override Russell King
                   ` (20 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:15 UTC (permalink / raw)
  To: linux-arm-kernel

Add L2C-210 specific cache operation handlers.  These are tailored to
the requirements of the L2C-210 cache controller, which doesn't
require any workarounds.  We avoid using the way operations during
normal operation, which means we can avoid locking: the only time
we use the way operations are during initialisation, and when
disabling the cache.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 135 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 4e12fad497b2..4930f63d5f4a 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -377,6 +377,122 @@ static const struct l2c_init_data l2x0_init_fns __initconst = {
 };
 
 /*
+ * L2C-210 specific code.
+ *
+ * The L2C-2x0 PA, set/way and sync operations are atomic, but we must
+ * ensure that no background operation is running.  The way operations
+ * are all background tasks.
+ *
+ * While a background operation is in progress, any new operation is
+ * ignored (unspecified whether this causes an error.)  Thankfully, not
+ * used on SMP.
+ *
+ * Never has a different sync register other than L2X0_CACHE_SYNC, but
+ * we use sync_reg_offset here so we can share some of this with L2C-310.
+ */
+static void __l2c210_cache_sync(void __iomem *base)
+{
+	writel_relaxed(0, base + sync_reg_offset);
+}
+
+static void __l2c210_op_pa_range(void __iomem *reg, unsigned long start,
+	unsigned long end)
+{
+	while (start < end) {
+		writel_relaxed(start, reg);
+		start += CACHE_LINE_SIZE;
+	}
+}
+
+static void l2c210_inv_range(unsigned long start, unsigned long end)
+{
+	void __iomem *base = l2x0_base;
+
+	if (start & (CACHE_LINE_SIZE - 1)) {
+		start &= ~(CACHE_LINE_SIZE - 1);
+		writel_relaxed(start, base + L2X0_CLEAN_INV_LINE_PA);
+		start += CACHE_LINE_SIZE;
+	}
+
+	if (end & (CACHE_LINE_SIZE - 1)) {
+		end &= ~(CACHE_LINE_SIZE - 1);
+		writel_relaxed(end, base + L2X0_CLEAN_INV_LINE_PA);
+	}
+
+	__l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
+	__l2c210_cache_sync(base);
+}
+
+static void l2c210_clean_range(unsigned long start, unsigned long end)
+{
+	void __iomem *base = l2x0_base;
+
+	start &= ~(CACHE_LINE_SIZE - 1);
+	__l2c210_op_pa_range(base + L2X0_CLEAN_LINE_PA, start, end);
+	__l2c210_cache_sync(base);
+}
+
+static void l2c210_flush_range(unsigned long start, unsigned long end)
+{
+	void __iomem *base = l2x0_base;
+
+	start &= ~(CACHE_LINE_SIZE - 1);
+	__l2c210_op_pa_range(base + L2X0_CLEAN_INV_LINE_PA, start, end);
+	__l2c210_cache_sync(base);
+}
+
+static void l2c210_flush_all(void)
+{
+	void __iomem *base = l2x0_base;
+
+	BUG_ON(!irqs_disabled());
+
+	__l2c_op_way(base + L2X0_CLEAN_INV_WAY);
+	__l2c210_cache_sync(base);
+}
+
+static void l2c210_disable(void)
+{
+	void __iomem *base = l2x0_base;
+
+	outer_flush_all();
+	writel_relaxed(0, base + L2X0_CTRL);
+	dsb(st);
+}
+
+static void l2c210_sync(void)
+{
+	__l2c210_cache_sync(l2x0_base);
+}
+
+static void l2c210_enable(void __iomem *base, u32 aux)
+{
+	/* Only one lock register on L2C-210 */
+	l2c_enable(base, aux, 1);
+}
+
+static void l2c210_resume(void)
+{
+	void __iomem *base = l2x0_base;
+
+	if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN))
+		l2c210_enable(base, l2x0_saved_regs.aux_ctrl);
+}
+
+static const struct l2c_init_data l2c210_data __initconst = {
+	.enable = l2c210_enable,
+	.outer_cache = {
+		.inv_range = l2c210_inv_range,
+		.clean_range = l2c210_clean_range,
+		.flush_range = l2c210_flush_range,
+		.flush_all = l2c210_flush_all,
+		.disable = l2c210_disable,
+		.sync = l2c210_sync,
+		.resume = l2c210_resume,
+	},
+};
+
+/*
  * L2C-310 specific code.
  *
  * Errata:
@@ -616,6 +732,10 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 		data = &l2x0_init_fns;
 		break;
 
+	case L2X0_CACHE_ID_PART_L210:
+		data = &l2c210_data;
+		break;
+
 	case L2X0_CACHE_ID_PART_L310:
 		data = &l2c310_init_fns;
 		break;
@@ -665,6 +785,20 @@ static void __init l2x0_of_parse(const struct device_node *np,
 	*aux_mask &= ~mask;
 }
 
+static const struct l2c_init_data of_l2c210_data __initconst = {
+	.of_parse = l2x0_of_parse,
+	.enable = l2c210_enable,
+	.outer_cache = {
+		.inv_range   = l2c210_inv_range,
+		.clean_range = l2c210_clean_range,
+		.flush_range = l2c210_flush_range,
+		.flush_all   = l2c210_flush_all,
+		.disable     = l2c210_disable,
+		.sync        = l2c210_sync,
+		.resume      = l2c210_resume,
+	},
+};
+
 static const struct l2c_init_data of_l2x0_data __initconst = {
 	.of_parse = l2x0_of_parse,
 	.enable = l2x0_enable,
@@ -1109,7 +1243,7 @@ static const struct l2c_init_data of_tauros3_data __initconst = {
 
 #define L2C_ID(name, fns) { .compatible = name, .data = (void *)&fns }
 static const struct of_device_id l2x0_ids[] __initconst = {
-	L2C_ID("arm,l210-cache", of_l2x0_data),
+	L2C_ID("arm,l210-cache", of_l2c210_data),
 	L2C_ID("arm,l220-cache", of_l2x0_data),
 	L2C_ID("arm,pl310-cache", of_pl310_data),
 	L2C_ID("brcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data),
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 26/44] ARM: l2c: implement L2C-310 erratum 727915 as a method override
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (24 preceding siblings ...)
  2014-03-17  0:15 ` [PATCH 25/44] ARM: l2c: add L2C-210 specific handlers Russell King
@ 2014-03-17  0:15 ` Russell King
  2014-03-17  0:15 ` [PATCH 27/44] ARM: l2c: Implement L2C-310 erratum 588369 " Russell King
                   ` (19 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:15 UTC (permalink / raw)
  To: linux-arm-kernel

Implement L2C-310 erratum 727915 by overriding the flush_all method
in the outer_cache operations structure.  This allows us to sensibly
contain the erratum code in one place without affecting other
locations or implementations.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 4930f63d5f4a..3371617a1c8b 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -524,6 +524,19 @@ static void l2c310_set_debug(unsigned long val)
 	writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL);
 }
 
+static void l2c310_flush_all_erratum(void)
+{
+	void __iomem *base = l2x0_base;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&l2x0_lock, flags);
+	l2c_set_debug(base, 0x03);
+	__l2c_op_way(base + L2X0_CLEAN_INV_WAY);
+	l2c_set_debug(base, 0x00);
+	__l2c210_cache_sync(base);
+	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
 static void l2c310_enable(void __iomem *base, u32 aux)
 {
 	/* PL310 has 8 lock registers */
@@ -598,6 +611,13 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 	if (revision <= L310_CACHE_ID_RTL_R3P0)
 		fns->set_debug = l2c310_set_debug;
 
+	if (IS_ENABLED(CONFIG_PL310_ERRATA_727915) &&
+	    revision >= L310_CACHE_ID_RTL_R2P0 &&
+	    revision < L310_CACHE_ID_RTL_R3P1) {
+		fns->flush_all = l2c310_flush_all_erratum;
+		errata[n++] = "727915";
+	}
+
 	if (IS_ENABLED(CONFIG_PL310_ERRATA_753970) &&
 	    revision == L310_CACHE_ID_RTL_R3P0) {
 		sync_reg_offset = L2X0_DUMMY_REG;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 27/44] ARM: l2c: Implement L2C-310 erratum 588369 as a method override
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (25 preceding siblings ...)
  2014-03-17  0:15 ` [PATCH 26/44] ARM: l2c: implement L2C-310 erratum 727915 as a method override Russell King
@ 2014-03-17  0:15 ` Russell King
  2014-03-17  0:15 ` [PATCH 28/44] ARM: l2c: use L2C-210 handlers for L2C-310 errata-less implementations Russell King
                   ` (18 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:15 UTC (permalink / raw)
  To: linux-arm-kernel

Implement L2C-310 erratum 588369 by overriding the invalidate range
and flush range methods in the outer_cache operations structure.
This allows us to sensibly contain the erratum code in one place
without affecting other locations/implemetations.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 3371617a1c8b..684bb5464f9a 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -524,6 +524,65 @@ static void l2c310_set_debug(unsigned long val)
 	writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL);
 }
 
+static void l2c310_inv_range_erratum(unsigned long start, unsigned long end)
+{
+	void __iomem *base = l2x0_base;
+
+	if ((start | end) & (CACHE_LINE_SIZE - 1)) {
+		unsigned long flags;
+
+		/* Erratum 588369 for both clean+invalidate operations */
+		raw_spin_lock_irqsave(&l2x0_lock, flags);
+		l2c_set_debug(base, 0x03);
+
+		if (start & (CACHE_LINE_SIZE - 1)) {
+			start &= ~(CACHE_LINE_SIZE - 1);
+			writel_relaxed(start, base + L2X0_CLEAN_LINE_PA);
+			writel_relaxed(start, base + L2X0_INV_LINE_PA);
+			start += CACHE_LINE_SIZE;
+		}
+
+		if (end & (CACHE_LINE_SIZE - 1)) {
+			end &= ~(CACHE_LINE_SIZE - 1);
+			writel_relaxed(end, base + L2X0_CLEAN_LINE_PA);
+			writel_relaxed(end, base + L2X0_INV_LINE_PA);
+		}
+
+		l2c_set_debug(base, 0x00);
+		raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+	}
+
+	__l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
+	__l2c210_cache_sync(base);
+}
+
+static void l2c310_flush_range_erratum(unsigned long start, unsigned long end)
+{
+	raw_spinlock_t *lock = &l2x0_lock;
+	unsigned long flags;
+	void __iomem *base = l2x0_base;
+
+	raw_spin_lock_irqsave(lock, flags);
+	while (start < end) {
+		unsigned long blk_end = start + min(end - start, 4096UL);
+
+		l2c_set_debug(base, 0x03);
+		while (start < blk_end) {
+			writel_relaxed(start, base + L2X0_CLEAN_LINE_PA);
+			writel_relaxed(start, base + L2X0_INV_LINE_PA);
+			start += CACHE_LINE_SIZE;
+		}
+		l2c_set_debug(base, 0x00);
+
+		if (blk_end < end) {
+			raw_spin_unlock_irqrestore(lock, flags);
+			raw_spin_lock_irqsave(lock, flags);
+		}
+	}
+	raw_spin_unlock_irqrestore(lock, flags);
+	__l2c210_cache_sync(base);
+}
+
 static void l2c310_flush_all_erratum(void)
 {
 	void __iomem *base = l2x0_base;
@@ -608,9 +667,19 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 	const char *errata[4];
 	unsigned n = 0;
 
+	/* For compatibility */
 	if (revision <= L310_CACHE_ID_RTL_R3P0)
 		fns->set_debug = l2c310_set_debug;
 
+	if (IS_ENABLED(CONFIG_PL310_ERRATA_588369) &&
+	    revision < L310_CACHE_ID_RTL_R2P0 &&
+	    /* For compatibility */
+	    fns->inv_range == l2x0_inv_range) {
+		fns->inv_range = l2c310_inv_range_erratum;
+		fns->flush_range = l2c310_flush_range_erratum;
+		errata[n++] = "533369";
+	}
+
 	if (IS_ENABLED(CONFIG_PL310_ERRATA_727915) &&
 	    revision >= L310_CACHE_ID_RTL_R2P0 &&
 	    revision < L310_CACHE_ID_RTL_R3P1) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 28/44] ARM: l2c: use L2C-210 handlers for L2C-310 errata-less implementations
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (26 preceding siblings ...)
  2014-03-17  0:15 ` [PATCH 27/44] ARM: l2c: Implement L2C-310 erratum 588369 " Russell King
@ 2014-03-17  0:15 ` Russell King
  2014-03-17  0:15 ` [PATCH 29/44] ARM: l2c: add L2C-220 specific handlers Russell King
                   ` (17 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:15 UTC (permalink / raw)
  To: linux-arm-kernel

Where no errata affect the L2C-310 handlers, they are functionally
equivalent to L2C-210.  Re-use the L2C-210 handlers for the L2C-310
part.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 59 ++++++++++++++++++++++++++++++------------------
 1 file changed, 37 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 684bb5464f9a..568d76016040 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -495,6 +495,19 @@ static const struct l2c_init_data l2c210_data __initconst = {
 /*
  * L2C-310 specific code.
  *
+ * Very similar to L2C-210, the PA, set/way and sync operations are atomic,
+ * and the way operations are all background tasks.  However, issuing an
+ * operation while a background operation is in progress results in a
+ * SLVERR response.  We can reuse:
+ *
+ *  __l2c210_cache_sync (using sync_reg_offset)
+ *  l2c210_sync
+ *  l2c210_inv_range (if 588369 is not applicable)
+ *  l2c210_clean_range
+ *  l2c210_flush_range (if 588369 is not applicable)
+ *  l2c210_flush_all (if 727915 is not applicable)
+ *  l2c210_disable
+ *
  * Errata:
  * 588369: PL310 R0P0->R1P0, fixed R2P0.
  *	Affects: all clean+invalidate operations
@@ -674,7 +687,7 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 	if (IS_ENABLED(CONFIG_PL310_ERRATA_588369) &&
 	    revision < L310_CACHE_ID_RTL_R2P0 &&
 	    /* For compatibility */
-	    fns->inv_range == l2x0_inv_range) {
+	    fns->inv_range == l2c210_inv_range) {
 		fns->inv_range = l2c310_inv_range_erratum;
 		fns->flush_range = l2c310_flush_range_erratum;
 		errata[n++] = "533369";
@@ -711,12 +724,13 @@ static const struct l2c_init_data l2c310_init_fns __initconst = {
 	.fixup = l2c310_fixup,
 	.save = l2c310_save,
 	.outer_cache = {
-		.inv_range = l2x0_inv_range,
-		.clean_range = l2x0_clean_range,
-		.flush_range = l2x0_flush_range,
-		.flush_all = l2x0_flush_all,
-		.disable = l2x0_disable,
-		.sync = l2x0_cache_sync,
+		.inv_range = l2c210_inv_range,
+		.clean_range = l2c210_clean_range,
+		.flush_range = l2c210_flush_range,
+		.flush_all = l2c210_flush_all,
+		.disable = l2c210_disable,
+		.sync = l2c210_sync,
+		.set_debug = l2c310_set_debug,
 		.resume = l2c310_resume,
 	},
 };
@@ -902,8 +916,8 @@ static const struct l2c_init_data of_l2x0_data __initconst = {
 	},
 };
 
-static void __init pl310_of_parse(const struct device_node *np,
-				  u32 *aux_val, u32 *aux_mask)
+static void __init l2c310_of_parse(const struct device_node *np,
+	u32 *aux_val, u32 *aux_mask)
 {
 	u32 data[3] = { 0, 0, 0 };
 	u32 tag[3] = { 0, 0, 0 };
@@ -936,18 +950,19 @@ static void __init pl310_of_parse(const struct device_node *np,
 	}
 }
 
-static const struct l2c_init_data of_pl310_data __initconst = {
-	.of_parse = pl310_of_parse,
+static const struct l2c_init_data of_l2c310_data __initconst = {
+	.of_parse = l2c310_of_parse,
 	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
 	.save  = l2c310_save,
 	.outer_cache = {
-		.inv_range   = l2x0_inv_range,
-		.clean_range = l2x0_clean_range,
-		.flush_range = l2x0_flush_range,
-		.flush_all   = l2x0_flush_all,
-		.disable     = l2x0_disable,
-		.sync        = l2x0_cache_sync,
+		.inv_range   = l2c210_inv_range,
+		.clean_range = l2c210_clean_range,
+		.flush_range = l2c210_flush_range,
+		.flush_all   = l2c210_flush_all,
+		.disable     = l2c210_disable,
+		.sync        = l2c210_sync,
+		.set_debug   = l2c310_set_debug,
 		.resume      = l2c310_resume,
 	},
 };
@@ -1284,7 +1299,7 @@ static void bcm_flush_range(unsigned long start, unsigned long end)
 }
 
 static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
-	.of_parse = pl310_of_parse,
+	.of_parse = l2c310_of_parse,
 	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
 	.save  = l2c310_save,
@@ -1292,9 +1307,9 @@ static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
 		.inv_range   = bcm_inv_range,
 		.clean_range = bcm_clean_range,
 		.flush_range = bcm_flush_range,
-		.flush_all   = l2x0_flush_all,
-		.disable     = l2x0_disable,
-		.sync        = l2x0_cache_sync,
+		.flush_all   = l2c210_flush_all,
+		.disable     = l2c210_disable,
+		.sync        = l2c210_sync,
 		.resume      = l2c310_resume,
 	},
 };
@@ -1334,7 +1349,7 @@ static const struct l2c_init_data of_tauros3_data __initconst = {
 static const struct of_device_id l2x0_ids[] __initconst = {
 	L2C_ID("arm,l210-cache", of_l2c210_data),
 	L2C_ID("arm,l220-cache", of_l2x0_data),
-	L2C_ID("arm,pl310-cache", of_pl310_data),
+	L2C_ID("arm,pl310-cache", of_l2c310_data),
 	L2C_ID("brcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data),
 	L2C_ID("marvell,aurora-outer-cache", of_aurora_with_outer_data),
 	L2C_ID("marvell,aurora-system-cache", of_aurora_no_outer_data),
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 29/44] ARM: l2c: add L2C-220 specific handlers
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (27 preceding siblings ...)
  2014-03-17  0:15 ` [PATCH 28/44] ARM: l2c: use L2C-210 handlers for L2C-310 errata-less implementations Russell King
@ 2014-03-17  0:15 ` Russell King
  2014-03-17  0:16 ` [PATCH 30/44] ARM: l2c: remove obsolete l2x0 ops for non-OF init Russell King
                   ` (16 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:15 UTC (permalink / raw)
  To: linux-arm-kernel

The L2C-220 is different from the L2C-210 and L2C-310 in that every
operation is a background operation: this means we have to use
spinlocks to protect all operations, and we have to wait for every
operation to complete.

Should a second operation be attempted while a previous operation
is in progress, the response will be an imprecise abort.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 166 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 156 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 568d76016040..29d12ae05c39 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -493,6 +493,148 @@ static const struct l2c_init_data l2c210_data __initconst = {
 };
 
 /*
+ * L2C-220 specific code.
+ *
+ * All operations are background operations: they have to be waited for.
+ * Conflicting requests generate a slave error (which will cause an
+ * imprecise abort.)  Never uses sync_reg_offset, so we hard-code the
+ * sync register here.
+ *
+ * However, we can re-use the l2c210_disable, l2c210_enable and
+ * l2c210_resume calls.
+ */
+static inline void __l2c220_cache_sync(void __iomem *base)
+{
+	writel_relaxed(0, base + L2X0_CACHE_SYNC);
+	l2c_wait_mask(base + L2X0_CACHE_SYNC, 1);
+}
+
+static void l2c220_op_way(void __iomem *base, unsigned reg)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&l2x0_lock, flags);
+	__l2c_op_way(base + reg);
+	__l2c220_cache_sync(base);
+	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static unsigned long l2c220_op_pa_range(void __iomem *reg, unsigned long start,
+	unsigned long end, unsigned long flags)
+{
+	raw_spinlock_t *lock = &l2x0_lock;
+
+	while (start < end) {
+		unsigned long blk_end = start + min(end - start, 4096UL);
+
+		while (start < blk_end) {
+			l2c_wait_mask(reg, 1);
+			writel_relaxed(start, reg);
+			start += CACHE_LINE_SIZE;
+		}
+
+		if (blk_end < end) {
+			raw_spin_unlock_irqrestore(lock, flags);
+			raw_spin_lock_irqsave(lock, flags);
+		}
+	}
+
+	return flags;
+}
+
+static void l2c220_inv_range(unsigned long start, unsigned long end)
+{
+	void __iomem *base = l2x0_base;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&l2x0_lock, flags);
+	if ((start | end) & (CACHE_LINE_SIZE - 1)) {
+		if (start & (CACHE_LINE_SIZE - 1)) {
+			start &= ~(CACHE_LINE_SIZE - 1);
+			writel_relaxed(start, base + L2X0_CLEAN_INV_LINE_PA);
+			start += CACHE_LINE_SIZE;
+		}
+
+		if (end & (CACHE_LINE_SIZE - 1)) {
+			end &= ~(CACHE_LINE_SIZE - 1);
+			l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
+			writel_relaxed(end, base + L2X0_CLEAN_INV_LINE_PA);
+		}
+	}
+
+	flags = l2c220_op_pa_range(base + L2X0_INV_LINE_PA,
+				   start, end, flags);
+	l2c_wait_mask(base + L2X0_INV_LINE_PA, 1);
+	__l2c220_cache_sync(base);
+	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2c220_clean_range(unsigned long start, unsigned long end)
+{
+	void __iomem *base = l2x0_base;
+	unsigned long flags;
+
+	start &= ~(CACHE_LINE_SIZE - 1);
+	if ((end - start) >= l2x0_size) {
+		l2c220_op_way(base, L2X0_CLEAN_WAY);
+		return;
+	}
+
+	raw_spin_lock_irqsave(&l2x0_lock, flags);
+	flags = l2c220_op_pa_range(base + L2X0_CLEAN_LINE_PA,
+				   start, end, flags);
+	l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
+	__l2c220_cache_sync(base);
+	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2c220_flush_range(unsigned long start, unsigned long end)
+{
+	void __iomem *base = l2x0_base;
+	unsigned long flags;
+
+	start &= ~(CACHE_LINE_SIZE - 1);
+	if ((end - start) >= l2x0_size) {
+		l2c220_op_way(base, L2X0_CLEAN_INV_WAY);
+		return;
+	}
+
+	raw_spin_lock_irqsave(&l2x0_lock, flags);
+	flags = l2c220_op_pa_range(base + L2X0_CLEAN_INV_LINE_PA,
+				   start, end, flags);
+	l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
+	__l2c220_cache_sync(base);
+	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2c220_flush_all(void)
+{
+	l2c220_op_way(l2x0_base, L2X0_CLEAN_INV_WAY);
+}
+
+static void l2c220_sync(void)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&l2x0_lock, flags);
+	__l2c220_cache_sync(l2x0_base);
+	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static const struct l2c_init_data l2c220_data = {
+	.enable = l2c210_enable,
+	.outer_cache = {
+		.inv_range = l2c220_inv_range,
+		.clean_range = l2c220_clean_range,
+		.flush_range = l2c220_flush_range,
+		.flush_all = l2c220_flush_all,
+		.disable = l2c210_disable,
+		.sync = l2c220_sync,
+		.resume = l2c210_resume,
+	},
+};
+
+/*
  * L2C-310 specific code.
  *
  * Very similar to L2C-210, the PA, set/way and sync operations are atomic,
@@ -839,6 +981,10 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 		data = &l2c210_data;
 		break;
 
+	case L2X0_CACHE_ID_PART_L220:
+		data = &l2c220_data;
+		break;
+
 	case L2X0_CACHE_ID_PART_L310:
 		data = &l2c310_init_fns;
 		break;
@@ -902,17 +1048,17 @@ static const struct l2c_init_data of_l2c210_data __initconst = {
 	},
 };
 
-static const struct l2c_init_data of_l2x0_data __initconst = {
+static const struct l2c_init_data of_l2c220_data __initconst = {
 	.of_parse = l2x0_of_parse,
-	.enable = l2x0_enable,
+	.enable = l2c210_enable,
 	.outer_cache = {
-		.inv_range   = l2x0_inv_range,
-		.clean_range = l2x0_clean_range,
-		.flush_range = l2x0_flush_range,
-		.flush_all   = l2x0_flush_all,
-		.disable     = l2x0_disable,
-		.sync        = l2x0_cache_sync,
-		.resume      = l2x0_resume,
+		.inv_range   = l2c220_inv_range,
+		.clean_range = l2c220_clean_range,
+		.flush_range = l2c220_flush_range,
+		.flush_all   = l2c220_flush_all,
+		.disable     = l2c210_disable,
+		.sync        = l2c220_sync,
+		.resume      = l2c210_resume,
 	},
 };
 
@@ -1348,7 +1494,7 @@ static const struct l2c_init_data of_tauros3_data __initconst = {
 #define L2C_ID(name, fns) { .compatible = name, .data = (void *)&fns }
 static const struct of_device_id l2x0_ids[] __initconst = {
 	L2C_ID("arm,l210-cache", of_l2c210_data),
-	L2C_ID("arm,l220-cache", of_l2x0_data),
+	L2C_ID("arm,l220-cache", of_l2c220_data),
 	L2C_ID("arm,pl310-cache", of_l2c310_data),
 	L2C_ID("brcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data),
 	L2C_ID("marvell,aurora-outer-cache", of_aurora_with_outer_data),
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 30/44] ARM: l2c: remove obsolete l2x0 ops for non-OF init
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (28 preceding siblings ...)
  2014-03-17  0:15 ` [PATCH 29/44] ARM: l2c: add L2C-220 specific handlers Russell King
@ 2014-03-17  0:16 ` Russell King
  2014-03-17  0:16 ` [PATCH 31/44] ARM: l2c: move type string into l2c_init_data structure Russell King
                   ` (15 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:16 UTC (permalink / raw)
  To: linux-arm-kernel

non-OF initialisation has never been used with any cache controller
which isn't an ARM cache controller, so we can safely get rid of the
old (and buggy) l2x0_*-based operations structure.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 29d12ae05c39..606f9eed1b23 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -363,19 +363,6 @@ static void l2x0_resume(void)
 		l2x0_enable(base, l2x0_saved_regs.aux_ctrl);
 }
 
-static const struct l2c_init_data l2x0_init_fns __initconst = {
-	.enable = l2x0_enable,
-	.outer_cache = {
-		.inv_range = l2x0_inv_range,
-		.clean_range = l2x0_clean_range,
-		.flush_range = l2x0_flush_range,
-		.flush_all = l2x0_flush_all,
-		.disable = l2x0_disable,
-		.sync = l2x0_cache_sync,
-		.resume = l2x0_resume,
-	},
-};
-
 /*
  * L2C-210 specific code.
  *
@@ -974,9 +961,6 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 
 	switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
 	default:
-		data = &l2x0_init_fns;
-		break;
-
 	case L2X0_CACHE_ID_PART_L210:
 		data = &l2c210_data;
 		break;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 31/44] ARM: l2c: move type string into l2c_init_data structure
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (29 preceding siblings ...)
  2014-03-17  0:16 ` [PATCH 30/44] ARM: l2c: remove obsolete l2x0 ops for non-OF init Russell King
@ 2014-03-17  0:16 ` Russell King
  2014-03-17  0:16 ` [PATCH 32/44] ARM: l2c: add decode for L2C-220 cache ways Russell King
                   ` (14 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:16 UTC (permalink / raw)
  To: linux-arm-kernel

Rather than decoding this from the ID register, store it in the
l2c_init_data structure.  This simplifies things some more, and
allows us to better provide further details as to how we're
driving the cache.  We print the cache ID value anyway should we
need to precisely identify the cache hardware.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 606f9eed1b23..b932513366a3 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -29,6 +29,7 @@
 #include "cache-aurora-l2.h"
 
 struct l2c_init_data {
+	const char *type;
 	void (*of_parse)(const struct device_node *, u32 *, u32 *);
 	void (*enable)(void __iomem *, u32);
 	void (*fixup)(void __iomem *, u32, struct outer_cache_fns *);
@@ -467,6 +468,7 @@ static void l2c210_resume(void)
 }
 
 static const struct l2c_init_data l2c210_data __initconst = {
+	.type = "L2C-210",
 	.enable = l2c210_enable,
 	.outer_cache = {
 		.inv_range = l2c210_inv_range,
@@ -609,6 +611,7 @@ static void l2c220_sync(void)
 }
 
 static const struct l2c_init_data l2c220_data = {
+	.type = "L2C-220",
 	.enable = l2c210_enable,
 	.outer_cache = {
 		.inv_range = l2c220_inv_range,
@@ -849,6 +852,7 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 }
 
 static const struct l2c_init_data l2c310_init_fns __initconst = {
+	.type = "L2C-310",
 	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
 	.save = l2c310_save,
@@ -872,7 +876,6 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	u32 way_size = 0;
 	int ways;
 	int way_size_shift = L2X0_WAY_SIZE_SHIFT;
-	const char *type;
 
 	/*
 	 * It is strange to save the register state before initialisation,
@@ -893,25 +896,21 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 			ways = 16;
 		else
 			ways = 8;
-		type = "L310";
 		break;
 
 	case L2X0_CACHE_ID_PART_L210:
 		ways = (aux >> 13) & 0xf;
-		type = "L210";
 		break;
 
 	case AURORA_CACHE_ID:
 		ways = (aux >> 13) & 0xf;
 		ways = 2 << ((ways + 1) >> 2);
 		way_size_shift = AURORA_WAY_SIZE_SHIFT;
-		type = "Aurora";
 		break;
 
 	default:
 		/* Assume unknown chips have 8 ways */
 		ways = 8;
-		type = "L2x0 series";
 		break;
 	}
 
@@ -945,9 +944,9 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	outer_cache = fns;
 
 	pr_info("%s cache controller enabled, %d ways, %d kB\n",
-		type, ways, l2x0_size >> 10);
+		data->type, ways, l2x0_size >> 10);
 	pr_info("%s: CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
-		type, cache_id, aux);
+		data->type, cache_id, aux);
 }
 
 void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
@@ -1019,6 +1018,7 @@ static void __init l2x0_of_parse(const struct device_node *np,
 }
 
 static const struct l2c_init_data of_l2c210_data __initconst = {
+	.type = "L2C-210",
 	.of_parse = l2x0_of_parse,
 	.enable = l2c210_enable,
 	.outer_cache = {
@@ -1033,6 +1033,7 @@ static const struct l2c_init_data of_l2c210_data __initconst = {
 };
 
 static const struct l2c_init_data of_l2c220_data __initconst = {
+	.type = "L2C-220",
 	.of_parse = l2x0_of_parse,
 	.enable = l2c210_enable,
 	.outer_cache = {
@@ -1081,6 +1082,7 @@ static void __init l2c310_of_parse(const struct device_node *np,
 }
 
 static const struct l2c_init_data of_l2c310_data __initconst = {
+	.type = "L2C-310",
 	.of_parse = l2c310_of_parse,
 	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
@@ -1262,6 +1264,7 @@ static void __init aurora_of_parse(const struct device_node *np,
 }
 
 static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
+	.type = "Aurora",
 	.of_parse = aurora_of_parse,
 	.enable = aurora_enable,
 	.fixup = aurora_fixup,
@@ -1278,6 +1281,7 @@ static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
 };
 
 static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
+	.type = "Aurora",
 	.of_parse = aurora_of_parse,
 	.enable = aurora_enable_no_outer,
 	.fixup = aurora_fixup,
@@ -1429,6 +1433,7 @@ static void bcm_flush_range(unsigned long start, unsigned long end)
 }
 
 static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
+	.type = "BCM-L2C-310",
 	.of_parse = l2c310_of_parse,
 	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
@@ -1467,6 +1472,7 @@ static void tauros3_resume(void)
 }
 
 static const struct l2c_init_data of_tauros3_data __initconst = {
+	.type = "Tauros3",
 	.enable = l2x0_enable,
 	.save  = tauros3_save,
 	/* Tauros3 broadcasts L1 cache operations to L2 */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 32/44] ARM: l2c: add decode for L2C-220 cache ways
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (30 preceding siblings ...)
  2014-03-17  0:16 ` [PATCH 31/44] ARM: l2c: move type string into l2c_init_data structure Russell King
@ 2014-03-17  0:16 ` Russell King
  2014-03-17  0:16 ` [PATCH 33/44] ARM: l2c: move way size calculation data into l2c_init_data Russell King
                   ` (13 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:16 UTC (permalink / raw)
  To: linux-arm-kernel

Rather than assuming these are always 8-way, it can be decoded from the
auxillary register in the same manner as L2C-210.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index b932513366a3..f9829c7165e8 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -899,6 +899,7 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 		break;
 
 	case L2X0_CACHE_ID_PART_L210:
+	case L2X0_CACHE_ID_PART_L220:
 		ways = (aux >> 13) & 0xf;
 		break;
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 33/44] ARM: l2c: move way size calculation data into l2c_init_data
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (31 preceding siblings ...)
  2014-03-17  0:16 ` [PATCH 32/44] ARM: l2c: add decode for L2C-220 cache ways Russell King
@ 2014-03-17  0:16 ` Russell King
  2014-03-17  0:16 ` [PATCH 34/44] ARM: outer cache: add documentation of outer cache functions Russell King
                   ` (12 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:16 UTC (permalink / raw)
  To: linux-arm-kernel

Move the way size calculation data (base of way size) out of the
switch statement into the provided initialisation data.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index f9829c7165e8..44b8fd6ae2f6 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -30,6 +30,7 @@
 
 struct l2c_init_data {
 	const char *type;
+	unsigned way_size_0;
 	void (*of_parse)(const struct device_node *, u32 *, u32 *);
 	void (*enable)(void __iomem *, u32);
 	void (*fixup)(void __iomem *, u32, struct outer_cache_fns *);
@@ -469,6 +470,7 @@ static void l2c210_resume(void)
 
 static const struct l2c_init_data l2c210_data __initconst = {
 	.type = "L2C-210",
+	.way_size_0 = SZ_8K,
 	.enable = l2c210_enable,
 	.outer_cache = {
 		.inv_range = l2c210_inv_range,
@@ -612,6 +614,7 @@ static void l2c220_sync(void)
 
 static const struct l2c_init_data l2c220_data = {
 	.type = "L2C-220",
+	.way_size_0 = SZ_8K,
 	.enable = l2c210_enable,
 	.outer_cache = {
 		.inv_range = l2c220_inv_range,
@@ -853,6 +856,7 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 
 static const struct l2c_init_data l2c310_init_fns __initconst = {
 	.type = "L2C-310",
+	.way_size_0 = SZ_8K,
 	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
 	.save = l2c310_save,
@@ -872,10 +876,8 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	u32 aux_val, u32 aux_mask, u32 cache_id)
 {
 	struct outer_cache_fns fns;
+	unsigned way_size_bits, ways;
 	u32 aux;
-	u32 way_size = 0;
-	int ways;
-	int way_size_shift = L2X0_WAY_SIZE_SHIFT;
 
 	/*
 	 * It is strange to save the register state before initialisation,
@@ -906,7 +908,6 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	case AURORA_CACHE_ID:
 		ways = (aux >> 13) & 0xf;
 		ways = 2 << ((ways + 1) >> 2);
-		way_size_shift = AURORA_WAY_SIZE_SHIFT;
 		break;
 
 	default:
@@ -918,12 +919,15 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	l2x0_way_mask = (1 << ways) - 1;
 
 	/*
-	 * L2 cache Size =  Way size * Number of ways
+	 * way_size_0 is the size that a way_size value of zero would be
+	 * given the calculation: way_size = way_size_0 << way_size_bits.
+	 * So, if way_size_bits=0 is reserved, but way_size_bits=1 is 16k,
+	 * then way_size_0 would be 8k.
+	 *
+	 * L2 cache size = number of ways * way size.
 	 */
-	way_size = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >> 17;
-	way_size = 1 << (way_size + way_size_shift);
-
-	l2x0_size = ways * way_size * SZ_1K;
+	way_size_bits = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >> 17;
+	l2x0_size = ways * (data->way_size_0 << way_size_bits);
 
 	fns = data->outer_cache;
 	if (data->fixup)
@@ -1020,6 +1024,7 @@ static void __init l2x0_of_parse(const struct device_node *np,
 
 static const struct l2c_init_data of_l2c210_data __initconst = {
 	.type = "L2C-210",
+	.way_size_0 = SZ_8K,
 	.of_parse = l2x0_of_parse,
 	.enable = l2c210_enable,
 	.outer_cache = {
@@ -1035,6 +1040,7 @@ static const struct l2c_init_data of_l2c210_data __initconst = {
 
 static const struct l2c_init_data of_l2c220_data __initconst = {
 	.type = "L2C-220",
+	.way_size_0 = SZ_8K,
 	.of_parse = l2x0_of_parse,
 	.enable = l2c210_enable,
 	.outer_cache = {
@@ -1084,6 +1090,7 @@ static void __init l2c310_of_parse(const struct device_node *np,
 
 static const struct l2c_init_data of_l2c310_data __initconst = {
 	.type = "L2C-310",
+	.way_size_0 = SZ_8K,
 	.of_parse = l2c310_of_parse,
 	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
@@ -1266,6 +1273,7 @@ static void __init aurora_of_parse(const struct device_node *np,
 
 static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
 	.type = "Aurora",
+	.way_size_0 = SZ_4K,
 	.of_parse = aurora_of_parse,
 	.enable = aurora_enable,
 	.fixup = aurora_fixup,
@@ -1283,6 +1291,7 @@ static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
 
 static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
 	.type = "Aurora",
+	.way_size_0 = SZ_4K,
 	.of_parse = aurora_of_parse,
 	.enable = aurora_enable_no_outer,
 	.fixup = aurora_fixup,
@@ -1435,6 +1444,7 @@ static void bcm_flush_range(unsigned long start, unsigned long end)
 
 static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
 	.type = "BCM-L2C-310",
+	.way_size_0 = SZ_8K,
 	.of_parse = l2c310_of_parse,
 	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
@@ -1474,6 +1484,7 @@ static void tauros3_resume(void)
 
 static const struct l2c_init_data of_tauros3_data __initconst = {
 	.type = "Tauros3",
+	.way_size_0 = SZ_8K, /* FIXME: a guess */
 	.enable = l2x0_enable,
 	.save  = tauros3_save,
 	/* Tauros3 broadcasts L1 cache operations to L2 */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 34/44] ARM: outer cache: add documentation of outer cache functions
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (32 preceding siblings ...)
  2014-03-17  0:16 ` [PATCH 33/44] ARM: l2c: move way size calculation data into l2c_init_data Russell King
@ 2014-03-17  0:16 ` Russell King
  2014-03-17  0:16 ` [PATCH 35/44] ARM: outer cache: add WARN_ON() to outer_disable() Russell King
                   ` (11 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:16 UTC (permalink / raw)
  To: linux-arm-kernel

Add some documentation to cover the outer cache functions so that their
requirements can be better understood.  Of particular note are the
flush_all() and disable() methods which must not be called except in
very specific circumstances.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/outercache.h | 48 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
index 0e4420858990..bd80540fe8b9 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -39,35 +39,75 @@ struct outer_cache_fns {
 extern struct outer_cache_fns outer_cache;
 
 #ifdef CONFIG_OUTER_CACHE
-
+/**
+ * outer_inv_range: invalidate range of outer cache lines
+ * @start: starting physical address, inclusive
+ * @end: end physical address, exclusive
+ */
 static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
 {
 	if (outer_cache.inv_range)
 		outer_cache.inv_range(start, end);
 }
+
+/**
+ * outer_clean_range: clean dirty outer cache lines
+ * @start: starting physical address, inclusive
+ * @end: end physical address, exclusive
+ */
 static inline void outer_clean_range(phys_addr_t start, phys_addr_t end)
 {
 	if (outer_cache.clean_range)
 		outer_cache.clean_range(start, end);
 }
+
+/**
+ * outer_flush_range: clean and invalidate outer cache lines
+ * @start: starting physical address, inclusive
+ * @end: end physical address, exclusive
+ */
 static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
 {
 	if (outer_cache.flush_range)
 		outer_cache.flush_range(start, end);
 }
 
+/**
+ * outer_flush_all: clean and invalidate all cache lines in the outer cache
+ *
+ * Note: depending on implementation, this may not be atomic - it must
+ * only be called with interrupts disabled and no other active outer
+ * cache masters.
+ *
+ * It is intended that this function is only used by implementations
+ * needing to override the outer_cache.disable() method due to security.
+ * (Some implementations perform this as a clean followed by an invalidate.)
+ */
 static inline void outer_flush_all(void)
 {
 	if (outer_cache.flush_all)
 		outer_cache.flush_all();
 }
 
+/**
+ * outer_disable: clean, invalidate and disable the outer cache
+ *
+ * Disable the outer cache, ensuring that any data contained in the outer
+ * cache is pushed out to lower levels of system memory.  The note and
+ * conditions above concerning outer_flush_all() applies here.
+ */
 static inline void outer_disable(void)
 {
 	if (outer_cache.disable)
 		outer_cache.disable();
 }
 
+/**
+ * outer_resume: restore the cache configuration and re-enable outer cache
+ *
+ * Restore any configuration that the cache had when previously enabled,
+ * and re-enable the outer cache.
+ */
 static inline void outer_resume(void)
 {
 	if (outer_cache.resume)
@@ -89,6 +129,12 @@ static inline void outer_resume(void) { }
 #endif
 
 #ifdef CONFIG_OUTER_CACHE_SYNC
+/**
+ * outer_sync: perform a sync point for outer cache
+ *
+ * Ensure that all outer cache operations are complete and any store
+ * buffers are drained.
+ */
 static inline void outer_sync(void)
 {
 	if (outer_cache.sync)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 35/44] ARM: outer cache: add WARN_ON() to outer_disable()
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (33 preceding siblings ...)
  2014-03-17  0:16 ` [PATCH 34/44] ARM: outer cache: add documentation of outer cache functions Russell King
@ 2014-03-17  0:16 ` Russell King
  2014-03-17  0:16 ` [PATCH 36/44] ARM: l2c: move errata configuration options to arch/arm/mm/Kconfig Russell King
                   ` (10 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:16 UTC (permalink / raw)
  To: linux-arm-kernel

Add WARN_ON() conditions to outer_disable() to ensure that its
requirements aren't violated.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/outercache.h |  7 ++-----
 arch/arm/mm/Makefile              |  1 +
 arch/arm/mm/l2c-common.c          | 20 ++++++++++++++++++++
 3 files changed, 23 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/mm/l2c-common.c

diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
index bd80540fe8b9..1ee2cf23fae1 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -21,6 +21,7 @@
 #ifndef __ASM_OUTERCACHE_H
 #define __ASM_OUTERCACHE_H
 
+#include <linux/bug.h>
 #include <linux/types.h>
 
 struct outer_cache_fns {
@@ -96,11 +97,7 @@ static inline void outer_flush_all(void)
  * cache is pushed out to lower levels of system memory.  The note and
  * conditions above concerning outer_flush_all() applies here.
  */
-static inline void outer_disable(void)
-{
-	if (outer_cache.disable)
-		outer_cache.disable();
-}
+extern void outer_disable(void);
 
 /**
  * outer_resume: restore the cache configuration and re-enable outer cache
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 7f39ce2f841f..de5a6a27081b 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_CPU_V7M)		+= proc-v7m.o
 AFLAGS_proc-v6.o	:=-Wa,-march=armv6
 AFLAGS_proc-v7.o	:=-Wa,-march=armv7-a
 
+obj-$(CONFIG_OUTER_CACHE)	+= l2c-common.o
 obj-$(CONFIG_CACHE_FEROCEON_L2)	+= cache-feroceon-l2.o
 obj-$(CONFIG_CACHE_L2X0)	+= cache-l2x0.o
 obj-$(CONFIG_CACHE_XSC3L2)	+= cache-xsc3l2.o
diff --git a/arch/arm/mm/l2c-common.c b/arch/arm/mm/l2c-common.c
new file mode 100644
index 000000000000..10a3cf28c362
--- /dev/null
+++ b/arch/arm/mm/l2c-common.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2010 ARM Ltd.
+ * Written by Catalin Marinas <catalin.marinas@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/bug.h>
+#include <linux/smp.h>
+#include <asm/outercache.h>
+
+void outer_disable(void)
+{
+	WARN_ON(!irqs_disabled());
+	WARN_ON(num_online_cpus() > 1);
+
+	if (outer_cache.disable)
+		outer_cache.disable();
+}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 36/44] ARM: l2c: move errata configuration options to arch/arm/mm/Kconfig
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (34 preceding siblings ...)
  2014-03-17  0:16 ` [PATCH 35/44] ARM: outer cache: add WARN_ON() to outer_disable() Russell King
@ 2014-03-17  0:16 ` Russell King
  2014-03-17  0:16 ` [PATCH 37/44] ARM: l2c: provide generic hook to intercept writes to secure registers Russell King
                   ` (9 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:16 UTC (permalink / raw)
  To: linux-arm-kernel

Move the L2C-310 errata configuration options to arch/arm/mm/Kconfig
along side the option which enables support for this device.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/Kconfig    | 51 ---------------------------------------------------
 arch/arm/mm/Kconfig | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 51 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 50ccc1fdb0cb..3a0b24e4ffe9 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1230,19 +1230,6 @@ config ARM_ERRATA_742231
 	  register of the Cortex-A9 which reduces the linefill issuing
 	  capabilities of the processor.
 
-config PL310_ERRATA_588369
-	bool "PL310 errata: Clean & Invalidate maintenance operations do not invalidate clean lines"
-	depends on CACHE_L2X0
-	help
-	   The PL310 L2 cache controller implements three types of Clean &
-	   Invalidate maintenance operations: by Physical Address
-	   (offset 0x7F0), by Index/Way (0x7F8) and by Way (0x7FC).
-	   They are architecturally defined to behave as the execution of a
-	   clean operation followed immediately by an invalidate operation,
-	   both performing to the same memory location. This functionality
-	   is not correctly implemented in PL310 as clean lines are not
-	   invalidated as a result of these operations.
-
 config ARM_ERRATA_643719
 	bool "ARM errata: LoUIS bit field in CLIDR register is incorrect"
 	depends on CPU_V7 && SMP
@@ -1265,17 +1252,6 @@ config ARM_ERRATA_720789
 	  tables. The workaround changes the TLB flushing routines to invalidate
 	  entries regardless of the ASID.
 
-config PL310_ERRATA_727915
-	bool "PL310 errata: Background Clean & Invalidate by Way operation can cause data corruption"
-	depends on CACHE_L2X0
-	help
-	  PL310 implements the Clean & Invalidate by Way L2 cache maintenance
-	  operation (offset 0x7FC). This operation runs in background so that
-	  PL310 can handle normal accesses while it is in progress. Under very
-	  rare circumstances, due to this erratum, write data can be lost when
-	  PL310 treats a cacheable write transaction during a Clean &
-	  Invalidate by Way operation.
-
 config ARM_ERRATA_743622
 	bool "ARM errata: Faulty hazard checking in the Store Buffer may lead to data corruption"
 	depends on CPU_V7
@@ -1301,21 +1277,6 @@ config ARM_ERRATA_751472
 	  operation is received by a CPU before the ICIALLUIS has completed,
 	  potentially leading to corrupted entries in the cache or TLB.
 
-config PL310_ERRATA_753970
-	bool "PL310 errata: cache sync operation may be faulty"
-	depends on CACHE_PL310
-	help
-	  This option enables the workaround for the 753970 PL310 (r3p0) erratum.
-
-	  Under some condition the effect of cache sync operation on
-	  the store buffer still remains when the operation completes.
-	  This means that the store buffer is always asked to drain and
-	  this prevents it from merging any further writes. The workaround
-	  is to replace the normal offset of cache sync operation (0x730)
-	  by another offset targeting an unmapped PL310 register 0x740.
-	  This has the same effect as the cache sync operation: store buffer
-	  drain and waiting for all buffers empty.
-
 config ARM_ERRATA_754322
 	bool "ARM errata: possible faulty MMU translations following an ASID switch"
 	depends on CPU_V7
@@ -1364,18 +1325,6 @@ config ARM_ERRATA_764369
 	  relevant cache maintenance functions and sets a specific bit
 	  in the diagnostic control register of the SCU.
 
-config PL310_ERRATA_769419
-	bool "PL310 errata: no automatic Store Buffer drain"
-	depends on CACHE_L2X0
-	help
-	  On revisions of the PL310 prior to r3p2, the Store Buffer does
-	  not automatically drain. This can cause normal, non-cacheable
-	  writes to be retained when the memory system is idle, leading
-	  to suboptimal I/O performance for drivers using coherent DMA.
-	  This option adds a write barrier to the cpu_idle loop so that,
-	  on systems with an outer cache, the store buffer is drained
-	  explicitly.
-
 config ARM_ERRATA_775420
        bool "ARM errata: A data cache maintenance operation which aborts, might lead to deadlock"
        depends on CPU_V7
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index ca8ecdee47d8..118d691e70f5 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -897,6 +897,57 @@ config CACHE_PL310
 	  This option enables optimisations for the PL310 cache
 	  controller.
 
+config PL310_ERRATA_588369
+	bool "PL310 errata: Clean & Invalidate maintenance operations do not invalidate clean lines"
+	depends on CACHE_L2X0
+	help
+	   The PL310 L2 cache controller implements three types of Clean &
+	   Invalidate maintenance operations: by Physical Address
+	   (offset 0x7F0), by Index/Way (0x7F8) and by Way (0x7FC).
+	   They are architecturally defined to behave as the execution of a
+	   clean operation followed immediately by an invalidate operation,
+	   both performing to the same memory location. This functionality
+	   is not correctly implemented in PL310 as clean lines are not
+	   invalidated as a result of these operations.
+
+config PL310_ERRATA_727915
+	bool "PL310 errata: Background Clean & Invalidate by Way operation can cause data corruption"
+	depends on CACHE_L2X0
+	help
+	  PL310 implements the Clean & Invalidate by Way L2 cache maintenance
+	  operation (offset 0x7FC). This operation runs in background so that
+	  PL310 can handle normal accesses while it is in progress. Under very
+	  rare circumstances, due to this erratum, write data can be lost when
+	  PL310 treats a cacheable write transaction during a Clean &
+	  Invalidate by Way operation.
+
+config PL310_ERRATA_753970
+	bool "PL310 errata: cache sync operation may be faulty"
+	depends on CACHE_PL310
+	help
+	  This option enables the workaround for the 753970 PL310 (r3p0) erratum.
+
+	  Under some condition the effect of cache sync operation on
+	  the store buffer still remains when the operation completes.
+	  This means that the store buffer is always asked to drain and
+	  this prevents it from merging any further writes. The workaround
+	  is to replace the normal offset of cache sync operation (0x730)
+	  by another offset targeting an unmapped PL310 register 0x740.
+	  This has the same effect as the cache sync operation: store buffer
+	  drain and waiting for all buffers empty.
+
+config PL310_ERRATA_769419
+	bool "PL310 errata: no automatic Store Buffer drain"
+	depends on CACHE_L2X0
+	help
+	  On revisions of the PL310 prior to r3p2, the Store Buffer does
+	  not automatically drain. This can cause normal, non-cacheable
+	  writes to be retained when the memory system is idle, leading
+	  to suboptimal I/O performance for drivers using coherent DMA.
+	  This option adds a write barrier to the cpu_idle loop so that,
+	  on systems with an outer cache, the store buffer is drained
+	  explicitly.
+
 config CACHE_TAUROS2
 	bool "Enable the Tauros2 L2 cache controller"
 	depends on (ARCH_DOVE || ARCH_MMP || CPU_PJ4)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 37/44] ARM: l2c: provide generic hook to intercept writes to secure registers
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (35 preceding siblings ...)
  2014-03-17  0:16 ` [PATCH 36/44] ARM: l2c: move errata configuration options to arch/arm/mm/Kconfig Russell King
@ 2014-03-17  0:16 ` Russell King
  2014-03-17  0:16 ` [PATCH 38/44] ARM: l2c: OMAP: implement new write_sec method Russell King
                   ` (8 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:16 UTC (permalink / raw)
  To: linux-arm-kernel

When Linux is running in the non-secure world, any write to a secure
L2C register will generate an abort.  Platforms normally have to call
firmware to work around this.  Provide a hook for them to intercept
any L2C secure register write.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/outercache.h |  5 ++++-
 arch/arm/mm/cache-l2x0.c          | 34 ++++++++++++++++++++++++++--------
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
index 1ee2cf23fae1..69f57a5c0dd3 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -33,8 +33,11 @@ struct outer_cache_fns {
 #ifdef CONFIG_OUTER_CACHE_SYNC
 	void (*sync)(void);
 #endif
-	void (*set_debug)(unsigned long);
 	void (*resume)(void);
+
+	/* This is an ARM L2C thing */
+	void (*set_debug)(unsigned long);
+	void (*write_sec)(unsigned long, unsigned);
 };
 
 extern struct outer_cache_fns outer_cache;
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 44b8fd6ae2f6..f9fe70792bc9 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -59,13 +59,28 @@ static inline void l2c_wait_mask(void __iomem *reg, unsigned long mask)
 }
 
 /*
+ * By default, we write directly to secure registers.  Platforms must
+ * override this if they are running non-secure.
+ */
+static void l2c_write_sec(unsigned long val, void __iomem *base, unsigned reg)
+{
+	if (outer_cache.write_sec)
+		outer_cache.write_sec(val, reg);
+	else
+		writel_relaxed(val, base + reg);
+}
+
+/*
  * This should only be called when we have a requirement that the
  * register be written due to a work-around, as platforms running
  * in non-secure mode may not be able to access this register.
  */
 static inline void l2c_set_debug(void __iomem *base, unsigned long val)
 {
-	outer_cache.set_debug(val);
+	if (outer_cache.set_debug)
+		outer_cache.set_debug(val);
+	else
+		l2c_write_sec(val, base, L2X0_DEBUG_CTRL);
 }
 
 static void __l2c_op_way(void __iomem *reg)
@@ -96,7 +111,7 @@ static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
 
 	l2c_unlock(base, num_lock);
 
-	writel_relaxed(aux, base + L2X0_AUX_CTRL);
+	l2c_write_sec(aux, base, L2X0_AUX_CTRL);
 
 	local_irq_save(flags);
 	__l2c_op_way(base + L2X0_INV_WAY);
@@ -104,7 +119,7 @@ static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
 	l2c_wait_mask(base + sync_reg_offset, 1);
 	local_irq_restore(flags);
 
-	writel_relaxed(L2X0_CTRL_EN, base + L2X0_CTRL);
+	l2c_write_sec(L2X0_CTRL_EN, base, L2X0_CTRL);
 }
 
 #ifdef CONFIG_CACHE_PL310
@@ -141,7 +156,7 @@ static inline void l2x0_inv_line(unsigned long addr)
 #if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
 static inline void debug_writel(unsigned long val)
 {
-	if (outer_cache.set_debug)
+	if (outer_cache.set_debug || outer_cache.write_sec)
 		l2c_set_debug(l2x0_base, val);
 }
 #else
@@ -330,7 +345,7 @@ static void l2x0_disable(void)
 
 	raw_spin_lock_irqsave(&l2x0_lock, flags);
 	__l2x0_flush_all();
-	writel_relaxed(0, l2x0_base + L2X0_CTRL);
+	l2c_write_sec(0, l2x0_base, L2X0_CTRL);
 	dsb(st);
 	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
@@ -349,12 +364,12 @@ static void l2x0_enable(void __iomem *base, u32 aux)
 	l2c_unlock(base, num_lock);
 
 	/* l2x0 controller is disabled */
-	writel_relaxed(aux, base + L2X0_AUX_CTRL);
+	l2c_write_sec(aux, base, L2X0_AUX_CTRL);
 
 	l2x0_inv_all();
 
 	/* enable L2X0 */
-	writel_relaxed(L2X0_CTRL_EN, base + L2X0_CTRL);
+	l2c_write_sec(L2X0_CTRL_EN, base, L2X0_CTRL);
 }
 
 static void l2x0_resume(void)
@@ -445,7 +460,7 @@ static void l2c210_disable(void)
 	void __iomem *base = l2x0_base;
 
 	outer_flush_all();
-	writel_relaxed(0, base + L2X0_CTRL);
+	l2c_write_sec(0, base, L2X0_CTRL);
 	dsb(st);
 }
 
@@ -930,8 +945,11 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	l2x0_size = ways * (data->way_size_0 << way_size_bits);
 
 	fns = data->outer_cache;
+	fns.write_sec = outer_cache.write_sec;
 	if (data->fixup)
 		data->fixup(l2x0_base, cache_id, &fns);
+	if (fns.write_sec)
+		fns.set_debug = NULL;
 
 	/*
 	 * Check if l2x0 controller is already enabled.  If we are booting
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 38/44] ARM: l2c: OMAP: implement new write_sec method
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (36 preceding siblings ...)
  2014-03-17  0:16 ` [PATCH 37/44] ARM: l2c: provide generic hook to intercept writes to secure registers Russell King
@ 2014-03-17  0:16 ` Russell King
  2014-03-17  0:16 ` [PATCH 39/44] ARM: l2c: highbank: " Russell King
                   ` (7 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:16 UTC (permalink / raw)
  To: linux-arm-kernel

With the write_sec method, we no longer need to override the default
L2C disable method, and we no longer need the L2C set_debug method.
Both of these can be handled via the write_sec method.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mach-omap2/omap4-common.c | 38 ++++++++++++++++++++++----------------
 1 file changed, 22 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 6cd3f3772ecf..07b4efd23078 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -166,17 +166,29 @@ void __iomem *omap4_get_l2cache_base(void)
 	return l2cache_base;
 }
 
-static void omap4_l2x0_disable(void)
+static void omap4_l2c310_write_sec(unsigned long val, unsigned reg)
 {
-	outer_flush_all();
-	/* Disable PL310 L2 Cache controller */
-	omap_smc1(0x102, 0x0);
-}
+	unsigned smc_op;
 
-static void omap4_l2x0_set_debug(unsigned long val)
-{
-	/* Program PL310 L2 Cache controller debug register */
-	omap_smc1(0x100, val);
+	switch (reg) {
+	case L2X0_CTRL:
+		smc_op = 0x102;
+		break;
+
+	case L2X0_AUX_CTRL:
+		smc_op = 0x109;
+		break;
+
+	case L2X0_DEBUG_CTRL:
+		smc_op = 0x100:
+		break;
+
+	default:
+		WARN_ONCE(1, "OMAP L2C310: ignoring write to reg 0x%x\n", reg);
+		return;
+	}
+
+	omap_smc1(smc_op, val);
 }
 
 static int __init omap_l2_cache_init(void)
@@ -220,18 +232,12 @@ static int __init omap_l2_cache_init(void)
 	/* Enable PL310 L2 Cache controller */
 	omap_smc1(0x102, 0x1);
 
+	outer_cache.write_sec = omap4_l2c310_write_sec;
 	if (of_have_populated_dt())
 		l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
 	else
 		l2x0_init(l2cache_base, aux_ctrl, L2X0_AUX_CTRL_MASK);
 
-	/*
-	 * Override default outer_cache.disable with a OMAP4
-	 * specific one
-	*/
-	outer_cache.disable = omap4_l2x0_disable;
-	outer_cache.set_debug = omap4_l2x0_set_debug;
-
 	return 0;
 }
 omap_early_initcall(omap_l2_cache_init);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 39/44] ARM: l2c: highbank: implement new write_sec method
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (37 preceding siblings ...)
  2014-03-17  0:16 ` [PATCH 38/44] ARM: l2c: OMAP: implement new write_sec method Russell King
@ 2014-03-17  0:16 ` Russell King
  2014-03-26 20:35   ` Rob Herring
  2014-03-17  0:16 ` [PATCH 40/44] ARM: l2c: ux500: implement dummy " Russell King
                   ` (6 subsequent siblings)
  45 siblings, 1 reply; 52+ messages in thread
From: Russell King @ 2014-03-17  0:16 UTC (permalink / raw)
  To: linux-arm-kernel

With the write_sec method, we no longer need to override the default L2C
disable method.  This can be handled via the write_sec method instead.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mach-highbank/highbank.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index c7de89b263dd..d6b803594358 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -51,11 +51,13 @@ static void __init highbank_scu_map_io(void)
 }
 
 
-static void highbank_l2x0_disable(void)
+static void highbank_l2c310_write_sec(unsigned long val, unsigned reg)
 {
-	outer_flush_all();
-	/* Disable PL310 L2 Cache controller */
-	highbank_smc1(0x102, 0x0);
+	if (reg == L2X0_CTRL)
+		highbank_smc1(0x102, val);
+	else
+		WARN_ONCE(1, "Highbank L2C310: ignoring write to reg 0x%x\n",
+			  reg);
 }
 
 static void __init highbank_init_irq(void)
@@ -69,8 +71,8 @@ static void __init highbank_init_irq(void)
 	if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
 	    of_find_compatible_node(NULL, NULL, "arm,pl310-cache")) {
 		highbank_smc1(0x102, 0x1);
+		outer_cache.write_sec = highbank_l2x0_write_sec;
 		l2x0_of_init(0, ~0UL);
-		outer_cache.disable = highbank_l2x0_disable;
 	}
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 40/44] ARM: l2c: ux500: implement dummy write_sec method
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (38 preceding siblings ...)
  2014-03-17  0:16 ` [PATCH 39/44] ARM: l2c: highbank: " Russell King
@ 2014-03-17  0:16 ` Russell King
  2014-03-17  0:17 ` [PATCH 41/44] ARM: l2c: remove old .set_debug method Russell King
                   ` (5 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:16 UTC (permalink / raw)
  To: linux-arm-kernel

ux500 can't write to any of the secure registers on the L2C controllers,
so provide a dummy handler which ignores all writes.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mach-ux500/cache-l2x0.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-ux500/cache-l2x0.c b/arch/arm/mach-ux500/cache-l2x0.c
index 264f894c0e3d..5cc7e3625d8c 100644
--- a/arch/arm/mach-ux500/cache-l2x0.c
+++ b/arch/arm/mach-ux500/cache-l2x0.c
@@ -35,6 +35,14 @@ static int __init ux500_l2x0_unlock(void)
 	return 0;
 }
 
+static void ux500_l2c310_write_sec(unsigned long val, unsigned reg)
+{
+	/*
+	 * We can't write to secure registers as we are in non-secure
+	 * mode, until we have some SMI service available.
+	 */
+}
+
 static int __init ux500_l2x0_init(void)
 {
 	u32 aux_val = 0x3e000000;
@@ -56,21 +64,14 @@ static int __init ux500_l2x0_init(void)
 		/* 64KB way size */
 		aux_val |= (0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
 
+	outer_cache.write_sec = ux500_l2c310_write_sec;
+
 	/* 64KB way size, 8 way associativity, force WA */
 	if (of_have_populated_dt())
 		l2x0_of_init(aux_val, 0xc0000fff);
 	else
 		l2x0_init(l2x0_base, aux_val, 0xc0000fff);
 
-	/*
-	 * We can't disable l2 as we are in non secure mode, currently
-	 * this seems be called only during kexec path. So let's
-	 * override outer.disable with nasty assignment until we have
-	 * some SMI service available.
-	 */
-	outer_cache.disable = NULL;
-	outer_cache.set_debug = NULL;
-
 	return 0;
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 41/44] ARM: l2c: remove old .set_debug method
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (39 preceding siblings ...)
  2014-03-17  0:16 ` [PATCH 40/44] ARM: l2c: ux500: implement dummy " Russell King
@ 2014-03-17  0:17 ` Russell King
  2014-03-17  0:17 ` [PATCH 42/44] ARM: l2c: implement L2C-310 erratum 752271 in core L2C code Russell King
                   ` (4 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:17 UTC (permalink / raw)
  To: linux-arm-kernel

We no longer need or require the .set_debug method; we handle everything
it used to do via the .write_sec method instead.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/outercache.h |  1 -
 arch/arm/mm/cache-l2x0.c          | 21 ++-------------------
 2 files changed, 2 insertions(+), 20 deletions(-)

diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
index 69f57a5c0dd3..2e0de485a210 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -36,7 +36,6 @@ struct outer_cache_fns {
 	void (*resume)(void);
 
 	/* This is an ARM L2C thing */
-	void (*set_debug)(unsigned long);
 	void (*write_sec)(unsigned long, unsigned);
 };
 
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index f9fe70792bc9..ae838bb97cc2 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -77,10 +77,7 @@ static void l2c_write_sec(unsigned long val, void __iomem *base, unsigned reg)
  */
 static inline void l2c_set_debug(void __iomem *base, unsigned long val)
 {
-	if (outer_cache.set_debug)
-		outer_cache.set_debug(val);
-	else
-		l2c_write_sec(val, base, L2X0_DEBUG_CTRL);
+	l2c_write_sec(val, base, L2X0_DEBUG_CTRL);
 }
 
 static void __l2c_op_way(void __iomem *reg)
@@ -156,8 +153,7 @@ static inline void l2x0_inv_line(unsigned long addr)
 #if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
 static inline void debug_writel(unsigned long val)
 {
-	if (outer_cache.set_debug || outer_cache.write_sec)
-		l2c_set_debug(l2x0_base, val);
+	l2c_set_debug(l2x0_base, val);
 }
 #else
 /* Optimised out for non-errata case */
@@ -682,11 +678,6 @@ static const struct l2c_init_data l2c220_data = {
  *	Affects: store buffer
  *	store buffer is not automatically drained.
  */
-static void l2c310_set_debug(unsigned long val)
-{
-	writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL);
-}
-
 static void l2c310_inv_range_erratum(unsigned long start, unsigned long end)
 {
 	void __iomem *base = l2x0_base;
@@ -830,10 +821,6 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 	const char *errata[4];
 	unsigned n = 0;
 
-	/* For compatibility */
-	if (revision <= L310_CACHE_ID_RTL_R3P0)
-		fns->set_debug = l2c310_set_debug;
-
 	if (IS_ENABLED(CONFIG_PL310_ERRATA_588369) &&
 	    revision < L310_CACHE_ID_RTL_R2P0 &&
 	    /* For compatibility */
@@ -882,7 +869,6 @@ static const struct l2c_init_data l2c310_init_fns __initconst = {
 		.flush_all = l2c210_flush_all,
 		.disable = l2c210_disable,
 		.sync = l2c210_sync,
-		.set_debug = l2c310_set_debug,
 		.resume = l2c310_resume,
 	},
 };
@@ -948,8 +934,6 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	fns.write_sec = outer_cache.write_sec;
 	if (data->fixup)
 		data->fixup(l2x0_base, cache_id, &fns);
-	if (fns.write_sec)
-		fns.set_debug = NULL;
 
 	/*
 	 * Check if l2x0 controller is already enabled.  If we are booting
@@ -1120,7 +1104,6 @@ static const struct l2c_init_data of_l2c310_data __initconst = {
 		.flush_all   = l2c210_flush_all,
 		.disable     = l2c210_disable,
 		.sync        = l2c210_sync,
-		.set_debug   = l2c310_set_debug,
 		.resume      = l2c310_resume,
 	},
 };
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 42/44] ARM: l2c: implement L2C-310 erratum 752271 in core L2C code
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (40 preceding siblings ...)
  2014-03-17  0:17 ` [PATCH 41/44] ARM: l2c: remove old .set_debug method Russell King
@ 2014-03-17  0:17 ` Russell King
  2014-03-17  0:17 ` [PATCH 43/44] ARM: l2c: rename all L2C-310 constants with an L310_ prefix Russell King
                   ` (3 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:17 UTC (permalink / raw)
  To: linux-arm-kernel

Rather than having SoCs work around L2C erratum themselves, move them
into core code.  This erratum affects the double linefill feature which
needs to be disabled for r3p0 to r3p1-50rel0.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index ae838bb97cc2..34980c75bacd 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -669,6 +669,11 @@ static const struct l2c_init_data l2c220_data = {
  *	hit the line between the clean operation and invalidate operation,
  *	resulting in the store being lost.
  *
+ * 752271: PL310 R3P0->R3P1-50REL0, fixed R3P2.
+ *	Affects: 8x64-bit (double fill) line fetches
+ *	double fill line fetches can fail to cause dirty data to be evicted
+ *	from the cache before the new data overwrites the second line.
+ *
  * 753970: PL310 R3P0, fixed R3P1.
  *	Affects: sync
  *	prevents merging writes after the sync operation, until another L2C
@@ -818,7 +823,7 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 	struct outer_cache_fns *fns)
 {
 	unsigned revision = cache_id & L2X0_CACHE_ID_RTL_MASK;
-	const char *errata[4];
+	const char *errata[8];
 	unsigned n = 0;
 
 	if (IS_ENABLED(CONFIG_PL310_ERRATA_588369) &&
@@ -837,6 +842,17 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 		errata[n++] = "727915";
 	}
 
+	if (revision >= L310_CACHE_ID_RTL_R3P0 &&
+	    revision < L310_CACHE_ID_RTL_R3P2) {
+		u32 val = readl_relaxed(base + L2X0_PREFETCH_CTRL);
+		/* I don't think bit23 is required here... but iMX6 does so */
+		if (val & (BIT(30) | BIT(23))) {
+			val &= ~(BIT(30) | BIT(23));
+			l2c_write_sec(val, base, L2X0_PREFETCH_CTRL);
+			errata[n++] = "752271";
+		}
+	}
+
 	if (IS_ENABLED(CONFIG_PL310_ERRATA_753970) &&
 	    revision == L310_CACHE_ID_RTL_R3P0) {
 		sync_reg_offset = L2X0_DUMMY_REG;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 43/44] ARM: l2c: rename all L2C-310 constants with an L310_ prefix
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (41 preceding siblings ...)
  2014-03-17  0:17 ` [PATCH 42/44] ARM: l2c: implement L2C-310 erratum 752271 in core L2C code Russell King
@ 2014-03-17  0:17 ` Russell King
  2014-03-17  0:17 ` [PATCH 44/44] ARM: l2c: add L2C-310 power control DT properties Russell King
                   ` (2 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Russell King @ 2014-03-17  0:17 UTC (permalink / raw)
  To: linux-arm-kernel

We have a mixture of different revisions with different register
layouts, but we group all the bits together in an opaque mess.
Split them out into those which are L2C-310 specific and ones
which refer to earlier devices.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/hardware/cache-l2x0.h | 41 +++++++++++----------
 arch/arm/mach-cns3xxx/core.c               |  8 ++---
 arch/arm/mach-imx/system.c                 |  8 ++---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c  |  2 +-
 arch/arm/mach-omap2/omap4-common.c         | 20 +++++------
 arch/arm/mach-prima2/l2x0.c                |  5 ++-
 arch/arm/mach-realview/realview_pbx.c      |  4 +--
 arch/arm/mach-spear/spear13xx.c            |  6 ++--
 arch/arm/mach-sti/board-dt.c               |  8 ++---
 arch/arm/mach-tegra/sleep.h                |  8 ++---
 arch/arm/mach-ux500/cache-l2x0.c           |  4 +--
 arch/arm/mach-vexpress/ct-ca9x4.c          |  4 +--
 arch/arm/mm/cache-l2x0.c                   | 57 +++++++++++++++---------------
 arch/arm/plat-samsung/s5p-sleep.S          |  8 ++---
 14 files changed, 93 insertions(+), 90 deletions(-)

diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 94fbcec216ae..048e817841ad 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -26,8 +26,8 @@
 #define L2X0_CACHE_TYPE			0x004
 #define L2X0_CTRL			0x100
 #define L2X0_AUX_CTRL			0x104
-#define L2X0_TAG_LATENCY_CTRL		0x108
-#define L2X0_DATA_LATENCY_CTRL		0x10C
+#define L310_TAG_LATENCY_CTRL		0x108
+#define L310_DATA_LATENCY_CTRL		0x10C
 #define L2X0_EVENT_CNT_CTRL		0x200
 #define L2X0_EVENT_CNT1_CFG		0x204
 #define L2X0_EVENT_CNT0_CFG		0x208
@@ -54,16 +54,16 @@
 #define L2X0_LOCKDOWN_WAY_D_BASE	0x900
 #define L2X0_LOCKDOWN_WAY_I_BASE	0x904
 #define L2X0_LOCKDOWN_STRIDE		0x08
-#define L2X0_ADDR_FILTER_START		0xC00
-#define L2X0_ADDR_FILTER_END		0xC04
+#define L310_ADDR_FILTER_START		0xC00
+#define L310_ADDR_FILTER_END		0xC04
 #define L2X0_TEST_OPERATION		0xF00
 #define L2X0_LINE_DATA			0xF10
 #define L2X0_LINE_TAG			0xF30
 #define L2X0_DEBUG_CTRL			0xF40
-#define L2X0_PREFETCH_CTRL		0xF60
-#define L2X0_POWER_CTRL			0xF80
-#define   L2X0_DYNAMIC_CLK_GATING_EN	(1 << 1)
-#define   L2X0_STNDBY_MODE_EN		(1 << 0)
+#define L310_PREFETCH_CTRL		0xF60
+#define L310_POWER_CTRL			0xF80
+#define   L310_DYNAMIC_CLK_GATING_EN	(1 << 1)
+#define   L310_STNDBY_MODE_EN		(1 << 0)
 
 /* Registers shifts and masks */
 #define L2X0_CACHE_ID_PART_MASK		(0xf << 6)
@@ -96,21 +96,24 @@
 #define L2X0_AUX_CTRL_TAG_LATENCY_MASK		(0x7 << 6)
 #define L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT	9
 #define L2X0_AUX_CTRL_DIRTY_LATENCY_MASK	(0x7 << 9)
-#define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT	16
 #define L2X0_AUX_CTRL_WAY_SIZE_SHIFT		17
 #define L2X0_AUX_CTRL_WAY_SIZE_MASK		(0x7 << 17)
-#define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT	22
-#define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT		26
-#define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT		27
-#define L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT	28
-#define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT	29
-#define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT		30
 
-#define L2X0_LATENCY_CTRL_SETUP_SHIFT	0
-#define L2X0_LATENCY_CTRL_RD_SHIFT	4
-#define L2X0_LATENCY_CTRL_WR_SHIFT	8
+#define L310_AUX_CTRL_ASSOCIATIVITY_16		BIT(16)
+#define L310_AUX_CTRL_WAY_SIZE(n)		((n) << 17)
+#define L310_AUX_CTRL_SHARED_OVERRIDE		BIT(22)
+#define L310_AUX_CTRL_CACHE_REPLACE_RR		BIT(25)
+#define L310_AUX_CTRL_NS_LOCKDOWN		BIT(26)
+#define L310_AUX_CTRL_NS_INT_CTRL		BIT(27)
+#define L310_AUX_CTRL_DATA_PREFETCH		BIT(28)
+#define L310_AUX_CTRL_INSTR_PREFETCH		BIT(29)
+#define L310_AUX_CTRL_EARLY_BRESP		BIT(30)
 
-#define L2X0_ADDR_FILTER_EN		1
+#define L310_LATENCY_CTRL_SETUP(n)		((n) << 0)
+#define L310_LATENCY_CTRL_RD(n)			((n) << 4)
+#define L310_LATENCY_CTRL_WR(n)			((n) << 8)
+
+#define L310_ADDR_FILTER_EN		1
 
 #define L2X0_CTRL_EN			1
 
diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c
index 384dc859e6c6..1e8860e4c9e3 100644
--- a/arch/arm/mach-cns3xxx/core.c
+++ b/arch/arm/mach-cns3xxx/core.c
@@ -240,9 +240,9 @@ void __init cns3xxx_l2x0_init(void)
 	 *
 	 * 1 cycle of latency for setup, read and write accesses
 	 */
-	val = readl(base + L2X0_TAG_LATENCY_CTRL);
+	val = readl(base + L310_TAG_LATENCY_CTRL);
 	val &= 0xfffff888;
-	writel(val, base + L2X0_TAG_LATENCY_CTRL);
+	writel(val, base + L310_TAG_LATENCY_CTRL);
 
 	/*
 	 * Data RAM Control register
@@ -253,9 +253,9 @@ void __init cns3xxx_l2x0_init(void)
 	 *
 	 * 1 cycle of latency for setup, read and write accesses
 	 */
-	val = readl(base + L2X0_DATA_LATENCY_CTRL);
+	val = readl(base + L310_DATA_LATENCY_CTRL);
 	val &= 0xfffff888;
-	writel(val, base + L2X0_DATA_LATENCY_CTRL);
+	writel(val, base + L310_DATA_LATENCY_CTRL);
 
 	/* 32 KiB, 8-way, parity disable */
 	l2x0_init(base, 0x00540000, 0xfe000fff);
diff --git a/arch/arm/mach-imx/system.c b/arch/arm/mach-imx/system.c
index 5e3027d3692f..3f270e5e25a1 100644
--- a/arch/arm/mach-imx/system.c
+++ b/arch/arm/mach-imx/system.c
@@ -124,7 +124,7 @@ void __init imx_init_l2cache(void)
 	}
 
 	/* Configure the L2 PREFETCH and POWER registers */
-	val = readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL);
+	val = readl_relaxed(l2x0_base + L310_PREFETCH_CTRL);
 	val |= 0x70800000;
 	/*
 	 * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
@@ -137,9 +137,9 @@ void __init imx_init_l2cache(void)
 	 */
 	if (cpu_is_imx6q())
 		val &= ~(1 << 30 | 1 << 23);
-	writel_relaxed(val, l2x0_base + L2X0_PREFETCH_CTRL);
-	val = L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN;
-	writel_relaxed(val, l2x0_base + L2X0_POWER_CTRL);
+	writel_relaxed(val, l2x0_base + L310_PREFETCH_CTRL);
+	val = L310_DYNAMIC_CLK_GATING_EN | L310_STNDBY_MODE_EN;
+	writel_relaxed(val, l2x0_base + L310_POWER_CTRL);
 
 	iounmap(l2x0_base);
 	of_node_put(np);
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 667915d236f3..ba43f49fbb59 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -194,7 +194,7 @@ static void save_l2x0_context(void)
 	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);
+		val = __raw_readl(l2x0_base + L310_PREFETCH_CTRL);
 		__raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET);
 	}
 }
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 07b4efd23078..1d936f2747de 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -212,19 +212,19 @@ static int __init omap_l2_cache_init(void)
 	 * Way size - 32KB (es1.0)
 	 * Way size - 64KB (es2.0 +)
 	 */
-	aux_ctrl = ((1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT) |
-			(0x1 << 25) |
-			(0x1 << L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT) |
-			(0x1 << L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT));
+	aux_ctrl = L310_AUX_CTRL_ASSOCIATIVITY_16 |
+		   L310_AUX_CTRL_CACHE_REPLACE_RR |
+		   L310_AUX_CTRL_NS_LOCKDOWN |
+		   L310_AUX_CTRL_NS_INT_CTRL;
 
 	if (omap_rev() == OMAP4430_REV_ES1_0) {
-		aux_ctrl |= 0x2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT;
+		aux_ctrl |= L310_AUX_CTRL_WAY_SIZE(2);
 	} else {
-		aux_ctrl |= ((0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
-			(1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
-			(1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
-			(1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
-			(1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT));
+		aux_ctrl |= L310_AUX_CTRL_WAY_SIZE(3) |
+			    L310_AUX_CTRL_SHARED_OVERRIDE |
+			    L310_AUX_CTRL_DATA_PREFETCH |
+			    L310_AUX_CTRL_INSTR_PREFETCH |
+			    L310_AUX_CTRL_EARLY_BRESP;
 	}
 	if (omap_rev() != OMAP4430_REV_ES1_0)
 		omap_smc1(0x109, aux_ctrl);
diff --git a/arch/arm/mach-prima2/l2x0.c b/arch/arm/mach-prima2/l2x0.c
index cbcbe9cb094c..3a9ddc3d6d0f 100644
--- a/arch/arm/mach-prima2/l2x0.c
+++ b/arch/arm/mach-prima2/l2x0.c
@@ -18,13 +18,12 @@ struct l2x0_aux
 };
 
 static struct l2x0_aux prima2_l2x0_aux __initconst = {
-	.val = 2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT,
+	.val = L310_AUX_CTRL_WAY_SIZE(2),
 	.mask =	0,
 };
 
 static struct l2x0_aux marco_l2x0_aux __initconst = {
-	.val = (2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
-		(1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT),
+	.val = L310_AUX_CTRL_WAY_SIZE(2) | L310_AUX_CTRL_ASSOCIATIVITY_16,
 	.mask = L2X0_AUX_CTRL_MASK,
 };
 
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index e880b8723d13..7757f1426fe1 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -371,8 +371,8 @@ static void __init realview_pbx_init(void)
 			__io_address(REALVIEW_PBX_TILE_L220_BASE);
 
 		/* set RAM latencies to 1 cycle for eASIC */
-		writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
-		writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
+		writel(0, l2x0_base + L310_TAG_LATENCY_CTRL);
+		writel(0, l2x0_base + L310_DATA_LATENCY_CTRL);
 
 		/* 16KB way size, 8-way associativity, parity disabled
 		 * Bits:  .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... */
diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c
index 7aa6e8cf830f..92860fa01668 100644
--- a/arch/arm/mach-spear/spear13xx.c
+++ b/arch/arm/mach-spear/spear13xx.c
@@ -38,14 +38,14 @@ void __init spear13xx_l2x0_init(void)
 	if (!IS_ENABLED(CONFIG_CACHE_L2X0))
 		return;
 
-	writel_relaxed(0x06, VA_L2CC_BASE + L2X0_PREFETCH_CTRL);
+	writel_relaxed(0x06, VA_L2CC_BASE + L310_PREFETCH_CTRL);
 
 	/*
 	 * Program following latencies in order to make
 	 * SPEAr1340 work@600 MHz
 	 */
-	writel_relaxed(0x221, VA_L2CC_BASE + L2X0_TAG_LATENCY_CTRL);
-	writel_relaxed(0x441, VA_L2CC_BASE + L2X0_DATA_LATENCY_CTRL);
+	writel_relaxed(0x221, VA_L2CC_BASE + L310_TAG_LATENCY_CTRL);
+	writel_relaxed(0x441, VA_L2CC_BASE + L310_DATA_LATENCY_CTRL);
 	l2x0_init(VA_L2CC_BASE, 0x70A60001, 0xfe00ffff);
 }
 
diff --git a/arch/arm/mach-sti/board-dt.c b/arch/arm/mach-sti/board-dt.c
index 1217fb598cfd..fbe726c30f73 100644
--- a/arch/arm/mach-sti/board-dt.c
+++ b/arch/arm/mach-sti/board-dt.c
@@ -19,10 +19,10 @@ void __init stih41x_l2x0_init(void)
 	u32 way_size = 0x4;
 	u32 aux_ctrl;
 	/* may be this can be encoded in macros like BIT*() */
-	aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
-		(0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
-		(0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
-		(way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
+	aux_ctrl = L310_AUX_CTRL_SHARED_OVERRIDE |
+		   L310_AUX_CTRL_DATA_PREFETCH |
+		   L310_AUX_CTRL_INSTR_PREFETCH |
+		   L310_AUX_CTRL_WAY_SIZE(way_size);
 
 	l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
 }
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index a4edbb3abd3d..a032820d2fac 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -134,13 +134,13 @@
 	tst	\tmp3, #L2X0_CTRL_EN
 	bne	exit_l2_resume
 	ldr	\tmp3, [\tmp1, #L2X0_R_TAG_LATENCY]
-	str	\tmp3, [\tmp2, #L2X0_TAG_LATENCY_CTRL]
+	str	\tmp3, [\tmp2, #L310_TAG_LATENCY_CTRL]
 	ldr	\tmp3, [\tmp1, #L2X0_R_DATA_LATENCY]
-	str	\tmp3, [\tmp2, #L2X0_DATA_LATENCY_CTRL]
+	str	\tmp3, [\tmp2, #L310_DATA_LATENCY_CTRL]
 	ldr	\tmp3, [\tmp1, #L2X0_R_PREFETCH_CTRL]
-	str	\tmp3, [\tmp2, #L2X0_PREFETCH_CTRL]
+	str	\tmp3, [\tmp2, #L310_PREFETCH_CTRL]
 	ldr	\tmp3, [\tmp1, #L2X0_R_PWR_CTRL]
-	str	\tmp3, [\tmp2, #L2X0_POWER_CTRL]
+	str	\tmp3, [\tmp2, #L310_POWER_CTRL]
 	ldr	\tmp3, [\tmp1, #L2X0_R_AUX_CTRL]
 	str	\tmp3, [\tmp2, #L2X0_AUX_CTRL]
 	mov	\tmp3, #L2X0_CTRL_EN
diff --git a/arch/arm/mach-ux500/cache-l2x0.c b/arch/arm/mach-ux500/cache-l2x0.c
index 5cc7e3625d8c..9c1d083a3c8d 100644
--- a/arch/arm/mach-ux500/cache-l2x0.c
+++ b/arch/arm/mach-ux500/cache-l2x0.c
@@ -59,10 +59,10 @@ static int __init ux500_l2x0_init(void)
 	/* DBx540's L2 has 128KB way size */
 	if (cpu_is_ux540_family())
 		/* 128KB way size */
-		aux_val |= (0x4 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
+		aux_val |= L310_AUX_CTRL_WAY_SIZE(4);
 	else
 		/* 64KB way size */
-		aux_val |= (0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
+		aux_val |= L310_AUX_CTRL_WAY_SIZE(3);
 
 	outer_cache.write_sec = ux500_l2c310_write_sec;
 
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 6f34497a4245..6c4ffb6c5ad8 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -145,8 +145,8 @@ static void __init ct_ca9x4_init(void)
 	void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
 
 	/* set RAM latencies to 1 cycle for this core tile. */
-	writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
-	writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
+	writel(0, l2x0_base + L310_TAG_LATENCY_CTRL);
+	writel(0, l2x0_base + L310_DATA_LATENCY_CTRL);
 
 	l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
 #endif
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 34980c75bacd..831c65d55ab3 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -766,13 +766,13 @@ static void __init l2c310_save(void __iomem *base)
 	unsigned revision;
 
 	l2x0_saved_regs.tag_latency = readl_relaxed(base +
-		L2X0_TAG_LATENCY_CTRL);
+		L310_TAG_LATENCY_CTRL);
 	l2x0_saved_regs.data_latency = readl_relaxed(base +
-		L2X0_DATA_LATENCY_CTRL);
+		L310_DATA_LATENCY_CTRL);
 	l2x0_saved_regs.filter_end = readl_relaxed(base +
-		L2X0_ADDR_FILTER_END);
+		L310_ADDR_FILTER_END);
 	l2x0_saved_regs.filter_start = readl_relaxed(base +
-		L2X0_ADDR_FILTER_START);
+		L310_ADDR_FILTER_START);
 
 	revision = readl_relaxed(base + L2X0_CACHE_ID) &
 			L2X0_CACHE_ID_RTL_MASK;
@@ -780,12 +780,12 @@ static void __init l2c310_save(void __iomem *base)
 	/* From r2p0, there is Prefetch offset/control register */
 	if (revision >= L310_CACHE_ID_RTL_R2P0)
 		l2x0_saved_regs.prefetch_ctrl = readl_relaxed(base +
-							L2X0_PREFETCH_CTRL);
+							L310_PREFETCH_CTRL);
 
 	/* From r3p0, there is Power control register */
 	if (revision >= L310_CACHE_ID_RTL_R3P0)
 		l2x0_saved_regs.pwr_ctrl = readl_relaxed(base +
-							L2X0_POWER_CTRL);
+							L310_POWER_CTRL);
 }
 
 static void l2c310_resume(void)
@@ -797,23 +797,23 @@ static void l2c310_resume(void)
 
 		/* restore pl310 setup */
 		writel_relaxed(l2x0_saved_regs.tag_latency,
-			       base + L2X0_TAG_LATENCY_CTRL);
+			       base + L310_TAG_LATENCY_CTRL);
 		writel_relaxed(l2x0_saved_regs.data_latency,
-			       base + L2X0_DATA_LATENCY_CTRL);
+			       base + L310_DATA_LATENCY_CTRL);
 		writel_relaxed(l2x0_saved_regs.filter_end,
-			       base + L2X0_ADDR_FILTER_END);
+			       base + L310_ADDR_FILTER_END);
 		writel_relaxed(l2x0_saved_regs.filter_start,
-			       base + L2X0_ADDR_FILTER_START);
+			       base + L310_ADDR_FILTER_START);
 
 		revision = readl_relaxed(base + L2X0_CACHE_ID) &
 				L2X0_CACHE_ID_RTL_MASK;
 
 		if (revision >= L310_CACHE_ID_RTL_R2P0)
 			writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
-				       base + L2X0_PREFETCH_CTRL);
+				       base + L310_PREFETCH_CTRL);
 		if (revision >= L310_CACHE_ID_RTL_R3P0)
 			writel_relaxed(l2x0_saved_regs.pwr_ctrl,
-				       base + L2X0_POWER_CTRL);
+				       base + L310_POWER_CTRL);
 
 		l2c310_enable(base, l2x0_saved_regs.aux_ctrl);
 	}
@@ -844,11 +844,11 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 
 	if (revision >= L310_CACHE_ID_RTL_R3P0 &&
 	    revision < L310_CACHE_ID_RTL_R3P2) {
-		u32 val = readl_relaxed(base + L2X0_PREFETCH_CTRL);
+		u32 val = readl_relaxed(base + L310_PREFETCH_CTRL);
 		/* I don't think bit23 is required here... but iMX6 does so */
 		if (val & (BIT(30) | BIT(23))) {
 			val &= ~(BIT(30) | BIT(23));
-			l2c_write_sec(val, base, L2X0_PREFETCH_CTRL);
+			l2c_write_sec(val, base, L310_PREFETCH_CTRL);
 			errata[n++] = "752271";
 		}
 	}
@@ -943,7 +943,8 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	 *
 	 * L2 cache size = number of ways * way size.
 	 */
-	way_size_bits = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >> 17;
+	way_size_bits = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >>
+			L2X0_AUX_CTRL_WAY_SIZE_SHIFT;
 	l2x0_size = ways * (data->way_size_0 << way_size_bits);
 
 	fns = data->outer_cache;
@@ -1082,27 +1083,27 @@ static void __init l2c310_of_parse(const struct device_node *np,
 	of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
 	if (tag[0] && tag[1] && tag[2])
 		writel_relaxed(
-			((tag[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
-			((tag[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
-			((tag[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
-			l2x0_base + L2X0_TAG_LATENCY_CTRL);
+			L310_LATENCY_CTRL_RD(tag[0] - 1) |
+			L310_LATENCY_CTRL_WR(tag[1] - 1) |
+			L310_LATENCY_CTRL_SETUP(tag[2] - 1),
+			l2x0_base + L310_TAG_LATENCY_CTRL);
 
 	of_property_read_u32_array(np, "arm,data-latency",
 				   data, ARRAY_SIZE(data));
 	if (data[0] && data[1] && data[2])
 		writel_relaxed(
-			((data[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
-			((data[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
-			((data[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
-			l2x0_base + L2X0_DATA_LATENCY_CTRL);
+			L310_LATENCY_CTRL_RD(data[0] - 1) |
+			L310_LATENCY_CTRL_WR(data[1] - 1) |
+			L310_LATENCY_CTRL_SETUP(data[2] - 1),
+			l2x0_base + L310_DATA_LATENCY_CTRL);
 
 	of_property_read_u32_array(np, "arm,filter-ranges",
 				   filter, ARRAY_SIZE(filter));
 	if (filter[1]) {
 		writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M),
-			       l2x0_base + L2X0_ADDR_FILTER_END);
-		writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L2X0_ADDR_FILTER_EN,
-			       l2x0_base + L2X0_ADDR_FILTER_START);
+			       l2x0_base + L310_ADDR_FILTER_END);
+		writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L310_ADDR_FILTER_EN,
+			       l2x0_base + L310_ADDR_FILTER_START);
 	}
 }
 
@@ -1482,7 +1483,7 @@ static void __init tauros3_save(void __iomem *base)
 	l2x0_saved_regs.aux2_ctrl =
 		readl_relaxed(base + TAUROS3_AUX2_CTRL);
 	l2x0_saved_regs.prefetch_ctrl =
-		readl_relaxed(base + L2X0_PREFETCH_CTRL);
+		readl_relaxed(base + L310_PREFETCH_CTRL);
 }
 
 static void tauros3_resume(void)
@@ -1493,7 +1494,7 @@ static void tauros3_resume(void)
 		writel_relaxed(l2x0_saved_regs.aux2_ctrl,
 			       base + TAUROS3_AUX2_CTRL);
 		writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
-			       base + L2X0_PREFETCH_CTRL);
+			       base + L310_PREFETCH_CTRL);
 	}
 
 	l2x0_resume();
diff --git a/arch/arm/plat-samsung/s5p-sleep.S b/arch/arm/plat-samsung/s5p-sleep.S
index a030e7301da8..497301944090 100644
--- a/arch/arm/plat-samsung/s5p-sleep.S
+++ b/arch/arm/plat-samsung/s5p-sleep.S
@@ -69,13 +69,13 @@ ENTRY(s3c_cpu_resume)
 	ldr	r2, [r0, #L2X0_R_AUX_CTRL]
 	str	r2, [r1, #L2X0_AUX_CTRL]
 	ldr	r2, [r0, #L2X0_R_TAG_LATENCY]
-	str	r2, [r1, #L2X0_TAG_LATENCY_CTRL]
+	str	r2, [r1, #L310_TAG_LATENCY_CTRL]
 	ldr	r2, [r0, #L2X0_R_DATA_LATENCY]
-	str	r2, [r1, #L2X0_DATA_LATENCY_CTRL]
+	str	r2, [r1, #L310_DATA_LATENCY_CTRL]
 	ldr	r2, [r0, #L2X0_R_PREFETCH_CTRL]
-	str	r2, [r1, #L2X0_PREFETCH_CTRL]
+	str	r2, [r1, #L310_PREFETCH_CTRL]
 	ldr	r2, [r0, #L2X0_R_PWR_CTRL]
-	str	r2, [r1, #L2X0_POWER_CTRL]
+	str	r2, [r1, #L310_POWER_CTRL]
 	mov	r2, #1
 	str	r2, [r1, #L2X0_CTRL]
 resume_l2on:
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 44/44] ARM: l2c: add L2C-310 power control DT properties
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (42 preceding siblings ...)
  2014-03-17  0:17 ` [PATCH 43/44] ARM: l2c: rename all L2C-310 constants with an L310_ prefix Russell King
@ 2014-03-17  0:17 ` Russell King
  2014-03-26 21:08   ` Rob Herring
  2014-03-26 20:05 ` [PATCH 00/44] outer cache changes Gregory CLEMENT
  2014-03-28 18:50   ` Nishanth Menon
  45 siblings, 1 reply; 52+ messages in thread
From: Russell King @ 2014-03-17  0:17 UTC (permalink / raw)
  To: linux-arm-kernel

Add two new properties for setting thte L3 power control register.  Two
new properties are added:

	arm,dynamic-clk-gating
	arm,standby-mode

iMX6 sets both these, add the properties there.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 Documentation/devicetree/bindings/arm/l2cc.txt |  2 ++
 arch/arm/boot/dts/imx6qdl.dtsi                 |  2 ++
 arch/arm/boot/dts/imx6sl.dtsi                  |  2 ++
 arch/arm/mm/cache-l2x0.c                       | 10 ++++++++++
 4 files changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/l2cc.txt b/Documentation/devicetree/bindings/arm/l2cc.txt
index b513cb8196fe..e0dd400ecea6 100644
--- a/Documentation/devicetree/bindings/arm/l2cc.txt
+++ b/Documentation/devicetree/bindings/arm/l2cc.txt
@@ -40,6 +40,8 @@ implementations of the L2 cache controller with compatible programming models.
 - arm,filter-ranges : <start length> Starting address and length of window to
   filter. Addresses in the filter window are directed to the M1 port. Other
   addresses will go to the M0 port.
+- arm,dynamic-clk-gating : Enables dynamic clock gating (PL310)
+- arm,standby-mode : Enables standby mode (PL310)
 - interrupts : 1 combined interrupt.
 - cache-id-part: cache id part number to be used if it is not present
   on hardware
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 64a8cbe9480f..c96b7bc90dfe 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -114,6 +114,8 @@
 			cache-level = <2>;
 			arm,tag-latency = <4 2 3>;
 			arm,data-latency = <4 2 3>;
+			arm,dynamic-clk-gating;
+			arm,standby-mode;
 		};
 
 		pcie: pcie at 0x01000000 {
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index 28558f1aaf2d..8094ac1cedc5 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -81,6 +81,8 @@
 			cache-level = <2>;
 			arm,tag-latency = <4 2 3>;
 			arm,data-latency = <4 2 3>;
+			arm,dynamic-clk-gating;
+			arm,standby-mode;
 		};
 
 		pmu {
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 831c65d55ab3..547072b16768 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -1079,6 +1079,7 @@ static void __init l2c310_of_parse(const struct device_node *np,
 	u32 data[3] = { 0, 0, 0 };
 	u32 tag[3] = { 0, 0, 0 };
 	u32 filter[2] = { 0, 0 };
+	u32 val;
 
 	of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
 	if (tag[0] && tag[1] && tag[2])
@@ -1105,6 +1106,15 @@ static void __init l2c310_of_parse(const struct device_node *np,
 		writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L310_ADDR_FILTER_EN,
 			       l2x0_base + L310_ADDR_FILTER_START);
 	}
+
+	val = 0;
+	if (of_property_read_bool(np, "arm,dynamic-clk-gating"))
+		val |= L310_DYNAMIC_CLK_GATING_EN;
+	if (of_property_read_bool(np, "arm,standby-mode"))
+		val |= L310_STNDBY_MODE_EN;
+
+	if (val)
+		l2c_write_sec(val, l2x0_base, L310_POWER_CTRL);
 }
 
 static const struct l2c_init_data of_l2c310_data __initconst = {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 00/44] outer cache changes
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
                   ` (43 preceding siblings ...)
  2014-03-17  0:17 ` [PATCH 44/44] ARM: l2c: add L2C-310 power control DT properties Russell King
@ 2014-03-26 20:05 ` Gregory CLEMENT
  2014-03-28 18:50   ` Nishanth Menon
  45 siblings, 0 replies; 52+ messages in thread
From: Gregory CLEMENT @ 2014-03-26 20:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

On 17/03/2014 01:13, Russell King - ARM Linux wrote:
> This patch series is where I'm currently at with the total mess which
> is L2 cache support.  That's putting it mildly.  This isn't intended
> for anyone to pick up - this is still mostly in development.
> 
> I need help with the Aurora/Tauros3/Broadcom stuff, as that remains
> addicted to the old buggy code that we used to have (eg, if you build
> a v6+v7 kernel, all PL310 errata get disabled.  If CONFIG_CACHE_PL310
> is enabled and you actually have a L2C-220, the necessary waits will
> be omitted.  If you enable erratum 588369 and set the .set_debug
> method to NULL or have a PL310 later than R3P0, you're opening a
> race condition. etc.)
> 
> One of the potentially explosive issues is the utter crap and fscked
> state of DT implementation here, much of which /can't/ now be fixed
> without breaking existing DT based booting with existing files,
> because we have a mixture of DT properties combined with platform
> specific code setting various L2C configuration parameters (sometimes
> writing directly to the registers.)
> 
> For example, I've made a start at trying to prevent any further additions
> of platform code writing to the L2C-310's power control register by
> adding a couple of properties - but we can't delete the direct register
> write in iMX6 code without breaking existing DT descriptions.
> 
> The same goes for the mess which is the auxillary control register,
> or now the prefetch control register.  Or the erratum 752271 which
> iMX6 implements in their own SoC specific code.
> 
> Here's the *big* explosive question: how have we ended up in this mess?
> A bigger question: why was none of this caught at review time?  An even
> bigger question (which I believe is at the root of much of the pain that
> people feel with DT): why aren't device properties being thought out
> better - by that I mean, why isn't the question "are the properties you
> are proposing for device X sufficient to describe all it's configurable
> parameters, and if not, what are you omitting?" being asked when new
> device bindings are being proposed.
> 
> You can see the extent of the L2C crap from the diffstat below - every
> arch/arm/mach-* file touched here is a symptom of failing to adequately
> describe the properties that platforms need to specify.  It's a failing
> of DT process.  It's a failing of review of SoC code.
> 

I had a quick look on this series and it is a really good improvement of
the code. I didn't notice anything suspicious regarding the Aurora L2
cache controller.

Then I have applied this series on 3.14-rc8 using our mvebu_defconfig. And
made some performance tests using cachebench. So I tested it on:

- an Armada XP based board which use the Aurora cache controller with the
aurora-system-cache flavor.

- an Armada 370 based board which use the Aurora cache controller with the
aurora-outer-cache.

I didn't notice any regression in both case.

So at least you can add my

Tested-by: Gregory CLEMENT <gregory.clement@free-electrons.com>


Thanks for your work,

Gregory


> Anyway, here's the diffstat so far.  Not Cc'ing anyone this time around
> (the Cc list is huge), so it's all on LAKML.
> 
>  Documentation/devicetree/bindings/arm/l2cc.txt |    2 +
>  arch/arm/Kconfig                               |   51 -
>  arch/arm/boot/dts/imx6qdl.dtsi                 |    2 +
>  arch/arm/boot/dts/imx6sl.dtsi                  |    2 +
>  arch/arm/include/asm/hardware/cache-l2x0.h     |   63 +-
>  arch/arm/include/asm/outercache.h              |   67 +-
>  arch/arm/mach-cns3xxx/core.c                   |    8 +-
>  arch/arm/mach-highbank/highbank.c              |   12 +-
>  arch/arm/mach-imx/system.c                     |    8 +-
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c      |    2 +-
>  arch/arm/mach-omap2/omap4-common.c             |   58 +-
>  arch/arm/mach-prima2/l2x0.c                    |    5 +-
>  arch/arm/mach-prima2/pm.c                      |    1 -
>  arch/arm/mach-realview/realview_pbx.c          |    4 +-
>  arch/arm/mach-spear/platsmp.c                  |   19 +-
>  arch/arm/mach-spear/spear13xx.c                |    6 +-
>  arch/arm/mach-sti/board-dt.c                   |    8 +-
>  arch/arm/mach-tegra/sleep.h                    |    8 +-
>  arch/arm/mach-ux500/cache-l2x0.c               |   23 +-
>  arch/arm/mach-vexpress/ct-ca9x4.c              |    4 +-
>  arch/arm/mm/Kconfig                            |   51 +
>  arch/arm/mm/Makefile                           |    1 +
>  arch/arm/mm/cache-feroceon-l2.c                |    1 -
>  arch/arm/mm/cache-l2x0.c                       | 1354 +++++++++++++++++-------
>  arch/arm/mm/l2c-common.c                       |   20 +
>  arch/arm/plat-samsung/s5p-sleep.S              |    8 +-
>  26 files changed, 1221 insertions(+), 567 deletions(-)
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 04/44] ARM: l2c: add helper for L2 cache controller DT IDs
  2014-03-17  0:13 ` [PATCH 04/44] ARM: l2c: add helper for L2 cache controller DT IDs Russell King
@ 2014-03-26 20:30   ` Rob Herring
  0 siblings, 0 replies; 52+ messages in thread
From: Rob Herring @ 2014-03-26 20:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Mar 16, 2014 at 7:13 PM, Russell King
<rmk+kernel@arm.linux.org.uk> wrote:
> Make it easier to declare L2 cache controller DT IDs by using a macro.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  arch/arm/mm/cache-l2x0.c | 23 ++++++++++-------------
>  1 file changed, 10 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
> index f9985e5a208c..ac410b21edfb 100644
> --- a/arch/arm/mm/cache-l2x0.c
> +++ b/arch/arm/mm/cache-l2x0.c
> @@ -946,20 +946,17 @@ static const struct l2x0_of_data bcm_l2x0_data = {
>         },
>  };
>
> +#define L2C_ID(name, fns) { .compatible = name, .data = (void *)&fns }

This would useful globally. It probably needs to be without the & in that case.

Rob

>  static const struct of_device_id l2x0_ids[] __initconst = {
> -       { .compatible = "arm,l210-cache", .data = (void *)&l2x0_data },
> -       { .compatible = "arm,l220-cache", .data = (void *)&l2x0_data },
> -       { .compatible = "arm,pl310-cache", .data = (void *)&pl310_data },
> -       { .compatible = "bcm,bcm11351-a2-pl310-cache", /* deprecated name */
> -         .data = (void *)&bcm_l2x0_data},
> -       { .compatible = "brcm,bcm11351-a2-pl310-cache",
> -         .data = (void *)&bcm_l2x0_data},
> -       { .compatible = "marvell,aurora-outer-cache",
> -         .data = (void *)&aurora_with_outer_data},
> -       { .compatible = "marvell,aurora-system-cache",
> -         .data = (void *)&aurora_no_outer_data},
> -       { .compatible = "marvell,tauros3-cache",
> -         .data = (void *)&tauros3_data },
> +       L2C_ID("arm,l210-cache", l2x0_data),
> +       L2C_ID("arm,l220-cache", l2x0_data),
> +       L2C_ID("arm,pl310-cache", pl310_data),
> +       L2C_ID("brcm,bcm11351-a2-pl310-cache", bcm_l2x0_data),
> +       L2C_ID("marvell,aurora-outer-cache", aurora_with_outer_data),
> +       L2C_ID("marvell,aurora-system-cache", aurora_no_outer_data),
> +       L2C_ID("marvell,tauros3-cache", tauros3_data),
> +       /* Deprecated IDs */
> +       L2C_ID("bcm,bcm11351-a2-pl310-cache", bcm_l2x0_data),
>         {}
>  };
>
> --
> 1.8.3.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 39/44] ARM: l2c: highbank: implement new write_sec method
  2014-03-17  0:16 ` [PATCH 39/44] ARM: l2c: highbank: " Russell King
@ 2014-03-26 20:35   ` Rob Herring
  0 siblings, 0 replies; 52+ messages in thread
From: Rob Herring @ 2014-03-26 20:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Mar 16, 2014 at 7:16 PM, Russell King
<rmk+kernel@arm.linux.org.uk> wrote:
> With the write_sec method, we no longer need to override the default L2C
> disable method.  This can be handled via the write_sec method instead.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Acked-by: Rob Herring <robh@kernel.org>

> ---
>  arch/arm/mach-highbank/highbank.c | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
> index c7de89b263dd..d6b803594358 100644
> --- a/arch/arm/mach-highbank/highbank.c
> +++ b/arch/arm/mach-highbank/highbank.c
> @@ -51,11 +51,13 @@ static void __init highbank_scu_map_io(void)
>  }
>
>
> -static void highbank_l2x0_disable(void)
> +static void highbank_l2c310_write_sec(unsigned long val, unsigned reg)
>  {
> -       outer_flush_all();
> -       /* Disable PL310 L2 Cache controller */
> -       highbank_smc1(0x102, 0x0);
> +       if (reg == L2X0_CTRL)
> +               highbank_smc1(0x102, val);
> +       else
> +               WARN_ONCE(1, "Highbank L2C310: ignoring write to reg 0x%x\n",
> +                         reg);
>  }
>
>  static void __init highbank_init_irq(void)
> @@ -69,8 +71,8 @@ static void __init highbank_init_irq(void)
>         if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
>             of_find_compatible_node(NULL, NULL, "arm,pl310-cache")) {
>                 highbank_smc1(0x102, 0x1);
> +               outer_cache.write_sec = highbank_l2x0_write_sec;
>                 l2x0_of_init(0, ~0UL);
> -               outer_cache.disable = highbank_l2x0_disable;
>         }
>  }
>
> --
> 1.8.3.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 44/44] ARM: l2c: add L2C-310 power control DT properties
  2014-03-17  0:17 ` [PATCH 44/44] ARM: l2c: add L2C-310 power control DT properties Russell King
@ 2014-03-26 21:08   ` Rob Herring
  2014-03-28 13:29     ` Russell King - ARM Linux
  0 siblings, 1 reply; 52+ messages in thread
From: Rob Herring @ 2014-03-26 21:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Mar 16, 2014 at 7:17 PM, Russell King
<rmk+kernel@arm.linux.org.uk> wrote:
> Add two new properties for setting thte L3 power control register.  Two
> new properties are added:
>
>         arm,dynamic-clk-gating
>         arm,standby-mode
>
> iMX6 sets both these, add the properties there.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  Documentation/devicetree/bindings/arm/l2cc.txt |  2 ++
>  arch/arm/boot/dts/imx6qdl.dtsi                 |  2 ++
>  arch/arm/boot/dts/imx6sl.dtsi                  |  2 ++
>  arch/arm/mm/cache-l2x0.c                       | 10 ++++++++++
>  4 files changed, 16 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/arm/l2cc.txt b/Documentation/devicetree/bindings/arm/l2cc.txt
> index b513cb8196fe..e0dd400ecea6 100644
> --- a/Documentation/devicetree/bindings/arm/l2cc.txt
> +++ b/Documentation/devicetree/bindings/arm/l2cc.txt
> @@ -40,6 +40,8 @@ implementations of the L2 cache controller with compatible programming models.
>  - arm,filter-ranges : <start length> Starting address and length of window to
>    filter. Addresses in the filter window are directed to the M1 port. Other
>    addresses will go to the M0 port.
> +- arm,dynamic-clk-gating : Enables dynamic clock gating (PL310)
> +- arm,standby-mode : Enables standby mode (PL310)

I'd rather see properties to disable these features and the default to
be to enable them. I would expect disabling them to be the exception.
I can't imagine that they would be broken at an integration level
unless h/w is doing something based on CLKSTOPPED. Given you also need
s/w interaction (flush and disable the cache) to do anything like
reducing voltage or cutting power to the L2, it's unlikely that the
h/w will do anything in reaction to CLKSTOPPED . There is some risk of
breaking a platform with this approach, but there's also the risk we
never see power improvements because no one ever goes and adds these
to the dts file.

Also, standby probably doesn't really gain anything over dynamic clk
gating, so standby may not be worth adding.

Rob

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 44/44] ARM: l2c: add L2C-310 power control DT properties
  2014-03-26 21:08   ` Rob Herring
@ 2014-03-28 13:29     ` Russell King - ARM Linux
  0 siblings, 0 replies; 52+ messages in thread
From: Russell King - ARM Linux @ 2014-03-28 13:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 26, 2014 at 04:08:55PM -0500, Rob Herring wrote:
> On Sun, Mar 16, 2014 at 7:17 PM, Russell King
> <rmk+kernel@arm.linux.org.uk> wrote:
> > Add two new properties for setting thte L3 power control register.  Two
> > new properties are added:
> >
> >         arm,dynamic-clk-gating
> >         arm,standby-mode
> >
> > iMX6 sets both these, add the properties there.
> >
> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> > ---
> >  Documentation/devicetree/bindings/arm/l2cc.txt |  2 ++
> >  arch/arm/boot/dts/imx6qdl.dtsi                 |  2 ++
> >  arch/arm/boot/dts/imx6sl.dtsi                  |  2 ++
> >  arch/arm/mm/cache-l2x0.c                       | 10 ++++++++++
> >  4 files changed, 16 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/arm/l2cc.txt b/Documentation/devicetree/bindings/arm/l2cc.txt
> > index b513cb8196fe..e0dd400ecea6 100644
> > --- a/Documentation/devicetree/bindings/arm/l2cc.txt
> > +++ b/Documentation/devicetree/bindings/arm/l2cc.txt
> > @@ -40,6 +40,8 @@ implementations of the L2 cache controller with compatible programming models.
> >  - arm,filter-ranges : <start length> Starting address and length of window to
> >    filter. Addresses in the filter window are directed to the M1 port. Other
> >    addresses will go to the M0 port.
> > +- arm,dynamic-clk-gating : Enables dynamic clock gating (PL310)
> > +- arm,standby-mode : Enables standby mode (PL310)
> 
> I'd rather see properties to disable these features and the default to
> be to enable them. I would expect disabling them to be the exception.
> I can't imagine that they would be broken at an integration level
> unless h/w is doing something based on CLKSTOPPED. Given you also need
> s/w interaction (flush and disable the cache) to do anything like
> reducing voltage or cutting power to the L2, it's unlikely that the
> h/w will do anything in reaction to CLKSTOPPED .

This doesn't make sense.  Ask this question: "what is the point in the
hardware providing a signal which ultimately does nothing". :)

> There is some risk of
> breaking a platform with this approach, but there's also the risk we
> never see power improvements because no one ever goes and adds these
> to the dts file.
> 
> Also, standby probably doesn't really gain anything over dynamic clk
> gating, so standby may not be worth adding.

I'm not so sure.  Standby mode is not well described in the TRM - it
doesn't describe what the exit strategy is from this mode.  If the exit
strategy is the STOPCLK input going low, then setting this bit could be
problematical if it has been integrated with STOPCLK high.  The danger
here is that setting this bit may cause the L2 slave interfaces to
become unavailable to the CPUs, thereby hanging the system.  The TRM
just hints that one possible configuration is to connect STOPCLK to a
CPU output indicating that it is in WFI mode, but this is not mandated.

Also, we don't know if enabling these features adds additional latency.
In both these cases, when the lower-power mode is entered, the AXI
ready signal is deasserted to the CPUs, which presumably have to wait
until that signal is reasserted before an AXI transaction can be
completed.

We probably want to check whether there is any measurable performance
penalty to enabling dynamic clock gating.  Standby mode should be less
of a risk in that regard because it requires something to assert the
STOPCLK input, which /may/ (or may not) be an indication from the CPU
that it is in WFI mode.

So... we don't know quite a lot of details here.  While I can buy just
setting these two bits and seeing whether anyone complains, that seems
to be a brutal way to do this.  Nevertheless, that approach does have
the advantage that people have to report back if it breaks and they
care about it. :)

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/44] outer cache changes
  2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
@ 2014-03-28 18:50   ` Nishanth Menon
  2014-03-17  0:13 ` [PATCH 02/44] ARM: l2c: remove unnecessary call to outer_flush_all() Russell King
                     ` (44 subsequent siblings)
  45 siblings, 0 replies; 52+ messages in thread
From: Nishanth Menon @ 2014-03-28 18:50 UTC (permalink / raw)
  To: Russell King - ARM Linux, linux-arm-kernel; +Cc: linux-omap

On 03/16/2014 07:13 PM, Russell King - ARM Linux wrote:
> This patch series is where I'm currently at with the total mess which
> is L2 cache support.  That's putting it mildly.  This isn't intended
> for anyone to pick up - this is still mostly in development.

Quick boot test against v3.14-rc8 showed no regressions for the
platforms I ran through - ofcourse, the tests are basic boot, and
unfortunately not any comprehensive cache performance tests.


russell-l2c-fc0adeb-v3.14-rc8-test-omap2plus_defconfig
 1: am335x-evm:  Boot PASS: http://slexy.org/raw/s20BepYQRE
 2:  am335x-sk:  Boot PASS: http://slexy.org/raw/s2UN5rONP3
 3: am3517-evm:  Boot PASS: http://slexy.org/raw/s24AcPGSZL
 4:  am37x-evm:  Boot PASS: http://slexy.org/raw/s2IArYgC7S
 5: am43xx-epos:  Boot PASS: http://slexy.org/raw/s20JBi80c7
 6: BeagleBoard-XM:  Boot PASS: http://slexy.org/raw/s21KDOKenY
 7: beaglebone-black:  Boot PASS: http://slexy.org/raw/s2lXBwgynB
 8: beaglebone:  Boot PASS: http://slexy.org/raw/s2KzNGNIBt
 9: OMAP3430-Labrador(LDP):  Boot FAIL: http://slexy.org/raw/s21ekHLEY5
(legacy problem - fix in linux-next)
10: pandaboard-es:  Boot PASS: http://slexy.org/raw/s20dKIf8sa
11:    sdp2430:  Boot PASS: http://slexy.org/raw/s20jxn1zA5
12:    sdp3430:  Boot PASS: http://slexy.org/raw/s21m0nx262
13:    sdp4430:  Boot PASS: http://slexy.org/raw/s21IxkfYTm
14: OMAP5432uEVM:  Boot PASS: http://slexy.org/raw/s20AKR1hRy
TOTAL = 14 boards, Booted Boards = 13, No Boot boards = 1

Vs:

v3.14-rc8-omap2plus_defconfig
 1: am335x-evm:  Boot PASS: http://slexy.org/raw/s21CKn6A7h
 2:  am335x-sk:  Boot PASS: http://slexy.org/raw/s20eC7gQ9T
 3: am3517-evm:  Boot PASS: http://slexy.org/raw/s20amKvVx5
 4:  am37x-evm:  Boot PASS: http://slexy.org/raw/s2yVk3doef
 5: am43xx-epos:  Boot PASS: http://slexy.org/raw/s22SsOWHaY
 6: BeagleBoard-XM:  Boot PASS: http://slexy.org/raw/s21TDD4jhW
 7: beaglebone-black:  Boot PASS: http://slexy.org/raw/s20ltoXaiZ
 8: beaglebone:  Boot PASS: http://slexy.org/raw/s2DkrTbwG3
 9: OMAP3430-Labrador(LDP):  Boot FAIL: http://slexy.org/raw/s2JDOKtx9U
(legacy problem - fix in linux-next)
10: pandaboard-es:  Boot PASS: http://slexy.org/raw/s21WGaaGut
11:    sdp2430:  Boot PASS: http://slexy.org/raw/s2Nr9p1Zyf
12:    sdp3430:  Boot PASS: http://slexy.org/raw/s2kh0cfpGC
13:    sdp4430:  Boot PASS: http://slexy.org/raw/s2Q6VyjmyW
14: OMAP5432uEVM:  Boot PASS: http://slexy.org/raw/s216EEpDwU
TOTAL = 14 boards, Booted Boards = 13, No Boot boards = 1


Please feel to add:
Tested-by: Nishanth Menon <nm@ti.com>

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 00/44] outer cache changes
@ 2014-03-28 18:50   ` Nishanth Menon
  0 siblings, 0 replies; 52+ messages in thread
From: Nishanth Menon @ 2014-03-28 18:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/16/2014 07:13 PM, Russell King - ARM Linux wrote:
> This patch series is where I'm currently at with the total mess which
> is L2 cache support.  That's putting it mildly.  This isn't intended
> for anyone to pick up - this is still mostly in development.

Quick boot test against v3.14-rc8 showed no regressions for the
platforms I ran through - ofcourse, the tests are basic boot, and
unfortunately not any comprehensive cache performance tests.


russell-l2c-fc0adeb-v3.14-rc8-test-omap2plus_defconfig
 1: am335x-evm:  Boot PASS: http://slexy.org/raw/s20BepYQRE
 2:  am335x-sk:  Boot PASS: http://slexy.org/raw/s2UN5rONP3
 3: am3517-evm:  Boot PASS: http://slexy.org/raw/s24AcPGSZL
 4:  am37x-evm:  Boot PASS: http://slexy.org/raw/s2IArYgC7S
 5: am43xx-epos:  Boot PASS: http://slexy.org/raw/s20JBi80c7
 6: BeagleBoard-XM:  Boot PASS: http://slexy.org/raw/s21KDOKenY
 7: beaglebone-black:  Boot PASS: http://slexy.org/raw/s2lXBwgynB
 8: beaglebone:  Boot PASS: http://slexy.org/raw/s2KzNGNIBt
 9: OMAP3430-Labrador(LDP):  Boot FAIL: http://slexy.org/raw/s21ekHLEY5
(legacy problem - fix in linux-next)
10: pandaboard-es:  Boot PASS: http://slexy.org/raw/s20dKIf8sa
11:    sdp2430:  Boot PASS: http://slexy.org/raw/s20jxn1zA5
12:    sdp3430:  Boot PASS: http://slexy.org/raw/s21m0nx262
13:    sdp4430:  Boot PASS: http://slexy.org/raw/s21IxkfYTm
14: OMAP5432uEVM:  Boot PASS: http://slexy.org/raw/s20AKR1hRy
TOTAL = 14 boards, Booted Boards = 13, No Boot boards = 1

Vs:

v3.14-rc8-omap2plus_defconfig
 1: am335x-evm:  Boot PASS: http://slexy.org/raw/s21CKn6A7h
 2:  am335x-sk:  Boot PASS: http://slexy.org/raw/s20eC7gQ9T
 3: am3517-evm:  Boot PASS: http://slexy.org/raw/s20amKvVx5
 4:  am37x-evm:  Boot PASS: http://slexy.org/raw/s2yVk3doef
 5: am43xx-epos:  Boot PASS: http://slexy.org/raw/s22SsOWHaY
 6: BeagleBoard-XM:  Boot PASS: http://slexy.org/raw/s21TDD4jhW
 7: beaglebone-black:  Boot PASS: http://slexy.org/raw/s20ltoXaiZ
 8: beaglebone:  Boot PASS: http://slexy.org/raw/s2DkrTbwG3
 9: OMAP3430-Labrador(LDP):  Boot FAIL: http://slexy.org/raw/s2JDOKtx9U
(legacy problem - fix in linux-next)
10: pandaboard-es:  Boot PASS: http://slexy.org/raw/s21WGaaGut
11:    sdp2430:  Boot PASS: http://slexy.org/raw/s2Nr9p1Zyf
12:    sdp3430:  Boot PASS: http://slexy.org/raw/s2kh0cfpGC
13:    sdp4430:  Boot PASS: http://slexy.org/raw/s2Q6VyjmyW
14: OMAP5432uEVM:  Boot PASS: http://slexy.org/raw/s216EEpDwU
TOTAL = 14 boards, Booted Boards = 13, No Boot boards = 1


Please feel to add:
Tested-by: Nishanth Menon <nm@ti.com>

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 52+ messages in thread

end of thread, other threads:[~2014-03-28 18:50 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-17  0:13 [PATCH 00/44] outer cache changes Russell King - ARM Linux
2014-03-17  0:13 ` [PATCH 01/44] ARM: l2c: remove outer_inv_all() method Russell King
2014-03-17  0:13 ` [PATCH 02/44] ARM: l2c: remove unnecessary call to outer_flush_all() Russell King
2014-03-17  0:13 ` [PATCH 03/44] ARM: l2c: avoid calling outer_flush_all() unnecessarily (Spear) Russell King
2014-03-17  0:13 ` [PATCH 04/44] ARM: l2c: add helper for L2 cache controller DT IDs Russell King
2014-03-26 20:30   ` Rob Herring
2014-03-17  0:13 ` [PATCH 05/44] ARM: l2c: tidy up l2x0_of_data declarations Russell King
2014-03-17  0:14 ` [PATCH 06/44] ARM: l2c: rename OF specific things, making l2x0_of_data available to all Russell King
2014-03-17  0:14 ` [PATCH 07/44] ARM: l2c: provide generic function for calling set_debug method Russell King
2014-03-17  0:14 ` [PATCH 08/44] ARM: l2c: split out cache unlock code Russell King
2014-03-17  0:14 ` [PATCH 09/44] ARM: l2c: provide generic helper for way-based operations Russell King
2014-03-17  0:14 ` [PATCH 10/44] ARM: l2c: rename cache_wait_way() Russell King
2014-03-17  0:14 ` [PATCH 11/44] ARM: l2c: use add L2C revision constants Russell King
2014-03-17  0:14 ` [PATCH 12/44] ARM: l2c: clean up OF initialisation a bit Russell King
2014-03-17  0:14 ` [PATCH 13/44] ARM: l2c: pass iomem address into data->save function Russell King
2014-03-17  0:14 ` [PATCH 14/44] ARM: l2c: move l2c save function to __l2c_init() Russell King
2014-03-17  0:14 ` [PATCH 15/44] ARM: l2c: provide enable method Russell King
2014-03-17  0:14 ` [PATCH 16/44] ARM: l2c: move aurora broadcast setup to enable function Russell King
2014-03-17  0:14 ` [PATCH 17/44] ARM: l2c: group implementation specific code together Russell King
2014-03-17  0:15 ` [PATCH 18/44] ARM: l2c: implement fixups for L2 cache controller quirks/errata Russell King
2014-03-17  0:15 ` [PATCH 19/44] ARM: l2c: clean up L2 cache initialisation messages Russell King
2014-03-17  0:15 ` [PATCH 20/44] ARM: l2c: split L2C-310 enable function from l2x0 code Russell King
2014-03-17  0:15 ` [PATCH 21/44] ARM: l2c: move and add ARM L2C-2x0/L2C-310 save/resume code to non-OF Russell King
2014-03-17  0:15 ` [PATCH 22/44] ARM: l2c: clean up save/resume functions Russell King
2014-03-17  0:15 ` [PATCH 23/44] ARM: l2c: simplify l2x0 unlocking code Russell King
2014-03-17  0:15 ` [PATCH 24/44] ARM: l2c: move pl310_set_debug() into l2c-310 code Russell King
2014-03-17  0:15 ` [PATCH 25/44] ARM: l2c: add L2C-210 specific handlers Russell King
2014-03-17  0:15 ` [PATCH 26/44] ARM: l2c: implement L2C-310 erratum 727915 as a method override Russell King
2014-03-17  0:15 ` [PATCH 27/44] ARM: l2c: Implement L2C-310 erratum 588369 " Russell King
2014-03-17  0:15 ` [PATCH 28/44] ARM: l2c: use L2C-210 handlers for L2C-310 errata-less implementations Russell King
2014-03-17  0:15 ` [PATCH 29/44] ARM: l2c: add L2C-220 specific handlers Russell King
2014-03-17  0:16 ` [PATCH 30/44] ARM: l2c: remove obsolete l2x0 ops for non-OF init Russell King
2014-03-17  0:16 ` [PATCH 31/44] ARM: l2c: move type string into l2c_init_data structure Russell King
2014-03-17  0:16 ` [PATCH 32/44] ARM: l2c: add decode for L2C-220 cache ways Russell King
2014-03-17  0:16 ` [PATCH 33/44] ARM: l2c: move way size calculation data into l2c_init_data Russell King
2014-03-17  0:16 ` [PATCH 34/44] ARM: outer cache: add documentation of outer cache functions Russell King
2014-03-17  0:16 ` [PATCH 35/44] ARM: outer cache: add WARN_ON() to outer_disable() Russell King
2014-03-17  0:16 ` [PATCH 36/44] ARM: l2c: move errata configuration options to arch/arm/mm/Kconfig Russell King
2014-03-17  0:16 ` [PATCH 37/44] ARM: l2c: provide generic hook to intercept writes to secure registers Russell King
2014-03-17  0:16 ` [PATCH 38/44] ARM: l2c: OMAP: implement new write_sec method Russell King
2014-03-17  0:16 ` [PATCH 39/44] ARM: l2c: highbank: " Russell King
2014-03-26 20:35   ` Rob Herring
2014-03-17  0:16 ` [PATCH 40/44] ARM: l2c: ux500: implement dummy " Russell King
2014-03-17  0:17 ` [PATCH 41/44] ARM: l2c: remove old .set_debug method Russell King
2014-03-17  0:17 ` [PATCH 42/44] ARM: l2c: implement L2C-310 erratum 752271 in core L2C code Russell King
2014-03-17  0:17 ` [PATCH 43/44] ARM: l2c: rename all L2C-310 constants with an L310_ prefix Russell King
2014-03-17  0:17 ` [PATCH 44/44] ARM: l2c: add L2C-310 power control DT properties Russell King
2014-03-26 21:08   ` Rob Herring
2014-03-28 13:29     ` Russell King - ARM Linux
2014-03-26 20:05 ` [PATCH 00/44] outer cache changes Gregory CLEMENT
2014-03-28 18:50 ` Nishanth Menon
2014-03-28 18:50   ` Nishanth Menon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.