Commit 06922821 authored by Daniel Vetter's avatar Daniel Vetter

drm/i915: fix up readout of the lvds dither bit on gen2/3

It's in the PFIT_CONTROL register, but very much associated with the
lvds encoder. So move the readout for it (in the case of an otherwise
disabled pfit) from the pipe to the lvds encoder's get_config
function.

Otherwise we get a pipe state mismatch if we use pipe B for a non-lvds
output and we've left the dither bit enabled behind us. This can
happen if the BIOS has set the bit (some seem to unconditionally do
that, even in the complete absence of an lvds port), but not enabled
pipe B at boot-up. Then we won't clear the pfit control register since
we can only touch that if the pfit is associated with our pipe in the
crtc configuration - we could trample over the pfit state of the other
pipe otherwise since it's shared. Once pipe B is enabled we notice
that the 6to8 dither bit is set and complain about the mismatch.

Note that testing indicates that we don't actually need to set this
bit when the pfit is disabled, dithering on 18bpp panels seems to work
regardless. But ripping that code out is not something for a bugfix
meant for -rc kernels.

v2: While at it clarify the logic in i9xx_get_pfit_config, spurred by
comments from Chris on irc.

v3: Use Chris suggestion to make the control flow in
i9xx_get_pfit_config easier to understand.

v4: Kill the extra line, spotted by Chris.
Reported-by: default avatarKnut Petersen <Knut_Petersen@t-online.de>
Cc: Knut Petersen <Knut_Petersen@t-online.de>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
References: http://lists.freedesktop.org/archives/intel-gfx/2013-July/030092.htmlTested-by: default avatarKnut Petersen <Knut_Petersen@t-online.de>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 46a0b638
...@@ -4913,22 +4913,19 @@ static void i9xx_get_pfit_config(struct intel_crtc *crtc, ...@@ -4913,22 +4913,19 @@ static void i9xx_get_pfit_config(struct intel_crtc *crtc,
uint32_t tmp; uint32_t tmp;
tmp = I915_READ(PFIT_CONTROL); tmp = I915_READ(PFIT_CONTROL);
if (!(tmp & PFIT_ENABLE))
return;
/* Check whether the pfit is attached to our pipe. */
if (INTEL_INFO(dev)->gen < 4) { if (INTEL_INFO(dev)->gen < 4) {
if (crtc->pipe != PIPE_B) if (crtc->pipe != PIPE_B)
return; return;
/* gen2/3 store dither state in pfit control, needs to match */
pipe_config->gmch_pfit.control = tmp & PANEL_8TO6_DITHER_ENABLE;
} else { } else {
if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT)) if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT))
return; return;
} }
if (!(tmp & PFIT_ENABLE)) pipe_config->gmch_pfit.control = tmp;
return;
pipe_config->gmch_pfit.control = I915_READ(PFIT_CONTROL);
pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS); pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS);
if (INTEL_INFO(dev)->gen < 5) if (INTEL_INFO(dev)->gen < 5)
pipe_config->gmch_pfit.lvds_border_bits = pipe_config->gmch_pfit.lvds_border_bits =
......
...@@ -109,6 +109,13 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, ...@@ -109,6 +109,13 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
flags |= DRM_MODE_FLAG_PVSYNC; flags |= DRM_MODE_FLAG_PVSYNC;
pipe_config->adjusted_mode.flags |= flags; pipe_config->adjusted_mode.flags |= flags;
/* gen2/3 store dither state in pfit control, needs to match */
if (INTEL_INFO(dev)->gen < 4) {
tmp = I915_READ(PFIT_CONTROL);
pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE;
}
} }
/* The LVDS pin pair needs to be on before the DPLLs are enabled. /* The LVDS pin pair needs to be on before the DPLLs are enabled.
......
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