[Intel-gfx] [PATCH 4/6] drm/i915: Redefine the fifo size on 965/g4x and the function of intel_calculate_wm

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


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

According to the spec we use the incorrect fifo size on 965/g4x platform to
calculate the self-refresh watermark for display plane/cursor. So redefine
the fifo size on 965/g4x platform to calculate the self-refresh watermark.

At the same time this patch also redefines the function of intel_calculate_wm
so that it can be used on g4x/965/9xx/pineviw platform. It contains the
following parts:
   1. Add a watermark flag to indicate whether the required fifo size
is directly used as the watermark. This is required on g4x platform.
   2. we add another new method to calculate the watermark, which uses the
following formula to calcuate the required size. 
    >(Trunc(required_latency / line_time) + 1) * pixel_size * surface_width
   The argument of calc_flags can decide which method is used to
calculate the watermark.

   3. Consider the difference between the total fifo size and the size of 8
whole lines when calculating the watermark for display plane. 

Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
Reviewd-by: Jesse Barnes <jbarnes at virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_reg.h      |    8 +
 drivers/gpu/drm/i915/intel_display.c |  341 +++++++++++++++++++++++-----------
 2 files changed, 242 insertions(+), 107 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 847006c..485f1d5 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1846,6 +1846,14 @@
 #define PINEVIEW_CURSOR_DFT_WM	0
 #define PINEVIEW_CURSOR_GUARD_WM	5
 
+#define I965GM_DISPLAY_FIFO	512 /* in 64byte unit */
+#define I965GM_FIFO_LINE_SIZE	64
+#define I965GM_MAX_WM		0x1ff
+#define I965GM_DFT_WM		0x3f
+
+#define I965GM_CURSOR_FIFO	64 /* in 64bytes unit */
+#define I965GM_CURSOR_MAX_WM	32
+#define I965GM_CURSOR_DFT_WM	8
 /*
  * The two pipe frame counter registers are not synchronized, so
  * reading a stable value is somewhat tricky. The following code
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0eaf48e..d107532 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2131,6 +2131,8 @@ ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock,
 	fdi_reduce_ratio(&m_n->link_m, &m_n->link_n);
 }
 
+#define WM_TYPE_PLANE	1
+#define WM_TYPE_CURSOR	2
 
 struct intel_watermark_params {
 	unsigned long fifo_size;
@@ -2138,6 +2140,13 @@ struct intel_watermark_params {
 	unsigned long default_wm;
 	unsigned long guard_size;
 	unsigned long cacheline_size;
+	/*
+	 * indicate whether the required entry is treated as the watermark.
+	 * If it is 1, it will use the required entries to set the watermark.
+	 * Otherwise we will subtract the required entry from the total size
+	 * to get the watermark.
+	 */
+	int watermark_flag;
 };
 
 /* Pineview has different values for various configs */
@@ -2175,7 +2184,43 @@ static struct intel_watermark_params g4x_wm_info = {
 	G4X_MAX_WM,
 	2,
 	G4X_FIFO_LINE_SIZE,
+	1
+};
+
+static struct intel_watermark_params g4x_self_wm_info = {
+	I965GM_DISPLAY_FIFO,
+	I965GM_MAX_WM,
+	I965GM_DFT_WM,
+	2,
+	G4X_FIFO_LINE_SIZE,
+	1,
+};
+
+static struct intel_watermark_params g4x_self_cursor_info = {
+	I965GM_CURSOR_FIFO,
+	I965GM_CURSOR_MAX_WM,
+	I965GM_CURSOR_DFT_WM,
+	2,
+	G4X_FIFO_LINE_SIZE,
+	1,
+};
+
+static struct intel_watermark_params gm965_self_wm_info = {
+	I965GM_DISPLAY_FIFO,
+	I965GM_MAX_WM,
+	I965GM_DFT_WM,
+	2,
+	I965GM_FIFO_LINE_SIZE,
 };
