diff mbox

[v2,2/9] drm/i915: Add update_wm callback for pineview to update watermark

Message ID 1263980478-18338-3-git-send-email-yakui.zhao@intel.com (mailing list archive)
State Deferred, archived
Headers show

Commit Message

Zhao, Yakui Jan. 20, 2010, 9:41 a.m. UTC
None
diff mbox

Patch

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;