Skip to content

Commit 86f271f

Browse files
kishonkwilczynski
authored andcommitted
PCI: keystone: Add workaround for Errata #i2037 (AM65x SR 1.0)
Errata #i2037 in AM65x/DRA80xM Processors Silicon Revision 1.0 (SPRZ452D_July 2018_Revised December 2019 [1]) mentions when an inbound PCIe TLP spans more than two internal AXI 128-byte bursts, the bus may corrupt the packet payload and the corrupt data may cause associated applications or the processor to hang. The workaround for Errata #i2037 is to limit the maximum read request size and maximum payload size to 128 bytes. Add workaround for Errata #i2037 here. The errata and workaround is applicable only to AM65x SR 1.0 and later versions of the silicon will have this fixed. [1] -> https://www.ti.com/lit/er/sprz452i/sprz452i.pdf Link: https://lore.kernel.org/linux-pci/[email protected] Signed-off-by: Kishon Vijay Abraham I <[email protected]> Signed-off-by: Achal Verma <[email protected]> Signed-off-by: Vignesh Raghavendra <[email protected]> Signed-off-by: Jan Kiszka <[email protected]> Signed-off-by: Krzysztof Wilczyński <[email protected]> Reviewed-by: Siddharth Vadapalli <[email protected]>
1 parent a231707 commit 86f271f

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

drivers/pci/controller/dwc/pci-keystone.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
#define PCIE_DEVICEID_SHIFT 16
3535

3636
/* Application registers */
37+
#define PID 0x000
38+
#define RTL GENMASK(15, 11)
39+
#define RTL_SHIFT 11
40+
#define AM6_PCI_PG1_RTL_VER 0x15
41+
3742
#define CMD_STATUS 0x004
3843
#define LTSSM_EN_VAL BIT(0)
3944
#define OB_XLAT_EN_VAL BIT(1)
@@ -104,6 +109,8 @@
104109

105110
#define to_keystone_pcie(x) dev_get_drvdata((x)->dev)
106111

112+
#define PCI_DEVICE_ID_TI_AM654X 0xb00c
113+
107114
struct ks_pcie_of_data {
108115
enum dw_pcie_device_mode mode;
109116
const struct dw_pcie_host_ops *host_ops;
@@ -516,7 +523,11 @@ static int ks_pcie_start_link(struct dw_pcie *pci)
516523
static void ks_pcie_quirk(struct pci_dev *dev)
517524
{
518525
struct pci_bus *bus = dev->bus;
526+
struct keystone_pcie *ks_pcie;
527+
struct device *bridge_dev;
519528
struct pci_dev *bridge;
529+
u32 val;
530+
520531
static const struct pci_device_id rc_pci_devids[] = {
521532
{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCIE_RC_K2HK),
522533
.class = PCI_CLASS_BRIDGE_PCI_NORMAL, .class_mask = ~0, },
@@ -528,6 +539,11 @@ static void ks_pcie_quirk(struct pci_dev *dev)
528539
.class = PCI_CLASS_BRIDGE_PCI_NORMAL, .class_mask = ~0, },
529540
{ 0, },
530541
};
542+
static const struct pci_device_id am6_pci_devids[] = {
543+
{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654X),
544+
.class = PCI_CLASS_BRIDGE_PCI << 8, .class_mask = ~0, },
545+
{ 0, },
546+
};
531547

532548
if (pci_is_root_bus(bus))
533549
bridge = dev;
@@ -549,10 +565,36 @@ static void ks_pcie_quirk(struct pci_dev *dev)
549565
*/
550566
if (pci_match_id(rc_pci_devids, bridge)) {
551567
if (pcie_get_readrq(dev) > 256) {
552-
dev_info(&dev->dev, "limiting MRRS to 256\n");
568+
dev_info(&dev->dev, "limiting MRRS to 256 bytes\n");
553569
pcie_set_readrq(dev, 256);
554570
}
555571
}
572+
573+
/*
574+
* Memory transactions fail with PCI controller in AM654 PG1.0
575+
* when MRRS is set to more than 128 bytes. Force the MRRS to
576+
* 128 bytes in all downstream devices.
577+
*/
578+
if (pci_match_id(am6_pci_devids, bridge)) {
579+
bridge_dev = pci_get_host_bridge_device(dev);
580+
if (!bridge_dev && !bridge_dev->parent)
581+
return;
582+
583+
ks_pcie = dev_get_drvdata(bridge_dev->parent);
584+
if (!ks_pcie)
585+
return;
586+
587+
val = ks_pcie_app_readl(ks_pcie, PID);
588+
val &= RTL;
589+
val >>= RTL_SHIFT;
590+
if (val != AM6_PCI_PG1_RTL_VER)
591+
return;
592+
593+
if (pcie_get_readrq(dev) > 128) {
594+
dev_info(&dev->dev, "limiting MRRS to 128 bytes\n");
595+
pcie_set_readrq(dev, 128);
596+
}
597+
}
556598
}
557599
DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, ks_pcie_quirk);
558600

0 commit comments

Comments
 (0)