From: Mark Kettenis Subject: Re: dwpcie: initialize Qualcomm PARF glue for Glymur To: Tobias Heider Cc: tech@openbsd.org, patrick@openbsd.org, kettenis@openbsd.org Date: Fri, 25 Sep 2026 11:52:26 +0200 > Date: Fri, 25 Sep 2026 01:51:22 +0200 > From: Tobias Heider > > 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. I wonder why this isn't an issue on those older SoCs. Could it be that on Glymor the firmware uses a different configuration than what's specified in the device tree? Anyway, I think this is fine for now. We can extend the configuration to the older SoCs later. > ok? One nit below; otherwise ok kettenis@ P.S. Theo was asking about Snapdragon X2 support on icb the other day. I told him you probably know more about what works and what doesn't work than I. > 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 */ Since these registers aren't specific to Glymor, maybe just say: /* Qualcomm 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); > > >