[Resend,V2] drm/i915: Disable VGA plane reliably
diff mbox

Message ID 1248688566-6206-1-git-send-email-ling.ma@intel.com
State Accepted
Headers show

Commit Message

ling.ma@intel.com July 27, 2009, 9:56 a.m. UTC
VGA random hang on recent G45/43 board. From spec, SR01
bit 5 should be set before VGA plane disable through
control register, otherwise we might get random crash
and lockups.

sync up with 2D driver which fixed freedesktop.org bug #17235

Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Ma Ling <ling.ma@intel.com>
---
clean up work in this version

 drivers/gpu/drm/i915/i915_reg.h      |    1 +
 drivers/gpu/drm/i915/intel_display.c |   30 +++++++++++++++++++++++++++++-
 2 files changed, 30 insertions(+), 1 deletions(-)

Comments

Zhenyu Wang July 28, 2009, 7:18 a.m. UTC | #1
On 2009.07.27 17:56:06 +0800, ling.ma@intel.com wrote:
> VGA random hang on recent G45/43 board. From spec, SR01
> bit 5 should be set before VGA plane disable through
> control register, otherwise we might get random crash
> and lockups.
> 
> sync up with 2D driver which fixed freedesktop.org bug #17235
> 
> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> Signed-off-by: Ma Ling <ling.ma@intel.com>
> ---
> clean up work in this version
> 
>  drivers/gpu/drm/i915/i915_reg.h      |    1 +
>  drivers/gpu/drm/i915/intel_display.c |   30 +++++++++++++++++++++++++++++-
>  2 files changed, 30 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 897a116..563e01c 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -1767,6 +1767,7 @@
>  # define VGA_DISP_DISABLE			(1 << 31)
>  # define VGA_2X_MODE				(1 << 30)
>  # define VGA_PIPE_B_SELECT			(1 << 29)
> +# define VGA_CENTER_ENABLE			(3 << 24)
>  
>  /* IGDNG */
>  
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index a58bfad..a10a303 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -1281,6 +1281,34 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
>  	}
>  }
>  
> +static void
> +intel_crtc_disable_vga_plane(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	int vgacntrl = I915_READ(VGACNTRL);
> +	uint8_t sr01;
> +
> +	if (vgacntrl & VGA_DISP_DISABLE)
> +		return;
> +	/*
> +	 * Set SR01_SCREEN_OFF of SR1 register;
> +	 * Wait 30us;
> +	 */
> +
> +	I915_WRITE8(SRX_INDEX, SR01);
> +	sr01 = I915_READ8(SRX_DATA);
> +	I915_WRITE8(SRX_DATA, sr01 | SR01_SCREEN_OFF);
> +	udelay(30);
> +	/* disable center mode on 965GM and G4X platform */
> +	if (IS_I965GM(dev) || IS_G4X(dev))
> +		vgacntrl &= ~VGA_CENTER_ENABLE;
> +	vgacntrl |= VGA_DISP_DISABLE;
> +
> +	I915_WRITE(VGACNTRL, vgacntrl);
> +	intel_wait_for_vblank(dev);
> +}
> +

Could you carry this to IGDNG too? like in my 1/6 patch set for
IGDNG, which has different VGACNTRL register offset as CPU_VGACNTRL.

> +
>  static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
>  {
>  	struct drm_device *dev = crtc->dev;
> @@ -1342,7 +1370,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
>  		//intel_crtc_dpms_video(crtc, FALSE); TODO
>  
>  		/* Disable the VGA plane that we never use */
> -		I915_WRITE(VGACNTRL, VGA_DISP_DISABLE);
> +		intel_crtc_disable_vga_plane(dev);
>  
>  		/* Disable display plane */
>  		temp = I915_READ(dspcntr_reg);
> -- 
> 1.5.4.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Patch
diff mbox

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 897a116..563e01c 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1767,6 +1767,7 @@ 
 # define VGA_DISP_DISABLE			(1 << 31)
 # define VGA_2X_MODE				(1 << 30)
 # define VGA_PIPE_B_SELECT			(1 << 29)
+# define VGA_CENTER_ENABLE			(3 << 24)
 
 /* IGDNG */
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a58bfad..a10a303 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1281,6 +1281,34 @@  static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
 	}
 }
 
+static void
+intel_crtc_disable_vga_plane(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int vgacntrl = I915_READ(VGACNTRL);
+	uint8_t sr01;
+
+	if (vgacntrl & VGA_DISP_DISABLE)
+		return;
+	/*
+	 * Set SR01_SCREEN_OFF of SR1 register;
+	 * Wait 30us;
+	 */
+
+	I915_WRITE8(SRX_INDEX, SR01);
+	sr01 = I915_READ8(SRX_DATA);
+	I915_WRITE8(SRX_DATA, sr01 | SR01_SCREEN_OFF);
+	udelay(30);
+	/* disable center mode on 965GM and G4X platform */
+	if (IS_I965GM(dev) || IS_G4X(dev))
+		vgacntrl &= ~VGA_CENTER_ENABLE;
+	vgacntrl |= VGA_DISP_DISABLE;
+
+	I915_WRITE(VGACNTRL, vgacntrl);
+	intel_wait_for_vblank(dev);
+}
+
+
 static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
 {
 	struct drm_device *dev = crtc->dev;
@@ -1342,7 +1370,7 @@  static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
 		//intel_crtc_dpms_video(crtc, FALSE); TODO
 
 		/* Disable the VGA plane that we never use */
-		I915_WRITE(VGACNTRL, VGA_DISP_DISABLE);
+		intel_crtc_disable_vga_plane(dev);
 
 		/* Disable display plane */
 		temp = I915_READ(dspcntr_reg);