diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2015-09-14 15:43:44 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-09-24 14:14:21 -0400 |
commit | 3bb403bf421b5b00366a9041a7edc0a1f6494f5e (patch) | |
tree | d280555ef17c89c2a1e952d03749d230547598c3 /drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | |
parent | eba1f35dfe145247c7eb690c7c32740fde8ec699 (diff) |
drm: Stop using linedur_ns and pixeldur_ns for vblank timestamps
linedur_ns, and especially pixeldur_ns are becoming rather inaccurate
to be used for the vblank timestamp correction. With 4k@60 the pixel
duration is already below 2ns, so the amount of error due to the
truncation to nanoseconds is introducing quite a bit of error.
We can avoid such problems if we instead calculate the timestamp
delta_ns directly from the dislay timings, avoiding the use of
these intermediate truncated values.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
[danvet: Squash in fixup from Thierry Reding for amdgpu.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_display.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index e3d70772b531..9b34a3410c32 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | |||
@@ -745,7 +745,8 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
745 | * | 745 | * |
746 | */ | 746 | */ |
747 | int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags, | 747 | int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags, |
748 | int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) | 748 | int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, |
749 | const struct drm_display_mode *mode) | ||
749 | { | 750 | { |
750 | u32 vbl = 0, position = 0; | 751 | u32 vbl = 0, position = 0; |
751 | int vbl_start, vbl_end, vtotal, ret = 0; | 752 | int vbl_start, vbl_end, vtotal, ret = 0; |
@@ -781,7 +782,7 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl | |||
781 | } | 782 | } |
782 | else { | 783 | else { |
783 | /* No: Fake something reasonable which gives at least ok results. */ | 784 | /* No: Fake something reasonable which gives at least ok results. */ |
784 | vbl_start = adev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay; | 785 | vbl_start = mode->crtc_vdisplay; |
785 | vbl_end = 0; | 786 | vbl_end = 0; |
786 | } | 787 | } |
787 | 788 | ||
@@ -797,7 +798,7 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl | |||
797 | 798 | ||
798 | /* Inside "upper part" of vblank area? Apply corrective offset if so: */ | 799 | /* Inside "upper part" of vblank area? Apply corrective offset if so: */ |
799 | if (in_vbl && (*vpos >= vbl_start)) { | 800 | if (in_vbl && (*vpos >= vbl_start)) { |
800 | vtotal = adev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal; | 801 | vtotal = mode->crtc_vtotal; |
801 | *vpos = *vpos - vtotal; | 802 | *vpos = *vpos - vtotal; |
802 | } | 803 | } |
803 | 804 | ||
@@ -819,8 +820,8 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl | |||
819 | * We only do this if DRM_CALLED_FROM_VBLIRQ. | 820 | * We only do this if DRM_CALLED_FROM_VBLIRQ. |
820 | */ | 821 | */ |
821 | if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) { | 822 | if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) { |
822 | vbl_start = adev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay; | 823 | vbl_start = mode->crtc_vdisplay; |
823 | vtotal = adev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal; | 824 | vtotal = mode->crtc_vtotal; |
824 | 825 | ||
825 | if (vbl_start - *vpos < vtotal / 100) { | 826 | if (vbl_start - *vpos < vtotal / 100) { |
826 | *vpos -= vtotal; | 827 | *vpos -= vtotal; |