vblank: Clean up compensation for spurious wraparounds of driver counter.
Only compensate when the driver counter actually appears to have moved backwards. The compensation deltas need to be incremental instead of absolute; drop the vblank_offset field and just use atomic_sub().main
parent
d1dcb2b32e
commit
237172b767
|
@ -840,13 +840,12 @@ struct drm_device {
|
|||
atomic_t *vblank_refcount; /* number of users of vblank interrupts per crtc */
|
||||
u32 *last_vblank; /* protected by dev->vbl_lock, used */
|
||||
/* for wraparound handling */
|
||||
u32 *vblank_offset; /* used to track how many vblanks */
|
||||
int *vblank_enabled; /* so we don't call enable more than
|
||||
once per disable */
|
||||
u32 *vblank_premodeset; /* were lost during modeset */
|
||||
u32 *vblank_premodeset; /* for compensation of spurious wraparounds */
|
||||
struct timer_list vblank_disable_timer;
|
||||
|
||||
unsigned long max_vblank_count; /**< size of vblank counter register */
|
||||
u32 max_vblank_count; /**< size of vblank counter register */
|
||||
spinlock_t tasklet_lock; /**< For drm_locked_tasklet */
|
||||
void (*locked_tasklet_func)(struct drm_device *dev);
|
||||
|
||||
|
|
|
@ -112,8 +112,6 @@ static void drm_vblank_cleanup(struct drm_device *dev)
|
|||
DRM_MEM_DRIVER);
|
||||
drm_free(dev->vblank_premodeset, sizeof(*dev->vblank_premodeset) *
|
||||
dev->num_crtcs, DRM_MEM_DRIVER);
|
||||
drm_free(dev->vblank_offset, sizeof(*dev->vblank_offset) * dev->num_crtcs,
|
||||
DRM_MEM_DRIVER);
|
||||
|
||||
dev->num_crtcs = 0;
|
||||
}
|
||||
|
@ -162,10 +160,6 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
|
|||
if (!dev->vblank_premodeset)
|
||||
goto err;
|
||||
|
||||
dev->vblank_offset = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER);
|
||||
if (!dev->vblank_offset)
|
||||
goto err;
|
||||
|
||||
/* Zero per-crtc vblank stuff */
|
||||
for (i = 0; i < num_crtcs; i++) {
|
||||
init_waitqueue_head(&dev->vbl_queue[i]);
|
||||
|
@ -330,8 +324,7 @@ int drm_control(struct drm_device *dev, void *data,
|
|||
*/
|
||||
u32 drm_vblank_count(struct drm_device *dev, int crtc)
|
||||
{
|
||||
return atomic_read(&dev->_vblank_count[crtc]) +
|
||||
dev->vblank_offset[crtc];
|
||||
return atomic_read(&dev->_vblank_count[crtc]);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_vblank_count);
|
||||
|
||||
|
@ -457,7 +450,18 @@ int drm_modeset_ctl(struct drm_device *dev, void *data,
|
|||
break;
|
||||
case _DRM_POST_MODESET:
|
||||
new = dev->driver->get_vblank_counter(dev, crtc);
|
||||
dev->vblank_offset[crtc] = dev->vblank_premodeset[crtc] - new;
|
||||
|
||||
/* Compensate for spurious wraparound */
|
||||
if (new < dev->vblank_premodeset[crtc]) {
|
||||
atomic_sub(dev->max_vblank_count + new -
|
||||
dev->vblank_premodeset[crtc],
|
||||
&dev->_vblank_count[crtc]);
|
||||
DRM_DEBUG("vblank_premodeset[%d]=0x%x, new=0x%x "
|
||||
"=> _vblank_count[%d]-=0x%x\n", crtc,
|
||||
dev->vblank_premodeset[crtc], new,
|
||||
crtc, dev->max_vblank_count + new -
|
||||
dev->vblank_premodeset[crtc]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
|
|
Loading…
Reference in New Issue