Index | Thread | Search

From:
Tobias Heider <tobias.heider@stusta.de>
Subject:
dwpcie: initialize Qualcomm PARF glue for Glymur
To:
tech@openbsd.org
Cc:
patrick@openbsd.org, kettenis@openbsd.org
Date:
Fri, 25 Sep 2026 01:51:22 +0200

Download raw body.

Thread
On Qualcomm Glymur SoCs it looks like we need to explicitly configure
the DBI and ATU register windows in the PARF wrapper to make them work.
Without this we get a timeout in dwpcie_atu_config (and no NVME).

Currently this only adds the initialization for glymur. Technically
it looks like sc8280xp and x1e80100 support the same init sequence
but since it didn't cause issues so far I'm assuming it comes
pre-configured by firmware on those.

ok?

diff df887fd1d5630a53a50e8c53614faa20fadd33d7 38a3f2df271ba42cdc0ef2562894c05324fdbcdd
commit - df887fd1d5630a53a50e8c53614faa20fadd33d7
commit + 38a3f2df271ba42cdc0ef2562894c05324fdbcdd
blob - 40ee2922e0855a56664b137144d551dc16a599b7
blob + b604af06693aba95bc89fb61d3a73dabe74a02ee
--- sys/dev/fdt/dwpcie.c
+++ sys/dev/fdt/dwpcie.c
@@ -191,6 +191,15 @@
 #define  PCIE_CLIENT_LTSSM_MASK			(0x1f << 0)
 #define  PCIE_CLIENT_LTSSM_UP			(0x11 << 0)
 
+/* Qualcomm Glymur registers */
+#define QCOM_PARF_DBI_BASE_ADDR_V2		0x350
+#define QCOM_PARF_DBI_BASE_ADDR_V2_HI		0x354
+#define QCOM_PARF_SLV_ADDR_SPACE_SIZE_V2	0x358
+#define QCOM_PARF_SLV_ADDR_SPACE_SIZE_V2_HI	0x35c
+#define  QCOM_PARF_SLV_ADDR_SPACE_SIZE_DEFAULT	0x80000000
+#define QCOM_PARF_ATU_BASE_ADDR			0x634
+#define QCOM_PARF_ATU_BASE_ADDR_HI		0x638
+
 #define HREAD4(sc, reg)							\
 	(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
 #define HWRITE4(sc, reg, val)						\
@@ -325,6 +334,7 @@ dwpcie_match(struct device *parent, void *match, void 
 	    OF_is_compatible(faa->fa_node, "qcom,pcie-sc7280") ||
 	    OF_is_compatible(faa->fa_node, "qcom,pcie-sc8280xp") ||
 	    OF_is_compatible(faa->fa_node, "qcom,pcie-x1e80100") ||
+	    OF_is_compatible(faa->fa_node, "qcom,glymur-pcie") ||
 	    OF_is_compatible(faa->fa_node, "rockchip,rk3568-pcie") ||
 	    OF_is_compatible(faa->fa_node, "rockchip,rk3588-pcie") ||
 	    OF_is_compatible(faa->fa_node, "sifive,fu740-pcie") ||
@@ -465,6 +475,17 @@ dwpcie_attach(struct device *parent, struct device *se
 		sc->sc_glue_size = faa->fa_reg[glue].size;
 	}
 
+	if (OF_is_compatible(faa->fa_node, "qcom,glymur-pcie")) {
+		glue = OF_getindex(faa->fa_node, "parf", "reg-names");
+		if (glue < 0 || glue >= faa->fa_nreg) {
+			printf(": no parf registers\n");
+			return;
+		}
+
+		sc->sc_glue_base = faa->fa_reg[glue].addr;
+		sc->sc_glue_size = faa->fa_reg[glue].size;
+	}
+
 	sc->sc_iot = faa->fa_iot;
 	sc->sc_dmat = faa->fa_dmat;
 	sc->sc_node = faa->fa_node;
@@ -563,7 +584,8 @@ dwpcie_attach_deferred(struct device *self)
 		error = dwpcie_imx8mq_init(sc);
 	if (OF_is_compatible(sc->sc_node, "qcom,pcie-sc7280") ||
 	    OF_is_compatible(sc->sc_node, "qcom,pcie-sc8280xp") ||
-	    OF_is_compatible(sc->sc_node, "qcom,pcie-x1e80100"))
+	    OF_is_compatible(sc->sc_node, "qcom,pcie-x1e80100") ||
+	    OF_is_compatible(sc->sc_node, "qcom,glymur-pcie"))
 		error = dwpcie_sc7280_init(sc);
 	if (OF_is_compatible(sc->sc_node, "rockchip,rk3568-pcie") ||
 	    OF_is_compatible(sc->sc_node, "rockchip,rk3588-pcie"))
@@ -1852,6 +1874,30 @@ dwpcie_sc7280_init(struct dwpcie_softc *sc)
 {
 	sc->sc_num_viewport = 8;
 
+	if (OF_is_compatible(sc->sc_node, "qcom,glymur-pcie")) {
+		if (bus_space_map(sc->sc_iot, sc->sc_glue_base,
+		    sc->sc_glue_size, 0, &sc->sc_glue_ioh))
+			return ENOMEM;
+
+		bus_space_write_4(sc->sc_iot, sc->sc_glue_ioh,
+		    QCOM_PARF_DBI_BASE_ADDR_V2, (uint32_t)sc->sc_ctrl_base);
+		bus_space_write_4(sc->sc_iot, sc->sc_glue_ioh,
+		    QCOM_PARF_DBI_BASE_ADDR_V2_HI,
+		    (uint32_t)(sc->sc_ctrl_base >> 32));
+
+		bus_space_write_4(sc->sc_iot, sc->sc_glue_ioh,
+		    QCOM_PARF_ATU_BASE_ADDR, (uint32_t)sc->sc_atu_base);
+		bus_space_write_4(sc->sc_iot, sc->sc_glue_ioh,
+		    QCOM_PARF_ATU_BASE_ADDR_HI,
+		    (uint32_t)(sc->sc_atu_base >> 32));
+
+		bus_space_write_4(sc->sc_iot, sc->sc_glue_ioh,
+		    QCOM_PARF_SLV_ADDR_SPACE_SIZE_V2, 0);
+		bus_space_write_4(sc->sc_iot, sc->sc_glue_ioh,
+		    QCOM_PARF_SLV_ADDR_SPACE_SIZE_V2_HI,
+		    QCOM_PARF_SLV_ADDR_SPACE_SIZE_DEFAULT);
+	}
+
 	if (OF_getproplen(sc->sc_node, "msi-map") <= 0)
 		return dwpcie_msi_init(sc);