irqchip/gic-v3: Add Rockchip 3588001 erratum workaround
authorSebastian Reichel <sebastian.reichel@collabora.com>
Tue, 18 Apr 2023 14:21:08 +0000 (16:21 +0200)
committerMarc Zyngier <maz@kernel.org>
Tue, 18 Apr 2023 16:31:17 +0000 (17:31 +0100)
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: XiaoDong Huang <derrick.huang@rock-chips.com>
Signed-off-by: XiaoDong Huang <derrick.huang@rock-chips.com>
Co-developed-by: Kever Yang <kever.yang@rock-chips.com>
Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
Co-developed-by: Lucas Tanure <lucas.tanure@collabora.com>
Signed-off-by: Lucas Tanure <lucas.tanure@collabora.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230418142109.49762-2-sebastian.reichel@collabora.com
Documentation/arm64/silicon-errata.rst
arch/arm64/Kconfig
drivers/irqchip/irq-gic-v3-its.c

index e31f6c0..9e311bc 100644 (file)
@@ -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      |
index 1023e89..0278921 100644 (file)
@@ -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
index 586271b..fa4641a 100644 (file)
 #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 @@ retry_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
        {
@@ -4756,6 +4780,14 @@ static const struct gic_quirk its_quirks[] = {
                .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)) {
                        /*