Skip to contentSkip to conversation

l2c series

PATCH New Russell King - ARM Linux 16 participants 141 messages Mar 28, 2014 – Apr 7, 2014

Subsystems (20)
lore
Share & tools
lore
#0 lore raw

cover l2c series

This is another posting of the L2 cache controller series. I'm not planning for this for the upcoming merge window, but the one after, as people need to test it and still need to feed back to me on various issues. Hence, this is not a finalised series.

There are still various issues which I've raised, and have had no feedback on.

This series is being posted with Cc's on the individual patches.

 arch/arm/Kconfig                                   |   51 -
 arch/arm/boot/dts/imx6qdl.dtsi                     |    2 +
 arch/arm/boot/dts/imx6sl.dtsi                      |    2 +
 arch/arm/boot/dts/marco.dtsi                       |    2 +-
 arch/arm/boot/dts/prima2.dtsi                      |    2 +-
 arch/arm/include/asm/hardware/cache-l2x0.h         |  104 +-
 arch/arm/include/asm/outercache.h                  |   67 +-
 arch/arm/mach-berlin/berlin.c                      |    2 +-
 arch/arm/mach-cns3xxx/core.c                       |   10 +-
 arch/arm/mach-exynos/common.c                      |    5 +-
 arch/arm/mach-highbank/highbank.c                  |   18 +-
 arch/arm/mach-imx/mach-vf610.c                     |    2 +-
 arch/arm/mach-imx/system.c                         |    8 +-
 arch/arm/mach-mvebu/armada-370-xp.c                |    2 +-
 arch/arm/mach-nomadik/cpu-8815.c                   |    2 +-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c          |    2 +-
 arch/arm/mach-omap2/omap4-common.c                 |   79 +-
 arch/arm/mach-prima2/l2x0.c                        |   35 +-
 arch/arm/mach-prima2/pm.c                          |    1 -
 arch/arm/mach-realview/realview_eb.c               |    9 +-
 arch/arm/mach-realview/realview_pb1176.c           |    8 +-
 arch/arm/mach-realview/realview_pb11mp.c           |    9 +-
 arch/arm/mach-realview/realview_pbx.c              |    4 +-
 arch/arm/mach-rockchip/rockchip.c                  |    2 +-
 .../board-armadillo800eva-reference.c              |    4 +-
 arch/arm/mach-shmobile/board-armadillo800eva.c     |    4 +-
 arch/arm/mach-shmobile/board-kzm9g-reference.c     |    4 +-
 arch/arm/mach-shmobile/board-kzm9g.c               |    4 +-
 arch/arm/mach-shmobile/setup-r8a7778.c             |    4 +-
 arch/arm/mach-shmobile/setup-r8a7779.c             |    4 +-
 arch/arm/mach-socfpga/socfpga.c                    |    2 +-
 arch/arm/mach-spear/platsmp.c                      |   19 +-
 arch/arm/mach-spear/spear13xx.c                    |    8 +-
 arch/arm/mach-sti/board-dt.c                       |   12 +-
 arch/arm/mach-tegra/sleep.h                        |    8 +-
 arch/arm/mach-tegra/tegra.c                        |   18 +-
 arch/arm/mach-ux500/cache-l2x0.c                   |   32 +-
 arch/arm/mach-vexpress/ct-ca9x4.c                  |   28 +-
 arch/arm/mach-zynq/common.c                        |    2 +-
 arch/arm/mm/Kconfig                                |   51 +
 arch/arm/mm/Makefile                               |    1 +
 arch/arm/mm/cache-feroceon-l2.c                    |    1 -
 arch/arm/mm/cache-l2x0.c                           | 1520 +++++++++++++-------
 arch/arm/mm/l2c-common.c                           |   20 +
 arch/arm/plat-samsung/s5p-sleep.S                  |    8 +-
 45 files changed, 1382 insertions(+), 800 deletions(-)
Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#1 lore raw

PATCH 1/75 ARM: l2c: remove outer_inv_all() method

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.

---
 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(-)
arch/arm/include/asm/outercache.h +0 -8
index f94784f0e3a6..0e4420858990 100644
@@ -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) { }
 
arch/arm/mm/cache-feroceon-l2.c +0 -1
index 48bc3c0a87ce..dd3d59122cc3 100644
@@ -343,7 +343,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();
 
arch/arm/mm/cache-l2x0.c +0 -5
index 7abde2ce8973..f9985e5a208c 100644
@@ -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,
 	},
 };
Signature · 1 line
1.8.3.1
#2 lore raw

PATCH 2/75 ARM: l2c: remove unnecessary call to outer_flush_all()

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mach-prima2/pm.c | 1 -
 1 file changed, 1 deletion(-)
arch/arm/mach-prima2/pm.c +0 -1
index c4525a88e5da..96e9bc102117 100644
@@ -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);
Signature · 1 line
1.8.3.1
#3 lore raw

PATCH 3/75 ARM: l2c: avoid calling outer_flush_all() unnecessarily (Spear)

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mach-spear/platsmp.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)
arch/arm/mach-spear/platsmp.c +14 -5
index 5c4a19887b2b..eb9f2ef1e974 100644
@@ -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)) {
Signature · 1 line
1.8.3.1
#4 lore raw

PATCH 4/75 ARM: l2c: omap2: remove ES1.0 support

In reply to Russell King - ARM Linux

Santosh says:

Quoted 4 lines

But we should kill all of that since we long back decided to remove ES1.0 related code. The mach-omap code alreasy has removed the ES1.0 compatibility so feel free to remove any specific ES1.0 related stuff. That silicon is long dead.

---
 arch/arm/mach-omap2/omap4-common.c | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)
arch/arm/mach-omap2/omap4-common.c +8 -17
index 6cd3f3772ecf..9f8d506f511d 100644
@@ -181,7 +181,7 @@ static void omap4_l2x0_set_debug(unsigned long val)
 
 static int __init omap_l2_cache_init(void)
 {
-	u32 aux_ctrl = 0;
+	u32 aux_ctrl;
 
 	/*
 	 * To avoid code running on other OMAPs in
@@ -195,27 +195,18 @@ static int __init omap_l2_cache_init(void)
 	if (WARN_ON(!l2cache_base))
 		return -ENOMEM;
 
-	/*
-	 * 16-way associativity, parity disabled
-	 * Way size - 32KB (es1.0)
-	 * Way size - 64KB (es2.0 +)
-	 */
-	aux_ctrl = ((1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT) |
+	/* 16-way associativity, parity disabled, 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));
-
-	if (omap_rev() == OMAP4430_REV_ES1_0) {
-		aux_ctrl |= 0x2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT;
-	} else {
-		aux_ctrl |= ((0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
+			(0x1 << L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT)) |
+			(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));
-	}
-	if (omap_rev() != OMAP4430_REV_ES1_0)
-		omap_smc1(0x109, aux_ctrl);
+			(1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT);
+
+	omap_smc1(0x109, aux_ctrl);
 
 	/* Enable PL310 L2 Cache controller */
 	omap_smc1(0x102, 0x1);
Signature · 1 line
1.8.3.1
maintainer
#5 lore raw

PATCH 4/75 ARM: l2c: omap2: remove ES1.0 support

Quoted 7 lines · Russell King

Santosh says:

Quoted 4 lines

But we should kill all of that since we long back decided to remove ES1.0 related code. The mach-omap code alreasy has removed the ES1.0 compatibility so feel free to remove any specific ES1.0 related stuff. That silicon is long dead.

Makes sense to me to make the handling generic:

#6 lore raw

PATCH 5/75 ARM: l2c: remove unnecessary UL-suffix to mask values

In reply to Russell King - ARM Linux

They're u32, they're not unsigned long. The UL suffix is not required here.

---
 arch/arm/mach-highbank/highbank.c   | 2 +-
 arch/arm/mach-imx/mach-vf610.c      | 2 +-
 arch/arm/mach-imx/system.c          | 2 +-
 arch/arm/mach-mvebu/armada-370-xp.c | 2 +-
 arch/arm/mach-rockchip/rockchip.c   | 2 +-
 arch/arm/mach-socfpga/socfpga.c     | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)
arch/arm/mach-highbank/highbank.c +1 -1
index c7de89b263dd..38e1dc3b4c6e 100644
@@ -69,7 +69,7 @@ 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);
-		l2x0_of_init(0, ~0UL);
+		l2x0_of_init(0, ~0);
 		outer_cache.disable = highbank_l2x0_disable;
 	}
 }
arch/arm/mach-imx/mach-vf610.c +1 -1
index 2d8aef5a6efa..6288a9690e78 100644
@@ -22,7 +22,7 @@ static void __init vf610_init_machine(void)
 
 static void __init vf610_init_irq(void)
 {
-	l2x0_of_init(0, ~0UL);
+	l2x0_of_init(0, ~0);
 	irqchip_init();
 }
 
arch/arm/mach-imx/system.c +1 -1
index 5e3027d3692f..c6571f1de9fd 100644
@@ -145,6 +145,6 @@ void __init imx_init_l2cache(void)
 	of_node_put(np);
 
 out:
-	l2x0_of_init(0, ~0UL);
+	l2x0_of_init(0, ~0);
 }
 #endif
arch/arm/mach-mvebu/armada-370-xp.c +1 -1
index f6c9d1d85c14..9d6c401d8738 100644
@@ -43,7 +43,7 @@ static void __init armada_370_xp_timer_and_clk_init(void)
 	coherency_init();
 	BUG_ON(mvebu_mbus_dt_init());
 #ifdef CONFIG_CACHE_L2X0
-	l2x0_of_init(0, ~0UL);
+	l2x0_of_init(0, ~0);
 #endif
 }
 
arch/arm/mach-rockchip/rockchip.c +1 -1
index 82c0b0709712..de9dc5f87d55 100644
@@ -25,7 +25,7 @@
 
 static void __init rockchip_dt_init(void)
 {
-	l2x0_of_init(0, ~0UL);
+	l2x0_of_init(0, ~0);
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
arch/arm/mach-socfpga/socfpga.c +1 -1
index dd0d49cdbe09..395fa085b43e 100644
@@ -104,7 +104,7 @@ static void socfpga_cyclone5_restart(enum reboot_mode mode, const char *cmd)
 
 static void __init socfpga_cyclone5_init(void)
 {
-	l2x0_of_init(0, ~0UL);
+	l2x0_of_init(0, ~0);
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 	socfpga_init_clocks();
 }
Signature · 1 line
1.8.3.1
maintainer
#7 lore raw

PATCH 5/75 ARM: l2c: remove unnecessary UL-suffix to mask values

Quoted 18 lines · Russell King

They're u32, they're not unsigned long. The UL suffix is not required here.

---
 arch/arm/mach-highbank/highbank.c   | 2 +-
 arch/arm/mach-imx/mach-vf610.c      | 2 +-
 arch/arm/mach-imx/system.c          | 2 +-
 arch/arm/mach-mvebu/armada-370-xp.c | 2 +-
 arch/arm/mach-rockchip/rockchip.c   | 2 +-
 arch/arm/mach-socfpga/socfpga.c     | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)
arch/arm/mach-highbank/highbank.c +0 -0
index c7de89b263dd..38e1dc3b4c6e 100644

arch/arm/mach-highbank/highbank.c static void __init highbank_init_irq(void) · line 72

Quoted 5 lines
arch/arm/mach-highbank/highbank.c +1 -1
@@ -69,7 +69,7 @@ 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);
-               l2x0_of_init(0, ~0UL);
+               l2x0_of_init(0, ~0);

What about changing these callers to use l2x0_of_init(void) and creating l2x0_of_init_legacy(val, mask) for ones that need the aux ctrl setup? We do want to encourage people to either setup aux ctrl in the bootloader or via DT properties.

Rob

#8 lore raw

PATCH 5/75 ARM: l2c: remove unnecessary UL-suffix to mask values

Quoted 4 lines · Rob Herring

What about changing these callers to use l2x0_of_init(void) and creating l2x0_of_init_legacy(val, mask) for ones that need the aux ctrl setup? We do want to encourage people to either setup aux ctrl in the bootloader or via DT properties.

I have thought about that, but let's first sort out what platforms need. It sounds like some platforms really do need to manipulate the register, some really need to do it to have a functional setup because they never set the hardware configuration of the cache size.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#9 lore raw

PATCH 6/75 ARM: outer cache: add documentation of outer cache functions

In reply to Russell King - ARM Linux

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.

---
 arch/arm/include/asm/outercache.h | 48 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)
arch/arm/include/asm/outercache.h +47 -1
index 0e4420858990..bd80540fe8b9 100644
@@ -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)
Signature · 1 line
1.8.3.1
#10 lore raw

PATCH 6/75 ARM: outer cache: add documentation of outer cache functions

Quoted 15 lines · Russell King

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.

---
 arch/arm/include/asm/outercache.h | 48 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)
arch/arm/include/asm/outercache.h +0 -0
index 0e4420858990..bd80540fe8b9 100644

arch/arm/include/asm/outercache.h struct outer_cache_fns { · line 43

Quoted 6 lines
arch/arm/include/asm/outercache.h +2 -1
@@ -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

This is not proper kernel-doc format.

It should be like this:
/**
- * outer_inv_range: invalidate range of outer cache lines
+ * outer_inv_range - invalidate range of outer cache lines

The same change should be done below too.

[linux]$ ./scripts/kernel-doc -man -v arch/arm/include/asm/outercache.h >/dev/null Warning(arch/arm/include/asm/outercache.h:43): missing initial short description on line:
* outer_inv_range: invalidate range of outer cache lines
Info(arch/arm/include/asm/outercache.h:43): Scanning doc for outer_inv_range Warning(arch/arm/include/asm/outercache.h:54): missing initial short description on line:
* outer_clean_range: clean dirty outer cache lines
Info(arch/arm/include/asm/outercache.h:54): Scanning doc for outer_clean_range Warning(arch/arm/include/asm/outercache.h:65): missing initial short description on line:
* outer_flush_range: clean and invalidate outer cache lines
Info(arch/arm/include/asm/outercache.h:65): Scanning doc for outer_flush_range Warning(arch/arm/include/asm/outercache.h:76): missing initial short description on line:
* outer_flush_all: clean and invalidate all cache lines in the outer cache
Info(arch/arm/include/asm/outercache.h:76): Scanning doc for outer_flush_all Warning(arch/arm/include/asm/outercache.h:93): missing initial short description on line:
* outer_disable: clean, invalidate and disable the outer cache
Info(arch/arm/include/asm/outercache.h:93): Scanning doc for outer_disable Info(arch/arm/include/asm/outercache.h:106): Scanning doc for restore the cache configuration and re Warning(arch/arm/include/asm/outercache.h:133): missing initial short description on line:
* outer_sync: perform a sync point for outer cache
Info(arch/arm/include/asm/outercache.h:133): Scanning doc for outer_sync

Thanks,
Michal

Signature · 14 lines
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140402/fd84ac0b/attachment.sig>
#11 lore raw

PATCH 6/75 ARM: outer cache: add documentation of outer cache functions

Quoted 18 lines · Michal Simek
Quoted 17 lines · Russell King

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.

---
 arch/arm/include/asm/outercache.h | 48 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)
arch/arm/include/asm/outercache.h +0 -0
index 0e4420858990..bd80540fe8b9 100644
@@ -39,35 +39,75 @@ struct outer_cache_fns {
 extern struct outer_cache_fns outer_cache;
 
Quoted 6 lines

arch/arm/include/asm/outercache.h struct outer_cache_fns { · line 43

Quoted 4 lines
arch/arm/include/asm/outercache.h +2 -1
 #ifdef CONFIG_OUTER_CACHE
-
+/**
+ * outer_inv_range: invalidate range of outer cache lines

This is not proper kernel-doc format.

Fixed, thanks.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#12 lore raw

PATCH 7/75 ARM: outer cache: add WARN_ON() to outer_disable()

In reply to Russell King - ARM Linux

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

---
 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
arch/arm/include/asm/outercache.h +2 -5
index bd80540fe8b9..1ee2cf23fae1 100644
@@ -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
arch/arm/mm/Makefile +1 -0
index 7f39ce2f841f..de5a6a27081b 100644
@@ -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
arch/arm/mm/l2c-common.c new file +20 -0
new file mode 100644
index 000000000000..10a3cf28c362
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2010 ARM Ltd.
+ * Written by Catalin Marinas <[email protected]>
+ *
+ * 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();
+}
Signature · 1 line
1.8.3.1
#13 lore raw

PATCH 8/75 ARM: l2c: add helper for L2 cache controller DT IDs

In reply to Russell King - ARM Linux

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

---
 arch/arm/mm/cache-l2x0.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)
arch/arm/mm/cache-l2x0.c +10 -13
index f9985e5a208c..ac410b21edfb 100644
@@ -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),
 	{}
 };
 
Signature · 1 line
1.8.3.1
#14 lore raw

PATCH 9/75 ARM: l2c: tidy up l2x0_of_data declarations

In reply to Russell King - ARM Linux

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

---
 arch/arm/mm/cache-l2x0.c | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)
arch/arm/mm/cache-l2x0.c +14 -16
index ac410b21edfb..063e1787e8c3 100644
@@ -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,
 	},
 };
 
Signature · 1 line
1.8.3.1
#15 lore raw

PATCH 10/75 ARM: l2c: rename OF specific things, making l2x0_of_data available to all

In reply to Russell King - ARM Linux

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

---
 arch/arm/mm/cache-l2x0.c | 64 ++++++++++++++++++++++++------------------------
 1 file changed, 32 insertions(+), 32 deletions(-)
arch/arm/mm/cache-l2x0.c +32 -32
index 063e1787e8c3..d659c4ca46bb 100644
@@ -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();
 	}
 
Signature · 1 line
1.8.3.1
#16 lore raw

PATCH 11/75 ARM: l2c: provide generic function for calling set_debug method

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
arch/arm/mm/cache-l2x0.c +11 -1
index d659c4ca46bb..595c50519e41 100644
@@ -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)
Signature · 1 line
1.8.3.1
#17 lore raw

PATCH 12/75 ARM: l2c: split out cache unlock code

In reply to Russell King - ARM Linux

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

---
 arch/arm/mm/cache-l2x0.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)
arch/arm/mm/cache-l2x0.c +16 -7
index 595c50519e41..a1313d20f205 100644
@@ -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)
Signature · 1 line
1.8.3.1
#18 lore raw

PATCH 13/75 ARM: l2c: provide generic helper for way-based operations

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)
arch/arm/mm/cache-l2x0.c +9 -6
index a1313d20f205..1c3a23318f53 100644
@@ -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);
 }
Signature · 1 line
1.8.3.1
#19 lore raw

PATCH 14/75 ARM: l2c: rename cache_wait_way()

In reply to Russell King - ARM Linux

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().

---
 arch/arm/mm/cache-l2x0.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm/mm/cache-l2x0.c +3 -3
index 1c3a23318f53..29ee7f692801 100644
@@ -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)
Signature · 1 line
1.8.3.1
#20 lore raw

PATCH 15/75 ARM: l2c: add and use L2C revision constants

In reply to Russell King - ARM Linux

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

---
 arch/arm/include/asm/hardware/cache-l2x0.h | 22 ++++++++++++++++------
 arch/arm/mm/cache-l2x0.c                   | 10 +++++-----
 2 files changed, 21 insertions(+), 11 deletions(-)
arch/arm/include/asm/hardware/cache-l2x0.h +16 -6
index 6795ff743b3d..94fbcec216ae 100644
@@ -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
arch/arm/mm/cache-l2x0.c +5 -5
index 29ee7f692801..c39602ef2cdd 100644
@@ -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);
 		}
Signature · 1 line
1.8.3.1
#21 lore raw

PATCH 15/75 ARM: l2c: add and use L2C revision constants

Quoted 31 lines · Russell King

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

---
 arch/arm/include/asm/hardware/cache-l2x0.h | 22 ++++++++++++++++------
 arch/arm/mm/cache-l2x0.c                   | 10 +++++-----
 2 files changed, 21 insertions(+), 11 deletions(-)
arch/arm/include/asm/hardware/cache-l2x0.h +6 -6
index 6795ff743b3d..94fbcec216ae 100644
@@ -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

arch/arm/include/asm/hardware/cache-l2x0.h line 88

Quoted 10 lines
arch/arm/include/asm/hardware/cache-l2x0.h +10 -0
+#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

Will be good to also clear tabs and spaces usage here (tabs or spaces not mixing both).

Thanks,
Michal

Signature · 14 lines
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140402/82150868/attachment.sig>
#22 lore raw

PATCH 15/75 ARM: l2c: add and use L2C revision constants

Quoted 37 lines · Michal Simek
Quoted 36 lines · Russell King

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

---
 arch/arm/include/asm/hardware/cache-l2x0.h | 22 ++++++++++++++++------
 arch/arm/mm/cache-l2x0.c                   | 10 +++++-----
 2 files changed, 21 insertions(+), 11 deletions(-)
arch/arm/include/asm/hardware/cache-l2x0.h +11 -6
index 6795ff743b3d..94fbcec216ae 100644
@@ -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
Quoted 8 lines

arch/arm/include/asm/hardware/cache-l2x0.h line 88

Quoted 5 lines
arch/arm/include/asm/hardware/cache-l2x0.h +5 -0
+#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

Will be good to also clear tabs and spaces usage here (tabs or spaces not mixing both).

That's because I just modified the names of the old ones, and added the new ones using tabs. All +'d lines fixed to use tabs. I haven't changed the L2X0_CACHE_ID_RTL_MASK line because that would imply I'm doing a cleanup to this rather than fixing these definitions.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#23 lore raw

PATCH 16/75 ARM: l2c: clean up OF initialisation a bit

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 66 +++++++++++++++++++++++++++++-------------------
 1 file changed, 40 insertions(+), 26 deletions(-)
arch/arm/mm/cache-l2x0.c +40 -26
index c39602ef2cdd..0d83b24b7971 100644
@@ -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;
 }
Signature · 1 line
1.8.3.1
#24 lore raw

PATCH 17/75 ARM: l2c: pass iomem address into data->save function

In reply to Russell King - ARM Linux

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

---
 arch/arm/mm/cache-l2x0.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)
arch/arm/mm/cache-l2x0.c +16 -16
index 0d83b24b7971..08f9cade028a 100644
@@ -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;
Signature · 1 line
1.8.3.1
#25 lore raw

PATCH 18/75 ARM: l2c: move l2c save function to __l2c_init()

In reply to Russell King - ARM Linux

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

---
 arch/arm/mm/cache-l2x0.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
arch/arm/mm/cache-l2x0.c +7 -3
index 08f9cade028a..3b6213838054 100644
@@ -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
Signature · 1 line
1.8.3.1
#26 lore raw

PATCH 19/75 ARM: l2c: group implementation specific code together

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 502 +++++++++++++++++++++++------------------------
 1 file changed, 251 insertions(+), 251 deletions(-)
arch/arm/mm/cache-l2x0.c +251 -251
index 3b6213838054..09fe0f5eada5 100644
@@ -464,6 +464,175 @@ 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,
+	.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,
+	.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
@@ -562,6 +731,75 @@ 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 __init aurora_broadcast_l2_commands(void)
+{
+	__u32 u;
+	/* Enable Broadcasting of cache commands to L2*/
+	__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));
+	isb();
+}
+
+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,
+	.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,
+	.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
@@ -703,108 +941,19 @@ 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,
+	.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)
 {
@@ -814,60 +963,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)) {
@@ -880,87 +975,6 @@ static void tauros3_resume(void)
 	l2x0_resume();
 }
 
-static void __init aurora_broadcast_l2_commands(void)
-{
-	__u32 u;
-	/* Enable Broadcasting of cache commands to L2*/
-	__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));
-	isb();
-}
-
-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,
-	.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,
-	.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,
-	.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,
-	.save  = aurora_save,
-	.outer_cache = {
-		.resume      = aurora_resume,
-	},
-};
-
 static const struct l2c_init_data of_tauros3_data __initconst = {
 	.save  = tauros3_save,
 	/* Tauros3 broadcasts L1 cache operations to L2 */
@@ -969,20 +983,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,
-	.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),
Signature · 1 line
1.8.3.1
#27 lore raw

PATCH 20/75 ARM: l2c: provide enable method

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 80 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 62 insertions(+), 18 deletions(-)
arch/arm/mm/cache-l2x0.c +62 -18
index 09fe0f5eada5..2adb82e7f4b3 100644
@@ -29,7 +29,9 @@
 #include "cache-aurora-l2.h"
 
 struct l2c_init_data {
+	unsigned num_lock;
 	void (*of_parse)(const struct device_node *, u32 *, u32 *);
+	void (*enable)(void __iomem *, u32, unsigned);
 	void (*save)(void __iomem *);
 	struct outer_cache_fns outer_cache;
 };
@@ -82,6 +84,36 @@ 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);
+}
+
+static void l2c_disable(void)
+{
+	void __iomem *base = l2x0_base;
+
+	outer_cache.flush_all();
+	writel_relaxed(0, base + L2X0_CTRL);
+	dsb(st);
+}
+
 #ifdef CONFIG_CACHE_PL310
 static inline void cache_wait(void __iomem *reg, unsigned long mask)
 {
@@ -325,9 +357,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 +366,22 @@ static void l2x0_unlock(u32 cache_id)
 	l2c_unlock(l2x0_base, lockregs);
 }
 
