Hi folks,

as by discussion, the problem with the i830 watermark problems is likely that the 830 requires the number of entries in the buffer to be a multiple of the cache line size. I provide hereby a small patch
against intel_pm.c that performs the alignment for GEN2 chips.

Tested on the Fujitsu S6010 and R31, seems to work fine here and generates reasonable watermarks that do not flicker.

What is a bit unsatisfactory is that, due to the nature of the patch, the number of entries in the buffer is always rounded up (necessarily, to be conservative), even though for all practical configurations, the rounded up size is too large to fit into the buffer, and thus the rounding direction is "round down" instead of "round up" for all realistic settings.

Anyhow, the stuff works.

Greetings,
        Thomas
>From ee1210a1f49abaddc2c6c46cfb521db6ab08c261 Mon Sep 17 00:00:00 2001
From: thor <t...@math.tu-berlin.de>
Date: Sun, 1 Jun 2014 18:33:20 +0200
Subject: [PATCH] Align i830 watermark to cache lines.

Signed-off-by: thor <t...@math.tu-berlin.de>
---
 drivers/gpu/drm/i915/intel_pm.c |   38 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1840d15..fbfd57c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1489,6 +1489,22 @@ static void i965_update_wm(struct drm_crtc *unused_crtc)
 	I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT));
 }
 
+static int round_to_lines(int watermark, int fifo_size, int line_size)
+{
+	int entries = fifo_size - watermark;
+
+	if (entries < 0)
+		entries = 0;
+
+	entries = DIV_ROUND_UP(entries, line_size);
+	while (entries > fifo_size)
+		entries -= line_size;
+
+	watermark = fifo_size - line_size;
+
+	return watermark;
+}
+
 static void i9xx_update_wm(struct drm_crtc *unused_crtc)
 {
 	struct drm_device *dev = unused_crtc->dev;
@@ -1520,6 +1536,12 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
 		planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
 					       wm_info, fifo_size, cpp,
 					       latency_ns);
+
+		if (IS_GEN2(dev))
+			planea_wm = round_to_lines(planea_wm,
+						   fifo_size,
+						   I830_FIFO_LINE_SIZE);
+
 		enabled = crtc;
 	} else
 		planea_wm = fifo_size - wm_info->guard_size;
@@ -1536,6 +1558,12 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
 		planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
 					       wm_info, fifo_size, cpp,
 					       latency_ns);
+
+		if (IS_GEN2(dev))
+			planeb_wm = round_to_lines(planeb_wm,
+						   fifo_size,
+						   I830_FIFO_LINE_SIZE);
+
 		if (enabled == NULL)
 			enabled = crtc;
 		else
@@ -1631,16 +1659,24 @@ static void i845_update_wm(struct drm_crtc *unused_crtc)
 	const struct drm_display_mode *adjusted_mode;
 	uint32_t fwater_lo;
 	int planea_wm;
+	int fifo_size;
 
 	crtc = single_enabled_crtc(dev);
 	if (crtc == NULL)
 		return;
 
 	adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
+	fifo_size = dev_priv->display.get_fifo_size(dev, 0);
 	planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
 				       &i845_wm_info,
-				       dev_priv->display.get_fifo_size(dev, 0),
+				       fifo_size,
 				       4, latency_ns);
+
+	planea_wm = round_to_lines(planea_wm,
+				   fifo_size,
+				   I830_FIFO_LINE_SIZE);
+
+
 	fwater_lo = I915_READ(FW_BLC) & ~0xfff;
 	fwater_lo |= (3<<8) | planea_wm;
 
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to