2023-03-10 08:05:54

by Lucas Tanure

[permalink] [raw]
Subject: [PATCH 0/7] Add PCIe2 support for Rockchip Boards

I am assisting with PCIe and networking bring-up for Rock Pi 5B (RK3588).
This chip uses the same GICv3 as RK356X but has fixed the previous
limitation of GIC only supporting 32-bit addresses.

We sent this RFC a few weeks back:
https://lore.kernel.org/all/CAMdYzYrmq1ftBaBj1XHVWWXUQ4Prr1VpTpunyNOQ2ha-DkXMjQ@mail.gmail.com/

The big change from that RFC to this patch series is the change from
ITS quirks to a DMA Non-Coherent flag, as sugested by Robin Murphy.

This is work based on prior work from XiaoDong Huang and
Peter Geis fixing this issue specifically for Rockchip 356x.
Plus comments of Robin Murphy about Non-Coherent properties.

Lucas Tanure (7):
irqchip/gic-v3: Add a DMA Non-Coherent flag
PCI: rockchip-dwc: Add rk3588 compatible line
dt-bindings: phy: rockchip: Add rk3588 compatible line
phy: rockchip: Add naneng combo phy support for RK3588
arm64: dts: rockchip: Add ITS GIC600 configuration for rk3588s
arm64: dts: rockchip: Add PCIE2.0x1 lane @fe190000 for RK3588s
arm64: dts: rockchip: RK3588s: Enable PCIE2.0x1 @fe190000

.../phy/phy-rockchip-naneng-combphy.yaml | 1 +
.../boot/dts/rockchip/rk3588-rock-5b.dts | 18 ++
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 97 +++++++++
drivers/irqchip/irq-gic-v3-its.c | 22 +++
drivers/pci/controller/dwc/pcie-dw-rockchip.c | 1 +
.../rockchip/phy-rockchip-naneng-combphy.c | 184 ++++++++++++++++++
6 files changed, 323 insertions(+)

--
2.39.2



2023-03-10 08:05:55

by Lucas Tanure

[permalink] [raw]
Subject: [PATCH 1/7] irqchip/gic-v3: Add a DMA Non-Coherent flag

The GIC600 integration in RK356x, used in rk3588, doesn't support
any of the shareability or cacheability attributes, and requires
both values to be set to 0b00 for all the ITS and Redistributor
tables.

This is loosely based on prior work from XiaoDong Huang and
Peter Geis fixing this issue specifically for Rockchip 356x.

Suggested-by: Robin Murphy <[email protected]>
Signed-off-by: Lucas Tanure <[email protected]>
---
drivers/irqchip/irq-gic-v3-its.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 973ede0197e3..1c334dfeb647 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -42,6 +42,7 @@
#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_DMA_NON_COHERENT (1ULL << 3)

