Commit 47356eb6 authored by Chris Wilson's avatar Chris Wilson

drm/i915/panel: Only record the backlight level when it is enabled

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=22672Tested-by: default avatarAlex Riesen <raa.lkml@gmail.com>
Tested-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: stable@kernel.org
parent 97aaf910
...@@ -332,6 +332,7 @@ typedef struct drm_i915_private { ...@@ -332,6 +332,7 @@ typedef struct drm_i915_private {
/* LVDS info */ /* LVDS info */
int backlight_level; /* restore backlight to this value */ int backlight_level; /* restore backlight to this value */
bool backlight_enabled;
struct drm_display_mode *panel_fixed_mode; struct drm_display_mode *panel_fixed_mode;
struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */ struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */ struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
......
...@@ -5802,6 +5802,8 @@ static void intel_setup_outputs(struct drm_device *dev) ...@@ -5802,6 +5802,8 @@ static void intel_setup_outputs(struct drm_device *dev)
encoder->base.possible_clones = encoder->base.possible_clones =
intel_encoder_clones(dev, encoder->clone_mask); intel_encoder_clones(dev, encoder->clone_mask);
} }
intel_panel_setup_backlight(dev);
} }
static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
......
...@@ -257,6 +257,9 @@ extern void intel_pch_panel_fitting(struct drm_device *dev, ...@@ -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_max_backlight(struct drm_device *dev);
extern u32 intel_panel_get_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_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_crtc_load_lut(struct drm_crtc *crtc);
extern void intel_encoder_prepare (struct drm_encoder *encoder); extern void intel_encoder_prepare (struct drm_encoder *encoder);
......
...@@ -106,7 +106,7 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds) ...@@ -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); I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
POSTING_READ(lvds_reg); 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) static void intel_lvds_disable(struct intel_lvds *intel_lvds)
...@@ -123,8 +123,7 @@ 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; lvds_reg = LVDS;
} }
dev_priv->backlight_level = intel_panel_get_backlight(dev); intel_panel_disable_backlight(dev);
intel_panel_set_backlight(dev, 0);
I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
...@@ -398,8 +397,6 @@ static void intel_lvds_prepare(struct drm_encoder *encoder) ...@@ -398,8 +397,6 @@ static void intel_lvds_prepare(struct drm_encoder *encoder)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_lvds *intel_lvds = to_intel_lvds(encoder); 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 /* We try to do the minimum that is necessary in order to unlock
* the registers for mode setting. * the registers for mode setting.
* *
...@@ -430,9 +427,6 @@ static void intel_lvds_commit(struct drm_encoder *encoder) ...@@ -430,9 +427,6 @@ static void intel_lvds_commit(struct drm_encoder *encoder)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_lvds *intel_lvds = to_intel_lvds(encoder); 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 /* Undo any unlocking done in prepare to prevent accidental
* adjustment of the registers. * adjustment of the registers.
*/ */
......
...@@ -250,3 +250,34 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level) ...@@ -250,3 +250,34 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level)
tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK; tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK;
I915_WRITE(BLC_PWM_CTL, tmp | level); 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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment