]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/pci/host/pci-keystone.c
PCI: keystone: Limit MRSS for all downstream devices
[karo-tx-linux.git] / drivers / pci / host / pci-keystone.c
index c1cfaef7faf3a29a2c8e88f410fcea11886b0087..c58a9eb60141e7d87f327a72b441947e2511736c 100644 (file)
 /* DEV_STAT_CTRL */
 #define PCIE_CAP_BASE          0x70
 
+/* PCIE controller device IDs */
+#define PCIE_RC_K2HK           0xb008
+#define PCIE_RC_K2E            0xb009
+#define PCIE_RC_K2L            0xb00a
+
 #define to_keystone_pcie(x)    container_of(x, struct keystone_pcie, pp)
 
+static void quirk_limit_mrrs(struct pci_dev *dev)
+{
+       struct pci_bus *bus = dev->bus;
+       struct pci_dev *bridge = bus->self;
+       static const struct pci_device_id rc_pci_devids[] = {
+               { PCI_DEVICE(PCI_VENDOR_ID_TI, PCIE_RC_K2HK),
+                .class = PCI_CLASS_BRIDGE_PCI << 8, .class_mask = ~0, },
+               { PCI_DEVICE(PCI_VENDOR_ID_TI, PCIE_RC_K2E),
+                .class = PCI_CLASS_BRIDGE_PCI << 8, .class_mask = ~0, },
+               { PCI_DEVICE(PCI_VENDOR_ID_TI, PCIE_RC_K2L),
+                .class = PCI_CLASS_BRIDGE_PCI << 8, .class_mask = ~0, },
+               { 0, },
+       };
+
+       if (pci_is_root_bus(bus))
+               return;
+
+       /* look for the host bridge */
+       while (!pci_is_root_bus(bus)) {
+               bridge = bus->self;
+               bus = bus->parent;
+       }
+
+       if (bridge) {
+               /*
+                * Keystone PCI controller has a h/w limitation of
+                * 256 bytes maximum read request size.  It can't handle
+                * anything higher than this.  So force this limit on
+                * all downstream devices.
+                */
+               if (pci_match_id(rc_pci_devids, bridge)) {
+                       if (pcie_get_readrq(dev) > 256) {
+                               dev_info(&dev->dev, "limiting MRRS to 256\n");
+                               pcie_set_readrq(dev, 256);
+                       }
+               }
+       }
+}
+DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, quirk_limit_mrrs);
+
 static int ks_pcie_establish_link(struct keystone_pcie *ks_pcie)
 {
        struct pcie_port *pp = &ks_pcie->pp;