drm/i915/panel: Only record the backlight level when it is enabled
authorChris Wilson <chris@chris-wilson.co.uk>
Tue, 11 Jan 2011 17:06:04 +0000 (17:06 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Tue, 11 Jan 2011 20:27:04 +0000 (20:27 +0000)
By tracking the current status of the backlight we can prevent recording
the value of the current backlight when we have disabled it. And so
prevent restoring it to 'off' after an unbalanced sequence of
intel_lvds_disable/enable.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=22672
Tested-by: Alex Riesen <raa.lkml@gmail.com>
Tested-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: stable@kernel.org
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_panel.c

index aac1bf332f75bc3dcf30b4955b8617ac1acfabc5..972e08e4e054eea989a3131857742320fc6ac55c 100644 (file)
@@ -332,6 +332,7 @@ typedef struct drm_i915_private {
 
        /* LVDS info */
        int backlight_level;  /* restore backlight to this value */
+       bool backlight_enabled;
        struct drm_display_mode *panel_fixed_mode;
        struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
        struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
index f4d1797350f6dbe36e9a9cee79aab35d6e0026c7..bc829bbc14c80336b4a944f079d9cf66a7dcc5cc 100644 (file)
@@ -5802,6 +5802,8 @@ static void intel_setup_outputs(struct drm_device *dev)
                encoder->base.possible_clones =
                        intel_encoder_clones(dev, encoder->clone_mask);
        }
+
+       intel_panel_setup_backlight(dev);
 }
 
 static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
index d782ad9fd6dbb4aa7a18c40d90d9552e3d70309b..74db2557d6440ccc7b45e4f6cebf83d0ccb33751 100644 (file)
@@ -257,6 +257,9 @@ extern void intel_pch_panel_fitting(struct drm_device *dev,
 extern u32 intel_panel_get_max_backlight(struct drm_device *dev);
 extern u32 intel_panel_get_backlight(struct drm_device *dev);
 extern void intel_panel_set_backlight(struct drm_device *dev, u32 level);
+extern void intel_panel_setup_backlight(struct drm_device *dev);
+extern void intel_panel_enable_backlight(struct drm_device *dev);
+extern void intel_panel_disable_backlight(struct drm_device *dev);
 
 extern void intel_crtc_load_lut(struct drm_crtc *crtc);
 extern void intel_encoder_prepare (struct drm_encoder *encoder);
index aa2307080be2a1c501308488bb7f44f9ebf322cf..4e7dcb330dadba8156ce46aa7923d09fef4c3446 100644 (file)
@@ -106,7 +106,7 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds)
        I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
        POSTING_READ(lvds_reg);
 
-       intel_panel_set_backlight(dev, dev_priv->backlight_level);
+       intel_panel_enable_backlight(dev);
 }
 
 static void intel_lvds_disable(struct intel_lvds *intel_lvds)
@@ -123,8 +123,7 @@ static void intel_lvds_disable(struct intel_lvds *intel_lvds)
                lvds_reg = LVDS;
        }
 
-       dev_priv->backlight_level = intel_panel_get_backlight(dev);
-       intel_panel_set_backlight(dev, 0);
+       intel_panel_disable_backlight(dev);
 
        I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
 
@@ -398,8 +397,6 @@ static void intel_lvds_prepare(struct drm_encoder *encoder)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
 
-       dev_priv->backlight_level = intel_panel_get_backlight(dev);
-
        /* We try to do the minimum that is necessary in order to unlock
         * the registers for mode setting.
         *
@@ -430,9 +427,6 @@ static void intel_lvds_commit(struct drm_encoder *encoder)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
 
-       if (dev_priv->backlight_level == 0)
-               dev_priv->backlight_level = intel_panel_get_max_backlight(dev);
-
        /* Undo any unlocking done in prepare to prevent accidental
         * adjustment of the registers.
         */
index 7350ec2515c6947ba84dd9da432c6230c0787cdb..e00d200df3db1fe2b4dd7c2f2c8789003e58fc86 100644 (file)
@@ -250,3 +250,34 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level)
                tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK;
        I915_WRITE(BLC_PWM_CTL, tmp | level);
 }
+
+void intel_panel_disable_backlight(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       if (dev_priv->backlight_enabled) {
+               dev_priv->backlight_level = intel_panel_get_backlight(dev);
+               dev_priv->backlight_enabled = false;
+       }
+
+       intel_panel_set_backlight(dev, 0);
+}
+
+void intel_panel_enable_backlight(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       if (dev_priv->backlight_level == 0)
+               dev_priv->backlight_level = intel_panel_get_max_backlight(dev);
+
+       intel_panel_set_backlight(dev, dev_priv->backlight_level);
+       dev_priv->backlight_enabled = true;
+}
+
+void intel_panel_setup_backlight(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       dev_priv->backlight_level = intel_panel_get_max_backlight(dev);
+       dev_priv->backlight_enabled = dev_priv->backlight_level != 0;
+}