+static void l2x0_enable(void __iomem *base, u32 aux, unsigned num_lock)
+{
+	/* 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 +456,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, data->num_lock);
 
 	/* Re-read it in case some bits are reserved. */
 	aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
@@ -515,6 +548,7 @@ static void l2x0_resume(void)
 
 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,
@@ -620,7 +654,9 @@ static void pl310_resume(void)
 }
 
 static const struct l2c_init_data of_pl310_data __initconst = {
+	.num_lock = 8,
 	.of_parse = pl310_of_parse,
+	.enable = l2c_enable,
 	.save  = pl310_save,
 	.outer_cache = {
 		.inv_range   = l2x0_inv_range,
@@ -779,7 +815,9 @@ static void __init aurora_of_parse(const struct device_node *np,
 }
 
 static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
+	.num_lock = 4,
 	.of_parse = aurora_of_parse,
+	.enable = l2c_enable,
 	.save  = aurora_save,
 	.outer_cache = {
 		.inv_range   = aurora_inv_range,
@@ -793,7 +831,9 @@ static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
 };
 
 static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
+	.num_lock = 4,
 	.of_parse = aurora_of_parse,
+	.enable = l2c_enable,
 	.save  = aurora_save,
 	.outer_cache = {
 		.resume      = aurora_resume,
@@ -942,7 +982,9 @@ static void bcm_flush_range(unsigned long start, unsigned long end)
 }
 
 static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
+	.num_lock = 8,
 	.of_parse = pl310_of_parse,
+	.enable = l2c_enable,
 	.save  = pl310_save,
 	.outer_cache = {
 		.inv_range   = bcm_inv_range,
@@ -976,6 +1018,8 @@ static void tauros3_resume(void)
 }
 
 static const struct l2c_init_data of_tauros3_data __initconst = {
+	.num_lock = 8,
+	.enable = l2c_enable,
 	.save  = tauros3_save,
 	/* Tauros3 broadcasts L1 cache operations to L2 */
 	.outer_cache = {
Signature · 1 line
1.8.3.1
#28 lore raw

PATCH 21/75 ARM: l2c: write auxctrl register before unlocking

In reply to Russell King - ARM Linux

We should write the auxillary control register before unlocking: the write may be necessary to enable non-secure access to the lock registers.

---
 arch/arm/mm/cache-l2x0.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
arch/arm/mm/cache-l2x0.c +5 -5
index 2adb82e7f4b3..fc609550b7fa 100644
@@ -92,10 +92,10 @@ 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);
 
+	l2c_unlock(base, num_lock);
+
 	local_irq_save(flags);
 	__l2c_op_way(base + L2X0_INV_WAY);
 	writel_relaxed(0, base + sync_reg_offset);
@@ -368,12 +368,12 @@ static void l2x0_unlock(u32 cache_id)
 
 static void l2x0_enable(void __iomem *base, u32 aux, unsigned num_lock)
 {
-	/* 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);
 
+	/* Make sure that I&D is not locked down when starting */
+	l2x0_unlock(readl_relaxed(base + L2X0_CACHE_ID));
+
 	l2x0_inv_all();
 
 	/* enable L2X0 */
Signature · 1 line
1.8.3.1
#29 lore raw

PATCH 22/75 ARM: l2c: only write the auxiliary control register if required

In reply to Russell King - ARM Linux

Avoid unnecessary writes to the auxiliary control register if the register already contains the required value. This allows us to avoid invoking the platforms secure monitor code unnecessarily.

---
 arch/arm/mm/cache-l2x0.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/arm/mm/cache-l2x0.c +3 -1
index fc609550b7fa..1c947b4c7f05 100644
@@ -92,7 +92,9 @@ static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
 {
 	unsigned long flags;
 
-	writel_relaxed(aux, base + L2X0_AUX_CTRL);
+	/* Only write the aux register if it needs changing */
+	if (readl_relaxed(base + L2X0_AUX_CTRL) != aux)
+		writel_relaxed(aux, base + L2X0_AUX_CTRL);
 
 	l2c_unlock(base, num_lock);
 
Signature · 1 line
1.8.3.1
#30 lore raw

PATCH 23/75 ARM: l2c: move aurora broadcast setup to enable function

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)
arch/arm/mm/cache-l2x0.c +15 -13
index 1c947b4c7f05..5f381af1a7a4 100644
@@ -784,14 +784,22 @@ static void aurora_resume(void)
 	}
 }
 
-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,
+	unsigned num_lock)
 {
-	__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();
+
+	l2c_enable(base, aux, num_lock);
 }
 
 static void __init aurora_of_parse(const struct device_node *np,
@@ -835,7 +843,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 = {
 	.num_lock = 4,
 	.of_parse = aurora_of_parse,
-	.enable = l2c_enable,
+	.enable = aurora_enable_no_outer,
 	.save  = aurora_save,
 	.outer_cache = {
 		.resume      = aurora_resume,
@@ -1066,16 +1074,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
Signature · 1 line
1.8.3.1
#31 lore raw

PATCH 24/75 ARM: l2c: implement fixups for L2 cache controller quirks/errata

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 112 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 101 insertions(+), 11 deletions(-)
arch/arm/mm/cache-l2x0.c +101 -11
index 5f381af1a7a4..a544f19c448f 100644
@@ -32,6 +32,7 @@ struct l2c_init_data {
 	unsigned num_lock;
 	void (*of_parse)(const struct device_node *, u32 *, u32 *);
 	void (*enable)(void __iomem *, u32, unsigned);
+	void (*fixup)(void __iomem *, u32, struct outer_cache_fns *);
 	void (*save)(void __iomem *);
 	struct outer_cache_fns outer_cache;
 };
@@ -394,9 +395,80 @@ 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 = {
+	.num_lock = 8,
+	.enable = l2c_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;
@@ -423,23 +495,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;
@@ -457,6 +526,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.
@@ -470,11 +543,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",
@@ -483,13 +552,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
@@ -659,6 +739,7 @@ static const struct l2c_init_data of_pl310_data __initconst = {
 	.num_lock = 8,
 	.of_parse = pl310_of_parse,
 	.enable = l2c_enable,
+	.fixup = l2c310_fixup,
 	.save  = pl310_save,
 	.outer_cache = {
 		.inv_range   = l2x0_inv_range,
@@ -802,6 +883,12 @@ static void __init aurora_enable_no_outer(void __iomem *base, u32 aux,
 	l2c_enable(base, aux, num_lock);
 }
 
+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)
 {
@@ -828,6 +915,7 @@ static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
 	.num_lock = 4,
 	.of_parse = aurora_of_parse,
 	.enable = l2c_enable,
+	.fixup = aurora_fixup,
 	.save  = aurora_save,
 	.outer_cache = {
 		.inv_range   = aurora_inv_range,
@@ -844,6 +932,7 @@ static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
 	.num_lock = 4,
 	.of_parse = aurora_of_parse,
 	.enable = aurora_enable_no_outer,
+	.fixup = aurora_fixup,
 	.save  = aurora_save,
 	.outer_cache = {
 		.resume      = aurora_resume,
@@ -995,6 +1084,7 @@ static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
 	.num_lock = 8,
 	.of_parse = pl310_of_parse,
 	.enable = l2c_enable,
+	.fixup = l2c310_fixup,
 	.save  = pl310_save,
 	.outer_cache = {
 		.inv_range   = bcm_inv_range,
Signature · 1 line
1.8.3.1
#32 lore raw

PATCH 25/75 ARM: l2c: clean up L2 cache initialisation messages

In reply to Russell King - ARM Linux

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

---
 arch/arm/mm/cache-l2x0.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
arch/arm/mm/cache-l2x0.c +4 -3
index a544f19c448f..713cdcef25d1 100644
@@ -545,9 +545,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)
Signature · 1 line
1.8.3.1
#33 lore raw

PATCH 26/75 ARM: l2c: move and add ARM L2C-2x0/L2C-310 save/resume code to non-OF

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 151 ++++++++++++++++++++++++-----------------------
 1 file changed, 77 insertions(+), 74 deletions(-)
arch/arm/mm/cache-l2x0.c +77 -74
index 713cdcef25d1..4d985c17291c 100644
@@ -383,6 +383,21 @@ static void l2x0_enable(void __iomem *base, u32 aux, unsigned num_lock)
 	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 = {
@@ -392,6 +407,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,
 	},
 };
 
@@ -422,6 +438,65 @@ static const struct l2c_init_data l2x0_init_fns __initconst = {
  *	Affects: store buffer
  *	store buffer is not automatically drained.
  */
+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)
 {
@@ -455,6 +530,7 @@ static const struct l2c_init_data l2c310_init_fns __initconst = {
 	.num_lock = 8,
 	.enable = l2c_enable,
 	.fixup = l2c310_fixup,
+	.save = pl310_save,
 	.outer_cache = {
 		.inv_range = l2x0_inv_range,
 		.clean_range = l2x0_clean_range,
@@ -462,6 +538,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,
 	},
 };
 
@@ -614,21 +691,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,
@@ -677,65 +739,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 = {
 	.num_lock = 8,
 	.of_parse = pl310_of_parse,
Signature · 1 line
1.8.3.1
#34 lore raw

PATCH 27/75 ARM: l2c: clean up save/resume functions

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 109 ++++++++++++++++++++++-------------------------
 1 file changed, 52 insertions(+), 57 deletions(-)
arch/arm/mm/cache-l2x0.c +52 -57
index 4d985c17291c..e3f4fcbcc88b 100644
@@ -385,17 +385,10 @@ static void l2x0_enable(void __iomem *base, u32 aux, unsigned num_lock)
 
 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, 0);
 }
 
 static const struct l2c_init_data l2x0_init_fns __initconst = {
@@ -438,10 +431,9 @@ static const struct l2c_init_data l2x0_init_fns __initconst = {
  *	Affects: store buffer
  *	store buffer is not automatically drained.
  */
-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);
@@ -452,49 +444,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();
+		l2c_enable(base, l2x0_saved_regs.aux_ctrl, 8);
+	}
 }
 
 static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
@@ -530,7 +522,7 @@ static const struct l2c_init_data l2c310_init_fns __initconst = {
 	.num_lock = 8,
 	.enable = l2c_enable,
 	.fixup = l2c310_fixup,
-	.save = pl310_save,
+	.save = l2c310_save,
 	.outer_cache = {
 		.inv_range = l2x0_inv_range,
 		.clean_range = l2x0_clean_range,
@@ -538,7 +530,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,
 	},
 };
 
@@ -744,7 +736,7 @@ static const struct l2c_init_data of_pl310_data __initconst = {
 	.of_parse = pl310_of_parse,
 	.enable = l2c_enable,
 	.fixup = l2c310_fixup,
-	.save  = pl310_save,
+	.save  = l2c310_save,
 	.outer_cache = {
 		.inv_range   = l2x0_inv_range,
 		.clean_range = l2x0_clean_range,
@@ -752,7 +744,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,
 	},
 };
 
@@ -862,10 +854,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);
 	}
 }
 
@@ -1089,7 +1082,7 @@ static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
 	.of_parse = pl310_of_parse,
 	.enable = l2c_enable,
 	.fixup = l2c310_fixup,
-	.save  = pl310_save,
+	.save  = l2c310_save,
 	.outer_cache = {
 		.inv_range   = bcm_inv_range,
 		.clean_range = bcm_clean_range,
@@ -1097,7 +1090,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,
 	},
 };
 
@@ -1111,14 +1104,16 @@ 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();
+		l2c_enable(base, l2x0_saved_regs.aux_ctrl, 8);
+	}
 }
 
 static const struct l2c_init_data of_tauros3_data __initconst = {
Signature · 1 line
1.8.3.1
#35 lore raw

PATCH 28/75 ARM: l2c: simplify l2x0 unlocking code

In reply to Russell King - ARM Linux

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

---
 arch/arm/mm/cache-l2x0.c | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)
arch/arm/mm/cache-l2x0.c +8 -17
index e3f4fcbcc88b..157fd7ae331a 100644
@@ -352,30 +352,21 @@ 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, unsigned num_lock)
 {
-	int lockregs;
+	unsigned id;
 
-	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, unsigned num_lock)
-{
 	/* l2x0 controller is disabled */
 	writel_relaxed(aux, base + L2X0_AUX_CTRL);
 
 	/* 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_inv_all();
 
Signature · 1 line
1.8.3.1
#36 lore raw

PATCH 29/75 ARM: l2c: move pl310_set_debug() into l2c-310 code

In reply to Russell King - ARM Linux

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

---
 arch/arm/mm/cache-l2x0.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)
arch/arm/mm/cache-l2x0.c +6 -8
index 157fd7ae331a..9586be73ca4f 100644
@@ -154,18 +154,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
@@ -422,6 +415,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 __init l2c310_save(void __iomem *base)
 {
 	unsigned revision;
@@ -488,7 +486,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) {
Signature · 1 line
1.8.3.1
#37 lore raw

PATCH 30/75 ARM: l2c: add L2C-210 specific handlers

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 122 insertions(+), 1 deletion(-)
arch/arm/mm/cache-l2x0.c +122 -1
index 9586be73ca4f..d07fa4fc95a3 100644
@@ -389,6 +389,108 @@ 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_sync(void)
+{
+	__l2c210_cache_sync(l2x0_base);
+}
+
+static void l2c210_resume(void)
+{
+	void __iomem *base = l2x0_base;
+
+	if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN))
+		l2c_enable(base, l2x0_saved_regs.aux_ctrl, 1);
+}
+
+static const struct l2c_init_data l2c210_data __initconst = {
+	.num_lock = 1,
+	.enable = l2c_enable,
+	.outer_cache = {
+		.inv_range = l2c210_inv_range,
+		.clean_range = l2c210_clean_range,
+		.flush_range = l2c210_flush_range,
+		.flush_all = l2c210_flush_all,
+		.disable = l2c_disable,
+		.sync = l2c210_sync,
+		.resume = l2c210_resume,
+	},
+};
+
+/*
  * L2C-310 specific code.
  *
  * Errata:
@@ -623,6 +725,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;
@@ -672,6 +778,21 @@ static void __init l2x0_of_parse(const struct device_node *np,
 	*aux_mask &= ~mask;
 }
 
+static const struct l2c_init_data of_l2c210_data __initconst = {
+	.num_lock = 1,
+	.of_parse = l2x0_of_parse,
+	.enable = l2c_enable,
+	.outer_cache = {
+		.inv_range   = l2c210_inv_range,
+		.clean_range = l2c210_clean_range,
+		.flush_range = l2c210_flush_range,
+		.flush_all   = l2c210_flush_all,
+		.disable     = l2c_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,
@@ -1117,7 +1238,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),
Signature · 1 line
1.8.3.1
#38 lore raw

PATCH 31/75 ARM: l2c: implement L2C-310 erratum 727915 as a method override

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
arch/arm/mm/cache-l2x0.c +20 -0
index d07fa4fc95a3..6161232c8a85 100644
@@ -522,6 +522,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 __init l2c310_save(void __iomem *base)
 {
 	unsigned revision;
@@ -590,6 +603,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;
Signature · 1 line
1.8.3.1
#39 lore raw

PATCH 32/75 ARM: l2c: implement L2C-310 erratum 588369 as a method override

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)
arch/arm/mm/cache-l2x0.c +69 -0
index 6161232c8a85..310ed787595f 100644
@@ -522,6 +522,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;
@@ -600,9 +659,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) {
Signature · 1 line
1.8.3.1
#40 lore raw

PATCH 32/75 ARM: l2c: implement L2C-310 erratum 588369 as a method override

Quoted 7 lines · Russell King

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.

---

[snip]

arch/arm/mm/cache-l2x0.c static void __init l2c310_fixup(void __iomem *base, u32 cache_id, · line 662

Quoted 5 lines
arch/arm/mm/cache-l2x0.c +1 -0
@@ -600,9 +659,19 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
        const char *errata[4];
        unsigned n = 0;
 
+       /* For compatibility */

Compatibility of what? This needs a better comment.

arch/arm/mm/cache-l2x0.c static void __init l2c310_fixup(void __iomem *base, u32 cache_id, · line 668

Quoted 6 lines
arch/arm/mm/cache-l2x0.c +3 -0
        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 */

same here.

arch/arm/mm/cache-l2x0.c static void __init l2c310_fixup(void __iomem *base, u32 cache_id, · line 672

Quoted 4 lines
arch/arm/mm/cache-l2x0.c +4 -0
+           fns->inv_range == l2x0_inv_range) {
+               fns->inv_range = l2c310_inv_range_erratum;
+               fns->flush_range = l2c310_flush_range_erratum;
+               errata[n++] = "533369";

s/533369/588369/

Quoted 13 lines
arch/arm/mm/cache-l2x0.c +2 -1
+       }
+
        if (IS_ENABLED(CONFIG_PL310_ERRATA_727915) &&
            revision >= L310_CACHE_ID_RTL_R2P0 &&
            revision < L310_CACHE_ID_RTL_R3P1) {
--

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

#41 lore raw

PATCH 32/75 ARM: l2c: implement L2C-310 erratum 588369 as a method override

Quoted 12 lines · Rob Herring
Quoted 7 lines · Russell King

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.

---

[snip]

Quoted 10 lines

arch/arm/mm/cache-l2x0.c static void __init l2c310_fixup(void __iomem *base, u32 cache_id, · line 662

Quoted 5 lines
arch/arm/mm/cache-l2x0.c +1 -0
@@ -600,9 +659,19 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
        const char *errata[4];
        unsigned n = 0;
 
+       /* For compatibility */

Compatibility of what? This needs a better comment.

Quoted 2 lines
arch/arm/mm/cache-l2x0.c +0 -0
        if (revision <= L310_CACHE_ID_RTL_R3P0)
                fns->set_debug = l2c310_set_debug;

With the way the existing code works with the set_debug method. You may notice that this comment and code is removed in "ARM: l2c: remove old .set_debug method".

Quoted 8 lines

arch/arm/mm/cache-l2x0.c static void __init l2c310_fixup(void __iomem *base, u32 cache_id, · line 668

Quoted 4 lines
arch/arm/mm/cache-l2x0.c +3 -0
+       if (IS_ENABLED(CONFIG_PL310_ERRATA_588369) &&
+           revision < L310_CACHE_ID_RTL_R2P0 &&
+           /* For compatibility */

same here.

Quoted 1 line
arch/arm/mm/cache-l2x0.c +1 -0
+           fns->inv_range == l2x0_inv_range) {
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

hint - the comment is above the code which it applies to in both cases.

It's referring to those which don't have a .inv_range of that, but are L2C-310. Well, there's Broadcom's implementation which thankfully is R3 or later, though I later dropped the call to this function from the Broadcom stuff since I had confirmation that it was of a sufficiently modern version not to need any errata workarounds at all.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#42 lore raw

PATCH 33/75 ARM: l2c: use L2C-210 handlers for L2C-310 errata-less implementations

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 58 ++++++++++++++++++++++++++++++------------------
 1 file changed, 36 insertions(+), 22 deletions(-)
arch/arm/mm/cache-l2x0.c +36 -22
index 310ed787595f..1e52fd75c3d5 100644
@@ -493,6 +493,18 @@ 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)
+ *
  * Errata:
  * 588369: PL310 R0P0->R1P0, fixed R2P0.
  *	Affects: all clean+invalidate operations
@@ -666,7 +678,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";
@@ -704,12 +716,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 = l2c_disable,
+		.sync = l2c210_sync,
+		.set_debug = l2c310_set_debug,
 		.resume = l2c310_resume,
 	},
 };
@@ -896,8 +909,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 };
@@ -930,19 +943,20 @@ static void __init pl310_of_parse(const struct device_node *np,
 	}
 }
 
-static const struct l2c_init_data of_pl310_data __initconst = {
+static const struct l2c_init_data of_l2c310_data __initconst = {
 	.num_lock = 8,
-	.of_parse = pl310_of_parse,
+	.of_parse = l2c310_of_parse,
 	.enable = l2c_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     = l2c_disable,
+		.sync        = l2c210_sync,
+		.set_debug   = l2c310_set_debug,
 		.resume      = l2c310_resume,
 	},
 };
@@ -1278,7 +1292,7 @@ static void bcm_flush_range(unsigned long start, unsigned long end)
 
 static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
 	.num_lock = 8,
-	.of_parse = pl310_of_parse,
+	.of_parse = l2c310_of_parse,
 	.enable = l2c_enable,
 	.fixup = l2c310_fixup,
 	.save  = l2c310_save,
@@ -1286,9 +1300,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     = l2c_disable,
+		.sync        = l2c210_sync,
 		.resume      = l2c310_resume,
 	},
 };
@@ -1329,7 +1343,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),
Signature · 1 line
1.8.3.1
#43 lore raw

PATCH 34/75 ARM: l2c: add L2C-220 specific handlers

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 167 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 157 insertions(+), 10 deletions(-)
arch/arm/mm/cache-l2x0.c +157 -10
index 1e52fd75c3d5..ee2134671699 100644
@@ -491,6 +491,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_resume call.
+ */
+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 = {
+	.num_lock = 1,
+	.enable = l2c_enable,
+	.outer_cache = {
+		.inv_range = l2c220_inv_range,
+		.clean_range = l2c220_clean_range,
+		.flush_range = l2c220_flush_range,
+		.flush_all = l2c220_flush_all,
+		.disable = l2c_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,
@@ -831,6 +973,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;
@@ -895,17 +1041,18 @@ 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 = {
+	.num_lock = 1,
 	.of_parse = l2x0_of_parse,
-	.enable = l2x0_enable,
+	.enable = l2c_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     = l2c_disable,
+		.sync        = l2c220_sync,
+		.resume      = l2c210_resume,
 	},
 };
 
@@ -1342,7 +1489,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),
Signature · 1 line
1.8.3.1
#44 lore raw

PATCH 35/75 ARM: l2c: convert Broadcom L2C-310 to new code

In reply to Russell King - ARM Linux

The Broadcom L2C-310 devices use ARMs L2C-310 R2P3 or later. These require no errata workarounds, and so we can directly call the l2c210 functions from their methods.

---
 arch/arm/mm/cache-l2x0.c | 27 +++++++++++----------------
 1 file changed, 11 insertions(+), 16 deletions(-)
arch/arm/mm/cache-l2x0.c +11 -16
index ee2134671699..b059b8d885dc 100644
@@ -1360,16 +1360,16 @@ static void bcm_inv_range(unsigned long start, unsigned long end)
 
 	/* normal case, no cross section between start and end */
 	if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
-		l2x0_inv_range(new_start, new_end);
+		l2c210_inv_range(new_start, new_end);
 		return;
 	}
 
 	/* They cross sections, so it can only be a cross from section
 	 * 2 to section 3
 	 */
-	l2x0_inv_range(new_start,
+	l2c210_inv_range(new_start,
 		bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
-	l2x0_inv_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
+	l2c210_inv_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
 		new_end);
 }
 
@@ -1382,26 +1382,21 @@ static void bcm_clean_range(unsigned long start, unsigned long end)
 	if (unlikely(end <= start))
 		return;
 
-	if ((end - start) >= l2x0_size) {
-		l2x0_clean_all();
-		return;
-	}
-
 	new_start = bcm_l2_phys_addr(start);
 	new_end = bcm_l2_phys_addr(end);
 
 	/* normal case, no cross section between start and end */
 	if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
-		l2x0_clean_range(new_start, new_end);
+		l2c210_clean_range(new_start, new_end);
 		return;
 	}
 
 	/* They cross sections, so it can only be a cross from section
 	 * 2 to section 3
 	 */
-	l2x0_clean_range(new_start,
+	l2c210_clean_range(new_start,
 		bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
-	l2x0_clean_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
+	l2c210_clean_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
 		new_end);
 }
 
@@ -1415,7 +1410,7 @@ static void bcm_flush_range(unsigned long start, unsigned long end)
 		return;
 
 	if ((end - start) >= l2x0_size) {
-		l2x0_flush_all();
+		outer_cache.flush_all();
 		return;
 	}
 
@@ -1424,24 +1419,24 @@ static void bcm_flush_range(unsigned long start, unsigned long end)
 
 	/* normal case, no cross section between start and end */
 	if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
-		l2x0_flush_range(new_start, new_end);
+		l2c210_flush_range(new_start, new_end);
 		return;
 	}
 
 	/* They cross sections, so it can only be a cross from section
 	 * 2 to section 3
 	 */
-	l2x0_flush_range(new_start,
+	l2c210_flush_range(new_start,
 		bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
-	l2x0_flush_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
+	l2c210_flush_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
 		new_end);
 }
 
+/* Broadcom L2C-310 start from ARMs R3P2 or later, and require no fixups */
 static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
 	.num_lock = 8,
 	.of_parse = l2c310_of_parse,
 	.enable = l2c_enable,
-	.fixup = l2c310_fixup,
 	.save  = l2c310_save,
 	.outer_cache = {
 		.inv_range   = bcm_inv_range,
Signature · 1 line
1.8.3.1
#45 lore raw

PATCH 36/75 ARM: l2c: remove obsolete l2x0 ops for non-OF init

In reply to Russell King - ARM Linux

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.

This is also the last reference to:
- l2x0_clean_line()
- l2x0_inv_line()
- l2x0_flush_line()
- l2x0_flush_all()
- l2x0_clean_all()
- l2x0_inv_all()
- l2x0_inv_range()
- l2x0_clean_range()
- l2x0_flush_range()
- l2x0_enable()
- l2x0_resume()
so kill those functions too.

---
 arch/arm/mm/cache-l2x0.c | 206 -----------------------------------------------
 1 file changed, 206 deletions(-)
arch/arm/mm/cache-l2x0.c +0 -206
index b059b8d885dc..fc7ce31d9b52 100644
@@ -134,20 +134,6 @@ static inline void cache_sync(void)
 	cache_wait(base + L2X0_CACHE_SYNC, 1);
 }
 
-static inline void l2x0_clean_line(unsigned long addr)
-{
-	void __iomem *base = l2x0_base;
-	cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
-	writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA);
-}
-
-static inline void l2x0_inv_line(unsigned long addr)
-{
-	void __iomem *base = l2x0_base;
-	cache_wait(base + L2X0_INV_LINE_PA, 1);
-	writel_relaxed(addr, base + L2X0_INV_LINE_PA);
-}
-
 #if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
 static inline void debug_writel(unsigned long val)
 {
@@ -161,27 +147,6 @@ static inline void debug_writel(unsigned long val)
 }
 #endif
 
