#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"
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.
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.
#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;
}
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);