linux-stable-rt/drivers
Mario Kleiner 27641c3f00 drm/vblank: Add support for precise vblank timestamping.
The DRI2 swap & sync implementation needs precise
vblank counts and precise timestamps corresponding
to those vblank counts. For conformance to the OpenML
OML_sync_control extension specification the DRM
timestamp associated with a vblank count should
correspond to the start of video scanout of the first
scanline of the video frame following the vblank
interval for that vblank count.

Therefore we need to carry around precise timestamps
for vblanks. Currently the DRM and KMS drivers generate
timestamps ad-hoc via do_gettimeofday() in some
places. The resulting timestamps are sometimes not
very precise due to interrupt handling delays, they
don't conform to OML_sync_control and some are wrong,
as they aren't taken synchronized to the vblank.

This patch implements support inside the drm core
for precise and robust timestamping. It consists
of the following interrelated pieces.

1. Vblank timestamp caching:

A per-crtc ringbuffer stores the most recent vblank
timestamps corresponding to vblank counts.

The ringbuffer can be read out lock-free via the
accessor function:

struct timeval timestamp;
vblankcount = drm_vblank_count_and_time(dev, crtcid, &timestamp).

The function returns the current vblank count and
the corresponding timestamp for start of video
scanout following the vblank interval. It can be
used anywhere between enclosing drm_vblank_get(dev, crtcid)
and drm_vblank_put(dev,crtcid) statements. It is used
inside the drmWaitVblank ioctl and in the vblank event
queueing and handling. It should be used by kms drivers for
timestamping of bufferswap completion.

The timestamp ringbuffer is reinitialized each time
vblank irq's get reenabled in drm_vblank_get()/
drm_update_vblank_count(). It is invalidated when
vblank irq's get disabled.

The ringbuffer is updated inside drm_handle_vblank()
at each vblank irq.

2. Calculation of precise vblank timestamps:

drm_get_last_vbltimestamp() is used to compute the
timestamp for the end of the most recent vblank (if
inside active scanout), or the expected end of the
current vblank interval (if called inside a vblank
interval). The function calls into a new optional kms
driver entry point dev->driver->get_vblank_timestamp()
which is supposed to provide the precise timestamp.
If a kms driver doesn't implement the entry point or
if the call fails, a simple do_gettimeofday() timestamp
is returned as crude approximation of the true vblank time.

A new drm module parameter drm.timestamp_precision_usec
allows to disable high precision timestamps (if set to
zero) or to specify the maximum acceptable error in
the timestamps in microseconds.

Kms drivers could implement their get_vblank_timestamp()
function in a gpu specific way, as long as returned
timestamps conform to OML_sync_control, e.g., by use
of gpu specific hardware timestamps.

Optionally, kms drivers can simply wrap and use the new
utility function drm_calc_vbltimestamp_from_scanoutpos().
This function calls a new optional kms driver function
dev->driver->get_scanout_position() which returns the
current horizontal and vertical video scanout position
of the crtc. The scanout position together with the
drm_display_timing of the current video mode is used
to calculate elapsed time relative to start of active scanout
for the current video frame. This elapsed time is subtracted
from the current do_gettimeofday() time to get the timestamp
corresponding to start of video scanout. Currently
non-interlaced, non-doublescan video modes, with or
without panel scaling are handled correctly. Interlaced/
doublescan modes are tbd in a future patch.

3. Filtering of redundant vblank irq's and removal of
some race-conditions in the vblank irq enable/disable path:

Some gpu's (e.g., Radeon R500/R600) send spurious vblank
irq's outside the vblank if vblank irq's get reenabled.
These get detected by use of the vblank timestamps and
filtered out to avoid miscounting of vblanks.

Some race-conditions between the vblank irq enable/disable
functions, the vblank irq handler and the gpu itself (updating
its hardware vblank counter in the "wrong" moment) are
fixed inside vblank_disable_and_save() and
drm_update_vblank_count() by use of the vblank timestamps and
a new spinlock dev->vblank_time_lock.

The time until vblank irq disable is now configurable via
a new drm module parameter drm.vblankoffdelay to allow
experimentation with timeouts that are much shorter than
the current 5 seconds and should allow longer vblank off
periods for better power savings.

Followup patches will use these new functions to
implement precise timestamping for the intel and radeon
kms drivers.

Signed-off-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2010-11-22 11:45:05 +10:00
..
accessibility
acpi ACPI: debugfs custom_method open to non-root 2010-11-13 09:52:16 -08:00
amba
ata sata_via: apply magic FIFO fix to vt6420 too 2010-11-19 13:16:26 -05:00
atm
auxdisplay
base PM: Allow devices to be removed during late suspend and early resume 2010-11-11 01:50:53 +01:00
block BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
bluetooth
cdrom
char BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
clocksource
connector
cpufreq
cpuidle
crypto Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 2010-11-13 09:55:56 -08:00
dca
dio
dma
edac
eisa
firewire SCSI host lock push-down 2010-11-16 13:33:23 -08:00
firmware
gpio
gpu drm/vblank: Add support for precise vblank timestamping. 2010-11-22 11:45:05 +10:00
hid BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
hwmon hwmon: (w83795) Check for BEEP pin availability 2010-11-15 21:38:57 +01:00
i2c i2c: Sanity checks on adapter registration 2010-11-15 22:40:38 +01:00
ide
idle
ieee802154
infiniband BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
input Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input 2010-11-19 10:31:04 -08:00
isdn
leds drivers/leds/leds-gpio.c: properly initialize return value 2010-11-12 07:55:32 -08:00
lguest
macintosh drivers/macintosh/adb-iop.c: flags should be unsigned long 2010-11-12 07:55:30 -08:00
mca
md block: read i_size with i_size_read() 2010-11-10 14:40:53 +01:00
media BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
memstick
message SCSI host lock push-down 2010-11-16 13:33:23 -08:00
mfd
misc i2c: Remove obsolete cleanup for clientdata 2010-11-15 22:40:38 +01:00
mmc
mtd
net Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6 2010-11-19 15:25:59 -08:00
nubus
of
oprofile
parisc BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
parport
pci BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
pcmcia drivers/pcmcia/soc_common.c: Use printf extension %pV 2010-11-10 14:31:28 +01:00
platform
pnp BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
power
pps
ps3
rapidio rapidio: use resource_size() 2010-11-12 07:55:30 -08:00
regulator
rtc Merge branches 'sh/rtc' and 'common/clkfwk' into sh/urgent 2010-11-10 18:15:44 +09:00
s390 BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
sbus
scsi BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
serial BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
sfi
sh sh: intc: Fix up build failure introduced by radix tree changes. 2010-11-15 14:30:30 +09:00
sn
spi
ssb
staging Fix build failure at cx25821-video driver 2010-11-18 11:42:05 -08:00
tc
telephony
thermal
tty Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input 2010-11-19 10:31:04 -08:00
uio
usb BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
uwb UWB: Return UWB_RSV_ALLOC_NOT_FOUND rather than crashing on NULL dereference if kzalloc fails 2010-11-11 07:14:07 -08:00
vhost
video BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
virtio
vlynq
w1
watchdog
xen BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
zorro BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
Kconfig
Makefile