Skip to content

Commit

Permalink
drm/nouveau/display: Enable vblank irqs after display engine is on ag…
Browse files Browse the repository at this point in the history
…ain.

In the display resume path, move the calls to drm_vblank_on()
after the point when the display engine is running again.

Since changes were made to drm_update_vblank_count() in Linux 4.4+
to emulate hw vblank counters via vblank timestamping, the function
drm_vblank_on() now needs working high precision vblank timestamping
and therefore working scanout position queries at time of call.
These don't work before the display engine gets restarted, causing
miscalculation of vblank counter increments and thereby large forward
jumps in vblank count at display resume. These jumps can cause client
hangs on resume, or desktop hangs in the case of composited desktops.

Fix this Linux 4.4 regression by reordering calls accordingly.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: <stable@vger.kernel.org> # 4.4+
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: ville.syrjala@linux.intel.com
Cc: daniel.vetter@ffwll.ch
Cc: dri-devel@lists.freedesktop.org
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Mario Kleiner authored and Dave Airlie committed Feb 17, 2016
1 parent e0b34e3 commit ff683df
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions drivers/gpu/drm/nouveau/nouveau_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,10 +635,6 @@ nouveau_display_resume(struct drm_device *dev, bool runtime)
nv_crtc->lut.depth = 0;
}

/* Make sure that drm and hw vblank irqs get resumed if needed. */
for (head = 0; head < dev->mode_config.num_crtc; head++)
drm_vblank_on(dev, head);

/* This should ensure we don't hit a locking problem when someone
* wakes us up via a connector. We should never go into suspend
* while the display is on anyways.
Expand All @@ -648,6 +644,10 @@ nouveau_display_resume(struct drm_device *dev, bool runtime)

drm_helper_resume_force_mode(dev);

/* Make sure that drm and hw vblank irqs get resumed if needed. */
for (head = 0; head < dev->mode_config.num_crtc; head++)
drm_vblank_on(dev, head);

list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);

Expand Down

0 comments on commit ff683df

Please sign in to comment.