-#ifdef CONFIG_PL310_ERRATA_588369
-static inline void l2x0_flush_line(unsigned long addr)
-{
-	void __iomem *base = l2x0_base;
-
-	/* Clean by PA followed by Invalidate by PA */
-	cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
-	writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA);
-	cache_wait(base + L2X0_INV_LINE_PA, 1);
-	writel_relaxed(addr, base + L2X0_INV_LINE_PA);
-}
-#else
-
-static inline void l2x0_flush_line(unsigned long addr)
-{
-	void __iomem *base = l2x0_base;
-	cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
-	writel_relaxed(addr, base + L2X0_CLEAN_INV_LINE_PA);
-}
-#endif
-
 static void l2x0_cache_sync(void)
 {
 	unsigned long flags;
@@ -209,131 +174,6 @@ static void l2x0_flush_all(void)
 	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
-static void l2x0_clean_all(void)
-{
-	unsigned long flags;
-
-	/* clean all ways */
-	raw_spin_lock_irqsave(&l2x0_lock, flags);
-	__l2c_op_way(l2x0_base + L2X0_CLEAN_WAY);
-	cache_sync();
-	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
-}
-
-static void l2x0_inv_all(void)
-{
-	unsigned long flags;
-
-	/* invalidate all ways */
-	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);
-	__l2c_op_way(l2x0_base + L2X0_INV_WAY);
-	cache_sync();
-	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
-}
-
-static void l2x0_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 & (CACHE_LINE_SIZE - 1)) {
-		start &= ~(CACHE_LINE_SIZE - 1);
-		debug_writel(0x03);
-		l2x0_flush_line(start);
-		debug_writel(0x00);
-		start += CACHE_LINE_SIZE;
-	}
-
-	if (end & (CACHE_LINE_SIZE - 1)) {
-		end &= ~(CACHE_LINE_SIZE - 1);
-		debug_writel(0x03);
-		l2x0_flush_line(end);
-		debug_writel(0x00);
-	}
-
-	while (start < end) {
-		unsigned long blk_end = start + min(end - start, 4096UL);
-
-		while (start < blk_end) {
-			l2x0_inv_line(start);
-			start += CACHE_LINE_SIZE;
-		}
-
-		if (blk_end < end) {
-			raw_spin_unlock_irqrestore(&l2x0_lock, flags);
-			raw_spin_lock_irqsave(&l2x0_lock, flags);
-		}
-	}
-	cache_wait(base + L2X0_INV_LINE_PA, 1);
-	cache_sync();
-	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
-}
-
-static void l2x0_clean_range(unsigned long start, unsigned long end)
-{
-	void __iomem *base = l2x0_base;
-	unsigned long flags;
-
-	if ((end - start) >= l2x0_size) {
-		l2x0_clean_all();
-		return;
-	}
-
-	raw_spin_lock_irqsave(&l2x0_lock, flags);
-	start &= ~(CACHE_LINE_SIZE - 1);
-	while (start < end) {
-		unsigned long blk_end = start + min(end - start, 4096UL);
-
-		while (start < blk_end) {
-			l2x0_clean_line(start);
-			start += CACHE_LINE_SIZE;
-		}
-
-		if (blk_end < end) {
-			raw_spin_unlock_irqrestore(&l2x0_lock, flags);
-			raw_spin_lock_irqsave(&l2x0_lock, flags);
-		}
-	}
-	cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
-	cache_sync();
-	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
-}
-
-static void l2x0_flush_range(unsigned long start, unsigned long end)
-{
-	void __iomem *base = l2x0_base;
-	unsigned long flags;
-
-	if ((end - start) >= l2x0_size) {
-		l2x0_flush_all();
-		return;
-	}
-
-	raw_spin_lock_irqsave(&l2x0_lock, flags);
-	start &= ~(CACHE_LINE_SIZE - 1);
-	while (start < end) {
-		unsigned long blk_end = start + min(end - start, 4096UL);
-
-		debug_writel(0x03);
-		while (start < blk_end) {
-			l2x0_flush_line(start);
-			start += CACHE_LINE_SIZE;
-		}
-		debug_writel(0x00);
-
-		if (blk_end < end) {
-			raw_spin_unlock_irqrestore(&l2x0_lock, flags);
-			raw_spin_lock_irqsave(&l2x0_lock, flags);
-		}
-	}
-	cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
-	cache_sync();
-	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
-}
-
 static void l2x0_disable(void)
 {
 	unsigned long flags;
@@ -345,49 +185,6 @@ static void l2x0_disable(void)
 	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
-static void l2x0_enable(void __iomem *base, u32 aux, unsigned num_lock)
-{
-	unsigned id;
-
-	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;
-
-	/* l2x0 controller is disabled */
-	writel_relaxed(aux, base + L2X0_AUX_CTRL);
-
-	/* Make sure that I&D is not locked down when starting */
-	l2c_unlock(base, num_lock);
-
-	l2x0_inv_all();
-
-	/* enable L2X0 */
-	writel_relaxed(L2X0_CTRL_EN, base + L2X0_CTRL);
-}
-
-static void l2x0_resume(void)
-{
-	void __iomem *base = l2x0_base;
-
-	if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN))
-		l2x0_enable(base, l2x0_saved_regs.aux_ctrl, 0);
-}
-
-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.
  *
@@ -966,9 +763,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;
Signature · 1 line
1.8.3.1
#46 lore raw

PATCH 37/75 ARM: l2c: move type string into l2c_init_data structure

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)
arch/arm/mm/cache-l2x0.c +13 -7
index fc7ce31d9b52..75680809815f 100644
@@ -29,6 +29,7 @@
 #include "cache-aurora-l2.h"
 
 struct l2c_init_data {
+	const char *type;
 	unsigned num_lock;
 	void (*of_parse)(const struct device_node *, u32 *, u32 *);
 	void (*enable)(void __iomem *, u32, unsigned);
@@ -274,6 +275,7 @@ static void l2c210_resume(void)
 }
 
 static const struct l2c_init_data l2c210_data __initconst = {
+	.type = "L2C-210",
 	.num_lock = 1,
 	.enable = l2c_enable,
 	.outer_cache = {
@@ -416,6 +418,7 @@ static void l2c220_sync(void)
 }
 
 static const struct l2c_init_data l2c220_data = {
+	.type = "L2C-220",
 	.num_lock = 1,
 	.enable = l2c_enable,
 	.outer_cache = {
@@ -650,6 +653,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",
 	.num_lock = 8,
 	.enable = l2c_enable,
 	.fixup = l2c310_fixup,
@@ -674,7 +678,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,
@@ -695,25 +698,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;
 	}
 
@@ -747,9 +746,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)
@@ -821,6 +820,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",
 	.num_lock = 1,
 	.of_parse = l2x0_of_parse,
 	.enable = l2c_enable,
@@ -836,6 +836,7 @@ static const struct l2c_init_data of_l2c210_data __initconst = {
 };
 
 static const struct l2c_init_data of_l2c220_data __initconst = {
+	.type = "L2C-220",
 	.num_lock = 1,
 	.of_parse = l2x0_of_parse,
 	.enable = l2c_enable,
@@ -885,6 +886,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",
 	.num_lock = 8,
 	.of_parse = l2c310_of_parse,
 	.enable = l2c_enable,
@@ -1063,6 +1065,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",
 	.num_lock = 4,
 	.of_parse = aurora_of_parse,
 	.enable = l2c_enable,
@@ -1080,6 +1083,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",
 	.num_lock = 4,
 	.of_parse = aurora_of_parse,
 	.enable = aurora_enable_no_outer,
@@ -1228,6 +1232,7 @@ static void bcm_flush_range(unsigned long start, unsigned long end)
 
 /* Broadcom L2C-310 start from ARMs R3P2 or later, and require no fixups */
 static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
+	.type = "BCM-L2C-310",
 	.num_lock = 8,
 	.of_parse = l2c310_of_parse,
 	.enable = l2c_enable,
@@ -1266,6 +1271,7 @@ static void tauros3_resume(void)
 }
 
 static const struct l2c_init_data of_tauros3_data __initconst = {
+	.type = "Tauros3",
 	.num_lock = 8,
 	.enable = l2c_enable,
 	.save  = tauros3_save,
Signature · 1 line
1.8.3.1
#47 lore raw

PATCH 38/75 ARM: l2c: add decode for L2C-220 cache ways

In reply to Russell King - ARM Linux

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

---
 arch/arm/mm/cache-l2x0.c | 1 +
 1 file changed, 1 insertion(+)
arch/arm/mm/cache-l2x0.c +1 -0
index 75680809815f..f495d7c37fb9 100644
@@ -701,6 +701,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;
 
Signature · 1 line
1.8.3.1
#48 lore raw

PATCH 39/75 ARM: l2c: move way size calculation data into l2c_init_data

In reply to Russell King - ARM Linux

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

---
 arch/arm/mm/cache-l2x0.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)
arch/arm/mm/cache-l2x0.c +20 -9
index f495d7c37fb9..6b304db6f1c2 100644
@@ -30,6 +30,7 @@
 
 struct l2c_init_data {
 	const char *type;
+	unsigned way_size_0;
 	unsigned num_lock;
 	void (*of_parse)(const struct device_node *, u32 *, u32 *);
 	void (*enable)(void __iomem *, u32, unsigned);
@@ -276,6 +277,7 @@ static void l2c210_resume(void)
 
 static const struct l2c_init_data l2c210_data __initconst = {
 	.type = "L2C-210",
+	.way_size_0 = SZ_8K,
 	.num_lock = 1,
 	.enable = l2c_enable,
 	.outer_cache = {
@@ -419,6 +421,7 @@ static void l2c220_sync(void)
 
 static const struct l2c_init_data l2c220_data = {
 	.type = "L2C-220",
+	.way_size_0 = SZ_8K,
 	.num_lock = 1,
 	.enable = l2c_enable,
 	.outer_cache = {
@@ -654,6 +657,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,
 	.num_lock = 8,
 	.enable = l2c_enable,
 	.fixup = l2c310_fixup,
@@ -674,10 +678,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,
@@ -708,7 +710,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:
@@ -720,12 +721,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)
@@ -822,6 +826,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,
 	.num_lock = 1,
 	.of_parse = l2x0_of_parse,
 	.enable = l2c_enable,
@@ -838,6 +843,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,
 	.num_lock = 1,
 	.of_parse = l2x0_of_parse,
 	.enable = l2c_enable,
@@ -888,6 +894,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,
 	.num_lock = 8,
 	.of_parse = l2c310_of_parse,
 	.enable = l2c_enable,
@@ -1067,6 +1074,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,
 	.num_lock = 4,
 	.of_parse = aurora_of_parse,
 	.enable = l2c_enable,
@@ -1085,6 +1093,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,
 	.num_lock = 4,
 	.of_parse = aurora_of_parse,
 	.enable = aurora_enable_no_outer,
@@ -1234,6 +1243,7 @@ static void bcm_flush_range(unsigned long start, unsigned long end)
 /* Broadcom L2C-310 start from ARMs R3P2 or later, and require no fixups */
 static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
 	.type = "BCM-L2C-310",
+	.way_size_0 = SZ_8K,
 	.num_lock = 8,
 	.of_parse = l2c310_of_parse,
 	.enable = l2c_enable,
@@ -1273,6 +1283,7 @@ static void tauros3_resume(void)
 
 static const struct l2c_init_data of_tauros3_data __initconst = {
 	.type = "Tauros3",
+	.way_size_0 = SZ_8K,
 	.num_lock = 8,
 	.enable = l2c_enable,
 	.save  = tauros3_save,
Signature · 1 line
1.8.3.1
#49 lore raw

PATCH 40/75 ARM: l2c: move errata configuration options to arch/arm/mm/Kconfig

In reply to Russell King - ARM Linux

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

---
 arch/arm/Kconfig    | 51 ---------------------------------------------------
 arch/arm/mm/Kconfig | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 51 deletions(-)
arch/arm/Kconfig +0 -51
index 15949459611f..beacf698cdff 100644
@@ -1215,19 +1215,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
@@ -1250,17 +1237,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
@@ -1286,21 +1262,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
@@ -1349,18 +1310,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
arch/arm/mm/Kconfig +51 -0

57 lines not on this page · raw message

Signature · 1 line
1.8.3.1
#50 lore raw

PATCH 41/75 ARM: l2c: provide generic hook to intercept writes to secure registers

In reply to Russell King - ARM Linux

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.

l2c_write_sec() avoids writes to secure registers which are already set to the appropriate value, thus avoiding the overhead of needlessly calling into the secure monitor.

---
 arch/arm/include/asm/outercache.h |  5 ++++-
 arch/arm/mm/cache-l2x0.c          | 40 +++++++++++++++++++++++++++++----------
 2 files changed, 34 insertions(+), 11 deletions(-)
arch/arm/include/asm/outercache.h +4 -1
index 1ee2cf23fae1..69f57a5c0dd3 100644
@@ -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;
arch/arm/mm/cache-l2x0.c +30 -10
index 6b304db6f1c2..72a5f636b322 100644
@@ -60,13 +60,30 @@ 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 (val == readl_relaxed(base + reg))
+		return;
+	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)
@@ -97,7 +114,7 @@ static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
 
 	/* Only write the aux register if it needs changing */
 	if (readl_relaxed(base + L2X0_AUX_CTRL) != aux)
-		writel_relaxed(aux, base + L2X0_AUX_CTRL);
+		l2c_write_sec(aux, base, L2X0_AUX_CTRL);
 
 	l2c_unlock(base, num_lock);
 
@@ -107,7 +124,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);
 }
 
 static void l2c_disable(void)
@@ -115,7 +132,7 @@ static void l2c_disable(void)
 	void __iomem *base = l2x0_base;
 
 	outer_cache.flush_all();
-	writel_relaxed(0, base + L2X0_CTRL);
+	l2c_write_sec(0, base, L2X0_CTRL);
 	dsb(st);
 }
 
@@ -139,7 +156,7 @@ static inline void cache_sync(void)
 #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
@@ -182,7 +199,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);
 }
@@ -599,11 +616,11 @@ static void l2c310_resume(void)
 				L2X0_CACHE_ID_RTL_MASK;
 
 		if (revision >= L310_CACHE_ID_RTL_R2P0)
-			writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
-				       base + L2X0_PREFETCH_CTRL);
+			l2c_write_sec(l2x0_saved_regs.prefetch_ctrl, base,
+				      L2X0_PREFETCH_CTRL);
 		if (revision >= L310_CACHE_ID_RTL_R3P0)
-			writel_relaxed(l2x0_saved_regs.pwr_ctrl,
-				       base + L2X0_POWER_CTRL);
+			l2c_write_sec(l2x0_saved_regs.pwr_ctrl, base,
+				      L2X0_POWER_CTRL);
 
 		l2c_enable(base, l2x0_saved_regs.aux_ctrl, 8);
 	}
@@ -732,8 +749,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
Signature · 1 line
1.8.3.1
#51 lore raw

PATCH 41/75 ARM: l2c: provide generic hook to intercept writes to secure registers

Quoted 18 lines · Russell King
arch/arm/mm/cache-l2x0.c +14 -0
@@ -60,13 +60,30 @@ 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 (val == readl_relaxed(base + reg))
+		return;
+	if (outer_cache.write_sec)
+		outer_cache.write_sec(val, reg);
+	else
+		writel_relaxed(val, base + reg);
+}
+
+/*

[..]

arch/arm/mm/cache-l2x0.c static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock) · line 116

Quoted 4 lines
arch/arm/mm/cache-l2x0.c +0 -0
@@ -97,7 +114,7 @@ static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
 
 	/* Only write the aux register if it needs changing */
 	if (readl_relaxed(base + L2X0_AUX_CTRL) != aux)

It looks like this conditional can be dropped, since l2c_write_sec is just going to perform the same check.

Quoted 3 lines
arch/arm/mm/cache-l2x0.c +1 -1
-		writel_relaxed(aux, base + L2X0_AUX_CTRL);
+		l2c_write_sec(aux, base, L2X0_AUX_CTRL);
 
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
#52 lore raw

PATCH 41/75 ARM: l2c: provide generic hook to intercept writes to secure registers

Quoted 20 lines · Josh Cartwright
Quoted 18 lines · Russell King
arch/arm/mm/cache-l2x0.c +14 -0
@@ -60,13 +60,30 @@ 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 (val == readl_relaxed(base + reg))
+		return;
+	if (outer_cache.write_sec)
+		outer_cache.write_sec(val, reg);
+	else
+		writel_relaxed(val, base + reg);
+}
+
+/*

[..]

Quoted 7 lines

arch/arm/mm/cache-l2x0.c static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock) · line 116

Quoted 4 lines
arch/arm/mm/cache-l2x0.c +0 -0
@@ -97,7 +114,7 @@ static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
 
 	/* Only write the aux register if it needs changing */
 	if (readl_relaxed(base + L2X0_AUX_CTRL) != aux)

It looks like this conditional can be dropped, since l2c_write_sec is just going to perform the same check.

Yea, I changed l2c_write_sec() today because wanted to add it to a couple of other places and didn't check the existing users. Good catch. Thanks.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#53 lore raw

PATCH 42/75 ARM: l2c: omap2: implement new write_sec method

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mach-omap2/omap4-common.c | 42 +++++++++++++++++++++++---------------
 1 file changed, 26 insertions(+), 16 deletions(-)
arch/arm/mach-omap2/omap4-common.c +26 -16
index 9f8d506f511d..7abc1eb15bf9 100644
@@ -166,17 +166,33 @@ 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 = OMAP4_MON_L2X0_CTRL_INDEX;
+		break;
+
+	case L2X0_AUX_CTRL:
+		smc_op = OMAP4_MON_L2X0_AUXCTRL_INDEX;
+		break;
+
+	case L2X0_DEBUG_CTRL:
+		smc_op = OMAP4_MON_L2X0_DBG_CTRL_INDEX;
+		break;
+
+	case L310_PREFETCH_CTRL:
+		smc_op = OMAP4_MON_L2X0_PREFETCH_INDEX;
+		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)
@@ -211,18 +227,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);
Signature · 1 line
1.8.3.1
#55 lore raw

PATCH 43/75 ARM: l2c: omap2: remove explicit SMI calls to enable L2 cache

In reply to Russell King - ARM Linux

Now that OMAP2 uses the write_sec method, we don't need to enable the L2 cache in OMAP2 specific code; this can be done via the normal mechanisms in the L2C code. Remove the OMAP2 specific code.

---
 arch/arm/mach-omap2/omap4-common.c | 5 -----
 1 file changed, 5 deletions(-)
arch/arm/mach-omap2/omap4-common.c +0 -5
index 7abc1eb15bf9..343c354ae6f5 100644
@@ -222,11 +222,6 @@ static int __init omap_l2_cache_init(void)
 			(1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
 			(1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT);
 
-	omap_smc1(0x109, aux_ctrl);
-
-	/* 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);
Signature · 1 line
1.8.3.1
maintainer
#56 lore raw

PATCH 43/75 ARM: l2c: omap2: remove explicit SMI calls to enable L2 cache

Quoted 5 lines · Russell King

Now that OMAP2 uses the write_sec method, we don't need to enable the L2 cache in OMAP2 specific code; this can be done via the normal mechanisms in the L2C code. Remove the OMAP2 specific code.

Quoted 26 lines
 arch/arm/mach-omap2/omap4-common.c | 5 -----
 1 file changed, 5 deletions(-)
arch/arm/mach-omap2/omap4-common.c +0 -5
index 7abc1eb15bf9..343c354ae6f5 100644
@@ -222,11 +222,6 @@ static int __init omap_l2_cache_init(void)
 			(1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
 			(1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT);
 
-	omap_smc1(0x109, aux_ctrl);
-
-	/* 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);
Signature · 6 lines
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#57 lore raw

PATCH 44/75 ARM: l2c: highbank: implement new write_sec method

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mach-highbank/highbank.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)
arch/arm/mach-highbank/highbank.c +7 -5
index 38e1dc3b4c6e..4712aed3d9f6 100644
@@ -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_l2c310_write_sec;
 		l2x0_of_init(0, ~0);
-		outer_cache.disable = highbank_l2x0_disable;
 	}
 }
 
Signature · 1 line
1.8.3.1
#58 lore raw

PATCH 45/75 ARM: l2c: highbank: remove explicit SMI call in L2 cache initialisation

In reply to Russell King - ARM Linux

Now that highbank uses the write_sec method, we don't need to enable the L2 cache in SoC specific code; this can be done via the normal mechanisms in the L2C code.

Checking with Rob Herring:

Quoted 7 lines
Quoted 3 lines

Can we kill the "highbank_smc1(0x102, 0x1);" here? That means
l2x0_of_init() will see the L2 cache disabled, and will try to enable it via the write_sec hook, so it should do the right thing.

Yes, that should work. You should be able to just call l2x0_of_init unconditionally. The condition was really to just avoid the smc on Midway which does get handled on h/w, but not if running virtualized.

So also drop the DT check too. I'm leaving the config check in place so that if L2 is disabled, the write_sec hook can be optimised away.

---
 arch/arm/mach-highbank/highbank.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
arch/arm/mach-highbank/highbank.c +1 -3
index 4712aed3d9f6..245e588859ec 100644
@@ -68,9 +68,7 @@ static void __init highbank_init_irq(void)
 		highbank_scu_map_io();
 
 	/* Enable PL310 L2 Cache controller */
-	if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
-	    of_find_compatible_node(NULL, NULL, "arm,pl310-cache")) {
-		highbank_smc1(0x102, 0x1);
+	if (IS_ENABLED(CONFIG_CACHE_L2X0)) {
 		outer_cache.write_sec = highbank_l2c310_write_sec;
 		l2x0_of_init(0, ~0);
 	}
Signature · 1 line
1.8.3.1
#59 lore raw

PATCH 46/75 ARM: l2c: ux500: implement dummy write_sec method

In reply to Russell King - ARM Linux

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

---
 arch/arm/mach-ux500/cache-l2x0.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)
arch/arm/mach-ux500/cache-l2x0.c +10 -9
index 264f894c0e3d..5cc7e3625d8c 100644
@@ -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;
 }
 
Signature · 1 line
1.8.3.1
#61 lore raw

PATCH 47/75 ARM: l2c: remove old .set_debug method

In reply to Russell King - ARM Linux

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

---
 arch/arm/include/asm/outercache.h |  1 -
 arch/arm/mm/cache-l2x0.c          | 21 ++-------------------
 2 files changed, 2 insertions(+), 20 deletions(-)
arch/arm/include/asm/outercache.h +0 -1
index 69f57a5c0dd3..2e0de485a210 100644
@@ -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);
 };
 
arch/arm/mm/cache-l2x0.c +2 -19
index 72a5f636b322..96f57fd1a4e7 100644
@@ -80,10 +80,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 cache_sync(void)
 #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 */
@@ -491,11 +487,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;
@@ -633,10 +624,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 */
@@ -686,7 +673,6 @@ static const struct l2c_init_data l2c310_init_fns __initconst = {
 		.flush_all = l2c210_flush_all,
 		.disable = l2c_disable,
 		.sync = l2c210_sync,
-		.set_debug = l2c310_set_debug,
 		.resume = l2c310_resume,
 	},
 };
@@ -752,8 +738,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
@@ -927,7 +911,6 @@ static const struct l2c_init_data of_l2c310_data __initconst = {
 		.flush_all   = l2c210_flush_all,
 		.disable     = l2c_disable,
 		.sync        = l2c210_sync,
-		.set_debug   = l2c310_set_debug,
 		.resume      = l2c310_resume,
 	},
 };
Signature · 1 line
1.8.3.1
#62 lore raw

PATCH 48/75 ARM: l2c: implement L2C-310 erratum 752271 in core L2C code

In reply to Russell King - ARM Linux

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.

---
 arch/arm/mm/cache-l2x0.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)
arch/arm/mm/cache-l2x0.c +17 -1
index 96f57fd1a4e7..54ad15ea24eb 100644
@@ -478,6 +478,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
@@ -621,7 +626,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) &&
@@ -640,6 +645,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;
Signature · 1 line
1.8.3.1
#63 lore raw

PATCH 49/75 ARM: l2c: fix register naming

In reply to Russell King - ARM Linux

We have a mixture of different devices 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. Provide full auxiliary control register definitions.

---
 arch/arm/include/asm/hardware/cache-l2x0.h | 73 ++++++++++++++++++++----------
 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         | 18 ++++----
 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, 118 insertions(+), 95 deletions(-)
arch/arm/include/asm/hardware/cache-l2x0.h +48 -25
index 94fbcec216ae..e52584539743 100644
@@ -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)
@@ -88,29 +88,52 @@
 #define L310_CACHE_ID_RTL_R3P3		0x09
 
 #define L2X0_AUX_CTRL_MASK			0xc0000fff
+/* L2C auxiliary control register - bits common to L2C-210/220/310 */
+#define L2C_AUX_CTRL_WAY_SIZE_SHIFT		17
+#define L2C_AUX_CTRL_WAY_SIZE_MASK		(7 << 17)
+#define L2C_AUX_CTRL_WAY_SIZE(n)		((n) << 17)
+#define L2C_AUX_CTRL_EVTMON_ENABLE		BIT(20)
+#define L2C_AUX_CTRL_PARITY_ENABLE		BIT(21)
+#define L2C_AUX_CTRL_SHARED_OVERRIDE		BIT(22)
+/* L2C-210/220 common bits */
 #define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT	0
-#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK	0x7
+#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK	(7 << 0)
 #define L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT	3
-#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK	(0x7 << 3)
+#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK	(7 << 3)
 #define L2X0_AUX_CTRL_TAG_LATENCY_SHIFT		6
-#define L2X0_AUX_CTRL_TAG_LATENCY_MASK		(0x7 << 6)
+#define L2X0_AUX_CTRL_TAG_LATENCY_MASK		(7 << 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_AUX_CTRL_DIRTY_LATENCY_MASK	(7 << 9)
+#define L2X0_AUX_CTRL_ASSOC_SHIFT		13
+#define L2X0_AUX_CTRL_ASSOC_MASK		(15 << 13)
+/* L2C-210 specific bits */
+#define L210_AUX_CTRL_WRAP_DISABLE		BIT(12)
+#define L210_AUX_CTRL_WA_OVERRIDE		BIT(23)
+#define L210_AUX_CTRL_EXCLUSIVE_ABORT		BIT(24)
+/* L2C-220 specific bits */
+#define L220_AUX_CTRL_EXCLUSIVE_CACHE		BIT(12)
+#define L220_AUX_CTRL_FWA_SHIFT			23
+#define L220_AUX_CTRL_FWA_MASK			(3 << 23)
+#define L220_AUX_CTRL_NS_LOCKDOWN		BIT(26)
+#define L220_AUX_CTRL_NS_INT_CTRL		BIT(27)
+/* L2C-310 specific bits */
+#define L310_AUX_CTRL_FULL_LINE_ZERO		BIT(0)	/* R2P0+ */
+#define L310_AUX_CTRL_HIGHPRIO_SO_DEV		BIT(10)	/* R2P0+ */
+#define L310_AUX_CTRL_STORE_LIMITATION		BIT(11)	/* R2P0+ */
+#define L310_AUX_CTRL_EXCLUSIVE_CACHE		BIT(12)
+#define L310_AUX_CTRL_ASSOCIATIVITY_16		BIT(16)
+#define L310_AUX_CTRL_CACHE_REPLACE_RR		BIT(25)	/* R2P0+ */
+#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)	/* R2P0+ */
 