#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
#define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1)
@@ -2359,6 +2360,13 @@ 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_DMA_NON_COHERENT) {
+ 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
@@ -3055,6 +3063,7 @@ static u64 its_clear_vpend_valid(void __iomem *vlpi_base, u64 clr, u64 set)

static void its_cpu_init_lpis(void)
{
+ struct its_node *its = list_first_entry(&its_nodes, struct its_node, entry);
void __iomem *rbase = gic_data_rdist_rd_base();
struct page *pend_page;
phys_addr_t paddr;
@@ -3096,6 +3105,9 @@ static void its_cpu_init_lpis(void)
gicr_write_propbaser(val, rbase + GICR_PROPBASER);
tmp = gicr_read_propbaser(rbase + GICR_PROPBASER);

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

+ if (its->flags & ITS_FLAGS_DMA_NON_COHERENT)
+ tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK;
+
if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) {
/*
* The HW reports non-shareable, we must remove the
@@ -5005,6 +5020,7 @@ static int __init its_compute_its_list_map(struct resource *res,
static int __init its_probe_one(struct resource *res,
struct fwnode_handle *handle, int numa_node)
{
+ struct device_node *np = to_of_node(handle);
struct its_node *its;
void __iomem *its_base;
u64 baser, tmp, typer;
@@ -5076,6 +5092,9 @@ static int __init its_probe_one(struct resource *res,
its->get_msi_base = its_irq_get_msi_base;
its->msi_domain_flags = IRQ_DOMAIN_FLAG_MSI_REMAP;

+ if (np && !of_dma_is_coherent(np))
+ its->flags |= ITS_FLAGS_DMA_NON_COHERENT;
+
its_enable_quirks(its);

err = its_alloc_tables(its);
@@ -5095,6 +5114,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_DMA_NON_COHERENT)
+ tmp &= ~GITS_CBASER_SHAREABILITY_MASK;
+
if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) {
if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) {
/*
--
2.39.2


2023-03-10 08:06:01

by Lucas Tanure

[permalink] [raw]
Subject: [PATCH 3/7] dt-bindings: phy: rockchip: Add rk3588 compatible line

RK3568 Naneng Combo Phy driver can support RK3588 with the additional
clocks and initial configuration, so add the compatible line.

Signed-off-by: Lucas Tanure <[email protected]>
---
.../devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml | 1 +
1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
index 8d8698412de0..9ae514fa7533 100644
--- a/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
@@ -13,6 +13,7 @@ properties:
compatible:
enum:
- rockchip,rk3568-naneng-combphy
+ - rockchip,rk3588-naneng-combphy

reg:
maxItems: 1
--
2.39.2


2023-03-10 08:06:04

by Lucas Tanure

[permalink] [raw]
Subject: [PATCH 7/7] arm64: dts: rockchip: RK3588s: Enable PCIE2.0x1 @fe190000

Enable PCIE2.0x1 @fe190000 for RTL8125 network controller in
Rock 5B board.

This is based on prior work from XiaoDong Huang and
Peter Geis fixing this issue specifically for Rockchip 356x.

Signed-off-by: Lucas Tanure <[email protected]>
---
.../arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
index df8b135cf223..c4ae20ad2fd7 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
@@ -36,6 +36,15 @@ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3 {
regulator-max-microvolt = <1100000>;
vin-supply = <&vcc5v0_sys>;
};
+
+ vcc3v3_pcie2x1l2: vcc3v3-pcie2x1l2 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie2x1l2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc_3v3_s3>;
+ };
};

&sdhci {
@@ -70,3 +79,12 @@ &sdmmc {
status = "okay";
};

+&combphy0_ps {
+ status = "okay";
+};
+
+&pcie2x1l2 {
+ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie2x1l2>;
+ status = "okay";
+};
--
2.39.2


2023-03-10 08:06:09

by Lucas Tanure

[permalink] [raw]
Subject: [PATCH 6/7] arm64: dts: rockchip: Add PCIE2.0x1 lane @fe190000 for RK3588s

Add PCIE2.0x1 lane @fe190000 phy node for RK3588s.
This lane is used for network controller RTL8125 in ROCK 5B.

This is based on prior work from XiaoDong Huang and
Peter Geis fixing this issue specifically for Rockchip 356x.

Signed-off-by: Lucas Tanure <[email protected]>
---
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 78 +++++++++++++++++++++++
1 file changed, 78 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
index 695aed05eba2..bb66a8252d1b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
@@ -9,6 +9,7 @@
#include <dt-bindings/power/rk3588-power.h>
#include <dt-bindings/reset/rockchip,rk3588-cru.h>
#include <dt-bindings/thermal/thermal.h>
+#include <dt-bindings/phy/phy.h>

/ {
compatible = "rockchip,rk3588";
@@ -878,6 +879,83 @@ cru: clock-controller@fd7c0000 {
rockchip,grf = <&php_grf>;
#clock-cells = <1>;
#reset-cells = <1>;
+
+ };
+
+ pipe_phy0_grf: syscon@fd5bc000 {
+ compatible = "rockchip,pipe-phy-grf", "syscon";
+ reg = <0x0 0xfd5bc000 0x0 0x100>;
+ };
+
+ combphy0_ps: phy@fee00000 {
+ compatible = "rockchip,rk3588-naneng-combphy";
+ reg = <0x0 0xfee00000 0x0 0x100>;
+ #phy-cells = <1>;
+ clocks = <&cru CLK_REF_PIPE_PHY0>, <&cru PCLK_PCIE_COMBO_PIPE_PHY0>,
+ <&cru PCLK_PHP_ROOT>;
+ clock-names = "refclk", "apbclk", "phpclk";
+ assigned-clocks = <&cru CLK_REF_PIPE_PHY0>;
+ assigned-clock-rates = <100000000>;
+ resets = <&cru SRST_P_PCIE2_PHY0>, <&cru SRST_REF_PIPE_PHY0>;
+ reset-names = "combphy-apb", "combphy";
+ rockchip,pipe-grf = <&php_grf>;
+ rockchip,pipe-phy-grf = <&pipe_phy0_grf>;
+ status = "disabled";
+ };
+
+ pcie2x1l2: pcie@fe190000 {
+ compatible = "rockchip,rk3588-pcie", "snps,dw-pcie";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x40 0x4f>;
+ clocks = <&cru ACLK_PCIE_1L2_MSTR>, <&cru ACLK_PCIE_1L2_SLV>,
+ <&cru ACLK_PCIE_1L2_DBI>, <&cru PCLK_PCIE_1L2>,
+ <&cru CLK_PCIE_AUX4>, <&cru CLK_PCIE1L2_PIPE>;
+ clock-names = "aclk_mst", "aclk_slv",
+ "aclk_dbi", "pclk",
+ "aux", "pipe";
+ device_type = "pci";
+ interrupts = <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie2x1l2_intc 0>,
+ <0 0 0 2 &pcie2x1l2_intc 1>,
+ <0 0 0 3 &pcie2x1l2_intc 2>,
+ <0 0 0 4 &pcie2x1l2_intc 3>;
+ linux,pci-domain = <4>;
+ num-ib-windows = <8>;
+ num-ob-windows = <8>;
+ num-viewport = <4>;
+ max-link-speed = <2>;
+ msi-map = <0x4000 &its0 0x4000 0x1000>;
+ num-lanes = <1>;
+ phys = <&combphy0_ps PHY_TYPE_PCIE>;
+ phy-names = "pcie-phy";
+ power-domains = <&power RK3588_PD_PCIE>;
+ ranges = <0x01000000 0x0 0xf4100000 0x0 0xf4100000 0x0 0x00100000>,
+ <0x02000000 0x0 0xf4200000 0x0 0xf4200000 0x0 0x00e00000>,
+ <0x03000000 0xa 0x00000000 0xa 0x00000000 0x0 0x40000000>;
+ reg = <0xa 0x41000000 0x0 0x00400000>,
+ <0x0 0xfe190000 0x0 0x00010000>,
+ <0x0 0xf4000000 0x0 0x00100000>;
+ reg-names = "dbi", "apb", "config";
+ resets = <&cru SRST_PCIE4_POWER_UP>, <&cru SRST_P_PCIE4>;
+ reset-names = "pcie", "periph";
+ rockchip,pipe-grf = <&php_grf>;
+ status = "disabled";
+
+ pcie2x1l2_intc: legacy-interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 250 IRQ_TYPE_EDGE_RISING 0>;
+ };
};

i2c0: i2c@fd880000 {
--
2.39.2


2023-03-10 08:06:12

by Lucas Tanure

[permalink] [raw]
Subject: [PATCH 5/7] arm64: dts: rockchip: Add ITS GIC600 configuration for rk3588s

Add support for Interrupts to be translated by the GIC-600
Interrupt Translation Service (ITS).
ITS provides a software mechanism for translating message-based
interrupts into Locality-specific Peripheral Interrupts (LPIs).

This is based on prior work from XiaoDong Huang and
Peter Geis fixing this issue specifically for Rockchip 356x.
Plus comments of Robin Murphy about Non-Coherent properties.

Signed-off-by: Lucas Tanure <[email protected]>
---
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
index 24919cb5c153..695aed05eba2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
@@ -1594,6 +1594,25 @@ gic: interrupt-controller@fe600000 {
mbi-ranges = <424 56>;
msi-controller;
#interrupt-cells = <4>;
+ ranges;
+
+ its0: msi-controller@fe640000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ dma-noncoherent;
+ #msi-cells = <1>;
+ reg = <0x0 0xfe640000 0x0 0x20000>;
+ power-domains = <&power RK3588_PD_PCIE>;
+ };
+
+ its1: msi-controller@fe660000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ dma-noncoherent;
+ #msi-cells = <1>;
+ reg = <0x0 0xfe660000 0x0 0x20000>;
+ power-domains = <&power RK3588_PD_PCIE>;
+ };

ppi-partitions {
ppi_partition0: interrupt-partition-0 {
--
2.39.2


2023-03-10 08:06:15

by Lucas Tanure

[permalink] [raw]
Subject: [PATCH 4/7] phy: rockchip: Add naneng combo phy support for RK3588

Add support for RK3588 combo phy

This is based on prior work from XiaoDong Huang and
Peter Geis fixing this issue specifically for Rockchip 356x.

Co-developed-by: Andrew Powers-Holmes <[email protected]>
Signed-off-by: Andrew Powers-Holmes <[email protected]>
Signed-off-by: Lucas Tanure <[email protected]>
---
.../rockchip/phy-rockchip-naneng-combphy.c | 184 ++++++++++++++++++
1 file changed, 184 insertions(+)

diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
index 7b213825fb5d..7b8b001e4f9e 100644
--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
@@ -63,6 +63,9 @@
#define PHYREG18 0x44
#define PHYREG18_PLL_LOOP 0x32

+#define PHYREG27 0x6C
+#define PHYREG27_RX_TRIM_RK3588 0x4C
+
#define PHYREG32 0x7C
#define PHYREG32_SSC_MASK GENMASK(7, 4)
#define PHYREG32_SSC_DIR_SHIFT 4
@@ -114,7 +117,10 @@ struct rockchip_combphy_grfcfg {
struct combphy_reg con2_for_sata;
struct combphy_reg con3_for_sata;
struct combphy_reg pipe_con0_for_sata;
+ struct combphy_reg pipe_con1_for_sata;
struct combphy_reg pipe_xpcs_phy_ready;
+ struct combphy_reg pipe_pcie1l0_sel;
+ struct combphy_reg pipe_pcie1l1_sel;
};

struct rockchip_combphy_cfg {
@@ -559,11 +565,189 @@ static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
.combphy_cfg = rk3568_combphy_cfg,
};

+static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)
+{
+ const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
+ unsigned long rate;
+ u32 val;
+
+ switch (priv->type) {
+ case PHY_TYPE_PCIE:
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
+ rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l0_sel, true);
+ rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l1_sel, true);
+ break;
+ case PHY_TYPE_USB3:
+ /* Set SSC downward spread spectrum */
+ rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK,
+ PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT,
+ PHYREG32);
+
+ /* Enable adaptive CTLE for USB3.0 Rx. */
+ val = readl(priv->mmio + PHYREG15);
+ val |= PHYREG15_CTLE_EN;
+ writel(val, priv->mmio + PHYREG15);
+
+ /* Set PLL KVCO fine tuning signals. */
+ rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
+ PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT,
+ PHYREG33);
+
+ /* Enable controlling random jitter. */
+ writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
+
+ /* Set PLL input clock divider 1/2. */
+ rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK,
+ PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT,
+ PHYREG6);
+
+ writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
+ writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
+
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
+ break;
+ case PHY_TYPE_SATA:
+ /* Enable adaptive CTLE for SATA Rx. */
+ val = readl(priv->mmio + PHYREG15);
+ val |= PHYREG15_CTLE_EN;
+ writel(val, priv->mmio + PHYREG15);
+ /*
+ * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA.
+ * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm)
+ */
+ val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT;
+ val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT;
+ writel(val, priv->mmio + PHYREG7);
+
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
+ rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
+ rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
+ break;
+ case PHY_TYPE_SGMII:
+ case PHY_TYPE_QSGMII:
+ default:
+ dev_err(priv->dev, "incompatible PHY type\n");
+ return -EINVAL;
+ }
+
+ rate = clk_get_rate(priv->refclk);
+
+ switch (rate) {
+ case REF_CLOCK_24MHz:
+ if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) {
+ /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */
+ val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT;
+ rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK,
+ val, PHYREG15);
+
+ writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
+ }
+ break;
+
+ case REF_CLOCK_25MHz:
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
+ break;
+ case REF_CLOCK_100MHz:
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
+ if (priv->type == PHY_TYPE_PCIE) {
+ /* PLL KVCO fine tuning. */
+ val = 4 << PHYREG33_PLL_KVCO_SHIFT;
+ rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
+ val, PHYREG33);
+
+ /* Enable controlling random jitter. */
+ writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
+
+ /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
+ writel(PHYREG27_RX_TRIM_RK3588, priv->mmio + PHYREG27);
+
+ /* Set up su_trim: */
+ writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
+ } else if (priv->type == PHY_TYPE_SATA) {
+ /* downward spread spectrum +500ppm */
+ val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT;
+ val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT;
+ rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
+ }
+ break;
+ default:
+ dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
+ return -EINVAL;
+ }
+
+ if (priv->ext_refclk) {
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
+ if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
+ val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT;
+ val |= PHYREG13_CKRCV_AMP0;
+ rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13);
+
+ val = readl(priv->mmio + PHYREG14);
+ val |= PHYREG14_CKRCV_AMP1;
+ writel(val, priv->mmio + PHYREG14);
+ }
+ }
+
+ if (priv->enable_ssc) {
+ val = readl(priv->mmio + PHYREG8);
+ val |= PHYREG8_SSC_EN;
+ writel(val, priv->mmio + PHYREG8);
+ }
+
+ return 0;
+}
+
+static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = {
+ /* pipe-phy-grf */
+ .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 },
+ .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 },
+ .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 },
+ .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 },
+ .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 },
+ .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 },
+ .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 },
+ .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 },
+ .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 },
+ .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 },
+ .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 },
+ .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 },
+ .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 },
+ .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 },
+ .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 },
+ .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 },
+ .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0129 },
+ .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0000 },
+ .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c1 },
+ .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x0407 },
+ /* pipe-grf */
+ .pipe_con0_for_sata = { 0x0000, 11, 5, 0x00, 0x22 },
+ .pipe_con1_for_sata = { 0x0000, 2, 0, 0x00, 0x2 },
+ .pipe_pcie1l0_sel = { 0x0100, 0, 0, 0x01, 0x0 },
+ .pipe_pcie1l1_sel = { 0x0100, 1, 1, 0x01, 0x0 },
+};
+
+static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = {
+ .grfcfg = &rk3588_combphy_grfcfgs,
+ .combphy_cfg = rk3588_combphy_cfg,
+};
+
static const struct of_device_id rockchip_combphy_of_match[] = {
{
.compatible = "rockchip,rk3568-naneng-combphy",
.data = &rk3568_combphy_cfgs,
},
+ {
+ .compatible = "rockchip,rk3588-naneng-combphy",
+ .data = &rk3588_combphy_cfgs,
+ },
{ },
};
MODULE_DEVICE_TABLE(of, rockchip_combphy_of_match);
--
2.39.2