+
+static struct intel_watermark_params gm965_self_cursor_info = {
+	I965GM_CURSOR_FIFO,
+	I965GM_CURSOR_MAX_WM,
+	I965GM_CURSOR_DFT_WM,
+	2,
+	I965GM_FIFO_LINE_SIZE,
+};
+
 static struct intel_watermark_params i945_wm_info = {
 	I945_FIFO_SIZE,
 	I915_MAX_WM,
@@ -2207,10 +2252,12 @@ static struct intel_watermark_params i830_wm_info = {
 
 /**
  * intel_calculate_wm - calculate watermark level
- * @clock_in_khz: pixel clock
  * @wm: chip FIFO params
  * @pixel_size: display pixel size
+ * @wm_type: indicate whether it is for display plane or cursor
+ * @crtc_mode: the corresponding display mode
  * @latency_ns: memory latency for the platform
+ * @calc_flags: indicates which method is to calculate watermark.
  *
  * Calculate the watermark level (the level at which the display plane will
  * start fetching from memory again).  Each chip has a different display
@@ -2222,13 +2269,40 @@ static struct intel_watermark_params i830_wm_info = {
  * fetching FIFO line sized based chunks from memory until the FIFO fills
  * past the watermark point.  If the FIFO drains completely, a FIFO underrun
  * will occur, and a display engine hang could result.
+ *
+ * Calc_flags: This is to indicate which method is to calculate the watermark.
+ * 0 is the normal calculation(called as small buffer). 1 is the SR calculatiion
+ * (called as the large buffer).
+ *    The normal calculation is:
+ *     watermark = dotclock * bytes per pixel * latency
+ *   where latency is platform & configuration dependent (we assume pessimal
+ *   values here).
+ *
+ *   The SR calculation is:
+ *     watermark = (trunc(latency/line time)+1) * surface width *
+ *       bytes per pixel
+ *   where
+ *     line time = htotal / dotclock
+ *   and latency is assumed to be high, as above.
+ *
+ * At the same time the difference between FIFO size and 8 lines size is also
+ * considered when calculating the watermark for display plane.
+ *
  */
-static unsigned long intel_calculate_wm(unsigned long clock_in_khz,
-					struct intel_watermark_params *wm,
-					int pixel_size,
-					unsigned long latency_ns)
+static unsigned long intel_calculate_wm(struct intel_watermark_params *wm,
+					int pixel_size, int wm_type,
+					struct drm_display_mode *crtc_mode,
+					unsigned long latency_ns,
+					int calc_flags)
 {
-	long entries_required, wm_size;
+	long entries_required;
+	int sr_entries, wm_size, hdisplay;
+	unsigned long line_time_us;
+
+	if (wm_type == WM_TYPE_PLANE)
+		hdisplay = crtc_mode->hdisplay;
+	else
+		hdisplay = 64;
 
 	/*
 	 * Note: we need to make sure we don't overflow for various clock &
@@ -2236,13 +2310,53 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz,
 	 * clocks go from a few thousand to several hundred thousand.
 	 * latency is usually a few thousand
 	 */
-	entries_required = ((clock_in_khz / 1000) * pixel_size * latency_ns) /
-		1000;
-	entries_required /= wm->cacheline_size;
+	if (calc_flags) {
+		/* calculate the line time. The unit is us */
+		line_time_us = (crtc_mode->htotal * 1000) /
+					crtc_mode->clock;
 
-	DRM_DEBUG_KMS("FIFO entries required for mode: %d\n", entries_required);
+		/* Use ns/us then divide to preserve precision */
+		entries_required = (((latency_ns / line_time_us) + 1000) /
+				1000) * pixel_size * hdisplay;
 
-	wm_size = wm->fifo_size - (entries_required + wm->guard_size);
+	} else {
+		entries_required = ((crtc_mode->clock / 1000) * pixel_size *
+				latency_ns) / 1000;
+	}
+	/*
+	 * When we caluclate the watermark for display plane, we will check
+	 * whether the total fifo size can contain 8 lines. If yes, we will
+	 * adjust the watermark by using the difference between the fifo size
+	 * and 8 lines size.
+	 */
+	if (wm_type == WM_TYPE_PLANE) {
+		int diff;
+		diff = wm->fifo_size * wm->cacheline_size -
+					8 * hdisplay * pixel_size;
+		if (diff > 0)
+			entries_required += diff;
+	}
+	/* Round up to the next cacheline boudary */
+	sr_entries = DIV_ROUND_UP(entries_required, wm->cacheline_size);
+
+	if (wm_type == WM_TYPE_PLANE)
+		DRM_DEBUG_KMS("FIFO entries required for plane: %d\n",
+				sr_entries);
+	else
+		DRM_DEBUG_KMS("FIFO entries required for cursor: %d\n",
+				sr_entries);
+
+	/*
+	 * When the watermark flag is non-zero, the required entry size will
+	 * be treated as the watermark.
+	 * Otherwise we will subtract the required entry size from the total
+	 * size to get the watermark.
+	 */
+	if (wm->watermark_flag) {
+		wm_size = sr_entries + wm->guard_size;
+	} else {
+		wm_size = wm->fifo_size - (sr_entries + wm->guard_size);
+	}
 
 	DRM_DEBUG_KMS("FIFO watermark level: %d\n", wm_size);
 
@@ -2405,7 +2519,6 @@ static void pineview_update_wm(struct drm_device *dev,
 	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;
 
@@ -2436,14 +2549,16 @@ static void pineview_update_wm(struct drm_device *dev,
 	 * We don't touch the watermark for display C.
 	 */
 	if (crtc_modea->clock)
-		planea_wm = intel_calculate_wm(crtc_modea->clock,
-				&planea_params, pixel_size, latency_ns);
+		planea_wm = intel_calculate_wm(&planea_params, pixel_size,
+					WM_TYPE_PLANE, crtc_modea,
+					latency_ns, 0);
 	else
 		planea_wm = 15;
 
 	if (crtc_modeb->clock)
-		planeb_wm = intel_calculate_wm(crtc_modeb->clock,
-				&planeb_params, pixel_size, latency_ns);
+		planeb_wm = intel_calculate_wm(&planeb_params, pixel_size,
+					WM_TYPE_PLANE, crtc_modeb,
+					latency_ns, 0);
 	else
 		planeb_wm = 15;
 
@@ -2468,14 +2583,17 @@ static void pineview_update_wm(struct drm_device *dev,
 	 */
 
 	if (!crtc_modea->clock || !crtc_modeb->clock) {
-		if (crtc_modea->clock) {
-			sr_clock = crtc_modea->clock;
-		} else {
-			sr_clock = crtc_modeb->clock;
-		}
+		struct drm_display_mode *crtc_mode;
+
+		if (crtc_modea->clock)
+			crtc_mode = crtc_modea;
+		else
+			crtc_mode = crtc_modeb;
+
 		/* Display SR */
-		wm = intel_calculate_wm(sr_clock, &pineview_display_wm,
-				pixel_size, latency->display_sr);
+		wm = intel_calculate_wm(&pineview_display_wm, pixel_size,
+					WM_TYPE_PLANE, crtc_mode,
+					latency->display_sr, 0);
 		reg = I915_READ(DSPFW1);
 		reg &= 0x7fffff;
 		reg |= wm << 23;
@@ -2483,24 +2601,27 @@ static void pineview_update_wm(struct drm_device *dev,
 		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);
+		wm = intel_calculate_wm(&pineview_cursor_wm, pixel_size,
+					WM_TYPE_CURSOR, crtc_mode,
+					latency->cursor_sr, 1);
 		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);
+		wm = intel_calculate_wm(&pineview_display_hplloff_wm, pixel_size,
+					WM_TYPE_PLANE, crtc_mode,
+					latency->display_hpll_disable, 0);
 		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);
+		wm = intel_calculate_wm(&pineview_cursor_hplloff_wm,
+					pixel_size, WM_TYPE_CURSOR, crtc_mode,
+					latency->cursor_hpll_disable, 1);
 		reg = I915_READ(DSPFW3);
 		reg &= ~(0x3f << 16);
 		reg |= (wm & 0x3f) << 16;
@@ -2527,8 +2648,7 @@ static void g4x_update_wm(struct drm_device *dev,
 	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, sr_hdisplay;
+	int sr_entries = 0;
 
 	/* Create copies of the base settings for each pipe */
 	planea_params = planeb_params = g4x_wm_info;
@@ -2543,20 +2663,18 @@ static void g4x_update_wm(struct drm_device *dev,
 	 * clocks go from a few thousand to several hundred thousand.
 	 * latency is usually a few thousand
 	 */
-	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
+	if (crtc_modea->clock)
+		planea_wm = intel_calculate_wm(&planea_params, pixel_size,
+					WM_TYPE_PLANE, crtc_modea,
+					latency_ns, 0);
+	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
+	if (crtc_modeb->clock)
+		planeb_wm = intel_calculate_wm(&planeb_params, pixel_size,
+					WM_TYPE_PLANE, crtc_modeb,
+					latency_ns, 0);
+	else
 		planeb_wm = 16;
 
 	cursora_wm = cursorb_wm = 16;
@@ -2566,35 +2684,38 @@ static void g4x_update_wm(struct drm_device *dev,
 
 	/* Calc sr entries for one plane configs */
 	if (!crtc_modea->clock || !crtc_modeb->clock) {
+		struct drm_display_mode *crtc_mode;
 		/* self-refresh has much higher latency */
 		static const int sr_latency_ns = 12000;
-		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);
+		if (crtc_modea->clock)
+			crtc_mode = crtc_modea;
+		else
+			crtc_mode = crtc_modeb;
+
+		/* calculate the display plane self-refresh watermark */
+		sr_entries = intel_calculate_wm(&g4x_self_wm_info, pixel_size,
+					WM_TYPE_PLANE, crtc_mode,
+					sr_latency_ns, 1);
+		/* calculate the cursor self-refresh watermark */
+		cursor_sr = intel_calculate_wm(&g4x_self_cursor_info,
+					pixel_size, WM_TYPE_CURSOR, crtc_mode,
+				sr_latency_ns, 1);
+		DRM_DEBUG_KMS("Display plane self-refresh entries: %d\n",
+				sr_entries);
+		DRM_DEBUG_KMS("cursor self-refresh entries: %d\n",
+				cursor_sr);
 
-		/* Use ns/us then divide to preserve precision */
-		sr_entries = (((sr_latency_ns / line_time_us) + 1) *
-			      pixel_size * sr_hdisplay) / 1000;
-		sr_entries = roundup(sr_entries / cacheline_size, 1);
-		DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
 		I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
 	}
 
-	DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n",
+	DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, SR %d\n",
 		  planea_wm, planeb_wm, sr_entries);
 
-	planea_wm &= 0x3f;
-	planeb_wm &= 0x3f;
-
 	I915_WRITE(DSPFW1, (sr_entries << DSPFW_SR_SHIFT) |
 		   (cursorb_wm << DSPFW_CURSORB_SHIFT) |
 		   (planeb_wm << DSPFW_PLANEB_SHIFT) | planea_wm);
-	I915_WRITE(DSPFW2, (I915_READ(DSPFW2) & DSPFW_CURSORA_MASK) |
+	/* Only update cursor A watermark in FW2 */
+	I915_WRITE(DSPFW2, (I915_READ(DSPFW2) & ~DSPFW_CURSORA_MASK) |
 		   (cursora_wm << DSPFW_CURSORA_SHIFT));
 	/* HPLL off in SR has some issues on G4x... disable it */
 	I915_WRITE(DSPFW3, (I915_READ(DSPFW3) & ~DSPFW_HPLL_SR_EN) |
@@ -2607,33 +2728,28 @@ static void i965_update_wm(struct drm_device *dev,
 				int pixel_size)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	unsigned long line_time_us;
-	int sr_clock, sr_entries, srwm = 1, sr_hdisplay;
+	int srwm = 1, cursor_sr;
 
+	cursor_sr = 32;
 	/* Calc sr entries for one plane configs */
 	if (!crtc_modea->clock || !crtc_modeb->clock) {
+		struct drm_display_mode *crtc_mode;
 		/* self-refresh has much higher latency */
 		static const int sr_latency_ns = 12000;
 
-		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;
-		}
+		if (crtc_modea->clock)
+			crtc_mode = crtc_modea;
+		else
+			crtc_mode = crtc_modeb;
 
-		line_time_us = ((sr_hdisplay * 1000) / sr_clock);
+		srwm = intel_calculate_wm(&gm965_self_wm_info, pixel_size,
+					WM_TYPE_PLANE, crtc_mode,
+					sr_latency_ns, 1);
+		/* calculate the cursor self-refresh watermark */
+		cursor_sr = intel_calculate_wm(&gm965_self_cursor_info,
+					pixel_size, WM_TYPE_CURSOR, crtc_mode,
+					sr_latency_ns, 1);
 
-		/* Use ns/us then divide to preserve precision */
-		sr_entries = (((sr_latency_ns / line_time_us) + 1) *
-			      pixel_size * sr_hdisplay) / 1000;
-		sr_entries = roundup(sr_entries / I915_FIFO_LINE_SIZE, 1);
-		DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
-		srwm = I945_FIFO_SIZE - sr_entries;
-		if (srwm < 0)
-			srwm = 1;
-		srwm &= 0x3f;
 		I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
 	}
 
@@ -2644,6 +2760,8 @@ static void i965_update_wm(struct drm_device *dev,
 	I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | (8 << 16) | (8 << 8) |
 		   (8 << 0));
 	I915_WRITE(DSPFW2, (8 << 8) | (8 << 0));
+	/* update the cursor self-refresh watermark */
+	I915_WRITE(DSPFW3, (cursor_sr << 24));
 }
 
 static void i9xx_update_wm(struct drm_device *dev,
@@ -2654,11 +2772,11 @@ static void i9xx_update_wm(struct drm_device *dev,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t fwater_lo;
 	uint32_t fwater_hi;
-	int total_size, cacheline_size, cwm, srwm = 1;
+	int total_size, cacheline_size, cwm;
 	int planea_wm, planeb_wm;
 	struct intel_watermark_params planea_params, planeb_params;
-	unsigned long line_time_us;
-	int sr_clock, sr_hdisplay, sr_entries = 0;
+	struct intel_watermark_params plane_sr;
+	int sr_entries = 8;
 
 	/* Create copies of the base settings for each pipe */
 	if (IS_I965GM(dev) || IS_I945GM(dev))
@@ -2668,6 +2786,7 @@ static void i9xx_update_wm(struct drm_device *dev,
 	else
 		planea_params = planeb_params = i855_wm_info;
 
+	plane_sr = planea_params;
 	/* Grab a couple of global values before we overwrite them */
 	total_size = planea_params.fifo_size;
 	cacheline_size = planea_params.cacheline_size;
@@ -2676,10 +2795,23 @@ static void i9xx_update_wm(struct drm_device *dev,
 	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(crtc_modea->clock, &planea_params,
-				       pixel_size, latency_ns);
-	planeb_wm = intel_calculate_wm(crtc_modeb->clock, &planeb_params,
-				       pixel_size, latency_ns);
+	/* update max watermark for per display plane */
+	planea_params.max_wm = planea_params.fifo_size / 2;
+	planeb_params.max_wm = planeb_params.fifo_size / 2;
+
+	if (crtc_modea->clock)
+		planea_wm = intel_calculate_wm(&planea_params, pixel_size,
+					WM_TYPE_PLANE, crtc_modea,
+					latency_ns, 0);
+	else
+		planea_wm = 8;
+
+	if (crtc_modeb->clock)
+		planeb_wm = intel_calculate_wm(&planeb_params, pixel_size,
+					WM_TYPE_PLANE, crtc_modeb,
+					latency_ns, 0);
+	else
+		planeb_wm = 8;
 	DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
 
 	/*
@@ -2690,32 +2822,26 @@ static void i9xx_update_wm(struct drm_device *dev,
 	/* Calc sr entries for one plane configs */
 	if (HAS_FW_BLC(dev) &&
 	    (!crtc_modea->clock || !crtc_modeb->clock)) {
+		struct drm_display_mode *crtc_mode;
 		/* self-refresh has much higher latency */
 		static const int sr_latency_ns = 6000;
 
-		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;
-		}
+		if (crtc_modea->clock)
+			crtc_mode = crtc_modea;
+		else
+			crtc_mode = crtc_modeb;
 
-		line_time_us = ((sr_hdisplay * 1000) / sr_clock);
+		/* calcuate the display self-refresh watermark */
+		sr_entries = intel_calculate_wm(&plane_sr,
+				pixel_size, WM_TYPE_PLANE,
+				crtc_mode, sr_latency_ns, 1);
 
-		/* Use ns/us then divide to preserve precision */
-		sr_entries = (((sr_latency_ns / line_time_us) + 1) *
-			      pixel_size * sr_hdisplay) / 1000;
-		sr_entries = roundup(sr_entries / cacheline_size, 1);
 		DRM_DEBUG_KMS("self-refresh entries: %d\n", sr_entries);
-		srwm = total_size - sr_entries;
-		if (srwm < 0)
-			srwm = 1;
-		I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f));
+		I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (sr_entries));
 	}
 
-	DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
-		  planea_wm, planeb_wm, cwm, srwm);
+	DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d\n",
+		  planea_wm, planeb_wm, cwm);
 
 	fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f);
 	fwater_hi = (cwm & 0x1f);
@@ -2742,8 +2868,9 @@ static void i830_update_wm(struct drm_device *dev,
 
 	i830_wm_info.fifo_size = dev_priv->display.get_fifo_size(dev, 0);
 
-	planea_wm = intel_calculate_wm(planea_clock, &i830_wm_info,
-				       pixel_size, latency_ns);
+	planea_wm = intel_calculate_wm(&i830_wm_info, pixel_size,
+				WM_TYPE_PLANE, crtc_modea,
+				latency_ns, 0);
 	fwater_lo |= (3<<8) | planea_wm;
 
 	DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm);
-- 
1.5.4.5




More information about the Intel-gfx mailing list