On Thu, Mar 24, 2022 at 04:25:13AM +0300, Serge Semin wrote: > Commit c2b0c098fbd1 ("PCI: dwc: Use generic config accessors") replaced > the locally defined DW PCIe host controller config-space accessors with > the generic methods pci_generic_config_read() and > pci_generic_config_write(). It was intended that the corresponding > bus-mapping callback returned a correct virtual address of the passed PCI > config-space register. The problem of the proposed solution was that it > didn't take into account the way the host config-space is accessed on the > DW PCIe. Depending on the DW PCIe IP-core synthesize parameters different > interfaces can be used to access the host and peripheral config/memory > spaces. The former one can be accessed via the DBI interface, while the > later ones is reached via the AHB/AXI application bus. In case if the DW > PCIe controller is configured to have a dedicated DBI interface, the way > it is mapped into the IO-memory turns to be platform-specific. For such > setups the DWC PCIe driver provides a set of the callbacks > dw_pcie_ops.{read_dbi,write_dbi} so the platforms glue-drivers would be > able to take into account the DBI bus IO peculiarities. Since > commit c2b0c098fbd1 ("PCI: dwc: Use generic config accessors") these > methods haven't been utilized during the generic host initialization > performed by the PCIe subsystem code. > > I don't really know how come there have been no problems spotted for the > Histb/Exynos/Kirin PCIe controllers so far, but in our case with dword > aligned IO requirement the generic config-space accessors can't be > utilized for the host config-space. Thus in order to make sure the host > config-space is properly accessed via the DBI bus let's get back the > dw_pcie_rd_own_conf() and dw_pcie_wr_own_conf() methods. They are going to > be just wrappers around the already defined > dw_pcie_read_dbi()/dw_pcie_write_dbi() functions with proper arguments > conversion. These methods perform the platform-specific config-space IO if > the DBI accessors are specified, otherwise they call normal MMIO > operations. > Why can't you override the "pci_ops" in your host driver's "host_init"? Thanks, Mani > Fixes: c2b0c098fbd1 ("PCI: dwc: Use generic config accessors") > Signed-off-by: Serge Semin <Sergey.Semin@xxxxxxxxxxxxxxxxxxxx> > --- > .../pci/controller/dwc/pcie-designware-host.c | 34 +++++++++++++++++-- > 1 file changed, 32 insertions(+), 2 deletions(-) > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c > index a03619a30c20..f89e6552139b 100644 > --- a/drivers/pci/controller/dwc/pcie-designware-host.c > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c > @@ -528,10 +528,40 @@ void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus, unsigned int devfn, > } > EXPORT_SYMBOL_GPL(dw_pcie_own_conf_map_bus); > > +static int dw_pcie_rd_own_conf(struct pci_bus *bus, unsigned int devfn, > + int where, int size, u32 *val) > +{ > + struct pcie_port *pp = bus->sysdata; > + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); > + > + if (PCI_SLOT(devfn) > 0) { > + *val = ~0U; > + return PCIBIOS_DEVICE_NOT_FOUND; > + } > + > + *val = dw_pcie_read_dbi(pci, where, size); > + > + return PCIBIOS_SUCCESSFUL; > +} > + > +static int dw_pcie_wr_own_conf(struct pci_bus *bus, unsigned int devfn, > + int where, int size, u32 val) > +{ > + struct pcie_port *pp = bus->sysdata; > + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); > + > + if (PCI_SLOT(devfn) > 0) > + return PCIBIOS_DEVICE_NOT_FOUND; > + > + dw_pcie_write_dbi(pci, where, size, val); > + > + return PCIBIOS_SUCCESSFUL; > +} > + > static struct pci_ops dw_pcie_ops = { > .map_bus = dw_pcie_own_conf_map_bus, > - .read = pci_generic_config_read, > - .write = pci_generic_config_write, > + .read = dw_pcie_rd_own_conf, > + .write = dw_pcie_wr_own_conf, > }; > > void dw_pcie_setup_rc(struct pcie_port *pp) > -- > 2.35.1 >