-#define L2X0_LATENCY_CTRL_SETUP_SHIFT	0
-#define L2X0_LATENCY_CTRL_RD_SHIFT	4
-#define L2X0_LATENCY_CTRL_WR_SHIFT	8
+#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 L2X0_ADDR_FILTER_EN		1
+#define L310_ADDR_FILTER_EN		1
 
 #define L2X0_CTRL_EN			1
 
arch/arm/mach-cns3xxx/core.c +4 -4
index e38b279f402c..dd2b9926a76c 100644
@@ -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);
arch/arm/mach-imx/system.c +4 -4
index c6571f1de9fd..59013a81107b 100644
@@ -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);
arch/arm/mach-omap2/omap-mpuss-lowpower.c +1 -1
index 667915d236f3..ba43f49fbb59 100644
@@ -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);
 	}
 }
arch/arm/mach-omap2/omap4-common.c +9 -9
index 343c354ae6f5..84e097f5fdf4 100644
@@ -212,15 +212,15 @@ static int __init omap_l2_cache_init(void)
 		return -ENOMEM;
 
 	/* 16-way associativity, parity disabled, 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)) |
-			(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_ASSOCIATIVITY_16 |
+		   L310_AUX_CTRL_CACHE_REPLACE_RR |
+		   L310_AUX_CTRL_NS_LOCKDOWN |
+		   L310_AUX_CTRL_NS_INT_CTRL |
+		   L2C_AUX_CTRL_WAY_SIZE(3) |
+		   L2C_AUX_CTRL_SHARED_OVERRIDE |
+		   L310_AUX_CTRL_DATA_PREFETCH |
+		   L310_AUX_CTRL_INSTR_PREFETCH |
+		   L310_AUX_CTRL_EARLY_BRESP;
 
 	outer_cache.write_sec = omap4_l2c310_write_sec;
 	if (of_have_populated_dt())
arch/arm/mach-prima2/l2x0.c +2 -3
index cbcbe9cb094c..3a4eda45171e 100644
@@ -18,13 +18,12 @@ struct l2x0_aux
 };
 
 static struct l2x0_aux prima2_l2x0_aux __initconst = {
-	.val = 2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT,
+	.val = L2C_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 = L2C_AUX_CTRL_WAY_SIZE(2) | L310_AUX_CTRL_ASSOCIATIVITY_16,
 	.mask = L2X0_AUX_CTRL_MASK,
 };
 
arch/arm/mach-realview/realview_pbx.c +2 -2
index 9d75493e3f0c..f0cfd7e7e569 100644
@@ -370,8 +370,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 .... .... .... */
arch/arm/mach-spear/spear13xx.c +3 -3
index 7aa6e8cf830f..92860fa01668 100644
@@ -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);
 }
 
arch/arm/mach-sti/board-dt.c +4 -4
index 1217fb598cfd..dc8669efc12d 100644
@@ -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 = L2C_AUX_CTRL_SHARED_OVERRIDE |
+		   L310_AUX_CTRL_DATA_PREFETCH |
+		   L310_AUX_CTRL_INSTR_PREFETCH |
+		   L2C_AUX_CTRL_WAY_SIZE(way_size);
 
 	l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
 }
arch/arm/mach-tegra/sleep.h +4 -4
index a4edbb3abd3d..a032820d2fac 100644
@@ -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
arch/arm/mach-ux500/cache-l2x0.c +2 -2
index 5cc7e3625d8c..067c37a054fb 100644
@@ -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 |= L2C_AUX_CTRL_WAY_SIZE(4);
 	else
 		/* 64KB way size */
-		aux_val |= (0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
+		aux_val |= L2C_AUX_CTRL_WAY_SIZE(3);
 
 	outer_cache.write_sec = ux500_l2c310_write_sec;
 
arch/arm/mach-vexpress/ct-ca9x4.c +2 -2
index 6f34497a4245..6c4ffb6c5ad8 100644
@@ -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
arch/arm/mm/cache-l2x0.c +29 -28

136 lines not on this page · raw message

arch/arm/plat-samsung/s5p-sleep.S +4 -4
index a030e7301da8..497301944090 100644
@@ -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:
Signature · 1 line
1.8.3.1
maintainer
#64 lore raw

PATCH 49/75 ARM: l2c: fix register naming

Quoted 6 lines · Russell King

We have a mixture of different devices 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. Provide full auxiliary control register definitions.

Quoted 14 lines
arch/arm/mach-omap2/omap4-common.c +0 -8
@@ -212,15 +212,15 @@ static int __init omap_l2_cache_init(void)
 		return -ENOMEM;
 
 	/* 16-way associativity, parity disabled, 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)) |
-			(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) |

arch/arm/mach-omap2/omap4-common.c static int __init omap_l2_cache_init(void) · line 223

Quoted 10 lines
arch/arm/mach-omap2/omap4-common.c +9 -1
-			(1 << L2X0_AUX_CTRL_EARLY_BRESP_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 |
+		   L2C_AUX_CTRL_WAY_SIZE(3) |
+		   L2C_AUX_CTRL_SHARED_OVERRIDE |
+		   L310_AUX_CTRL_DATA_PREFETCH |
+		   L310_AUX_CTRL_INSTR_PREFETCH |
+		   L310_AUX_CTRL_EARLY_BRESP;

I guess eventually we can set up some common configuration mask define for these kind of things?

Regards,

Tony

#65 lore raw

PATCH 49/75 ARM: l2c: fix register naming

Quoted 29 lines · Tony Lindgren
Quoted 6 lines · Russell King

We have a mixture of different devices 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. Provide full auxiliary control register definitions.

Quoted 19 lines
arch/arm/mach-omap2/omap4-common.c +4 -9
@@ -212,15 +212,15 @@ static int __init omap_l2_cache_init(void)
 		return -ENOMEM;
 
 	/* 16-way associativity, parity disabled, 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)) |
-			(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_ASSOCIATIVITY_16 |
+		   L310_AUX_CTRL_CACHE_REPLACE_RR |
+		   L310_AUX_CTRL_NS_LOCKDOWN |
+		   L310_AUX_CTRL_NS_INT_CTRL |
Quoted 8 lines

arch/arm/mach-omap2/omap4-common.c static int __init omap_l2_cache_init(void) · line 223

Quoted 5 lines
arch/arm/mach-omap2/omap4-common.c +5 -0
+		   L2C_AUX_CTRL_WAY_SIZE(3) |
+		   L2C_AUX_CTRL_SHARED_OVERRIDE |
+		   L310_AUX_CTRL_DATA_PREFETCH |
+		   L310_AUX_CTRL_INSTR_PREFETCH |
+		   L310_AUX_CTRL_EARLY_BRESP;

I guess eventually we can set up some common configuration mask define for these kind of things?

The idea is that eventually platforms should just specify no changes to the auxctl configuration. You will notice later patches remove a number of the above flags.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
maintainer
#66 lore raw

PATCH 49/75 ARM: l2c: fix register naming

Quoted 39 lines · Russell King - ARM Linux
Quoted 29 lines · Tony Lindgren
Quoted 6 lines · Russell King

We have a mixture of different devices 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. Provide full auxiliary control register definitions.

Quoted 19 lines
arch/arm/mach-omap2/omap4-common.c +4 -9
@@ -212,15 +212,15 @@ static int __init omap_l2_cache_init(void)
 		return -ENOMEM;
 
 	/* 16-way associativity, parity disabled, 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)) |
-			(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_ASSOCIATIVITY_16 |
+		   L310_AUX_CTRL_CACHE_REPLACE_RR |
+		   L310_AUX_CTRL_NS_LOCKDOWN |
+		   L310_AUX_CTRL_NS_INT_CTRL |
Quoted 8 lines

arch/arm/mach-omap2/omap4-common.c static int __init omap_l2_cache_init(void) · line 223

Quoted 5 lines
arch/arm/mach-omap2/omap4-common.c +5 -0
+		   L2C_AUX_CTRL_WAY_SIZE(3) |
+		   L2C_AUX_CTRL_SHARED_OVERRIDE |
+		   L310_AUX_CTRL_DATA_PREFETCH |
+		   L310_AUX_CTRL_INSTR_PREFETCH |
+		   L310_AUX_CTRL_EARLY_BRESP;

I guess eventually we can set up some common configuration mask define for these kind of things?

Quoted 3 lines

The idea is that eventually platforms should just specify no changes to the auxctl configuration. You will notice later patches remove a number of the above flags.

OK thanks great!

Tony

maintainer
#67 lore raw

PATCH 49/75 ARM: l2c: fix register naming

In reply to Russell King
Quoted 6 lines · Russell King

We have a mixture of different devices 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. Provide full auxiliary control register definitions.

#68 lore raw

PATCH 49/75 ARM: l2c: fix register naming

In reply to Russell King

Thanks Russel,

Quoted 6 lines · Russell King

We have a mixture of different devices 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. Provide full auxiliary control register definitions.

Quoted 17 lines
---
  arch/arm/include/asm/hardware/cache-l2x0.h | 73 ++++++++++++++++++++----------
  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         | 18 ++++----
  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, 118 insertions(+), 95 deletions(-)

For the mach-sti part:

Thanks,
Maxime

#69 lore raw

PATCH 49/75 ARM: l2c: fix register naming

In reply to Russell King
Quoted 6 lines · Russell King

We have a mixture of different devices 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. Provide full auxiliary control register definitions.

For ux500.

Yours,
Linus Walleij

#70 lore raw

PATCH 50/75 ARM: l2c: add automatic enable of early BRESP

In reply to Russell King - ARM Linux

The AXI bus protocol requires that a write response should only be sent back to the master when the last write has been accepted. Early BRESP allows the L2C-310 to send the write response as soon as the store buffer accepts the write address.

Cortex-A9 processors can signal to the L2C-310 that they wish to be notified early, and if this optimisation is enabled, the L2C-310 can signal an early write response.

---
 arch/arm/mm/cache-l2x0.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)
arch/arm/mm/cache-l2x0.c +22 -3
index cfea0f2aecd6..8af157031056 100644
@@ -24,6 +24,7 @@
 #include <linux/of_address.h>
 
 #include <asm/cacheflush.h>
+#include <asm/cputype.h>
 #include <asm/hardware/cache-l2x0.h>
 #include "cache-tauros3.h"
 #include "cache-aurora-l2.h"
@@ -622,6 +623,24 @@ static void l2c310_resume(void)
 	}
 }
 
+static void __init l2c310_enable(void __iomem *base, u32 aux, unsigned num_lock)
+{
+	unsigned rev = readl_relaxed(base + L2X0_CACHE_ID) & L2X0_CACHE_ID_PART_MASK;
+	bool cortex_a9 = read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9;
+
+	if (rev >= L310_CACHE_ID_RTL_R2P0) {
+		if (cortex_a9) {
+			aux |= L310_AUX_CTRL_EARLY_BRESP;
+			pr_info("L2C-310 enabling early BRESP for Cortex-A9\n");
+		} else if (aux & L310_AUX_CTRL_EARLY_BRESP) {
+			pr_warn("L2C-310 early BRESP only supported with Cortex-A9\n");
+			aux &= ~L310_AUX_CTRL_EARLY_BRESP;
+		}
+	}
+
+	l2c_enable(base, aux, num_lock);
+}
+
 static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
 	struct outer_cache_fns *fns)
 {
@@ -679,7 +698,7 @@ static const struct l2c_init_data l2c310_init_fns __initconst = {
 	.type = "L2C-310",
 	.way_size_0 = SZ_8K,
 	.num_lock = 8,
-	.enable = l2c_enable,
+	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
 	.save = l2c310_save,
 	.outer_cache = {
@@ -918,7 +937,7 @@ static const struct l2c_init_data of_l2c310_data __initconst = {
 	.way_size_0 = SZ_8K,
 	.num_lock = 8,
 	.of_parse = l2c310_of_parse,
-	.enable = l2c_enable,
+	.enable = l2c310_enable,
 	.fixup = l2c310_fixup,
 	.save  = l2c310_save,
 	.outer_cache = {
@@ -1266,7 +1285,7 @@ static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
 	.way_size_0 = SZ_8K,
 	.num_lock = 8,
 	.of_parse = l2c310_of_parse,
-	.enable = l2c_enable,
+	.enable = l2c310_enable,
 	.save  = l2c310_save,
 	.outer_cache = {
 		.inv_range   = bcm_inv_range,
Signature · 1 line
1.8.3.1
#71 lore raw

PATCH 51/75 ARM: l2c: remove platforms/SoCs setting early BRESP

In reply to Russell King - ARM Linux

Since we now automatically enable early BRESP in core L2C-310 code when we detect a Cortex-A9, we don't need platforms/SoCs to set this bit explicitly. Instead, they should seek to preserve the value of bit 30 in the auxiliary control register.

---
 arch/arm/mach-berlin/berlin.c                            | 2 +-
 arch/arm/mach-exynos/common.c                            | 4 ++--
 arch/arm/mach-omap2/omap4-common.c                       | 3 +--
 arch/arm/mach-shmobile/board-armadillo800eva-reference.c | 4 ++--
 arch/arm/mach-shmobile/board-armadillo800eva.c           | 4 ++--
 arch/arm/mach-shmobile/board-kzm9g-reference.c           | 4 ++--
 arch/arm/mach-shmobile/board-kzm9g.c                     | 4 ++--
 arch/arm/mach-shmobile/setup-r8a7778.c                   | 4 ++--
 arch/arm/mach-shmobile/setup-r8a7779.c                   | 4 ++--
 arch/arm/mach-spear/spear13xx.c                          | 2 +-
 arch/arm/mach-tegra/tegra.c                              | 4 ++--
 11 files changed, 19 insertions(+), 20 deletions(-)
arch/arm/mach-berlin/berlin.c +1 -1
index 025bcb5473eb..6709d2a6bec8 100644
@@ -24,7 +24,7 @@ static void __init berlin_init_machine(void)
 	 * with DT probing for L2CCs, berlin_init_machine can be removed.
 	 * Note: 88DE3005 (Armada 1500-mini) uses pl310 l2cc
 	 */
-	l2x0_of_init(0x70c00000, 0xfeffffff);
+	l2x0_of_init(0x30c00000, 0xfeffffff);
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
arch/arm/mach-exynos/common.c +2 -2
index f18be40e5b21..cd53b72449a0 100644
@@ -45,8 +45,8 @@
 #include "common.h"
 #include "regs-pmu.h"
 
-#define L2_AUX_VAL 0x7C470001
-#define L2_AUX_MASK 0xC200ffff
+#define L2_AUX_VAL 0x3c470001
+#define L2_AUX_MASK 0xc200ffff
 
 static const char name_exynos4210[] = "EXYNOS4210";
 static const char name_exynos4212[] = "EXYNOS4212";
arch/arm/mach-omap2/omap4-common.c +1 -2
index 84e097f5fdf4..ce2fad84a43c 100644
@@ -219,8 +219,7 @@ static int __init omap_l2_cache_init(void)
 		   L2C_AUX_CTRL_WAY_SIZE(3) |
 		   L2C_AUX_CTRL_SHARED_OVERRIDE |
 		   L310_AUX_CTRL_DATA_PREFETCH |
-		   L310_AUX_CTRL_INSTR_PREFETCH |
-		   L310_AUX_CTRL_EARLY_BRESP;
+		   L310_AUX_CTRL_INSTR_PREFETCH;
 
 	outer_cache.write_sec = omap4_l2c310_write_sec;
 	if (of_have_populated_dt())
arch/arm/mach-shmobile/board-armadillo800eva-reference.c +2 -2
index 57d1a78367b6..34e7f3c17dd2 100644
@@ -164,8 +164,8 @@ static void __init eva_init(void)
 	r8a7740_meram_workaround();
 
 #ifdef CONFIG_CACHE_L2X0
-	/* Early BRESP enable, Shared attribute override enable, 32K*8way */
-	l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff);
+	/* Shared attribute override enable, 32K*8way */
+	l2x0_init(IOMEM(0xf0002000), 0x00440000, 0xc2000fff);
 #endif
 
 	r8a7740_add_standard_devices_dt();
arch/arm/mach-shmobile/board-armadillo800eva.c +2 -2
index 93533e2710a8..69ec71038ec7 100644
@@ -1270,8 +1270,8 @@ static void __init eva_init(void)
 
 
 #ifdef CONFIG_CACHE_L2X0
-	/* Early BRESP enable, Shared attribute override enable, 32K*8way */
-	l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff);
+	/* Shared attribute override enable, 32K*8way */
+	l2x0_init(IOMEM(0xf0002000), 0x00440000, 0xc2000fff);
 #endif
 
 	i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
arch/arm/mach-shmobile/board-kzm9g-reference.c +2 -2
index 598e32488410..85873f186d77 100644
@@ -36,8 +36,8 @@ static void __init kzm_init(void)
 	sh73a0_add_standard_devices_dt();
 
 #ifdef CONFIG_CACHE_L2X0
-	/* Early BRESP enable, Shared attribute override enable, 64K*8way */
-	l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff);
+	/* Shared attribute override enable, 64K*8way */
+	l2x0_init(IOMEM(0xf0100000), 0x00460000, 0xc2000fff);
 #endif
 }
 
arch/arm/mach-shmobile/board-kzm9g.c +2 -2
index bc40b853ffd3..bd9931f223ae 100644
@@ -878,8 +878,8 @@ static void __init kzm_init(void)
 	gpio_request_one(223, GPIOF_IN, NULL); /* IRQ8 */
 
 #ifdef CONFIG_CACHE_L2X0
-	/* Early BRESP enable, Shared attribute override enable, 64K*8way */
-	l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff);
+	/* Shared attribute override enable, 64K*8way */
+	l2x0_init(IOMEM(0xf0100000), 0x00460000, 0xc2000fff);
 #endif
 
 	i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
arch/arm/mach-shmobile/setup-r8a7778.c +2 -2
index 6d694526e4ca..3a8e5316671e 100644
@@ -298,10 +298,10 @@ void __init r8a7778_add_dt_devices(void)
 	void __iomem *base = ioremap_nocache(0xf0100000, 0x1000);
 	if (base) {
 		/*
-		 * Early BRESP enable, Shared attribute override enable, 64K*16way
+		 * Shared attribute override enable, 64K*16way
 		 * don't call iounmap(base)
 		 */
-		l2x0_init(base, 0x40470000, 0x82000fff);
+		l2x0_init(base, 0x00470000, 0xc2000fff);
 	}
 #endif
 
arch/arm/mach-shmobile/setup-r8a7779.c +2 -2
index 8e860b36997a..91c90bf0ae83 100644
@@ -700,8 +700,8 @@ static struct platform_device *r8a7779_standard_devices[] __initdata = {
 void __init r8a7779_add_standard_devices(void)
 {
 #ifdef CONFIG_CACHE_L2X0
-	/* Early BRESP enable, Shared attribute override enable, 64K*16way */
-	l2x0_init(IOMEM(0xf0100000), 0x40470000, 0x82000fff);
+	/* Shared attribute override enable, 64K*16way */
+	l2x0_init(IOMEM(0xf0100000), 0x00470000, 0xc2000fff);
 #endif
 	r8a7779_pm_init();
 
arch/arm/mach-spear/spear13xx.c +1 -1
index 92860fa01668..dcb300443b66 100644
@@ -46,7 +46,7 @@ void __init spear13xx_l2x0_init(void)
 	 */
 	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);
+	l2x0_init(VA_L2CC_BASE, 0x30a60001, 0xfe00ffff);
 }
 
 /*
arch/arm/mach-tegra/tegra.c +2 -2
index 6191603379e1..ecbb5411a104 100644
@@ -89,9 +89,9 @@ static void __init tegra_init_cache(void)
 
 	cache_type = readl(p + L2X0_CACHE_TYPE);
 	aux_ctrl = (cache_type & 0x700) << (17-8);
-	aux_ctrl |= 0x7C400001;
+	aux_ctrl |= 0x3c400001;
 
-	ret = l2x0_of_init(aux_ctrl, 0x8200c3fe);
+	ret = l2x0_of_init(aux_ctrl, 0xc200c3fe);
 	if (!ret)
 		l2x0_saved_regs_addr = virt_to_phys(&l2x0_saved_regs);
 #endif
Signature · 1 line
1.8.3.1
maintainer
#72 lore raw

PATCH 51/75 ARM: l2c: remove platforms/SoCs setting early BRESP

Quoted 6 lines · Russell King

Since we now automatically enable early BRESP in core L2C-310 code when we detect a Cortex-A9, we don't need platforms/SoCs to set this bit explicitly. Instead, they should seek to preserve the value of bit 30 in the auxiliary control register.

#73 lore raw

PATCH 52/75 ARM: l2c: tegra: remove associativity and way size from aux_ctrl

In reply to Russell King - ARM Linux
---
 arch/arm/mach-tegra/tegra.c | 18 +-----------------
 1 file changed, 1 insertion(+), 17 deletions(-)
arch/arm/mach-tegra/tegra.c +1 -17
index ecbb5411a104..fb802e24b647 100644
@@ -73,25 +73,9 @@ u32 tegra_uart_config[3] = {
 static void __init tegra_init_cache(void)
 {
 #ifdef CONFIG_CACHE_L2X0
-	static const struct of_device_id pl310_ids[] __initconst = {
-		{ .compatible = "arm,pl310-cache",  },
-		{}
-	};
-
-	struct device_node *np;
 	int ret;
-	void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
-	u32 aux_ctrl, cache_type;
-
-	np = of_find_matching_node(NULL, pl310_ids);
-	if (!np)
-		return;
-
-	cache_type = readl(p + L2X0_CACHE_TYPE);
-	aux_ctrl = (cache_type & 0x700) << (17-8);
-	aux_ctrl |= 0x3c400001;
 
-	ret = l2x0_of_init(aux_ctrl, 0xc200c3fe);
+	ret = l2x0_of_init(0x3c400001, 0xc20fc3fe);
 	if (!ret)
 		l2x0_saved_regs_addr = virt_to_phys(&l2x0_saved_regs);
 #endif
Signature · 1 line
1.8.3.1
#74 lore raw

PATCH 53/75 ARM: l2c: ux500: remove associativity and way size from aux_ctrl

In reply to Russell King - ARM Linux
---
 arch/arm/mach-ux500/cache-l2x0.c | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)
arch/arm/mach-ux500/cache-l2x0.c +2 -13
index 067c37a054fb..5b891d051054 100644
@@ -45,8 +45,6 @@ static void ux500_l2c310_write_sec(unsigned long val, unsigned reg)
 
 static int __init ux500_l2x0_init(void)
 {
-	u32 aux_val = 0x3e000000;
-
 	if (cpu_is_u8500_family() || cpu_is_ux540_family())
 		l2x0_base = __io_address(U8500_L2CC_BASE);
 	else
@@ -56,21 +54,12 @@ static int __init ux500_l2x0_init(void)
 	/* Unlock before init */
 	ux500_l2x0_unlock();
 
-	/* DBx540's L2 has 128KB way size */
-	if (cpu_is_ux540_family())
-		/* 128KB way size */
-		aux_val |= L2C_AUX_CTRL_WAY_SIZE(4);
-	else
-		/* 64KB way size */
-		aux_val |= L2C_AUX_CTRL_WAY_SIZE(3);
-
 	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);
+		l2x0_of_init(0x3e000000, 0xc00f0fff);
 	else
-		l2x0_init(l2x0_base, aux_val, 0xc0000fff);
+		l2x0_init(l2x0_base, 0x3e000000, 0xc00f0fff);
 
 	return 0;
 }
Signature · 1 line
1.8.3.1
#76 lore raw

PATCH 54/75 ARM: l2c: ux500: don't try to change the L2 cache auxiliary control register

In reply to Russell King - ARM Linux

ux500 can't change the auxiliary control register, so there's no point passing values to try and modify it to the l2x0 init functions.

---
 arch/arm/mach-ux500/cache-l2x0.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/mach-ux500/cache-l2x0.c +2 -2
index 5b891d051054..842ebedbdd1c 100644
@@ -57,9 +57,9 @@ static int __init ux500_l2x0_init(void)
 	outer_cache.write_sec = ux500_l2c310_write_sec;
 
 	if (of_have_populated_dt())
-		l2x0_of_init(0x3e000000, 0xc00f0fff);
+		l2x0_of_init(0, ~0);
 	else
-		l2x0_init(l2x0_base, 0x3e000000, 0xc00f0fff);
+		l2x0_init(l2x0_base, 0, ~0);
 
 	return 0;
 }
Signature · 1 line
1.8.3.1
#78 lore raw

PATCH 55/75 ARM: l2c: cns3xxx: remove cache size override

In reply to Russell King - ARM Linux
---
 arch/arm/mach-cns3xxx/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-cns3xxx/core.c +1 -1
index dd2b9926a76c..bce1d36d0ffb 100644
@@ -258,7 +258,7 @@ void __init cns3xxx_l2x0_init(void)
 	writel(val, base + L310_DATA_LATENCY_CTRL);
 
 	/* 32 KiB, 8-way, parity disable */
-	l2x0_init(base, 0x00540000, 0xfe000fff);
+	l2x0_init(base, 0x00500000, 0xfe0f0fff);
 }
 
 #endif /* CONFIG_CACHE_L2X0 */
Signature · 1 line
1.8.3.1
#79 lore raw

PATCH 56/75 ARM: l2c: exynos: remove cache size override

In reply to Russell King - ARM Linux
---
 arch/arm/mach-exynos/common.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
