[U-Boot] [PATCHv4 11/12] pci: ls_pcie_g4: Add Workaround for A-011451

Z.q. Hou zhiqiang.hou at nxp.com
Wed Mar 13 14:54:45 UTC 2019


Hi All,

Please ignore this patch, rev1.0 will not be production.

Thanks,
Zhiqiang


> -----Original Message-----
> From: Z.q. Hou
> Sent: 2019年3月11日 10:59
> To: u-boot at lists.denx.de; bmeng.cn at gmail.com; 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>
> Cc: Z.q. Hou <zhiqiang.hou at nxp.com>
> Subject: [PATCHv4 11/12] pci: ls_pcie_g4: Add Workaround for A-011451
> 
> 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>
> ---
> V4:
>  - V3 patch find root port wrongly, fix it in V4.
>  - Change to use the MPS and MRRS accessors.
> 
>  drivers/pci/pci_auto.c             | 35
> ++++++++++++++++++++++++++++++
>  drivers/pci/pcie_layerscape_gen4.c |  8 +++++++
> drivers/pci/pcie_layerscape_gen4.h |  4 ++++
>  include/pci_ids.h                  |  1 +
>  4 files changed, 48 insertions(+)
> 
> diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index
> d7237f6eee..611462d1d4 100644
> --- a/drivers/pci/pci_auto.c
> +++ b/drivers/pci/pci_auto.c
> @@ -22,6 +22,8 @@ void dm_pciauto_setup_device(struct udevice *dev, int
> bars_num,
>  			     struct pci_region *prefetch, struct pci_region *io,
>  			     bool enum_only)
>  {
> +	struct udevice *ctrl = pci_get_controller(dev);
> +	struct udevice *rp;
>  	u32 bar_response;
>  	pci_size_t bar_size;
>  	u16 cmdstat = 0;
> @@ -32,6 +34,8 @@ void dm_pciauto_setup_device(struct udevice *dev, int
> bars_num,
>  	struct pci_region *bar_res = NULL;
>  	int found_mem64 = 0;
>  	u16 class;
> +	u16 vendor, dev_id;
> +	u8 rev;
> 
>  	dm_pci_read_config16(dev, PCI_COMMAND, &cmdstat);
>  	cmdstat = (cmdstat & ~(PCI_COMMAND_IO |
> PCI_COMMAND_MEMORY)) | @@ -161,6 +165,37 @@ 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.
> +	 */
> +	device_find_first_child(ctrl, &rp);
> +	if (!rp) {
> +		debug("%s: Host: %s, RP is NULL\n", __func__, ctrl->name);
> +		return;
> +	}
> +
> +	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) {
> +		dm_pci_set_mps(dev, 128);
> +		dm_pci_set_readrq(dev, 128);
> +	}
>  }
> 
>  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_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
> 
> --
> 2.17.1



More information about the U-Boot mailing list