2023-03-10 09:02:46

by Marc Zyngier

[permalink] [raw]
Subject: Re: [PATCH 1/7] irqchip/gic-v3: Add a DMA Non-Coherent flag

On 2023-03-10 08:05, Lucas Tanure wrote:
> The GIC600 integration in RK356x, used in rk3588, doesn't support
> any of the shareability or cacheability attributes, and requires
> both values to be set to 0b00 for all the ITS and Redistributor
> tables.
>
> This is loosely based on prior work from XiaoDong Huang and
> Peter Geis fixing this issue specifically for Rockchip 356x.

No.

If we are going to do *anything* about this thing, it is by
describing the actual topology. And it has to work for both DT
and ACPI.

Alternatively, this is an erratum.

M.
--
Jazz is not dead. It just smells funny...

2023-03-10 09:53:28

by Lucas Tanure

[permalink] [raw]
Subject: Re: [PATCH 1/7] irqchip/gic-v3: Add a DMA Non-Coherent flag

On 10-03-2023 08:56, Marc Zyngier wrote:
> On 2023-03-10 08:05, Lucas Tanure wrote:
>> The GIC600 integration in RK356x, used in rk3588, doesn't support
>> any of the shareability or cacheability attributes, and requires
>> both values to be set to 0b00 for all the ITS and Redistributor
>> tables.
>>
>> This is loosely based on prior work from XiaoDong Huang and
>> Peter Geis fixing this issue specifically for Rockchip 356x.
>
> No.
>
> If we are going to do *anything* about this thing, it is by
> describing the actual topology.
What do you mean by describe the topology?
What kind of information are you expecting?


