linux/drivers/gpu/drm
Mario Kleiner 1bf59f1dcb drm/vc4: Implement precise vblank timestamping.
Precise vblank timestamping is implemented via the
usual scanout position based method. On VC4 the
pixelvalves PV do not have a scanout position
register. Only the hardware video scaler HVS has a
similar register which describes which scanline for
the output is currently composited and stored in the
HVS fifo for later consumption by the PV.

This causes a problem in that the HVS runs at a much
faster clock (system clock / audio gate) than the PV
which runs at video mode dot clock, so the unless the
fifo between HVS and PV is full, the HVS will progress
faster in its observable read line position than video
scan rate, so the HVS position reading can't be directly
translated into a scanout position for timestamp correction.

Additionally when the PV is in vblank, it doesn't consume
from the fifo, so the fifo gets full very quickly and then
the HVS stops compositing until the PV enters active scanout
and starts consuming scanlines from the fifo again, making
new space for the HVS to composite.

Therefore a simple translation of HVS read position into
elapsed time since (or to) start of active scanout does
not work, but for the most interesting cases we can still
get useful and sufficiently accurate results:

1. The PV enters active scanout of a new frame with the
   fifo of the HVS completely full, and the HVS can refill
   any fifo line which gets consumed and thereby freed up by
   the PV during active scanout very quickly. Therefore the
   PV and HVS work effectively in lock-step during active
   scanout with the fifo never having more than 1 scanline
   freed up by the PV before it gets refilled. The PV's
   real scanout position is therefore trailing the HVS
   compositing position as scanoutpos = hvspos - fifosize
   and we can get the true scanoutpos as HVS readpos minus
   fifo size, so precise timestamping works while in active
   scanout, except for the last few scanlines of the frame,
   when the HVS reaches end of frame, stops compositing and
   the PV catches up and drains the fifo. This special case
   would only introduce minor errors though.

2. If we are in vblank, then we can only guess something
   reasonable. If called from vblank irq, we assume the irq is
   usually dispatched with minimum delay, so we can take a
   timestamp taken at entry into the vblank irq handler as a
   baseline and then add a full vblank duration until the
   guessed start of active scanout. As irq dispatch is usually
   pretty low latency this works with relatively low jitter and
   good results.

   If we aren't called from vblank then we could be anywhere
   within the vblank interval, so we return a neutral result,
   simply the current system timestamp, and hope for the best.

Measurement shows the generated timestamps to be rather precise,
and at least never off more than 1 vblank duration worst-case.

Limitations: Doesn't work well yet for interlaced video modes,
             therefore disabled in interlaced mode for now.

