drm/i915: Fix PIPESTAT irq ack on i965/g4x
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 11 Jun 2018 20:02:55 +0000 (23:02 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 8 Jul 2018 13:32:20 +0000 (15:32 +0200)
commitea6ac2b5cf18c50321208952f3ff91810174926d
tree66ef37b3ea2e256241d2f2200c659c668f816f36
parentd85341e000f14c18abec5d97a008432d4cd30426
drm/i915: Fix PIPESTAT irq ack on i965/g4x

commit 4dc055c9cc8b3dac966b54d3cd5cf463a988299b upstream.

On i965/g4x IIR is edge triggered. So in order for IIR to notice that
there is still a pending interrupt we have to force and edge in ISR.
For the ISR/IIR pipe event bits we can do that by temporarily
clearing all the PIPESTAT enable bits when we ack the status bits.
This will force the ISR pipe event bit low, and it can then go back
high when we restore the PIPESTAT enable bits.

This avoids the following race:
1. stat = read(PIPESTAT)
2. an enabled PIPESTAT status bit goes high
3. write(PIPESTAT, enable|stat);
4. write(IIR, PIPE_EVENT)

The end result is IIR==0 and ISR!=0. This can lead to nasty
vblank wait/flip_done timeouts if another interrupt source
doesn't trick us into looking at the PIPESTAT status bits despite
the IIR PIPE_EVENT bit being low.

Before i965 IIR was level triggered so this problem can't actually
happen there. And curiously VLV/CHV went back to the level triggered
scheme as well. But for simplicity we'll use the same i965/g4x
compatible code for all platforms.

Cc: stable@vger.kernel.org
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=106033
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105225
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=106030
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180611200258.27121-1-ville.syrjala@linux.intel.com
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
(cherry picked from commit 132c27c97cb958f637dc05adc35a61b47779bcd8)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/i915/i915_irq.c