And it has to work for both DT
> and ACPI.
>
> Alternatively, this is an erratum.
>
>         M.


2023-03-10 10:45:08

by Marc Zyngier

[permalink] [raw]
Subject: Re: [PATCH 1/7] irqchip/gic-v3: Add a DMA Non-Coherent flag

On Fri, 10 Mar 2023 09:53:16 +0000,
Lucas Tanure <[email protected]> wrote:
>
> On 10-03-2023 08:56, Marc Zyngier wrote:
> > On 2023-03-10 08:05, Lucas Tanure wrote:
> >> The GIC600 integration in RK356x, used in rk3588, doesn't support
> >> any of the shareability or cacheability attributes, and requires
> >> both values to be set to 0b00 for all the ITS and Redistributor
> >> tables.
> >>
> >> This is loosely based on prior work from XiaoDong Huang and
> >> Peter Geis fixing this issue specifically for Rockchip 356x.
> >
> > No.
> >
> > If we are going to do *anything* about this thing, it is by
> > describing the actual topology.
> What do you mean by describe the topology?

Exactly what it means. Describe which shareability domains the GIC is
in w.r.t the whole SoC. Do it consistently over the whole SoC.

M.

--
Without deviation from the norm, progress is not possible.

2023-03-10 11:42:49

by Peter Geis

[permalink] [raw]
Subject: Re: [PATCH 1/7] irqchip/gic-v3: Add a DMA Non-Coherent flag

On Fri, Mar 10, 2023 at 3:05 AM Lucas Tanure <[email protected]> wrote:
>
> The GIC600 integration in RK356x, used in rk3588, doesn't support
> any of the shareability or cacheability attributes, and requires
> both values to be set to 0b00 for all the ITS and Redistributor
> tables.
>
> This is loosely based on prior work from XiaoDong Huang and
> Peter Geis fixing this issue specifically for Rockchip 356x.

Good Morning,

Since the gic is using dma, would it be reasonable to have all memory
allocations be requested with the GFP_DMA flag? Otherwise this doesn't
fully solve the problem for rk356x, where only the lower 4GB range is
DMA capable, but this tends to get allocated in the upper 4GB on 8GB
boards.

Very Respectfully,
Peter Geis

