aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-04-11 10:29:06 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-04-18 03:43:25 -0400
commit87476d632c5041cfb962630e618d787243c81ed8 (patch)
tree472b386d263ac65d6a768f0297b45e0dea2d6feb
parentb6c5164d7bf624f3e1b750787ddb983150c5117c (diff)
drm/i915: Fixup pfit disabling for gen2/3
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 Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index fd7fb6a6a9a0..1bbf7071e0c4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3724,6 +3724,26 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
3724 encoder->enable(encoder); 3724 encoder->enable(encoder);
3725} 3725}
3726 3726
3727static void i9xx_pfit_disable(struct intel_crtc *crtc)
3728{
3729 struct drm_device *dev = crtc->base.dev;
3730 struct drm_i915_private *dev_priv = dev->dev_private;
3731 enum pipe pipe;
3732 uint32_t pctl = I915_READ(PFIT_CONTROL);
3733
3734 assert_pipe_disabled(dev_priv, crtc->pipe);
3735
3736 if (INTEL_INFO(dev)->gen >= 4)
3737 pipe = (pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT;
3738 else
3739 pipe = PIPE_B;
3740
3741 if (pipe == crtc->pipe) {
3742 DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n", pctl);
3743 I915_WRITE(PFIT_CONTROL, 0);
3744 }
3745}
3746
3727static void i9xx_crtc_disable(struct drm_crtc *crtc) 3747static void i9xx_crtc_disable(struct drm_crtc *crtc)
3728{ 3748{
3729 struct drm_device *dev = crtc->dev; 3749 struct drm_device *dev = crtc->dev;
@@ -3732,8 +3752,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
3732 struct intel_encoder *encoder; 3752 struct intel_encoder *encoder;
3733 int pipe = intel_crtc->pipe; 3753 int pipe = intel_crtc->pipe;
3734 int plane = intel_crtc->plane; 3754 int plane = intel_crtc->plane;
3735 u32 pctl;
3736
3737 3755
3738 if (!intel_crtc->active) 3756 if (!intel_crtc->active)
3739 return; 3757 return;
@@ -3753,11 +3771,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
3753 intel_disable_plane(dev_priv, plane, pipe); 3771 intel_disable_plane(dev_priv, plane, pipe);
3754 intel_disable_pipe(dev_priv, pipe); 3772 intel_disable_pipe(dev_priv, pipe);
3755 3773
3756 /* Disable pannel fitter if it is on this pipe. */ 3774 i9xx_pfit_disable(intel_crtc);
3757 pctl = I915_READ(PFIT_CONTROL);
3758 if ((pctl & PFIT_ENABLE) &&
3759 ((pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT) == pipe)
3760 I915_WRITE(PFIT_CONTROL, 0);
3761 3775
3762 intel_disable_pll(dev_priv, pipe); 3776 intel_disable_pll(dev_priv, pipe);
3763 3777