]> Pileus Git - ~andy/linux/blobdiff - drivers/gpu/drm/i915/i915_drv.c
Merge tag 'v3.5-rc4' into drm-intel-next-queued
[~andy/linux] / drivers / gpu / drm / i915 / i915_drv.c
index 238a521658330bbf7468b95b351148436d383602..a378c0800304fbafd6b925312d3914763ca2d177 100644 (file)
@@ -233,6 +233,7 @@ static const struct intel_device_info intel_sandybridge_d_info = {
        .has_blt_ring = 1,
        .has_llc = 1,
        .has_pch_split = 1,
+       .has_force_wake = 1,
 };
 
 static const struct intel_device_info intel_sandybridge_m_info = {
@@ -243,6 +244,7 @@ static const struct intel_device_info intel_sandybridge_m_info = {
        .has_blt_ring = 1,
        .has_llc = 1,
        .has_pch_split = 1,
+       .has_force_wake = 1,
 };
 
 static const struct intel_device_info intel_ivybridge_d_info = {
@@ -252,6 +254,7 @@ static const struct intel_device_info intel_ivybridge_d_info = {
        .has_blt_ring = 1,
        .has_llc = 1,
        .has_pch_split = 1,
+       .has_force_wake = 1,
 };
 
 static const struct intel_device_info intel_ivybridge_m_info = {
@@ -262,6 +265,7 @@ static const struct intel_device_info intel_ivybridge_m_info = {
        .has_blt_ring = 1,
        .has_llc = 1,
        .has_pch_split = 1,
+       .has_force_wake = 1,
 };
 
 static const struct intel_device_info intel_valleyview_m_info = {
@@ -289,6 +293,7 @@ static const struct intel_device_info intel_haswell_d_info = {
        .has_blt_ring = 1,
        .has_llc = 1,
        .has_pch_split = 1,
+       .has_force_wake = 1,
 };
 
 static const struct intel_device_info intel_haswell_m_info = {
@@ -298,6 +303,7 @@ static const struct intel_device_info intel_haswell_m_info = {
        .has_blt_ring = 1,
        .has_llc = 1,
        .has_pch_split = 1,
+       .has_force_wake = 1,
 };
 
 static const struct pci_device_id pciidlist[] = {              /* aka */
@@ -352,6 +358,9 @@ static const struct pci_device_id pciidlist[] = {           /* aka */
        INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */
        INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */
        INTEL_VGA_DEVICE(0x0c16, &intel_haswell_d_info), /* SDV */
+       INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info),
+       INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info),
+       INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info),
        {0, 0, 0}
 };
 
@@ -799,7 +808,7 @@ static int gen6_do_reset(struct drm_device *dev)
        return ret;
 }
 
-static int intel_gpu_reset(struct drm_device *dev)
+int intel_gpu_reset(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret = -ENODEV;
@@ -860,8 +869,6 @@ int i915_reset(struct drm_device *dev)
        if (!mutex_trylock(&dev->struct_mutex))
                return -EBUSY;
 
-       dev_priv->stop_rings = 0;
-
        i915_gem_reset(dev);
 
        ret = -ENODEV;
@@ -903,12 +910,16 @@ int i915_reset(struct drm_device *dev)
                for_each_ring(ring, dev_priv, i)
                        ring->init(ring);
 
+               i915_gem_context_init(dev);
                i915_gem_init_ppgtt(dev);
 
-               mutex_unlock(&dev->struct_mutex);
+               /*
+                * 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.
+                */
 
-               if (drm_core_check_feature(dev, DRIVER_MODESET))
-                       intel_modeset_init_hw(dev);
+               mutex_unlock(&dev->struct_mutex);
 
                drm_irq_uninstall(dev);
                drm_irq_install(dev);
@@ -1139,10 +1150,87 @@ MODULE_LICENSE("GPL and additional rights");
 
 /* 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))
+       ((HAS_FORCE_WAKE((dev_priv)->dev)) && \
+        ((reg) < 0x40000) &&            \
+        ((reg) != FORCEWAKE))
+
+static bool IS_DISPLAYREG(u32 reg)
+{
+       /*
+        * This should make it easier to transition modules over to the
+        * new register block scheme, since we can do it incrementally.
+        */
+       if (reg >= 0x180000)
+               return false;
+
+       if (reg >= RENDER_RING_BASE &&
+           reg < RENDER_RING_BASE + 0xff)
+               return false;
+       if (reg >= GEN6_BSD_RING_BASE &&
+           reg < GEN6_BSD_RING_BASE + 0xff)
+               return false;
+       if (reg >= BLT_RING_BASE &&
+           reg < BLT_RING_BASE + 0xff)
+               return false;
+
+       if (reg == PGTBL_ER)
+               return false;
+
+       if (reg >= IPEIR_I965 &&
+           reg < HWSTAM)
+               return false;
+
+       if (reg == MI_MODE)
+               return false;
+
+       if (reg == GFX_MODE_GEN7)
+               return false;
+
+       if (reg == RENDER_HWS_PGA_GEN7 ||
+           reg == BSD_HWS_PGA_GEN7 ||
+           reg == BLT_HWS_PGA_GEN7)
+               return false;
+
+       if (reg == GEN6_BSD_SLEEP_PSMI_CONTROL ||
+           reg == GEN6_BSD_RNCID)
+               return false;
+
+       if (reg == GEN6_BLITTER_ECOSKPD)
+               return false;
+
+       if (reg >= 0x4000c &&
+           reg <= 0x4002c)
+               return false;
+
+       if (reg >= 0x4f000 &&
+           reg <= 0x4f08f)
+               return false;
+
+       if (reg >= 0x4f100 &&
+           reg <= 0x4f11f)
+               return false;
+
+       if (reg >= VLV_MASTER_IER &&
+           reg <= GEN6_PMIER)
+               return false;
+
+       if (reg >= FENCE_REG_SANDYBRIDGE_0 &&
+           reg < (FENCE_REG_SANDYBRIDGE_0 + (16*8)))
+               return false;
+
+       if (reg >= VLV_IIR_RW &&
+           reg <= VLV_ISR)
+               return false;
+
+       if (reg == FORCEWAKE_VLV ||
+           reg == FORCEWAKE_ACK_VLV)
+               return false;
+
+       if (reg == GEN6_GDRST)
+               return false;
+
+       return true;
+}
 
 #define __i915_read(x, y) \
 u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
@@ -1156,6 +1244,8 @@ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
                if (dev_priv->forcewake_count == 0) \
                        dev_priv->display.force_wake_put(dev_priv); \
                spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \
+       } else if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \
+               val = read##y(dev_priv->regs + reg + 0x180000);         \
        } else { \
                val = read##y(dev_priv->regs + reg); \
        } \
@@ -1176,7 +1266,11 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
        if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
                __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
        } \
-       write##y(val, dev_priv->regs + reg); \
+       if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \
+               write##y(val, dev_priv->regs + reg + 0x180000);         \
+       } else {                                                        \
+               write##y(val, dev_priv->regs + reg);                    \
+       }                                                               \
        if (unlikely(__fifo_ret)) { \
                gen6_gt_check_fifodbg(dev_priv); \
        } \