From: Tobias Heider 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 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);