>
> Suggested-by: Robin Murphy <[email protected]>
> Signed-off-by: Lucas Tanure <[email protected]>
> ---
> drivers/irqchip/irq-gic-v3-its.c | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
>
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 973ede0197e3..1c334dfeb647 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -42,6 +42,7 @@
> #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_DMA_NON_COHERENT (1ULL << 3)
>
> #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
> #define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1)
> @@ -2359,6 +2360,13 @@ 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_DMA_NON_COHERENT) {
> + 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
> @@ -3055,6 +3063,7 @@ static u64 its_clear_vpend_valid(void __iomem *vlpi_base, u64 clr, u64 set)
>
> static void its_cpu_init_lpis(void)
> {
> + struct its_node *its = list_first_entry(&its_nodes, struct its_node, entry);
> void __iomem *rbase = gic_data_rdist_rd_base();
> struct page *pend_page;
> phys_addr_t paddr;
> @@ -3096,6 +3105,9 @@ static void its_cpu_init_lpis(void)
> gicr_write_propbaser(val, rbase + GICR_PROPBASER);
> tmp = gicr_read_propbaser(rbase + GICR_PROPBASER);
>
> + if (its->flags & ITS_FLAGS_DMA_NON_COHERENT)
> + tmp &= ~GICR_PROPBASER_SHAREABILITY_MASK;
> +
> if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) {
> if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) {
> /*
> @@ -3120,6 +3132,9 @@ static void its_cpu_init_lpis(void)
> gicr_write_pendbaser(val, rbase + GICR_PENDBASER);
> tmp = gicr_read_pendbaser(rbase + GICR_PENDBASER);
>
> + if (its->flags & ITS_FLAGS_DMA_NON_COHERENT)
> + tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK;
> +
> if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) {
> /*
> * The HW reports non-shareable, we must remove the
> @@ -5005,6 +5020,7 @@ static int __init its_compute_its_list_map(struct resource *res,
> static int __init its_probe_one(struct resource *res,
> struct fwnode_handle *handle, int numa_node)
> {
> + struct device_node *np = to_of_node(handle);
> struct its_node *its;
> void __iomem *its_base;
> u64 baser, tmp, typer;
> @@ -5076,6 +5092,9 @@ static int __init its_probe_one(struct resource *res,
> its->get_msi_base = its_irq_get_msi_base;
> its->msi_domain_flags = IRQ_DOMAIN_FLAG_MSI_REMAP;
>
> + if (np && !of_dma_is_coherent(np))
> + its->flags |= ITS_FLAGS_DMA_NON_COHERENT;
> +
> its_enable_quirks(its);
>
> err = its_alloc_tables(its);
> @@ -5095,6 +5114,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_DMA_NON_COHERENT)
> + tmp &= ~GITS_CBASER_SHAREABILITY_MASK;
> +
> if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) {
> if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) {
> /*
> --
> 2.39.2
>

2023-03-10 11:57:05

by Marc Zyngier

[permalink] [raw]
Subject: Re: [PATCH 1/7] irqchip/gic-v3: Add a DMA Non-Coherent flag

On Fri, 10 Mar 2023 11:41:46 +0000,
Peter Geis <[email protected]> wrote:
>
> On Fri, Mar 10, 2023 at 3:05 AM Lucas Tanure <[email protected]> wrote:
> >
> > The GIC600 integration in RK356x, used in rk3588, doesn't support
> > any of the shareability or cacheability attributes, and requires
> > both values to be set to 0b00 for all the ITS and Redistributor
> > tables.
> >
> > This is loosely based on prior work from XiaoDong Huang and
> > Peter Geis fixing this issue specifically for Rockchip 356x.
>
> Good Morning,
>
> Since the gic is using dma, would it be reasonable to have all memory
> allocations be requested with the GFP_DMA flag? Otherwise this doesn't
> fully solve the problem for rk356x, where only the lower 4GB range is
> DMA capable, but this tends to get allocated in the upper 4GB on 8GB
> boards.

That's an erratum. Please treat as such.

M.

--
Without deviation from the norm, progress is not possible.

2023-03-10 12:04:35

by Peter Geis

[permalink] [raw]
Subject: Re: [PATCH 1/7] irqchip/gic-v3: Add a DMA Non-Coherent flag

On Fri, Mar 10, 2023 at 6:57 AM Marc Zyngier <[email protected]> wrote:
>
> On Fri, 10 Mar 2023 11:41:46 +0000,
> Peter Geis <[email protected]> wrote:
> >
> > On Fri, Mar 10, 2023 at 3:05 AM Lucas Tanure <[email protected]> wrote:
> > >
> > > The GIC600 integration in RK356x, used in rk3588, doesn't support
> > > any of the shareability or cacheability attributes, and requires
> > > both values to be set to 0b00 for all the ITS and Redistributor
> > > tables.
> > >
> > > This is loosely based on prior work from XiaoDong Huang and
> > > Peter Geis fixing this issue specifically for Rockchip 356x.
> >
> > Good Morning,
> >
> > Since the gic is using dma, would it be reasonable to have all memory
> > allocations be requested with the GFP_DMA flag? Otherwise this doesn't
> > fully solve the problem for rk356x, where only the lower 4GB range is
> > DMA capable, but this tends to get allocated in the upper 4GB on 8GB
> > boards.
>
> That's an erratum. Please treat as such.

Good Morning,

Yes, believe me I'm fully aware of how broken rk356x is. I'm asking an
educational question from a kernel standards point of view, absent the
rk356x issues. Would it be reasonable that since the gic uses dma
memory, allocations for the gic should be made with the GFP_DMA flag?
Or is that a misuse of the flag?

Very Respectfully,
Peter Geis

>
> M.
>
> --
> Without deviation from the norm, progress is not possible.

2023-03-10 12:04:38

by Robin Murphy

[permalink] [raw]
Subject: Re: [PATCH 1/7] irqchip/gic-v3: Add a DMA Non-Coherent flag

On 2023-03-10 11:41, Peter Geis wrote:
> On Fri, Mar 10, 2023 at 3:05 AM Lucas Tanure <[email protected]> wrote:
>>
>> The GIC600 integration in RK356x, used in rk3588, doesn't support
>> any of the shareability or cacheability attributes, and requires
>> both values to be set to 0b00 for all the ITS and Redistributor
>> tables.
>>
>> This is loosely based on prior work from XiaoDong Huang and
>> Peter Geis fixing this issue specifically for Rockchip 356x.
>
> Good Morning,
>
> Since the gic is using dma, would it be reasonable to have all memory
> allocations be requested with the GFP_DMA flag? Otherwise this doesn't
> fully solve the problem for rk356x, where only the lower 4GB range is
> DMA capable, but this tends to get allocated in the upper 4GB on 8GB
> boards.

Not really, because there's no fixed definition of what GFP_DMA actually
means, and it may mean nothing (same for GFP_DMA32, which may or may not
be meaningful depending on kernel config and platform topology). Drivers
should really use the DMA API allocation functions if they care about
what they get, which comes back round to the notion from years ago of
converting the ITS driver to a regular platform driver, so it can
benefit from regular DT concepts like "dma-ranges" automatically.

Thanks,
Robin.

>
> Very Respectfully,
> Peter Geis
>
>>
>> Suggested-by: Robin Murphy <[email protected]>
>> Signed-off-by: Lucas Tanure <[email protected]>
>> ---
>> drivers/irqchip/irq-gic-v3-its.c | 22 ++++++++++++++++++++++
>> 1 file changed, 22 insertions(+)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
>> index 973ede0197e3..1c334dfeb647 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -42,6 +42,7 @@
>> #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_DMA_NON_COHERENT (1ULL << 3)
>>
>> #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
>> #define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1)
>> @@ -2359,6 +2360,13 @@ 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_DMA_NON_COHERENT) {
>> + 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
>> @@ -3055,6 +3063,7 @@ static u64 its_clear_vpend_valid(void __iomem *vlpi_base, u64 clr, u64 set)
>>
>> static void its_cpu_init_lpis(void)
>> {
>> + struct its_node *its = list_first_entry(&its_nodes, struct its_node, entry);
>> void __iomem *rbase = gic_data_rdist_rd_base();
>> struct page *pend_page;
>> phys_addr_t paddr;
>> @@ -3096,6 +3105,9 @@ static void its_cpu_init_lpis(void)
>> gicr_write_propbaser(val, rbase + GICR_PROPBASER);
>> tmp = gicr_read_propbaser(rbase + GICR_PROPBASER);
>>
>> + if (its->flags & ITS_FLAGS_DMA_NON_COHERENT)
>> + tmp &= ~GICR_PROPBASER_SHAREABILITY_MASK;
>> +
>> if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) {
>> if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) {
>> /*
>> @@ -3120,6 +3132,9 @@ static void its_cpu_init_lpis(void)
>> gicr_write_pendbaser(val, rbase + GICR_PENDBASER);
>> tmp = gicr_read_pendbaser(rbase + GICR_PENDBASER);
>>
>> + if (its->flags & ITS_FLAGS_DMA_NON_COHERENT)
>> + tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK;
>> +
>> if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) {
>> /*
>> * The HW reports non-shareable, we must remove the
>> @@ -5005,6 +5020,7 @@ static int __init its_compute_its_list_map(struct resource *res,
>> static int __init its_probe_one(struct resource *res,
>> struct fwnode_handle *handle, int numa_node)
>> {
>> + struct device_node *np = to_of_node(handle);
>> struct its_node *its;
>> void __iomem *its_base;
>> u64 baser, tmp, typer;
>> @@ -5076,6 +5092,9 @@ static int __init its_probe_one(struct resource *res,
>> its->get_msi_base = its_irq_get_msi_base;
>> its->msi_domain_flags = IRQ_DOMAIN_FLAG_MSI_REMAP;
>>
>> + if (np && !of_dma_is_coherent(np))
>> + its->flags |= ITS_FLAGS_DMA_NON_COHERENT;
>> +
>> its_enable_quirks(its);
>>
>> err = its_alloc_tables(its);
>> @@ -5095,6 +5114,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_DMA_NON_COHERENT)
>> + tmp &= ~GITS_CBASER_SHAREABILITY_MASK;
>> +
>> if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) {
>> if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) {
>> /*
>> --
>> 2.39.2
>>

2023-03-10 12:12:38

by Marc Zyngier

[permalink] [raw]
Subject: Re: [PATCH 1/7] irqchip/gic-v3: Add a DMA Non-Coherent flag

On Fri, 10 Mar 2023 12:04:16 +0000,
Peter Geis <[email protected]> wrote:
>
> On Fri, Mar 10, 2023 at 6:57 AM Marc Zyngier <[email protected]> wrote:
> >
> > On Fri, 10 Mar 2023 11:41:46 +0000,
> > Peter Geis <[email protected]> wrote:
> > >
> > > On Fri, Mar 10, 2023 at 3:05 AM Lucas Tanure <[email protected]> wrote:
> > > >
> > > > The GIC600 integration in RK356x, used in rk3588, doesn't support
> > > > any of the shareability or cacheability attributes, and requires
> > > > both values to be set to 0b00 for all the ITS and Redistributor
> > > > tables.
> > > >
> > > > This is loosely based on prior work from XiaoDong Huang and
> > > > Peter Geis fixing this issue specifically for Rockchip 356x.
> > >
> > > Good Morning,
> > >
> > > Since the gic is using dma, would it be reasonable to have all memory
> > > allocations be requested with the GFP_DMA flag? Otherwise this doesn't
> > > fully solve the problem for rk356x, where only the lower 4GB range is
> > > DMA capable, but this tends to get allocated in the upper 4GB on 8GB
> > > boards.
> >
> > That's an erratum. Please treat as such.
>
> Good Morning,
>
> Yes, believe me I'm fully aware of how broken rk356x is. I'm asking an
> educational question from a kernel standards point of view, absent the
> rk356x issues. Would it be reasonable that since the gic uses dma
> memory, allocations for the gic should be made with the GFP_DMA flag?
> Or is that a misuse of the flag?

As Robin points out in another part of the thread, the right fix would
be to convert the ITS as a pure platform driver and handle the probing
dependencies that this would generate. Then you can start making us of
the DMA allocator and of the firmware description of what ranges are
reachable from the GIC (although this isn't strictly the ITS, but
also the redistributors).

We're in a better place for this now than we were a few years ago, but
this is still a sizeable amount of work.

If someone is motivated enough, they can have a go at it.

M.

--
Without deviation from the norm, progress is not possible.

2023-03-10 12:32:02

by Peter Geis

[permalink] [raw]
Subject: Re: [PATCH 4/7] phy: rockchip: Add naneng combo phy support for RK3588

On Fri, Mar 10, 2023 at 3:05 AM Lucas Tanure <[email protected]> wrote:
>
> Add support for RK3588 combo phy
>
> This is based on prior work from XiaoDong Huang and
> Peter Geis fixing this issue specifically for Rockchip 356x.
>
> Co-developed-by: Andrew Powers-Holmes <[email protected]>
> Signed-off-by: Andrew Powers-Holmes <[email protected]>
> Signed-off-by: Lucas Tanure <[email protected]>
> ---
> .../rockchip/phy-rockchip-naneng-combphy.c | 184 ++++++++++++++++++
> 1 file changed, 184 insertions(+)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> index 7b213825fb5d..7b8b001e4f9e 100644
> --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> @@ -63,6 +63,9 @@
> #define PHYREG18 0x44
> #define PHYREG18_PLL_LOOP 0x32
>
> +#define PHYREG27 0x6C
> +#define PHYREG27_RX_TRIM_RK3588 0x4C
> +
> #define PHYREG32 0x7C
> #define PHYREG32_SSC_MASK GENMASK(7, 4)
> #define PHYREG32_SSC_DIR_SHIFT 4
> @@ -114,7 +117,10 @@ struct rockchip_combphy_grfcfg {
> struct combphy_reg con2_for_sata;
> struct combphy_reg con3_for_sata;
> struct combphy_reg pipe_con0_for_sata;
> + struct combphy_reg pipe_con1_for_sata;
> struct combphy_reg pipe_xpcs_phy_ready;
> + struct combphy_reg pipe_pcie1l0_sel;
> + struct combphy_reg pipe_pcie1l1_sel;
> };
>
> struct rockchip_combphy_cfg {
> @@ -559,11 +565,189 @@ static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
> .combphy_cfg = rk3568_combphy_cfg,
> };
>
> +static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)
> +{
> + const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
> + unsigned long rate;
> + u32 val;
> +
> + switch (priv->type) {
> + case PHY_TYPE_PCIE:
> + rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
> + rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
> + rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
> + rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
> + rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l0_sel, true);
> + rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l1_sel, true);

It's theoretically possible to have a different configuration than
both lanes being PCIe. If this exists yet in hardware I can't answer,
but you need to be able to support it. I recommend a similar solution
to what we applied to the PCIe3 phy driver.

> + break;
> + case PHY_TYPE_USB3:
> + /* Set SSC downward spread spectrum */
> + rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK,
> + PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT,
> + PHYREG32);
> +
> + /* Enable adaptive CTLE for USB3.0 Rx. */
> + val = readl(priv->mmio + PHYREG15);
> + val |= PHYREG15_CTLE_EN;
> + writel(val, priv->mmio + PHYREG15);
> +
> + /* Set PLL KVCO fine tuning signals. */
> + rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
> + PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT,
> + PHYREG33);
> +
> + /* Enable controlling random jitter. */
> + writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
> +
> + /* Set PLL input clock divider 1/2. */
> + rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK,
> + PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT,
> + PHYREG6);
> +
> + writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
> + writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
> +
> + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
> + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
> + rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
> + break;
> + case PHY_TYPE_SATA:
> + /* Enable adaptive CTLE for SATA Rx. */
> + val = readl(priv->mmio + PHYREG15);
> + val |= PHYREG15_CTLE_EN;
> + writel(val, priv->mmio + PHYREG15);
> + /*
> + * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA.
> + * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm)
> + */
> + val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT;
> + val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT;
> + writel(val, priv->mmio + PHYREG7);
> +
> + rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
> + rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
> + rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
> + rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
> + rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
> + rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
> + break;
> + case PHY_TYPE_SGMII:
> + case PHY_TYPE_QSGMII:
> + default:
> + dev_err(priv->dev, "incompatible PHY type\n");
> + return -EINVAL;
> + }
> +
> + rate = clk_get_rate(priv->refclk);
> +
> + switch (rate) {
> + case REF_CLOCK_24MHz:
> + if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) {
> + /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */
> + val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT;
> + rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK,
> + val, PHYREG15);
> +
> + writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
> + }
> + break;
> +
> + case REF_CLOCK_25MHz:
> + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
> + break;
> + case REF_CLOCK_100MHz:
> + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
> + if (priv->type == PHY_TYPE_PCIE) {
> + /* PLL KVCO fine tuning. */
> + val = 4 << PHYREG33_PLL_KVCO_SHIFT;
> + rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
> + val, PHYREG33);
> +
> + /* Enable controlling random jitter. */
> + writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
> +
> + /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
> + writel(PHYREG27_RX_TRIM_RK3588, priv->mmio + PHYREG27);
> +
> + /* Set up su_trim: */
> + writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
> + } else if (priv->type == PHY_TYPE_SATA) {
> + /* downward spread spectrum +500ppm */
> + val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT;
> + val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT;
> + rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
> + }
> + break;
> + default:
> + dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
> + return -EINVAL;
> + }
> +
> + if (priv->ext_refclk) {
> + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
> + if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
> + val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT;
> + val |= PHYREG13_CKRCV_AMP0;
> + rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13);
> +
> + val = readl(priv->mmio + PHYREG14);
> + val |= PHYREG14_CKRCV_AMP1;
> + writel(val, priv->mmio + PHYREG14);
> + }
> + }
> +
> + if (priv->enable_ssc) {
> + val = readl(priv->mmio + PHYREG8);
> + val |= PHYREG8_SSC_EN;
> + writel(val, priv->mmio + PHYREG8);
> + }
> +
> + return 0;
> +}
> +
> +static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = {
> + /* pipe-phy-grf */
> + .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 },
> + .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 },
> + .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 },
> + .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 },
> + .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 },
> + .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 },
> + .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 },
> + .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 },
> + .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 },
> + .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 },
> + .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 },
> + .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 },
> + .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 },
> + .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 },
> + .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 },
> + .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 },
> + .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0129 },
> + .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0000 },
> + .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c1 },
> + .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x0407 },
> + /* pipe-grf */
> + .pipe_con0_for_sata = { 0x0000, 11, 5, 0x00, 0x22 },
> + .pipe_con1_for_sata = { 0x0000, 2, 0, 0x00, 0x2 },
> + .pipe_pcie1l0_sel = { 0x0100, 0, 0, 0x01, 0x0 },
> + .pipe_pcie1l1_sel = { 0x0100, 1, 1, 0x01, 0x0 },
> +};
> +
> +static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = {
> + .grfcfg = &rk3588_combphy_grfcfgs,
> + .combphy_cfg = rk3588_combphy_cfg,
> +};
> +
> static const struct of_device_id rockchip_combphy_of_match[] = {
> {
> .compatible = "rockchip,rk3568-naneng-combphy",
> .data = &rk3568_combphy_cfgs,
> },
> + {
> + .compatible = "rockchip,rk3588-naneng-combphy",
> + .data = &rk3588_combphy_cfgs,
> + },
> { },
> };
> MODULE_DEVICE_TABLE(of, rockchip_combphy_of_match);
> --
> 2.39.2
>

