[PATCH 09/19] drm/i915: clean up pipe bpp confusion

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



- 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>

Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
---
 drivers/gpu/drm/i915/intel_display.c |  8 ++++++++
 drivers/gpu/drm/i915/intel_hdmi.c    |  5 +++--
 drivers/gpu/drm/i915/intel_sdvo.c    |  3 +++
 drivers/gpu/drm/i915/intel_tv.c      | 14 ++++++++------
 4 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6f1b5cc..ed88a6e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3880,6 +3880,14 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc,
 		adjusted_mode->hsync_start == adjusted_mode->hdisplay)
 		return false;
 
+	if (IS_G4X(dev) && pipe_config->pipe_bpp > 10) {
+		pipe_config->pipe_bpp = 10; /* 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;
+	}
+
 	return true;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 48cb9f2..abe4abd 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -799,9 +799,10 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
 
 	/*
 	 * HDMI is either 12 or 8, so if the display lets 10bpc sneak
-	 * through, clamp it down.
+	 * through, clamp it down. Note that only gen5+ has 12bpc pipes, g4x
+	 * only has a 10bpc pipe, all earlier platforms have only 8bpc.
 	 */
-	if (pipe_config->pipe_bpp > 8*3) {
+	if (pipe_config->pipe_bpp > 8*3 && INTEL_INFO(dev)->gen > 5) {
 		DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");
 		pipe_config->pipe_bpp = 12*3;
 	} else {
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 02df8ad..5e3dfe8 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1045,6 +1045,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;
 
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 984a113..29b14ed 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -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,
 	.disable = intel_encoder_noop,
 };
@@ -1621,6 +1622,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;
-- 
1.7.11.7



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux