aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/quirks.c
diff options
context:
space:
mode:
authorXudong Hao <xudong.hao@intel.com>2012-04-27 11:16:46 -0400
committerBjorn Helgaas <bhelgaas@google.com>2012-05-02 12:02:32 -0400
commitdf558de16c8a90e44ffb405e9224980b15158c93 (patch)
tree6bebe9ffb0b9ca46862121b9030c2934194e8c3a /drivers/pci/quirks.c
parent0f1103e40f9186bd2cdac4dde6c5bbd2f5273365 (diff)
PCI: work around IvyBridge internal graphics FLR erratum
For IvyBridge Mobile platform, a system hang may occur if a FLR (Function Level Reset) is asserted to internal graphics. This quirk is a workaround for the IVB FLR errata issue. We are disabling the FLR reset handshake between the PCH and CPU display, then manually powering down the panel power sequencing and resetting the PCH display. Signed-off-by: Xudong Hao <xudong.hao@intel.com> Signed-off-by: Kay, Allen M <allen.m.kay@intel.com> Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r--drivers/pci/quirks.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 4bf71028556b..6279d5b85993 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3085,16 +3085,74 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe)
3085 return 0; 3085 return 0;
3086} 3086}
3087 3087
3088#include "../gpu/drm/i915/i915_reg.h"
3089#define MSG_CTL 0x45010
3090#define NSDE_PWR_STATE 0xd0100
3091#define IGD_OPERATION_TIMEOUT 10000 /* set timeout 10 seconds */
3092
3093static int reset_ivb_igd(struct pci_dev *dev, int probe)
3094{
3095 void __iomem *mmio_base;
3096 unsigned long timeout;
3097 u32 val;
3098
3099 if (probe)
3100 return 0;
3101
3102 mmio_base = pci_iomap(dev, 0, 0);
3103 if (!mmio_base)
3104 return -ENOMEM;
3105
3106 iowrite32(0x00000002, mmio_base + MSG_CTL);
3107
3108 /*
3109 * Clobbering SOUTH_CHICKEN2 register is fine only if the next
3110 * driver loaded sets the right bits. However, this's a reset and
3111 * the bits have been set by i915 previously, so we clobber
3112 * SOUTH_CHICKEN2 register directly here.
3113 */
3114 iowrite32(0x00000005, mmio_base + SOUTH_CHICKEN2);
3115
3116 val = ioread32(mmio_base + PCH_PP_CONTROL) & 0xfffffffe;
3117 iowrite32(val, mmio_base + PCH_PP_CONTROL);
3118
3119 timeout = jiffies + msecs_to_jiffies(IGD_OPERATION_TIMEOUT);
3120 do {
3121 val = ioread32(mmio_base + PCH_PP_STATUS);
3122 if ((val & 0xb0000000) == 0)
3123 goto reset_complete;
3124 msleep(10);
3125 } while (time_before(jiffies, timeout));
3126 dev_warn(&dev->dev, "timeout during reset\n");
3127
3128reset_complete:
3129 iowrite32(0x00000002, mmio_base + NSDE_PWR_STATE);
3130
3131 pci_iounmap(dev, mmio_base);
3132 return 0;
3133}
3134
3088#define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed 3135#define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed
3136#define PCI_DEVICE_ID_INTEL_IVB_M_VGA 0x0156
3137#define PCI_DEVICE_ID_INTEL_IVB_M2_VGA 0x0166
3089 3138
3090static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { 3139static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
3091 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, 3140 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF,
3092 reset_intel_82599_sfp_virtfn }, 3141 reset_intel_82599_sfp_virtfn },
3142 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M_VGA,
3143 reset_ivb_igd },
3144 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M2_VGA,
3145 reset_ivb_igd },
3093 { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, 3146 { PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
3094 reset_intel_generic_dev }, 3147 reset_intel_generic_dev },
3095 { 0 } 3148 { 0 }
3096}; 3149};
3097 3150
3151/*
3152 * These device-specific reset methods are here rather than in a driver
3153 * because when a host assigns a device to a guest VM, the host may need
3154 * to reset the device but probably doesn't have a driver for it.
3155 */
3098int pci_dev_specific_reset(struct pci_dev *dev, int probe) 3156int pci_dev_specific_reset(struct pci_dev *dev, int probe)
3099{ 3157{
3100 const struct pci_dev_reset_methods *i; 3158 const struct pci_dev_reset_methods *i;