summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/Kconfig17
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c37
2 files changed, 50 insertions, 4 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 490df449377d..440d906429de 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -348,6 +348,23 @@ config ARM64_ERRATUM_843419
348 348
349 If unsure, say Y. 349 If unsure, say Y.
350 350
351config CAVIUM_ERRATUM_22375
352 bool "Cavium erratum 22375, 24313"
353 default y
354 help
355 Enable workaround for erratum 22375, 24313.
356
357 This implements two gicv3-its errata workarounds for ThunderX. Both
358 with small impact affecting only ITS table allocation.
359
360 erratum 22375: only alloc 8MB table size
361 erratum 24313: ignore memory access type
362
363 The fixes are in ITS initialization and basically ignore memory access
364 type and table size provided by the TYPER and BASER registers.
365
366 If unsure, say Y.
367
351config CAVIUM_ERRATUM_23154 368config CAVIUM_ERRATUM_23154
352 bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed" 369 bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
353 default y 370 default y
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 82622afc916b..eac44dd28ca1 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -39,7 +39,8 @@
39 39
40#include "irq-gic-common.h" 40#include "irq-gic-common.h"
41 41
42#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1 << 0) 42#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1ULL << 0)
43#define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1)
43 44
44#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) 45#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
45 46
@@ -816,9 +817,22 @@ static int its_alloc_tables(const char *node_name, struct its_node *its)
816 int i; 817 int i;
817 int psz = SZ_64K; 818 int psz = SZ_64K;
818 u64 shr = GITS_BASER_InnerShareable; 819 u64 shr = GITS_BASER_InnerShareable;
819 u64 cache = GITS_BASER_WaWb; 820 u64 cache;
820 u64 typer = readq_relaxed(its->base + GITS_TYPER); 821 u64 typer;
821 u32 ids = GITS_TYPER_DEVBITS(typer); 822 u32 ids;
823
824 if (its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_22375) {
825 /*
826 * erratum 22375: only alloc 8MB table size
827 * erratum 24313: ignore memory access type
828 */
829 cache = 0;
830 ids = 0x14; /* 20 bits, 8MB */
831 } else {
832 cache = GITS_BASER_WaWb;
833 typer = readq_relaxed(its->base + GITS_TYPER);
834 ids = GITS_TYPER_DEVBITS(typer);
835 }
822 836
823 for (i = 0; i < GITS_BASER_NR_REGS; i++) { 837 for (i = 0; i < GITS_BASER_NR_REGS; i++) {
824 u64 val = readq_relaxed(its->base + GITS_BASER + i * 8); 838 u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
@@ -1377,7 +1391,22 @@ static int its_force_quiescent(void __iomem *base)
1377 } 1391 }
1378} 1392}
1379 1393
1394static void __maybe_unused its_enable_quirk_cavium_22375(void *data)
1395{
1396 struct its_node *its = data;
1397
1398 its->flags |= ITS_FLAGS_WORKAROUND_CAVIUM_22375;
1399}
1400
1380static const struct gic_quirk its_quirks[] = { 1401static const struct gic_quirk its_quirks[] = {
1402#ifdef CONFIG_CAVIUM_ERRATUM_22375
1403 {
1404 .desc = "ITS: Cavium errata 22375, 24313",
1405 .iidr = 0xa100034c, /* ThunderX pass 1.x */
1406 .mask = 0xffff0fff,
1407 .init = its_enable_quirk_cavium_22375,
1408 },
1409#endif
1381 { 1410 {
1382 } 1411 }
1383}; 1412};