blob: 749976e53696a123f17b30201ec4f7b628ab0f34 [file] [log] [blame]
From 3bd01ef97d4c2dd8f35f47f1fb11047931cf2158 Mon Sep 17 00:00:00 2001
From: Daniel Vetter <>
Date: Thu, 11 Jul 2013 13:35:40 +0200
Subject: 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
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: Knut Petersen <>
Cc: Knut Petersen <>
Cc: Chris Wilson <>
Tested-by: Knut Petersen <>
Reviewed-by: Chris Wilson <>
Signed-off-by: Daniel Vetter <>
(cherry picked from commit 0692282181e248328c226c2520994fc06dfd65bf)
Signed-off-by: Darren Hart <>
drivers/gpu/drm/i915/intel_display.c | 11 ++++-------
drivers/gpu/drm/i915/intel_lvds.c | 7 +++++++
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7a4669183b6a..2962d0fa11e1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4913,22 +4913,19 @@ static void i9xx_get_pfit_config(struct intel_crtc *crtc,
uint32_t tmp;
+ 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)
- /* 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))
- 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 3264bfa842fc..9eeae0e3a062 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,
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.