Author: dumbbell
Date: Tue Oct 27 21:23:19 2015
New Revision: 290070
URL: https://svnweb.freebsd.org/changeset/base/290070

Log:
  drm/i915: Reduce diff with Linux 3.8
  
  There is no functional change. The goal is to ease the future update to
  Linux 3.8's i915 driver.
  
  MFC after:    2 months

Modified:
  head/sys/dev/drm2/i915/i915_drv.c

Modified: head/sys/dev/drm2/i915/i915_drv.c
==============================================================================
--- head/sys/dev/drm2/i915/i915_drv.c   Tue Oct 27 21:20:00 2015        
(r290069)
+++ head/sys/dev/drm2/i915/i915_drv.c   Tue Oct 27 21:23:19 2015        
(r290070)
@@ -42,6 +42,44 @@ __FBSDID("$FreeBSD$");
 
 #include "fb_if.h"
 
+int intel_iommu_enabled = 0;
+TUNABLE_INT("drm.i915.intel_iommu_enabled", &intel_iommu_enabled);
+int intel_iommu_gfx_mapped = 0;
+TUNABLE_INT("drm.i915.intel_iommu_gfx_mapped", &intel_iommu_gfx_mapped);
+
+int i915_prefault_disable;
+TUNABLE_INT("drm.i915.prefault_disable", &i915_prefault_disable);
+int i915_semaphores = -1;
+TUNABLE_INT("drm.i915.semaphores", &i915_semaphores);
+static int i915_try_reset = 1;
+TUNABLE_INT("drm.i915.try_reset", &i915_try_reset);
+unsigned int i915_lvds_downclock = 0;
+TUNABLE_INT("drm.i915.lvds_downclock", &i915_lvds_downclock);
+int i915_vbt_sdvo_panel_type = -1;
+TUNABLE_INT("drm.i915.vbt_sdvo_panel_type", &i915_vbt_sdvo_panel_type);
+unsigned int i915_powersave = 1;
+TUNABLE_INT("drm.i915.powersave", &i915_powersave);
+int i915_enable_fbc = 0;
+TUNABLE_INT("drm.i915.enable_fbc", &i915_enable_fbc);
+int i915_enable_rc6 = 0;
+TUNABLE_INT("drm.i915.enable_rc6", &i915_enable_rc6);
+int i915_lvds_channel_mode;
+TUNABLE_INT("drm.i915.lvds_channel_mode", &i915_lvds_channel_mode);
+int i915_panel_use_ssc = -1;
+TUNABLE_INT("drm.i915.panel_use_ssc", &i915_panel_use_ssc);
+int i915_panel_ignore_lid = 0;
+TUNABLE_INT("drm.i915.panel_ignore_lid", &i915_panel_ignore_lid);
+int i915_panel_invert_brightness;
+TUNABLE_INT("drm.i915.panel_invert_brightness", &i915_panel_invert_brightness);
+int i915_modeset = 1;
+TUNABLE_INT("drm.i915.modeset", &i915_modeset);
+int i915_enable_ppgtt = -1;
+TUNABLE_INT("drm.i915.enable_ppgtt", &i915_enable_ppgtt);
+int i915_enable_hangcheck = 1;
+TUNABLE_INT("drm.i915.enable_hangcheck", &i915_enable_hangcheck);
+static int i915_enable_unsupported = 0;
+TUNABLE_INT("drm.i915.enable_unsupported", &i915_enable_unsupported);
+
 /* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
 static drm_pci_id_list_t i915_pciidlist[] = {
        i915_PCI_IDS
@@ -229,7 +267,7 @@ static const struct intel_device_info in
 static const struct intel_gfx_device_id {
        int device;
        const struct intel_device_info *info;
-} pciidlist[] = {                                              /* aka */
+} i915_infolist[] = {          /* aka */
        INTEL_VGA_DEVICE(0x3577, &intel_i830_info),             /* I830_M */
        INTEL_VGA_DEVICE(0x2562, &intel_845g_info),             /* 845_G */
        INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),             /* I855_GM */
@@ -316,7 +354,61 @@ static const struct intel_gfx_device_id 
        {0, 0}
 };
 
