Commit a8707f55 authored by Sebastian Reichel's avatar Sebastian Reichel Committed by Marc Zyngier
Browse files

irqchip/gic-v3: Add Rockchip 3588001 erratum workaround



Rockchip RK3588/RK3588s GIC600 integration does not support the
sharability feature. Rockchip assigned Erratum ID #3588001 for this
issue.

Note, that the 0x0201743b ID is not Rockchip specific and thus
there is an extra of_machine_is_compatible() check.

The flags are named FORCE_NON_SHAREABLE to be vendor agnostic,
since apparently similar integration design errors exist in other
platforms and they can reuse the same flag.

Co-developed-by: default avatarXiaoDong Huang <derrick.huang@rock-chips.com>
Signed-off-by: default avatarXiaoDong Huang <derrick.huang@rock-chips.com>
Co-developed-by: default avatarKever Yang <kever.yang@rock-chips.com>
Signed-off-by: default avatarKever Yang <kever.yang@rock-chips.com>
Co-developed-by: default avatarLucas Tanure <lucas.tanure@collabora.com>
Signed-off-by: default avatarLucas Tanure <lucas.tanure@collabora.com>
Reviewed-by: default avatarAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230418142109.49762-2-sebastian.reichel@collabora.com
parent 35727af2
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -207,6 +207,9 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| Qualcomm Tech. | Kryo4xx Gold    | N/A             | ARM64_ERRATUM_1286807       |
+----------------+-----------------+-----------------+-----------------------------+
+----------------+-----------------+-----------------+-----------------------------+
| Rockchip       | RK3588          | #3588001        | ROCKCHIP_ERRATUM_3588001    |
+----------------+-----------------+-----------------+-----------------------------+

+----------------+-----------------+-----------------+-----------------------------+
| Fujitsu        | A64FX           | E#010001        | FUJITSU_ERRATUM_010001      |
+10 −0
Original line number Diff line number Diff line
@@ -1150,6 +1150,16 @@ config NVIDIA_CARMEL_CNP_ERRATUM

	  If unsure, say Y.

config ROCKCHIP_ERRATUM_3588001
	bool "Rockchip 3588001: GIC600 can not support shareability attributes"
	default y
	help
	  The Rockchip RK3588 GIC600 SoC integration does not support ACE/ACE-lite.
	  This means, that its sharability feature may not be used, even though it
	  is supported by the IP itself.

	  If unsure, say Y.

config SOCIONEXT_SYNQUACER_PREITS
	bool "Socionext Synquacer: Workaround for GICv3 pre-ITS"
	default y
+35 −0
Original line number Diff line number Diff line
@@ -42,9 +42,11 @@
#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1ULL << 0)
#define ITS_FLAGS_WORKAROUND_CAVIUM_22375	(1ULL << 1)
#define ITS_FLAGS_WORKAROUND_CAVIUM_23144	(1ULL << 2)
#define ITS_FLAGS_FORCE_NON_SHAREABLE		(1ULL << 3)

#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING	(1 << 0)
#define RDIST_FLAGS_RD_TABLES_PREALLOCATED	(1 << 1)
#define RDIST_FLAGS_FORCE_NON_SHAREABLE		(1 << 2)

#define RD_LOCAL_LPI_ENABLED                    BIT(0)
#define RD_LOCAL_PENDTABLE_PREALLOCATED         BIT(1)
@@ -2359,6 +2361,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
	its_write_baser(its, baser, val);
	tmp = baser->val;

	if (its->flags & ITS_FLAGS_FORCE_NON_SHAREABLE)
		tmp &= ~GITS_BASER_SHAREABILITY_MASK;

	if ((val ^ tmp) & GITS_BASER_SHAREABILITY_MASK) {
		/*
		 * Shareability didn't stick. Just use
@@ -3096,6 +3101,9 @@ static void its_cpu_init_lpis(void)
	gicr_write_propbaser(val, rbase + GICR_PROPBASER);
	tmp = gicr_read_propbaser(rbase + GICR_PROPBASER);

	if (gic_rdists->flags & RDIST_FLAGS_FORCE_NON_SHAREABLE)
		tmp &= ~GICR_PROPBASER_SHAREABILITY_MASK;

	if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) {
		if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) {
			/*
@@ -3120,6 +3128,9 @@ static void its_cpu_init_lpis(void)
	gicr_write_pendbaser(val, rbase + GICR_PENDBASER);
	tmp = gicr_read_pendbaser(rbase + GICR_PENDBASER);

	if (gic_rdists->flags & RDIST_FLAGS_FORCE_NON_SHAREABLE)
		tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK;

	if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) {
		/*
		 * The HW reports non-shareable, we must remove the
@@ -4710,6 +4721,19 @@ static bool __maybe_unused its_enable_quirk_hip07_161600802(void *data)
	return true;
}

static bool __maybe_unused its_enable_rk3588001(void *data)
{
	struct its_node *its = data;

	if (!of_machine_is_compatible("rockchip,rk3588"))
		return false;

	its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
	gic_rdists->flags |= RDIST_FLAGS_FORCE_NON_SHAREABLE;

	return true;
}

static const struct gic_quirk its_quirks[] = {
#ifdef CONFIG_CAVIUM_ERRATUM_22375
	{
@@ -4755,6 +4779,14 @@ static const struct gic_quirk its_quirks[] = {
		.mask	= 0xffffffff,
		.init	= its_enable_quirk_hip07_161600802,
	},
#endif
#ifdef CONFIG_ROCKCHIP_ERRATUM_3588001
	{
		.desc   = "ITS: Rockchip erratum RK3588001",
		.iidr   = 0x0201743b,
		.mask   = 0xffffffff,
		.init   = its_enable_rk3588001,
	},
#endif
	{
	}
@@ -5096,6 +5128,9 @@ static int __init its_probe_one(struct resource *res,
	gits_write_cbaser(baser, its->base + GITS_CBASER);
	tmp = gits_read_cbaser(its->base + GITS_CBASER);

	if (its->flags & ITS_FLAGS_FORCE_NON_SHAREABLE)
		tmp &= ~GITS_CBASER_SHAREABILITY_MASK;

	if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) {
		if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) {
			/*