arch/arm/mach-exynos/common.c +1 -4
index cd53b72449a0..0d19a1b0444e 100644
@@ -45,9 +45,6 @@
 #include "common.h"
 #include "regs-pmu.h"
 
-#define L2_AUX_VAL 0x3c470001
-#define L2_AUX_MASK 0xc200ffff
-
 static const char name_exynos4210[] = "EXYNOS4210";
 static const char name_exynos4212[] = "EXYNOS4212";
 static const char name_exynos4412[] = "EXYNOS4412";
@@ -400,7 +397,7 @@ static int __init exynos4_l2x0_cache_init(void)
 {
 	int ret;
 
-	ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
+	ret = l2x0_of_init(0x3c400001, 0xc20fffff);
 	if (ret)
 		return ret;
 
Signature · 1 line
1.8.3.1
#80 lore raw

PATCH 57/75 ARM: l2c: nomadik: remove cache size override

In reply to Russell King - ARM Linux
---
 arch/arm/mach-nomadik/cpu-8815.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-nomadik/cpu-8815.c +1 -1
index 4a1065e41e9c..0f245bcc6b7e 100644
@@ -147,7 +147,7 @@ static void __init cpu8815_init_of(void)
 {
 #ifdef CONFIG_CACHE_L2X0
 	/* At full speed latency must be >=2, so 0x249 in low bits */
-	l2x0_of_init(0x00730249, 0xfe000fff);
+	l2x0_of_init(0x00700249, 0xfe0fefff);
 #endif
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
Signature · 1 line
1.8.3.1
#82 lore raw

PATCH 58/75 ARM: l2c: omap2: remove cache size override

In reply to Russell King - ARM Linux
---
 arch/arm/mach-omap2/omap4-common.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)
arch/arm/mach-omap2/omap4-common.c +3 -5
index ce2fad84a43c..c0f9a81a2d32 100644
@@ -212,20 +212,18 @@ static int __init omap_l2_cache_init(void)
 		return -ENOMEM;
 
 	/* 16-way associativity, parity disabled, way size - 64KB (es2.0 +) */
-	aux_ctrl = L310_AUX_CTRL_ASSOCIATIVITY_16 |
-		   L310_AUX_CTRL_CACHE_REPLACE_RR |
+	aux_ctrl = L310_AUX_CTRL_CACHE_REPLACE_RR |
 		   L310_AUX_CTRL_NS_LOCKDOWN |
 		   L310_AUX_CTRL_NS_INT_CTRL |
-		   L2C_AUX_CTRL_WAY_SIZE(3) |
 		   L2C_AUX_CTRL_SHARED_OVERRIDE |
 		   L310_AUX_CTRL_DATA_PREFETCH |
 		   L310_AUX_CTRL_INSTR_PREFETCH;
 
 	outer_cache.write_sec = omap4_l2c310_write_sec;
 	if (of_have_populated_dt())
-		l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
+		l2x0_of_init(aux_ctrl, 0xc19fffff);
 	else
-		l2x0_init(l2cache_base, aux_ctrl, L2X0_AUX_CTRL_MASK);
+		l2x0_init(l2cache_base, aux_ctrl, 0xc19fffff);
 
 	return 0;
 }
Signature · 1 line
1.8.3.1
maintainer
#83 lore raw

PATCH 58/75 ARM: l2c: omap2: remove cache size override

* Russell King <[email protected]> [140328 08:22]:

Missing description?

Quoted 36 lines
---
 arch/arm/mach-omap2/omap4-common.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)
arch/arm/mach-omap2/omap4-common.c +3 -5
index ce2fad84a43c..c0f9a81a2d32 100644
@@ -212,20 +212,18 @@ static int __init omap_l2_cache_init(void)
 		return -ENOMEM;
 
 	/* 16-way associativity, parity disabled, way size - 64KB (es2.0 +) */
-	aux_ctrl = L310_AUX_CTRL_ASSOCIATIVITY_16 |
-		   L310_AUX_CTRL_CACHE_REPLACE_RR |
+	aux_ctrl = L310_AUX_CTRL_CACHE_REPLACE_RR |
 		   L310_AUX_CTRL_NS_LOCKDOWN |
 		   L310_AUX_CTRL_NS_INT_CTRL |
-		   L2C_AUX_CTRL_WAY_SIZE(3) |
 		   L2C_AUX_CTRL_SHARED_OVERRIDE |
 		   L310_AUX_CTRL_DATA_PREFETCH |
 		   L310_AUX_CTRL_INSTR_PREFETCH;
 
 	outer_cache.write_sec = omap4_l2c310_write_sec;
 	if (of_have_populated_dt())
-		l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
+		l2x0_of_init(aux_ctrl, 0xc19fffff);
 	else
-		l2x0_init(l2cache_base, aux_ctrl, L2X0_AUX_CTRL_MASK);
+		l2x0_init(l2cache_base, aux_ctrl, 0xc19fffff);
 
 	return 0;
 }
Signature · 1 line
1.8.3.1
#84 lore raw

PATCH 58/75 ARM: l2c: omap2: remove cache size override

Quoted 3 lines · Tony Lindgren

* Russell King <[email protected]> [140328 08:22]:

Missing description?

No, I just got sick and tired of trying to write descriptions for these patches. Many of these I regard as totally unnecessary patches that should never have been required had platform folk not invested in cargo cult programming.

Given the number of patches I'm presently dealing with in my tree right now, I don't actually have time to even follow the mailing lists at the moment. If I were to properly describe all of these patches, I'd probably be at this for another few weeks.

So, I'm at the point of "what you see is what you've got" as far as the descriptions go... it's going to cause me a /lot/ of pain to just add all the acks I'm going to need to these patches.

And... don't expect me to send the series out again any time soon to LAKML - it's taken four to five hours for all these patches to filter through the lists.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
maintainer
#85 lore raw

PATCH 58/75 ARM: l2c: omap2: remove cache size override

Quoted 10 lines · Russell King - ARM Linux
Quoted 3 lines · Tony Lindgren

* Russell King <[email protected]> [140328 08:22]:

Missing description?

No, I just got sick and tired of trying to write descriptions for these patches. Many of these I regard as totally unnecessary patches that should never have been required had platform folk not invested in cargo cult programming.

Quoted 4 lines

Given the number of patches I'm presently dealing with in my tree right now, I don't actually have time to even follow the mailing lists at the moment. If I were to properly describe all of these patches, I'd probably be at this for another few weeks.

Heh well I have a feeling you'll add some generic description anyways :)

Quoted 3 lines

So, I'm at the point of "what you see is what you've got" as far as the descriptions go... it's going to cause me a /lot/ of pain to just add all the acks I'm going to need to these patches.

In that case here's one more painful ack for this patch:

Quoted 3 lines

And... don't expect me to send the series out again any time soon to LAKML - it's taken four to five hours for all these patches to filter through the lists.

No need to repost on my part.

Tony

#86 lore raw

PATCH 58/75 ARM: l2c: omap2: remove cache size override

Quoted 11 lines · Tony Lindgren
Quoted 10 lines · Russell King - ARM Linux
Quoted 3 lines · Tony Lindgren

* Russell King <[email protected]> [140328 08:22]:

Missing description?

No, I just got sick and tired of trying to write descriptions for these patches. Many of these I regard as totally unnecessary patches that should never have been required had platform folk not invested in cargo cult programming.

Quoted 6 lines
Quoted 4 lines

Given the number of patches I'm presently dealing with in my tree right now, I don't actually have time to even follow the mailing lists at the moment. If I were to properly describe all of these patches, I'd probably be at this for another few weeks.

Heh well I have a feeling you'll add some generic description anyways :)

If I end up merging each of these patches removingthe cache override together into one commit touching many of the SoCs, then yes.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#87 lore raw

PATCH 59/75 ARM: l2c: prima2: remove cache size override

In reply to Russell King - ARM Linux
---
 arch/arm/boot/dts/marco.dtsi  |  2 +-
 arch/arm/boot/dts/prima2.dtsi |  2 +-
 arch/arm/mach-prima2/l2x0.c   | 34 +---------------------------------
 3 files changed, 3 insertions(+), 35 deletions(-)