-static int i915_enable_unsupported;
+#define        PCI_VENDOR_INTEL                0x8086
+#define INTEL_PCH_DEVICE_ID_MASK       0xff00
+#define INTEL_PCH_IBX_DEVICE_ID_TYPE   0x3b00
+#define INTEL_PCH_CPT_DEVICE_ID_TYPE   0x1c00
+#define INTEL_PCH_PPT_DEVICE_ID_TYPE   0x1e00
+#define INTEL_PCH_LPT_DEVICE_ID_TYPE   0x8c00
+
+void intel_detect_pch(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       device_t pch;
+       uint32_t id;
+
+       pch = pci_find_class(PCIC_BRIDGE, PCIS_BRIDGE_ISA);
+       if (pch != NULL && pci_get_vendor(pch) == PCI_VENDOR_INTEL) {
+               id = pci_get_device(pch) & INTEL_PCH_DEVICE_ID_MASK;
+               if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
+                       dev_priv->pch_type = PCH_IBX;
+                       dev_priv->num_pch_pll = 2;
+                       DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
+               } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
+                       dev_priv->pch_type = PCH_CPT;
+                       dev_priv->num_pch_pll = 2;
+                       DRM_DEBUG_KMS("Found CougarPoint PCH\n");
+               } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
+                       /* PantherPoint is CPT compatible */
+                       dev_priv->pch_type = PCH_CPT;
+                       dev_priv->num_pch_pll = 2;
+                       DRM_DEBUG_KMS("Found PatherPoint PCH\n");
+               } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
+                       dev_priv->pch_type = PCH_LPT;
+                       dev_priv->num_pch_pll = 0;
+                       DRM_DEBUG_KMS("Found LynxPoint PCH\n");
+               } else
+                       DRM_DEBUG_KMS("No PCH detected\n");
+               KASSERT(dev_priv->num_pch_pll <= I915_NUM_PLLS,
+                   ("num_pch_pll %d\n", dev_priv->num_pch_pll));
+       } else
+               DRM_DEBUG_KMS("No Intel PCI-ISA bridge found\n");
+}
+
+bool i915_semaphore_is_enabled(struct drm_device *dev)
+{
+       if (INTEL_INFO(dev)->gen < 6)
+               return 0;
+
+       if (i915_semaphores >= 0)
+               return i915_semaphores;
+
+       /* Enable semaphores on SNB when IO remapping is off */
+       if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped)
+               return false;
+
+       return 1;
+}
 
 static int i915_drm_freeze(struct drm_device *dev)
 {
@@ -355,7 +447,7 @@ static int i915_suspend(device_t kdev)
        int error;
 
        dev = device_get_softc(kdev);
-       if (dev == NULL || dev->dev_private == NULL) {
+       if (!dev || !dev->dev_private) {
                DRM_ERROR("DRM not initialized, aborting suspend.\n");
                return ENODEV;
        }
@@ -363,7 +455,7 @@ static int i915_suspend(device_t kdev)
        DRM_DEBUG_KMS("starting suspend\n");
        error = i915_drm_freeze(dev);
        if (error)
-               return (-error);
+               return -error;
 
        error = bus_generic_suspend(kdev);
        DRM_DEBUG_KMS("finished suspend %d\n", error);
@@ -429,8 +521,8 @@ static int i915_resume(device_t kdev)
 #endif
 
        ret = i915_drm_thaw(dev);
-       if (ret != 0)
-               return (-ret);
+       if (ret)
+               return -ret;
 
        drm_kms_helper_poll_enable(dev);
        ret = bus_generic_resume(kdev);
@@ -438,189 +530,348 @@ static int i915_resume(device_t kdev)
        return (ret);
 }
 
-static int
-i915_probe(device_t kdev)
+static int i8xx_do_reset(struct drm_device *dev)
 {
-       const struct intel_device_info *info;
-       int error;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int onems;
 
-       error = drm_probe_helper(kdev, i915_pciidlist);
-       if (error != 0)
-               return (-error);
-       info = i915_get_device_id(pci_get_device(kdev));
-       if (info == NULL)
-               return (ENXIO);
-       return (0);
-}
+       if (IS_I85X(dev))
+               return -ENODEV;
+
+       onems = hz / 1000;
+       if (onems == 0)
+               onems = 1;
+
+       I915_WRITE(D_STATE, I915_READ(D_STATE) | DSTATE_GFX_RESET_I830);
+       POSTING_READ(D_STATE);
+
+       if (IS_I830(dev) || IS_845G(dev)) {
+               I915_WRITE(DEBUG_RESET_I830,
+                          DEBUG_RESET_DISPLAY |
+                          DEBUG_RESET_RENDER |
+                          DEBUG_RESET_FULL);
+               POSTING_READ(DEBUG_RESET_I830);
+               pause("i8xxrst1", onems);
+
+               I915_WRITE(DEBUG_RESET_I830, 0);
+               POSTING_READ(DEBUG_RESET_I830);
+       }
+
+       pause("i8xxrst2", onems);
+
+       I915_WRITE(D_STATE, I915_READ(D_STATE) & ~DSTATE_GFX_RESET_I830);
+       POSTING_READ(D_STATE);
 
-int i915_modeset;
+       return 0;
+}
 
