Am Do., 4. Mai 2023 um 13:33 Uhr schrieb Verma, Achal <a-verma1@xxxxxx>: > > > > On 4/27/2023 11:20 AM, Dominic Rath wrote: > > From: Alexander Bahle <bahle@xxxxxxxxxxxxxxx> > > > > Use optional "tx-phy-latency-ps" and "rx-phy-latency-ps" > > DeviceTree bindings to set the CDNS_PCIE_LM_PTM_LAT_PARAM(_IDX) > > register(s) during PCIe host and endpoint setup. > > > > The properties are lists of uint32 PHY latencies in picoseconds for > > every supported speed starting at PCIe Gen1, e.g.: > > > > tx-phy-latency-ps = <100000 200000>; /* Gen1: 100ns, Gen2: 200ns */ > > rx-phy-latency-ps = <150000 250000>; /* Gen1: 150ns, Gen2: 250ns */ > > > > There should be a value for every supported speed, otherwise a info > > message is emitted to let users know that the PTM timestamps from this > > PCIe device may not be precise enough for some applications. > > > > Signed-off-by: Alexander Bahle <bahle@xxxxxxxxxxxxxxx> > > Signed-off-by: Dominic Rath <rath@xxxxxxxxxxxxxxx> > > --- > > .../pci/controller/cadence/pcie-cadence-ep.c | 2 + > > .../controller/cadence/pcie-cadence-host.c | 1 + > > drivers/pci/controller/cadence/pcie-cadence.c | 92 +++++++++++++++++++ > > drivers/pci/controller/cadence/pcie-cadence.h | 23 +++++ > > 4 files changed, 118 insertions(+) > > > > diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c > > index b8b655d4047e..6e39126922d1 100644 > > --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c > > +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c > > @@ -664,6 +664,8 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep) > > } > > pcie->mem_res = res; > > > > + cdns_pcie_init_ptm_phy_latency(dev, pcie); > > + > > ep->max_regions = CDNS_PCIE_MAX_OB; > > of_property_read_u32(np, "cdns,max-outbound-regions", &ep->max_regions); > > > > diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c > > index 940c7dd701d6..8933002f828e 100644 > > --- a/drivers/pci/controller/cadence/pcie-cadence-host.c > > +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c > > @@ -510,6 +510,7 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc) > > cdns_pcie_detect_quiet_min_delay_set(&rc->pcie); > > > > cdns_pcie_host_enable_ptm_response(pcie) > Hi Dominic, > Shouldn't cdns_pcie_init_ptm_phy_latency() called before > cdns_pcie_host_enable_ptm_response(), enabling host to reply PTM > requests. However host could receive PTM requests later only after > cdns_pcie_start_link(). Good catch! > > + cdns_pcie_init_ptm_phy_latency(dev, pcie); > > > > ret = cdns_pcie_start_link(pcie); > > if (ret) { > > diff --git a/drivers/pci/controller/cadence/pcie-cadence.c b/drivers/pci/controller/cadence/pcie-cadence.c > > index 13c4032ca379..1a282ed9b888 100644 > > --- a/drivers/pci/controller/cadence/pcie-cadence.c > > +++ b/drivers/pci/controller/cadence/pcie-cadence.c > > @@ -5,8 +5,100 @@ > > > > #include <linux/kernel.h> > > > > +#include "../../pci.h" > > #include "pcie-cadence.h" > > > > +void cdns_pcie_set_ptm_phy_latency_param(struct cdns_pcie *pcie, bool rx, > > + u32 speed_index, u32 latency) > > +{ > > + u32 val; > > + > > + /* Set the speed index */ > > + val = cdns_pcie_readl(pcie, CDNS_PCIE_LM_PTM_LAT_PARAM_IDX); > > + val = ((val & ~CDNS_PCIE_LM_PTM_LAT_PARAM_IDX_PTMLATIN_MASK) | > > + CDNS_PCIE_LM_PTM_LAT_PARAM_IDX_PTMLATIN(speed_index)); > > + cdns_pcie_writel(pcie, CDNS_PCIE_LM_PTM_LAT_PARAM_IDX, val); > > + > > + val = cdns_pcie_readl(pcie, CDNS_PCIE_LM_PTM_LAT_PARAM); > > + if (rx) { > > + /* Set the RX direction latency */ > > + val = ((val & ~CDNS_PCIE_LM_PTM_LAT_PARAM_PTMRXLAT_MASK) | > > + CDNS_PCIE_LM_PTM_LAT_PARAM_PTMRXLAT(latency)); > > + } else { > > + /* Set TX direction latency */ > > + val = ((val & ~CDNS_PCIE_LM_PTM_LAT_PARAM_PTMTXLAT_MASK) | > > + CDNS_PCIE_LM_PTM_LAT_PARAM_PTMTXLAT(latency)); > > + } > > + cdns_pcie_writel(pcie, CDNS_PCIE_LM_PTM_LAT_PARAM, val); > > +} > > + > > +static int cdns_pcie_set_ptm_phy_latency(struct device *dev, struct cdns_pcie *pcie, > > + bool rx, const char *key) > > +{ > > + struct device_node *np; > > + int max_link_speed; > > + int param_count; > > + u32 latency; > > + int ret; > > + int i; > > + > > + /* Do nothing if there is no phy */ > > + if (pcie->phy_count < 1) > > + return 0; > > + > > + np = dev->of_node; > > + max_link_speed = of_pci_get_max_link_speed(np); > > + if (max_link_speed < 1) > > + return -EINVAL; > > + > > + /* Only check and use params of the first phy */ > > + np = pcie->phy[0]->dev.of_node; > > + param_count = of_property_count_u32_elems(np, key); > > + if (param_count < 0 || param_count < max_link_speed) { > > + dev_info(dev, > > + "PTM: no %s set for one or more speeds: %d\n", > > + key, param_count); > > + } > > + > > + /* Don't set param for unsupported speed */ > > + if (param_count > max_link_speed) > > + param_count = max_link_speed; > > + > > + for (i = 0; i < param_count; i++) { > > + ret = of_property_read_u32_index(np, key, i, &latency); > > + if (ret != 0) { > > + dev_err(dev, "failed to read PTM latency for speed %d from %s\n", > > + i, key); > > + return ret; > > + } > > + > > + /* convert ps to ns */ > > + latency /= 1000; > > + > > + cdns_pcie_set_ptm_phy_latency_param(pcie, rx, > > + i, latency); > > + > > + dev_dbg(dev, "PTM: %s phy latency Gen.%d: %uns\n", > > + rx ? "rx" : "tx", i+1, latency); > > + } > > + > > + return 0; > > +} > > + > > +int cdns_pcie_init_ptm_phy_latency(struct device *dev, struct cdns_pcie *pcie) > > +{ > > + int ret; > > + > > + ret = cdns_pcie_set_ptm_phy_latency(dev, pcie, false, > > + "tx-phy-latency-ps"); > > + if (ret) > > + return ret; > > + > > + ret = cdns_pcie_set_ptm_phy_latency(dev, pcie, true, > > + "rx-phy-latency-ps"); > > + return ret; > > +} > > + > > void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie) > > { > > u32 delay = 0x3; > > diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h > > index 190786e47df9..483b957a8212 100644 > > --- a/drivers/pci/controller/cadence/pcie-cadence.h > > +++ b/drivers/pci/controller/cadence/pcie-cadence.h > > @@ -120,6 +120,26 @@ > > #define CDNS_PCIE_LM_PTM_CTRL (CDNS_PCIE_LM_BASE + 0x0da8) > > #define CDNS_PCIE_LM_TPM_CTRL_PTMRSEN BIT(17) > > > > +/* PTM Latency Parameters Index Register */ > > +#define CDNS_PCIE_LM_PTM_LAT_PARAM_IDX \ > > + (CDNS_PCIE_LM_BASE + 0x0db0) > > +#define CDNS_PCIE_LM_PTM_LAT_PARAM_IDX_PTMLATIN_MASK \ > > + GENMASK(3, 0) > > +#define CDNS_PCIE_LM_PTM_LAT_PARAM_IDX_PTMLATIN(a) \ > > + (((a) << 0) & CDNS_PCIE_LM_PTM_LAT_PARAM_IDX_PTMLATIN_MASK) > > + > > +/* PTM Latency Parameters Register */ > > +#define CDNS_PCIE_LM_PTM_LAT_PARAM \ > > + (CDNS_PCIE_LM_BASE + 0x0db4) > > +#define CDNS_PCIE_LM_PTM_LAT_PARAM_PTMTXLAT_MASK \ > > + GENMASK(9, 0) > > +#define CDNS_PCIE_LM_PTM_LAT_PARAM_PTMTXLAT(a) \ > > + (((a) << 0) & CDNS_PCIE_LM_PTM_LAT_PARAM_PTMTXLAT_MASK) > > +#define CDNS_PCIE_LM_PTM_LAT_PARAM_PTMRXLAT_MASK \ > > + GENMASK(19, 10) > > +#define CDNS_PCIE_LM_PTM_LAT_PARAM_PTMRXLAT(b) \ > > + (((b) << 10) & CDNS_PCIE_LM_PTM_LAT_PARAM_PTMRXLAT_MASK) > > + > > /* > > * Endpoint Function Registers (PCI configuration space for endpoint functions) > > */ > > @@ -541,6 +561,9 @@ static inline int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep) > > #endif > > > > void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie); > > +void cdns_pcie_set_ptm_phy_latency_param(struct cdns_pcie *pcie, bool rx, > > + u32 speed_index, u32 latency); > > +int cdns_pcie_init_ptm_phy_latency(struct device *dev, struct cdns_pcie *pcie); > > > > void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn, > > u32 r, bool is_io, > Acked-by: Achal Verma <a-verma1@xxxxxx> With the suggested change: Reviewed-by: Christian Gmeiner <christian.gmeiner@xxxxxxxxx> -- greets -- Christian Gmeiner, MSc https://christian-gmeiner.info/privacypolicy