Skip to content

Commit 3a0fff0

Browse files
Lorenzo PieralisiMarc Zyngier
authored andcommitted
irqchip/gic-v3: Enable non-coherent redistributors/ITSes DT probing
The GIC architecture specification defines a set of registers for redistributors and ITSes that control the sharebility and cacheability attributes of redistributors/ITSes initiator ports on the interconnect (GICR_[V]PROPBASER, GICR_[V]PENDBASER, GITS_BASER<n>). Architecturally the GIC provides a means to drive shareability and cacheability attributes signals and related IWB/OWB/ISH barriers but it is not mandatory for designs to wire up the corresponding interconnect signals that control the cacheability/shareability of transactions. Redistributors and ITSes interconnect ports can be connected to non-coherent interconnects that are not able to manage the shareability/cacheability attributes; this implicitly makes the redistributors and ITSes non-coherent observers. So far, the GIC driver on probe executes a write to "probe" for the redistributors and ITSes registers shareability bitfields by writing a value (ie InnerShareable - the shareability domain the CPUs are in) and check it back to detect whether the value sticks or not; this hinges on a GIC programming model behaviour that predates the current specifications, that just define shareability bits as writeable but do not guarantee that writing certain shareability values enable the expected behaviour for the redistributors/ITSes memory interconnect ports. To enable non-coherent GIC designs, introduce the "dma-noncoherent" device tree property to allow firmware to describe redistributors and ITSes as non-coherent observers on the memory interconnect and use the property to force the shareability attributes to be programmed into the redistributors and ITSes registers through the GIC quirks mechanism. Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Cc: Robin Murphy <robin.murphy@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Marc Zyngier <maz@kernel.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20231006125929.48591-3-lpieralisi@kernel.org
1 parent 9585a49 commit 3a0fff0

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

drivers/irqchip/irq-gic-common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,8 @@ void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
2929
void gic_enable_of_quirks(const struct device_node *np,
3030
const struct gic_quirk *quirks, void *data);
3131

32+
#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
33+
#define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1)
34+
#define RDIST_FLAGS_FORCE_NON_SHAREABLE (1 << 2)
35+
3236
#endif /* _IRQ_GIC_COMMON_H */

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@
4444
#define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2)
4545
#define ITS_FLAGS_FORCE_NON_SHAREABLE (1ULL << 3)
4646

47-
#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
48-
#define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1)
49-
#define RDIST_FLAGS_FORCE_NON_SHAREABLE (1 << 2)
50-
5147
#define RD_LOCAL_LPI_ENABLED BIT(0)
5248
#define RD_LOCAL_PENDTABLE_PREALLOCATED BIT(1)
5349
#define RD_LOCAL_MEMRESERVE_DONE BIT(2)
@@ -4754,6 +4750,14 @@ static bool __maybe_unused its_enable_rk3588001(void *data)
47544750
return true;
47554751
}
47564752

4753+
static bool its_set_non_coherent(void *data)
4754+
{
4755+
struct its_node *its = data;
4756+
4757+
its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
4758+
return true;
4759+
}
4760+
47574761
static const struct gic_quirk its_quirks[] = {
47584762
#ifdef CONFIG_CAVIUM_ERRATUM_22375
47594763
{
@@ -4808,6 +4812,11 @@ static const struct gic_quirk its_quirks[] = {
48084812
.init = its_enable_rk3588001,
48094813
},
48104814
#endif
4815+
{
4816+
.desc = "ITS: non-coherent attribute",
4817+
.property = "dma-noncoherent",
4818+
.init = its_set_non_coherent,
4819+
},
48114820
{
48124821
}
48134822
};
@@ -4817,6 +4826,10 @@ static void its_enable_quirks(struct its_node *its)
48174826
u32 iidr = readl_relaxed(its->base + GITS_IIDR);
48184827

48194828
gic_enable_quirks(iidr, its_quirks, its);
4829+
4830+
if (is_of_node(its->fwnode_handle))
4831+
gic_enable_of_quirks(to_of_node(its->fwnode_handle),
4832+
its_quirks, its);
48204833
}
48214834

48224835
static int its_save_disable(void)

drivers/irqchip/irq-gic-v3.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1857,6 +1857,14 @@ static bool gic_enable_quirk_arm64_2941627(void *data)
18571857
return true;
18581858
}
18591859

1860+
static bool rd_set_non_coherent(void *data)
1861+
{
1862+
struct gic_chip_data *d = data;
1863+
1864+
d->rdists.flags |= RDIST_FLAGS_FORCE_NON_SHAREABLE;
1865+
return true;
1866+
}
1867+
18601868
static const struct gic_quirk gic_quirks[] = {
18611869
{
18621870
.desc = "GICv3: Qualcomm MSM8996 broken firmware",
@@ -1923,6 +1931,11 @@ static const struct gic_quirk gic_quirks[] = {
19231931
.mask = 0xff0f0fff,
19241932
.init = gic_enable_quirk_arm64_2941627,
19251933
},
1934+
{
1935+
.desc = "GICv3: non-coherent attribute",
1936+
.property = "dma-noncoherent",
1937+
.init = rd_set_non_coherent,
1938+
},
19261939
{
19271940
}
19281941
};

0 commit comments

Comments
 (0)