summaryrefslogtreecommitdiff
path: root/drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c
diff options
context:
space:
mode:
authorHou Zhiqiang <Zhiqiang.Hou@nxp.com>2018-11-06 10:14:57 +0800
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2021-06-30 16:02:26 +0100
commitb8f2afe3eb468e1c8b136a52a688e9018af58b9c (patch)
tree897bd7f1d34bba3d23cd4bd2afda08539452b760 /drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c
parent2bc5fcc38900a31408a432c22cdb76230c8d855d (diff)
PCI: mobiveil: ls_pcie_g4: add Workaround for A-011451
When LX2 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 LX2 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 patch implemented part 1, the part 2 can be set by kernel parameter 'pci=pcie_bus_perf' This ERRATA is only for LX2160A Rev1.0, and it will be fixed in Rev2.0. Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com> [fixed up for mainline -- rmk] Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c')
-rw-r--r--drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c b/drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c
index 366adf3f1d4b..80150fa2e344 100644
--- a/drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c
+++ b/drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c
@@ -81,12 +81,27 @@ static bool ls_pcie_g4_is_bridge(struct ls_pcie_g4 *pcie)
return header_type == PCI_HEADER_TYPE_BRIDGE;
}
+static void workaround_A011451(struct ls_pcie_g4 *pcie)
+{
+ struct mobiveil_pcie *mv_pci = &pcie->pci;
+ u32 val;
+
+ /* Set ACK latency timeout */
+ val = mobiveil_csr_readl(mv_pci, GPEX_ACK_REPLAY_TO);
+ val &= ~(ACK_LAT_TO_VAL_MASK << ACK_LAT_TO_VAL_SHIFT);
+ val |= (4 << ACK_LAT_TO_VAL_SHIFT);
+ mobiveil_csr_writel(mv_pci, val, GPEX_ACK_REPLAY_TO);
+}
+
static int ls_pcie_g4_host_init(struct mobiveil_pcie *pci)
{
struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
pcie->rev = mobiveil_csr_readb(pci, PCI_REVISION_ID);
+ if (pcie->rev == REV_1_0)
+ workaround_A011451(pcie);
+
return 0;
}