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. Reported-by: Knut Petersen <Knut_Petersen at t-online.de> Cc: Knut Petersen <Knut_Petersen at t-online.de> Cc: Chris Wilson <chris at chris-wilson.co.uk> References: http://lists.freedesktop.org/archives/intel-gfx/2013-July/030092.html Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch> --- drivers/gpu/drm/i915/intel_display.c | 12 +++++------- drivers/gpu/drm/i915/intel_lvds.c | 7 +++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 85f3eb7..1ccc468 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4913,22 +4913,20 @@ static void i9xx_get_pfit_config(struct intel_crtc *crtc, uint32_t tmp; 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 (crtc->pipe != PIPE_B) return; - - /* gen2/3 store dither state in pfit control, needs to match */ - pipe_config->gmch_pfit.control = tmp & PANEL_8TO6_DITHER_ENABLE; } else { if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT)) return; } - if (!(tmp & PFIT_ENABLE)) - return; - - pipe_config->gmch_pfit.control = I915_READ(PFIT_CONTROL); + pipe_config->gmch_pfit.control = tmp; pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS); if (INTEL_INFO(dev)->gen < 5) pipe_config->gmch_pfit.lvds_border_bits = diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 2abb2d3..1207998 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -109,6 +109,13 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, flags |= DRM_MODE_FLAG_PVSYNC; 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. -- 1.8.1.4