arch/arm/boot/dts/marco.dtsi +1 -1
index 1579c3491ccd..247879aa1224 100644
@@ -36,7 +36,7 @@
 		ranges = <0x40000000 0x40000000 0xa0000000>;
 
 		l2-cache-controller at c0030000 {
-			compatible = "sirf,marco-pl310-cache", "arm,pl310-cache";
+			compatible = "arm,pl310-cache";
 			reg = <0xc0030000 0x1000>;
 			interrupts = <0 59 0>;
 			arm,tag-latency = <1 1 1>;
arch/arm/boot/dts/prima2.dtsi +1 -1
index 0e219932d7cc..29b578727b0a 100644
@@ -48,7 +48,7 @@
 		ranges = <0x40000000 0x40000000 0x80000000>;
 
 		l2-cache-controller at 80040000 {
-			compatible = "arm,pl310-cache", "sirf,prima2-pl310-cache";
+			compatible = "arm,pl310-cache";
 			reg = <0x80040000 0x1000>;
 			interrupts = <59>;
 			arm,tag-latency = <1 1 1>;
arch/arm/mach-prima2/l2x0.c +1 -33
index 3a4eda45171e..09f68f046830 100644
@@ -8,42 +8,10 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/of.h>
 #include <asm/hardware/cache-l2x0.h>
 
-struct l2x0_aux
-{
-	u32 val;
-	u32 mask;
-};
-
-static struct l2x0_aux prima2_l2x0_aux __initconst = {
-	.val = L2C_AUX_CTRL_WAY_SIZE(2),
-	.mask =	0,
-};
-
-static struct l2x0_aux marco_l2x0_aux __initconst = {
-	.val = L2C_AUX_CTRL_WAY_SIZE(2) | L310_AUX_CTRL_ASSOCIATIVITY_16,
-	.mask = L2X0_AUX_CTRL_MASK,
-};
-
-static struct of_device_id sirf_l2x0_ids[] __initconst = {
-	{ .compatible = "sirf,prima2-pl310-cache", .data = &prima2_l2x0_aux, },
-	{ .compatible = "sirf,marco-pl310-cache", .data = &marco_l2x0_aux, },
-	{},
-};
-
 static int __init sirfsoc_l2x0_init(void)
 {
-	struct device_node *np;
-	const struct l2x0_aux *aux;
-
-	np = of_find_matching_node(NULL, sirf_l2x0_ids);
-	if (np) {
-		aux = of_match_node(sirf_l2x0_ids, np)->data;
-		return l2x0_of_init(aux->val, aux->mask);
-	}
-
-	return 0;
+	return l2x0_of_init(0, ~0);
 }
 early_initcall(sirfsoc_l2x0_init);
Signature · 1 line
1.8.3.1
#88 lore raw

PATCH 59/75 ARM: l2c: prima2: remove cache size override

2014-03-28 23:19 GMT+08:00 Russell King <[email protected]>:

Quoted 69 lines
---
 arch/arm/boot/dts/marco.dtsi  |  2 +-
 arch/arm/boot/dts/prima2.dtsi |  2 +-
 arch/arm/mach-prima2/l2x0.c   | 34 +---------------------------------
 3 files changed, 3 insertions(+), 35 deletions(-)
arch/arm/boot/dts/marco.dtsi +1 -1
index 1579c3491ccd..247879aa1224 100644
@@ -36,7 +36,7 @@
                ranges = <0x40000000 0x40000000 0xa0000000>;
 
                l2-cache-controller at c0030000 {
-                       compatible = "sirf,marco-pl310-cache", "arm,pl310-cache";
+                       compatible = "arm,pl310-cache";
                        reg = <0xc0030000 0x1000>;
                        interrupts = <0 59 0>;
                        arm,tag-latency = <1 1 1>;
arch/arm/boot/dts/prima2.dtsi +1 -1
index 0e219932d7cc..29b578727b0a 100644
@@ -48,7 +48,7 @@
                ranges = <0x40000000 0x40000000 0x80000000>;
 
                l2-cache-controller at 80040000 {
-                       compatible = "arm,pl310-cache", "sirf,prima2-pl310-cache";
+                       compatible = "arm,pl310-cache";
                        reg = <0x80040000 0x1000>;
                        interrupts = <59>;
                        arm,tag-latency = <1 1 1>;
arch/arm/mach-prima2/l2x0.c +0 -24
index 3a4eda45171e..09f68f046830 100644
@@ -8,42 +8,10 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/of.h>
 #include <asm/hardware/cache-l2x0.h>
 
-struct l2x0_aux
-{
-       u32 val;
-       u32 mask;
-};
-
-static struct l2x0_aux prima2_l2x0_aux __initconst = {
-       .val = L2C_AUX_CTRL_WAY_SIZE(2),
-       .mask = 0,
-};
-
-static struct l2x0_aux marco_l2x0_aux __initconst = {
-       .val = L2C_AUX_CTRL_WAY_SIZE(2) | L310_AUX_CTRL_ASSOCIATIVITY_16,
-       .mask = L2X0_AUX_CTRL_MASK,
-};
-
-static struct of_device_id sirf_l2x0_ids[] __initconst = {
-       { .compatible = "sirf,prima2-pl310-cache", .data = &prima2_l2x0_aux, },
-       { .compatible = "sirf,marco-pl310-cache", .data = &marco_l2x0_aux, },
-       {},
-};
-
 static int __init sirfsoc_l2x0_init(void)
 {
-       struct device_node *np;

arch/arm/mach-prima2/l2x0.c line 15

Quoted 10 lines
arch/arm/mach-prima2/l2x0.c +1 -9
-       const struct l2x0_aux *aux;
-
-       np = of_find_matching_node(NULL, sirf_l2x0_ids);
-       if (np) {
-               aux = of_match_node(sirf_l2x0_ids, np)->data;
-               return l2x0_of_init(aux->val, aux->mask);
-       }
-
-       return 0;
+       return l2x0_of_init(0, ~0);

Russell, as i mailed you before, pre-set L2 has disabled write_combined, here we can make the bit restored.

Quoted 5 lines
arch/arm/mach-prima2/l2x0.c +0 -1
 }
 early_initcall(sirfsoc_l2x0_init);
--

1.8.3.1

-barry

#89 lore raw

PATCH 59/75 ARM: l2c: prima2: remove cache size override

Quoted 75 lines · Barry Song

2014-03-28 23:19 GMT+08:00 Russell King <[email protected]>:

Quoted 74 lines
---
 arch/arm/boot/dts/marco.dtsi  |  2 +-
 arch/arm/boot/dts/prima2.dtsi |  2 +-
 arch/arm/mach-prima2/l2x0.c   | 34 +---------------------------------
 3 files changed, 3 insertions(+), 35 deletions(-)
arch/arm/boot/dts/marco.dtsi +1 -1
index 1579c3491ccd..247879aa1224 100644
@@ -36,7 +36,7 @@
                ranges = <0x40000000 0x40000000 0xa0000000>;
 
                l2-cache-controller at c0030000 {
-                       compatible = "sirf,marco-pl310-cache", "arm,pl310-cache";
+                       compatible = "arm,pl310-cache";
                        reg = <0xc0030000 0x1000>;
                        interrupts = <0 59 0>;
                        arm,tag-latency = <1 1 1>;
arch/arm/boot/dts/prima2.dtsi +1 -1
index 0e219932d7cc..29b578727b0a 100644
@@ -48,7 +48,7 @@
                ranges = <0x40000000 0x40000000 0x80000000>;
 
                l2-cache-controller at 80040000 {
-                       compatible = "arm,pl310-cache", "sirf,prima2-pl310-cache";
+                       compatible = "arm,pl310-cache";
                        reg = <0x80040000 0x1000>;
                        interrupts = <59>;
                        arm,tag-latency = <1 1 1>;
arch/arm/mach-prima2/l2x0.c +0 -29
index 3a4eda45171e..09f68f046830 100644
@@ -8,42 +8,10 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/of.h>
 #include <asm/hardware/cache-l2x0.h>
 
-struct l2x0_aux
-{
-       u32 val;
-       u32 mask;
-};
-
-static struct l2x0_aux prima2_l2x0_aux __initconst = {
-       .val = L2C_AUX_CTRL_WAY_SIZE(2),
-       .mask = 0,
-};
-
-static struct l2x0_aux marco_l2x0_aux __initconst = {
-       .val = L2C_AUX_CTRL_WAY_SIZE(2) | L310_AUX_CTRL_ASSOCIATIVITY_16,
-       .mask = L2X0_AUX_CTRL_MASK,
-};
-
-static struct of_device_id sirf_l2x0_ids[] __initconst = {
-       { .compatible = "sirf,prima2-pl310-cache", .data = &prima2_l2x0_aux, },
-       { .compatible = "sirf,marco-pl310-cache", .data = &marco_l2x0_aux, },
-       {},
-};
-
 static int __init sirfsoc_l2x0_init(void)
 {
-       struct device_node *np;
-       const struct l2x0_aux *aux;
-
-       np = of_find_matching_node(NULL, sirf_l2x0_ids);
-       if (np) {
-               aux = of_match_node(sirf_l2x0_ids, np)->data;
Quoted 8 lines

arch/arm/mach-prima2/l2x0.c line 15

Quoted 5 lines
arch/arm/mach-prima2/l2x0.c +1 -4
-               return l2x0_of_init(aux->val, aux->mask);
-       }
-
-       return 0;
+       return l2x0_of_init(0, ~0);

Russell, as i mailed you before, pre-set L2 has disabled write_combined, here we can make the bit restored.

*Sigh*. This is what your final email said on the subject:

[Barry Song]
Anyway, it seems I can drop the whole mach-prima2/l2x0.c if I use 0 as the aux_val. For aux_mask, let me zero those bits I really want to zero.

which to me means "I need to figure out what we need to do here, and I'll eventually send you a patch".

It's really quite simple. I've done nothing (as you can see if you compare this to what I sent you originally) because you've done nothing to help me. If you want me to do something different here, send me what you need. Otherwise, I'm not going to change it, because I don't know what you want here.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#90 lore raw

PATCH 59/75 ARM: l2c: prima2: remove cache size override

2014-04-04 22:10 GMT+08:00 Russell King - ARM Linux <[email protected]>:

Quoted 85 lines · Barry Song
Quoted 75 lines

2014-03-28 23:19 GMT+08:00 Russell King <[email protected]>:

Quoted 74 lines
---
 arch/arm/boot/dts/marco.dtsi  |  2 +-
 arch/arm/boot/dts/prima2.dtsi |  2 +-
 arch/arm/mach-prima2/l2x0.c   | 34 +---------------------------------
 3 files changed, 3 insertions(+), 35 deletions(-)
arch/arm/boot/dts/marco.dtsi +1 -1
index 1579c3491ccd..247879aa1224 100644
@@ -36,7 +36,7 @@
                ranges = <0x40000000 0x40000000 0xa0000000>;
 
                l2-cache-controller at c0030000 {
-                       compatible = "sirf,marco-pl310-cache", "arm,pl310-cache";
+                       compatible = "arm,pl310-cache";
                        reg = <0xc0030000 0x1000>;
                        interrupts = <0 59 0>;
                        arm,tag-latency = <1 1 1>;
arch/arm/boot/dts/prima2.dtsi +1 -1
index 0e219932d7cc..29b578727b0a 100644
@@ -48,7 +48,7 @@
                ranges = <0x40000000 0x40000000 0x80000000>;
 
                l2-cache-controller at 80040000 {
-                       compatible = "arm,pl310-cache", "sirf,prima2-pl310-cache";
+                       compatible = "arm,pl310-cache";
                        reg = <0x80040000 0x1000>;
                        interrupts = <59>;
                        arm,tag-latency = <1 1 1>;
arch/arm/mach-prima2/l2x0.c +0 -29
index 3a4eda45171e..09f68f046830 100644
@@ -8,42 +8,10 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/of.h>
 #include <asm/hardware/cache-l2x0.h>
 
-struct l2x0_aux
-{
-       u32 val;
-       u32 mask;
-};
-
-static struct l2x0_aux prima2_l2x0_aux __initconst = {
-       .val = L2C_AUX_CTRL_WAY_SIZE(2),
-       .mask = 0,
-};
-
-static struct l2x0_aux marco_l2x0_aux __initconst = {
-       .val = L2C_AUX_CTRL_WAY_SIZE(2) | L310_AUX_CTRL_ASSOCIATIVITY_16,
-       .mask = L2X0_AUX_CTRL_MASK,
-};
-
-static struct of_device_id sirf_l2x0_ids[] __initconst = {
-       { .compatible = "sirf,prima2-pl310-cache", .data = &prima2_l2x0_aux, },
-       { .compatible = "sirf,marco-pl310-cache", .data = &marco_l2x0_aux, },
-       {},
-};
-
 static int __init sirfsoc_l2x0_init(void)
 {
-       struct device_node *np;
-       const struct l2x0_aux *aux;
-
-       np = of_find_matching_node(NULL, sirf_l2x0_ids);
-       if (np) {
-               aux = of_match_node(sirf_l2x0_ids, np)->data;
Quoted 8 lines

arch/arm/mach-prima2/l2x0.c line 15

Quoted 5 lines
arch/arm/mach-prima2/l2x0.c +1 -4
-               return l2x0_of_init(aux->val, aux->mask);
-       }
-
-       return 0;
+       return l2x0_of_init(0, ~0);

Russell, as i mailed you before, pre-set L2 has disabled write_combined, here we can make the bit restored.

Quoted 5 lines

*Sigh*. This is what your final email said on the subject:

[Barry Song]
Anyway, it seems I can drop the whole mach-prima2/l2x0.c if I use 0 as the aux_val. For aux_mask, let me zero those bits I really want to zero.

yes. it is my final mail on the subject.

Quoted 3 lines

which to me means "I need to figure out what we need to do here, and I'll eventually send you a patch".

it was because i missed your this mail and patch in mail list when i got that mail. so i said i would send a patch to follow your requirement.
but since you already had one here, i will not.

Quoted 7 lines

It's really quite simple. I've done nothing (as you can see if you compare this to what I sent you originally) because you've done nothing to help me. If you want me to do something different here, send me what you need. Otherwise, I'm not going to change it, because I don't know what you want here.

i was not asking why you have not done anything. i was just remarking when i found this mail today.
about what i want here, my 1st goal is making aux_mask 0xfdffffff. my 2nd goal is making mach-prima2/l2x0.c disappear and moving l2x0_of_init to mach-prima2/common.c.

-barry

#91 lore raw

PATCH 60/75 ARM: l2c: shmobile: remove cache size override

In reply to Russell King - ARM Linux
---
 arch/arm/mach-shmobile/board-armadillo800eva-reference.c | 2 +-
 arch/arm/mach-shmobile/board-armadillo800eva.c           | 2 +-
 arch/arm/mach-shmobile/board-kzm9g-reference.c           | 2 +-
 arch/arm/mach-shmobile/board-kzm9g.c                     | 2 +-
 arch/arm/mach-shmobile/setup-r8a7778.c                   | 2 +-
 arch/arm/mach-shmobile/setup-r8a7779.c                   | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)
arch/arm/mach-shmobile/board-armadillo800eva-reference.c +1 -1
index 34e7f3c17dd2..39e11f48e8bc 100644
@@ -165,7 +165,7 @@ static void __init eva_init(void)
 
 #ifdef CONFIG_CACHE_L2X0
 	/* Shared attribute override enable, 32K*8way */
-	l2x0_init(IOMEM(0xf0002000), 0x00440000, 0xc2000fff);
+	l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff);
 #endif
 
 	r8a7740_add_standard_devices_dt();
arch/arm/mach-shmobile/board-armadillo800eva.c +1 -1
index 69ec71038ec7..179f455d96c7 100644
@@ -1271,7 +1271,7 @@ static void __init eva_init(void)
 
 #ifdef CONFIG_CACHE_L2X0
 	/* Shared attribute override enable, 32K*8way */
-	l2x0_init(IOMEM(0xf0002000), 0x00440000, 0xc2000fff);
+	l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff);
 #endif
 
 	i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
arch/arm/mach-shmobile/board-kzm9g-reference.c +1 -1
index 85873f186d77..a735a1d80c28 100644
@@ -37,7 +37,7 @@ static void __init kzm_init(void)
 
 #ifdef CONFIG_CACHE_L2X0
 	/* Shared attribute override enable, 64K*8way */
-	l2x0_init(IOMEM(0xf0100000), 0x00460000, 0xc2000fff);
+	l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
 #endif
 }
 
arch/arm/mach-shmobile/board-kzm9g.c +1 -1
index bd9931f223ae..4c4cb64e99fe 100644
@@ -879,7 +879,7 @@ static void __init kzm_init(void)
 
 #ifdef CONFIG_CACHE_L2X0
 	/* Shared attribute override enable, 64K*8way */
-	l2x0_init(IOMEM(0xf0100000), 0x00460000, 0xc2000fff);
+	l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
 #endif
 
 	i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
arch/arm/mach-shmobile/setup-r8a7778.c +1 -1
index 3a8e5316671e..6dd7ddf88741 100644
@@ -301,7 +301,7 @@ void __init r8a7778_add_dt_devices(void)
 		 * Shared attribute override enable, 64K*16way
 		 * don't call iounmap(base)
 		 */
-		l2x0_init(base, 0x00470000, 0xc2000fff);
+		l2x0_init(base, 0x00400000, 0xc20f0fff);
 	}
 #endif
 
arch/arm/mach-shmobile/setup-r8a7779.c +1 -1
index 91c90bf0ae83..a6630fccfc45 100644
@@ -701,7 +701,7 @@ void __init r8a7779_add_standard_devices(void)
 {
 #ifdef CONFIG_CACHE_L2X0
 	/* Shared attribute override enable, 64K*16way */
-	l2x0_init(IOMEM(0xf0100000), 0x00470000, 0xc2000fff);
+	l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
 #endif
 	r8a7779_pm_init();
 
Signature · 1 line
1.8.3.1
#92 lore raw

PATCH 61/75 ARM: l2c: spear13xx: remove cache size override

In reply to Russell King - ARM Linux
---
 arch/arm/mach-spear/spear13xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-spear/spear13xx.c +1 -1
index dcb300443b66..c9897ea38980 100644
@@ -46,7 +46,7 @@ void __init spear13xx_l2x0_init(void)
 	 */
 	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, 0x30a60001, 0xfe00ffff);
+	l2x0_init(VA_L2CC_BASE, 0x30a00001, 0xfe0fffff);
 }
 
 /*
Signature · 1 line
1.8.3.1
#93 lore raw

PATCH 62/75 ARM: l2c: sti: remove cache size override

In reply to Russell King - ARM Linux
---
 arch/arm/mach-sti/board-dt.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)
arch/arm/mach-sti/board-dt.c +3 -9
index dc8669efc12d..cf716ae10726 100644
@@ -16,15 +16,9 @@
 
 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 = L2C_AUX_CTRL_SHARED_OVERRIDE |
-		   L310_AUX_CTRL_DATA_PREFETCH |
-		   L310_AUX_CTRL_INSTR_PREFETCH |
-		   L2C_AUX_CTRL_WAY_SIZE(way_size);
-
-	l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
+	l2x0_of_init(L2C_AUX_CTRL_SHARED_OVERRIDE |
+		     L310_AUX_CTRL_DATA_PREFETCH |
+		     L310_AUX_CTRL_INSTR_PREFETCH, 0xc00f0fff);
 }
 
 static void __init stih41x_machine_init(void)
Signature · 1 line
1.8.3.1
#94 lore raw

PATCH 62/75 ARM: l2c: sti: remove cache size override

Quoted 15 lines · Russell King
---
  arch/arm/mach-sti/board-dt.c | 12 +++---------
  1 file changed, 3 insertions(+), 9 deletions(-)
arch/arm/mach-sti/board-dt.c +0 -2
index dc8669efc12d..cf716ae10726 100644
@@ -16,15 +16,9 @@
 
  void __init stih41x_l2x0_init(void)
  {
-	u32 way_size = 0x4;
-	u32 aux_ctrl;

arch/arm/mach-sti/board-dt.c line 21

Quoted 10 lines
arch/arm/mach-sti/board-dt.c +3 -7
-	/* may be this can be encoded in macros like BIT*() */
-	aux_ctrl = L2C_AUX_CTRL_SHARED_OVERRIDE |
-		   L310_AUX_CTRL_DATA_PREFETCH |
-		   L310_AUX_CTRL_INSTR_PREFETCH |
-		   L2C_AUX_CTRL_WAY_SIZE(way_size);
-
-	l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
+	l2x0_of_init(L2C_AUX_CTRL_SHARED_OVERRIDE |
+		     L310_AUX_CTRL_DATA_PREFETCH |
+		     L310_AUX_CTRL_INSTR_PREFETCH, 0xc00f0fff);

As discussed last week, the STiH416 SoC has his way size value set to 0 at reset instead of 4.

I think this should be done by the bootloader instead of the Kernel. Sadly the bootloader don't set it for now, but I will request it to be implemented.

Regards,
Maxime

Quoted 4 lines
arch/arm/mach-sti/board-dt.c +0 -0
  }
 
  static void __init stih41x_machine_init(void)
#95 lore raw

PATCH 63/75 ARM: l2c: zynq: remove cache size override

In reply to Russell King - ARM Linux
---
 arch/arm/mach-zynq/common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-zynq/common.c +1 -1
index 8c09a8393fb6..b58f17178006 100644
@@ -67,7 +67,7 @@ static void __init zynq_init_machine(void)
 	/*
 	 * 64KB way size, 8-way associativity, parity disabled
 	 */
-	l2x0_of_init(0x02060000, 0xF0F0FFFF);
+	l2x0_of_init(0x02000000, 0xf0ffffff);
 
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 
Signature · 1 line
1.8.3.1
#96 lore raw

PATCH 63/75 ARM: l2c: zynq: remove cache size override

Hi Russell,

Quoted 10 lines · Russell King
---
 arch/arm/mach-zynq/common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-zynq/common.c +0 -0
index 8c09a8393fb6..b58f17178006 100644

arch/arm/mach-zynq/common.c static void __init zynq_init_machine(void) · line 73

Quoted 8 lines
arch/arm/mach-zynq/common.c +1 -1
@@ -67,7 +67,7 @@ static void __init zynq_init_machine(void)
 	/*
 	 * 64KB way size, 8-way associativity, parity disabled
 	 */
-	l2x0_of_init(0x02060000, 0xF0F0FFFF);
+	l2x0_of_init(0x02000000, 0xf0ffffff);
 
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 

We have done one fix some days/weeks ago which is here.
https://github.com/Xilinx/linux-xlnx/commit/1a85939af40acca2bf963407b497cc31c303ff3e
(Feel free to ignore L2_PREFETCH config option)

There are 2 things there.
1. Extending macros in cache-l2x0.h which I believe can go to the mainline (when we align with changes you have done in 49/75)
2. Set L2X0_AUX_CTRL_SHARE_OVERRIDE_EN_MASK bit which is what vexpress did. The reason was problem with gem driver with iperf testing.

Regarding your post about bits 19:17

Quoted 5 lines

Bits 19:17 are the way size, bit 16 (for the PL310) is the associativity (8 or 16 ways.) It seems many people have the impression that they have to set these values according to the size of the cache and they can't rely on the value already initialised by hardware from synthesis the options.

Reset values are correctly setup by bootrom to 0x02060000 That's why we can even use full mask.
For current mainline code just like this

	l2x0_of_init(0x00000000, 0xffffffff);
and we will submit the code which change this to
	l2x0_of_init(0x00400000, 0xffffffff);

Please let me know if this is aligned with your goal what you want to reach.

Thanks,
Michal

Signature · 14 lines
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140402/f4056b1c/attachment.sig>
#97 lore raw

PATCH 63/75 ARM: l2c: zynq: remove cache size override

Quoted 39 lines · Michal Simek

Hi Russell,

Quoted 10 lines · Russell King
---
 arch/arm/mach-zynq/common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-zynq/common.c +0 -0
index 8c09a8393fb6..b58f17178006 100644

arch/arm/mach-zynq/common.c static void __init zynq_init_machine(void) · line 73

Quoted 8 lines
arch/arm/mach-zynq/common.c +1 -1
@@ -67,7 +67,7 @@ static void __init zynq_init_machine(void)
 	/*
 	 * 64KB way size, 8-way associativity, parity disabled
 	 */
-	l2x0_of_init(0x02060000, 0xF0F0FFFF);
+	l2x0_of_init(0x02000000, 0xf0ffffff);
 
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 

We have done one fix some days/weeks ago which is here.
https://github.com/Xilinx/linux-xlnx/commit/1a85939af40acca2bf963407b497cc31c303ff3e
(Feel free to ignore L2_PREFETCH config option)

There are 2 things there.
1. Extending macros in cache-l2x0.h which I believe can go to the mainline (when we align with changes you have done in 49/75)
2. Set L2X0_AUX_CTRL_SHARE_OVERRIDE_EN_MASK bit which is what vexpress did. The reason was problem with gem driver with iperf testing.

Regarding your post about bits 19:17

Quoted 5 lines

Bits 19:17 are the way size, bit 16 (for the PL310) is the associativity (8 or 16 ways.) It seems many people have the impression that they have to set these values according to the size of the cache and they can't rely on the value already initialised by hardware from synthesis the options.

Quoted 6 lines

Reset values are correctly setup by bootrom to 0x02060000 That's why we can even use full mask.
For current mainline code just like this

	l2x0_of_init(0x00000000, 0xffffffff);
and we will submit the code which change this to
	l2x0_of_init(0x00400000, 0xffffffff);

Ok. I have read the whole thread and just to be align with your changes zynq can be changed to l2x0_of_init(0, ~0);

I have looked at other changes - we have r3p2 and we will want to setup L310_AUX_CTRL_DATA_PREFETCH | L310_AUX_CTRL_INSTR_PREFETCH as is in 72/75.

We can enable L2C_AUX_CTRL_SHARED_OVERRIDE later.
The same with L310_AUX_CTRL_DATA_PREFETCH and L310_AUX_CTRL_INSTR_PREFETCH.

If you are willing to add this to your series, please let me know and I will provide you the patch.

BTW: do you have branch somewhere which I can just download and test?

Thanks,
Michal

Signature · 14 lines
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140402/e33e73dc/attachment.sig>
#98 lore raw

PATCH 63/75 ARM: l2c: zynq: remove cache size override

In reply to Michal Simek
Quoted 26 lines · Michal Simek

Hi Russell,

Quoted 10 lines · Russell King
---
 arch/arm/mach-zynq/common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-zynq/common.c +0 -0
index 8c09a8393fb6..b58f17178006 100644

arch/arm/mach-zynq/common.c static void __init zynq_init_machine(void) · line 73

Quoted 8 lines
arch/arm/mach-zynq/common.c +1 -1
@@ -67,7 +67,7 @@ static void __init zynq_init_machine(void)
 	/*
 	 * 64KB way size, 8-way associativity, parity disabled
 	 */
-	l2x0_of_init(0x02060000, 0xF0F0FFFF);
+	l2x0_of_init(0x02000000, 0xf0ffffff);
 
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 

We have done one fix some days/weeks ago which is here.
https://github.com/Xilinx/linux-xlnx/commit/1a85939af40acca2bf963407b497cc31c303ff3e
(Feel free to ignore L2_PREFETCH config option)

Quoted 5 lines

There are 2 things there.
1. Extending macros in cache-l2x0.h which I believe can go to the mainline (when we align with changes you have done in 49/75)
2. Set L2X0_AUX_CTRL_SHARE_OVERRIDE_EN_MASK bit which is what vexpress did. The reason was problem with gem driver with iperf testing.

So reading the original commit text from Catalin
(1a8e41cd672f894bbd74874eac601e6cedf838fb):

ARM: 6395/1: VExpress: Set bit 22 in the PL310 (cache controller)
AuxCtlr register

Clearing bit 22 in the PL310 Auxiliary Control register (shared attribute override enable) has the side effect of transforming Normal Shared Non-cacheable reads into Cacheable no-allocate reads.

Coherent DMA buffers in Linux always have a Cacheable alias via the kernel linear mapping and the processor can speculatively load cache lines into the PL310 controller. With bit 22 cleared, Non-cacheable reads would unexpectedly hit such cache lines leading to buffer corruption.

It looks like all Linux systems will have to use Sharable override to avoid corruption? I see OMAP4 had a similar commit to enable bit 22 of aux control register.

If yes, how about doing it by default in cache-l2x0.c rather than leaving it to each platform?

Thanks,
Sekhar

#99 lore raw

PATCH 63/75 ARM: l2c: zynq: remove cache size override

Quoted 22 lines · Sekhar Nori

So reading the original commit text from Catalin
(1a8e41cd672f894bbd74874eac601e6cedf838fb):

ARM: 6395/1: VExpress: Set bit 22 in the PL310 (cache controller)
AuxCtlr register

Clearing bit 22 in the PL310 Auxiliary Control register (shared attribute override enable) has the side effect of transforming Normal Shared Non-cacheable reads into Cacheable no-allocate reads.

Coherent DMA buffers in Linux always have a Cacheable alias via the kernel linear mapping and the processor can speculatively load cache lines into the PL310 controller. With bit 22 cleared, Non-cacheable reads would unexpectedly hit such cache lines leading to buffer corruption.

Quoted 6 lines

It looks like all Linux systems will have to use Sharable override to avoid corruption? I see OMAP4 had a similar commit to enable bit 22 of aux control register.

If yes, how about doing it by default in cache-l2x0.c rather than leaving it to each platform?

The comments in the commit are no longer true with CMA, which finally fixes the multiple mapping problem. The sharable override bit should not need to be set for systems using CMA as their backing store for DMA coherent memory.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#100 lore raw

PATCH 63/75 ARM: l2c: zynq: remove cache size override

Quoted 27 lines · Russell King - ARM Linux
Quoted 26 lines · Sekhar Nori

So reading the original commit text from Catalin
(1a8e41cd672f894bbd74874eac601e6cedf838fb):

ARM: 6395/1: VExpress: Set bit 22 in the PL310 (cache controller)
AuxCtlr register

Clearing bit 22 in the PL310 Auxiliary Control register (shared attribute override enable) has the side effect of transforming Normal Shared Non-cacheable reads into Cacheable no-allocate reads.

Coherent DMA buffers in Linux always have a Cacheable alias via the kernel linear mapping and the processor can speculatively load cache lines into the PL310 controller. With bit 22 cleared, Non-cacheable reads would unexpectedly hit such cache lines leading to buffer corruption.

It looks like all Linux systems will have to use Sharable override to avoid corruption? I see OMAP4 had a similar commit to enable bit 22 of aux control register.

Quoted 7 lines
Quoted 2 lines

If yes, how about doing it by default in cache-l2x0.c rather than leaving it to each platform?

The comments in the commit are no longer true with CMA, which finally fixes the multiple mapping problem. The sharable override bit should not need to be set for systems using CMA as their backing store for DMA coherent memory.

Thanks for the explanation. Note to myself: some platforms are using arm_memblock_steal() or memblock_remove() for reserving coherent memory which should also be safe as the memory is not mapped in kernel page tables.

Thanks,
Sekhar

#101 lore raw

PATCH 63/75 ARM: l2c: zynq: remove cache size override

In reply to Michal Simek
Quoted 6 lines · Michal Simek

Reset values are correctly setup by bootrom to 0x02060000 That's why we can even use full mask.
For current mainline code just like this

	l2x0_of_init(0x00000000, 0xffffffff);
and we will submit the code which change this to
	l2x0_of_init(0x00400000, 0xffffffff);

If you wish to do that, please use 0xffbfffff as the mask, otherwise some of the checks will fire (about possibly corrupted values.)

Fields you wish to set to a value must have clear bits in the mask. This is to stop things like:

	l2x0_of_init(0x...246, 0x...fff)

which if the LSBs of the register are already set to a different value, ends up doing this:

new_reg = (old_reg & mask) | val

and hence ends up ORing the specified value with the existing value in the register. Hence, (val & mask) must be zero.

I'd rather not force bit 22 on for everyone - this problem /should/ no longer be present with CMA since the memory is remapped in place rather than having a second mapping setup.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#102 lore raw

PATCH 63/75 ARM: l2c: zynq: remove cache size override

Quoted 19 lines · Russell King - ARM Linux
Quoted 6 lines · Michal Simek

Reset values are correctly setup by bootrom to 0x02060000 That's why we can even use full mask.
For current mainline code just like this

	l2x0_of_init(0x00000000, 0xffffffff);
and we will submit the code which change this to
	l2x0_of_init(0x00400000, 0xffffffff);

If you wish to do that, please use 0xffbfffff as the mask, otherwise some of the checks will fire (about possibly corrupted values.)

Fields you wish to set to a value must have clear bits in the mask. This is to stop things like:

	l2x0_of_init(0x...246, 0x...fff)

which if the LSBs of the register are already set to a different value, ends up doing this:

Quoted 8 lines

new_reg = (old_reg & mask) | val

and hence ends up ORing the specified value with the existing value in the register. Hence, (val & mask) must be zero.

I'd rather not force bit 22 on for everyone - this problem /should/ no longer be present with CMA since the memory is remapped in place rather than having a second mapping setup.

ok. I think reasonable solution is to use
l2x0_of_init(0, ~0); in this patch.
And we will enable L2C_AUX_CTRL_SHARED_OVERRIDE on the top of this series.

Thanks,
Michal

Signature · 14 lines
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140404/313ffc31/attachment.sig>
#103 lore raw

PATCH 64/75 ARM: l2c: realview: improve commentry about the L2 cache requirements

In reply to Russell King - ARM Linux

Add better commentry about the L2 cache requirements on these platforms. Unfortunately, the auxiliary control register is not pre-set to indicate the correct cache parameters, so we have to manually program these.

---
 arch/arm/mach-realview/realview_eb.c     | 9 +++++++--
 arch/arm/mach-realview/realview_pb1176.c | 8 +++++++-
 arch/arm/mach-realview/realview_pb11mp.c | 9 +++++++--
 3 files changed, 21 insertions(+), 5 deletions(-)
arch/arm/mach-realview/realview_eb.c +7 -2
index c85ddb2a0ad0..b575895037b8 100644
@@ -442,8 +442,13 @@ static void __init realview_eb_init(void)
 		realview_eb11mp_fixup();
 
 #ifdef CONFIG_CACHE_L2X0
-		/* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
-		 * Bits:  .... ...0 0111 1001 0000 .... .... .... */
+		/*
+		 * The PL220 needs to be manually configured as the hardware
+		 * doesn't report the correct sizes.
+		 * 1MB (128KB/way), 8-way associativity, event monitor and
+		 * parity enabled, ignore share bit, no force write allocate
+		 * Bits:  .... ...0 0111 1001 0000 .... .... ....
+		 */
 		l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff);
 #endif
 		platform_device_register(&pmu_device);
arch/arm/mach-realview/realview_pb1176.c +7 -1
index c5eade76461b..e3bddb5ab10f 100644
@@ -355,7 +355,13 @@ static void __init realview_pb1176_init(void)
 	int i;
 
 #ifdef CONFIG_CACHE_L2X0
-	/* 128Kb (16Kb/way) 8-way associativity. evmon/parity/share enabled. */
+	/*
+	 * The PL220 needs to be manually configured as the hardware
+	 * doesn't report the correct sizes.
+	 * 128kB (16kB/way), 8-way associativity, event monitor and
+	 * parity enabled, ignore share bit, no force write allocate
+	 * Bits:  .... ...0 0111 0011 0000 .... .... ....
+	 */
 	l2x0_init(__io_address(REALVIEW_PB1176_L220_BASE), 0x00730000, 0xfe000fff);
 #endif
 
arch/arm/mach-realview/realview_pb11mp.c +7 -2
index f4b0962578fe..101deaf2630b 100644
@@ -337,8 +337,13 @@ static void __init realview_pb11mp_init(void)
 	int i;
 
 #ifdef CONFIG_CACHE_L2X0
-	/* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
-	 * Bits:  .... ...0 0111 1001 0000 .... .... .... */
+	/*
+	 * The PL220 needs to be manually configured as the hardware
+	 * doesn't report the correct sizes.
+	 * 1MB (128KB/way), 8-way associativity, event monitor and
+	 * parity enabled, ignore share bit, no force write allocate
+	 * Bits:  .... ...0 0111 1001 0000 .... .... ....
+	 */
 	l2x0_init(__io_address(REALVIEW_TC11MP_L220_BASE), 0x00790000, 0xfe000fff);
 #endif
 
Signature · 1 line
1.8.3.1
#104 lore raw

PATCH 65/75 ARM: l2c: kill L2X0_AUX_CTRL_MASK before anyone else makes use of this

In reply to Russell King - ARM Linux

L2X0_AUX_CTRL_MASK is not useful for PL310s. It would be better if people thought about their value for this rather than cargo-cult programming.

---
 arch/arm/include/asm/hardware/cache-l2x0.h | 1 -
 1 file changed, 1 deletion(-)
arch/arm/include/asm/hardware/cache-l2x0.h +0 -1
index e52584539743..3f2a9987b96c 100644
@@ -87,7 +87,6 @@
 #define L310_CACHE_ID_RTL_R3P2          0x08
 #define L310_CACHE_ID_RTL_R3P3		0x09
 
-#define L2X0_AUX_CTRL_MASK			0xc0000fff
 /* L2C auxiliary control register - bits common to L2C-210/220/310 */
 #define L2C_AUX_CTRL_WAY_SIZE_SHIFT		17
 #define L2C_AUX_CTRL_WAY_SIZE_MASK		(7 << 17)
Signature · 1 line
1.8.3.1
#105 lore raw

PATCH 66/75 ARM: l2c: print a warning with L2C-310 caches if the cache size is modified

In reply to Russell King - ARM Linux

As we have now removed all instances of the L2C-310 having its cache size "modified" via platform/SoC code, discourage new cases showing up by printing a warning.

---
 arch/arm/mm/cache-l2x0.c | 2 ++
 1 file changed, 2 insertions(+)
arch/arm/mm/cache-l2x0.c +2 -0
index 8af157031056..462675847cb7 100644
@@ -734,6 +734,8 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	/* Determine the number of ways */
 	switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
 	case L2X0_CACHE_ID_PART_L310:
+		if ((aux_val | ~aux_mask) & (L2C_AUX_CTRL_WAY_SIZE_MASK | L310_AUX_CTRL_ASSOCIATIVITY_16))
+			pr_warn("L2C: DT/platform tries to modify or specify cache size\n");
 		if (aux & (1 << 16))
 			ways = 16;
 		else
Signature · 1 line
1.8.3.1
#106 lore raw

PATCH 67/75 ARM: l2c: vexpress ca9x4: move L2 cache initialisation earlier

In reply to Russell King - ARM Linux

It is beneficial to have the L2 cache up and running earlier in the system boot. Not only will this allow for simpler code when we come to enable some features, but it also means that we get a more accurate bogomips value for the udelay() loop. Calibrating the loop with the L2 cache off, and then running with the L2 cache on is not the best idea.

---
 arch/arm/mach-vexpress/ct-ca9x4.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)
arch/arm/mach-vexpress/ct-ca9x4.c +18 -10
index 6c4ffb6c5ad8..204038ef3795 100644
@@ -45,6 +45,23 @@ static void __init ct_ca9x4_map_io(void)
 	iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
 }
 
+static void __init ca9x4_l2_init(void)
+{
+#ifdef CONFIG_CACHE_L2X0
+	void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
+
+	if (l2x0_base) {
+		/* set RAM latencies to 1 cycle for this core tile. */
+		writel(0, l2x0_base + L310_TAG_LATENCY_CTRL);
+		writel(0, l2x0_base + L310_DATA_LATENCY_CTRL);
+
+		l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
+	} else {
+		pr_err("L2C: unable to map L2 cache controller\n");
+	}
+#endif
+}
+
 #ifdef CONFIG_HAVE_ARM_TWD
 static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, A9_MPCORE_TWD, IRQ_LOCALTIMER);
 
@@ -63,6 +80,7 @@ static void __init ct_ca9x4_init_irq(void)
 	gic_init(0, 29, ioremap(A9_MPCORE_GIC_DIST, SZ_4K),
 		 ioremap(A9_MPCORE_GIC_CPU, SZ_256));
 	ca9x4_twd_init();
+	ca9x4_l2_init();
 }
 
 static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
