aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2017-05-09 10:03:28 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2017-05-10 04:21:31 -0400
commit1bf6ad622b9be58484279978f85716fbb10d545b (patch)
treef7add5183253140848bff995e5084e8fd35dacb8 /drivers/gpu/drm/amd
parent2a39b88bc121645e95a2b3b25a97ef4ceb4208b8 (diff)
drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos
If we restrict this helper to only kms drivers (which is the case) we can look up the correct mode easily ourselves. But it's a bit tricky: - All legacy drivers look at crtc->hwmode. But that is updated already at the beginning of the modeset helper, which means when we disable a pipe. Hence the final timestamps might be a bit off. But since this is an existing bug I'm not going to change it, but just try to be bug-for-bug compatible with the current code. This only applies to radeon&amdgpu. - i915 tries to get it perfect by updating crtc->hwmode when the pipe is off (i.e. vblank->enabled = false). - All other atomic drivers look at crtc->state->adjusted_mode. Those that look at state->requested_mode simply don't adjust their mode, so it's the same. That has two problems: Accessing crtc->state from interrupt handling code is unsafe, and it's updated before we shut down the pipe. For nonblocking modesets it's even worse. For atomic drivers try to implement what i915 does. To do that we add a new hwmode field to the vblank structure, and update it from drm_calc_timestamping_constants(). For atomic drivers that's called from the right spot by the helper library already, so all fine. But for safety let's enforce that. For legacy driver this function is only called at the end (oh the fun), which is broken, so again let's not bother and just stay bug-for-bug compatible. The benefit is that we can use drm_calc_vbltimestamp_from_scanoutpos directly to implement ->get_vblank_timestamp in every driver, deleting a lot of code. v2: Completely new approach, trying to mimick the i915 solution. v3: Fixup kerneldoc. v4: Drop the WARN_ON to check that the vblank is off, atomic helpers currently unconditionally call this. Recomputing the same stuff should be harmless. v5: Fix typos and move misplaced hunks to the right patches (Neil). v6: Undo hunk movement (kbuild). Cc: Mario Kleiner <mario.kleiner@tuebingen.mpg.de> Cc: Eric Anholt <eric@anholt.net> Cc: Rob Clark <robdclark@gmail.com> Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher <alexander.deucher@amd.com> Cc: Christian König <christian.koenig@amd.com> Cc: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170509140329.24114-4-daniel.vetter@ffwll.ch
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c41
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h3
4 files changed, 15 insertions, 47 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 0ce8292d97c0..9de615bb0c2e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1910,10 +1910,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon);
1910u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); 1910u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe);
1911int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); 1911int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe);
1912void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); 1912void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe);
1913bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
1914 int *max_error,
1915 struct timeval *vblank_time,
1916 bool in_vblank_irq);
1917long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, 1913long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd,
1918 unsigned long arg); 1914 unsigned long arg);
1919 1915
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 4e0f7d2d87f1..73e982cd6136 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -711,6 +711,16 @@ static const struct file_operations amdgpu_driver_kms_fops = {
711#endif 711#endif
712}; 712};
713 713
714static bool
715amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe,
716 bool in_vblank_irq, int *vpos, int *hpos,
717 ktime_t *stime, ktime_t *etime,
718 const struct drm_display_mode *mode)
719{
720 return amdgpu_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos,
721 stime, etime, mode);
722}
723
714static struct drm_driver kms_driver = { 724static struct drm_driver kms_driver = {
715 .driver_features = 725 .driver_features =
716 DRIVER_USE_AGP | 726 DRIVER_USE_AGP |
@@ -725,8 +735,8 @@ static struct drm_driver kms_driver = {
725 .get_vblank_counter = amdgpu_get_vblank_counter_kms, 735 .get_vblank_counter = amdgpu_get_vblank_counter_kms,
726 .enable_vblank = amdgpu_enable_vblank_kms, 736 .enable_vblank = amdgpu_enable_vblank_kms,
727 .disable_vblank = amdgpu_disable_vblank_kms, 737 .disable_vblank = amdgpu_disable_vblank_kms,
728 .get_vblank_timestamp = amdgpu_get_vblank_timestamp_kms, 738 .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
729 .get_scanout_position = amdgpu_get_crtc_scanoutpos, 739 .get_scanout_position = amdgpu_get_crtc_scanout_position,
730#if defined(CONFIG_DEBUG_FS) 740#if defined(CONFIG_DEBUG_FS)
731 .debugfs_init = amdgpu_debugfs_init, 741 .debugfs_init = amdgpu_debugfs_init,
732#endif 742#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index babd969a63d1..40f45ba71b86 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -934,47 +934,6 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe)
934 amdgpu_irq_put(adev, &adev->crtc_irq, idx); 934 amdgpu_irq_put(adev, &adev->crtc_irq, idx);
935} 935}
936 936
937/**
938 * amdgpu_get_vblank_timestamp_kms - get vblank timestamp
939 *
940 * @dev: drm dev pointer
941 * @crtc: crtc to get the timestamp for
942 * @max_error: max error
943 * @vblank_time: time value
944 * @in_vblank_irq: called from drm_handle_vblank()
945 *
946 * Gets the timestamp on the requested crtc based on the
947 * scanout position. (all asics).
948 * Returns true on success, false on failure.
949 */
950bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
951 int *max_error,
952 struct timeval *vblank_time,
953 bool in_vblank_irq)
954{
955 struct drm_crtc *crtc;
956 struct amdgpu_device *adev = dev->dev_private;
957
958 if (pipe >= dev->num_crtcs) {
959 DRM_ERROR("Invalid crtc %u\n", pipe);
960 return false;
961 }
962
963 /* Get associated drm_crtc: */
964 crtc = &adev->mode_info.crtcs[pipe]->base;
965 if (!crtc) {
966 /* This can occur on driver load if some component fails to
967 * initialize completely and driver is unloaded */
968 DRM_ERROR("Uninitialized crtc %d\n", pipe);
969 return false;
970 }
971
972 /* Helper routine in DRM core does all the work: */
973 return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
974 vblank_time, in_vblank_irq,
975 &crtc->hwmode);
976}
977
978const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { 937const struct drm_ioctl_desc amdgpu_ioctls_kms[] = {
979 DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 938 DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
980 DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 939 DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index db8f8dda209c..20d6522fd7b4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -534,6 +534,9 @@ struct amdgpu_framebuffer {
534 ((em) == ATOM_ENCODER_MODE_DP_MST)) 534 ((em) == ATOM_ENCODER_MODE_DP_MST))
535 535
536/* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */ 536/* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */
537#define DRM_SCANOUTPOS_VALID (1 << 0)
538#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1)
539#define DRM_SCANOUTPOS_ACCURATE (1 << 2)
537#define USE_REAL_VBLANKSTART (1 << 30) 540#define USE_REAL_VBLANKSTART (1 << 30)
538#define GET_DISTANCE_TO_VBLANKSTART (1 << 31) 541#define GET_DISTANCE_TO_VBLANKSTART (1 << 31)
539 542