[Intel-gfx] [RFC PATCH 2/2] drm/i915: Use the igd_update_wm to update watermark on IGD

yakui.zhao at intel.com yakui.zhao at intel.com
Fri Dec 4 16:01:05 CET 2009


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

Use the igd_update_wm to update the watermark on IGD. In such case only one
function is used, in which it will calculate the self-refresh watermark when
only one single display plane is used. If more than one display plane is used,
we will calculate the watermark for display plane/cursor.

Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |  204 +++++++++++++++++++++-------------
 1 files changed, 125 insertions(+), 79 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index fa7531f..5577976 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2403,78 +2403,6 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb,
 	return NULL;
 }
 
-static void igd_disable_cxsr(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 reg;
-
-	/* deactivate cxsr */
-	reg = I915_READ(DSPFW3);
-	reg &= ~(IGD_SELF_REFRESH_EN);
-	I915_WRITE(DSPFW3, reg);
-	DRM_INFO("Big FIFO is disabled\n");
-}
-
-static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock,
-			    int pixel_size)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 reg;
-	unsigned long wm;
-	struct cxsr_latency *latency;
-
-	latency = intel_get_cxsr_latency(IS_IGDG(dev), dev_priv->fsb_freq,
-		dev_priv->mem_freq);
-	if (!latency) {
-		DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
-		igd_disable_cxsr(dev);
-		return;
-	}
-
-	/* Display SR */
-	wm = intel_calculate_wm(clock, &igd_display_wm, pixel_size,
-				latency->display_sr);
-	reg = I915_READ(DSPFW1);
-	reg &= 0x7fffff;
-	reg |= wm << 23;
-	I915_WRITE(DSPFW1, reg);
-	DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg);
-
-	/* cursor SR */
-	wm = intel_calculate_wm(clock, &igd_cursor_wm, pixel_size,
-				latency->cursor_sr);
-	reg = I915_READ(DSPFW3);
-	reg &= ~(0x3f << 24);
-	reg |= (wm & 0x3f) << 24;
-	I915_WRITE(DSPFW3, reg);
-
-	/* Display HPLL off SR */
-	wm = intel_calculate_wm(clock, &igd_display_hplloff_wm,
-		latency->display_hpll_disable, I915_FIFO_LINE_SIZE);
-	reg = I915_READ(DSPFW3);
-	reg &= 0xfffffe00;
-	reg |= wm & 0x1ff;
-	I915_WRITE(DSPFW3, reg);
-
-	/* cursor HPLL off SR */
-	wm = intel_calculate_wm(clock, &igd_cursor_hplloff_wm, pixel_size,
-				latency->cursor_hpll_disable);
-	reg = I915_READ(DSPFW3);
-	reg &= ~(0x3f << 16);
-	reg |= (wm & 0x3f) << 16;
-	I915_WRITE(DSPFW3, reg);
-	DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg);
-
-	/* activate cxsr */
-	reg = I915_READ(DSPFW3);
-	reg |= IGD_SELF_REFRESH_EN;
-	I915_WRITE(DSPFW3, reg);
-
-	DRM_INFO("Big FIFO is enabled\n");
-
-	return;
-}
-
 /*
  * Latency for FIFO fetches is dependent on several factors:
  *   - memory configuration (speed, channels)
@@ -2559,6 +2487,127 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane)
 	return size;
 }
 
+static void igd_update_wm(struct drm_device *dev,  int planea_clock,
+			  int planeb_clock, int sr_hdisplay, int pixel_size)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 reg;
+	unsigned long wm;
+	struct cxsr_latency *latency;
+	int sr_clock;
+	struct intel_watermark_params planea_params, planeb_params;
+	int planea_wm, planeb_wm, cursora_wm, cursorb_wm;
+
+	latency = intel_get_cxsr_latency(IS_IGDG(dev), dev_priv->fsb_freq,
+		dev_priv->mem_freq);
+	if (!latency) {
+		DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
+		/* deactivate cxsr */
+		reg = I915_READ(DSPFW3);
+		reg &= ~(IGD_SELF_REFRESH_EN);
+		I915_WRITE(DSPFW3, reg);
+		return;
+	}
+
+	planea_params = planeb_params = i945_wm_info;
+	/* Update the fifo size /max_wm for display plane A */
+	planea_params.fifo_size =
+			dev_priv->display.get_fifo_size(dev, 0);
+	planea_params.max_wm = planea_params.fifo_size / 2;
+	/* update the fifo size/max_wm for display plane B */
+	planeb_params.fifo_size =
+			dev_priv->display.get_fifo_size(dev, 1);
+	planeb_params.max_wm = planeb_params.fifo_size / 2;
+
+	/*
+	 * We calculate the watermark for every display plane by using the
+	 * function of intel_calculate_wm.
+	 * We don't touch the watermark for display C.
+	 * In theory we can also use the intel_calculate_wm to get the
+	 * cursor watermark.  But now we use the fixed value.
+	 * cursora_wm = 16
+	 * cursorb_wm = 16
+	 */
+	if (planea_clock)
+		planea_wm = intel_calculate_wm(planea_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);
+	else
+		planeb_wm = 15;
+
+	cursora_wm = 16;
+	cursorb_wm = 16;
+
+	reg = I915_READ(DSPFW1);
+	reg &= ~(0x7F | (0x7F << 8) | (0x3F << 16));
+	reg |= (planea_wm | (planeb_wm << 8) | (cursorb_wm << 16));
+		I915_WRITE(DSPFW1, reg);
+
+	reg = I915_READ(DSPFW2);
+	reg &= ~(0x3f << 8);
+	reg |= (cursora_wm << 8);
+	I915_WRITE(DSPFW2, reg);
+
+	/*
+	 * If both planea_clock and planeb_clock are effective, it means that
+	 * the two planes are used. In such case it is unnecessary to touch
+	 * the self-refresh watermark. Instead we should configure the correct
+	 * watermark for display/cursor.
+	 */
+
+	if (!planea_clock || !planeb_clock) {
+		sr_clock = planea_clock ? planea_clock : planeb_clock;
+
+		/* Display SR */
+		wm = intel_calculate_wm(sr_clock, &igd_display_wm, pixel_size,
+				latency->display_sr);
+		reg = I915_READ(DSPFW1);
+		reg &= 0x7fffff;
+		reg |= wm << 23;
+		I915_WRITE(DSPFW1, reg);
+		DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg);
+
+		/* cursor SR */
+		wm = intel_calculate_wm(sr_clock, &igd_cursor_wm, pixel_size,
+				latency->cursor_sr);
+		reg = I915_READ(DSPFW3);
+		reg &= ~(0x3f << 24);
+		reg |= (wm & 0x3f) << 24;
+		I915_WRITE(DSPFW3, reg);
+
+		/* Display HPLL off SR */
+		wm = intel_calculate_wm(sr_clock, &igd_display_hplloff_wm,
+			latency->display_hpll_disable, I915_FIFO_LINE_SIZE);
+		reg = I915_READ(DSPFW3);
+		reg &= 0xfffffe00;
+		reg |= wm & 0x1ff;
+		I915_WRITE(DSPFW3, reg);
+
+		/* cursor HPLL off SR */
+		wm = intel_calculate_wm(sr_clock, &igd_cursor_hplloff_wm,
+				pixel_size, latency->cursor_hpll_disable);
+		reg = I915_READ(DSPFW3);
+		reg &= ~(0x3f << 16);
+		reg |= (wm & 0x3f) << 16;
+		I915_WRITE(DSPFW3, reg);
+		DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg);
+
+		/* activate cxsr */
+		reg = I915_READ(DSPFW3);
+		reg |= IGD_SELF_REFRESH_EN;
+		I915_WRITE(DSPFW3, reg);
+
+		DRM_DEBUG_KMS("Big FIFO is enabled\n");
+	}
+	return;
+
+}
+
 static void g4x_update_wm(struct drm_device *dev,  int planea_clock,
 			  int planeb_clock, int sr_hdisplay, int pixel_size)
 {
@@ -2825,12 +2874,6 @@ static void intel_update_watermarks(struct drm_device *dev)
 	if (enabled <= 0)
 		return;
 
-	/* Single plane configs can enable self refresh */
-	if (enabled == 1 && IS_IGD(dev))
-		igd_enable_cxsr(dev, sr_clock, pixel_size);
-	else if (IS_IGD(dev))
-		igd_disable_cxsr(dev);
-
 	dev_priv->display.update_wm(dev, planea_clock, planeb_clock,
 				    sr_hdisplay, pixel_size);
 }
@@ -4692,7 +4735,10 @@ static void intel_init_display(struct drm_device *dev)
 			i830_get_display_clock_speed;
 
 	/* For FIFO watermark updates */
-	if (IS_IGDNG(dev))
+	if (IS_IGD(dev)) {
+		dev_priv->display.update_wm = igd_update_wm;
+		dev_priv->display.get_fifo_size = i9xx_get_fifo_size;
+	} else	if (IS_IGDNG(dev))
 		dev_priv->display.update_wm = NULL;
 	else if (IS_G4X(dev))
 		dev_priv->display.update_wm = g4x_update_wm;
-- 
1.5.4.5




More information about the Intel-gfx mailing list