-static int
-i915_attach(device_t kdev)
+static int i965_reset_complete(struct drm_device *dev)
 {
+       u8 gdrst;
 
-       if (i915_modeset == 1)
-               i915_driver_info.driver_features |= DRIVER_MODESET;
-       return (-drm_attach_helper(kdev, i915_pciidlist, &i915_driver_info));
+       gdrst = pci_read_config(dev->dev, I965_GDRST, 1);
+       return (gdrst & GRDOM_RESET_ENABLE) == 0;
 }
 
-static struct fb_info *
-i915_fb_helper_getinfo(device_t kdev)
+static int i965_do_reset(struct drm_device *dev)
 {
-       struct intel_fbdev *ifbdev;
-       drm_i915_private_t *dev_priv;
-       struct drm_device *dev;
-       struct fb_info *info;
+       int ret;
+       u8 gdrst;
 
-       dev = device_get_softc(kdev);
-       dev_priv = dev->dev_private;
-       ifbdev = dev_priv->fbdev;
-       if (ifbdev == NULL)
-               return (NULL);
+       /*
+        * Set the domains we want to reset (GRDOM/bits 2 and 3) as
+        * well as the reset bit (GR/bit 0).  Setting the GR bit
+        * triggers the reset; when done, the hardware will clear it.
+        */
+       gdrst = pci_read_config(dev->dev, I965_GDRST, 1);
+       pci_write_config(dev->dev, I965_GDRST,
+                             gdrst | GRDOM_RENDER |
+                             GRDOM_RESET_ENABLE, 1);
+       ret =  wait_for(i965_reset_complete(dev), 500);
+       if (ret)
+               return ret;
 
-       info = ifbdev->helper.fbdev;
+       /* We can't reset render&media without also resetting display ... */
+       gdrst = pci_read_config(dev->dev, I965_GDRST, 1);
+       pci_write_config(dev->dev, I965_GDRST,
+                             gdrst | GRDOM_MEDIA |
+                             GRDOM_RESET_ENABLE, 1);
 
-       return (info);
+       return wait_for(i965_reset_complete(dev), 500);
 }
 
-const struct intel_device_info *
-i915_get_device_id(int device)
+static int ironlake_do_reset(struct drm_device *dev)
 {
-       const struct intel_gfx_device_id *did;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 gdrst;
+       int ret;
 
-       for (did = &pciidlist[0]; did->device != 0; did++) {
-               if (did->device != device)
-                       continue;
-               if (did->info->not_supported && !i915_enable_unsupported)
-                       return (NULL);
-               return (did->info);
-       }
-       return (NULL);
+       gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR);
+       I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR,
+                  gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE);
+       ret = wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500);
+       if (ret)
+               return ret;
+
+       /* We can't reset render&media without also resetting display ... */
+       gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR);
+       I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR,
+                  gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE);
+       return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500);
 }
 
-static device_method_t i915_methods[] = {
-       /* Device interface */
-       DEVMETHOD(device_probe,         i915_probe),
-       DEVMETHOD(device_attach,        i915_attach),
-       DEVMETHOD(device_suspend,       i915_suspend),
-       DEVMETHOD(device_resume,        i915_resume),
-       DEVMETHOD(device_detach,        drm_generic_detach),
+static int gen6_do_reset(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int     ret;
 
-       /* Framebuffer service methods */
-       DEVMETHOD(fb_getinfo,           i915_fb_helper_getinfo),
+       /* Hold gt_lock across reset to prevent any register access
+        * with forcewake not set correctly
+        */
+       mtx_lock(&dev_priv->gt_lock);
 
-       DEVMETHOD_END
-};
+       /* Reset the chip */
 
-static driver_t i915_driver = {
-       "drmn",
-       i915_methods,
-       sizeof(struct drm_device)
-};
+       /* GEN6_GDRST is not in the gt power well, no need to check
+        * for fifo space for the write or forcewake the chip for
+        * the read
+        */
+       I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL);
 
