drm/i915: clean up pipe bpp confusion
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 26 Mar 2013 23:45:01 +0000 (00:45 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 28 Mar 2013 00:09:35 +0000 (01:09 +0100)
- gen4 and earlier (save for g4x) only really have a 8bpc pipe, with
  the possibility to dither to 6bpc using the panel fitter
- g4x has hdmi, but no 12 bpc pipe ... !? Clamp hdmi accordingly.
- TV/SDVO out are the only connectors available on platforms with
  a pipe bpp != 8, add code to force the pipe to 8bpc unconditionally.

<rant>
The dither handling on gmch platforms is one giant disaster. I'm hoping
somewhat that vlv enabling will fix this up, but given that the 6bpc
handling for edp was simply added with another quick hack, I don't have
high hopes ...
</rant>

v2: Neither vlv nor g4x have 12bpc pipes. Still set pipe_bpp to 12*3,
but let the crtc code clamp things down to 10bpc on these platforms.

v3: Fix a bpc vs. bpp mixup in the gen4 and earlier pipe_bpp limiter
code.

v4: Drop the hunk in intel_hdmi.c about g4x/vlv 12bpc, it was wrong.

Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_tv.c

index 70c22b12b7c9b0247e31a665dff06dcadb3f7ca6..84bd8d36ce02fedfaf690aa6bb58ec28d778beda 100644 (file)
@@ -3971,6 +3971,14 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc,
                adjusted_mode->hsync_start == adjusted_mode->hdisplay)
                return false;
 
+       if ((IS_G4X(dev) || IS_VALLEYVIEW(dev)) && pipe_config->pipe_bpp > 10) {
+               pipe_config->pipe_bpp = 10*3; /* 12bpc is gen5+ */
+       } else if (INTEL_INFO(dev)->gen <= 4 && pipe_config->pipe_bpp > 8) {
+               /* only a 8bpc pipe, with 6bpc dither through the panel fitter
+                * for lvds. */
+               pipe_config->pipe_bpp = 8*3;
+       }
+
        return true;
 }
 
index c6fbfd1afc0500516dd4b6c26865a543b3cb5ef5..80f8680337dfea8d090e5d569b1e1fce4c6e345a 100644 (file)
@@ -1048,6 +1048,9 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
        struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
        struct drm_display_mode *mode = &pipe_config->requested_mode;
 
+       DRM_DEBUG_KMS("forcing bpc to 8 for SDVO\n");
+       pipe_config->pipe_bpp = 8*3;
+
        if (HAS_PCH_SPLIT(encoder->base.dev))
                pipe_config->has_pch_encoder = true;
 
index d808421c1c808e2b0f49480d73968ebae26d07ed..66737265200f63bf0735d7a67ec8ca122211b6fe 100644 (file)
@@ -905,11 +905,10 @@ intel_tv_mode_valid(struct drm_connector *connector,
 
 
 static bool
-intel_tv_mode_fixup(struct drm_encoder *encoder,
-                   const struct drm_display_mode *mode,
-                   struct drm_display_mode *adjusted_mode)
+intel_tv_compute_config(struct intel_encoder *encoder,
+                       struct intel_crtc_config *pipe_config)
 {
-       struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
+       struct intel_tv *intel_tv = enc_to_intel_tv(&encoder->base);
        const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
 
        if (!tv_mode)
@@ -918,7 +917,10 @@ intel_tv_mode_fixup(struct drm_encoder *encoder,
        if (intel_encoder_check_is_cloned(&intel_tv->base))
                return false;
 
-       adjusted_mode->clock = tv_mode->clock;
+       pipe_config->adjusted_mode.clock = tv_mode->clock;
+       DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
+       pipe_config->pipe_bpp = 8*3;
+
        return true;
 }
 
@@ -1485,7 +1487,6 @@ out:
 }
 
 static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
-       .mode_fixup = intel_tv_mode_fixup,
        .mode_set = intel_tv_mode_set,
 };
 
@@ -1620,6 +1621,7 @@ intel_tv_init(struct drm_device *dev)
        drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
                         DRM_MODE_ENCODER_TVDAC);
 
+       intel_encoder->compute_config = intel_tv_compute_config;
        intel_encoder->enable = intel_enable_tv;
        intel_encoder->disable = intel_disable_tv;
        intel_encoder->get_hw_state = intel_tv_get_hw_state;