The calculation seem backwards as they compute the number of entries that would be drained during a memory fetch, and but return the opposite value.
This fixes a common flicker [or even completely scrambled display] on high resolution outputs (e.g. 1920x1080 with 915GM). However, as we do not adjust DSPARB, we are still limited by the FIFO setup by the BIOS which may continue to cause underruns with high resolutions on some machines. References: Bug 22996 - [945GM] external lcd does not work on high resolution https://bugs.freedesktop.org/show_bug.cgi?id=22996 Bug 25284 - [915GM] random flickering when using metacity-compositor https://bugs.freedesktop.org/show_bug.cgi?id=25284 Bug 25857 - [945]: Entire screen "jerks" randomly after removing external monitor https://bugs.freedesktop.org/show_bug.cgi?id=25857 Bug 27738 - [915] 1920x1200 resolution fails, probable FIFO issue. https://bugs.freedesktop.org/show_bug.cgi?id=27738 Bug 28149 - [945GM] KMS regression. https://bugs.freedesktop.org/show_bug.cgi?id=28149 Also it may address some instances where the monitor fails to sync due to underruns. Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> --- drivers/gpu/drm/i915/intel_display.c | 26 +++++++++----------------- 1 files changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c0ab92f..e574e6a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2762,7 +2762,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, int pixel_size, unsigned long latency_ns) { - long entries_required, wm_size; + long entries; /* * Note: we need to make sure we don't overflow for various clock & @@ -2770,28 +2770,20 @@ 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 = DIV_ROUND_UP(entries_required, wm->cacheline_size); - - DRM_DEBUG_KMS("FIFO entries required for mode: %d\n", entries_required); - - wm_size = wm->fifo_size - (entries_required + wm->guard_size); + entries = ((clock_in_khz / 1000) * pixel_size * latency_ns) / 1000; + entries = DIV_ROUND_UP(entries, wm->cacheline_size); + entries += wm->guard_size; - DRM_DEBUG_KMS("FIFO watermark level: %d\n", wm_size); + DRM_DEBUG_KMS("FIFO entries required for mode: %d\n", entries); - /* Don't promote wm_size to unsigned... */ - if (wm_size > (long)wm->max_wm) - wm_size = wm->max_wm; - if (wm_size <= 0) { - wm_size = wm->default_wm; + if (entries >= (long)wm->fifo_size) { DRM_ERROR("Insufficient FIFO for plane, expect flickering:" " entries required = %ld, available = %lu.\n", - entries_required + wm->guard_size, - wm->fifo_size); + entries, wm->fifo_size); + entries = wm->fifo_size - 1; } - return wm_size; + return entries; } struct cxsr_latency { -- 1.7.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx