drm/i915: make rc6 module parameter read-only
[pandora-kernel.git] / drivers / gpu / drm / i915 / i915_drv.c
index 15bfa91..d0f8830 100644 (file)
@@ -58,15 +58,15 @@ module_param_named(powersave, i915_powersave, int, 0600);
 MODULE_PARM_DESC(powersave,
                "Enable powersavings, fbc, downclocking, etc. (default: true)");
 
-unsigned int i915_semaphores __read_mostly = 0;
+int i915_semaphores __read_mostly = -1;
 module_param_named(semaphores, i915_semaphores, int, 0600);
 MODULE_PARM_DESC(semaphores,
-               "Use semaphores for inter-ring sync (default: false)");
+               "Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))");
 
-unsigned int i915_enable_rc6 __read_mostly = 0;
-module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);
+int i915_enable_rc6 __read_mostly = -1;
+module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400);
 MODULE_PARM_DESC(i915_enable_rc6,
-               "Enable power-saving render C-state 6 (default: true)");
+               "Enable power-saving render C-state 6 (default: -1 (use per-chip default)");
 
 int i915_enable_fbc __read_mostly = -1;
 module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600);
@@ -328,7 +328,7 @@ void intel_detect_pch(struct drm_device *dev)
        }
 }
 
-static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
+void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
 {
        int count;
 
@@ -344,6 +344,22 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
                udelay(10);
 }
 
+void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
+{
+       int count;
+
+       count = 0;
+       while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
+               udelay(10);
+
+       I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 1);
+       POSTING_READ(FORCEWAKE_MT);
+
+       count = 0;
+       while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
+               udelay(10);
+}
+
 /*
  * Generally this is called implicitly by the register read function. However,
  * if some sequence requires the GT to not power down then this function should
@@ -352,28 +368,37 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
  */
 void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
 {
-       WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+       unsigned long irqflags;
 
-       /* Forcewake is atomic in case we get in here without the lock */
-       if (atomic_add_return(1, &dev_priv->forcewake_count) == 1)
-               __gen6_gt_force_wake_get(dev_priv);
+       spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
+       if (dev_priv->forcewake_count++ == 0)
+               dev_priv->display.force_wake_get(dev_priv);
+       spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
 }
 
-static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
+void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
 {
        I915_WRITE_NOTRACE(FORCEWAKE, 0);
        POSTING_READ(FORCEWAKE);
 }
 
+void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
+{
+       I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 0);
+       POSTING_READ(FORCEWAKE_MT);
+}
+
 /*
  * see gen6_gt_force_wake_get()
  */
 void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
 {
-       WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+       unsigned long irqflags;
 
-       if (atomic_dec_and_test(&dev_priv->forcewake_count))
-               __gen6_gt_force_wake_put(dev_priv);
+       spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
+       if (--dev_priv->forcewake_count == 0)
+               dev_priv->display.force_wake_put(dev_priv);
+       spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
 }
 
 void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
@@ -417,6 +442,10 @@ static int i915_drm_freeze(struct drm_device *dev)
        /* Modeset on resume, not lid events */
        dev_priv->modeset_on_lid = 0;
 
+       console_lock();
+       intel_fbdev_set_suspend(dev, 1);
+       console_unlock();
+
        return 0;
 }
 
@@ -479,7 +508,9 @@ static int i915_drm_thaw(struct drm_device *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);
 
                if (IS_IRONLAKE_M(dev))
                        ironlake_enable_rc6(dev);
@@ -489,6 +520,9 @@ static int i915_drm_thaw(struct drm_device *dev)
 
        dev_priv->modeset_on_lid = 0;
 
+       console_lock();
+       intel_fbdev_set_suspend(dev, 0);
+       console_unlock();
        return error;
 }
 
@@ -604,6 +638,7 @@ int i915_reset(struct drm_device *dev, u8 flags)
         * need to
         */
        bool need_display = true;
+       unsigned long irqflags;
        int ret;
 
        if (!i915_try_reset)
@@ -622,8 +657,10 @@ int i915_reset(struct drm_device *dev, u8 flags)
        case 6:
                ret = gen6_do_reset(dev, flags);
                /* If reset with a user forcewake, try to restore */
-               if (atomic_read(&dev_priv->forcewake_count))
-                       __gen6_gt_force_wake_get(dev_priv);
+               spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
+               if (dev_priv->forcewake_count)
+                       dev_priv->display.force_wake_get(dev_priv);
+               spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
                break;
        case 5:
                ret = ironlake_do_reset(dev, flags);
@@ -903,8 +940,9 @@ 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))
+        ((reg) < 0x40000) &&            \
+        ((reg) != FORCEWAKE) &&         \
+        ((reg) != ECOBUS))
 
 #define __i915_read(x, y) \
 u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \