From c4be33b792e926c7c83ae41aa704d0010de0efb5 Mon Sep 17 00:00:00 2001 From: AmadeusGhost <42570690+AmadeusGhost@users.noreply.github.com> Date: Fri, 16 Dec 2022 23:19:26 +0800 Subject: [PATCH] rockchip: force enable rk3568 msi interrupt Since the interrupt of RK3568 has hardware bug, we need a workaround to enable msi interrupt. Without this, the r8125 will not be stable. --- target/linux/rockchip/armv8/config-5.15 | 1 + target/linux/rockchip/armv8/config-6.1 | 1 + .../boot/dts/rockchip/rk3568-fastrhino.dtsi | 4 - ...568-update-gicv3-its-and-pci-msi-map.patch | 94 +++++++++ ...gic-v3-add-hackaround-for-rk3568-its.patch | 198 ++++++++++++++++++ ...568-update-gicv3-its-and-pci-msi-map.patch | 94 +++++++++ ...gic-v3-add-hackaround-for-rk3568-its.patch | 198 ++++++++++++++++++ 7 files changed, 586 insertions(+), 4 deletions(-) create mode 100644 target/linux/rockchip/patches-5.15/110-arm64-rk3568-update-gicv3-its-and-pci-msi-map.patch create mode 100644 target/linux/rockchip/patches-5.15/111-irqchip-gic-v3-add-hackaround-for-rk3568-its.patch create mode 100644 target/linux/rockchip/patches-6.1/110-arm64-rk3568-update-gicv3-its-and-pci-msi-map.patch create mode 100644 target/linux/rockchip/patches-6.1/111-irqchip-gic-v3-add-hackaround-for-rk3568-its.patch diff --git a/target/linux/rockchip/armv8/config-5.15 b/target/linux/rockchip/armv8/config-5.15 index 80e66eb3e..e2510b3e7 100644 --- a/target/linux/rockchip/armv8/config-5.15 +++ b/target/linux/rockchip/armv8/config-5.15 @@ -555,6 +555,7 @@ CONFIG_RESET_CONTROLLER=y CONFIG_RESET_SCMI=y CONFIG_RFS_ACCEL=y CONFIG_ROCKCHIP_EFUSE=y +CONFIG_ROCKCHIP_ERRATUM_114514=y CONFIG_ROCKCHIP_GRF=y CONFIG_ROCKCHIP_IODOMAIN=y CONFIG_ROCKCHIP_IOMMU=y diff --git a/target/linux/rockchip/armv8/config-6.1 b/target/linux/rockchip/armv8/config-6.1 index 8da2355c2..1a47c65f0 100644 --- a/target/linux/rockchip/armv8/config-6.1 +++ b/target/linux/rockchip/armv8/config-6.1 @@ -534,6 +534,7 @@ CONFIG_RESET_CONTROLLER=y CONFIG_RESET_SCMI=y CONFIG_RFS_ACCEL=y CONFIG_ROCKCHIP_EFUSE=y +CONFIG_ROCKCHIP_ERRATUM_114514=y CONFIG_ROCKCHIP_GRF=y CONFIG_ROCKCHIP_IODOMAIN=y CONFIG_ROCKCHIP_IOMMU=y diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-fastrhino.dtsi b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-fastrhino.dtsi index 1322c9090..be08b25d9 100644 --- a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-fastrhino.dtsi +++ b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-fastrhino.dtsi @@ -389,10 +389,6 @@ }; }; -&gic { - mbi-ranges = <94 31>, <229 31>, <289 31>; -}; - &pcie30phy { data-lanes = <1 2>; status = "okay"; diff --git a/target/linux/rockchip/patches-5.15/110-arm64-rk3568-update-gicv3-its-and-pci-msi-map.patch b/target/linux/rockchip/patches-5.15/110-arm64-rk3568-update-gicv3-its-and-pci-msi-map.patch new file mode 100644 index 000000000..48dc44284 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/110-arm64-rk3568-update-gicv3-its-and-pci-msi-map.patch @@ -0,0 +1,94 @@ +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -899,6 +899,14 @@ config SOCIONEXT_SYNQUACER_PREITS + + If unsure, say Y. + ++config ROCKCHIP_ERRATUM_114514 ++ bool "Rockchip RK3568 force no_local_cache" ++ default y ++ help ++ They consider this as a SoC implement design instead of a bug. ++ ++ If unsure, say Y. ++ + endmenu + + +--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi +@@ -64,7 +64,7 @@ + compatible = "rockchip,rk3568-pcie"; + #address-cells = <3>; + #size-cells = <2>; +- bus-range = <0x0 0xf>; ++ bus-range = <0x10 0x1f>; + clocks = <&cru ACLK_PCIE30X1_MST>, <&cru ACLK_PCIE30X1_SLV>, + <&cru ACLK_PCIE30X1_DBI>, <&cru PCLK_PCIE30X1>, + <&cru CLK_PCIE30X1_AUX_NDFT>; +@@ -87,7 +87,7 @@ + num-ib-windows = <6>; + num-ob-windows = <2>; + max-link-speed = <3>; +- msi-map = <0x0 &gic 0x1000 0x1000>; ++ msi-map = <0x1000 &its 0x1000 0x1000>; + num-lanes = <1>; + phys = <&pcie30phy>; + phy-names = "pcie-phy"; +@@ -116,7 +116,7 @@ + compatible = "rockchip,rk3568-pcie"; + #address-cells = <3>; + #size-cells = <2>; +- bus-range = <0x0 0xf>; ++ bus-range = <0x20 0x2f>; + clocks = <&cru ACLK_PCIE30X2_MST>, <&cru ACLK_PCIE30X2_SLV>, + <&cru ACLK_PCIE30X2_DBI>, <&cru PCLK_PCIE30X2>, + <&cru CLK_PCIE30X2_AUX_NDFT>; +@@ -139,7 +139,7 @@ + num-ib-windows = <6>; + num-ob-windows = <2>; + max-link-speed = <3>; +- msi-map = <0x0 &gic 0x2000 0x1000>; ++ msi-map = <0x2000 &its 0x2000 0x1000>; + num-lanes = <2>; + phys = <&pcie30phy>; + phy-names = "pcie-phy"; +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -260,14 +260,21 @@ + + gic: interrupt-controller@fd400000 { + compatible = "arm,gic-v3"; ++ #interrupt-cells = <3>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ interrupt-controller; ++ + reg = <0x0 0xfd400000 0 0x10000>, /* GICD */ +- <0x0 0xfd460000 0 0x80000>; /* GICR */ ++ <0x0 0xfd460000 0 0xc0000>; /* GICR */ + interrupts = ; +- interrupt-controller; +- #interrupt-cells = <3>; +- mbi-alias = <0x0 0xfd410000>; +- mbi-ranges = <296 24>; +- msi-controller; ++ its: interrupt-controller@fd440000 { ++ compatible = "arm,gic-v3-its"; ++ msi-controller; ++ #msi-cells = <1>; ++ reg = <0x0 0xfd440000 0x0 0x20000>; ++ }; + }; + + usb_host0_ehci: usb@fd800000 { +@@ -731,7 +738,7 @@ + num-ib-windows = <6>; + num-ob-windows = <2>; + max-link-speed = <2>; +- msi-map = <0x0 &gic 0x0 0x1000>; ++ msi-map = <0x0 &its 0x0 0x1000>; + num-lanes = <1>; + phys = <&combphy2 PHY_TYPE_PCIE>; + phy-names = "pcie-phy"; diff --git a/target/linux/rockchip/patches-5.15/111-irqchip-gic-v3-add-hackaround-for-rk3568-its.patch b/target/linux/rockchip/patches-5.15/111-irqchip-gic-v3-add-hackaround-for-rk3568-its.patch new file mode 100644 index 000000000..27579ccce --- /dev/null +++ b/target/linux/rockchip/patches-5.15/111-irqchip-gic-v3-add-hackaround-for-rk3568-its.patch @@ -0,0 +1,198 @@ +From 536378a084c6a4148141e132efee2fa9a464e007 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Thu, 3 Jun 2021 11:36:35 -0400 +Subject: [PATCH] irqchip: gic-v3: add hackaround for rk3568 its + +--- + drivers/irqchip/irq-gic-v3-its.c | 70 +++++++++++++++++++++++++++++--- + 1 file changed, 65 insertions(+), 5 deletions(-) + +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -45,6 +45,7 @@ + + #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) + #define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1) ++#define RDIST_FLAGS_FORCE_NO_LOCAL_CACHE (1 << 2) + + static u32 lpi_id_bits; + +@@ -2172,6 +2173,11 @@ static struct page *its_allocate_prop_table(gfp_t gfp_flags) + { + struct page *prop_page; + ++ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) { ++ pr_err("ITS ALLOCATE PROP WORKAROUND\n"); ++ gfp_flags |= GFP_DMA; ++ } ++ + prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ)); + if (!prop_page) + return NULL; +@@ -2295,6 +2301,7 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, + u32 alloc_pages, psz; + struct page *page; + void *base; ++ gfp_t gfp_flags; + + psz = baser->psz; + alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz); +@@ -2306,7 +2313,10 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, + order = get_order(GITS_BASER_PAGES_MAX * psz); + } + +- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order); ++ gfp_flags = GFP_KERNEL | __GFP_ZERO; ++ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) ++ gfp_flags |= GFP_DMA; ++ page = alloc_pages_node(its->numa_node, gfp_flags, order); + if (!page) + return -ENOMEM; + +@@ -2353,6 +2363,13 @@ retry_baser: + its_write_baser(its, baser, val); + tmp = baser->val; + ++ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) { ++ if (tmp & GITS_BASER_SHAREABILITY_MASK) ++ tmp &= ~GITS_BASER_SHAREABILITY_MASK; ++ else ++ gic_flush_dcache_to_poc(base, PAGE_ORDER_TO_SIZE(order)); ++ } ++ + if ((val ^ tmp) & GITS_BASER_SHAREABILITY_MASK) { + /* + * Shareability didn't stick. Just use +@@ -2935,6 +2952,10 @@ static struct page *its_allocate_pending_table(gfp_t gfp_flags) + { + struct page *pend_page; + ++ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) { ++ gfp_flags |= GFP_DMA; ++ } ++ + pend_page = alloc_pages(gfp_flags | __GFP_ZERO, + get_order(LPI_PENDBASE_SZ)); + if (!pend_page) +@@ -3092,6 +3113,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_NO_LOCAL_CACHE) ++ tmp &= ~GICR_PROPBASER_SHAREABILITY_MASK; ++ + if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) { + if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) { + /* +@@ -3116,6 +3140,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_NO_LOCAL_CACHE) ++ tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK; ++ + if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) { + /* + * The HW reports non-shareable, we must remove the +@@ -3278,7 +3305,12 @@ static bool its_alloc_table_entry(struct its_node *its, + + /* Allocate memory for 2nd level table */ + if (!table[idx]) { +- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, ++ gfp_t gfp_flags = GFP_KERNEL | __GFP_ZERO; ++ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) { ++ gfp_flags |= GFP_DMA; ++ } ++ ++ page = alloc_pages_node(its->numa_node, gfp_flags, + get_order(baser->psz)); + if (!page) + return false; +@@ -3367,6 +3399,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, + int nr_lpis; + int nr_ites; + int sz; ++ gfp_t gfp_flags; + + if (!its_alloc_device_table(its, dev_id)) + return NULL; +@@ -3374,7 +3407,11 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, + if (WARN_ON(!is_power_of_2(nvecs))) + nvecs = roundup_pow_of_two(nvecs); + +- dev = kzalloc(sizeof(*dev), GFP_KERNEL); ++ gfp_flags = GFP_KERNEL; ++ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) ++ gfp_flags |= GFP_DMA; ++ ++ dev = kzalloc(sizeof(*dev), gfp_flags); + /* + * Even if the device wants a single LPI, the ITT must be + * sized as a power of two (and you need at least one bit...). +@@ -3382,7 +3419,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, + nr_ites = max(2, nvecs); + sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1); + sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; +- itt = kzalloc_node(sz, GFP_KERNEL, its->numa_node); ++ itt = kzalloc_node(sz, gfp_flags, its->numa_node); + if (alloc_lpis) { + lpi_map = its_lpi_alloc(nvecs, &lpi_base, &nr_lpis); + if (lpi_map) +@@ -4705,6 +4742,13 @@ static bool __maybe_unused its_enable_quirk_hip07_161600802(void *data) + return true; + } + ++static bool __maybe_unused its_enable_quirk_rk3568(void *data) ++{ ++ gic_rdists->flags |= RDIST_FLAGS_FORCE_NO_LOCAL_CACHE; ++ ++ return true; ++} ++ + static const struct gic_quirk its_quirks[] = { + #ifdef CONFIG_CAVIUM_ERRATUM_22375 + { +@@ -4750,6 +4794,14 @@ static const struct gic_quirk its_quirks[] = { + .mask = 0xffffffff, + .init = its_enable_quirk_hip07_161600802, + }, ++#endif ++#ifdef CONFIG_ROCKCHIP_ERRATUM_114514 ++ { ++ .desc = "ITS: Rockchip erratum 114514", ++ .iidr = 0x0201743b, ++ .mask = 0xffffffff, ++ .init = its_enable_quirk_rk3568, ++ }, + #endif + { + } +@@ -4974,6 +5026,7 @@ static int __init its_probe_one(struct resource *res, + u64 baser, tmp, typer; + struct page *page; + int err; ++ gfp_t gfp_flags; + + its_base = ioremap(res->start, SZ_64K); + if (!its_base) { +@@ -5042,7 +5095,9 @@ static int __init its_probe_one(struct resource *res, + + its->numa_node = numa_node; + +- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, ++ gfp_flags = GFP_KERNEL | __GFP_ZERO | GFP_DMA; ++ ++ page = alloc_pages_node(its->numa_node, gfp_flags, + get_order(ITS_CMD_QUEUE_SZ)); + if (!page) { + err = -ENOMEM; +@@ -5073,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 (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) ++ tmp &= ~GITS_CBASER_SHAREABILITY_MASK; ++ + if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) { + if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) { + /* diff --git a/target/linux/rockchip/patches-6.1/110-arm64-rk3568-update-gicv3-its-and-pci-msi-map.patch b/target/linux/rockchip/patches-6.1/110-arm64-rk3568-update-gicv3-its-and-pci-msi-map.patch new file mode 100644 index 000000000..d26c92859 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/110-arm64-rk3568-update-gicv3-its-and-pci-msi-map.patch @@ -0,0 +1,94 @@ +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -1133,6 +1133,14 @@ config SOCIONEXT_SYNQUACER_PREITS + + If unsure, say Y. + ++config ROCKCHIP_ERRATUM_114514 ++ bool "Rockchip RK3568 force no_local_cache" ++ default y ++ help ++ They consider this as a SoC implement design instead of a bug. ++ ++ If unsure, say Y. ++ + endmenu # "ARM errata workarounds via the alternatives framework" + + choice +--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi +@@ -64,7 +64,7 @@ + compatible = "rockchip,rk3568-pcie"; + #address-cells = <3>; + #size-cells = <2>; +- bus-range = <0x0 0xf>; ++ bus-range = <0x10 0x1f>; + clocks = <&cru ACLK_PCIE30X1_MST>, <&cru ACLK_PCIE30X1_SLV>, + <&cru ACLK_PCIE30X1_DBI>, <&cru PCLK_PCIE30X1>, + <&cru CLK_PCIE30X1_AUX_NDFT>; +@@ -87,7 +87,7 @@ + num-ib-windows = <6>; + num-ob-windows = <2>; + max-link-speed = <3>; +- msi-map = <0x0 &gic 0x1000 0x1000>; ++ msi-map = <0x1000 &its 0x1000 0x1000>; + num-lanes = <1>; + phys = <&pcie30phy>; + phy-names = "pcie-phy"; +@@ -116,7 +116,7 @@ + compatible = "rockchip,rk3568-pcie"; + #address-cells = <3>; + #size-cells = <2>; +- bus-range = <0x0 0xf>; ++ bus-range = <0x20 0x2f>; + clocks = <&cru ACLK_PCIE30X2_MST>, <&cru ACLK_PCIE30X2_SLV>, + <&cru ACLK_PCIE30X2_DBI>, <&cru PCLK_PCIE30X2>, + <&cru CLK_PCIE30X2_AUX_NDFT>; +@@ -139,7 +139,7 @@ + num-ib-windows = <6>; + num-ob-windows = <2>; + max-link-speed = <3>; +- msi-map = <0x0 &gic 0x2000 0x1000>; ++ msi-map = <0x2000 &its 0x2000 0x1000>; + num-lanes = <2>; + phys = <&pcie30phy>; + phy-names = "pcie-phy"; +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -315,14 +315,21 @@ + + gic: interrupt-controller@fd400000 { + compatible = "arm,gic-v3"; ++ #interrupt-cells = <3>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ interrupt-controller; ++ + reg = <0x0 0xfd400000 0 0x10000>, /* GICD */ +- <0x0 0xfd460000 0 0x80000>; /* GICR */ ++ <0x0 0xfd460000 0 0xc0000>; /* GICR */ + interrupts = ; +- interrupt-controller; +- #interrupt-cells = <3>; +- mbi-alias = <0x0 0xfd410000>; +- mbi-ranges = <296 24>; +- msi-controller; ++ its: interrupt-controller@fd440000 { ++ compatible = "arm,gic-v3-its"; ++ msi-controller; ++ #msi-cells = <1>; ++ reg = <0x0 0xfd440000 0x0 0x20000>; ++ }; + }; + + usb_host0_ehci: usb@fd800000 { +@@ -975,7 +982,7 @@ + num-ib-windows = <6>; + num-ob-windows = <2>; + max-link-speed = <2>; +- msi-map = <0x0 &gic 0x0 0x1000>; ++ msi-map = <0x0 &its 0x0 0x1000>; + num-lanes = <1>; + phys = <&combphy2 PHY_TYPE_PCIE>; + phy-names = "pcie-phy"; diff --git a/target/linux/rockchip/patches-6.1/111-irqchip-gic-v3-add-hackaround-for-rk3568-its.patch b/target/linux/rockchip/patches-6.1/111-irqchip-gic-v3-add-hackaround-for-rk3568-its.patch new file mode 100644 index 000000000..42373edfa --- /dev/null +++ b/target/linux/rockchip/patches-6.1/111-irqchip-gic-v3-add-hackaround-for-rk3568-its.patch @@ -0,0 +1,198 @@ +From 536378a084c6a4148141e132efee2fa9a464e007 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Thu, 3 Jun 2021 11:36:35 -0400 +Subject: [PATCH] irqchip: gic-v3: add hackaround for rk3568 its + +--- + drivers/irqchip/irq-gic-v3-its.c | 70 +++++++++++++++++++++++++++++--- + 1 file changed, 65 insertions(+), 5 deletions(-) + +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -45,6 +45,7 @@ + + #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) + #define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1) ++#define RDIST_FLAGS_FORCE_NO_LOCAL_CACHE (1 << 2) + + #define RD_LOCAL_LPI_ENABLED BIT(0) + #define RD_LOCAL_PENDTABLE_PREALLOCATED BIT(1) +@@ -2172,6 +2173,11 @@ static struct page *its_allocate_prop_table(gfp_t gfp_flags) + { + struct page *prop_page; + ++ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) { ++ pr_err("ITS ALLOCATE PROP WORKAROUND\n"); ++ gfp_flags |= GFP_DMA; ++ } ++ + prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ)); + if (!prop_page) + return NULL; +@@ -2295,6 +2301,7 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, + u32 alloc_pages, psz; + struct page *page; + void *base; ++ gfp_t gfp_flags; + + psz = baser->psz; + alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz); +@@ -2306,7 +2313,10 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, + order = get_order(GITS_BASER_PAGES_MAX * psz); + } + +- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order); ++ gfp_flags = GFP_KERNEL | __GFP_ZERO; ++ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) ++ gfp_flags |= GFP_DMA; ++ page = alloc_pages_node(its->numa_node, gfp_flags, order); + if (!page) + return -ENOMEM; + +@@ -2353,6 +2363,13 @@ retry_baser: + its_write_baser(its, baser, val); + tmp = baser->val; + ++ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) { ++ if (tmp & GITS_BASER_SHAREABILITY_MASK) ++ tmp &= ~GITS_BASER_SHAREABILITY_MASK; ++ else ++ gic_flush_dcache_to_poc(base, PAGE_ORDER_TO_SIZE(order)); ++ } ++ + if ((val ^ tmp) & GITS_BASER_SHAREABILITY_MASK) { + /* + * Shareability didn't stick. Just use +@@ -2935,6 +2952,10 @@ static struct page *its_allocate_pending_table(gfp_t gfp_flags) + { + struct page *pend_page; + ++ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) { ++ gfp_flags |= GFP_DMA; ++ } ++ + pend_page = alloc_pages(gfp_flags | __GFP_ZERO, + get_order(LPI_PENDBASE_SZ)); + if (!pend_page) +@@ -3092,6 +3113,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_NO_LOCAL_CACHE) ++ tmp &= ~GICR_PROPBASER_SHAREABILITY_MASK; ++ + if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) { + if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) { + /* +@@ -3116,6 +3140,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_NO_LOCAL_CACHE) ++ tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK; ++ + if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) { + /* + * The HW reports non-shareable, we must remove the +@@ -3278,7 +3305,12 @@ static bool its_alloc_table_entry(struct its_node *its, + + /* Allocate memory for 2nd level table */ + if (!table[idx]) { +- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, ++ gfp_t gfp_flags = GFP_KERNEL | __GFP_ZERO; ++ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) { ++ gfp_flags |= GFP_DMA; ++ } ++ ++ page = alloc_pages_node(its->numa_node, gfp_flags, + get_order(baser->psz)); + if (!page) + return false; +@@ -3367,6 +3399,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, + int nr_lpis; + int nr_ites; + int sz; ++ gfp_t gfp_flags; + + if (!its_alloc_device_table(its, dev_id)) + return NULL; +@@ -3374,7 +3407,11 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, + if (WARN_ON(!is_power_of_2(nvecs))) + nvecs = roundup_pow_of_two(nvecs); + +- dev = kzalloc(sizeof(*dev), GFP_KERNEL); ++ gfp_flags = GFP_KERNEL; ++ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) ++ gfp_flags |= GFP_DMA; ++ ++ dev = kzalloc(sizeof(*dev), gfp_flags); + /* + * Even if the device wants a single LPI, the ITT must be + * sized as a power of two (and you need at least one bit...). +@@ -3382,7 +3419,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, + nr_ites = max(2, nvecs); + sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1); + sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; +- itt = kzalloc_node(sz, GFP_KERNEL, its->numa_node); ++ itt = kzalloc_node(sz, gfp_flags, its->numa_node); + if (alloc_lpis) { + lpi_map = its_lpi_alloc(nvecs, &lpi_base, &nr_lpis); + if (lpi_map) +@@ -4705,6 +4742,13 @@ static bool __maybe_unused its_enable_quirk_hip07_161600802(void *data) + return true; + } + ++static bool __maybe_unused its_enable_quirk_rk3568(void *data) ++{ ++ gic_rdists->flags |= RDIST_FLAGS_FORCE_NO_LOCAL_CACHE; ++ ++ return true; ++} ++ + static const struct gic_quirk its_quirks[] = { + #ifdef CONFIG_CAVIUM_ERRATUM_22375 + { +@@ -4750,6 +4794,14 @@ static const struct gic_quirk its_quirks[] = { + .mask = 0xffffffff, + .init = its_enable_quirk_hip07_161600802, + }, ++#endif ++#ifdef CONFIG_ROCKCHIP_ERRATUM_114514 ++ { ++ .desc = "ITS: Rockchip erratum 114514", ++ .iidr = 0x0201743b, ++ .mask = 0xffffffff, ++ .init = its_enable_quirk_rk3568, ++ }, + #endif + { + } +@@ -4974,6 +5026,7 @@ static int __init its_probe_one(struct resource *res, + struct page *page; + u32 ctlr; + int err; ++ gfp_t gfp_flags; + + its_base = its_map_one(res, &err); + if (!its_base) +@@ -5042,7 +5095,9 @@ static int __init its_probe_one(struct resource *res, + + its->numa_node = numa_node; + +- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, ++ gfp_flags = GFP_KERNEL | __GFP_ZERO | GFP_DMA; ++ ++ page = alloc_pages_node(its->numa_node, gfp_flags, + get_order(ITS_CMD_QUEUE_SZ)); + if (!page) { + err = -ENOMEM; +@@ -5073,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 (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) ++ tmp &= ~GITS_CBASER_SHAREABILITY_MASK; ++ + if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) { + if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) { + /*