irqchip/gicv3-its: Workaround for Cavium ThunderX errata 22375, 24313

This implements two gicv3-its errata workarounds for ThunderX. Both
with small impact affecting only ITS table allocation.

 erratum 22375: only alloc 8MB table size
 erratum 24313: ignore memory access type

The fixes are in ITS initialization and basically ignore memory access
type and table size provided by the TYPER and BASER registers.

Signed-off-by: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
Signed-off-by: Robert Richter <rrichter@cavium.com>
Reviewed-by: Marc Zygnier <marc.zyngier@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Tirumalesh Chalamarla <tchalamarla@cavium.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Will Deacon <will.deacon@arm.com>
Link: http://lkml.kernel.org/r/1442869119-1814-6-git-send-email-rric@kernel.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Robert Richter 2015-09-21 22:58:38 +02:00 committed by Thomas Gleixner
parent 67510ccafb
commit 9410097074
2 changed files with 50 additions and 4 deletions

View file

@ -348,6 +348,23 @@ config ARM64_ERRATUM_843419
If unsure, say Y. If unsure, say Y.
config CAVIUM_ERRATUM_22375
bool "Cavium erratum 22375, 24313"
default y
help
Enable workaround for erratum 22375, 24313.
This implements two gicv3-its errata workarounds for ThunderX. Both
with small impact affecting only ITS table allocation.
erratum 22375: only alloc 8MB table size
erratum 24313: ignore memory access type
The fixes are in ITS initialization and basically ignore memory access
type and table size provided by the TYPER and BASER registers.
If unsure, say Y.
config CAVIUM_ERRATUM_23154 config CAVIUM_ERRATUM_23154
bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed" bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
default y default y

View file

@ -39,7 +39,8 @@
#include "irq-gic-common.h" #include "irq-gic-common.h"
#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1 << 0) #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1ULL << 0)
#define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1)
#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
@ -816,9 +817,22 @@ static int its_alloc_tables(const char *node_name, struct its_node *its)
int i; int i;
int psz = SZ_64K; int psz = SZ_64K;
u64 shr = GITS_BASER_InnerShareable; u64 shr = GITS_BASER_InnerShareable;
u64 cache = GITS_BASER_WaWb; u64 cache;
u64 typer = readq_relaxed(its->base + GITS_TYPER); u64 typer;
u32 ids = GITS_TYPER_DEVBITS(typer); u32 ids;
if (its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_22375) {
/*
* erratum 22375: only alloc 8MB table size
* erratum 24313: ignore memory access type
*/
cache = 0;
ids = 0x14; /* 20 bits, 8MB */
} else {
cache = GITS_BASER_WaWb;
typer = readq_relaxed(its->base + GITS_TYPER);
ids = GITS_TYPER_DEVBITS(typer);
}
for (i = 0; i < GITS_BASER_NR_REGS; i++) { for (i = 0; i < GITS_BASER_NR_REGS; i++) {
u64 val = readq_relaxed(its->base + GITS_BASER + i * 8); u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
@ -1377,7 +1391,22 @@ static int its_force_quiescent(void __iomem *base)
} }
} }
static void __maybe_unused its_enable_quirk_cavium_22375(void *data)
{
struct its_node *its = data;
its->flags |= ITS_FLAGS_WORKAROUND_CAVIUM_22375;
}
static const struct gic_quirk its_quirks[] = { static const struct gic_quirk its_quirks[] = {
#ifdef CONFIG_CAVIUM_ERRATUM_22375
{
.desc = "ITS: Cavium errata 22375, 24313",
.iidr = 0xa100034c, /* ThunderX pass 1.x */
.mask = 0xffff0fff,
.init = its_enable_quirk_cavium_22375,
},
#endif
{ {
} }
}; };