2023-03-12 11:32:37

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH 3/7] dt-bindings: phy: rockchip: Add rk3588 compatible line

On 10/03/2023 09:05, Lucas Tanure wrote:
> RK3568 Naneng Combo Phy driver can support RK3588 with the additional
> clocks and initial configuration, so add the compatible line.
>
> Signed-off-by: Lucas Tanure <[email protected]>


Acked-by: Krzysztof Kozlowski <[email protected]>

Best regards,
Krzysztof


2023-03-14 13:28:43

by Lucas Tanure

[permalink] [raw]
Subject: Re: [PATCH 1/7] irqchip/gic-v3: Add a DMA Non-Coherent flag

On 10-03-2023 12:04, Robin Murphy wrote:
> On 2023-03-10 11:41, Peter Geis wrote:
>> On Fri, Mar 10, 2023 at 3:05 AM Lucas Tanure
>> <[email protected]> wrote:
>>>
>>> The GIC600 integration in RK356x, used in rk3588, doesn't support
>>> any of the shareability or cacheability attributes, and requires
>>> both values to be set to 0b00 for all the ITS and Redistributor
>>> tables.
>>>
>>> This is loosely based on prior work from XiaoDong Huang and
>>> Peter Geis fixing this issue specifically for Rockchip 356x.
>>
>> Good Morning,
>>
>> Since the gic is using dma, would it be reasonable to have all memory
>> allocations be requested with the GFP_DMA flag? Otherwise this doesn't
>> fully solve the problem for rk356x, where only the lower 4GB range is
>> DMA capable, but this tends to get allocated in the upper 4GB on 8GB
>> boards.
>
> Not really, because there's no fixed definition of what GFP_DMA actually
> means, and it may mean nothing (same for GFP_DMA32, which may or may not
> be meaningful depending on kernel config and platform topology). Drivers
> should really use the DMA API allocation functions if they care about
> what they get, which comes back round to the notion from years ago of
> converting the ITS driver to a regular platform driver, so it can
> benefit from regular DT concepts like "dma-ranges" automatically.
>
> Thanks,
> Robin.
>
I am looking how to do that conversion to platform driver.
But about the communication between irq-gic-v3-its and irq-gic-v3.
Should irq-gic-v3-its be a MFD child of irq-gic-v3?
Or use the component bind/unbind framework?

