[Intel-gfx] [PATCH 2/6] drm/i915: Add update_wm callback for pineview to update watermark

yakui.zhao at intel.com yakui.zhao at intel.com
Wed Jan 13 15:10:51 CET 2010


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

Now we don't define the update_wm callback function explicitly for
pineview platform. But as it also belongs to mobile platform, we will
use the function of i9xx_update_wm function to update its watermark again
after we configure the watermark. This is incorrect.

So we will add a update_wm callback function for pineview to update watermark.
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. At the same time
we will also calculate the watermark for display plane/cursor when it doesn't
enter the self-refresh.

Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
cc: Li Shaohua <shaohua.li at intel.com>
---
According to the spec the memory will enter the self-refresh state only when
display plane is used and the CPU enters the deep C-state(C3). So this patch
won't disable the self-refresh bit explicitly in this update_wm callback.

The second is that I also update the watermark for display plane/cursor when
it doesn't enter the self-refresh. And I use the fifo size defined for 945gm
to calculate the corresponding watermark. Before this patch, the display
plane/cursor will use the default value when the memory doesn't enter the
self-refresh.

 drivers/gpu/drm/i915/intel_display.c |  199 +++++++++++++++++++++-------------
 1 files changed, 121 insertions(+), 78 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 42e8c03..a04ccec 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2311,77 +2311,6 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb,
 	return NULL;
 }
 
-static void pineview_disable_cxsr(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 reg;
-
-	/* deactivate cxsr */
-	reg = I915_READ(DSPFW3);
-	reg &= ~(PINEVIEW_SELF_REFRESH_EN);
-	I915_WRITE(DSPFW3, reg);
-	DRM_INFO("Big FIFO is disabled\n");
-}
-
-static void pineview_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_PINEVIEW_G(dev), dev_priv->fsb_freq,
-		dev_priv->mem_freq);
-	if (!latency) {
-		DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
-		pineview_disable_cxsr(dev);
-		return;
-	}
-
-	/* Display SR */
-	wm = intel_calculate_wm(clock, &pineview_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, &pineview_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, &pineview_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, &pineview_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 |= PINEVIEW_SELF_REFRESH_EN;
-	I915_WRITE(DSPFW3, reg);
-
-	DRM_INFO("Big FIFO is enabled\n");
-
-	return;
-}
 
 /*
  * Latency for FIFO fetches is dependent on several factors:
@@ -2467,6 +2396,123 @@ 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)
+{
+	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_PINEVIEW(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 &= ~(PINEVIEW_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.
+	 */
+	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, &pineview_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, &pineview_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, &pineview_display_hplloff_wm,
+			pixel_size, latency->display_hpll_disable);
+		reg = I915_READ(DSPFW3);
+		reg &= 0xfffffe00;
+		reg |= wm & 0x1ff;
+		I915_WRITE(DSPFW3, reg);
+
+		/* cursor HPLL off SR */
+		wm = intel_calculate_wm(sr_clock, &pineview_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 |= PINEVIEW_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)
 {
@@ -2733,12 +2779,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_PINEVIEW(dev))
-		pineview_enable_cxsr(dev, sr_clock, pixel_size);
-	else if (IS_PINEVIEW(dev))
-		pineview_disable_cxsr(dev);
-
 	dev_priv->display.update_wm(dev, planea_clock, planeb_clock,
 				    sr_hdisplay, pixel_size);
 }
@@ -4546,7 +4586,10 @@ static void intel_init_display(struct drm_device *dev)
 			i830_get_display_clock_speed;
 
 	/* For FIFO watermark updates */
-	if (IS_IRONLAKE(dev))
+	if (IS_PINEVIEW(dev)) {
+		dev_priv->display.update_wm = pineview_update_wm;
+		dev_priv->display.get_fifo_size = i9xx_get_fifo_size;
+	} else if (IS_IRONLAKE(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