[Intel-gfx] [PATCH 5/8] drm/i915: Fix port_clock readout for SDVO and HDMI 12bpc cases

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Wed Sep 4 13:14:49 CEST 2013


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

Now that adjusted_mode.clock no longer contains the pixel_multiplier, we
can kill the get_clock() callback and instead read out the DPLL stuff in
get_pipe_config().

We start by filling out both adjusted_mode.clock and port_clock in
i9xx_crtc_clock_get() and ironlake_crtc_clock_get(). We must keep in
mind that now both clocks include pixel_multiplier on non-PCH
platforms, and on PCH platforms neither clock includes pixel_multiplier.
We fix that up in the encoders' get_config() functions after we've
determined the actual value of pixel_multiplier.

We can also use the pipe_bpp value to fix up port_clock for the 12bpc
HDMI case on PCH platforms.

Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  1 -
 drivers/gpu/drm/i915/intel_display.c | 32 +++++++++++++++-----------------
 drivers/gpu/drm/i915/intel_hdmi.c    |  3 +++
 drivers/gpu/drm/i915/intel_sdvo.c    | 11 +++++++++++
 4 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 769c138..09fc308 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -369,7 +369,6 @@ struct drm_i915_display_funcs {
 	 * fills out the pipe-config with the hw state. */
 	bool (*get_pipe_config)(struct intel_crtc *,
 				struct intel_crtc_config *);
-	void (*get_clock)(struct intel_crtc *, struct intel_crtc_config *);
 	int (*crtc_mode_set)(struct drm_crtc *crtc,
 			     int x, int y,
 			     struct drm_framebuffer *old_fb);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 74affb1..8fcb8db 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5068,7 +5068,12 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
 		}
 	}
 
-	pipe_config->adjusted_mode.clock = clock.dot;
+	/*
+	 * This value includes pixel_multiplier. We will fix
+	 * adjusted_mode.clock in the encoder's get_config()
+	 * function if necessary.
+	 */
+	pipe_config->port_clock = pipe_config->adjusted_mode.clock = clock.dot;
 }
 
 static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
@@ -5133,6 +5138,8 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
 		}
 	}
 
+	i9xx_crtc_clock_get(crtc, pipe_config);
+
 	return true;
 }
 
@@ -6029,7 +6036,11 @@ static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
 	clock = ((u64)link_m * (u64)link_freq);
 	do_div(clock, link_n);
 
-	pipe_config->adjusted_mode.clock = clock;
+	/*
+	 * This value does not include pixel_multiplier. We will fix
+	 * port_clock in the encoder's get_config() function if necessary.
+	 */
+	pipe_config->port_clock = pipe_config->adjusted_mode.clock = clock;
 }
 
 static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
@@ -6102,6 +6113,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
 
 	ironlake_get_pfit_config(crtc, pipe_config);
 
+	ironlake_crtc_clock_get(crtc, pipe_config);
+
 	return true;
 }
 
@@ -8811,9 +8824,6 @@ check_crtc_state(struct drm_device *dev)
 				encoder->get_config(encoder, &pipe_config);
 		}
 
-		if (dev_priv->display.get_clock)
-			dev_priv->display.get_clock(crtc, &pipe_config);
-
 		WARN(crtc->active != active,
 		     "crtc active state doesn't match with hw state "
 		     "(expected %i, found %i)\n", crtc->active, active);
@@ -9839,7 +9849,6 @@ static void intel_init_display(struct drm_device *dev)
 		dev_priv->display.update_plane = ironlake_update_plane;
 	} else if (HAS_PCH_SPLIT(dev)) {
 		dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
-		dev_priv->display.get_clock = ironlake_crtc_clock_get;
 		dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set;
 		dev_priv->display.crtc_enable = ironlake_crtc_enable;
 		dev_priv->display.crtc_disable = ironlake_crtc_disable;
@@ -9847,7 +9856,6 @@ static void intel_init_display(struct drm_device *dev)
 		dev_priv->display.update_plane = ironlake_update_plane;
 	} else if (IS_VALLEYVIEW(dev)) {
 		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
-		dev_priv->display.get_clock = i9xx_crtc_clock_get;
 		dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
 		dev_priv->display.crtc_enable = valleyview_crtc_enable;
 		dev_priv->display.crtc_disable = i9xx_crtc_disable;
@@ -9855,7 +9863,6 @@ static void intel_init_display(struct drm_device *dev)
 		dev_priv->display.update_plane = i9xx_update_plane;
 	} else {
 		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
-		dev_priv->display.get_clock = i9xx_crtc_clock_get;
 		dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
 		dev_priv->display.crtc_enable = i9xx_crtc_enable;
 		dev_priv->display.crtc_disable = i9xx_crtc_disable;
@@ -10469,15 +10476,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			      pipe);
 	}
 
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list,
-			    base.head) {
-		if (!crtc->active)
-			continue;
-		if (dev_priv->display.get_clock)
-			dev_priv->display.get_clock(crtc,
-						    &crtc->config);
-	}
-
 	list_for_each_entry(connector, &dev->mode_config.connector_list,
 			    base.head) {
 		if (connector->get_hw_state(connector)) {
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 4148cc8..3d833a3 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -727,6 +727,9 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
 		flags |= DRM_MODE_FLAG_NVSYNC;
 
 	pipe_config->adjusted_mode.flags |= flags;
+
+	if (pipe_config->pipe_bpp == 12*3)
+		pipe_config->port_clock = pipe_config->adjusted_mode.clock * 3 / 2;
 }
 
 static void intel_enable_hdmi(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 74042c6..4c1b9ac 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1357,6 +1357,17 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
 			 >> SDVO_PORT_MULTIPLY_SHIFT) + 1;
 	}
 
+	/*
+	 * On PCH platforms our clock doesn't yet include the pixel
+	 * multiplier, whereas on non-PCH platforms it already does.
+	 */
+	if (HAS_PCH_SPLIT(dev))
+		pipe_config->port_clock = pipe_config->adjusted_mode.clock *
+			pipe_config->pixel_multiplier;
+	else
+		pipe_config->adjusted_mode.clock = pipe_config->port_clock /
+			pipe_config->pixel_multiplier;
+
 	/* Cross check the port pixel multiplier with the sdvo encoder state. */
 	if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT,
 				 &val, 1)) {
-- 
1.8.1.5




More information about the Intel-gfx mailing list