On Fri, Jun 24, 2022 at 05:39:36PM +0300, Serge Semin wrote: > Since DWC PCIe v4.70a the controller version and version type can be read > from the PORT_LOGIC.PCIE_VERSION_OFF and PORT_LOGIC.PCIE_VERSION_TYPE_OFF > registers respectively. Seeing the generic code has got version-dependent > parts let's use these registers to find out the controller version. The > detection procedure is executed for both RC and EP modes right after the > platform-specific initialization. We can't do that earlier since the > glue-drivers can perform the DBI-related setups there including the bus > reference clocks activation, without which the CSRs just can't be read. > > Note the CSRs content is zero on the older DWC PCIe controller. In that > case we have no choice but to rely on the platform setup. > > Signed-off-by: Serge Semin <Sergey.Semin@xxxxxxxxxxxxxxxxxxxx> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx> > Reviewed-by: Rob Herring <robh@xxxxxxxxxx> > > --- > > Changelog v2: > - Move the IP-core version detection procedure call from > dw_pcie_ep_init_complete() to dw_pcie_ep_init(). > --- > .../pci/controller/dwc/pcie-designware-ep.c | 2 ++ > .../pci/controller/dwc/pcie-designware-host.c | 2 ++ > drivers/pci/controller/dwc/pcie-designware.c | 24 +++++++++++++++++++ > drivers/pci/controller/dwc/pcie-designware.h | 6 +++++ > 4 files changed, 34 insertions(+) > > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c > index 1e35542d6f72..ffbd3af6d65a 100644 > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c > @@ -711,6 +711,8 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) > ep->phys_base = res->start; > ep->addr_size = resource_size(res); > > + dw_pcie_version_detect(pci); > + There is still an ongoing debate about moving all DBI accesses to init_complete. But this is fine atm. Thanks, Mani > dw_pcie_iatu_detect(pci); > > ep->ib_window_map = devm_kcalloc(dev, > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c > index 95256434913f..b1437b37140f 100644 > --- a/drivers/pci/controller/dwc/pcie-designware-host.c > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c > @@ -405,6 +405,8 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) > } > } > > + dw_pcie_version_detect(pci); > + > dw_pcie_iatu_detect(pci); > > dw_pcie_setup_rc(pp); > diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c > index f10a7d5d94e8..cbb36ccaa48b 100644 > --- a/drivers/pci/controller/dwc/pcie-designware.c > +++ b/drivers/pci/controller/dwc/pcie-designware.c > @@ -16,6 +16,30 @@ > #include "../../pci.h" > #include "pcie-designware.h" > > +void dw_pcie_version_detect(struct dw_pcie *pci) > +{ > + u32 ver; > + > + /* The content of the CSR is zero on DWC PCIe older than v4.70a */ > + ver = dw_pcie_readl_dbi(pci, PCIE_VERSION_NUMBER); > + if (!ver) > + return; > + > + if (pci->version && pci->version != ver) > + dev_warn(pci->dev, "Versions don't match (%08x != %08x)\n", > + pci->version, ver); > + else > + pci->version = ver; > + > + ver = dw_pcie_readl_dbi(pci, PCIE_VERSION_TYPE); > + > + if (pci->type && pci->type != ver) > + dev_warn(pci->dev, "Types don't match (%08x != %08x)\n", > + pci->type, ver); > + else > + pci->type = ver; > +} > + > /* > * These interfaces resemble the pci_find_*capability() interfaces, but these > * are for configuring host controllers, which are bridges *to* PCI devices but > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h > index 6b81530fb2ca..7899808bdbc6 100644 > --- a/drivers/pci/controller/dwc/pcie-designware.h > +++ b/drivers/pci/controller/dwc/pcie-designware.h > @@ -85,6 +85,9 @@ > #define PCIE_PORT_MULTI_LANE_CTRL 0x8C0 > #define PORT_MLTI_UPCFG_SUPPORT BIT(7) > > +#define PCIE_VERSION_NUMBER 0x8F8 > +#define PCIE_VERSION_TYPE 0x8FC > + > #define PCIE_ATU_VIEWPORT 0x900 > #define PCIE_ATU_REGION_INBOUND BIT(31) > #define PCIE_ATU_REGION_OUTBOUND 0 > @@ -279,6 +282,7 @@ struct dw_pcie { > struct dw_pcie_ep ep; > const struct dw_pcie_ops *ops; > u32 version; > + u32 type; > int num_lanes; > int link_gen; > u8 n_fts[2]; > @@ -290,6 +294,8 @@ struct dw_pcie { > #define to_dw_pcie_from_ep(endpoint) \ > container_of((endpoint), struct dw_pcie, ep) > > +void dw_pcie_version_detect(struct dw_pcie *pci); > + > u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap); > u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap); > > -- > 2.35.1 > -- மணிவண்ணன் சதாசிவம்