Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
[linux-3.10.git] / drivers / gpu / drm / i915 / i915_drv.c
index f682532..aac4e5e 100644 (file)
@@ -469,6 +469,9 @@ static int i915_drm_freeze(struct drm_device *dev)
                                "GEM idle failed, resume might fail\n");
                        return error;
                }
+
+               intel_modeset_disable(dev);
+
                drm_irq_uninstall(dev);
        }
 
@@ -542,13 +545,9 @@ static int i915_drm_thaw(struct drm_device *dev)
                mutex_unlock(&dev->struct_mutex);
 
                intel_modeset_init_hw(dev);
+               intel_modeset_setup_hw_state(dev);
                drm_mode_config_reset(dev);
                drm_irq_install(dev);
-
-               /* Resume the modeset for every activated CRTC */
-               mutex_lock(&dev->mode_config.mutex);
-               drm_helper_resume_force_mode(dev);
-               mutex_unlock(&dev->mode_config.mutex);
        }
 
        intel_opregion_init(dev);
@@ -1059,7 +1058,7 @@ 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)
+       if (reg >= VLV_DISPLAY_BASE)
                return false;
 
        if (reg >= RENDER_RING_BASE &&
@@ -1173,9 +1172,59 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
        if (unlikely(__fifo_ret)) { \
                gen6_gt_check_fifodbg(dev_priv); \
        } \
+       if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \
+               DRM_ERROR("Unclaimed write to %x\n", reg); \
+               writel(ERR_INT_MMIO_UNCLAIMED, dev_priv->regs + GEN7_ERR_INT);  \
+       } \
 }
 __i915_write(8, b)
 __i915_write(16, w)
 __i915_write(32, l)
 __i915_write(64, q)
 #undef __i915_write
+
+static const struct register_whitelist {
+       uint64_t offset;
+       uint32_t size;
+       uint32_t gen_bitmask; /* support gens, 0x10 for 4, 0x30 for 4 and 5, etc. */
+} whitelist[] = {
+       { RING_TIMESTAMP(RENDER_RING_BASE), 8, 0xF0 },
+};
+
+int i915_reg_read_ioctl(struct drm_device *dev,
+                       void *data, struct drm_file *file)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_reg_read *reg = data;
+       struct register_whitelist const *entry = whitelist;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(whitelist); i++, entry++) {
+               if (entry->offset == reg->offset &&
+                   (1 << INTEL_INFO(dev)->gen & entry->gen_bitmask))
+                       break;
+       }
+
+       if (i == ARRAY_SIZE(whitelist))
+               return -EINVAL;
+
+       switch (entry->size) {
+       case 8:
+               reg->val = I915_READ64(reg->offset);
+               break;
+       case 4:
+               reg->val = I915_READ(reg->offset);
+               break;
+       case 2:
+               reg->val = I915_READ16(reg->offset);
+               break;
+       case 1:
+               reg->val = I915_READ8(reg->offset);
+               break;
+       default:
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       return 0;
+}