diff mbox

[3/7] drm/i915: Fixup pfit disabling for gen2/3

Message ID 1365690550-5716-3-git-send-email-daniel.vetter@ffwll.ch (mailing list archive)
State New, archived
Headers show

Commit Message

Daniel Vetter April 11, 2013, 2:29 p.m. UTC
The recent rework of the pfit handling didn't take into account that
the panel fitter is fixed to pipe B:

commit 24a1f16de97c4cf0029d9acd04be06db32208726
Author: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Date:   Fri Feb 8 16:35:37 2013 +0200

    drm/i915: disable shared panel fitter for pipe

Fix this up by properly computing the pipe the pfit is on. Also
extract the logic into its own function, add a debug assert to check
that the pipe is off (mostly just documentation) and add some debug
output.

If pipe A was disabled after pipe B was set up, the panel fitter will
be disabled. Now most userspace doesn't do modesets in this order,
which is why I couldn't ever reproduce this and why it took me so long
to figure out.

We really need hw state readout and check support for the pannel
fitter ...

Reported-by: Hans de Bruin <jmdebruin@xmsnet.nl>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Hans de Bruin <jmdebruin@xmsnet.nl>
References: http://permalink.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/19049
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_display.c |   28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

Comments

Chris Wilson April 12, 2013, 2:01 p.m. UTC | #1
On Thu, Apr 11, 2013 at 04:29:06PM +0200, Daniel Vetter wrote:
> The recent rework of the pfit handling didn't take into account that
> the panel fitter is fixed to pipe B:
> 
> commit 24a1f16de97c4cf0029d9acd04be06db32208726
> Author: Mika Kuoppala <mika.kuoppala@linux.intel.com>
> Date:   Fri Feb 8 16:35:37 2013 +0200
> 
>     drm/i915: disable shared panel fitter for pipe
> 
> Fix this up by properly computing the pipe the pfit is on. Also
> extract the logic into its own function, add a debug assert to check
> that the pipe is off (mostly just documentation) and add some debug
> output.
> 
> If pipe A was disabled after pipe B was set up, the panel fitter will
> be disabled. Now most userspace doesn't do modesets in this order,
> which is why I couldn't ever reproduce this and why it took me so long
> to figure out.
> 
> We really need hw state readout and check support for the pannel
> fitter ...
> 
> Reported-by: Hans de Bruin <jmdebruin@xmsnet.nl>
> Cc: Mika Kuoppala <mika.kuoppala@intel.com>
> Cc: Hans de Bruin <jmdebruin@xmsnet.nl>
> References: http://permalink.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/19049
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 58c6bb6..38b8a77 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3623,6 +3623,26 @@  static void i9xx_crtc_enable(struct drm_crtc *crtc)
 		encoder->enable(encoder);
 }
 
+static void i9xx_pfit_disable(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe;
+	uint32_t pctl = I915_READ(PFIT_CONTROL);
+
+	assert_pipe_disabled(dev_priv, crtc->pipe);
+
+	if (INTEL_INFO(dev)->gen >= 4)
+		pipe = (pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT;
+	else
+		pipe = PIPE_B;
+
+	if (pipe == crtc->pipe) {
+		DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n", pctl);
+		I915_WRITE(PFIT_CONTROL, 0);
+	}
+}
+
 static void i9xx_crtc_disable(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
@@ -3631,8 +3651,6 @@  static void i9xx_crtc_disable(struct drm_crtc *crtc)
 	struct intel_encoder *encoder;
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
-	u32 pctl;
-
 
 	if (!intel_crtc->active)
 		return;
@@ -3652,11 +3670,7 @@  static void i9xx_crtc_disable(struct drm_crtc *crtc)
 	intel_disable_plane(dev_priv, plane, pipe);
 	intel_disable_pipe(dev_priv, pipe);
 
-	/* Disable pannel fitter if it is on this pipe. */
-	pctl = I915_READ(PFIT_CONTROL);
-	if ((pctl & PFIT_ENABLE) &&
-	    ((pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT) == pipe)
-		I915_WRITE(PFIT_CONTROL, 0);
+	i9xx_pfit_disable(intel_crtc);
 
 	intel_disable_pll(dev_priv, pipe);