[Arm-dev] [PATCH v0 19/20] its:thunder: ThunderX 23144 errata fix.

Thu Jul 23 12:37:56 UTC 2015
Vadim Lomovtsev <Vadim.Lomovtsev at caviumnetworks.com>

From: Tirumalesh Chalamarla <tchalamarla at caviumnetworks.com>

Workaround for Thunder Pass1 Errata 23144.
This fix is to avoid cross node ITS and redistrubutors(cpu) mapping.
This is applicable only for Multi-node/numa configuration.

Signed-off-by: Ganapatrao Kulkarni <ganapatrao.kulkarni at caviumnetworks.com>
Signed-off-by: Tirumalesh Chalamarla <tchalamarla at caviumnetworks.com>
Signed-off-by: Vadim Lomovtsev <Vadim.Lomovtsev at caviumnetworks.com>

Conflicts:
	arch/arm64/Kconfig
---
 arch/arm64/Kconfig               | 18 ++++++++++++------
 drivers/irqchip/irq-gic-v3-its.c | 20 ++++++++++++++++++++
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7302706..5e450fd 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -246,20 +246,26 @@ config ARCH_THUNDER
 
 menu   "Cavium ThunderX errata"
 
-config THUNDERX_PASS1_ERRATA_23154
-	bool "Cavium ThunderX erratum 23154"
+config THUNDERX_PASS1_ERRATA_22375
+	bool "Cavium ThunderX erratum 22375"
 	depends on ARCH_THUNDER
 	def_bool ARCH_THUNDER
 	help
-	  Enable workaround for erratum 23154.
+	  Enable workaround for erratum 22375.
 
+config THUNDERX_PASS1_ERRATA_23144
+	bool "Cavium ThunderX erratum 23144"
+	depends on ARCH_THUNDER && NUMA
+	def_bool ARCH_THUNDER
+	help
+	  Enable workaround for erratum 23144.
 
-config THUNDERX_PASS1_ERRATA_22375
-	bool "Cavium ThunderX erratum 22375"
+config THUNDERX_PASS1_ERRATA_23154
+	bool "Cavium ThunderX erratum 23154"
 	depends on ARCH_THUNDER
 	def_bool ARCH_THUNDER
 	help
-	  Enable workaround for erratum 22375.
+	  Enable workaround for erratum 23154.
 
 config THUNDERX_PASS1_ERRATA_24313
 	bool "Cavium ThunderX erratum 24313"
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 890aa3b..f098341 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -578,6 +578,16 @@ static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 	struct its_collection *target_col;
 	u32 id = its_get_event_id(d);
 
+#if defined(CONFIG_NUMA) && defined(CONFIG_THUNDERX_PASS1_ERRATA_23144)
+	u32 node = (its_dev->its->phys_base >> 44) & 0x3;
+	if (!cpumask_intersects(mask_val, cpumask_of_node(node))) {
+		pr_debug("Affinity not Set to CPU %d, not belongs to same NODE %d\n",
+				cpu, node);
+		return IRQ_SET_MASK_OK;
+	}
+	cpu = cpumask_any_and(mask_val, cpumask_of_node(node));
+#endif
+
 	if (cpu >= nr_cpu_ids)
 		return -EINVAL;
 
@@ -1053,6 +1063,11 @@ static void its_cpu_init_collection(void)
 	list_for_each_entry(its, &its_nodes, entry) {
 		u64 target;
 
+#if defined(CONFIG_NUMA) && defined(CONFIG_THUNDERX_PASS1_ERRATA_23144)
+		/* avoid cross node core and its mapping*/
+		if (((its->phys_base >> 44) & 0x3) != MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 2))
+			continue;
+#endif
 		/*
 		 * We now have to bind each collection to its target
 		 * redistributor.
@@ -1146,8 +1161,13 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
 	list_add(&dev->entry, &its->its_device_list);
 	raw_spin_unlock_irqrestore(&its->lock, flags);
 
+#if defined(CONFIG_NUMA) && defined(CONFIG_THUNDERX_PASS1_ERRATA_23144)
+	/* Bind the device to the first possible CPU of same NODE*/
+	cpu = cpumask_first(cpumask_of_node((its->phys_base >> 44) & 0x3));
+#else
 	/* Bind the device to the first possible CPU */
 	cpu = cpumask_first(cpu_online_mask);
+#endif
 	dev->collection = &its->collections[cpu];
 
 	/* Map device to its ITT */
-- 
2.4.3