[U-Boot] [PATCHv3 10/11] pci: ls_pcie_g4: Add Workaround for A-011451
Z.q. Hou
zhiqiang.hou at nxp.com
Thu Feb 14 03:52:22 UTC 2019
Hi Bin,
Thanks a lot for your comments!
> -----Original Message-----
> From: Bin Meng <bmeng.cn at gmail.com>
> Sent: 2019年2月12日 11:45
> To: Z.q. Hou <zhiqiang.hou at nxp.com>
> Cc: u-boot at lists.denx.de; albert.u.boot at aribaud.net; Priyanka Jain
> <priyanka.jain at nxp.com>; York Sun <york.sun at nxp.com>;
> sriram.dash at nxp.com; yamada.masahiro at socionext.com; Prabhakar
> Kushwaha <prabhakar.kushwaha at nxp.com>; Mingkai Hu
> <mingkai.hu at nxp.com>; M.h. Lian <minghuan.lian at nxp.com>
> Subject: Re: [U-Boot] [PATCHv3 10/11] pci: ls_pcie_g4: Add Workaround for
> A-011451
>
> Hi,
>
> On Fri, Jan 25, 2019 at 6:07 PM Z.q. Hou <zhiqiang.hou at nxp.com> wrote:
> >
> > From: Hou Zhiqiang <Zhiqiang.Hou at 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.Hou at 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?
No, not only the RC itself but also all the EP devices need to setup the same MPS and MRRS, it is hard to scan the PCIe EP devices in the RC driver (a platform driver).
>
> > }
> >
> > 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
Thanks,
Zhiqiang
More information about the U-Boot
mailing list