-extern devclass_t drm_devclass;
-DRIVER_MODULE_ORDERED(i915kms, vgapci, i915_driver, drm_devclass, 0, 0,
-    SI_ORDER_ANY);
-MODULE_DEPEND(i915kms, drmn, 1, 1, 1);
-MODULE_DEPEND(i915kms, agp, 1, 1, 1);
-MODULE_DEPEND(i915kms, iicbus, 1, 1, 1);
-MODULE_DEPEND(i915kms, iic, 1, 1, 1);
-MODULE_DEPEND(i915kms, iicbb, 1, 1, 1);
+       /* Spin waiting for the device to ack the reset request */
+       ret = _intel_wait_for(dev,
+           (I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0,
+           500, 0, "915rst");
 
-int intel_iommu_enabled = 0;
-TUNABLE_INT("drm.i915.intel_iommu_enabled", &intel_iommu_enabled);
-int intel_iommu_gfx_mapped = 0;
-TUNABLE_INT("drm.i915.intel_iommu_gfx_mapped", &intel_iommu_gfx_mapped);
+       /* If reset with a user forcewake, try to restore, otherwise turn it 
off */
+       if (dev_priv->forcewake_count)
+               dev_priv->display.force_wake_get(dev_priv);
+       else
+               dev_priv->display.force_wake_put(dev_priv);
 
-int i915_prefault_disable;
-TUNABLE_INT("drm.i915.prefault_disable", &i915_prefault_disable);
-int i915_semaphores = -1;
-TUNABLE_INT("drm.i915.semaphores", &i915_semaphores);
-static int i915_try_reset = 1;
-TUNABLE_INT("drm.i915.try_reset", &i915_try_reset);
-unsigned int i915_lvds_downclock = 0;
-TUNABLE_INT("drm.i915.lvds_downclock", &i915_lvds_downclock);
-int i915_vbt_sdvo_panel_type = -1;
-TUNABLE_INT("drm.i915.vbt_sdvo_panel_type", &i915_vbt_sdvo_panel_type);
-unsigned int i915_powersave = 1;
-TUNABLE_INT("drm.i915.powersave", &i915_powersave);
-int i915_enable_fbc = 0;
-TUNABLE_INT("drm.i915.enable_fbc", &i915_enable_fbc);
-int i915_enable_rc6 = 0;
-TUNABLE_INT("drm.i915.enable_rc6", &i915_enable_rc6);
-int i915_lvds_channel_mode;
-TUNABLE_INT("drm.i915.lvds_channel_mode", &i915_lvds_channel_mode);
-int i915_panel_use_ssc = -1;
-TUNABLE_INT("drm.i915.panel_use_ssc", &i915_panel_use_ssc);
-int i915_panel_ignore_lid = 0;
-TUNABLE_INT("drm.i915.panel_ignore_lid", &i915_panel_ignore_lid);
-int i915_panel_invert_brightness;
-TUNABLE_INT("drm.i915.panel_invert_brightness", &i915_panel_invert_brightness);
-int i915_modeset = 1;
-TUNABLE_INT("drm.i915.modeset", &i915_modeset);
-int i915_enable_ppgtt = -1;
-TUNABLE_INT("drm.i915.enable_ppgtt", &i915_enable_ppgtt);
-int i915_enable_hangcheck = 1;
-TUNABLE_INT("drm.i915.enable_hangcheck", &i915_enable_hangcheck);
-TUNABLE_INT("drm.i915.enable_unsupported", &i915_enable_unsupported);
+       /* Restore fifo count */
+       dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
 
-#define        PCI_VENDOR_INTEL                0x8086
-#define INTEL_PCH_DEVICE_ID_MASK       0xff00
-#define INTEL_PCH_IBX_DEVICE_ID_TYPE   0x3b00
-#define INTEL_PCH_CPT_DEVICE_ID_TYPE   0x1c00
-#define INTEL_PCH_PPT_DEVICE_ID_TYPE   0x1e00
-#define INTEL_PCH_LPT_DEVICE_ID_TYPE   0x8c00
+       mtx_unlock(&dev_priv->gt_lock);
+       return ret;
+}
 
