Hi, On Fri, Jan 25, 2019 at 6:07 PM Z.q. Hou <zhiqiang....@nxp.com> wrote: > > From: Hou Zhiqiang <zhiqiang....@nxp.com> > > When LAYERSCAPE Gen4 PCIe controller is sending multiple split > completions and ACK latency expires indicating that ACK should > be send at priority. But because of large number of split > completions and FC update DLLP, the controller does not give > priority to ACK transmission. This results into ACK latency > timer timeout error at the link partner and the pending TLPs > are replayed by the link partner again. > > Workaround: > 1. Reduce the ACK latency timeout value to a very small value. > 2. Restrict the number of completions from the PCIe controller > to 1, by changing the Max Read Request Size (MRRS) of link > partner to the same value as Max Packet size (MPS). > > This ERRATA is only for LX2160A Rev1.0 and will be fixed in Rev2.0. > > Signed-off-by: Hou Zhiqiang <zhiqiang....@nxp.com> > --- > V3: > - New patch. > > drivers/pci/pci_auto.c | 34 ++++++++++++++++++++++++++++++ > drivers/pci/pcie_layerscape_gen4.c | 8 +++++++ > drivers/pci/pcie_layerscape_gen4.h | 4 ++++ > include/pci.h | 9 ++++++++ > include/pci_ids.h | 1 + > 5 files changed, 56 insertions(+) > > diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c > index d7237f6eee..37307bd54b 100644 > --- a/drivers/pci/pci_auto.c > +++ b/drivers/pci/pci_auto.c > @@ -22,6 +22,7 @@ void dm_pciauto_setup_device(struct udevice *dev, int > bars_num, > struct pci_region *prefetch, struct pci_region > *io, > bool enum_only) > { > + struct udevice *rp = pci_get_controller(dev); > u32 bar_response; > pci_size_t bar_size; > u16 cmdstat = 0; > @@ -32,6 +33,9 @@ void dm_pciauto_setup_device(struct udevice *dev, int > bars_num, > struct pci_region *bar_res = NULL; > int found_mem64 = 0; > u16 class; > + int pos; > + u16 val, vendor, dev_id; > + u8 rev; > > dm_pci_read_config16(dev, PCI_COMMAND, &cmdstat); > cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | > @@ -161,6 +165,36 @@ void dm_pciauto_setup_device(struct udevice *dev, int > bars_num, > dm_pci_write_config8(dev, PCI_CACHE_LINE_SIZE, > CONFIG_SYS_PCI_CACHE_LINE_SIZE); > dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x80); > + > + /* > + * When NXP LAYERSCAPE Gen4 PCIe controller is sending multiple split > + * completions and ACK latency expires indicating that ACK should be > + * send at priority. But because of large number of split completions > + * and FC update DLLP, the controller does not give priority to ACK > + * transmission. This results into ACK latency timer timeout error at > + * the link partner and the pending TLPs are replayed by the link > + * partner again. > + * > + * The workaround: > + * Restrict the number of completions from the PCIe controller to 1, > + * by changing the Max Read Request Size (MRRS) of link partner to the > + * same value as Max Packet size (MPS). > + * > + * So, set both the MPS and MRRS to the minimum 128B. > + */ > + dm_pci_read_config16(rp, PCI_VENDOR_ID, &vendor); > + dm_pci_read_config16(rp, PCI_DEVICE_ID, &dev_id); > + dm_pci_read_config8(rp, PCI_REVISION_ID, &rev); > + if (vendor == PCI_VENDOR_ID_FREESCALE && > + dev_id == PCI_DEVICE_ID_LX2160A && rev == 0x10) { > + pos = dm_pci_find_capability(dev, PCI_CAP_ID_EXP); > + if (pos) { > + dm_pci_read_config16(dev, pos + PCI_EXP_DEVCTL, &val); > + val &= ~(PCI_EXP_DEVCTL_READRQ | > + PCI_EXP_DEVCTL_PAYLOAD); > + dm_pci_write_config16(dev, pos + PCI_EXP_DEVCTL, val); > + } > + }
Can this be done in the probe() routine of the driver codes? > } > > void dm_pciauto_prescan_setup_bridge(struct udevice *dev, int sub_bus) > diff --git a/drivers/pci/pcie_layerscape_gen4.c > b/drivers/pci/pcie_layerscape_gen4.c > index 799da2f7df..b530a9979c 100644 > --- a/drivers/pci/pcie_layerscape_gen4.c > +++ b/drivers/pci/pcie_layerscape_gen4.c > @@ -526,6 +526,14 @@ static int ls_pcie_g4_probe(struct udevice *dev) > > pcie->rev = readb(pcie->ccsr + PCI_REVISION_ID); > > + /* Set ACK latency timeout */ > + if (pcie->rev == REV_1_0) { > + val = ccsr_readl(pcie, GPEX_ACK_REPLAY_TO); > + val &= ~(ACK_LAT_TO_VAL_MASK << ACK_LAT_TO_VAL_SHIFT); > + val |= (4 << ACK_LAT_TO_VAL_SHIFT); > + ccsr_writel(pcie, GPEX_ACK_REPLAY_TO, val); > + } > + > pcie->mode = readb(pcie->ccsr + PCI_HEADER_TYPE) & 0x7f; > > if (pcie->mode == PCI_HEADER_TYPE_NORMAL) { > diff --git a/drivers/pci/pcie_layerscape_gen4.h > b/drivers/pci/pcie_layerscape_gen4.h > index 137768cae7..ebde52e49a 100644 > --- a/drivers/pci/pcie_layerscape_gen4.h > +++ b/drivers/pci/pcie_layerscape_gen4.h > @@ -58,6 +58,10 @@ > #define INI_VF_SHIFT 0 > #define GPEX_SRIOV_VF_OFFSET_STRIDE(pf) (0x704 + (pf) * 4) > > +#define GPEX_ACK_REPLAY_TO 0x438 > +#define ACK_LAT_TO_VAL_SHIFT 0 > +#define ACK_LAT_TO_VAL_MASK 0x1fff > + > /* PAB CSR */ > #define PAB_CTRL 0x808 > #define PAB_CTRL_APIO_EN BIT(0) > diff --git a/include/pci.h b/include/pci.h > index 785d7d28b7..c4d3bccc5b 100644 > --- a/include/pci.h > +++ b/include/pci.h > @@ -414,6 +414,15 @@ > #define PCI_MAX_PCI_DEVICES 32 > #define PCI_MAX_PCI_FUNCTIONS 8 > > +/* PCI Express capability registers */ > +#define PCI_EXP_DEVCTL 8 /* Device Control */ > +#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */ > +#define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */ > +#define PCI_EXP_DEVCTL_READRQ_128B 0x0000 /* 128 Bytes */ > +#define PCI_EXP_DEVCTL_READRQ_256B 0x1000 /* 256 Bytes */ > +#define PCI_EXP_DEVCTL_READRQ_512B 0x2000 /* 512 Bytes */ > +#define PCI_EXP_DEVCTL_READRQ_1024B 0x3000 /* 1024 Bytes */ > + > #define PCI_FIND_CAP_TTL 0x48 > #define CAP_START_POS 0x40 > > diff --git a/include/pci_ids.h b/include/pci_ids.h > index fdda679cc0..92a4339e3e 100644 > --- a/include/pci_ids.h > +++ b/include/pci_ids.h > @@ -2481,6 +2481,7 @@ > #define PCI_DEVICE_ID_MPC8641 0x7010 > #define PCI_DEVICE_ID_MPC8641D 0x7011 > #define PCI_DEVICE_ID_MPC8610 0x7018 > +#define PCI_DEVICE_ID_LX2160A 0x8D80 > > #define PCI_VENDOR_ID_PASEMI 0x1959 > > -- Regards, Bin _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot