Message ID | 20220324013734.18234-6-Sergey.Semin@baikalelectronics.ru |
---|---|
State | New |
Headers | show |
Series | PCI: dwc: Add dma-ranges/YAML-schema/Baikal-T1 support | expand |
On Thu, Mar 24, 2022 at 04:37:23AM +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@baikalelectronics.ru> > --- > .../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 7c9315fffe24..3b981d13cca9 100644 > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c > @@ -645,6 +645,8 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) > u32 reg; > int i; > > + dw_pcie_version_detect(pci); > + > hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) & > PCI_HEADER_TYPE_MASK; > if (hdr_type != PCI_HEADER_TYPE_NORMAL) { > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c > index 8364ea234e88..8f0d473ff770 100644 > --- a/drivers/pci/controller/dwc/pcie-designware-host.c > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c > @@ -398,6 +398,8 @@ int dw_pcie_host_init(struct pcie_port *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 c21373c6cb51..49c494d82042 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); Trust the h/w is correct until we have a known case where it isn't. Just read the h/w reg if pci->version is zero. I would suspect as-is this will give some warnings. No doubt there is some platform with multiple revs of Si that didn't change their version in the driver. Or the author just guessed on the version that picked the right paths in the driver. Rob
On Tue, Mar 29, 2022 at 10:08:53AM -0500, Rob Herring wrote: > On Thu, Mar 24, 2022 at 04:37:23AM +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@baikalelectronics.ru> > > --- > > .../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 7c9315fffe24..3b981d13cca9 100644 > > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c > > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c > > @@ -645,6 +645,8 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) > > u32 reg; > > int i; > > > > + dw_pcie_version_detect(pci); > > + > > hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) & > > PCI_HEADER_TYPE_MASK; > > if (hdr_type != PCI_HEADER_TYPE_NORMAL) { > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c > > index 8364ea234e88..8f0d473ff770 100644 > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c > > @@ -398,6 +398,8 @@ int dw_pcie_host_init(struct pcie_port *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 c21373c6cb51..49c494d82042 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); > > Trust the h/w is correct until we have a known case where it isn't. Just > read the h/w reg if pci->version is zero. > > I would suspect as-is this will give some warnings. No doubt there is > some platform with multiple revs of Si that didn't change their version > in the driver. Or the author just guessed on the version that picked the > right paths in the driver. I'm not sure I fully get it. Could you elaborate what you suggest here? Do you suggest for me to drop the warnings and rewrite the pci->{version, type} fields with the values read from the registers if these fields were set with zeros? -Sergey > > Rob
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 7c9315fffe24..3b981d13cca9 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -645,6 +645,8 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) u32 reg; int i; + dw_pcie_version_detect(pci); + hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) & PCI_HEADER_TYPE_MASK; if (hdr_type != PCI_HEADER_TYPE_NORMAL) { diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 8364ea234e88..8f0d473ff770 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -398,6 +398,8 @@ int dw_pcie_host_init(struct pcie_port *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 c21373c6cb51..49c494d82042 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 5be43c662176..f70cbdedf5a3 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 @@ -278,6 +281,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);
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@baikalelectronics.ru> --- .../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(+)