-void intel_detect_pch(struct drm_device *dev)
+int intel_gpu_reset(struct drm_device *dev)
 {
-       struct drm_i915_private *dev_priv;
-       device_t pch;
-       uint32_t id;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int ret = -ENODEV;
 
-       dev_priv = dev->dev_private;
-       pch = pci_find_class(PCIC_BRIDGE, PCIS_BRIDGE_ISA);
-       if (pch != NULL && pci_get_vendor(pch) == PCI_VENDOR_INTEL) {
-               id = pci_get_device(pch) & INTEL_PCH_DEVICE_ID_MASK;
-               if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
-                       dev_priv->pch_type = PCH_IBX;
-                       dev_priv->num_pch_pll = 2;
-                       DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
-               } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
-                       dev_priv->pch_type = PCH_CPT;
-                       dev_priv->num_pch_pll = 2;
-                       DRM_DEBUG_KMS("Found CougarPoint PCH\n");
-               } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
-                       /* PantherPoint is CPT compatible */
-                       dev_priv->pch_type = PCH_CPT;
-                       dev_priv->num_pch_pll = 2;
-                       DRM_DEBUG_KMS("Found PatherPoint PCH\n");
-               } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
-                       dev_priv->pch_type = PCH_LPT;
-                       dev_priv->num_pch_pll = 0;
-                       DRM_DEBUG_KMS("Found LynxPoint PCH\n");
-               } else
-                       DRM_DEBUG_KMS("No PCH detected\n");
-               KASSERT(dev_priv->num_pch_pll <= I915_NUM_PLLS,
-                   ("num_pch_pll %d\n", dev_priv->num_pch_pll));
-       } else
-               DRM_DEBUG_KMS("No Intel PCI-ISA bridge found\n");
+       switch (INTEL_INFO(dev)->gen) {
+       case 7:
+       case 6:
+               ret = gen6_do_reset(dev);
+               break;
+       case 5:
+               ret = ironlake_do_reset(dev);
+               break;
+       case 4:
+               ret = i965_do_reset(dev);
+               break;
+       case 2:
+               ret = i8xx_do_reset(dev);
+               break;
+       }
+
+       /* Also reset the gpu hangman. */
+       if (dev_priv->stop_rings) {
+               DRM_DEBUG("Simulated gpu hang, resetting stop_rings\n");
+               dev_priv->stop_rings = 0;
+               if (ret == -ENODEV) {
+                       DRM_ERROR("Reset not implemented, but ignoring "
+                                 "error for simulated gpu hangs\n");
+                       ret = 0;
+               }
+       }
+
+       return ret;
 }
 
-bool i915_semaphore_is_enabled(struct drm_device *dev)
+/**
+ * i915_reset - reset chip after a hang
+ * @dev: drm device to reset
+ *
+ * Reset the chip.  Useful if a hang is detected. Returns zero on successful
+ * reset or otherwise an error code.
+ *
+ * Procedure is fairly simple:
+ *   - reset the chip using the reset reg
+ *   - re-init context state
+ *   - re-init hardware status page
+ *   - re-init ring buffer
+ *   - re-init interrupt state
+ *   - re-init display
+ */
+int i915_reset(struct drm_device *dev)
 {
-       if (INTEL_INFO(dev)->gen < 6)
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       int ret;
+
+       if (!i915_try_reset)
                return 0;
 
-       if (i915_semaphores >= 0)
-               return i915_semaphores;
+       if (!sx_try_xlock(&dev->dev_struct_lock))
+               return (-EBUSY);
 
-       /* Enable semaphores on SNB when IO remapping is off */
-       if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped)
-               return false;
+       dev_priv->stop_rings = 0;
 
-       return 1;
+       i915_gem_reset(dev);
+
+       ret = -ENODEV;
+       if (time_second - dev_priv->last_gpu_reset < 5)
+               DRM_ERROR("GPU hanging too fast, declaring wedged!\n");
+       else
+               ret = intel_gpu_reset(dev);
+
+       dev_priv->last_gpu_reset = time_second;
+       if (ret) {
+               DRM_ERROR("Failed to reset chip.\n");
+               DRM_UNLOCK(dev);
+               return ret;
+       }
+
+       /* Ok, now get things going again... */
+
+       /*
+        * Everything depends on having the GTT running, so we need to start
+        * there.  Fortunately we don't need to do this unless we reset the
+        * chip at a PCI level.
+        *
+        * Next we need to restore the context, but we don't use those
+        * yet either...
+        *
+        * Ring buffer needs to be re-initialized in the KMS case, or if X
+        * was running at the time of the reset (i.e. we weren't VT
+        * switched away).
+        */
+       if (drm_core_check_feature(dev, DRIVER_MODESET) ||
+                       !dev_priv->mm.suspended) {
+               struct intel_ring_buffer *ring;
+               int i;
+
+               dev_priv->mm.suspended = 0;
+
+               i915_gem_init_swizzling(dev);
+
+               for_each_ring(ring, dev_priv, i)
+                       ring->init(ring);
+
+               i915_gem_context_init(dev);
+               i915_gem_init_ppgtt(dev);
+
+               /*
+                * It would make sense to re-init all the other hw state, at
+                * least the rps/rc6/emon init done within modeset_init_hw. For
+                * some unknown reason, this blows up my ilk, so don't.
+                */
+
+               DRM_UNLOCK(dev);
+
+               if (drm_core_check_feature(dev, DRIVER_MODESET))
+                       intel_modeset_init_hw(dev);
+
+               drm_irq_uninstall(dev);
+               drm_irq_install(dev);
+       } else {
+               DRM_UNLOCK(dev);
+       }
+
+       return 0;
 }
 
