All of lore.kernel.org
 help / color / mirror / Atom feed
From: rmk+kernel@arm.linux.org.uk (Russell King)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 18/44] ARM: l2c: implement fixups for L2 cache controller quirks/errata
Date: Mon, 17 Mar 2014 00:15:02 +0000	[thread overview]
Message-ID: <E1WPLCo-0002d3-Rd@rmk-PC.arm.linux.org.uk> (raw)
In-Reply-To: <20140317001302.GY21483@n2100.arm.linux.org.uk>

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

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

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

  parent reply	other threads:[~2014-03-17  0:15 UTC|newest]

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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1WPLCo-0002d3-Rd@rmk-PC.arm.linux.org.uk \
    --to=rmk+kernel@arm.linux.org.uk \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.