Dear Daniel, and intel experts,
please find a revised patch concerning the i830 panning flicker attached.
The code should be much cleaner now, though it currently only addresses
the linear (and not the tiled) mode.
Thanks,
Thomas
>From fbb59580f1d85efeb9e2d155ce46791cb8b23c2d Mon Sep 17 00:00:00 2001
From: Thomas Richter <thor@xxxxxxxxxxxxxxxxx>
Date: Fri, 15 Nov 2013 11:53:55 +0100
Subject: [PATCH 11/11] Updated i830 patch to avoid pipe-A underruns.
This patch addresses a hardware issue on i830 chipsets that cause pipe A
underruns on screens where the base address is misaligned. This typically
happens when panning. The hardware issue causes at least an anoying
flicker at certain screen positions, but in worst case crashes and system
hangs when video overlays are active.
While details are still unknown, this workaround reloads the display base
address to an aligned position, causing the FIFO to fill, then adjusts the
base address to its final position.
The patch currently only works in linear framebuffer mode, tiled modes
are harder to address.
v1: First attempt to address the issue by an inline code.
v2: pulled out the inline code to a separate function
v3: cosmetical cleanups, removal of debug code.
Signed-off-by: Thomas Richter <thor@xxxxxxxxxxxxxxxxx>
---
drivers/gpu/drm/i915/intel_display.c | 59 +++++++++++++++++++++++++++++++++-
1 file changed, 58 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 971f6b9..566fe4d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2002,6 +2002,60 @@ unsigned long intel_gen4_compute_page_offset(int *x, int *y,
}
}
+/*
+ * Update the linear frame pointer for i830 based devices. Due to some
+ * unknown hardware feature, updating the frame pointer may cause
+ * the unified FIFO of these chips run dry, then causing a flicker
+ * and a potential shutdown of the video overlay, or worse.
+ * thor, 14.11.2013
+ */
+static void i830_update_plane_offset(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ unsigned long linear_offset)
+{
+ struct drm_i915_gem_object *obj;
+ struct intel_framebuffer *intel_fb;
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ unsigned long planeadr, oldadr;
+ int plane = intel_crtc->plane;
+ u32 reg = DSPCNTR(plane);
+
+ intel_fb = to_intel_framebuffer(fb);
+ obj = intel_fb->obj;
+
+ planeadr = i915_gem_obj_ggtt_offset(obj) + linear_offset;
+ /* I830 panning flicker work around.
+ * Only for non-LVDS output, only for i830.
+ * Tiling mode is still not supported.
+ */
+ if (obj->tiling_mode != I915_TILING_NONE) {
+ /*
+ * a suitable workaround for tiling is not
+ * yet available... TBD.
+ */
+ } else {
+ switch (fb->bits_per_pixel) {
+ case 32:
+ case 16:
+ oldadr = I915_READ(DSPADDR(plane));
+ if (((oldadr ^ planeadr) & 0x40) &&
+ (planeadr & 0xc0) == 0xc0) {
+ I915_WRITE(DSPADDR(plane),
+ planeadr & (~(0x80)));
+ POSTING_READ(reg);
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
+ }
+ break;
+ case 8:
+ /* workaround still to be done */
+ break;
+ }
+ }
+ I915_WRITE(DSPADDR(plane), planeadr);
+}
+
static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
int x, int y)
{
@@ -2094,7 +2148,10 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
I915_MODIFY_DISPBASE(DSPSURF(plane),
i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
- I915_WRITE(DSPLINOFF(plane), linear_offset);
+ I915_WRITE(DSPLINOFF(plane), linear_offset);
+ } else if (IS_I830(dev) &&
+ !intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+ i830_update_plane_offset(crtc, fb, linear_offset);
} else
I915_WRITE(DSPADDR(plane), i915_gem_obj_ggtt_offset(obj) + linear_offset);
POSTING_READ(reg);
--
1.7.10.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/intel-gfx