[Intel-gfx] [PATCH v2 3/9] drm/i915: Redefine the parameters of update_wm callback function

yakui.zhao at intel.com yakui.zhao at intel.com
Wed Jan 20 10:41:12 CET 2010


From: Zhao Yakui <yakui.zhao at intel.com>

When we calculate the display plane/cursor self-refresh watermark, we will
use another parameter to calculate the line_time. For example: htotal

So we will redefine the parameters of update_wm callback function.

Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
Reviewd-by: Jesse Barnes <jbarnes at virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_drv.h      |    6 +-
 drivers/gpu/drm/i915/intel_display.c |  150 ++++++++++++++++++++++------------
 2 files changed, 103 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a9e571f..e070dc9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -160,8 +160,10 @@ struct drm_i915_display_funcs {
 	void (*disable_fbc)(struct drm_device *dev);
 	int (*get_display_clock_speed)(struct drm_device *dev);
 	int (*get_fifo_size)(struct drm_device *dev, int plane);
-	void (*update_wm)(struct drm_device *dev, int planea_clock,
-			  int planeb_clock, int sr_hdisplay, int pixel_size);
+	void (*update_wm)(struct drm_device *dev,
+				struct drm_display_mode *modea_clock,
+				struct drm_display_mode *modeb_clock,
+				int pixel_size);
 	/* clock updates for mode set */
 	/* cursor updates */
 	/* render clock increase/decrease */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a04ccec..43ec351 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2396,8 +2396,10 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane)
 	return size;
 }
 
