diff options
| author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2014-08-06 07:49:49 -0400 |
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-08-06 16:39:25 -0400 |
| commit | f8ad028cc033f75fc479ca1c30e2ea4ba56e5269 (patch) | |
| tree | 57a183cb4277f706bccdcd0e48d22a72537913fa | |
| parent | 812e7465a7decf3cca0b5f71977a25eecd9626a4 (diff) | |
drm: Avoid random vblank counter jumps if the hardware counter has been reset
When drm_vblank_on() is called the hardware vblank counter may have
been reset, so we can't trust that the old values sampled prior to
drm_vblank_off() have anything to do with the new values.
So update the .last count in drm_vblank_on() to make the first
drm_vblank_enable() consider that as the reference point. This
will correct the user space visible counter to account for the
time between drm_vblank_on() and the first drm_vblank_enable()
calls.
For extra safety subtract one from the .last count in drm_vblank_on()
to make sure that user space will never see the same counter value
before and after modeset.
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
| -rw-r--r-- | drivers/gpu/drm/drm_irq.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 1f86f6c6ecc6..fc1525a499d9 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -1095,6 +1095,18 @@ void drm_vblank_on(struct drm_device *dev, int crtc) | |||
| 1095 | atomic_dec(&dev->vblank[crtc].refcount); | 1095 | atomic_dec(&dev->vblank[crtc].refcount); |
| 1096 | dev->vblank[crtc].inmodeset = 0; | 1096 | dev->vblank[crtc].inmodeset = 0; |
| 1097 | } | 1097 | } |
| 1098 | |||
| 1099 | /* | ||
| 1100 | * sample the current counter to avoid random jumps | ||
| 1101 | * when drm_vblank_enable() applies the diff | ||
| 1102 | * | ||
| 1103 | * -1 to make sure user will never see the same | ||
| 1104 | * vblank counter value before and after a modeset | ||
| 1105 | */ | ||
| 1106 | dev->vblank[crtc].last = | ||
| 1107 | (dev->driver->get_vblank_counter(dev, crtc) - 1) & | ||
| 1108 | dev->max_vblank_count; | ||
| 1109 | |||
| 1098 | /* re-enable interrupts if there's are users left */ | 1110 | /* re-enable interrupts if there's are users left */ |
| 1099 | if (atomic_read(&dev->vblank[crtc].refcount) != 0) | 1111 | if (atomic_read(&dev->vblank[crtc].refcount) != 0) |
| 1100 | WARN_ON(drm_vblank_enable(dev, crtc)); | 1112 | WARN_ON(drm_vblank_enable(dev, crtc)); |
