drm: Move drm_update_vblank_count()
Move drm_update_vblank_count() to avoid forward a declaration. No functional change. Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
844b03f277
commit
13b030af54
|
@ -55,6 +55,70 @@
|
|||
*/
|
||||
#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
|
||||
|
||||
/**
|
||||
* drm_update_vblank_count - update the master vblank counter
|
||||
* @dev: DRM device
|
||||
* @crtc: counter to update
|
||||
*
|
||||
* Call back into the driver to update the appropriate vblank counter
|
||||
* (specified by @crtc). Deal with wraparound, if it occurred, and
|
||||
* update the last read value so we can deal with wraparound on the next
|
||||
* call if necessary.
|
||||
*
|
||||
* Only necessary when going from off->on, to account for frames we
|
||||
* didn't get an interrupt for.
|
||||
*
|
||||
* Note: caller must hold dev->vbl_lock since this reads & writes
|
||||
* device vblank fields.
|
||||
*/
|
||||
static void drm_update_vblank_count(struct drm_device *dev, int crtc)
|
||||
{
|
||||
u32 cur_vblank, diff, tslot, rc;
|
||||
struct timeval t_vblank;
|
||||
|
||||
/*
|
||||
* Interrupts were disabled prior to this call, so deal with counter
|
||||
* wrap if needed.
|
||||
* NOTE! It's possible we lost a full dev->max_vblank_count events
|
||||
* here if the register is small or we had vblank interrupts off for
|
||||
* a long time.
|
||||
*
|
||||
* We repeat the hardware vblank counter & timestamp query until
|
||||
* we get consistent results. This to prevent races between gpu
|
||||
* updating its hardware counter while we are retrieving the
|
||||
* corresponding vblank timestamp.
|
||||
*/
|
||||
do {
|
||||
cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
|
||||
rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0);
|
||||
} while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc));
|
||||
|
||||
/* Deal with counter wrap */
|
||||
diff = cur_vblank - dev->vblank[crtc].last;
|
||||
if (cur_vblank < dev->vblank[crtc].last) {
|
||||
diff += dev->max_vblank_count;
|
||||
|
||||
DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
|
||||
crtc, dev->vblank[crtc].last, cur_vblank, diff);
|
||||
}
|
||||
|
||||
DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
|
||||
crtc, diff);
|
||||
|
||||
/* Reinitialize corresponding vblank timestamp if high-precision query
|
||||
* available. Skip this step if query unsupported or failed. Will
|
||||
* reinitialize delayed at next vblank interrupt in that case.
|
||||
*/
|
||||
if (rc) {
|
||||
tslot = atomic_read(&dev->vblank[crtc].count) + diff;
|
||||
vblanktimestamp(dev, crtc, tslot) = t_vblank;
|
||||
}
|
||||
|
||||
smp_mb__before_atomic();
|
||||
atomic_add(diff, &dev->vblank[crtc].count);
|
||||
smp_mb__after_atomic();
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable vblank irq's on crtc, make sure that last vblank count
|
||||
* of hardware and corresponding consistent software vblank counter
|
||||
|
@ -798,70 +862,6 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc,
|
|||
}
|
||||
EXPORT_SYMBOL(drm_send_vblank_event);
|
||||
|
||||
/**
|
||||
* drm_update_vblank_count - update the master vblank counter
|
||||
* @dev: DRM device
|
||||
* @crtc: counter to update
|
||||
*
|
||||
* Call back into the driver to update the appropriate vblank counter
|
||||
* (specified by @crtc). Deal with wraparound, if it occurred, and
|
||||
* update the last read value so we can deal with wraparound on the next
|
||||
* call if necessary.
|
||||
*
|
||||
* Only necessary when going from off->on, to account for frames we
|
||||
* didn't get an interrupt for.
|
||||
*
|
||||
* Note: caller must hold dev->vbl_lock since this reads & writes
|
||||
* device vblank fields.
|
||||
*/
|
||||
static void drm_update_vblank_count(struct drm_device *dev, int crtc)
|
||||
{
|
||||
u32 cur_vblank, diff, tslot, rc;
|
||||
struct timeval t_vblank;
|
||||
|
||||
/*
|
||||
* Interrupts were disabled prior to this call, so deal with counter
|
||||
* wrap if needed.
|
||||
* NOTE! It's possible we lost a full dev->max_vblank_count events
|
||||
* here if the register is small or we had vblank interrupts off for
|
||||
* a long time.
|
||||
*
|
||||
* We repeat the hardware vblank counter & timestamp query until
|
||||
* we get consistent results. This to prevent races between gpu
|
||||
* updating its hardware counter while we are retrieving the
|
||||
* corresponding vblank timestamp.
|
||||
*/
|
||||
do {
|
||||
cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
|
||||
rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0);
|
||||
} while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc));
|
||||
|
||||
/* Deal with counter wrap */
|
||||
diff = cur_vblank - dev->vblank[crtc].last;
|
||||
if (cur_vblank < dev->vblank[crtc].last) {
|
||||
diff += dev->max_vblank_count;
|
||||
|
||||
DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
|
||||
crtc, dev->vblank[crtc].last, cur_vblank, diff);
|
||||
}
|
||||
|
||||
DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
|
||||
crtc, diff);
|
||||
|
||||
/* Reinitialize corresponding vblank timestamp if high-precision query
|
||||
* available. Skip this step if query unsupported or failed. Will
|
||||
* reinitialize delayed at next vblank interrupt in that case.
|
||||
*/
|
||||
if (rc) {
|
||||
tslot = atomic_read(&dev->vblank[crtc].count) + diff;
|
||||
vblanktimestamp(dev, crtc, tslot) = t_vblank;
|
||||
}
|
||||
|
||||
smp_mb__before_atomic();
|
||||
atomic_add(diff, &dev->vblank[crtc].count);
|
||||
smp_mb__after_atomic();
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_vblank_enable - enable the vblank interrupt on a CRTC
|
||||
* @dev: DRM device
|
||||
|
|
Loading…
Reference in New Issue