@@ -141,16 +159,6 @@ static void __init ct_ca9x4_init(void)
 {
 	int i;
 
-#ifdef CONFIG_CACHE_L2X0
-	void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
-
-	/* set RAM latencies to 1 cycle for this core tile. */
-	writel(0, l2x0_base + L310_TAG_LATENCY_CTRL);
-	writel(0, l2x0_base + L310_DATA_LATENCY_CTRL);
-
-	l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
-#endif
-
 	for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
 		amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
 
Signature · 1 line
1.8.3.1
#107 lore raw

PATCH 68/75 ARM: l2c: add L2C-310 power control DT properties

In reply to Russell King - ARM Linux

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.

---
 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(+)
Documentation/devicetree/bindings/arm/l2cc.txt +2 -0
index b513cb8196fe..e0dd400ecea6 100644
@@ -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
arch/arm/boot/dts/imx6qdl.dtsi +2 -0
index fb28b2ecb1db..dea6ee66a01e 100644
@@ -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 {
arch/arm/boot/dts/imx6sl.dtsi +2 -0
index 28558f1aaf2d..8094ac1cedc5 100644
@@ -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 {
arch/arm/mm/cache-l2x0.c +10 -0
index 462675847cb7..655a363918f5 100644
@@ -906,6 +906,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])
@@ -932,6 +933,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 = {
Signature · 1 line
1.8.3.1
#108 lore raw

PATCH 69/75 ARM: l2c: check that DT files specify the required "cache-unified" property

In reply to Russell King - ARM Linux

This is a required property, and should always be specified.

---
 arch/arm/mm/cache-l2x0.c | 4 ++++
 1 file changed, 4 insertions(+)
arch/arm/mm/cache-l2x0.c +4 -0
index 655a363918f5..dd3de310b4ea 100644
@@ -1380,6 +1380,10 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 
 	data = of_match_node(l2x0_ids, np)->data;
 
+	/* All L2 caches are unified, so this property should be specified */
+	if (!of_property_read_bool(np, "cache-unified"))
+		pr_err("L2C: device tree omits to specify unified cache\n");
+
 	/* L2 configuration can only be changed if the cache is disabled */
 	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
 		if (data->of_parse)
Signature · 1 line
1.8.3.1
#109 lore raw

PATCH 70/75 ARM: l2c: add warnings for stuff modifying aux_ctrl register values

In reply to Russell King - ARM Linux
---
 arch/arm/mm/cache-l2x0.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)
arch/arm/mm/cache-l2x0.c +23 -4
index dd3de310b4ea..cbf036dff6d1 100644
@@ -717,7 +717,15 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 {
 	struct outer_cache_fns fns;
 	unsigned way_size_bits, ways;
-	u32 aux;
+	u32 aux, old_aux;
+
+	/*
+	 * Sanity check the aux values.  aux_mask is the bits we preserve
+	 * from reading the hardware register, and aux_val is the bits we
+	 * set.
+	 */
+	if (aux_val & aux_mask)
+		pr_alert("L2C: platform provided aux values permit register corruption.\n");
 
 	/*
 	 * It is strange to save the register state before initialisation,
@@ -726,11 +734,14 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	if (data->save)
 		data->save(l2x0_base);
 
-	aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
-
+	old_aux = aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
 	aux &= aux_mask;
 	aux |= aux_val;
 
+	if (old_aux != aux)
+		pr_warn("L2C: DT/platform modifies aux control register: 0x%08x -> 0x%08x\n",
+		        old_aux, aux);
+
 	/* Determine the number of ways */
 	switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
 	case L2X0_CACHE_ID_PART_L310:
@@ -1363,7 +1374,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;
+	u32 cache_id, old_aux;
 
 	np = of_find_matching_node(NULL, l2x0_ids);
 	if (!np)
@@ -1380,6 +1391,14 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 
 	data = of_match_node(l2x0_ids, np)->data;
 
+	old_aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
+	if (old_aux != ((old_aux & aux_mask) | aux_val)) {
+		pr_warn("L2C: platform modifies aux control register: 0x%08x -> 0x%08x\n",
+		        old_aux, (old_aux & aux_mask) | aux_val);
+	} else if (aux_mask != ~0U && aux_val != 0) {
+		pr_alert("L2C: platform provided aux values match the hardware, so have no effect.  Please remove them.\n");
+	}
+
 	/* All L2 caches are unified, so this property should be specified */
 	if (!of_property_read_bool(np, "cache-unified"))
 		pr_err("L2C: device tree omits to specify unified cache\n");
Signature · 1 line
1.8.3.1
#110 lore raw

PATCH 71/75 ARM: l2c: permit flush_all() on large flush_range() XXX Needs more thought XXX

In reply to Russell King - ARM Linux

In order to allow flush_all() to be used in normal operation, we need some locking to prevent any other cache operations being issued while a background flush_all() operation is proceeding. The read-write spinlock provides what's necessary here, but we must avoid bringing lockdep issues into this code. Hence we continue to use the raw_* operations, and use the arch read/write spinlock implementation directly.

---
 arch/arm/mm/cache-l2x0.c | 90 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 79 insertions(+), 11 deletions(-)
arch/arm/mm/cache-l2x0.c +79 -11
index cbf036dff6d1..c1750f1bf572 100644
@@ -53,6 +53,54 @@ struct l2x0_regs l2x0_saved_regs;
 /*
  * Common code for all cache controllers.
  */
+#ifdef CONFIG_SMP
+static arch_rwlock_t l2c_rw_lock = __ARCH_RW_LOCK_UNLOCKED;
+
+static unsigned long l2c_lock_exclusive(void)
+{
+	unsigned long flags;
+	raw_local_irq_save(flags);
+	arch_write_lock(&l2c_rw_lock);
+	return flags;
+}
+
+static void l2c_unlock_exclusive(unsigned long flags)
+{
+	arch_write_unlock(&l2c_rw_lock);
+	raw_local_irq_restore(flags);
+}
+
+static void l2c_lock_shared(void)
+{
+	arch_read_lock(&l2c_rw_lock);
+}
+
+static void l2c_unlock_shared(void)
+{
+	arch_read_unlock(&l2c_rw_lock);
+}
+#else
+static unsigned long l2c_lock_exclusive(void)
+{
+	unsigned long flags;
+	raw_local_irq_save(flags);
+	return flags;
+}
+
+static void l2c_unlock_exclusive(unsigned long flags)
+{
+	raw_local_irq_restore(flags);
+}
+
+static void l2c_lock_shared(void)
+{
+}
+
+static void l2c_unlock_shared(void)
+{
+}
+#endif
+
 static inline void l2c_wait_mask(void __iomem *reg, unsigned long mask)
 {
 	/* wait for cache operation by line or way to complete */
@@ -233,6 +281,7 @@ static void l2c210_inv_range(unsigned long start, unsigned long end)
 {
 	void __iomem *base = l2x0_base;
 
+	l2c_lock_shared();
 	if (start & (CACHE_LINE_SIZE - 1)) {
 		start &= ~(CACHE_LINE_SIZE - 1);
 		writel_relaxed(start, base + L2X0_CLEAN_INV_LINE_PA);
@@ -246,6 +295,7 @@ static void l2c210_inv_range(unsigned long start, unsigned long end)
 
 	__l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
 	__l2c210_cache_sync(base);
+	l2c_unlock_shared();
 }
 
 static void l2c210_clean_range(unsigned long start, unsigned long end)
@@ -253,8 +303,10 @@ static void l2c210_clean_range(unsigned long start, unsigned long end)
 	void __iomem *base = l2x0_base;
 
 	start &= ~(CACHE_LINE_SIZE - 1);
+	l2c_lock_shared();
 	__l2c210_op_pa_range(base + L2X0_CLEAN_LINE_PA, start, end);
 	__l2c210_cache_sync(base);
+	l2c_unlock_shared();
 }
 
 static void l2c210_flush_range(unsigned long start, unsigned long end)
@@ -262,23 +314,33 @@ static void l2c210_flush_range(unsigned long start, unsigned long end)
 	void __iomem *base = l2x0_base;
 
 	start &= ~(CACHE_LINE_SIZE - 1);
+	if ((end - start) >= l2x0_size) {
+		outer_cache.flush_all();
+		return;
+	}
+
+	l2c_lock_shared();
 	__l2c210_op_pa_range(base + L2X0_CLEAN_INV_LINE_PA, start, end);
 	__l2c210_cache_sync(base);
+	l2c_unlock_shared();
 }
 
 static void l2c210_flush_all(void)
 {
 	void __iomem *base = l2x0_base;
+	unsigned long flags;
 
-	BUG_ON(!irqs_disabled());
-
+	flags = l2c_lock_exclusive();
 	__l2c_op_way(base + L2X0_CLEAN_INV_WAY);
 	__l2c210_cache_sync(base);
+	l2c_unlock_exclusive(flags);
 }
 
 static void l2c210_sync(void)
 {
+	l2c_lock_shared();
 	__l2c210_cache_sync(l2x0_base);
+	l2c_unlock_shared();
 }
 
 static void l2c210_resume(void)
@@ -501,7 +563,7 @@ static void l2c310_inv_range_erratum(unsigned long start, unsigned long end)
 		unsigned long flags;
 
 		/* Erratum 588369 for both clean+invalidate operations */
-		raw_spin_lock_irqsave(&l2x0_lock, flags);
+		flags = l2c_lock_exclusive();
 		l2c_set_debug(base, 0x03);
 
 		if (start & (CACHE_LINE_SIZE - 1)) {
@@ -518,20 +580,26 @@ static void l2c310_inv_range_erratum(unsigned long start, unsigned long end)
 		}
 
 		l2c_set_debug(base, 0x00);
-		raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+		l2c_unlock_exclusive(flags);
 	}
 
+	l2c_lock_shared();
 	__l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
 	__l2c210_cache_sync(base);
+	l2c_unlock_shared();
 }
 
 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);
+	if ((end - start) >= l2x0_size) {
+		outer_cache.flush_all();
+		return;
+	}
+
+	flags = l2c_lock_exclusive();
 	while (start < end) {
 		unsigned long blk_end = start + min(end - start, 4096UL);
 
@@ -544,12 +612,12 @@ static void l2c310_flush_range_erratum(unsigned long start, unsigned long end)
 		l2c_set_debug(base, 0x00);
 
 		if (blk_end < end) {
-			raw_spin_unlock_irqrestore(lock, flags);
-			raw_spin_lock_irqsave(lock, flags);
+			l2c_unlock_exclusive(flags);
+			flags = l2c_lock_exclusive();
 		}
 	}
-	raw_spin_unlock_irqrestore(lock, flags);
 	__l2c210_cache_sync(base);
+	l2c_unlock_exclusive(flags);
 }
 
 static void l2c310_flush_all_erratum(void)
@@ -557,12 +625,12 @@ static void l2c310_flush_all_erratum(void)
 	void __iomem *base = l2x0_base;
 	unsigned long flags;
 
-	raw_spin_lock_irqsave(&l2x0_lock, flags);
+	flags = l2c_lock_exclusive();
 	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);
+	l2c_unlock_exclusive(flags);
 }
 
 static void __init l2c310_save(void __iomem *base)
Signature · 1 line
1.8.3.1
#111 lore raw

PATCH 72/75 ARM: l2c: trial at enabling some Cortex-A9 optimisations

In reply to Russell King - ARM Linux
---
 arch/arm/include/asm/hardware/cache-l2x0.h |  8 +++++
 arch/arm/mm/cache-l2x0.c                   | 51 ++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)
arch/arm/include/asm/hardware/cache-l2x0.h +8 -0
index 3f2a9987b96c..c47ac8f3b12e 100644
@@ -134,6 +134,14 @@
 
 #define L310_ADDR_FILTER_EN		1
 
+#define L310_PREFETCH_CTRL_OFFSET_MASK		0x1f
+#define L310_PREFETCH_CTRL_DBL_LINEFILL_INCR	BIT(23)
+#define L310_PREFETCH_CTRL_PREFETCH_DROP	BIT(24)
+#define L310_PREFETCH_CTRL_DBL_LINEFILL_WRAP	BIT(27)
+#define L310_PREFETCH_CTRL_DATA_PREFETCH	BIT(28)
+#define L310_PREFETCH_CTRL_INSTR_PREFETCH	BIT(29)
+#define L310_PREFETCH_CTRL_DBL_LINEFILL		BIT(30)
+
 #define L2X0_CTRL_EN			1
 
 #define L2X0_WAY_SIZE_SHIFT		3
arch/arm/mm/cache-l2x0.c +51 -0

78 lines not on this page · raw message

Signature · 1 line
1.8.3.1
#112 lore raw

PATCH 73/75 ARM: l2c: move L2 cache register saving to a more sensible location

In reply to Russell King - ARM Linux
---
 arch/arm/mm/cache-l2x0.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)
arch/arm/mm/cache-l2x0.c +9 -12
index 49155da7a8c4..700a66260f94 100644
@@ -846,13 +846,6 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	if (aux_val & aux_mask)
 		pr_alert("L2C: platform provided aux values permit register corruption.\n");
 
-	/*
-	 * 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);
-
 	old_aux = aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
 	aux &= aux_mask;
 	aux |= aux_val;
@@ -914,13 +907,17 @@ static void __init __l2c_init(const struct l2c_init_data *data,
 	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
 		data->enable(l2x0_base, aux, data->num_lock);
 
-	/* Re-read it in case some bits are reserved. */
-	aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
+	outer_cache = fns;
 
-	/* Save the value for resuming. */
-	l2x0_saved_regs.aux_ctrl = aux;
+	/*
+	 * 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);
 
-	outer_cache = fns;
+	/* Re-read it in case some bits are reserved. */
+	aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
 
 	pr_info("%s cache controller enabled, %d ways, %d kB\n",
 		data->type, ways, l2x0_size >> 10);
Signature · 1 line
1.8.3.1
#113 lore raw

PATCH 73/75 ARM: l2c: move L2 cache register saving to a more sensible location

Quoted 1 line · Russell King

EXCEPT this one patch, the series,

(on Tegra20/Toshiba AC100 and Tegra30/Beaver)

And any part which touches Tegra code,

However, this one patch causes boot failures on the Toshiba AC100, Springbank/Seaboard, and I would assume any Tegra20 system. I haven't investigated what the problem is; do you need me to and/or have any clues?

Here's the boot spew re: caches:

Quoted 9 lines
[    0.000000] L2C: platform modifies aux control register: 0x02080000 -> 0x3e480001
[    0.000000] L2C: DT/platform modifies aux control register: 0x02080000 -> 0x3e480001
[    0.000000] L2C-310 errata 727915 769419 enabled
[    0.000000] L2C-310 enabling early BRESP for Cortex-A9
[    0.000000] L2C-310: enabling full line of zeros but not enabled in Cortex-A9
[    0.000000] L2C-310 ID prefetch enabled, offset 1 lines
[    0.000000] L2C-310: dynamic clock gating disabled, standby mode disabled
[    0.000000] L2C-310 cache controller enabled, 8 ways, 1024 kB
[    0.000000] L2C-310: CACHE_ID 0x410000c4, AUX_CTRL 0x7e480001

The system simply hangs pretty late in the boot process from the AC100:

Quoted 31 lines
[    1.640426] usbhid: USB HID core driver
[    1.655176] nvec 7000c500.nvec: ec firmware version 01.20.00 / f9
[    1.670832] input: nvec keyboard as /devices/soc0/7000c500.nvec/nvec-kbd.0/input/input1
[    1.696465] tegra-alc5632 sound.7: alc5632-hifi <-> 70002800.i2s mapping ok
[    1.886296] psmouse serio0: Failed to reset mouse on nvec
[    1.908126] mmc0: new high speed SD card at address 0002
[    1.914613] mmcblk0: mmc0:0002 00000 1.86 GiB 
[    1.938532]  mmcblk0: p1
[    1.982522] mmc1: new high speed MMC card at address 0001
[    1.991327] mmcblk1: mmc1:0001 SEM08G 7.39 GiB 
[    1.997179] mmcblk1boot0: mmc1:0001 SEM08G partition 1 1.00 MiB
[    2.004356] mmcblk1boot1: mmc1:0001 SEM08G partition 2 1.00 MiB
[    2.015144]  mmcblk1: unknown partition table
[    2.026400]  mmcblk1boot1: unknown partition table
[    2.037914]  mmcblk1boot0: unknown partition table
[    2.224409] input: Compal PAZ00 Headset Jack as /devices/soc0/sound.7/sound/card0/input2
[    2.236688] TCP: cubic registered
[    2.241126] NET: Registered protocol family 10
[    2.251831] mip6: Mobile IPv6
[    2.254839] sit: IPv6 over IPv4 tunneling driver
[    2.268383] NET: Registered protocol family 17
[    2.272985] NET: Registered protocol family 15
[    2.277800] Bluetooth: RFCOMM socket layer initialized
[    2.283016] Bluetooth: RFCOMM ver 1.11
[    2.287034] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[    2.292435] Bluetooth: BNEP socket layer initialized
[    2.297472] Bluetooth: HIDP (Human Interface Emulation) ver 1.2
[    2.303474] Bluetooth: HIDP socket layer initialized
[    2.313364] rfkill_gpio rfkill_gpio: wifi_rfkill device registered.
[    2.319791] Registering SWP/SWPB emulation handler
[    2.330586] +3VS,vdd_pnl: 3300 mV 
Quoted 8 lines
[    2.335028] tegra-dc 54200000.dc: failed to probe RGB output: -517
[    2.341413] platform 54200000.dc: Driver tegra-dc requests probe deferral
[    2.352402] tegra-ehci c5000000.usb: EHCI Host Controller
[    2.357982] tegra-ehci c5000000.usb: new USB bus registered, assigned bus number 1
[    2.366221] tegra-ehci c5000000.usb: irq 52, io mem 0xc5000000
[    2.386343] tegra-ehci c5000000.usb: USB 2.0 started, EHCI 1.00
[    2.397034] hub 1-0:1.0: USB hub found
[    2.400932] hub 1-0:1.0: 1 port detected

<<hang>>

... and from Seaboard/Springbank:

Quoted 4 lines
[    2.715321] VFS: Mounted root (ext3 filesystem) on device 179:1.
[    2.720970] devtmpfs: mounted
[    2.721336] Freeing unused kernel memory: 264K (c07be000 - c0800000)
[    2.775391] usb 2-1: new low-speed USB device number 2 using tegra-ehci

...

Quoted 4 lines
[    9.515357] init: idmapd main process (525) terminated with status 1
[    9.515572] init: idmapd respawning too fast, stopped
[   11.978245] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
[   12.097190] asix 3-1:1.0 eth0: link down
#114 lore raw

PATCH 73/75 ARM: l2c: move L2 cache register saving to a more sensible location

Quoted 5 lines · Stephen Warren
Quoted 1 line · Russell King

EXCEPT this one patch, the series,

Quoted 8 lines

(on Tegra20/Toshiba AC100 and Tegra30/Beaver)

And any part which touches Tegra code,

However, this one patch causes boot failures on the Toshiba AC100, Springbank/Seaboard, and I would assume any Tegra20 system. I haven't investigated what the problem is; do you need me to and/or have any clues?

Ah, disabling CONFIG_CPU_IDLE "fixes" this.

#115 lore raw

PATCH 73/75 ARM: l2c: move L2 cache register saving to a more sensible location

Quoted 8 lines · Stephen Warren
Quoted 7 lines · Stephen Warren
Quoted 1 line · Russell King

EXCEPT this one patch, the series,

(on Tegra20/Toshiba AC100 and Tegra30/Beaver)

Quoted 8 lines
Quoted 6 lines

And any part which touches Tegra code,

However, this one patch causes boot failures on the Toshiba AC100, Springbank/Seaboard, and I would assume any Tegra20 system. I haven't investigated what the problem is; do you need me to and/or have any clues?

Ah, disabling CONFIG_CPU_IDLE "fixes" this.

Still brings up the question of what's going on here. Another thing could be that enabling BRESP is causing you problems. You could try disabling that code too, though why that would happen only with CPU IDLE I'm not sure.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#116 lore raw

PATCH 73/75 ARM: l2c: move L2 cache register saving to a more sensible location

Quoted 16 lines · Russell King - ARM Linux
Quoted 15 lines · Stephen Warren
Quoted 13 lines · Stephen Warren
Quoted 1 line · Russell King

EXCEPT this one patch, the series,

(on Tegra20/Toshiba AC100 and Tegra30/Beaver)

And any part which touches Tegra code,

However, this one patch causes boot failures on the Toshiba AC100, Springbank/Seaboard, and I would assume any Tegra20 system. I haven't investigated what the problem is; do you need me to and/or have any clues?

Quoted 6 lines
Quoted 1 line

Ah, disabling CONFIG_CPU_IDLE "fixes" this.

Still brings up the question of what's going on here. Another thing could be that enabling BRESP is causing you problems. You could try disabling that code too, though why that would happen only with CPU IDLE I'm not sure.

The problem also affects suspend/resume. Disabling CPU_IDLE simply removes one case where the CPUs gets power-cycled, but doesn't solve the suspend/resume issue.

Anyway, this patch removes the following code:

	/* Save the value for resuming. */
	l2x0_saved_regs.aux_ctrl = aux;

Was that intentional? Perhaps the call to data->save() should do this now?

Anyway, if I put that code back, in any of the following 3 places, then boot, CPU hotplug, and suspend/resume all work OK with your series:

1) Right after:

	outer_cache = fns;

2) Right after:

	if (data->save)
		data->save(l2x0_base);

3) Right after:

	aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
#117 lore raw

PATCH 73/75 ARM: l2c: move L2 cache register saving to a more sensible location

Quoted 28 lines · Stephen Warren
Quoted 16 lines · Russell King - ARM Linux
Quoted 15 lines · Stephen Warren
Quoted 13 lines · Stephen Warren
Quoted 1 line · Russell King

EXCEPT this one patch, the series,

(on Tegra20/Toshiba AC100 and Tegra30/Beaver)

And any part which touches Tegra code,

However, this one patch causes boot failures on the Toshiba AC100, Springbank/Seaboard, and I would assume any Tegra20 system. I haven't investigated what the problem is; do you need me to and/or have any clues?

Quoted 6 lines
Quoted 1 line

Ah, disabling CONFIG_CPU_IDLE "fixes" this.

Still brings up the question of what's going on here. Another thing could be that enabling BRESP is causing you problems. You could try disabling that code too, though why that would happen only with CPU IDLE I'm not sure.

The problem also affects suspend/resume. Disabling CPU_IDLE simply removes one case where the CPUs gets power-cycled, but doesn't solve the suspend/resume issue.

Quoted 6 lines

Anyway, this patch removes the following code:

	/* Save the value for resuming. */
	l2x0_saved_regs.aux_ctrl = aux;

Was that intentional? Perhaps the call to data->save() should do this now?

Good catch.

It should... this is a nice illustration why I consider the existing code to be unmaintainable - some "save" implementations save the aux control register themselves, others do not.

Yes, making everyone save it is the most logical solution, because then we have a hook which does what it says it does, rather than having that functionality spread across several separate functions.

This is my preferred solution (patch on top of this series.) Will be merged into the series shortly. Thanks for finding this.

 arch/arm/mm/cache-l2x0.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
arch/arm/mm/cache-l2x0.c +13 -0
index f718032cf9a0..e2f1ad674647 100644
@@ -250,6 +250,11 @@ static void l2x0_disable(void)
 	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
+static void l2c_save(void __iomem *base)
+{
+	l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
+}
+
 /*
  * L2C-210 specific code.
  *
@@ -357,6 +362,7 @@ static const struct l2c_init_data l2c210_data __initconst = {
 	.way_size_0 = SZ_8K,
 	.num_lock = 1,
 	.enable = l2c_enable,
+	.save = l2c_save,
 	.outer_cache = {
 		.inv_range = l2c210_inv_range,
 		.clean_range = l2c210_clean_range,
@@ -501,6 +507,7 @@ static const struct l2c_init_data l2c220_data = {
 	.way_size_0 = SZ_8K,
 	.num_lock = 1,
 	.enable = l2c_enable,
+	.save = l2c_save,
 	.outer_cache = {
 		.inv_range = l2c220_inv_range,
 		.clean_range = l2c220_clean_range,
@@ -638,6 +645,8 @@ static void __init l2c310_save(void __iomem *base)
 {
 	unsigned revision;
 
+	l2c_save(base);
+
 	l2x0_saved_regs.tag_latency = readl_relaxed(base +
 		L310_TAG_LATENCY_CTRL);
 	l2x0_saved_regs.data_latency = readl_relaxed(base +
@@ -1010,6 +1019,7 @@ static const struct l2c_init_data of_l2c210_data __initconst = {
 	.num_lock = 1,
 	.of_parse = l2x0_of_parse,
 	.enable = l2c_enable,
+	.save = l2c_save,
 	.outer_cache = {
 		.inv_range   = l2c210_inv_range,
 		.clean_range = l2c210_clean_range,
@@ -1027,6 +1037,7 @@ static const struct l2c_init_data of_l2c220_data __initconst = {
 	.num_lock = 1,
 	.of_parse = l2x0_of_parse,
 	.enable = l2c_enable,
+	.save = l2c_save,
 	.outer_cache = {
 		.inv_range   = l2c220_inv_range,
 		.clean_range = l2c220_clean_range,
@@ -1440,6 +1451,8 @@ static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
 
 static void __init tauros3_save(void __iomem *base)
 {
+	l2c_save(base);
+
 	l2x0_saved_regs.aux2_ctrl =
 		readl_relaxed(base + TAUROS3_AUX2_CTRL);
 	l2x0_saved_regs.prefetch_ctrl =
Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#118 lore raw

PATCH 73/75 ARM: l2c: move L2 cache register saving to a more sensible location

Quoted 5 lines · Russell King - ARM Linux
Quoted 4 lines · Stephen Warren
Quoted 3 lines · Russell King - ARM Linux
Quoted 2 lines · Stephen Warren
Quoted 1 line · Stephen Warren

On 03/28/2014 09:20 AM, Russell King wrote:

...

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

However, this one patch causes boot failures on the Toshiba AC100, Springbank/Seaboard, and I would assume any Tegra20 system. I haven't investigated what the problem is; do you need me to and/or have any clues?

...

Quoted 4 lines
Quoted 4 lines

Anyway, this patch removes the following code:

	/* Save the value for resuming. */
	l2x0_saved_regs.aux_ctrl = aux;

...

Quoted 7 lines

This is my preferred solution (patch on top of this series.) Will be merged into the series shortly. Thanks for finding this.

 arch/arm/mm/cache-l2x0.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
arch/arm/mm/cache-l2x0.c +0 -0

...

#119 lore raw

PATCH 73/75 ARM: l2c: move L2 cache register saving to a more sensible location

In reply to Stephen Warren
Quoted 5 lines · Stephen Warren
Quoted 1 line · Russell King

EXCEPT this one patch, the series,

Quoted 8 lines

(on Tegra20/Toshiba AC100 and Tegra30/Beaver)

And any part which touches Tegra code,

However, this one patch causes boot failures on the Toshiba AC100, Springbank/Seaboard, and I would assume any Tegra20 system. I haven't investigated what the problem is; do you need me to and/or have any clues?

My first thought is... try reverting the
"l2c: permit flush_all() on large flush_range()" commit and see what effect that may have - that isn't a perfected patch (hence the XXX in the summary line).

I'm hoping that we don't have people doing large dma_alloc_coherent() in interrupt context - if they are, that could lead to a silent deadlock (even with lockdep enabled.) Large being defined by "size of your L2 cache or larger".

If we are going to hit that kind of sillyness, then we're just going to have to pay the price of invalidating large blocks of memory on a per- cache line basis across the full size - yes, this means it will suck, people allocating frame buffers using CMA will complain, but then we really should not be doing such large allocations from IRQ context.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#120 lore raw

PATCH 74/75 ARM: l2c: always enable low power modes

In reply to Russell King - ARM Linux

Always enable the L2C low power modes on L2C-310 R3P0 and newer parts.

---
 Documentation/devicetree/bindings/arm/l2cc.txt |  2 --
 arch/arm/mm/cache-l2x0.c                       | 22 ++++++++++++----------
 2 files changed, 12 insertions(+), 12 deletions(-)
Documentation/devicetree/bindings/arm/l2cc.txt +0 -2
index e0dd400ecea6..b513cb8196fe 100644
@@ -40,8 +40,6 @@ 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
arch/arm/mm/cache-l2x0.c +12 -10
index 700a66260f94..b1f103d402be 100644
@@ -752,6 +752,18 @@ static void __init l2c310_enable(void __iomem *base, u32 aux, unsigned num_lock)
 			1 + (prefetch & L310_PREFETCH_CTRL_OFFSET_MASK));
 	}
 
+	/* r3p0 or later has power control register */
+	if (rev >= L310_CACHE_ID_RTL_R3P0) {
+		u32 power_ctrl;
+
+		l2c_write_sec(L310_DYNAMIC_CLK_GATING_EN | L310_STNDBY_MODE_EN,
+			      base, L310_POWER_CTRL);
+		power_ctrl = readl_relaxed(base + L310_POWER_CTRL);
+		pr_info("L2C-310: dynamic clock gating %sabled, standby mode %sabled\n",
+			power_ctrl & L310_DYNAMIC_CLK_GATING_EN ? "en" : "dis",
+			power_ctrl & L310_STNDBY_MODE_EN ? "en" : "dis");
+	}
+
 	l2c_enable(base, aux, num_lock);
 
 	if (aux & L310_AUX_CTRL_FULL_LINE_ZERO) {
@@ -1033,7 +1045,6 @@ 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])
@@ -1060,15 +1071,6 @@ 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 = {
Signature · 1 line
1.8.3.1
#121 lore raw

PATCH 74/75 ARM: l2c: always enable low power modes

Quoted 1 line · Russell King

Always enable the L2C low power modes on L2C-310 R3P0 and newer parts.

I assume you want to squash this with patch 68/75? Or you are still debating whether we want to do this or not? Given that it is r3px only, that should greatly reduce any chance of breakage to newer platforms.

Rob

Quoted 70 lines
---
 Documentation/devicetree/bindings/arm/l2cc.txt |  2 --
 arch/arm/mm/cache-l2x0.c                       | 22 ++++++++++++----------
 2 files changed, 12 insertions(+), 12 deletions(-)
Documentation/devicetree/bindings/arm/l2cc.txt +0 -2
index e0dd400ecea6..b513cb8196fe 100644
@@ -40,8 +40,6 @@ 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
arch/arm/mm/cache-l2x0.c +12 -11
index 700a66260f94..b1f103d402be 100644
@@ -752,6 +752,18 @@ static void __init l2c310_enable(void __iomem *base, u32 aux, unsigned num_lock)
                        1 + (prefetch & L310_PREFETCH_CTRL_OFFSET_MASK));
        }
 
