diff mbox

[1/4] drm/i915: Wait for LVDS panel power sequence

Message ID 1312653248-3487-2-git-send-email-keithp@keithp.com
State New, archived
Headers show

Commit Message

Keith Packard Aug. 6, 2011, 5:54 p.m. UTC
During mode setting, check to make sure the panel power sequencing has
completed before doing further operations on the device. This
uncovered errors with DPMS not turning the device off as it was left locked.

Signed-off-by: Keith Packard <keithp@keithp.com>
---
 drivers/gpu/drm/i915/intel_lvds.c |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)

Comments

Jesse Barnes Aug. 8, 2011, 4:27 p.m. UTC | #1
On Sat,  6 Aug 2011 10:54:05 -0700
Keith Packard <keithp@keithp.com> wrote:

> During mode setting, check to make sure the panel power sequencing has
> completed before doing further operations on the device. This
> uncovered errors with DPMS not turning the device off as it was left locked.
> 
> Signed-off-by: Keith Packard <keithp@keithp.com>
> ---
>  drivers/gpu/drm/i915/intel_lvds.c |   13 +++++++++++--
>  1 files changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> index 2e8ddfc..6985e42 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -72,14 +72,16 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds)
>  {
>  	struct drm_device *dev = intel_lvds->base.base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	u32 ctl_reg, lvds_reg;
> +	u32 ctl_reg, lvds_reg, stat_reg;
>  
>  	if (HAS_PCH_SPLIT(dev)) {
>  		ctl_reg = PCH_PP_CONTROL;
>  		lvds_reg = PCH_LVDS;
> +		stat_reg = PCH_PP_STATUS;
>  	} else {
>  		ctl_reg = PP_CONTROL;
>  		lvds_reg = LVDS;
> +		stat_reg = PP_STATUS;
>  	}
>  
>  	I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);
> @@ -105,6 +107,8 @@ 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);
> +	if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000))
> +		DRM_ERROR("timed out waiting for panel to power on\n");

Looks like maybe we want a small function for this...

>  	I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
> +	if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000))
> +		DRM_ERROR("timed out waiting for panel to power off status 0x%08x control 0x%08x\n",
> +			  I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL));

...to catch places like this where the wrong register gets used. :)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 2e8ddfc..6985e42 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -72,14 +72,16 @@  static void intel_lvds_enable(struct intel_lvds *intel_lvds)
 {
 	struct drm_device *dev = intel_lvds->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 ctl_reg, lvds_reg;
+	u32 ctl_reg, lvds_reg, stat_reg;
 
 	if (HAS_PCH_SPLIT(dev)) {
 		ctl_reg = PCH_PP_CONTROL;
 		lvds_reg = PCH_LVDS;
+		stat_reg = PCH_PP_STATUS;
 	} else {
 		ctl_reg = PP_CONTROL;
 		lvds_reg = LVDS;
+		stat_reg = PP_STATUS;
 	}
 
 	I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);
@@ -105,6 +107,8 @@  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);
+	if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000))
+		DRM_ERROR("timed out waiting for panel to power on\n");
 
 	intel_panel_enable_backlight(dev);
 }
@@ -113,19 +117,24 @@  static void intel_lvds_disable(struct intel_lvds *intel_lvds)
 {
 	struct drm_device *dev = intel_lvds->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 ctl_reg, lvds_reg;
+	u32 ctl_reg, lvds_reg, stat_reg;
 
 	if (HAS_PCH_SPLIT(dev)) {
 		ctl_reg = PCH_PP_CONTROL;
 		lvds_reg = PCH_LVDS;
+		stat_reg = PCH_PP_STATUS;
 	} else {
 		ctl_reg = PP_CONTROL;
 		lvds_reg = LVDS;
+		stat_reg = PP_STATUS;
 	}
 
 	intel_panel_disable_backlight(dev);
 
 	I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
+	if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000))
+		DRM_ERROR("timed out waiting for panel to power off status 0x%08x control 0x%08x\n",
+			  I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL));
 
 	if (intel_lvds->pfit_control) {
 		if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))