-static void pineview_update_wm(struct drm_device *dev,  int planea_clock,
-			  int planeb_clock, int sr_hdisplay, int pixel_size)
+static void pineview_update_wm(struct drm_device *dev,
+				struct drm_display_mode *crtc_modea,
+				struct drm_display_mode *crtc_modeb,
+				int pixel_size)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 reg;
@@ -2433,15 +2435,15 @@ static void pineview_update_wm(struct drm_device *dev,  int planea_clock,
 	 * function of intel_calculate_wm.
 	 * We don't touch the watermark for display C.
 	 */
-	if (planea_clock)
-		planea_wm = intel_calculate_wm(planea_clock, &planea_params,
-						pixel_size, latency_ns);
+	if (crtc_modea->clock)
+		planea_wm = intel_calculate_wm(crtc_modea->clock,
+				&planea_params, pixel_size, latency_ns);
 	else
 		planea_wm = 15;
 
-	if (planeb_clock)
-		planeb_wm = intel_calculate_wm(planeb_clock, &planeb_params,
-					pixel_size, latency_ns);
+	if (crtc_modeb->clock)
+		planeb_wm = intel_calculate_wm(crtc_modeb->clock,
+				&planeb_params, pixel_size, latency_ns);
 	else
 		planeb_wm = 15;
 
@@ -2465,9 +2467,12 @@ static void pineview_update_wm(struct drm_device *dev,  int planea_clock,
 	 * watermark for display/cursor.
 	 */
 
-	if (!planea_clock || !planeb_clock) {
-		sr_clock = planea_clock ? planea_clock : planeb_clock;
-
+	if (!crtc_modea->clock || !crtc_modeb->clock) {
+		if (crtc_modea->clock) {
+			sr_clock = crtc_modea->clock;
+		} else {
+			sr_clock = crtc_modeb->clock;
+		}
 		/* Display SR */
 		wm = intel_calculate_wm(sr_clock, &pineview_display_wm,
 				pixel_size, latency->display_sr);
@@ -2513,15 +2518,17 @@ static void pineview_update_wm(struct drm_device *dev,  int planea_clock,
 
 }
 
-static void g4x_update_wm(struct drm_device *dev,  int planea_clock,
-			  int planeb_clock, int sr_hdisplay, int pixel_size)
+static void g4x_update_wm(struct drm_device *dev,
+				struct drm_display_mode *crtc_modea,
+				struct drm_display_mode *crtc_modeb,
+				int pixel_size)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int total_size, cacheline_size;
 	int planea_wm, planeb_wm, cursora_wm, cursorb_wm, cursor_sr;
 	struct intel_watermark_params planea_params, planeb_params;
 	unsigned long line_time_us;
-	int sr_clock, sr_entries = 0, entries_required;
+	int sr_clock, sr_entries = 0, entries_required, sr_hdisplay;
 
 	/* Create copies of the base settings for each pipe */
 	planea_params = planeb_params = g4x_wm_info;
@@ -2536,15 +2543,21 @@ static void g4x_update_wm(struct drm_device *dev,  int planea_clock,
 	 * clocks go from a few thousand to several hundred thousand.
 	 * latency is usually a few thousand
 	 */
-	entries_required = ((planea_clock / 1000) * pixel_size * latency_ns) /
-		1000;
-	entries_required /= G4X_FIFO_LINE_SIZE;
-	planea_wm = entries_required + planea_params.guard_size;
-
-	entries_required = ((planeb_clock / 1000) * pixel_size * latency_ns) /
-		1000;
-	entries_required /= G4X_FIFO_LINE_SIZE;
-	planeb_wm = entries_required + planeb_params.guard_size;
+	if (crtc_modea->clock) {
+		entries_required = ((crtc_modea->clock / 1000) * pixel_size *
+				latency_ns) / 1000;
+		entries_required /= G4X_FIFO_LINE_SIZE;
+		planea_wm = entries_required + planea_params.guard_size;
+	} else
+		planea_wm = 16;
+
+	if (crtc_modeb->clock) {
+		entries_required = ((crtc_modeb->clock / 1000) * pixel_size *
+				latency_ns) / 1000;
+		entries_required /= G4X_FIFO_LINE_SIZE;
+		planeb_wm = entries_required + planeb_params.guard_size;
+	} else
+		planeb_wm = 16;
 
 	cursora_wm = cursorb_wm = 16;
 	cursor_sr = 32;
@@ -2552,11 +2565,16 @@ static void g4x_update_wm(struct drm_device *dev,  int planea_clock,
 	DRM_DEBUG("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
 
 	/* Calc sr entries for one plane configs */
-	if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
+	if (!crtc_modea->clock || !crtc_modeb->clock) {
 		/* self-refresh has much higher latency */
 		static const int sr_latency_ns = 12000;
-
-		sr_clock = planea_clock ? planea_clock : planeb_clock;
+		if (crtc_modea->clock) {
+			sr_clock = crtc_modea->clock;
+			sr_hdisplay = crtc_modea->hdisplay;
+		} else {
+			sr_clock = crtc_modeb->clock;
+			sr_hdisplay = crtc_modeb->hdisplay;
+		}
 		line_time_us = ((sr_hdisplay * 1000) / sr_clock);
 
 		/* Use ns/us then divide to preserve precision */
@@ -2583,19 +2601,28 @@ static void g4x_update_wm(struct drm_device *dev,  int planea_clock,
 		   (cursor_sr << DSPFW_CURSOR_SR_SHIFT));
 }
 
-static void i965_update_wm(struct drm_device *dev, int planea_clock,
-			   int planeb_clock, int sr_hdisplay, int pixel_size)
+static void i965_update_wm(struct drm_device *dev,
+				struct drm_display_mode *crtc_modea,
+				struct drm_display_mode *crtc_modeb,
+				int pixel_size)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	unsigned long line_time_us;
-	int sr_clock, sr_entries, srwm = 1;
+	int sr_clock, sr_entries, srwm = 1, sr_hdisplay;
 
 	/* Calc sr entries for one plane configs */
-	if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
+	if (!crtc_modea->clock || !crtc_modeb->clock) {
 		/* self-refresh has much higher latency */
 		static const int sr_latency_ns = 12000;
 
-		sr_clock = planea_clock ? planea_clock : planeb_clock;
+		if (crtc_modea->clock) {
+			sr_hdisplay = crtc_modea->hdisplay;
+			sr_clock = crtc_modea->clock;
+		} else {
+			sr_hdisplay = crtc_modeb->hdisplay;
+			sr_clock = crtc_modeb->clock;
+		}
+
 		line_time_us = ((sr_hdisplay * 1000) / sr_clock);
 
 		/* Use ns/us then divide to preserve precision */
@@ -2619,8 +2646,10 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock,
 	I915_WRITE(DSPFW2, (8 << 8) | (8 << 0));
 }
 
-static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
-			   int planeb_clock, int sr_hdisplay, int pixel_size)
+static void i9xx_update_wm(struct drm_device *dev,
+				struct drm_display_mode *crtc_modea,
+				struct drm_display_mode *crtc_modeb,
+				int pixel_size)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t fwater_lo;
@@ -2629,7 +2658,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
 	int planea_wm, planeb_wm;
 	struct intel_watermark_params planea_params, planeb_params;
 	unsigned long line_time_us;
-	int sr_clock, sr_entries = 0;
+	int sr_clock, sr_hdisplay, sr_entries = 0;
 
 	/* Create copies of the base settings for each pipe */
 	if (IS_I965GM(dev) || IS_I945GM(dev))
@@ -2647,10 +2676,17 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
 	planea_params.fifo_size = dev_priv->display.get_fifo_size(dev, 0);
 	planeb_params.fifo_size = dev_priv->display.get_fifo_size(dev, 1);
 
-	planea_wm = intel_calculate_wm(planea_clock, &planea_params,
-				       pixel_size, latency_ns);
-	planeb_wm = intel_calculate_wm(planeb_clock, &planeb_params,
-				       pixel_size, latency_ns);
+	if (crtc_modea->clock)
+		planea_wm = intel_calculate_wm(crtc_modea->clock,
+				&planea_params, pixel_size, latency_ns);
+	else
+		planea_wm = 8;
+
+	if (crtc_modeb->clock)
+		planeb_wm = intel_calculate_wm(crtc_modeb->clock,
+				&planeb_params, pixel_size, latency_ns);
+	else
+		planeb_wm = 8;
 	DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
 
 	/*
@@ -2659,12 +2695,19 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
 	cwm = 2;
 
 	/* Calc sr entries for one plane configs */
-	if (HAS_FW_BLC(dev) && sr_hdisplay &&
-	    (!planea_clock || !planeb_clock)) {
+	if (HAS_FW_BLC(dev) &&
+	    (!crtc_modea->clock || !crtc_modeb->clock)) {
 		/* self-refresh has much higher latency */
 		static const int sr_latency_ns = 6000;
 
-		sr_clock = planea_clock ? planea_clock : planeb_clock;
+		if (crtc_modea->clock) {
+			sr_clock = crtc_modea->clock;
+			sr_hdisplay = crtc_modea->hdisplay;
+		} else {
+			sr_clock = crtc_modeb->clock;
+			sr_hdisplay = crtc_modeb->hdisplay;
+		}
+
 		line_time_us = ((sr_hdisplay * 1000) / sr_clock);
 
 		/* Use ns/us then divide to preserve precision */
@@ -2692,12 +2735,17 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
 	I915_WRITE(FW_BLC2, fwater_hi);
 }
 
-static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused,
-			   int unused2, int pixel_size)
+static void i830_update_wm(struct drm_device *dev,
+				struct drm_display_mode *crtc_modea,
+				struct drm_display_mode *crtc_modeb,
+				int pixel_size)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff;
 	int planea_wm;
+	int planea_clock;
+
+	planea_clock = crtc_modea->clock;
 
 	i830_wm_info.fifo_size = dev_priv->display.get_fifo_size(dev, 0);
 
@@ -2746,13 +2794,14 @@ static void intel_update_watermarks(struct drm_device *dev)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc;
 	struct intel_crtc *intel_crtc;
-	int sr_hdisplay = 0;
-	unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0;
 	int enabled = 0, pixel_size = 0;
+	struct drm_display_mode crtc_modea, crtc_modeb;
 
 	if (!dev_priv->display.update_wm)
 		return;
 
+	memset(&crtc_modea, 0, sizeof(struct drm_display_mode));
+	memset(&crtc_modeb, 0, sizeof(struct drm_display_mode));
 	/* Get the clock config from both planes */
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		intel_crtc = to_intel_crtc(crtc);
@@ -2761,14 +2810,14 @@ static void intel_update_watermarks(struct drm_device *dev)
 			if (intel_crtc->plane == 0) {
 				DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n",
 					  intel_crtc->pipe, crtc->mode.clock);
-				planea_clock = crtc->mode.clock;
+				memcpy(&crtc_modea, &crtc->mode,
+					sizeof(struct drm_display_mode));
 			} else {
 				DRM_DEBUG_KMS("plane B (pipe %d) clock: %d\n",
 					  intel_crtc->pipe, crtc->mode.clock);
-				planeb_clock = crtc->mode.clock;
+				memcpy(&crtc_modeb, &crtc->mode,
+					sizeof(struct drm_display_mode));
 			}
-			sr_hdisplay = crtc->mode.hdisplay;
-			sr_clock = crtc->mode.clock;
 			if (crtc->fb)
 				pixel_size = crtc->fb->bits_per_pixel / 8;
 			else
@@ -2779,8 +2828,7 @@ static void intel_update_watermarks(struct drm_device *dev)
 	if (enabled <= 0)
 		return;
 
-	dev_priv->display.update_wm(dev, planea_clock, planeb_clock,
-				    sr_hdisplay, pixel_size);
+	dev_priv->display.update_wm(dev, &crtc_modea, &crtc_modeb, pixel_size);
 }
 
 static int intel_crtc_mode_set(struct drm_crtc *crtc,
-- 
1.5.4.5




More information about the Intel-gfx mailing list