aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorMario Kleiner <mario.kleiner.de@gmail.com>2013-10-30 00:13:06 -0400
committerDave Airlie <airlied@redhat.com>2013-11-05 20:53:41 -0500
commit8f6fce03ddaf10bfa40c7d6cd59b778d35d41800 (patch)
treecada34e1587b003af267a75877e30caf60292779 /include
parent862cc8b4bba9381c1824a0b7ed6404ec2cfb21b1 (diff)
drm: Push latency sensitive bits of vblank scanoutpos timestamping into kms drivers.
A change in locking of some kms drivers (currently intel-kms) make the old approach too inaccurate and also incompatible with the PREEMPT_RT realtime kernel patchset. The driver->get_scanout_position() method of intel-kms now needs to aquire a spinlock, which clashes badly with the former preempt_disable() calls in the drm, and it also introduces larger delays and timing uncertainty on a contended lock than acceptable. This patch changes the prototype of driver->get_scanout_position() to require/allow kms drivers to perform the ktime_get() system time queries which go along with actual scanout position readout in a way that provides maximum precision and to return those timestamps to the drm. kms drivers implementations of get_scanout_position() are asked to implement timestamping and scanoutpos readout in a way that is as precise as possible and compatible with preempt_disable() on a PREMPT_RT kernel. A driver should follow this pattern in get_scanout_position() for precision and compatibility: spin_lock...(...); preempt_disable_rt(); // On a PREEMPT_RT kernel, otherwise omit. if (stime) *stime = ktime_get(); ... Minimum amount of MMIO register reads to get scanout position ... ... no taking of locks allowed here! ... if (etime) *etime = ktime_get(); preempt_enable_rt(); // On PREEMPT_RT kernel, otherwise omit. spin_unlock...(...); v2: Fix formatting of new multi-line code comments. Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'include')
-rw-r--r--include/drm/drmP.h10
1 files changed, 8 insertions, 2 deletions
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index e6d0cd9f518e..748c72907829 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -836,12 +836,17 @@ struct drm_driver {
836 /** 836 /**
837 * Called by vblank timestamping code. 837 * Called by vblank timestamping code.
838 * 838 *
839 * Return the current display scanout position from a crtc. 839 * Return the current display scanout position from a crtc, and an
840 * optional accurate ktime_get timestamp of when position was measured.
840 * 841 *
841 * \param dev DRM device. 842 * \param dev DRM device.
842 * \param crtc Id of the crtc to query. 843 * \param crtc Id of the crtc to query.
843 * \param *vpos Target location for current vertical scanout position. 844 * \param *vpos Target location for current vertical scanout position.
844 * \param *hpos Target location for current horizontal scanout position. 845 * \param *hpos Target location for current horizontal scanout position.
846 * \param *stime Target location for timestamp taken immediately before
847 * scanout position query. Can be NULL to skip timestamp.
848 * \param *etime Target location for timestamp taken immediately after
849 * scanout position query. Can be NULL to skip timestamp.
845 * 850 *
846 * Returns vpos as a positive number while in active scanout area. 851 * Returns vpos as a positive number while in active scanout area.
847 * Returns vpos as a negative number inside vblank, counting the number 852 * Returns vpos as a negative number inside vblank, counting the number
@@ -858,7 +863,8 @@ struct drm_driver {
858 * 863 *
859 */ 864 */
860 int (*get_scanout_position) (struct drm_device *dev, int crtc, 865 int (*get_scanout_position) (struct drm_device *dev, int crtc,
861 int *vpos, int *hpos); 866 int *vpos, int *hpos, ktime_t *stime,
867 ktime_t *etime);
862 868
863 /** 869 /**
864 * Called by \c drm_get_last_vbltimestamp. Should return a precise 870 * Called by \c drm_get_last_vbltimestamp. Should return a precise