]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/pci/quirks.c
UBUNTU: [Config] CONFIG_MMC_SDHCI_XENON=m
[mirror_ubuntu-artful-kernel.git] / drivers / pci / quirks.c
index 140760403f36a932b7d39eb73ae3eb96d76cab37..99eec22d99b76639829fa43856102ecd94ec2431 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/sched.h>
 #include <linux/ktime.h>
 #include <linux/mm.h>
+#include <linux/vgaarb.h>
 #include <asm/dma.h>   /* isa_dma_bridge_buggy */
 #include "pci.h"
 
@@ -41,6 +42,21 @@ static void quirk_mmio_always_on(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID,
                                PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on);
 
+/* The BAR0 ~ BAR4 of Marvell 9125 device can't be accessed
+*  by IO resource file, and need to skip the files
+*/
+static void quirk_marvell_mask_bar(struct pci_dev *dev)
+{
+       int i;
+
+       for (i = 0; i < 5; i++)
+               if (dev->resource[i].start)
+                       dev->resource[i].start =
+                               dev->resource[i].end = 0;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9125,
+                               quirk_marvell_mask_bar);
+
 /* The Mellanox Tavor device gives false positive parity errors
  * Mark this device with a broken_parity_status, to allow
  * PCI scanning code to "skip" this now blacklisted device.
@@ -3993,6 +4009,30 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, 0x9000,
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, 0x9084,
                                quirk_bridge_cavm_thrx2_pcie_root);
 
+/*
+ * PCI BAR 5 is not setup correctly for the on-board AHCI controller
+ * on Broadcom's Vulcan processor. Added a quirk to fix BAR 5 by
+ * using BAR 4's resources which are populated correctly and NOT
+ * actually used by the AHCI controller.
+ */
+static void quirk_fix_vulcan_ahci_bars(struct pci_dev *dev)
+{
+       struct resource *r =  &dev->resource[4];
+
+       if (!(r->flags & IORESOURCE_MEM) || (r->start == 0))
+               return;
+
+       /* Set BAR5 resource to BAR4 */
+       dev->resource[5] = *r;
+
+       /* Update BAR5 in pci config space */
+       pci_write_config_dword(dev, PCI_BASE_ADDRESS_5, r->start);
+
+       /* Clear BAR4's resource */
+       memset(r, 0, sizeof(*r));
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, 0x9027, quirk_fix_vulcan_ahci_bars);
+
 /*
  * Intersil/Techwell TW686[4589]-based video capture cards have an empty (zero)
  * class code.  Fix it.
@@ -4210,17 +4250,32 @@ static int pci_quirk_amd_sb_acs(struct pci_dev *dev, u16 acs_flags)
 #endif
 }
 
+static bool pci_quirk_cavium_acs_match(struct pci_dev *dev)
+{
+       /*
+        * Effectively selects all downstream ports for whole ThunderX 1
+        * family by 0xf800 mask (which represents 8 SoCs), while the lower
+        * bits of device ID are used to indicate which subdevice is used
+        * within the SoC.
+        */
+       return (pci_is_pcie(dev) &&
+               (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) &&
+               ((dev->device & 0xf800) == 0xa000));
+}
+
 static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags)
 {
        /*
-        * Cavium devices matching this quirk do not perform peer-to-peer
-        * with other functions, allowing masking out these bits as if they
-        * were unimplemented in the ACS capability.
+        * Cavium root ports don't advertise an ACS capability.  However,
+        * the RTL internally implements similar protection as if ACS had
+        * Request Redirection, Completion Redirection, Source Validation,
+        * and Upstream Forwarding features enabled.  Assert that the
+        * hardware implements and enables equivalent ACS functionality for
+        * these flags.
         */
-       acs_flags &= ~(PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR |
-                      PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT);
+       acs_flags &= ~(PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_SV | PCI_ACS_UF);
 
-       if (!((dev->device >= 0xa000) && (dev->device <= 0xa0ff)))
+       if (!pci_quirk_cavium_acs_match(dev))
                return -ENOTTY;
 
        return acs_flags ? 0 : 1;
@@ -4770,3 +4825,69 @@ static void quirk_intel_no_flr(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1502, quirk_intel_no_flr);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1503, quirk_intel_no_flr);
+
+static void quirk_intel_th_rtit_bar(struct pci_dev *dev)
+{
+       struct resource *r = &dev->resource[4];
+
+       /*
+        * Hello, Denverton!
+        * Denverton reports 2k of RTIT_BAR (resource 4), which can't be
+        * right given the 16 threads. When Intel TH gets enabled, the
+        * actual resource overlaps the XHCI MMIO space and causes it
+        * to die.
+        * We're not really using RTIT_BAR at all at the moment, so it's
+        * a safe choice to disable this resource.
+        */
+       if (r->end == r->start + 0x7ff) {
+               r->flags = 0;
+               r->start = 0;
+               r->end   = 0;
+       }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x19e1, quirk_intel_th_rtit_bar);
+
+/*
+ * The hibmc card on a HiSilicon D05 board sits behind a non-compliant
+ * bridge. The bridge has the PCI_BRIDGE_CTL_VGA config bit fixed at 0
+ * in hardware. This prevents the vgaarb from marking a card behind it
+ * as boot VGA device.
+ *
+ * However, the hibmc card is known to still work, so if we have that
+ * card behind that particular bridge (19e5:1610), mark it as the
+ * default device if none has been detected.
+ */
+static void hibmc_fixup_vgaarb(struct pci_dev *pdev)
+{
+       struct pci_dev *bridge;
+       struct pci_bus *bus;
+       u16 config;
+
+       bus = pdev->bus;
+       bridge = bus->self;
+       if (!bridge)
+               return;
+
+       if (!pci_is_bridge(bridge))
+               return;
+
+       if (bridge->vendor != PCI_VENDOR_ID_HUAWEI ||
+           bridge->device != 0x1610)
+               return;
+
+       pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
+                            &config);
+       if (config & PCI_BRIDGE_CTL_VGA) {
+               /*
+                * Weirdly, this bridge *is* spec compliant, so bail
+                * and let vgaarb do its job
+                */
+               return;
+       }
+
+       if (vga_default_device())
+               return;
+
+       vga_set_default_device(pdev);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0x1711, hibmc_fixup_vgaarb);