>>
>> Very Respectfully,
>> Peter Geis
>>
>>>
>>> Suggested-by: Robin Murphy <[email protected]>
>>> Signed-off-by: Lucas Tanure <[email protected]>
>>> ---
>>>   drivers/irqchip/irq-gic-v3-its.c | 22 ++++++++++++++++++++++
>>>   1 file changed, 22 insertions(+)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-v3-its.c
>>> b/drivers/irqchip/irq-gic-v3-its.c
>>> index 973ede0197e3..1c334dfeb647 100644
>>> --- a/drivers/irqchip/irq-gic-v3-its.c
>>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>>> @@ -42,6 +42,7 @@
>>>   #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_DMA_NON_COHERENT             (1ULL << 3)
>>>
>>>   #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING    (1 << 0)
>>>   #define RDIST_FLAGS_RD_TABLES_PREALLOCATED     (1 << 1)
>>> @@ -2359,6 +2360,13 @@ 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_DMA_NON_COHERENT) {
>>> +               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
>>> @@ -3055,6 +3063,7 @@ static u64 its_clear_vpend_valid(void __iomem
>>> *vlpi_base, u64 clr, u64 set)
>>>
>>>   static void its_cpu_init_lpis(void)
>>>   {
>>> +       struct its_node *its = list_first_entry(&its_nodes, struct
>>> its_node, entry);
>>>          void __iomem *rbase = gic_data_rdist_rd_base();
>>>          struct page *pend_page;
>>>          phys_addr_t paddr;
>>> @@ -3096,6 +3105,9 @@ static void its_cpu_init_lpis(void)
>>>          gicr_write_propbaser(val, rbase + GICR_PROPBASER);
>>>          tmp = gicr_read_propbaser(rbase + GICR_PROPBASER);
>>>
>>> +       if (its->flags & ITS_FLAGS_DMA_NON_COHERENT)
>>> +               tmp &= ~GICR_PROPBASER_SHAREABILITY_MASK;
>>> +
>>>          if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) {
>>>                  if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) {
>>>                          /*
>>> @@ -3120,6 +3132,9 @@ static void its_cpu_init_lpis(void)
>>>          gicr_write_pendbaser(val, rbase + GICR_PENDBASER);
>>>          tmp = gicr_read_pendbaser(rbase + GICR_PENDBASER);
>>>
>>> +       if (its->flags & ITS_FLAGS_DMA_NON_COHERENT)
>>> +               tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK;
>>> +
>>>          if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) {
>>>                  /*
>>>                   * The HW reports non-shareable, we must remove the
>>> @@ -5005,6 +5020,7 @@ static int __init
>>> its_compute_its_list_map(struct resource *res,
>>>   static int __init its_probe_one(struct resource *res,
>>>                                  struct fwnode_handle *handle, int
>>> numa_node)
>>>   {
>>> +       struct device_node *np = to_of_node(handle);
>>>          struct its_node *its;
>>>          void __iomem *its_base;
>>>          u64 baser, tmp, typer;
>>> @@ -5076,6 +5092,9 @@ static int __init its_probe_one(struct resource
>>> *res,
>>>          its->get_msi_base = its_irq_get_msi_base;
>>>          its->msi_domain_flags = IRQ_DOMAIN_FLAG_MSI_REMAP;
>>>
>>> +       if (np && !of_dma_is_coherent(np))
>>> +               its->flags |= ITS_FLAGS_DMA_NON_COHERENT;
>>> +
>>>          its_enable_quirks(its);
>>>
>>>          err = its_alloc_tables(its);
>>> @@ -5095,6 +5114,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_DMA_NON_COHERENT)
>>> +               tmp &= ~GITS_CBASER_SHAREABILITY_MASK;
>>> +
>>>          if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) {
>>>                  if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) {
>>>                          /*
>>> --
>>> 2.39.2
>>>


2023-03-14 14:14:39

by Marc Zyngier

[permalink] [raw]
Subject: Re: [PATCH 1/7] irqchip/gic-v3: Add a DMA Non-Coherent flag

On Tue, 14 Mar 2023 13:25:28 +0000,
Lucas Tanure <[email protected]> wrote:
>
> On 10-03-2023 12:04, Robin Murphy wrote:
> > On 2023-03-10 11:41, Peter Geis wrote:
> >> On Fri, Mar 10, 2023 at 3:05 AM Lucas Tanure
> >> <[email protected]> wrote:
> >>>
> >>> The GIC600 integration in RK356x, used in rk3588, doesn't support
> >>> any of the shareability or cacheability attributes, and requires
> >>> both values to be set to 0b00 for all the ITS and Redistributor
> >>> tables.
> >>>
> >>> This is loosely based on prior work from XiaoDong Huang and
> >>> Peter Geis fixing this issue specifically for Rockchip 356x.
> >>
> >> Good Morning,
> >>
> >> Since the gic is using dma, would it be reasonable to have all memory
> >> allocations be requested with the GFP_DMA flag? Otherwise this doesn't
> >> fully solve the problem for rk356x, where only the lower 4GB range is
> >> DMA capable, but this tends to get allocated in the upper 4GB on 8GB
> >> boards.
> >
> > Not really, because there's no fixed definition of what GFP_DMA
> > actually means, and it may mean nothing (same for GFP_DMA32, which
> > may or may not be meaningful depending on kernel config and platform
> > topology). Drivers should really use the DMA API allocation
> > functions if they care about what they get, which comes back round
> > to the notion from years ago of converting the ITS driver to a
> > regular platform driver, so it can benefit from regular DT concepts
> > like "dma-ranges" automatically.
> >
> > Thanks,
> > Robin.
> >
> I am looking how to do that conversion to platform driver.
> But about the communication between irq-gic-v3-its and irq-gic-v3.
> Should irq-gic-v3-its be a MFD child of irq-gic-v3?

MFD? I'd rather suggest an VME bus driver. ;-)

Seriously, this is an interrupt controller. Nothing else. It should
probe the parent irqdomain, and stack onto that. No parent? Probe
deferral.

> Or use the component bind/unbind framework?

I don't understand what you mean here.

M.

--
Without deviation from the norm, progress is not possible.