aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/quirks.c
diff options
context:
space:
mode:
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;