Commit 87476d63 authored by Daniel Vetter's avatar Daniel Vetter

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 24a1f16d
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: default avatarHans 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/19049Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent b6c5164d
...@@ -3724,6 +3724,26 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) ...@@ -3724,6 +3724,26 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
encoder->enable(encoder); 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) static void i9xx_crtc_disable(struct drm_crtc *crtc)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
...@@ -3732,8 +3752,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) ...@@ -3732,8 +3752,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
struct intel_encoder *encoder; struct intel_encoder *encoder;
int pipe = intel_crtc->pipe; int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane; int plane = intel_crtc->plane;
u32 pctl;
if (!intel_crtc->active) if (!intel_crtc->active)
return; return;
...@@ -3753,11 +3771,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) ...@@ -3753,11 +3771,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
intel_disable_plane(dev_priv, plane, pipe); intel_disable_plane(dev_priv, plane, pipe);
intel_disable_pipe(dev_priv, pipe); intel_disable_pipe(dev_priv, pipe);
/* Disable pannel fitter if it is on this pipe. */ i9xx_pfit_disable(intel_crtc);
pctl = I915_READ(PFIT_CONTROL);
if ((pctl & PFIT_ENABLE) &&
((pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT) == pipe)
I915_WRITE(PFIT_CONTROL, 0);
intel_disable_pll(dev_priv, pipe); intel_disable_pll(dev_priv, pipe);
......
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