v2: Use the DISPBASE registers to determine the FIFO size (changes
    by anholt)

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-and-tested-by: Mario Kleiner <mario.kleiner.de@gmail.com> (v2)
2016-07-11 17:17:34 -07:00
..
amd Merge branch 'drm-next-4.7' of git://people.freedesktop.org/~agd5f/linux into drm-next 2016-05-27 16:03:48 +10:00
arc drm/arcpgu: use dedicated memory area for frame buffer 2016-04-29 14:22:32 +03:00
arm drm: Nuke ->vblank_disable_allowed 2016-05-21 07:03:31 +10:00
armada drm: Nuke ->vblank_disable_allowed 2016-05-21 07:03:31 +10:00
ast drm: Remove unused drm_device from drm_gem_object_lookup() 2016-05-17 08:47:30 +02:00
atmel-hlcdc drm: Drop crtc argument from __drm_atomic_helper_crtc_destroy_state 2016-05-17 08:56:41 +02:00
bochs drm: Remove unused drm_device from drm_gem_object_lookup() 2016-05-17 08:47:30 +02:00
bridge drm/bridge: Add Analogix anx78xx support 2016-05-12 11:32:14 +02:00
cirrus drm: Remove unused drm_device from drm_gem_object_lookup() 2016-05-17 08:47:30 +02:00
etnaviv Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux 2016-05-23 11:48:48 -07:00
exynos drm: Nuke ->vblank_disable_allowed 2016-05-21 07:03:31 +10:00
fsl-dcu drm: Nuke ->vblank_disable_allowed 2016-05-21 07:03:31 +10:00
gma500 drm: Nuke ->vblank_disable_allowed 2016-05-21 07:03:31 +10:00
hisilicon drm/hisilicon: Fix DRM_INFO printed issue 2016-05-11 19:05:36 +08:00
i2c
i810
i915 Merge tag 'drm-fixes-v4.7-rc1' of git://people.freedesktop.org/~airlied/linux 2016-05-27 14:08:56 -07:00
imx imx-drm probing fix 2016-05-25 12:36:20 +10:00
mediatek drm: mediatek: fixup drm_gem_object_lookup API change 2016-05-18 19:16:16 +02:00
mga
mgag200 drm: Remove unused drm_device from drm_gem_object_lookup() 2016-05-17 08:47:30 +02:00
msm Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux 2016-05-23 11:48:48 -07:00
nouveau Merge branch 'linux-4.7' of git://github.com/skeggsb/linux into drm-next 2016-05-21 06:12:13 +10:00
omapdrm drm: Drop plane argument from __drm_atomic_helper_plane_destroy_state 2016-05-17 08:56:55 +02:00
panel drm/panel: simple: Add support for TPK U.S.A. LLC Fusion 7" and 10.1" panels 2016-05-12 11:32:14 +02:00
qxl qxl: catch qxlfb_create_pinned_object failures 2016-05-17 09:11:23 +02:00
r128
radeon Merge branch 'drm-next-4.7' of git://people.freedesktop.org/~agd5f/linux into drm-next 2016-05-27 16:03:48 +10:00
rcar-du drm: Drop plane argument from __drm_atomic_helper_plane_destroy_state 2016-05-17 08:56:55 +02:00
rockchip drm: Nuke ->vblank_disable_allowed 2016-05-21 07:03:31 +10:00
savage
shmobile drm/shmobile: use drm_crtc_send_vblank_event() 2016-05-02 17:04:50 +02:00
sis
sti remove lots of IS_ERR_VALUE abuses 2016-05-27 15:26:11 -07:00
sun4i drm: sun4i: tv: Add NTSC output standard 2016-04-28 10:30:05 +02:00
tdfx
tegra Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux 2016-05-23 11:48:48 -07:00
tilcdc remove lots of IS_ERR_VALUE abuses 2016-05-27 15:26:11 -07:00
ttm Linux 4.6-rc7 2016-05-09 13:49:56 +10:00
udl drm: Remove unused drm_device from drm_gem_object_lookup() 2016-05-17 08:47:30 +02:00
vc4 drm/vc4: Implement precise vblank timestamping. 2016-07-11 17:17:34 -07:00
vgem drm: Remove unused drm_device from drm_gem_object_lookup() 2016-05-17 08:47:30 +02:00
via
virtio drm: Remove unused drm_device from drm_gem_object_lookup() 2016-05-17 08:47:30 +02:00
vmwgfx drm/vmwgfx: Report vmwgfx version to vmware.log 2016-05-20 17:40:07 +02:00
ati_pcigart.c
drm_agpsupport.c
drm_atomic_helper.c drm: Drop connector argument from __drm_atomic_helper_connector_destroy_state 2016-05-17 08:57:05 +02:00
drm_atomic.c drm: Avoid connector reference imbalance on error path 2016-05-18 10:42:01 +02:00
drm_auth.c
drm_bridge.c
drm_bufs.c drm: Hide master MAP cleanup in drm_bufs.c 2016-04-27 10:14:17 +02:00
drm_cache.c
drm_context.c
drm_crtc_helper.c drm: Make drm_encoder_helper_funcs optional 2016-05-10 08:54:09 +02:00
drm_crtc_internal.h
drm_crtc.c drm: Fix error handling in drm_connector_register 2016-05-18 12:24:51 +02:00
drm_debugfs.c
drm_dma.c
drm_dp_aux_dev.c drm/dp: Allow signals to interrupt drm_aux-dev reads/writes 2016-04-28 11:48:09 +02:00
drm_dp_dual_mode_helper.c drm: Add helper for DP++ adaptors 2016-05-23 11:10:46 +03:00
drm_dp_helper.c
drm_dp_mst_topology.c Linux 4.6-rc7 2016-05-09 13:49:56 +10:00
drm_drv.c drm: Protect dev->filelist with its own mutex 2016-04-27 10:16:17 +02:00
drm_edid_load.c
drm_edid.c drm/edid: add displayid detailed 1 timings to the modelist. (v1.1) 2016-05-23 11:35:31 +10:00
drm_encoder_slave.c
drm_fb_cma_helper.c drm/fb-cma-helper: Add function drm_fb_cma_create_with_funcs() 2016-05-17 09:08:32 +02:00
drm_fb_helper.c drm/fb_helper: Fix references to dev->mode_config.num_connector 2016-05-17 15:44:41 +02:00
drm_flip_work.c
drm_fops.c drm: Protect dev->filelist with its own mutex 2016-04-27 10:16:17 +02:00
drm_gem_cma_helper.c drm: Remove unused drm_device from drm_gem_object_lookup() 2016-05-17 08:47:30 +02:00
drm_gem.c drm: Remove unused drm_device from drm_gem_object_lookup() 2016-05-17 08:47:30 +02:00
drm_global.c
drm_hashtab.c
drm_info.c drm: Protect dev->filelist with its own mutex 2016-04-27 10:16:17 +02:00
drm_internal.h drm: Make drm_vm_open/close_locked private to drm_vm.c 2016-04-27 10:15:56 +02:00
drm_ioc32.c
drm_ioctl.c drm: Move drm_getmap into drm_bufs.c and give it a legacy prefix 2016-04-27 08:42:48 +02:00
drm_irq.c drm: Nuke ->vblank_disable_allowed 2016-05-21 07:03:31 +10:00
drm_kms_helper_common.c
drm_legacy.h drm: Move drm_getmap into drm_bufs.c and give it a legacy prefix 2016-04-27 08:42:48 +02:00
drm_lock.c
drm_memory.c
drm_mipi_dsi.c
drm_mm.c
drm_modes.c
drm_modeset_lock.c
drm_of.c
drm_panel.c drm/panel: Flesh out kerneldoc 2016-05-06 16:04:48 +02:00
drm_pci.c
drm_plane_helper.c
drm_platform.c
drm_prime.c drm: Remove unused drm_device from drm_gem_object_lookup() 2016-05-17 08:47:30 +02:00
drm_probe_helper.c
drm_rect.c
drm_scatter.c
drm_sysfs.c
drm_trace_points.c
drm_trace.h
drm_vm.c drm: Make drm_vm_open/close_locked private to drm_vm.c 2016-04-27 10:15:56 +02:00
drm_vma_manager.c
Kconfig drm/mediatek: Add DRM Driver for Mediatek SoC MT8173. 2016-05-06 17:47:35 +02:00
Makefile Merge tag 'drm-intel-next-fixes-2016-05-25' of git://anongit.freedesktop.org/drm-intel into drm-next 2016-05-27 16:08:38 +10:00