+       /* r3p0 or later has power control register */
+       if (rev >= L310_CACHE_ID_RTL_R3P0) {
+               u32 power_ctrl;
+
+               l2c_write_sec(L310_DYNAMIC_CLK_GATING_EN | L310_STNDBY_MODE_EN,
+                             base, L310_POWER_CTRL);
+               power_ctrl = readl_relaxed(base + L310_POWER_CTRL);
+               pr_info("L2C-310: dynamic clock gating %sabled, standby mode %sabled\n",
+                       power_ctrl & L310_DYNAMIC_CLK_GATING_EN ? "en" : "dis",
+                       power_ctrl & L310_STNDBY_MODE_EN ? "en" : "dis");
+       }
+
        l2c_enable(base, aux, num_lock);
 
        if (aux & L310_AUX_CTRL_FULL_LINE_ZERO) {
@@ -1033,7 +1045,6 @@ 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])
@@ -1060,15 +1071,6 @@ 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

#122 lore raw

PATCH 74/75 ARM: l2c: always enable low power modes

Quoted 8 lines · Rob Herring
Quoted 1 line · Russell King

Always enable the L2C low power modes on L2C-310 R3P0 and newer parts.

I assume you want to squash this with patch 68/75? Or you are still debating whether we want to do this or not? Given that it is r3px only, that should greatly reduce any chance of breakage to newer platforms.

I will eventually - I've kept it separate for the time being to give more options. Let's see how people get on with it - it'll be running through Olof's builder later today, and there's some other people wanting to take it for a spin.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#123 lore raw

PATCH 74/75 ARM: l2c: always enable low power modes

Quoted 10 lines · Russell King - ARM Linux
Quoted 8 lines · Rob Herring
Quoted 1 line · Russell King

Always enable the L2C low power modes on L2C-310 R3P0 and newer parts.

I assume you want to squash this with patch 68/75? Or you are still debating whether we want to do this or not? Given that it is r3px only, that should greatly reduce any chance of breakage to newer platforms.

Quoted 4 lines

I will eventually - I've kept it separate for the time being to give more options. Let's see how people get on with it - it'll be running through Olof's builder later today, and there's some other people wanting to take it for a spin.

A while back I suggested altering those bits, but that was turned down:
https://lkml.org/lkml/2013/3/1/350

Are there any numbers available on how enabling these features impacts the system? I'm a little bit concerned of always enabling them unconditionally, in case it increases latency for some use cases. I think I'd prefer the DT approach, unless the impact is reported to be negligible - which it likely is, I guess.

Thanks,
S?ren

#124 lore raw

PATCH 74/75 ARM: l2c: always enable low power modes

Quoted 11 lines · S?ren Brinkmann
Quoted 10 lines · Russell King - ARM Linux
Quoted 8 lines · Rob Herring
Quoted 1 line · Russell King

Always enable the L2C low power modes on L2C-310 R3P0 and newer parts.

I assume you want to squash this with patch 68/75? Or you are still debating whether we want to do this or not? Given that it is r3px only, that should greatly reduce any chance of breakage to newer platforms.

Quoted 7 lines
Quoted 4 lines

I will eventually - I've kept it separate for the time being to give more options. Let's see how people get on with it - it'll be running through Olof's builder later today, and there's some other people wanting to take it for a spin.

A while back I suggested altering those bits, but that was turned down:
https://lkml.org/lkml/2013/3/1/350

As I said yesterday, please use a different archive website, preferably one which works. lkml.org has been broken in various ways for a couple of days now, and quoting unreachable URLs isn't useful for discussion purposes.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#125 lore raw

PATCH 74/75 ARM: l2c: always enable low power modes

Quoted 17 lines · Russell King - ARM Linux
Quoted 16 lines · S?ren Brinkmann
Quoted 14 lines · Russell King - ARM Linux
Quoted 8 lines · Rob Herring
Quoted 1 line · Russell King

Always enable the L2C low power modes on L2C-310 R3P0 and newer parts.

I assume you want to squash this with patch 68/75? Or you are still debating whether we want to do this or not? Given that it is r3px only, that should greatly reduce any chance of breakage to newer platforms.

I will eventually - I've kept it separate for the time being to give more options. Let's see how people get on with it - it'll be running through Olof's builder later today, and there's some other people wanting to take it for a spin.

Quoted 7 lines
Quoted 2 lines

A while back I suggested altering those bits, but that was turned down:
https://lkml.org/lkml/2013/3/1/350

As I said yesterday, please use a different archive website, preferably one which works. lkml.org has been broken in various ways for a couple of days now, and quoting unreachable URLs isn't useful for discussion purposes.

It worked when I pulled the link. Anyway, the thread at gmane:
http://thread.gmane.org/gmane.linux.kernel/1449544/focus=1450475

S?ren

#126 lore raw

PATCH 75/75 ARM: l2c: imx: remove direct write to power control register

In reply to Russell King - ARM Linux

Now that we handle this in core code, we don't need platforms enabling the low power modes directly.

---
 arch/arm/mach-imx/system.c | 2 --
 1 file changed, 2 deletions(-)
arch/arm/mach-imx/system.c +0 -2
index 59013a81107b..3b0733edb68c 100644
@@ -138,8 +138,6 @@ void __init imx_init_l2cache(void)
 	if (cpu_is_imx6q())
 		val &= ~(1 << 30 | 1 << 23);
 	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);
Signature · 1 line
1.8.3.1
#128 lore raw

PATCH 75/75 ARM: l2c: imx: remove direct write to power control register

Quoted 9 lines · Shawn Guo
Quoted 4 lines · Russell King

Now that we handle this in core code, we don't need platforms enabling the low power modes directly.

For patches that I'm on Cc:

Not a particularly helpful way to send an ack, because I don't have a record other than the emails on the mailing list of which to add that to... I'll do my best, but I'm not going to make any guarantees of getting that right.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#129 lore raw

PATCH 75/75 ARM: l2c: imx: remove direct write to power control register

Quoted 7 lines · Russell King - ARM Linux
Quoted 6 lines · Shawn Guo
Quoted 4 lines · Russell King

Now that we handle this in core code, we don't need platforms enabling the low power modes directly.

Quoted 8 lines
Quoted 3 lines

For patches that I'm on Cc:

Not a particularly helpful way to send an ack, because I don't have a record other than the emails on the mailing list of which to add that to... I'll do my best, but I'm not going to make any guarantees of getting that right.

Right, it should be much easier for me to find them out than you. They are #5, #49, #68 and #75.

Shawn

#130 lore raw

cover l2c series - Olof's boot failures

In reply to Russell King - ARM Linux
Quoted 7 lines · Russell King - ARM Linux

This is another posting of the L2 cache controller series. I'm not planning for this for the upcoming merge window, but the one after, as people need to test it and still need to feed back to me on various issues. Hence, this is not a finalised series.

There are still various issues which I've raised, and have had no feedback on.

Olof's builder shows failures with this for:

    capri        multi_v7_defconfig            :        FAILED  1:03.10
    seaboard     tegra_defconfig               :        FAILED  1:29.70
    seaboard     multi_v7_defconfig            :        FAILED  1:26.35

I have no way to debug these failures.

However, strangely:

capri bcm_defconfig : passed 0:42.83

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#131 lore raw

cover l2c series - Olof's boot failures

Quoted 15 lines · Russell King
Quoted 7 lines · Russell King - ARM Linux

This is another posting of the L2 cache controller series. I'm not planning for this for the upcoming merge window, but the one after, as people need to test it and still need to feed back to me on various issues. Hence, this is not a finalised series.

There are still various issues which I've raised, and have had no feedback on.

Olof's builder shows failures with this for:

    capri        multi_v7_defconfig            :        FAILED  1:03.10
    seaboard     tegra_defconfig               :        FAILED  1:29.70
    seaboard     multi_v7_defconfig            :        FAILED  1:26.35
Quoted 5 lines

I have no way to debug these failures.

However, strangely:

capri bcm_defconfig : passed 0:42.83

This is fixed by the check cpu id for pj4 patch:
http://www.spinics.net/lists/arm-kernel/msg316431.html

updated version:
http://www.spinics.net/lists/arm-kernel/msg317283.html
http://www.spinics.net/lists/arm-kernel/msg317284.html

bcm_defconfig is fine because ARCH_DOVE isn't enabled

-Matt

#132 lore raw

cover l2c series

In reply to Russell King - ARM Linux

Hi Russell,

Quoted 9 lines · Russell King - ARM Linux

This is another posting of the L2 cache controller series. I'm not planning for this for the upcoming merge window, but the one after, as people need to test it and still need to feed back to me on various issues. Hence, this is not a finalised series.

There are still various issues which I've raised, and have had no feedback on.

This series is being posted with Cc's on the individual patches.

I just want to also point you that we have sent EDAC support for pl310 which will be good to have it for L2.
[RFC PATCH] EDAC support for ARM PL310 cache controller [RFC PATCH] edac: add support for ARM PL310 L2 cache parity
http://lkml.org/lkml/2014/3/2/85
http://lkml.org/lkml/2014/3/2/87

None has reviewed it yet but will be good to add it when you do this huge L2 cleanup.

Thanks,
Michal

Signature · 14 lines
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140403/bcd5ee5b/attachment.sig>
#133 lore raw

cover l2c series

Quoted 11 lines · Michal Simek

Hi Russell,

Quoted 8 lines · Russell King - ARM Linux

This is another posting of the L2 cache controller series. I'm not planning for this for the upcoming merge window, but the one after, as people need to test it and still need to feed back to me on various issues. Hence, this is not a finalised series.

There are still various issues which I've raised, and have had no feedback on.

Quoted 8 lines
Quoted 1 line

This series is being posted with Cc's on the individual patches.

I just want to also point you that we have sent EDAC support for pl310 which will be good to have it for L2.
[RFC PATCH] EDAC support for ARM PL310 cache controller [RFC PATCH] edac: add support for ARM PL310 L2 cache parity
http://lkml.org/lkml/2014/3/2/85
http://lkml.org/lkml/2014/3/2/87

As seems to be the norm, lkml.org is broken... please find a different archive instead. :)

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#134 lore raw

cover l2c series

Quoted 21 lines · Russell King - ARM Linux
Quoted 11 lines · Michal Simek

Hi Russell,

Quoted 8 lines · Russell King - ARM Linux

This is another posting of the L2 cache controller series. I'm not planning for this for the upcoming merge window, but the one after, as people need to test it and still need to feed back to me on various issues. Hence, this is not a finalised series.

There are still various issues which I've raised, and have had no feedback on.

Quoted 8 lines
Quoted 1 line

This series is being posted with Cc's on the individual patches.

I just want to also point you that we have sent EDAC support for pl310 which will be good to have it for L2.
[RFC PATCH] EDAC support for ARM PL310 cache controller [RFC PATCH] edac: add support for ARM PL310 L2 cache parity
http://lkml.org/lkml/2014/3/2/85
http://lkml.org/lkml/2014/3/2/87

Quoted 3 lines

As seems to be the norm, lkml.org is broken... please find a different archive instead. :)

Here it is:
http://lkml.iu.edu/hypermail/linux/kernel/1403.0/00250.html
http://lkml.iu.edu/hypermail/linux/kernel/1403.0/00251.html

Thanks,
Michal

Signature · 14 lines
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140404/324e6cfd/attachment.sig>
#135 lore raw

cover l2c series

Quoted 22 lines · Michal Simek
Quoted 21 lines · Russell King - ARM Linux
Quoted 19 lines · Michal Simek

Hi Russell,

Quoted 9 lines · Russell King - ARM Linux

This is another posting of the L2 cache controller series. I'm not planning for this for the upcoming merge window, but the one after, as people need to test it and still need to feed back to me on various issues. Hence, this is not a finalised series.

There are still various issues which I've raised, and have had no feedback on.

This series is being posted with Cc's on the individual patches.

I just want to also point you that we have sent EDAC support for pl310 which will be good to have it for L2.
[RFC PATCH] EDAC support for ARM PL310 cache controller [RFC PATCH] edac: add support for ARM PL310 L2 cache parity
http://lkml.org/lkml/2014/3/2/85
http://lkml.org/lkml/2014/3/2/87

Quoted 7 lines
Quoted 3 lines

As seems to be the norm, lkml.org is broken... please find a different archive instead. :)

Here it is:
http://lkml.iu.edu/hypermail/linux/kernel/1403.0/00250.html
http://lkml.iu.edu/hypermail/linux/kernel/1403.0/00251.html

A number of comments immediately spring to mind:

- the use of writel/readl rather than their ARM specific _relaxed versions is not a good idea: using the standard macros will result in another write due to the barrier.

- a driver coupled to the arm,pl310-cache compatible for this which is distinctly separate from the main "driver" is probably a bad idea. what if we want our existing l2 stuff to couple into the driver model to expose some properties at a later date (eg, maybe to deal with stuff like the power management settings?) For example, it may be that we want to expose the prefetch offset so that people can easily play with the value to determine the correct tuning for their workload.

- casting to void * is unnecessary for devm_request_irq()

- you really ought to check whether the interrupt registers are accessible in non-secure mode - and I guess if we're going to have this driver, we should have the L2 cache enabling code always try to set the NS access bit for the interrupt registers.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#136 lore raw

cover l2c series

Quoted 31 lines · Russell King - ARM Linux
Quoted 22 lines · Michal Simek
Quoted 21 lines · Russell King - ARM Linux
Quoted 19 lines · Michal Simek

Hi Russell,

Quoted 9 lines · Russell King - ARM Linux

This is another posting of the L2 cache controller series. I'm not planning for this for the upcoming merge window, but the one after, as people need to test it and still need to feed back to me on various issues. Hence, this is not a finalised series.

There are still various issues which I've raised, and have had no feedback on.

This series is being posted with Cc's on the individual patches.

I just want to also point you that we have sent EDAC support for pl310 which will be good to have it for L2.
[RFC PATCH] EDAC support for ARM PL310 cache controller [RFC PATCH] edac: add support for ARM PL310 L2 cache parity
http://lkml.org/lkml/2014/3/2/85
http://lkml.org/lkml/2014/3/2/87

Quoted 7 lines
Quoted 3 lines

As seems to be the norm, lkml.org is broken... please find a different archive instead. :)

Here it is:
http://lkml.iu.edu/hypermail/linux/kernel/1403.0/00250.html
http://lkml.iu.edu/hypermail/linux/kernel/1403.0/00251.html

Quoted 5 lines

A number of comments immediately spring to mind:

- the use of writel/readl rather than their ARM specific _relaxed versions is not a good idea: using the standard macros will result in another write due to the barrier.

Not a problem to use _relaxed version.

My concern about using _relaxed version is that everybody is still saying use COMPILE_TEST or just enable drivers for all archs. With using _relaxed IO helper function it is ending up in compilation problems for i386.
Last time with our i2c driver.
http://www.spinics.net/lists/arm-kernel/msg320255.html

It means shouldn't be that _relaxed version listed in asm-generic/io.h or just limit it to use this driver just for ARM like we have done for this edac driver.

Quoted 7 lines

- a driver coupled to the arm,pl310-cache compatible for this which is distinctly separate from the main "driver" is probably a bad idea. what if we want our existing l2 stuff to couple into the driver model to expose some properties at a later date (eg, maybe to deal with stuff like the power management settings?) For example, it may be that we want to expose the prefetch offset so that people can easily play with the value to determine the correct tuning for their workload.

We choose that name for starting to discuss this how to do it better. We could use zynq-edac-l2 or zynq-edac-r3p2, etc version.

Moving it to driver model will be perfect. Also considering to move this driver out or arch/arm is a good idea.

Quoted 1 line

- casting to void * is unnecessary for devm_request_irq()

ok. We will fix it.

Quoted 5 lines

- you really ought to check whether the interrupt registers are accessible in non-secure mode - and I guess if we're going to have this driver, we should have the L2 cache enabling code always try to set the NS access bit for the interrupt registers.

Our kernel for historical reasons runs in secure mode that's why I don't know if this will work for us but easy to try.

Thanks,
Michal

Signature · 14 lines
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140407/16ebc6cf/attachment-0001.sig>
#137 lore raw

cover l2c series

Quoted 47 lines · Michal Simek
Quoted 31 lines · Russell King - ARM Linux
Quoted 22 lines · Michal Simek
Quoted 21 lines · Russell King - ARM Linux
Quoted 19 lines · Michal Simek

Hi Russell,

Quoted 9 lines · Russell King - ARM Linux

This is another posting of the L2 cache controller series. I'm not planning for this for the upcoming merge window, but the one after, as people need to test it and still need to feed back to me on various issues. Hence, this is not a finalised series.

There are still various issues which I've raised, and have had no feedback on.

This series is being posted with Cc's on the individual patches.

I just want to also point you that we have sent EDAC support for pl310 which will be good to have it for L2.
[RFC PATCH] EDAC support for ARM PL310 cache controller [RFC PATCH] edac: add support for ARM PL310 L2 cache parity
http://lkml.org/lkml/2014/3/2/85
http://lkml.org/lkml/2014/3/2/87

Quoted 7 lines
Quoted 3 lines

As seems to be the norm, lkml.org is broken... please find a different archive instead. :)

Here it is:
http://lkml.iu.edu/hypermail/linux/kernel/1403.0/00250.html
http://lkml.iu.edu/hypermail/linux/kernel/1403.0/00251.html

Quoted 5 lines

A number of comments immediately spring to mind:

- the use of writel/readl rather than their ARM specific _relaxed versions is not a good idea: using the standard macros will result in another write due to the barrier.

Not a problem to use _relaxed version.

My concern about using _relaxed version is that everybody is still saying use COMPILE_TEST or just enable drivers for all archs. With using _relaxed IO helper function it is ending up in compilation problems for i386.
Last time with our i2c driver.
http://www.spinics.net/lists/arm-kernel/msg320255.html

Quoted 3 lines

It means shouldn't be that _relaxed version listed in asm-generic/io.h or just limit it to use this driver just for ARM like we have done for this edac driver.

As I said, it's a requirement for L2C code, because otherwise you end up with every IO access to the L2C also invoking a second IO access to the device.

Quoted 10 lines
Quoted 7 lines

- a driver coupled to the arm,pl310-cache compatible for this which is distinctly separate from the main "driver" is probably a bad idea. what if we want our existing l2 stuff to couple into the driver model to expose some properties at a later date (eg, maybe to deal with stuff like the power management settings?) For example, it may be that we want to expose the prefetch offset so that people can easily play with the value to determine the correct tuning for their workload.

We choose that name for starting to discuss this how to do it better. We could use zynq-edac-l2 or zynq-edac-r3p2, etc version.

I'm not talking about the compatible name. I'm certainly not suggesting that you should describe the L2 as two separate devices in DT. I'm saying that this should appear as one _single_ driver for the entire device.

Quoted 2 lines

Our kernel for historical reasons runs in secure mode that's why I don't know if this will work for us but easy to try.

Sorry, this kind of short sightedness is unacceptable. This is the "I'm only going to solve the problem immediately in front of my nose" syndrome which is currently causing me to end up rewriting lots of code in the kernel right now.

What you're doing is similar to this:
https://twitter.com/denny/status/452867158964326400/photo/1

You're solving the problem you have without thinking about the consequences for others.

Of course other people are going to want to use this, and as the L2C controllers are generic, so any code which adds support for EDAC support should also be generic and not written with a single platform in mind.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#138 lore raw

cover l2c series

Quoted 48 lines · Russell King - ARM Linux
Quoted 47 lines · Michal Simek
Quoted 31 lines · Russell King - ARM Linux
Quoted 22 lines · Michal Simek
Quoted 21 lines · Russell King - ARM Linux
Quoted 19 lines · Michal Simek

Hi Russell,

Quoted 9 lines · Russell King - ARM Linux

This is another posting of the L2 cache controller series. I'm not planning for this for the upcoming merge window, but the one after, as people need to test it and still need to feed back to me on various issues. Hence, this is not a finalised series.

There are still various issues which I've raised, and have had no feedback on.

This series is being posted with Cc's on the individual patches.

I just want to also point you that we have sent EDAC support for pl310 which will be good to have it for L2.
[RFC PATCH] EDAC support for ARM PL310 cache controller [RFC PATCH] edac: add support for ARM PL310 L2 cache parity
http://lkml.org/lkml/2014/3/2/85
http://lkml.org/lkml/2014/3/2/87

Quoted 7 lines
Quoted 3 lines

As seems to be the norm, lkml.org is broken... please find a different archive instead. :)

Here it is:
http://lkml.iu.edu/hypermail/linux/kernel/1403.0/00250.html
http://lkml.iu.edu/hypermail/linux/kernel/1403.0/00251.html

Quoted 5 lines

A number of comments immediately spring to mind:

- the use of writel/readl rather than their ARM specific _relaxed versions is not a good idea: using the standard macros will result in another write due to the barrier.

Not a problem to use _relaxed version.

My concern about using _relaxed version is that everybody is still saying use COMPILE_TEST or just enable drivers for all archs. With using _relaxed IO helper function it is ending up in compilation problems for i386.
Last time with our i2c driver.
http://www.spinics.net/lists/arm-kernel/msg320255.html

Quoted 7 lines
Quoted 3 lines

It means shouldn't be that _relaxed version listed in asm-generic/io.h or just limit it to use this driver just for ARM like we have done for this edac driver.

As I said, it's a requirement for L2C code, because otherwise you end up with every IO access to the L2C also invoking a second IO access to the device.

I understand your point and as I write above we will use relaxed version for reason you have written.

I just wanted to know your opinion regarding adding relaxed version to asm-generic/io.h that's it.

Quoted 8 lines
Quoted 8 lines
Quoted 7 lines

- a driver coupled to the arm,pl310-cache compatible for this which is distinctly separate from the main "driver" is probably a bad idea. what if we want our existing l2 stuff to couple into the driver model to expose some properties at a later date (eg, maybe to deal with stuff like the power management settings?) For example, it may be that we want to expose the prefetch offset so that people can easily play with the value to determine the correct tuning for their workload.

Quoted 6 lines
Quoted 2 lines

We choose that name for starting to discuss this how to do it better. We could use zynq-edac-l2 or zynq-edac-r3p2, etc version.

I'm not talking about the compatible name. I'm certainly not suggesting that you should describe the L2 as two separate devices in DT. I'm saying that this should appear as one _single_ driver for the entire device.

great.

Quoted 7 lines
Quoted 2 lines

Our kernel for historical reasons runs in secure mode that's why I don't know if this will work for us but easy to try.

Sorry, this kind of short sightedness is unacceptable. This is the "I'm only going to solve the problem immediately in front of my nose" syndrome which is currently causing me to end up rewriting lots of code in the kernel right now.

Not like that. I am just saying to give you full picture what I am able to easily test. It means kernel running in secure mode I can just download, rebuild and retest and give you results.
Because this is shared driver across platform I am just saying that for testing this in non secure mode will be better to do it on different platform because on zynq this could be problematic.

We have 3rd party secure monitor around but l2 was problematic there that's why choosing different platform is better choice.

Quoted 3 lines

What you're doing is similar to this:
https://twitter.com/denny/status/452867158964326400/photo/1

Nice picture. :-)

Quoted 2 lines

You're solving the problem you have without thinking about the consequences for others.

I don't think so. I wanted to clearly said our configuration for you to know what I can easily test it.

Quoted 4 lines

Of course other people are going to want to use this, and as the L2C controllers are generic, so any code which adds support for EDAC support should also be generic and not written with a single platform in mind.

Sure I agree with you. That was also the reason why generic string is used there and we are not pretending that this is something zynq specific.

Thanks,
Michal

Signature · 14 lines
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140407/5ed9e725/attachment.sig>
#139 lore raw

cover l2c series

Quoted 24 lines · Russell King - ARM Linux
Quoted 21 lines · Michal Simek
Quoted 20 lines · Russell King - ARM Linux
Quoted 18 lines · Michal Simek
Quoted 10 lines · Russell King - ARM Linux
Quoted 9 lines · Michal Simek
Quoted 8 lines

Hi Russell,

Quoted 5 lines · Russell King - ARM Linux

This is another posting of the L2 cache controller series. I'm not planning for this for the upcoming merge window, but the one after, as people need to test it and still need to feed back to me on various issues. Hence, this is not a finalised series.

- a driver coupled to the arm,pl310-cache compatible for this which is distinctly separate from the main "driver" is probably a bad idea. what if we want our existing l2 stuff to couple into the driver model to expose some properties at a later date (eg, maybe to deal with stuff like the power management settings?) For example, it may be that we want to expose the prefetch offset so that people can easily play with the value to determine the correct tuning for their workload.

Quoted 9 lines
Quoted 6 lines
Quoted 2 lines

We choose that name for starting to discuss this how to do it better. We could use zynq-edac-l2 or zynq-edac-r3p2, etc version.

I'm not talking about the compatible name. I'm certainly not suggesting that you should describe the L2 as two separate devices in DT. I'm saying that this should appear as one _single_ driver for the entire device.

great.

It means there are two drivers, one for l2 cache edac and one for l2 cache configuration
and management in a single file. Please correct me if I am wrong.

Thanks.
Punnaiah

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

#140 lore raw

cover l2c series

Quoted 3 lines · Punnaiah Choudary Kalluri

It means there are two drivers, one for l2 cache edac and one for l2 cache configuration and management in a single file. Please correct me if I am wrong.

Correct - just because you have one piece of hardware which needs to register with two subsystems isn't always a reason to create two separate drivers, and then have to deal with the problem of two separate drivers needing access to the same registers, possibly with register access synchronisation issues.

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