+const struct intel_device_info *
+i915_get_device_id(int device)
+{
+       const struct intel_gfx_device_id *did;
+
+       for (did = &i915_infolist[0]; did->device != 0; did++) {
+               if (did->device != device)
+                       continue;
+               if (did->info->not_supported && !i915_enable_unsupported)
+                       return (NULL);
+               return (did->info);
+       }
+       return (NULL);
+}
+
+static int i915_probe(device_t kdev)
+{
+       const struct intel_device_info *intel_info =
+               i915_get_device_id(pci_get_device(kdev));
+
+       if (intel_info == NULL)
+               return (ENXIO);
+
+       return -drm_probe_helper(kdev, i915_pciidlist);
+}
+
+static int i915_attach(device_t kdev)
+{
+
+       if (i915_modeset == 1)
+               i915_driver_info.driver_features |= DRIVER_MODESET;
+       return (-drm_attach_helper(kdev, i915_pciidlist, &i915_driver_info));
+}
+
+static struct fb_info *
+i915_fb_helper_getinfo(device_t kdev)
+{
+       struct intel_fbdev *ifbdev;
+       drm_i915_private_t *dev_priv;
+       struct drm_device *dev;
+       struct fb_info *info;
+
+       dev = device_get_softc(kdev);
+       dev_priv = dev->dev_private;
+       ifbdev = dev_priv->fbdev;
+       if (ifbdev == NULL)
+               return (NULL);
+
+       info = ifbdev->helper.fbdev;
+
+       return (info);
+}
+
+static device_method_t i915_methods[] = {
+       /* Device interface */
+       DEVMETHOD(device_probe,         i915_probe),
+       DEVMETHOD(device_attach,        i915_attach),
+       DEVMETHOD(device_suspend,       i915_suspend),
+       DEVMETHOD(device_resume,        i915_resume),
+       DEVMETHOD(device_detach,        drm_generic_detach),
+
+       /* Framebuffer service methods */
+       DEVMETHOD(fb_getinfo,           i915_fb_helper_getinfo),
+
+       DEVMETHOD_END
+};
+
+static driver_t i915_driver = {
+       "drmn",
+       i915_methods,
+       sizeof(struct drm_device)
+};
+
+extern devclass_t drm_devclass;
+DRIVER_MODULE_ORDERED(i915kms, vgapci, i915_driver, drm_devclass, 0, 0,
+    SI_ORDER_ANY);
+MODULE_DEPEND(i915kms, drmn, 1, 1, 1);
+MODULE_DEPEND(i915kms, agp, 1, 1, 1);
+MODULE_DEPEND(i915kms, iicbus, 1, 1, 1);
+MODULE_DEPEND(i915kms, iic, 1, 1, 1);
+MODULE_DEPEND(i915kms, iicbb, 1, 1, 1);
+
+/* We give fast paths for the really cool registers */
+#define NEEDS_FORCE_WAKE(dev_priv, reg) \
+       (((dev_priv)->info->gen >= 6) && \
+        ((reg) < 0x40000) &&            \
+        ((reg) != FORCEWAKE)) && \
+       (!IS_VALLEYVIEW((dev_priv)->dev))
+
 void
 __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
 {
@@ -753,264 +1004,6 @@ void vlv_force_wake_put(struct drm_i915_
        POSTING_READ(FORCEWAKE_VLV);
 }
 
-static int i8xx_do_reset(struct drm_device *dev)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       int onems;
-
-       if (IS_I85X(dev))
-               return -ENODEV;
-
-       onems = hz / 1000;
-       if (onems == 0)
-               onems = 1;
-
-       I915_WRITE(D_STATE, I915_READ(D_STATE) | DSTATE_GFX_RESET_I830);
-       POSTING_READ(D_STATE);
-
-       if (IS_I830(dev) || IS_845G(dev)) {
-               I915_WRITE(DEBUG_RESET_I830,
-                          DEBUG_RESET_DISPLAY |
-                          DEBUG_RESET_RENDER |
-                          DEBUG_RESET_FULL);
-               POSTING_READ(DEBUG_RESET_I830);
-               pause("i8xxrst1", onems);
-
-               I915_WRITE(DEBUG_RESET_I830, 0);
-               POSTING_READ(DEBUG_RESET_I830);
-       }
-
-       pause("i8xxrst2", onems);
-
-       I915_WRITE(D_STATE, I915_READ(D_STATE) & ~DSTATE_GFX_RESET_I830);
-       POSTING_READ(D_STATE);
-
-       return 0;
-}
-
-static int i965_reset_complete(struct drm_device *dev)
-{
-       u8 gdrst;
-
-       gdrst = pci_read_config(dev->dev, I965_GDRST, 1);
-       return (gdrst & GRDOM_RESET_ENABLE) == 0;
-}
-
-static int i965_do_reset(struct drm_device *dev)
-{
-       int ret;
-       u8 gdrst;
-
-       /*
-        * Set the domains we want to reset (GRDOM/bits 2 and 3) as
-        * well as the reset bit (GR/bit 0).  Setting the GR bit
-        * triggers the reset; when done, the hardware will clear it.
-        */
-       gdrst = pci_read_config(dev->dev, I965_GDRST, 1);
-       pci_write_config(dev->dev, I965_GDRST,
-           gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE, 1);
-
-       ret =  wait_for(i965_reset_complete(dev), 500);
-       if (ret)
-               return ret;
-
-       /* We can't reset render&media without also resetting display ... */
-       gdrst = pci_read_config(dev->dev, I965_GDRST, 1);
-       pci_write_config(dev->dev, I965_GDRST,
-                        gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE, 1);
-
-       return wait_for(i965_reset_complete(dev), 500);
-}
-
-static int ironlake_do_reset(struct drm_device *dev)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 gdrst;
-       int ret;
-
-       gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR);
-       I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR,
-                  gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE);
-       ret = wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500);
-       if (ret)
-               return ret;
-
-       /* We can't reset render&media without also resetting display ... */
-       gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR);
-       I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR,
-                  gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE);
-       return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500);
-}
-
-static int gen6_do_reset(struct drm_device *dev)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       int     ret;
-
-       /* Hold gt_lock across reset to prevent any register access
-        * with forcewake not set correctly
-        */
-       mtx_lock(&dev_priv->gt_lock);
-
-       /* Reset the chip */
-
-       /* GEN6_GDRST is not in the gt power well, no need to check
-        * for fifo space for the write or forcewake the chip for
-        * the read
-        */
-       I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL);
-
-       /* Spin waiting for the device to ack the reset request */
-       ret = _intel_wait_for(dev,
-           (I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0,
-           500, 0, "915rst");
-
-       /* If reset with a user forcewake, try to restore, otherwise turn it 
off */
-       if (dev_priv->forcewake_count)
-               dev_priv->display.force_wake_get(dev_priv);
-       else
-               dev_priv->display.force_wake_put(dev_priv);
-
-       /* Restore fifo count */
-       dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
-
-       mtx_unlock(&dev_priv->gt_lock);
-       return (ret);
-}
-
-int intel_gpu_reset(struct drm_device *dev)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       int ret = -ENODEV;
-
-       switch (INTEL_INFO(dev)->gen) {
-       case 7:
-       case 6:
-               ret = gen6_do_reset(dev);
-               break;
-       case 5:
-               ret = ironlake_do_reset(dev);
-               break;
-       case 4:
-               ret = i965_do_reset(dev);
-               break;
-       case 2:
-               ret = i8xx_do_reset(dev);
-               break;
-       }
-
-       /* Also reset the gpu hangman. */
-       if (dev_priv->stop_rings) {
-               DRM_DEBUG("Simulated gpu hang, resetting stop_rings\n");
-               dev_priv->stop_rings = 0;
-               if (ret == -ENODEV) {
-                       DRM_ERROR("Reset not implemented, but ignoring "
-                                 "error for simulated gpu hangs\n");
-                       ret = 0;
-               }
-       }
-
-       return ret;
-}
-
-/**
- * i915_reset - reset chip after a hang
- * @dev: drm device to reset
- *
- * Reset the chip.  Useful if a hang is detected. Returns zero on successful
- * reset or otherwise an error code.
- *
- * Procedure is fairly simple:
- *   - reset the chip using the reset reg
- *   - re-init context state
- *   - re-init hardware status page
- *   - re-init ring buffer
- *   - re-init interrupt state
- *   - re-init display
- */
-int i915_reset(struct drm_device *dev)
-{
-       drm_i915_private_t *dev_priv = dev->dev_private;
-       int ret;
-
-       if (!i915_try_reset)
-               return 0;
-
-       if (!sx_try_xlock(&dev->dev_struct_lock))
-               return (-EBUSY);
-
-       dev_priv->stop_rings = 0;
-
-       i915_gem_reset(dev);
-
-       ret = -ENODEV;
-       if (time_second - dev_priv->last_gpu_reset < 5)
-               DRM_ERROR("GPU hanging too fast, declaring wedged!\n");
-       else
-               ret = intel_gpu_reset(dev);
-
-       dev_priv->last_gpu_reset = time_second;
-       if (ret) {
-               DRM_ERROR("Failed to reset chip.\n");
-               DRM_UNLOCK(dev);
-               return ret;
-       }
-
-       /* Ok, now get things going again... */
-
-       /*
-        * Everything depends on having the GTT running, so we need to start
-        * there.  Fortunately we don't need to do this unless we reset the
-        * chip at a PCI level.
-        *
-        * Next we need to restore the context, but we don't use those
-        * yet either...
-        *
-        * Ring buffer needs to be re-initialized in the KMS case, or if X
-        * was running at the time of the reset (i.e. we weren't VT
-        * switched away).
-        */
-       if (drm_core_check_feature(dev, DRIVER_MODESET) ||
-                       !dev_priv->mm.suspended) {
-               struct intel_ring_buffer *ring;
-               int i;
-
-               dev_priv->mm.suspended = 0;
-
-               i915_gem_init_swizzling(dev);
-
-               for_each_ring(ring, dev_priv, i)
-                       ring->init(ring);
-
-               i915_gem_context_init(dev);
-               i915_gem_init_ppgtt(dev);
-
-               /*
-                * It would make sense to re-init all the other hw state, at
-                * least the rps/rc6/emon init done within modeset_init_hw. For
-                * some unknown reason, this blows up my ilk, so don't.
-                */
-               DRM_UNLOCK(dev);
-
-               if (drm_core_check_feature(dev, DRIVER_MODESET))
-                       intel_modeset_init_hw(dev);
-
-               drm_irq_uninstall(dev);
-               drm_irq_install(dev);
-       } else {
-               DRM_UNLOCK(dev);
-       }
-
-       return 0;
-}
-
-/* We give fast paths for the really cool registers */
-#define NEEDS_FORCE_WAKE(dev_priv, reg) \
-       (((dev_priv)->info->gen >= 6) && \
-        ((reg) < 0x40000) &&            \
-        ((reg) != FORCEWAKE)) && \
-       (!IS_VALLEYVIEW((dev_priv)->dev))
-
 #define __i915_read(x, y) \
 u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
        u##x val = 0; \
@@ -1018,12 +1011,12 @@ u##x i915_read##x(struct drm_i915_privat
                mtx_lock(&dev_priv->gt_lock); \
                if (dev_priv->forcewake_count == 0) \
                        dev_priv->display.force_wake_get(dev_priv); \
-               val = DRM_READ##y(dev_priv->mmio_map, reg);     \
+               val = DRM_READ##x(dev_priv->mmio_map, reg); \
                if (dev_priv->forcewake_count == 0) \
                        dev_priv->display.force_wake_put(dev_priv); \
                mtx_unlock(&dev_priv->gt_lock); \
        } else { \
-               val = DRM_READ##y(dev_priv->mmio_map, reg);     \
+               val = DRM_READ##x(dev_priv->mmio_map, reg); \
        } \
        trace_i915_reg_rw(false, reg, val, sizeof(val)); \
        return val; \
@@ -1042,7 +1035,7 @@ void i915_write##x(struct drm_i915_priva
        if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
                __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
        } \
-       DRM_WRITE##y(dev_priv->mmio_map, reg, val); \
+       DRM_WRITE##x(dev_priv->mmio_map, reg, val); \
        if (__predict_false(__fifo_ret)) { \
                gen6_gt_check_fifodbg(dev_priv); \
        } \
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to