* [PATCH 11/16] drm/vblank: Switch drm_driver->get_vblank_timestamp to return a bool [not found] ` <20170322083617.13361-1-daniel.vetter-/w4YWyX8dFk@public.gmane.org> @ 2017-03-22 8:36 ` Daniel Vetter [not found] ` <20170322083617.13361-12-daniel.vetter-/w4YWyX8dFk@public.gmane.org> 2017-03-22 20:55 ` [PATCH] " Daniel Vetter 2017-03-22 8:36 ` [PATCH 15/16] drm/vblank: Simplify the get_scanout_position helper hook Daniel Vetter 1 sibling, 2 replies; 19+ messages in thread From: Daniel Vetter @ 2017-03-22 8:36 UTC (permalink / raw) To: Intel Graphics Development Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, DRI Development, Eric Anholt, Rob Clark, Ben Skeggs, Mario Kleiner, Daniel Vetter, Alex Deucher, Daniel Vetter, freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Christian König There's really no reason for anything more: - Calling this while the crtc vblank stuff isn't set up is a driver bug. Those places arlready DRM_ERROR. - Calling this when the crtc is off is either a driver bug (callin drm_crtc_handle_vblank at the wrong time) or a core bug (for anything else). Again, we DRM_ERROR. - EINVAL is checked at higher levels already, and if we'd use struct drm_crtc * instead of (dev, pipe) it would be real obvious that those are again core bugs. The only valid failure mode is crap hardware that couldn't sample a useful timestamp, to ask the core to just grab a not-so-accurate timestampe. Bool is perfectly fine for that. 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> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 +++---- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 14 ++++++------ drivers/gpu/drm/drm_irq.c | 37 +++++++++++-------------------- drivers/gpu/drm/i915/i915_irq.c | 8 +++---- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 12 +++++----- drivers/gpu/drm/nouveau/nouveau_display.c | 4 ++-- drivers/gpu/drm/nouveau/nouveau_display.h | 4 ++-- drivers/gpu/drm/radeon/radeon_drv.c | 8 +++---- drivers/gpu/drm/radeon/radeon_kms.c | 14 ++++++------ drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- include/drm/drmP.h | 1 - include/drm/drm_drv.h | 7 +++--- include/drm/drm_irq.h | 10 ++++----- 14 files changed, 59 insertions(+), 72 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index c8860f05bfb9..acd8631d8024 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1768,10 +1768,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags); +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags); long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 55f951bcc91f..ac42f707c046 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -838,19 +838,19 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) * * Gets the timestamp on the requested crtc based on the * scanout position. (all asics). - * Returns postive status flags on success, negative error on failure. + * Returns true on success, false on failure. */ -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags) +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags) { struct drm_crtc *crtc; struct amdgpu_device *adev = dev->dev_private; if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; } /* Get associated drm_crtc: */ @@ -859,7 +859,7 @@ int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, /* This can occur on driver load if some component fails to * initialize completely and driver is unloaded */ DRM_ERROR("Uninitialized crtc %d\n", pipe); - return -EINVAL; + return false; } /* Helper routine in DRM core does all the work: */ diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 4b0c7475ed13..2121ea29e1b2 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -722,43 +722,32 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * active. Higher level code is expected to handle this. * * Returns: - * Negative value on error, failure or if not supported in current - * video mode: - * - * -EINVAL Invalid CRTC. - * -EAGAIN Temporary unavailable, e.g., called before initial modeset. - * -ENOTSUPP Function not supported in current display mode. - * -EIO Failed, e.g., due to failed scanout position query. - * - * Returns or'ed positive status flags on success: - * - * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. - * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. * + * Returns true on success, and false on failure, i.e. when no accurate + * timestamp could be acquired. */ -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, - unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags, - const struct drm_display_mode *mode) +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, + unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags, + const struct drm_display_mode *mode) { struct timeval tv_etime; ktime_t stime, etime; unsigned int vbl_status; - int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD; int vpos, hpos, i; int delta_ns, duration_ns; if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; } /* Scanout position query not supported? Should not happen. */ if (!dev->driver->get_scanout_position) { DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); - return -EIO; + return false; } /* If mode timing undefined, just return as no-op: @@ -766,7 +755,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, */ if (mode->crtc_clock == 0) { DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe); - return -EAGAIN; + return false; } /* Get current scanout position with system timestamp. @@ -790,7 +779,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", pipe, vbl_status); - return -EIO; + return false; } /* Compute uncertainty in timestamp of scanout position query. */ @@ -834,7 +823,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, duration_ns/1000, i); - return ret; + return true; } EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 26aa1c170b43..df149d159ce7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -964,7 +964,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) return position; } -static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, +static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags) @@ -974,19 +974,19 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; } /* Get drm_crtc to timestamp: */ crtc = intel_get_crtc_for_pipe(dev_priv, pipe); if (crtc == NULL) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; } if (!crtc->base.hwmode.crtc_clock) { DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); - return -EBUSY; + return false; } /* Helper routine in DRM core does all the work: */ diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 41ccd2a15d3c..655700eb42ba 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -595,23 +595,23 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, return ret; } -static int mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags) +static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags) { struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc; if (pipe < 0 || pipe >= priv->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", pipe); - return -EINVAL; + return false; } crtc = priv->crtcs[pipe]; if (!crtc) { DRM_ERROR("Invalid crtc %d\n", pipe); - return -EINVAL; + return false; } return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 33269c7df30f..42f18b0b9c43 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -156,7 +156,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, return 0; } -int +bool nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *time, unsigned flags) { @@ -174,7 +174,7 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, } } - return -EINVAL; + return false; } static void diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 4a75df06c139..bc9d1e7b0117 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -71,8 +71,8 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); -int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, - struct timeval *, unsigned); +bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, + struct timeval *, unsigned); int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 312436a8d9e5..6d79b5c2805b 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,10 +114,10 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags); +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags); void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index a32a62e03a44..9afe72010c64 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -868,25 +868,25 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) * * Gets the timestamp on the requested crtc based on the * scanout position. (all asics). - * Returns postive status flags on success, negative error on failure. + * Returns true on success, false on failure. */ -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, - int *max_error, - struct timeval *vblank_time, - unsigned flags) +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, + int *max_error, + struct timeval *vblank_time, + unsigned flags) { struct drm_crtc *drmcrtc; struct radeon_device *rdev = dev->dev_private; if (crtc < 0 || crtc >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", crtc); - return -EINVAL; + return false; } /* Get associated drm_crtc: */ drmcrtc = &rdev->mode_info.crtcs[crtc]->base; if (!drmcrtc) - return -EINVAL; + return false; /* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 24edd0c22cc9..74260990b6bf 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -270,7 +270,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, return ret; } -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags) { diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index dffce6293d87..8a5d0e12ee02 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -450,7 +450,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 27ecfcdbf752..6304de7e041e 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -322,7 +322,6 @@ struct pci_controller; /* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 -#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) /* get_scanout_position() return flags */ #define DRM_SCANOUTPOS_VALID (1 << 0) diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index d0b5f363bfa1..da78e248d9d8 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -316,11 +316,10 @@ struct drm_driver { * * Returns: * - * Zero if timestamping isn't supported in current display mode or a - * negative number on failure. A positive status code on success, - * which describes how the vblank_time timestamp was computed. + * True on success, false on failure, which means the core should + * fallback to a simple timestamp taken in drm_crtc_handle_vblank(). */ - int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, + bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags); diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index cf0be6594c8c..f0d5ccf9b282 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -153,11 +153,11 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc); void drm_vblank_cleanup(struct drm_device *dev); u32 drm_accurate_vblank_count(struct drm_crtc *crtc); -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, - unsigned int pipe, int *max_error, - struct timeval *vblank_time, - unsigned flags, - const struct drm_display_mode *mode); +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, + unsigned int pipe, int *max_error, + struct timeval *vblank_time, + unsigned flags, + const struct drm_display_mode *mode); void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode); -- 2.11.0 _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno ^ permalink raw reply related [flat|nested] 19+ messages in thread
[parent not found: <20170322083617.13361-12-daniel.vetter-/w4YWyX8dFk@public.gmane.org>]
* Re: [Intel-gfx] [PATCH 11/16] drm/vblank: Switch drm_driver->get_vblank_timestamp to return a bool [not found] ` <20170322083617.13361-12-daniel.vetter-/w4YWyX8dFk@public.gmane.org> @ 2017-03-22 10:33 ` Jani Nikula 2017-03-22 13:23 ` Daniel Vetter 0 siblings, 1 reply; 19+ messages in thread From: Jani Nikula @ 2017-03-22 10:33 UTC (permalink / raw) To: Intel Graphics Development Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, DRI Development, Ben Skeggs, Mario Kleiner, Daniel Vetter, Alex Deucher, Daniel Vetter, freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Christian König On Wed, 22 Mar 2017, Daniel Vetter <daniel.vetter@ffwll.ch> wrote: > There's really no reason for anything more: > - Calling this while the crtc vblank stuff isn't set up is a driver > bug. Those places arlready DRM_ERROR. > - Calling this when the crtc is off is either a driver bug (callin > drm_crtc_handle_vblank at the wrong time) or a core bug (for > anything else). Again, we DRM_ERROR. > - EINVAL is checked at higher levels already, and if we'd use struct > drm_crtc * instead of (dev, pipe) it would be real obvious that > those are again core bugs. > > The only valid failure mode is crap hardware that couldn't sample a > useful timestamp, to ask the core to just grab a not-so-accurate > timestampe. Bool is perfectly fine for that. FWIW, I'm not all that thrilled about changing int returns to bools, because it changes the check for success from !ret to ret, and the compiler won't help you. Sure, there aren't many call sites for the function, but, case in point, you forgot to change that lone call site. Though it still works by coincidence. BR, Jani. > > 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> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 +++---- > drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 14 ++++++------ > drivers/gpu/drm/drm_irq.c | 37 +++++++++++-------------------- > drivers/gpu/drm/i915/i915_irq.c | 8 +++---- > drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 12 +++++----- > drivers/gpu/drm/nouveau/nouveau_display.c | 4 ++-- > drivers/gpu/drm/nouveau/nouveau_display.h | 4 ++-- > drivers/gpu/drm/radeon/radeon_drv.c | 8 +++---- > drivers/gpu/drm/radeon/radeon_kms.c | 14 ++++++------ > drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- > drivers/gpu/drm/vc4/vc4_drv.h | 2 +- > include/drm/drmP.h | 1 - > include/drm/drm_drv.h | 7 +++--- > include/drm/drm_irq.h | 10 ++++----- > 14 files changed, 59 insertions(+), 72 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index c8860f05bfb9..acd8631d8024 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -1768,10 +1768,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); > u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); > int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); > void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); > -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > - int *max_error, > - struct timeval *vblank_time, > - unsigned flags); > +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > + int *max_error, > + struct timeval *vblank_time, > + unsigned flags); > long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, > unsigned long arg); > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > index 55f951bcc91f..ac42f707c046 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > @@ -838,19 +838,19 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) > * > * Gets the timestamp on the requested crtc based on the > * scanout position. (all asics). > - * Returns postive status flags on success, negative error on failure. > + * Returns true on success, false on failure. > */ > -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > - int *max_error, > - struct timeval *vblank_time, > - unsigned flags) > +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > + int *max_error, > + struct timeval *vblank_time, > + unsigned flags) > { > struct drm_crtc *crtc; > struct amdgpu_device *adev = dev->dev_private; > > if (pipe >= dev->num_crtcs) { > DRM_ERROR("Invalid crtc %u\n", pipe); > - return -EINVAL; > + return false; > } > > /* Get associated drm_crtc: */ > @@ -859,7 +859,7 @@ int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > /* This can occur on driver load if some component fails to > * initialize completely and driver is unloaded */ > DRM_ERROR("Uninitialized crtc %d\n", pipe); > - return -EINVAL; > + return false; > } > > /* Helper routine in DRM core does all the work: */ > diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c > index 4b0c7475ed13..2121ea29e1b2 100644 > --- a/drivers/gpu/drm/drm_irq.c > +++ b/drivers/gpu/drm/drm_irq.c > @@ -722,43 +722,32 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); > * active. Higher level code is expected to handle this. > * > * Returns: > - * Negative value on error, failure or if not supported in current > - * video mode: > - * > - * -EINVAL Invalid CRTC. > - * -EAGAIN Temporary unavailable, e.g., called before initial modeset. > - * -ENOTSUPP Function not supported in current display mode. > - * -EIO Failed, e.g., due to failed scanout position query. > - * > - * Returns or'ed positive status flags on success: > - * > - * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. > - * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. > * > + * Returns true on success, and false on failure, i.e. when no accurate > + * timestamp could be acquired. > */ > -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > - unsigned int pipe, > - int *max_error, > - struct timeval *vblank_time, > - unsigned flags, > - const struct drm_display_mode *mode) > +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > + unsigned int pipe, > + int *max_error, > + struct timeval *vblank_time, > + unsigned flags, > + const struct drm_display_mode *mode) > { > struct timeval tv_etime; > ktime_t stime, etime; > unsigned int vbl_status; > - int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD; > int vpos, hpos, i; > int delta_ns, duration_ns; > > if (pipe >= dev->num_crtcs) { > DRM_ERROR("Invalid crtc %u\n", pipe); > - return -EINVAL; > + return false; > } > > /* Scanout position query not supported? Should not happen. */ > if (!dev->driver->get_scanout_position) { > DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); > - return -EIO; > + return false; > } > > /* If mode timing undefined, just return as no-op: > @@ -766,7 +755,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > */ > if (mode->crtc_clock == 0) { > DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe); > - return -EAGAIN; > + return false; > } > > /* Get current scanout position with system timestamp. > @@ -790,7 +779,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { > DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", > pipe, vbl_status); > - return -EIO; > + return false; > } > > /* Compute uncertainty in timestamp of scanout position query. */ > @@ -834,7 +823,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, > duration_ns/1000, i); > > - return ret; > + return true; > } > EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); > > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > index 26aa1c170b43..df149d159ce7 100644 > --- a/drivers/gpu/drm/i915/i915_irq.c > +++ b/drivers/gpu/drm/i915/i915_irq.c > @@ -964,7 +964,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) > return position; > } > > -static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > +static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > int *max_error, > struct timeval *vblank_time, > unsigned flags) > @@ -974,19 +974,19 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > > if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { > DRM_ERROR("Invalid crtc %u\n", pipe); > - return -EINVAL; > + return false; > } > > /* Get drm_crtc to timestamp: */ > crtc = intel_get_crtc_for_pipe(dev_priv, pipe); > if (crtc == NULL) { > DRM_ERROR("Invalid crtc %u\n", pipe); > - return -EINVAL; > + return false; > } > > if (!crtc->base.hwmode.crtc_clock) { > DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); > - return -EBUSY; > + return false; > } > > /* Helper routine in DRM core does all the work: */ > diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > index 41ccd2a15d3c..655700eb42ba 100644 > --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > @@ -595,23 +595,23 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, > return ret; > } > > -static int mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > - int *max_error, > - struct timeval *vblank_time, > - unsigned flags) > +static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > + int *max_error, > + struct timeval *vblank_time, > + unsigned flags) > { > struct msm_drm_private *priv = dev->dev_private; > struct drm_crtc *crtc; > > if (pipe < 0 || pipe >= priv->num_crtcs) { > DRM_ERROR("Invalid crtc %d\n", pipe); > - return -EINVAL; > + return false; > } > > crtc = priv->crtcs[pipe]; > if (!crtc) { > DRM_ERROR("Invalid crtc %d\n", pipe); > - return -EINVAL; > + return false; > } > > return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c > index 33269c7df30f..42f18b0b9c43 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_display.c > +++ b/drivers/gpu/drm/nouveau/nouveau_display.c > @@ -156,7 +156,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, > return 0; > } > > -int > +bool > nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, > int *max_error, struct timeval *time, unsigned flags) > { > @@ -174,7 +174,7 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, > } > } > > - return -EINVAL; > + return false; > } > > static void > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h > index 4a75df06c139..bc9d1e7b0117 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_display.h > +++ b/drivers/gpu/drm/nouveau/nouveau_display.h > @@ -71,8 +71,8 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); > int nouveau_display_scanoutpos(struct drm_device *, unsigned int, > unsigned int, int *, int *, ktime_t *, > ktime_t *, const struct drm_display_mode *); > -int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, > - struct timeval *, unsigned); > +bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, > + struct timeval *, unsigned); > > int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, > struct drm_pending_vblank_event *event, > diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c > index 312436a8d9e5..6d79b5c2805b 100644 > --- a/drivers/gpu/drm/radeon/radeon_drv.c > +++ b/drivers/gpu/drm/radeon/radeon_drv.c > @@ -114,10 +114,10 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); > u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); > int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); > void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); > -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > - int *max_error, > - struct timeval *vblank_time, > - unsigned flags); > +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > + int *max_error, > + struct timeval *vblank_time, > + unsigned flags); > void radeon_driver_irq_preinstall_kms(struct drm_device *dev); > int radeon_driver_irq_postinstall_kms(struct drm_device *dev); > void radeon_driver_irq_uninstall_kms(struct drm_device *dev); > diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c > index a32a62e03a44..9afe72010c64 100644 > --- a/drivers/gpu/drm/radeon/radeon_kms.c > +++ b/drivers/gpu/drm/radeon/radeon_kms.c > @@ -868,25 +868,25 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) > * > * Gets the timestamp on the requested crtc based on the > * scanout position. (all asics). > - * Returns postive status flags on success, negative error on failure. > + * Returns true on success, false on failure. > */ > -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, > - int *max_error, > - struct timeval *vblank_time, > - unsigned flags) > +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, > + int *max_error, > + struct timeval *vblank_time, > + unsigned flags) > { > struct drm_crtc *drmcrtc; > struct radeon_device *rdev = dev->dev_private; > > if (crtc < 0 || crtc >= dev->num_crtcs) { > DRM_ERROR("Invalid crtc %d\n", crtc); > - return -EINVAL; > + return false; > } > > /* Get associated drm_crtc: */ > drmcrtc = &rdev->mode_info.crtcs[crtc]->base; > if (!drmcrtc) > - return -EINVAL; > + return false; > > /* Helper routine in DRM core does all the work: */ > return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, > diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c > index 24edd0c22cc9..74260990b6bf 100644 > --- a/drivers/gpu/drm/vc4/vc4_crtc.c > +++ b/drivers/gpu/drm/vc4/vc4_crtc.c > @@ -270,7 +270,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, > return ret; > } > > -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > int *max_error, struct timeval *vblank_time, > unsigned flags) > { > diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h > index dffce6293d87..8a5d0e12ee02 100644 > --- a/drivers/gpu/drm/vc4/vc4_drv.h > +++ b/drivers/gpu/drm/vc4/vc4_drv.h > @@ -450,7 +450,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, > unsigned int flags, int *vpos, int *hpos, > ktime_t *stime, ktime_t *etime, > const struct drm_display_mode *mode); > -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > int *max_error, struct timeval *vblank_time, > unsigned flags); > > diff --git a/include/drm/drmP.h b/include/drm/drmP.h > index 27ecfcdbf752..6304de7e041e 100644 > --- a/include/drm/drmP.h > +++ b/include/drm/drmP.h > @@ -322,7 +322,6 @@ struct pci_controller; > > /* Flags and return codes for get_vblank_timestamp() driver function. */ > #define DRM_CALLED_FROM_VBLIRQ 1 > -#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) > > /* get_scanout_position() return flags */ > #define DRM_SCANOUTPOS_VALID (1 << 0) > diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h > index d0b5f363bfa1..da78e248d9d8 100644 > --- a/include/drm/drm_drv.h > +++ b/include/drm/drm_drv.h > @@ -316,11 +316,10 @@ struct drm_driver { > * > * Returns: > * > - * Zero if timestamping isn't supported in current display mode or a > - * negative number on failure. A positive status code on success, > - * which describes how the vblank_time timestamp was computed. > + * True on success, false on failure, which means the core should > + * fallback to a simple timestamp taken in drm_crtc_handle_vblank(). > */ > - int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, > + bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, > int *max_error, > struct timeval *vblank_time, > unsigned flags); > diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h > index cf0be6594c8c..f0d5ccf9b282 100644 > --- a/include/drm/drm_irq.h > +++ b/include/drm/drm_irq.h > @@ -153,11 +153,11 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc); > void drm_vblank_cleanup(struct drm_device *dev); > u32 drm_accurate_vblank_count(struct drm_crtc *crtc); > > -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > - unsigned int pipe, int *max_error, > - struct timeval *vblank_time, > - unsigned flags, > - const struct drm_display_mode *mode); > +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > + unsigned int pipe, int *max_error, > + struct timeval *vblank_time, > + unsigned flags, > + const struct drm_display_mode *mode); > void drm_calc_timestamping_constants(struct drm_crtc *crtc, > const struct drm_display_mode *mode); -- Jani Nikula, Intel Open Source Technology Center _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 11/16] drm/vblank: Switch drm_driver->get_vblank_timestamp to return a bool 2017-03-22 10:33 ` [Intel-gfx] " Jani Nikula @ 2017-03-22 13:23 ` Daniel Vetter [not found] ` <20170322132305.zdtehgbox6erdhbq-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org> 0 siblings, 1 reply; 19+ messages in thread From: Daniel Vetter @ 2017-03-22 13:23 UTC (permalink / raw) To: Jani Nikula Cc: Daniel Vetter, Intel Graphics Development, DRI Development, Ben Skeggs, Mario Kleiner, linux-arm-msm, Alex Deucher, Daniel Vetter, freedreno, Christian König On Wed, Mar 22, 2017 at 12:33:35PM +0200, Jani Nikula wrote: > On Wed, 22 Mar 2017, Daniel Vetter <daniel.vetter@ffwll.ch> wrote: > > There's really no reason for anything more: > > - Calling this while the crtc vblank stuff isn't set up is a driver > > bug. Those places arlready DRM_ERROR. > > - Calling this when the crtc is off is either a driver bug (callin > > drm_crtc_handle_vblank at the wrong time) or a core bug (for > > anything else). Again, we DRM_ERROR. > > - EINVAL is checked at higher levels already, and if we'd use struct > > drm_crtc * instead of (dev, pipe) it would be real obvious that > > those are again core bugs. > > > > The only valid failure mode is crap hardware that couldn't sample a > > useful timestamp, to ask the core to just grab a not-so-accurate > > timestampe. Bool is perfectly fine for that. > > FWIW, I'm not all that thrilled about changing int returns to bools, > because it changes the check for success from !ret to ret, and the > compiler won't help you. Sure, there aren't many call sites for the > function, but, case in point, you forgot to change that lone call > site. Though it still works by coincidence. The old call site treated > 0 as success, and 0 or anything negative as failure. That the lone caller still works is the reason why I've switched to bool, because besides all the funny values that the caller gets and ignreos, it already is. Or did I miss something? -Daniel > > BR, > Jani. > > > > > 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> > > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> > > --- > > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 +++---- > > drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 14 ++++++------ > > drivers/gpu/drm/drm_irq.c | 37 +++++++++++-------------------- > > drivers/gpu/drm/i915/i915_irq.c | 8 +++---- > > drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 12 +++++----- > > drivers/gpu/drm/nouveau/nouveau_display.c | 4 ++-- > > drivers/gpu/drm/nouveau/nouveau_display.h | 4 ++-- > > drivers/gpu/drm/radeon/radeon_drv.c | 8 +++---- > > drivers/gpu/drm/radeon/radeon_kms.c | 14 ++++++------ > > drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- > > drivers/gpu/drm/vc4/vc4_drv.h | 2 +- > > include/drm/drmP.h | 1 - > > include/drm/drm_drv.h | 7 +++--- > > include/drm/drm_irq.h | 10 ++++----- > > 14 files changed, 59 insertions(+), 72 deletions(-) > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > > index c8860f05bfb9..acd8631d8024 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > > @@ -1768,10 +1768,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); > > u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); > > int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); > > void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); > > -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > > - int *max_error, > > - struct timeval *vblank_time, > > - unsigned flags); > > +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > > + int *max_error, > > + struct timeval *vblank_time, > > + unsigned flags); > > long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, > > unsigned long arg); > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > > index 55f951bcc91f..ac42f707c046 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > > @@ -838,19 +838,19 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) > > * > > * Gets the timestamp on the requested crtc based on the > > * scanout position. (all asics). > > - * Returns postive status flags on success, negative error on failure. > > + * Returns true on success, false on failure. > > */ > > -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > > - int *max_error, > > - struct timeval *vblank_time, > > - unsigned flags) > > +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > > + int *max_error, > > + struct timeval *vblank_time, > > + unsigned flags) > > { > > struct drm_crtc *crtc; > > struct amdgpu_device *adev = dev->dev_private; > > > > if (pipe >= dev->num_crtcs) { > > DRM_ERROR("Invalid crtc %u\n", pipe); > > - return -EINVAL; > > + return false; > > } > > > > /* Get associated drm_crtc: */ > > @@ -859,7 +859,7 @@ int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > > /* This can occur on driver load if some component fails to > > * initialize completely and driver is unloaded */ > > DRM_ERROR("Uninitialized crtc %d\n", pipe); > > - return -EINVAL; > > + return false; > > } > > > > /* Helper routine in DRM core does all the work: */ > > diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c > > index 4b0c7475ed13..2121ea29e1b2 100644 > > --- a/drivers/gpu/drm/drm_irq.c > > +++ b/drivers/gpu/drm/drm_irq.c > > @@ -722,43 +722,32 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); > > * active. Higher level code is expected to handle this. > > * > > * Returns: > > - * Negative value on error, failure or if not supported in current > > - * video mode: > > - * > > - * -EINVAL Invalid CRTC. > > - * -EAGAIN Temporary unavailable, e.g., called before initial modeset. > > - * -ENOTSUPP Function not supported in current display mode. > > - * -EIO Failed, e.g., due to failed scanout position query. > > - * > > - * Returns or'ed positive status flags on success: > > - * > > - * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. > > - * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. > > * > > + * Returns true on success, and false on failure, i.e. when no accurate > > + * timestamp could be acquired. > > */ > > -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > > - unsigned int pipe, > > - int *max_error, > > - struct timeval *vblank_time, > > - unsigned flags, > > - const struct drm_display_mode *mode) > > +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > > + unsigned int pipe, > > + int *max_error, > > + struct timeval *vblank_time, > > + unsigned flags, > > + const struct drm_display_mode *mode) > > { > > struct timeval tv_etime; > > ktime_t stime, etime; > > unsigned int vbl_status; > > - int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD; > > int vpos, hpos, i; > > int delta_ns, duration_ns; > > > > if (pipe >= dev->num_crtcs) { > > DRM_ERROR("Invalid crtc %u\n", pipe); > > - return -EINVAL; > > + return false; > > } > > > > /* Scanout position query not supported? Should not happen. */ > > if (!dev->driver->get_scanout_position) { > > DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); > > - return -EIO; > > + return false; > > } > > > > /* If mode timing undefined, just return as no-op: > > @@ -766,7 +755,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > > */ > > if (mode->crtc_clock == 0) { > > DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe); > > - return -EAGAIN; > > + return false; > > } > > > > /* Get current scanout position with system timestamp. > > @@ -790,7 +779,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > > if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { > > DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", > > pipe, vbl_status); > > - return -EIO; > > + return false; > > } > > > > /* Compute uncertainty in timestamp of scanout position query. */ > > @@ -834,7 +823,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > > (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, > > duration_ns/1000, i); > > > > - return ret; > > + return true; > > } > > EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); > > > > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > > index 26aa1c170b43..df149d159ce7 100644 > > --- a/drivers/gpu/drm/i915/i915_irq.c > > +++ b/drivers/gpu/drm/i915/i915_irq.c > > @@ -964,7 +964,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) > > return position; > > } > > > > -static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > > +static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > > int *max_error, > > struct timeval *vblank_time, > > unsigned flags) > > @@ -974,19 +974,19 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > > > > if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { > > DRM_ERROR("Invalid crtc %u\n", pipe); > > - return -EINVAL; > > + return false; > > } > > > > /* Get drm_crtc to timestamp: */ > > crtc = intel_get_crtc_for_pipe(dev_priv, pipe); > > if (crtc == NULL) { > > DRM_ERROR("Invalid crtc %u\n", pipe); > > - return -EINVAL; > > + return false; > > } > > > > if (!crtc->base.hwmode.crtc_clock) { > > DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); > > - return -EBUSY; > > + return false; > > } > > > > /* Helper routine in DRM core does all the work: */ > > diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > > index 41ccd2a15d3c..655700eb42ba 100644 > > --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > > +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > > @@ -595,23 +595,23 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, > > return ret; > > } > > > > -static int mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > > - int *max_error, > > - struct timeval *vblank_time, > > - unsigned flags) > > +static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > > + int *max_error, > > + struct timeval *vblank_time, > > + unsigned flags) > > { > > struct msm_drm_private *priv = dev->dev_private; > > struct drm_crtc *crtc; > > > > if (pipe < 0 || pipe >= priv->num_crtcs) { > > DRM_ERROR("Invalid crtc %d\n", pipe); > > - return -EINVAL; > > + return false; > > } > > > > crtc = priv->crtcs[pipe]; > > if (!crtc) { > > DRM_ERROR("Invalid crtc %d\n", pipe); > > - return -EINVAL; > > + return false; > > } > > > > return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, > > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c > > index 33269c7df30f..42f18b0b9c43 100644 > > --- a/drivers/gpu/drm/nouveau/nouveau_display.c > > +++ b/drivers/gpu/drm/nouveau/nouveau_display.c > > @@ -156,7 +156,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, > > return 0; > > } > > > > -int > > +bool > > nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, > > int *max_error, struct timeval *time, unsigned flags) > > { > > @@ -174,7 +174,7 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, > > } > > } > > > > - return -EINVAL; > > + return false; > > } > > > > static void > > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h > > index 4a75df06c139..bc9d1e7b0117 100644 > > --- a/drivers/gpu/drm/nouveau/nouveau_display.h > > +++ b/drivers/gpu/drm/nouveau/nouveau_display.h > > @@ -71,8 +71,8 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); > > int nouveau_display_scanoutpos(struct drm_device *, unsigned int, > > unsigned int, int *, int *, ktime_t *, > > ktime_t *, const struct drm_display_mode *); > > -int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, > > - struct timeval *, unsigned); > > +bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, > > + struct timeval *, unsigned); > > > > int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, > > struct drm_pending_vblank_event *event, > > diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c > > index 312436a8d9e5..6d79b5c2805b 100644 > > --- a/drivers/gpu/drm/radeon/radeon_drv.c > > +++ b/drivers/gpu/drm/radeon/radeon_drv.c > > @@ -114,10 +114,10 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); > > u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); > > int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); > > void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); > > -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > > - int *max_error, > > - struct timeval *vblank_time, > > - unsigned flags); > > +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > > + int *max_error, > > + struct timeval *vblank_time, > > + unsigned flags); > > void radeon_driver_irq_preinstall_kms(struct drm_device *dev); > > int radeon_driver_irq_postinstall_kms(struct drm_device *dev); > > void radeon_driver_irq_uninstall_kms(struct drm_device *dev); > > diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c > > index a32a62e03a44..9afe72010c64 100644 > > --- a/drivers/gpu/drm/radeon/radeon_kms.c > > +++ b/drivers/gpu/drm/radeon/radeon_kms.c > > @@ -868,25 +868,25 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) > > * > > * Gets the timestamp on the requested crtc based on the > > * scanout position. (all asics). > > - * Returns postive status flags on success, negative error on failure. > > + * Returns true on success, false on failure. > > */ > > -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, > > - int *max_error, > > - struct timeval *vblank_time, > > - unsigned flags) > > +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, > > + int *max_error, > > + struct timeval *vblank_time, > > + unsigned flags) > > { > > struct drm_crtc *drmcrtc; > > struct radeon_device *rdev = dev->dev_private; > > > > if (crtc < 0 || crtc >= dev->num_crtcs) { > > DRM_ERROR("Invalid crtc %d\n", crtc); > > - return -EINVAL; > > + return false; > > } > > > > /* Get associated drm_crtc: */ > > drmcrtc = &rdev->mode_info.crtcs[crtc]->base; > > if (!drmcrtc) > > - return -EINVAL; > > + return false; > > > > /* Helper routine in DRM core does all the work: */ > > return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, > > diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c > > index 24edd0c22cc9..74260990b6bf 100644 > > --- a/drivers/gpu/drm/vc4/vc4_crtc.c > > +++ b/drivers/gpu/drm/vc4/vc4_crtc.c > > @@ -270,7 +270,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, > > return ret; > > } > > > > -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > > +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > > int *max_error, struct timeval *vblank_time, > > unsigned flags) > > { > > diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h > > index dffce6293d87..8a5d0e12ee02 100644 > > --- a/drivers/gpu/drm/vc4/vc4_drv.h > > +++ b/drivers/gpu/drm/vc4/vc4_drv.h > > @@ -450,7 +450,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, > > unsigned int flags, int *vpos, int *hpos, > > ktime_t *stime, ktime_t *etime, > > const struct drm_display_mode *mode); > > -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > > +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > > int *max_error, struct timeval *vblank_time, > > unsigned flags); > > > > diff --git a/include/drm/drmP.h b/include/drm/drmP.h > > index 27ecfcdbf752..6304de7e041e 100644 > > --- a/include/drm/drmP.h > > +++ b/include/drm/drmP.h > > @@ -322,7 +322,6 @@ struct pci_controller; > > > > /* Flags and return codes for get_vblank_timestamp() driver function. */ > > #define DRM_CALLED_FROM_VBLIRQ 1 > > -#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) > > > > /* get_scanout_position() return flags */ > > #define DRM_SCANOUTPOS_VALID (1 << 0) > > diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h > > index d0b5f363bfa1..da78e248d9d8 100644 > > --- a/include/drm/drm_drv.h > > +++ b/include/drm/drm_drv.h > > @@ -316,11 +316,10 @@ struct drm_driver { > > * > > * Returns: > > * > > - * Zero if timestamping isn't supported in current display mode or a > > - * negative number on failure. A positive status code on success, > > - * which describes how the vblank_time timestamp was computed. > > + * True on success, false on failure, which means the core should > > + * fallback to a simple timestamp taken in drm_crtc_handle_vblank(). > > */ > > - int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, > > + bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, > > int *max_error, > > struct timeval *vblank_time, > > unsigned flags); > > diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h > > index cf0be6594c8c..f0d5ccf9b282 100644 > > --- a/include/drm/drm_irq.h > > +++ b/include/drm/drm_irq.h > > @@ -153,11 +153,11 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc); > > void drm_vblank_cleanup(struct drm_device *dev); > > u32 drm_accurate_vblank_count(struct drm_crtc *crtc); > > > > -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > > - unsigned int pipe, int *max_error, > > - struct timeval *vblank_time, > > - unsigned flags, > > - const struct drm_display_mode *mode); > > +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > > + unsigned int pipe, int *max_error, > > + struct timeval *vblank_time, > > + unsigned flags, > > + const struct drm_display_mode *mode); > > void drm_calc_timestamping_constants(struct drm_crtc *crtc, > > const struct drm_display_mode *mode); > > -- > Jani Nikula, Intel Open Source Technology Center -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 19+ messages in thread
[parent not found: <20170322132305.zdtehgbox6erdhbq-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>]
* Re: [Intel-gfx] [PATCH 11/16] drm/vblank: Switch drm_driver->get_vblank_timestamp to return a bool [not found] ` <20170322132305.zdtehgbox6erdhbq-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org> @ 2017-03-22 14:05 ` Jani Nikula [not found] ` <87d1d98kzc.fsf-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> 0 siblings, 1 reply; 19+ messages in thread From: Jani Nikula @ 2017-03-22 14:05 UTC (permalink / raw) To: Daniel Vetter Cc: Daniel Vetter, Intel Graphics Development, DRI Development, Ben Skeggs, Mario Kleiner, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Alex Deucher, Daniel Vetter, freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Christian König On Wed, 22 Mar 2017, Daniel Vetter <daniel@ffwll.ch> wrote: > On Wed, Mar 22, 2017 at 12:33:35PM +0200, Jani Nikula wrote: >> On Wed, 22 Mar 2017, Daniel Vetter <daniel.vetter@ffwll.ch> wrote: >> > There's really no reason for anything more: >> > - Calling this while the crtc vblank stuff isn't set up is a driver >> > bug. Those places arlready DRM_ERROR. >> > - Calling this when the crtc is off is either a driver bug (callin >> > drm_crtc_handle_vblank at the wrong time) or a core bug (for >> > anything else). Again, we DRM_ERROR. >> > - EINVAL is checked at higher levels already, and if we'd use struct >> > drm_crtc * instead of (dev, pipe) it would be real obvious that >> > those are again core bugs. >> > >> > The only valid failure mode is crap hardware that couldn't sample a >> > useful timestamp, to ask the core to just grab a not-so-accurate >> > timestampe. Bool is perfectly fine for that. >> >> FWIW, I'm not all that thrilled about changing int returns to bools, >> because it changes the check for success from !ret to ret, and the >> compiler won't help you. Sure, there aren't many call sites for the >> function, but, case in point, you forgot to change that lone call >> site. Though it still works by coincidence. > > The old call site treated > 0 as success, and 0 or anything negative as > failure. That the lone caller still works is the reason why I've switched > to bool, because besides all the funny values that the caller gets and > ignreos, it already is. > > Or did I miss something? Don't you think you should fix the call site too, if you insist on changing the return type? BR, Jani. > -Daniel > >> >> BR, >> Jani. >> >> > >> > 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> >> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> >> > --- >> > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 +++---- >> > drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 14 ++++++------ >> > drivers/gpu/drm/drm_irq.c | 37 +++++++++++-------------------- >> > drivers/gpu/drm/i915/i915_irq.c | 8 +++---- >> > drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 12 +++++----- >> > drivers/gpu/drm/nouveau/nouveau_display.c | 4 ++-- >> > drivers/gpu/drm/nouveau/nouveau_display.h | 4 ++-- >> > drivers/gpu/drm/radeon/radeon_drv.c | 8 +++---- >> > drivers/gpu/drm/radeon/radeon_kms.c | 14 ++++++------ >> > drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- >> > drivers/gpu/drm/vc4/vc4_drv.h | 2 +- >> > include/drm/drmP.h | 1 - >> > include/drm/drm_drv.h | 7 +++--- >> > include/drm/drm_irq.h | 10 ++++----- >> > 14 files changed, 59 insertions(+), 72 deletions(-) >> > >> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h >> > index c8860f05bfb9..acd8631d8024 100644 >> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h >> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h >> > @@ -1768,10 +1768,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); >> > u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); >> > int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); >> > void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); >> > -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, >> > - int *max_error, >> > - struct timeval *vblank_time, >> > - unsigned flags); >> > +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, >> > + int *max_error, >> > + struct timeval *vblank_time, >> > + unsigned flags); >> > long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, >> > unsigned long arg); >> > >> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c >> > index 55f951bcc91f..ac42f707c046 100644 >> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c >> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c >> > @@ -838,19 +838,19 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) >> > * >> > * Gets the timestamp on the requested crtc based on the >> > * scanout position. (all asics). >> > - * Returns postive status flags on success, negative error on failure. >> > + * Returns true on success, false on failure. >> > */ >> > -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, >> > - int *max_error, >> > - struct timeval *vblank_time, >> > - unsigned flags) >> > +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, >> > + int *max_error, >> > + struct timeval *vblank_time, >> > + unsigned flags) >> > { >> > struct drm_crtc *crtc; >> > struct amdgpu_device *adev = dev->dev_private; >> > >> > if (pipe >= dev->num_crtcs) { >> > DRM_ERROR("Invalid crtc %u\n", pipe); >> > - return -EINVAL; >> > + return false; >> > } >> > >> > /* Get associated drm_crtc: */ >> > @@ -859,7 +859,7 @@ int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, >> > /* This can occur on driver load if some component fails to >> > * initialize completely and driver is unloaded */ >> > DRM_ERROR("Uninitialized crtc %d\n", pipe); >> > - return -EINVAL; >> > + return false; >> > } >> > >> > /* Helper routine in DRM core does all the work: */ >> > diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c >> > index 4b0c7475ed13..2121ea29e1b2 100644 >> > --- a/drivers/gpu/drm/drm_irq.c >> > +++ b/drivers/gpu/drm/drm_irq.c >> > @@ -722,43 +722,32 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); >> > * active. Higher level code is expected to handle this. >> > * >> > * Returns: >> > - * Negative value on error, failure or if not supported in current >> > - * video mode: >> > - * >> > - * -EINVAL Invalid CRTC. >> > - * -EAGAIN Temporary unavailable, e.g., called before initial modeset. >> > - * -ENOTSUPP Function not supported in current display mode. >> > - * -EIO Failed, e.g., due to failed scanout position query. >> > - * >> > - * Returns or'ed positive status flags on success: >> > - * >> > - * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. >> > - * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. >> > * >> > + * Returns true on success, and false on failure, i.e. when no accurate >> > + * timestamp could be acquired. >> > */ >> > -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, >> > - unsigned int pipe, >> > - int *max_error, >> > - struct timeval *vblank_time, >> > - unsigned flags, >> > - const struct drm_display_mode *mode) >> > +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, >> > + unsigned int pipe, >> > + int *max_error, >> > + struct timeval *vblank_time, >> > + unsigned flags, >> > + const struct drm_display_mode *mode) >> > { >> > struct timeval tv_etime; >> > ktime_t stime, etime; >> > unsigned int vbl_status; >> > - int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD; >> > int vpos, hpos, i; >> > int delta_ns, duration_ns; >> > >> > if (pipe >= dev->num_crtcs) { >> > DRM_ERROR("Invalid crtc %u\n", pipe); >> > - return -EINVAL; >> > + return false; >> > } >> > >> > /* Scanout position query not supported? Should not happen. */ >> > if (!dev->driver->get_scanout_position) { >> > DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); >> > - return -EIO; >> > + return false; >> > } >> > >> > /* If mode timing undefined, just return as no-op: >> > @@ -766,7 +755,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, >> > */ >> > if (mode->crtc_clock == 0) { >> > DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe); >> > - return -EAGAIN; >> > + return false; >> > } >> > >> > /* Get current scanout position with system timestamp. >> > @@ -790,7 +779,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, >> > if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { >> > DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", >> > pipe, vbl_status); >> > - return -EIO; >> > + return false; >> > } >> > >> > /* Compute uncertainty in timestamp of scanout position query. */ >> > @@ -834,7 +823,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, >> > (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, >> > duration_ns/1000, i); >> > >> > - return ret; >> > + return true; >> > } >> > EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); >> > >> > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c >> > index 26aa1c170b43..df149d159ce7 100644 >> > --- a/drivers/gpu/drm/i915/i915_irq.c >> > +++ b/drivers/gpu/drm/i915/i915_irq.c >> > @@ -964,7 +964,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) >> > return position; >> > } >> > >> > -static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, >> > +static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, >> > int *max_error, >> > struct timeval *vblank_time, >> > unsigned flags) >> > @@ -974,19 +974,19 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, >> > >> > if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { >> > DRM_ERROR("Invalid crtc %u\n", pipe); >> > - return -EINVAL; >> > + return false; >> > } >> > >> > /* Get drm_crtc to timestamp: */ >> > crtc = intel_get_crtc_for_pipe(dev_priv, pipe); >> > if (crtc == NULL) { >> > DRM_ERROR("Invalid crtc %u\n", pipe); >> > - return -EINVAL; >> > + return false; >> > } >> > >> > if (!crtc->base.hwmode.crtc_clock) { >> > DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); >> > - return -EBUSY; >> > + return false; >> > } >> > >> > /* Helper routine in DRM core does all the work: */ >> > diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c >> > index 41ccd2a15d3c..655700eb42ba 100644 >> > --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c >> > +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c >> > @@ -595,23 +595,23 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, >> > return ret; >> > } >> > >> > -static int mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, >> > - int *max_error, >> > - struct timeval *vblank_time, >> > - unsigned flags) >> > +static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, >> > + int *max_error, >> > + struct timeval *vblank_time, >> > + unsigned flags) >> > { >> > struct msm_drm_private *priv = dev->dev_private; >> > struct drm_crtc *crtc; >> > >> > if (pipe < 0 || pipe >= priv->num_crtcs) { >> > DRM_ERROR("Invalid crtc %d\n", pipe); >> > - return -EINVAL; >> > + return false; >> > } >> > >> > crtc = priv->crtcs[pipe]; >> > if (!crtc) { >> > DRM_ERROR("Invalid crtc %d\n", pipe); >> > - return -EINVAL; >> > + return false; >> > } >> > >> > return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, >> > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c >> > index 33269c7df30f..42f18b0b9c43 100644 >> > --- a/drivers/gpu/drm/nouveau/nouveau_display.c >> > +++ b/drivers/gpu/drm/nouveau/nouveau_display.c >> > @@ -156,7 +156,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, >> > return 0; >> > } >> > >> > -int >> > +bool >> > nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, >> > int *max_error, struct timeval *time, unsigned flags) >> > { >> > @@ -174,7 +174,7 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, >> > } >> > } >> > >> > - return -EINVAL; >> > + return false; >> > } >> > >> > static void >> > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h >> > index 4a75df06c139..bc9d1e7b0117 100644 >> > --- a/drivers/gpu/drm/nouveau/nouveau_display.h >> > +++ b/drivers/gpu/drm/nouveau/nouveau_display.h >> > @@ -71,8 +71,8 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); >> > int nouveau_display_scanoutpos(struct drm_device *, unsigned int, >> > unsigned int, int *, int *, ktime_t *, >> > ktime_t *, const struct drm_display_mode *); >> > -int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, >> > - struct timeval *, unsigned); >> > +bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, >> > + struct timeval *, unsigned); >> > >> > int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, >> > struct drm_pending_vblank_event *event, >> > diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c >> > index 312436a8d9e5..6d79b5c2805b 100644 >> > --- a/drivers/gpu/drm/radeon/radeon_drv.c >> > +++ b/drivers/gpu/drm/radeon/radeon_drv.c >> > @@ -114,10 +114,10 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); >> > u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); >> > int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); >> > void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); >> > -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, >> > - int *max_error, >> > - struct timeval *vblank_time, >> > - unsigned flags); >> > +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, >> > + int *max_error, >> > + struct timeval *vblank_time, >> > + unsigned flags); >> > void radeon_driver_irq_preinstall_kms(struct drm_device *dev); >> > int radeon_driver_irq_postinstall_kms(struct drm_device *dev); >> > void radeon_driver_irq_uninstall_kms(struct drm_device *dev); >> > diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c >> > index a32a62e03a44..9afe72010c64 100644 >> > --- a/drivers/gpu/drm/radeon/radeon_kms.c >> > +++ b/drivers/gpu/drm/radeon/radeon_kms.c >> > @@ -868,25 +868,25 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) >> > * >> > * Gets the timestamp on the requested crtc based on the >> > * scanout position. (all asics). >> > - * Returns postive status flags on success, negative error on failure. >> > + * Returns true on success, false on failure. >> > */ >> > -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, >> > - int *max_error, >> > - struct timeval *vblank_time, >> > - unsigned flags) >> > +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, >> > + int *max_error, >> > + struct timeval *vblank_time, >> > + unsigned flags) >> > { >> > struct drm_crtc *drmcrtc; >> > struct radeon_device *rdev = dev->dev_private; >> > >> > if (crtc < 0 || crtc >= dev->num_crtcs) { >> > DRM_ERROR("Invalid crtc %d\n", crtc); >> > - return -EINVAL; >> > + return false; >> > } >> > >> > /* Get associated drm_crtc: */ >> > drmcrtc = &rdev->mode_info.crtcs[crtc]->base; >> > if (!drmcrtc) >> > - return -EINVAL; >> > + return false; >> > >> > /* Helper routine in DRM core does all the work: */ >> > return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, >> > diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c >> > index 24edd0c22cc9..74260990b6bf 100644 >> > --- a/drivers/gpu/drm/vc4/vc4_crtc.c >> > +++ b/drivers/gpu/drm/vc4/vc4_crtc.c >> > @@ -270,7 +270,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, >> > return ret; >> > } >> > >> > -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, >> > +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, >> > int *max_error, struct timeval *vblank_time, >> > unsigned flags) >> > { >> > diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h >> > index dffce6293d87..8a5d0e12ee02 100644 >> > --- a/drivers/gpu/drm/vc4/vc4_drv.h >> > +++ b/drivers/gpu/drm/vc4/vc4_drv.h >> > @@ -450,7 +450,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, >> > unsigned int flags, int *vpos, int *hpos, >> > ktime_t *stime, ktime_t *etime, >> > const struct drm_display_mode *mode); >> > -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, >> > +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, >> > int *max_error, struct timeval *vblank_time, >> > unsigned flags); >> > >> > diff --git a/include/drm/drmP.h b/include/drm/drmP.h >> > index 27ecfcdbf752..6304de7e041e 100644 >> > --- a/include/drm/drmP.h >> > +++ b/include/drm/drmP.h >> > @@ -322,7 +322,6 @@ struct pci_controller; >> > >> > /* Flags and return codes for get_vblank_timestamp() driver function. */ >> > #define DRM_CALLED_FROM_VBLIRQ 1 >> > -#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) >> > >> > /* get_scanout_position() return flags */ >> > #define DRM_SCANOUTPOS_VALID (1 << 0) >> > diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h >> > index d0b5f363bfa1..da78e248d9d8 100644 >> > --- a/include/drm/drm_drv.h >> > +++ b/include/drm/drm_drv.h >> > @@ -316,11 +316,10 @@ struct drm_driver { >> > * >> > * Returns: >> > * >> > - * Zero if timestamping isn't supported in current display mode or a >> > - * negative number on failure. A positive status code on success, >> > - * which describes how the vblank_time timestamp was computed. >> > + * True on success, false on failure, which means the core should >> > + * fallback to a simple timestamp taken in drm_crtc_handle_vblank(). >> > */ >> > - int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, >> > + bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, >> > int *max_error, >> > struct timeval *vblank_time, >> > unsigned flags); >> > diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h >> > index cf0be6594c8c..f0d5ccf9b282 100644 >> > --- a/include/drm/drm_irq.h >> > +++ b/include/drm/drm_irq.h >> > @@ -153,11 +153,11 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc); >> > void drm_vblank_cleanup(struct drm_device *dev); >> > u32 drm_accurate_vblank_count(struct drm_crtc *crtc); >> > >> > -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, >> > - unsigned int pipe, int *max_error, >> > - struct timeval *vblank_time, >> > - unsigned flags, >> > - const struct drm_display_mode *mode); >> > +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, >> > + unsigned int pipe, int *max_error, >> > + struct timeval *vblank_time, >> > + unsigned flags, >> > + const struct drm_display_mode *mode); >> > void drm_calc_timestamping_constants(struct drm_crtc *crtc, >> > const struct drm_display_mode *mode); >> >> -- >> Jani Nikula, Intel Open Source Technology Center -- Jani Nikula, Intel Open Source Technology Center _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno ^ permalink raw reply [flat|nested] 19+ messages in thread
[parent not found: <87d1d98kzc.fsf-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>]
* Re: [Intel-gfx] [PATCH 11/16] drm/vblank: Switch drm_driver->get_vblank_timestamp to return a bool [not found] ` <87d1d98kzc.fsf-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> @ 2017-03-22 17:52 ` Daniel Vetter 0 siblings, 0 replies; 19+ messages in thread From: Daniel Vetter @ 2017-03-22 17:52 UTC (permalink / raw) To: Jani Nikula Cc: Mario Kleiner, Daniel Vetter, Intel Graphics Development, DRI Development, Ben Skeggs, Daniel Vetter, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Alex Deucher, Daniel Vetter, freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Christian König On Wed, Mar 22, 2017 at 04:05:59PM +0200, Jani Nikula wrote: > On Wed, 22 Mar 2017, Daniel Vetter <daniel@ffwll.ch> wrote: > > On Wed, Mar 22, 2017 at 12:33:35PM +0200, Jani Nikula wrote: > >> On Wed, 22 Mar 2017, Daniel Vetter <daniel.vetter@ffwll.ch> wrote: > >> > There's really no reason for anything more: > >> > - Calling this while the crtc vblank stuff isn't set up is a driver > >> > bug. Those places arlready DRM_ERROR. > >> > - Calling this when the crtc is off is either a driver bug (callin > >> > drm_crtc_handle_vblank at the wrong time) or a core bug (for > >> > anything else). Again, we DRM_ERROR. > >> > - EINVAL is checked at higher levels already, and if we'd use struct > >> > drm_crtc * instead of (dev, pipe) it would be real obvious that > >> > those are again core bugs. > >> > > >> > The only valid failure mode is crap hardware that couldn't sample a > >> > useful timestamp, to ask the core to just grab a not-so-accurate > >> > timestampe. Bool is perfectly fine for that. > >> > >> FWIW, I'm not all that thrilled about changing int returns to bools, > >> because it changes the check for success from !ret to ret, and the > >> compiler won't help you. Sure, there aren't many call sites for the > >> function, but, case in point, you forgot to change that lone call > >> site. Though it still works by coincidence. > > > > The old call site treated > 0 as success, and 0 or anything negative as > > failure. That the lone caller still works is the reason why I've switched > > to bool, because besides all the funny values that the caller gets and > > ignreos, it already is. > > > > Or did I miss something? > > Don't you think you should fix the call site too, if you insist on > changing the return type? Oops, I thought I've done that. Will fix up. -Daniel > > BR, > Jani. > > > > > > -Daniel > > > >> > >> BR, > >> Jani. > >> > >> > > >> > 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> > >> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> > >> > --- > >> > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 +++---- > >> > drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 14 ++++++------ > >> > drivers/gpu/drm/drm_irq.c | 37 +++++++++++-------------------- > >> > drivers/gpu/drm/i915/i915_irq.c | 8 +++---- > >> > drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 12 +++++----- > >> > drivers/gpu/drm/nouveau/nouveau_display.c | 4 ++-- > >> > drivers/gpu/drm/nouveau/nouveau_display.h | 4 ++-- > >> > drivers/gpu/drm/radeon/radeon_drv.c | 8 +++---- > >> > drivers/gpu/drm/radeon/radeon_kms.c | 14 ++++++------ > >> > drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- > >> > drivers/gpu/drm/vc4/vc4_drv.h | 2 +- > >> > include/drm/drmP.h | 1 - > >> > include/drm/drm_drv.h | 7 +++--- > >> > include/drm/drm_irq.h | 10 ++++----- > >> > 14 files changed, 59 insertions(+), 72 deletions(-) > >> > > >> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > >> > index c8860f05bfb9..acd8631d8024 100644 > >> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > >> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > >> > @@ -1768,10 +1768,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); > >> > u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); > >> > int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); > >> > void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); > >> > -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > >> > - int *max_error, > >> > - struct timeval *vblank_time, > >> > - unsigned flags); > >> > +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > >> > + int *max_error, > >> > + struct timeval *vblank_time, > >> > + unsigned flags); > >> > long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, > >> > unsigned long arg); > >> > > >> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > >> > index 55f951bcc91f..ac42f707c046 100644 > >> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > >> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > >> > @@ -838,19 +838,19 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) > >> > * > >> > * Gets the timestamp on the requested crtc based on the > >> > * scanout position. (all asics). > >> > - * Returns postive status flags on success, negative error on failure. > >> > + * Returns true on success, false on failure. > >> > */ > >> > -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > >> > - int *max_error, > >> > - struct timeval *vblank_time, > >> > - unsigned flags) > >> > +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > >> > + int *max_error, > >> > + struct timeval *vblank_time, > >> > + unsigned flags) > >> > { > >> > struct drm_crtc *crtc; > >> > struct amdgpu_device *adev = dev->dev_private; > >> > > >> > if (pipe >= dev->num_crtcs) { > >> > DRM_ERROR("Invalid crtc %u\n", pipe); > >> > - return -EINVAL; > >> > + return false; > >> > } > >> > > >> > /* Get associated drm_crtc: */ > >> > @@ -859,7 +859,7 @@ int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > >> > /* This can occur on driver load if some component fails to > >> > * initialize completely and driver is unloaded */ > >> > DRM_ERROR("Uninitialized crtc %d\n", pipe); > >> > - return -EINVAL; > >> > + return false; > >> > } > >> > > >> > /* Helper routine in DRM core does all the work: */ > >> > diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c > >> > index 4b0c7475ed13..2121ea29e1b2 100644 > >> > --- a/drivers/gpu/drm/drm_irq.c > >> > +++ b/drivers/gpu/drm/drm_irq.c > >> > @@ -722,43 +722,32 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); > >> > * active. Higher level code is expected to handle this. > >> > * > >> > * Returns: > >> > - * Negative value on error, failure or if not supported in current > >> > - * video mode: > >> > - * > >> > - * -EINVAL Invalid CRTC. > >> > - * -EAGAIN Temporary unavailable, e.g., called before initial modeset. > >> > - * -ENOTSUPP Function not supported in current display mode. > >> > - * -EIO Failed, e.g., due to failed scanout position query. > >> > - * > >> > - * Returns or'ed positive status flags on success: > >> > - * > >> > - * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. > >> > - * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. > >> > * > >> > + * Returns true on success, and false on failure, i.e. when no accurate > >> > + * timestamp could be acquired. > >> > */ > >> > -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > >> > - unsigned int pipe, > >> > - int *max_error, > >> > - struct timeval *vblank_time, > >> > - unsigned flags, > >> > - const struct drm_display_mode *mode) > >> > +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > >> > + unsigned int pipe, > >> > + int *max_error, > >> > + struct timeval *vblank_time, > >> > + unsigned flags, > >> > + const struct drm_display_mode *mode) > >> > { > >> > struct timeval tv_etime; > >> > ktime_t stime, etime; > >> > unsigned int vbl_status; > >> > - int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD; > >> > int vpos, hpos, i; > >> > int delta_ns, duration_ns; > >> > > >> > if (pipe >= dev->num_crtcs) { > >> > DRM_ERROR("Invalid crtc %u\n", pipe); > >> > - return -EINVAL; > >> > + return false; > >> > } > >> > > >> > /* Scanout position query not supported? Should not happen. */ > >> > if (!dev->driver->get_scanout_position) { > >> > DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); > >> > - return -EIO; > >> > + return false; > >> > } > >> > > >> > /* If mode timing undefined, just return as no-op: > >> > @@ -766,7 +755,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > >> > */ > >> > if (mode->crtc_clock == 0) { > >> > DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe); > >> > - return -EAGAIN; > >> > + return false; > >> > } > >> > > >> > /* Get current scanout position with system timestamp. > >> > @@ -790,7 +779,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > >> > if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { > >> > DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", > >> > pipe, vbl_status); > >> > - return -EIO; > >> > + return false; > >> > } > >> > > >> > /* Compute uncertainty in timestamp of scanout position query. */ > >> > @@ -834,7 +823,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > >> > (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, > >> > duration_ns/1000, i); > >> > > >> > - return ret; > >> > + return true; > >> > } > >> > EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); > >> > > >> > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > >> > index 26aa1c170b43..df149d159ce7 100644 > >> > --- a/drivers/gpu/drm/i915/i915_irq.c > >> > +++ b/drivers/gpu/drm/i915/i915_irq.c > >> > @@ -964,7 +964,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) > >> > return position; > >> > } > >> > > >> > -static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > >> > +static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > >> > int *max_error, > >> > struct timeval *vblank_time, > >> > unsigned flags) > >> > @@ -974,19 +974,19 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > >> > > >> > if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { > >> > DRM_ERROR("Invalid crtc %u\n", pipe); > >> > - return -EINVAL; > >> > + return false; > >> > } > >> > > >> > /* Get drm_crtc to timestamp: */ > >> > crtc = intel_get_crtc_for_pipe(dev_priv, pipe); > >> > if (crtc == NULL) { > >> > DRM_ERROR("Invalid crtc %u\n", pipe); > >> > - return -EINVAL; > >> > + return false; > >> > } > >> > > >> > if (!crtc->base.hwmode.crtc_clock) { > >> > DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); > >> > - return -EBUSY; > >> > + return false; > >> > } > >> > > >> > /* Helper routine in DRM core does all the work: */ > >> > diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > >> > index 41ccd2a15d3c..655700eb42ba 100644 > >> > --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > >> > +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > >> > @@ -595,23 +595,23 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, > >> > return ret; > >> > } > >> > > >> > -static int mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > >> > - int *max_error, > >> > - struct timeval *vblank_time, > >> > - unsigned flags) > >> > +static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > >> > + int *max_error, > >> > + struct timeval *vblank_time, > >> > + unsigned flags) > >> > { > >> > struct msm_drm_private *priv = dev->dev_private; > >> > struct drm_crtc *crtc; > >> > > >> > if (pipe < 0 || pipe >= priv->num_crtcs) { > >> > DRM_ERROR("Invalid crtc %d\n", pipe); > >> > - return -EINVAL; > >> > + return false; > >> > } > >> > > >> > crtc = priv->crtcs[pipe]; > >> > if (!crtc) { > >> > DRM_ERROR("Invalid crtc %d\n", pipe); > >> > - return -EINVAL; > >> > + return false; > >> > } > >> > > >> > return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, > >> > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c > >> > index 33269c7df30f..42f18b0b9c43 100644 > >> > --- a/drivers/gpu/drm/nouveau/nouveau_display.c > >> > +++ b/drivers/gpu/drm/nouveau/nouveau_display.c > >> > @@ -156,7 +156,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, > >> > return 0; > >> > } > >> > > >> > -int > >> > +bool > >> > nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, > >> > int *max_error, struct timeval *time, unsigned flags) > >> > { > >> > @@ -174,7 +174,7 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, > >> > } > >> > } > >> > > >> > - return -EINVAL; > >> > + return false; > >> > } > >> > > >> > static void > >> > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h > >> > index 4a75df06c139..bc9d1e7b0117 100644 > >> > --- a/drivers/gpu/drm/nouveau/nouveau_display.h > >> > +++ b/drivers/gpu/drm/nouveau/nouveau_display.h > >> > @@ -71,8 +71,8 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); > >> > int nouveau_display_scanoutpos(struct drm_device *, unsigned int, > >> > unsigned int, int *, int *, ktime_t *, > >> > ktime_t *, const struct drm_display_mode *); > >> > -int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, > >> > - struct timeval *, unsigned); > >> > +bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, > >> > + struct timeval *, unsigned); > >> > > >> > int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, > >> > struct drm_pending_vblank_event *event, > >> > diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c > >> > index 312436a8d9e5..6d79b5c2805b 100644 > >> > --- a/drivers/gpu/drm/radeon/radeon_drv.c > >> > +++ b/drivers/gpu/drm/radeon/radeon_drv.c > >> > @@ -114,10 +114,10 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); > >> > u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); > >> > int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); > >> > void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); > >> > -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > >> > - int *max_error, > >> > - struct timeval *vblank_time, > >> > - unsigned flags); > >> > +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > >> > + int *max_error, > >> > + struct timeval *vblank_time, > >> > + unsigned flags); > >> > void radeon_driver_irq_preinstall_kms(struct drm_device *dev); > >> > int radeon_driver_irq_postinstall_kms(struct drm_device *dev); > >> > void radeon_driver_irq_uninstall_kms(struct drm_device *dev); > >> > diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c > >> > index a32a62e03a44..9afe72010c64 100644 > >> > --- a/drivers/gpu/drm/radeon/radeon_kms.c > >> > +++ b/drivers/gpu/drm/radeon/radeon_kms.c > >> > @@ -868,25 +868,25 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) > >> > * > >> > * Gets the timestamp on the requested crtc based on the > >> > * scanout position. (all asics). > >> > - * Returns postive status flags on success, negative error on failure. > >> > + * Returns true on success, false on failure. > >> > */ > >> > -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, > >> > - int *max_error, > >> > - struct timeval *vblank_time, > >> > - unsigned flags) > >> > +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, > >> > + int *max_error, > >> > + struct timeval *vblank_time, > >> > + unsigned flags) > >> > { > >> > struct drm_crtc *drmcrtc; > >> > struct radeon_device *rdev = dev->dev_private; > >> > > >> > if (crtc < 0 || crtc >= dev->num_crtcs) { > >> > DRM_ERROR("Invalid crtc %d\n", crtc); > >> > - return -EINVAL; > >> > + return false; > >> > } > >> > > >> > /* Get associated drm_crtc: */ > >> > drmcrtc = &rdev->mode_info.crtcs[crtc]->base; > >> > if (!drmcrtc) > >> > - return -EINVAL; > >> > + return false; > >> > > >> > /* Helper routine in DRM core does all the work: */ > >> > return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, > >> > diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c > >> > index 24edd0c22cc9..74260990b6bf 100644 > >> > --- a/drivers/gpu/drm/vc4/vc4_crtc.c > >> > +++ b/drivers/gpu/drm/vc4/vc4_crtc.c > >> > @@ -270,7 +270,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, > >> > return ret; > >> > } > >> > > >> > -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > >> > +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > >> > int *max_error, struct timeval *vblank_time, > >> > unsigned flags) > >> > { > >> > diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h > >> > index dffce6293d87..8a5d0e12ee02 100644 > >> > --- a/drivers/gpu/drm/vc4/vc4_drv.h > >> > +++ b/drivers/gpu/drm/vc4/vc4_drv.h > >> > @@ -450,7 +450,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, > >> > unsigned int flags, int *vpos, int *hpos, > >> > ktime_t *stime, ktime_t *etime, > >> > const struct drm_display_mode *mode); > >> > -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > >> > +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > >> > int *max_error, struct timeval *vblank_time, > >> > unsigned flags); > >> > > >> > diff --git a/include/drm/drmP.h b/include/drm/drmP.h > >> > index 27ecfcdbf752..6304de7e041e 100644 > >> > --- a/include/drm/drmP.h > >> > +++ b/include/drm/drmP.h > >> > @@ -322,7 +322,6 @@ struct pci_controller; > >> > > >> > /* Flags and return codes for get_vblank_timestamp() driver function. */ > >> > #define DRM_CALLED_FROM_VBLIRQ 1 > >> > -#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) > >> > > >> > /* get_scanout_position() return flags */ > >> > #define DRM_SCANOUTPOS_VALID (1 << 0) > >> > diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h > >> > index d0b5f363bfa1..da78e248d9d8 100644 > >> > --- a/include/drm/drm_drv.h > >> > +++ b/include/drm/drm_drv.h > >> > @@ -316,11 +316,10 @@ struct drm_driver { > >> > * > >> > * Returns: > >> > * > >> > - * Zero if timestamping isn't supported in current display mode or a > >> > - * negative number on failure. A positive status code on success, > >> > - * which describes how the vblank_time timestamp was computed. > >> > + * True on success, false on failure, which means the core should > >> > + * fallback to a simple timestamp taken in drm_crtc_handle_vblank(). > >> > */ > >> > - int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, > >> > + bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, > >> > int *max_error, > >> > struct timeval *vblank_time, > >> > unsigned flags); > >> > diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h > >> > index cf0be6594c8c..f0d5ccf9b282 100644 > >> > --- a/include/drm/drm_irq.h > >> > +++ b/include/drm/drm_irq.h > >> > @@ -153,11 +153,11 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc); > >> > void drm_vblank_cleanup(struct drm_device *dev); > >> > u32 drm_accurate_vblank_count(struct drm_crtc *crtc); > >> > > >> > -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > >> > - unsigned int pipe, int *max_error, > >> > - struct timeval *vblank_time, > >> > - unsigned flags, > >> > - const struct drm_display_mode *mode); > >> > +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > >> > + unsigned int pipe, int *max_error, > >> > + struct timeval *vblank_time, > >> > + unsigned flags, > >> > + const struct drm_display_mode *mode); > >> > void drm_calc_timestamping_constants(struct drm_crtc *crtc, > >> > const struct drm_display_mode *mode); > >> > >> -- > >> Jani Nikula, Intel Open Source Technology Center > > -- > Jani Nikula, Intel Open Source Technology Center -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH] drm/vblank: Switch drm_driver->get_vblank_timestamp to return a bool 2017-03-22 8:36 ` [PATCH 11/16] drm/vblank: Switch drm_driver->get_vblank_timestamp to return a bool Daniel Vetter [not found] ` <20170322083617.13361-12-daniel.vetter-/w4YWyX8dFk@public.gmane.org> @ 2017-03-22 20:55 ` Daniel Vetter 1 sibling, 0 replies; 19+ messages in thread From: Daniel Vetter @ 2017-03-22 20:55 UTC (permalink / raw) To: Intel Graphics Development Cc: Daniel Vetter, DRI Development, Mario Kleiner, linux-arm-msm, Alex Deucher, Daniel Vetter, freedreno, Christian König, Ben Skeggs There's really no reason for anything more: - Calling this while the crtc vblank stuff isn't set up is a driver bug. Those places arlready DRM_ERROR. - Calling this when the crtc is off is either a driver bug (callin drm_crtc_handle_vblank at the wrong time) or a core bug (for anything else). Again, we DRM_ERROR. - EINVAL is checked at higher levels already, and if we'd use struct drm_crtc * instead of (dev, pipe) it would be real obvious that those are again core bugs. The only valid failure mode is crap hardware that couldn't sample a useful timestamp, to ask the core to just grab a not-so-accurate timestampe. Bool is perfectly fine for that. v2: Also fix up the one caller, I lost that in the shuffling (Jani). Cc: Jani Nikula <jani.nikula@linux.intel.com> 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> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 ++--- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 14 ++++----- drivers/gpu/drm/drm_irq.c | 49 ++++++++++++------------------- drivers/gpu/drm/i915/i915_irq.c | 8 ++--- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 12 ++++---- drivers/gpu/drm/nouveau/nouveau_display.c | 4 +-- drivers/gpu/drm/nouveau/nouveau_display.h | 4 +-- drivers/gpu/drm/radeon/radeon_drv.c | 8 ++--- drivers/gpu/drm/radeon/radeon_kms.c | 14 ++++----- drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- include/drm/drmP.h | 1 - include/drm/drm_drv.h | 7 ++--- include/drm/drm_irq.h | 10 +++---- 14 files changed, 64 insertions(+), 79 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index c8860f05bfb9..acd8631d8024 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1768,10 +1768,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags); +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags); long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 55f951bcc91f..ac42f707c046 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -838,19 +838,19 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) * * Gets the timestamp on the requested crtc based on the * scanout position. (all asics). - * Returns postive status flags on success, negative error on failure. + * Returns true on success, false on failure. */ -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags) +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags) { struct drm_crtc *crtc; struct amdgpu_device *adev = dev->dev_private; if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; } /* Get associated drm_crtc: */ @@ -859,7 +859,7 @@ int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, /* This can occur on driver load if some component fails to * initialize completely and driver is unloaded */ DRM_ERROR("Uninitialized crtc %d\n", pipe); - return -EINVAL; + return false; } /* Helper routine in DRM core does all the work: */ diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 4b0c7475ed13..0996e6091bf9 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -722,43 +722,32 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * active. Higher level code is expected to handle this. * * Returns: - * Negative value on error, failure or if not supported in current - * video mode: - * - * -EINVAL Invalid CRTC. - * -EAGAIN Temporary unavailable, e.g., called before initial modeset. - * -ENOTSUPP Function not supported in current display mode. - * -EIO Failed, e.g., due to failed scanout position query. - * - * Returns or'ed positive status flags on success: - * - * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. - * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. * + * Returns true on success, and false on failure, i.e. when no accurate + * timestamp could be acquired. */ -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, - unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags, - const struct drm_display_mode *mode) +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, + unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags, + const struct drm_display_mode *mode) { struct timeval tv_etime; ktime_t stime, etime; unsigned int vbl_status; - int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD; int vpos, hpos, i; int delta_ns, duration_ns; if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; } /* Scanout position query not supported? Should not happen. */ if (!dev->driver->get_scanout_position) { DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); - return -EIO; + return false; } /* If mode timing undefined, just return as no-op: @@ -766,7 +755,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, */ if (mode->crtc_clock == 0) { DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe); - return -EAGAIN; + return false; } /* Get current scanout position with system timestamp. @@ -790,7 +779,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", pipe, vbl_status); - return -EIO; + return false; } /* Compute uncertainty in timestamp of scanout position query. */ @@ -834,7 +823,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, duration_ns/1000, i); - return ret; + return true; } EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); @@ -870,25 +859,23 @@ static bool drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, struct timeval *tvblank, unsigned flags) { - int ret; + bool ret = false; /* Define requested maximum error on timestamps (nanoseconds). */ int max_error = (int) drm_timestamp_precision * 1000; /* Query driver if possible and precision timestamping enabled. */ - if (dev->driver->get_vblank_timestamp && (max_error > 0)) { + if (dev->driver->get_vblank_timestamp && (max_error > 0)) ret = dev->driver->get_vblank_timestamp(dev, pipe, &max_error, tvblank, flags); - if (ret > 0) - return true; - } /* GPU high precision timestamp query unsupported or failed. * Return current monotonic/gettimeofday timestamp as best estimate. */ - *tvblank = get_drm_timestamp(); + if (!ret) + *tvblank = get_drm_timestamp(); - return false; + return ret; } /** diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 26aa1c170b43..df149d159ce7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -964,7 +964,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) return position; } -static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, +static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags) @@ -974,19 +974,19 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; } /* Get drm_crtc to timestamp: */ crtc = intel_get_crtc_for_pipe(dev_priv, pipe); if (crtc == NULL) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; } if (!crtc->base.hwmode.crtc_clock) { DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); - return -EBUSY; + return false; } /* Helper routine in DRM core does all the work: */ diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 41ccd2a15d3c..655700eb42ba 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -595,23 +595,23 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, return ret; } -static int mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags) +static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags) { struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc; if (pipe < 0 || pipe >= priv->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", pipe); - return -EINVAL; + return false; } crtc = priv->crtcs[pipe]; if (!crtc) { DRM_ERROR("Invalid crtc %d\n", pipe); - return -EINVAL; + return false; } return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 33269c7df30f..42f18b0b9c43 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -156,7 +156,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, return 0; } -int +bool nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *time, unsigned flags) { @@ -174,7 +174,7 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, } } - return -EINVAL; + return false; } static void diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 4a75df06c139..bc9d1e7b0117 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -71,8 +71,8 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); -int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, - struct timeval *, unsigned); +bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, + struct timeval *, unsigned); int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 312436a8d9e5..6d79b5c2805b 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,10 +114,10 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags); +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags); void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index a32a62e03a44..9afe72010c64 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -868,25 +868,25 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) * * Gets the timestamp on the requested crtc based on the * scanout position. (all asics). - * Returns postive status flags on success, negative error on failure. + * Returns true on success, false on failure. */ -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, - int *max_error, - struct timeval *vblank_time, - unsigned flags) +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, + int *max_error, + struct timeval *vblank_time, + unsigned flags) { struct drm_crtc *drmcrtc; struct radeon_device *rdev = dev->dev_private; if (crtc < 0 || crtc >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", crtc); - return -EINVAL; + return false; } /* Get associated drm_crtc: */ drmcrtc = &rdev->mode_info.crtcs[crtc]->base; if (!drmcrtc) - return -EINVAL; + return false; /* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 24edd0c22cc9..74260990b6bf 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -270,7 +270,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, return ret; } -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags) { diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index dffce6293d87..8a5d0e12ee02 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -450,7 +450,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 27ecfcdbf752..6304de7e041e 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -322,7 +322,6 @@ struct pci_controller; /* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 -#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) /* get_scanout_position() return flags */ #define DRM_SCANOUTPOS_VALID (1 << 0) diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index d0b5f363bfa1..da78e248d9d8 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -316,11 +316,10 @@ struct drm_driver { * * Returns: * - * Zero if timestamping isn't supported in current display mode or a - * negative number on failure. A positive status code on success, - * which describes how the vblank_time timestamp was computed. + * True on success, false on failure, which means the core should + * fallback to a simple timestamp taken in drm_crtc_handle_vblank(). */ - int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, + bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags); diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index cf0be6594c8c..f0d5ccf9b282 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -153,11 +153,11 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc); void drm_vblank_cleanup(struct drm_device *dev); u32 drm_accurate_vblank_count(struct drm_crtc *crtc); -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, - unsigned int pipe, int *max_error, - struct timeval *vblank_time, - unsigned flags, - const struct drm_display_mode *mode); +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, + unsigned int pipe, int *max_error, + struct timeval *vblank_time, + unsigned flags, + const struct drm_display_mode *mode); void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode); -- 2.11.0 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 15/16] drm/vblank: Simplify the get_scanout_position helper hook [not found] ` <20170322083617.13361-1-daniel.vetter-/w4YWyX8dFk@public.gmane.org> 2017-03-22 8:36 ` [PATCH 11/16] drm/vblank: Switch drm_driver->get_vblank_timestamp to return a bool Daniel Vetter @ 2017-03-22 8:36 ` Daniel Vetter 2017-03-24 21:28 ` [PATCH] drm/vblank: fix boolreturn.cocci warnings kbuild test robot ` (2 more replies) 1 sibling, 3 replies; 19+ messages in thread From: Daniel Vetter @ 2017-03-22 8:36 UTC (permalink / raw) To: Intel Graphics Development Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, DRI Development, Eric Anholt, Rob Clark, Ben Skeggs, Mario Kleiner, Daniel Vetter, Alex Deucher, Daniel Vetter, freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Christian König - We can drop the different return value flags, the only caller only cares about whether the scanout position is valid or not. Also, it's entirely undefined what "accurate" means, if we'd really care we should probably wire the max_error through. But since we never even report this to userspace it's kinda moot. - Drop all the fancy input flags, there's really only the "called from vblank irq" one. Well except for radeon/amdgpu, which added their own private flags. Since amdgpu/radoen also use the scanoutposition function internally I just gave them a tiny wrapper, plus copies of all the old #defines they need. Everyone else gets simplified code. Note how we could remove a lot of error conditions if we'd move this helper hook to drm_crtc_helper_funcs and would pass it a crtc directly. v2: Make it compile on arm. 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> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 12 +++++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 3 +++ drivers/gpu/drm/drm_irq.c | 16 ++++++++-------- drivers/gpu/drm/i915/i915_irq.c | 19 ++++++------------- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 19 +++++++------------ drivers/gpu/drm/nouveau/nouveau_display.c | 16 +++++++--------- drivers/gpu/drm/nouveau/nouveau_display.h | 6 +++--- drivers/gpu/drm/radeon/radeon_drv.c | 12 +++++++++++- drivers/gpu/drm/radeon/radeon_mode.h | 3 +++ drivers/gpu/drm/vc4/vc4_crtc.c | 21 ++++++++++----------- drivers/gpu/drm/vc4/vc4_drv.h | 8 ++++---- include/drm/drmP.h | 8 -------- include/drm/drm_drv.h | 26 ++++++++++---------------- 13 files changed, 83 insertions(+), 86 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index ba169a0699d5..87910850e5dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -678,6 +678,16 @@ static const struct file_operations amdgpu_driver_kms_fops = { #endif }; +static bool +amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +{ + return amdgpu_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos, + stime, etime, mode); +} + static struct drm_driver kms_driver = { .driver_features = DRIVER_USE_AGP | @@ -693,7 +703,7 @@ static struct drm_driver kms_driver = { .enable_vblank = amdgpu_enable_vblank_kms, .disable_vblank = amdgpu_disable_vblank_kms, .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, - .get_scanout_position = amdgpu_get_crtc_scanoutpos, + .get_scanout_position = amdgpu_get_crtc_scanout_position, #if defined(CONFIG_DEBUG_FS) .debugfs_init = amdgpu_debugfs_init, #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index c12497bd3889..6b8f766a6a35 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 { ((em) == ATOM_ENCODER_MODE_DP_MST)) /* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */ +#define DRM_SCANOUTPOS_VALID (1 << 0) +#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) +#define DRM_SCANOUTPOS_ACCURATE (1 << 2) #define USE_REAL_VBLANKSTART (1 << 30) #define GET_DISTANCE_TO_VBLANKSTART (1 << 31) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 61d726b1f810..00e26b4312cc 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -744,13 +744,12 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, { struct timeval tv_etime; ktime_t stime, etime; - unsigned int vbl_status; + bool vbl_status; struct drm_crtc *crtc; const struct drm_display_mode *mode; struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; int vpos, hpos, i; int delta_ns, duration_ns; - unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return false; @@ -793,15 +792,16 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, * Get vertical and horizontal scanout position vpos, hpos, * and bounding timestamps stime, etime, pre/post query. */ - vbl_status = dev->driver->get_scanout_position(dev, pipe, flags, + vbl_status = dev->driver->get_scanout_position(dev, pipe, + in_vblank_irq, &vpos, &hpos, &stime, &etime, mode); /* Return as no-op if scanout query unsupported or failed. */ - if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { - DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", - pipe, vbl_status); + if (!vbl_status) { + DRM_DEBUG("crtc %u : scanoutpos query failed.\n", + pipe); return false; } @@ -840,8 +840,8 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, etime = ktime_sub_ns(etime, delta_ns); *vblank_time = ktime_to_timeval(etime); - DRM_DEBUG_VBL("crtc %u : v 0x%x p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", - pipe, vbl_status, hpos, vpos, + DRM_DEBUG_VBL("crtc %u : v p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", + pipe, hpos, vpos, (long)tv_etime.tv_sec, (long)tv_etime.tv_usec, (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, duration_ns/1000, i); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index feadfea77354..a211f9d2e6ca 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -827,10 +827,10 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) return (position + crtc->scanline_offset) % vtotal; } -static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv, @@ -838,13 +838,12 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, int position; int vbl_start, vbl_end, hsync_start, htotal, vtotal; bool in_vbl = true; - int ret = 0; unsigned long irqflags; if (WARN_ON(!mode->crtc_clock)) { DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " "pipe %c\n", pipe_name(pipe)); - return 0; + return false; } htotal = mode->crtc_htotal; @@ -859,8 +858,6 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, vtotal /= 2; } - ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; - /* * Lock uncore.lock, as we will do multiple timing critical raw * register reads, potentially with preemption disabled, so the @@ -944,11 +941,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, *hpos = position - (*vpos * htotal); } - /* In vblank? */ - if (in_vbl) - ret |= DRM_SCANOUTPOS_IN_VBLANK; - - return ret; + return true; } int intel_get_crtc_scanline(struct intel_crtc *crtc) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 6ba216b8bba9..959b826123a2 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -530,31 +530,28 @@ static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc) return NULL; } -static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +static bool mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc; struct drm_encoder *encoder; int line, vsw, vbp, vactive_start, vactive_end, vfp_end; - int ret = 0; crtc = priv->crtcs[pipe]; if (!crtc) { DRM_ERROR("Invalid crtc %d\n", pipe); - return 0; + return false; } encoder = get_encoder_from_crtc(crtc); if (!encoder) { DRM_ERROR("no encoder found for crtc %d\n", pipe); - return 0; + return false; } - ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; - vsw = mode->crtc_vsync_end - mode->crtc_vsync_start; vbp = mode->crtc_vtotal - mode->crtc_vsync_end; @@ -578,10 +575,8 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, if (line < vactive_start) { line -= vactive_start; - ret |= DRM_SCANOUTPOS_IN_VBLANK; } else if (line > vactive_end) { line = line - vfp_end - vactive_start; - ret |= DRM_SCANOUTPOS_IN_VBLANK; } else { line -= vactive_start; } @@ -592,7 +587,7 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, if (etime) *etime = ktime_get(); - return ret; + return true; } static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index e4bdac13d4e9..8b3622afa530 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -98,7 +98,7 @@ calc(int blanks, int blanke, int total, int line) return line; } -static int +static bool nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) { @@ -111,16 +111,16 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, }; struct nouveau_display *disp = nouveau_display(crtc->dev); struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)]; - int ret, retry = 1; + int retry = 1; + bool ret = false; do { ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args)); if (ret != 0) - return 0; + return false; if (args.scan.vline) { - ret |= DRM_SCANOUTPOS_ACCURATE; - ret |= DRM_SCANOUTPOS_VALID; + ret = true; break; } @@ -133,14 +133,12 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, if (stime) *stime = ns_to_ktime(args.scan.time[0]); if (etime) *etime = ns_to_ktime(args.scan.time[1]); - if (*vpos < 0) - ret |= DRM_SCANOUTPOS_IN_VBLANK; return ret; } -int +bool nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, + bool in_vblank_irq, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode) { diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 8360a85ed5ef..b76b65c7c8da 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -68,9 +68,9 @@ int nouveau_display_suspend(struct drm_device *dev, bool runtime); void nouveau_display_resume(struct drm_device *dev, bool runtime); int nouveau_display_vblank_enable(struct drm_device *, unsigned int); void nouveau_display_vblank_disable(struct drm_device *, unsigned int); -int nouveau_display_scanoutpos(struct drm_device *, unsigned int, - unsigned int, int *, int *, ktime_t *, - ktime_t *, const struct drm_display_mode *); +bool nouveau_display_scanoutpos(struct drm_device *, unsigned int, + bool, int *, int *, ktime_t *, + ktime_t *, const struct drm_display_mode *); int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index a4bf09cd33f7..669ebfda8038 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -525,6 +525,16 @@ static const struct file_operations radeon_driver_kms_fops = { #endif }; +static bool +radeon_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +{ + return radeon_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos, + stime, etime, mode); +} + static struct drm_driver kms_driver = { .driver_features = DRIVER_USE_AGP | @@ -540,7 +550,7 @@ static struct drm_driver kms_driver = { .enable_vblank = radeon_enable_vblank_kms, .disable_vblank = radeon_disable_vblank_kms, .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, - .get_scanout_position = radeon_get_crtc_scanoutpos, + .get_scanout_position = radeon_get_crtc_scanout_position, .irq_preinstall = radeon_driver_irq_preinstall_kms, .irq_postinstall = radeon_driver_irq_postinstall_kms, .irq_uninstall = radeon_driver_irq_uninstall_kms, diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index ad282648fc8b..00f5ec5c12c7 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -691,6 +691,9 @@ struct atom_voltage_table }; /* Driver internal use only flags of radeon_get_crtc_scanoutpos() */ +#define DRM_SCANOUTPOS_VALID (1 << 0) +#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) +#define DRM_SCANOUTPOS_ACCURATE (1 << 2) #define USE_REAL_VBLANKSTART (1 << 30) #define GET_DISTANCE_TO_VBLANKSTART (1 << 31) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 2567d6c9a4ee..e871862a21b8 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -151,10 +151,10 @@ int vc4_crtc_debugfs_regs(struct seq_file *m, void *unused) } #endif -int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { struct vc4_dev *vc4 = to_vc4_dev(dev); struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); @@ -162,7 +162,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, u32 val; int fifo_lines; int vblank_lines; - int ret = 0; + bool ret = false; /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ @@ -198,7 +198,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, fifo_lines = vc4_crtc->cob_size / mode->crtc_hdisplay; if (fifo_lines > 0) - ret |= DRM_SCANOUTPOS_VALID; + ret = true; /* HVS more than fifo_lines into frame for compositing? */ if (*vpos > fifo_lines) { @@ -216,7 +216,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, */ *vpos -= fifo_lines + 1; - ret |= DRM_SCANOUTPOS_ACCURATE; return ret; } @@ -229,10 +228,9 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, * We can't get meaningful readings wrt. scanline position of the PV * and need to make things up in a approximative but consistent way. */ - ret |= DRM_SCANOUTPOS_IN_VBLANK; vblank_lines = mode->vtotal - mode->vdisplay; - if (flags & DRM_CALLED_FROM_VBLIRQ) { + if (in_vblank_irq) { /* * Assume the irq handler got called close to first * line of vblank, so PV has about a full vblank @@ -254,9 +252,10 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, * we are at the very beginning of vblank, as the hvs just * started refilling, and the stime and etime timestamps * truly correspond to start of vblank. + * + * Unfortunately there's no way to report this to upper levels + * and make it more useful. */ - if ((val & SCALER_DISPSTATX_FULL) != SCALER_DISPSTATX_FULL) - ret |= DRM_SCANOUTPOS_ACCURATE; } else { /* * No clue where we are inside vblank. Return a vpos of zero, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 64c92e0eb8f7..c34a0915e49d 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -446,10 +446,10 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *arg); extern struct platform_driver vc4_crtc_driver; bool vc4_event_pending(struct drm_crtc *crtc); int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg); -int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode); +bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode); /* vc4_debugfs.c */ int vc4_debugfs_init(struct drm_minor *minor); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 6304de7e041e..952c080e6b28 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -320,14 +320,6 @@ struct pci_controller; #define DRM_IF_VERSION(maj, min) (maj << 16 | min) -/* Flags and return codes for get_vblank_timestamp() driver function. */ -#define DRM_CALLED_FROM_VBLIRQ 1 - -/* get_scanout_position() return flags */ -#define DRM_SCANOUTPOS_VALID (1 << 0) -#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) -#define DRM_SCANOUTPOS_ACCURATE (1 << 2) - /** * DRM device structure. This structure represent a complete card that * may contain multiple heads. diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 0a367cf5d8d5..e64e33b9dd26 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -241,8 +241,10 @@ struct drm_driver { * DRM device. * pipe: * Id of the crtc to query. - * flags: - * Flags from the caller (DRM_CALLED_FROM_VBLIRQ or 0). + * in_vblank_irq: + * True when called from drm_crtc_handle_vblank(). Some drivers + * need to apply some workarounds for gpu-specific vblank irq quirks + * if flag is set. * vpos: * Target location for current vertical scanout position. * hpos: @@ -263,16 +265,8 @@ struct drm_driver { * * Returns: * - * Flags, or'ed together as follows: - * - * DRM_SCANOUTPOS_VALID: - * Query successful. - * DRM_SCANOUTPOS_INVBL: - * Inside vblank. - * DRM_SCANOUTPOS_ACCURATE: Returned position is accurate. A lack of - * this flag means that returned position may be offset by a - * constant but unknown small number of scanlines wrt. real scanout - * position. + * True on success, false if a reliable scanout position counter could + * not be read out. * * FIXME: * @@ -280,10 +274,10 @@ struct drm_driver { * move it to &struct drm_crtc_helper_funcs, like all the other * helper-internal hooks. */ - int (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode); + bool (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode); /** * @get_vblank_timestamp: -- 2.11.0 _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH] drm/vblank: fix boolreturn.cocci warnings 2017-03-22 8:36 ` [PATCH 15/16] drm/vblank: Simplify the get_scanout_position helper hook Daniel Vetter @ 2017-03-24 21:28 ` kbuild test robot 2017-03-24 21:28 ` [PATCH 15/16] drm/vblank: Simplify the get_scanout_position helper hook kbuild test robot 2017-03-25 21:37 ` [PATCH] " Daniel Vetter 2 siblings, 0 replies; 19+ messages in thread From: kbuild test robot @ 2017-03-24 21:28 UTC (permalink / raw) Cc: linux-arm-msm, Intel Graphics Development, DRI Development, kbuild-all, Mario Kleiner, Daniel Vetter, Alex Deucher, Daniel Vetter, freedreno, Christian König, Ben Skeggs drivers/gpu/drm/nouveau/nouveau_display.c:154:8-9: WARNING: return of 0/1 in function 'nouveau_display_scanoutpos' with return type bool Return statements in functions returning bool should use true/false instead of 1/0. Generated by: scripts/coccinelle/misc/boolreturn.cocci CC: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com> --- nouveau_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -151,7 +151,7 @@ nouveau_display_scanoutpos(struct drm_de } } - return 0; + return false; } static void _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 15/16] drm/vblank: Simplify the get_scanout_position helper hook 2017-03-22 8:36 ` [PATCH 15/16] drm/vblank: Simplify the get_scanout_position helper hook Daniel Vetter 2017-03-24 21:28 ` [PATCH] drm/vblank: fix boolreturn.cocci warnings kbuild test robot @ 2017-03-24 21:28 ` kbuild test robot 2017-03-25 21:37 ` [PATCH] " Daniel Vetter 2 siblings, 0 replies; 19+ messages in thread From: kbuild test robot @ 2017-03-24 21:28 UTC (permalink / raw) Cc: linux-arm-msm, Intel Graphics Development, DRI Development, kbuild-all, Mario Kleiner, Daniel Vetter, Alex Deucher, Daniel Vetter, freedreno, Christian König, Ben Skeggs Hi Daniel, [auto build test WARNING on drm/drm-next] [cannot apply to v4.11-rc3 next-20170324] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Daniel-Vetter/more-drmP-h-cleanup/20170325-030940 base: git://people.freedesktop.org/~airlied/linux.git drm-next coccinelle warnings: (new ones prefixed by >>) >> drivers/gpu/drm/nouveau/nouveau_display.c:154:8-9: WARNING: return of 0/1 in function 'nouveau_display_scanoutpos' with return type bool Please review and possibly fold the followup patch. --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH] drm/vblank: Simplify the get_scanout_position helper hook 2017-03-22 8:36 ` [PATCH 15/16] drm/vblank: Simplify the get_scanout_position helper hook Daniel Vetter 2017-03-24 21:28 ` [PATCH] drm/vblank: fix boolreturn.cocci warnings kbuild test robot 2017-03-24 21:28 ` [PATCH 15/16] drm/vblank: Simplify the get_scanout_position helper hook kbuild test robot @ 2017-03-25 21:37 ` Daniel Vetter 2 siblings, 0 replies; 19+ messages in thread From: Daniel Vetter @ 2017-03-25 21:37 UTC (permalink / raw) To: DRI Development Cc: linux-arm-msm, Intel Graphics Development, Ben Skeggs, Mario Kleiner, Daniel Vetter, Alex Deucher, Daniel Vetter, freedreno, Christian König - We can drop the different return value flags, the only caller only cares about whether the scanout position is valid or not. Also, it's entirely undefined what "accurate" means, if we'd really care we should probably wire the max_error through. But since we never even report this to userspace it's kinda moot. - Drop all the fancy input flags, there's really only the "called from vblank irq" one. Well except for radeon/amdgpu, which added their own private flags. Since amdgpu/radoen also use the scanoutposition function internally I just gave them a tiny wrapper, plus copies of all the old #defines they need. Everyone else gets simplified code. Note how we could remove a lot of error conditions if we'd move this helper hook to drm_crtc_helper_funcs and would pass it a crtc directly. v2: Make it compile on arm. v3: Squash in fixup from 0day. 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> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 12 +++++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 3 +++ drivers/gpu/drm/drm_irq.c | 16 ++++++++-------- drivers/gpu/drm/i915/i915_irq.c | 19 ++++++------------- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 19 +++++++------------ drivers/gpu/drm/nouveau/nouveau_display.c | 18 ++++++++---------- drivers/gpu/drm/nouveau/nouveau_display.h | 6 +++--- drivers/gpu/drm/radeon/radeon_drv.c | 12 +++++++++++- drivers/gpu/drm/radeon/radeon_mode.h | 3 +++ drivers/gpu/drm/vc4/vc4_crtc.c | 21 ++++++++++----------- drivers/gpu/drm/vc4/vc4_drv.h | 8 ++++---- include/drm/drmP.h | 8 -------- include/drm/drm_drv.h | 26 ++++++++++---------------- 13 files changed, 84 insertions(+), 87 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 4b4861741d7f..9a0312aadf04 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -679,6 +679,16 @@ static const struct file_operations amdgpu_driver_kms_fops = { #endif }; +static bool +amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +{ + return amdgpu_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos, + stime, etime, mode); +} + static struct drm_driver kms_driver = { .driver_features = DRIVER_USE_AGP | @@ -694,7 +704,7 @@ static struct drm_driver kms_driver = { .enable_vblank = amdgpu_enable_vblank_kms, .disable_vblank = amdgpu_disable_vblank_kms, .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, - .get_scanout_position = amdgpu_get_crtc_scanoutpos, + .get_scanout_position = amdgpu_get_crtc_scanout_position, #if defined(CONFIG_DEBUG_FS) .debugfs_init = amdgpu_debugfs_init, #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index c12497bd3889..6b8f766a6a35 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 { ((em) == ATOM_ENCODER_MODE_DP_MST)) /* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */ +#define DRM_SCANOUTPOS_VALID (1 << 0) +#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) +#define DRM_SCANOUTPOS_ACCURATE (1 << 2) #define USE_REAL_VBLANKSTART (1 << 30) #define GET_DISTANCE_TO_VBLANKSTART (1 << 31) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 46c923848c16..37541abac0d8 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -742,13 +742,12 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, { struct timeval tv_etime; ktime_t stime, etime; - unsigned int vbl_status; + bool vbl_status; struct drm_crtc *crtc; const struct drm_display_mode *mode; struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; int vpos, hpos, i; int delta_ns, duration_ns; - unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return false; @@ -791,15 +790,16 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, * Get vertical and horizontal scanout position vpos, hpos, * and bounding timestamps stime, etime, pre/post query. */ - vbl_status = dev->driver->get_scanout_position(dev, pipe, flags, + vbl_status = dev->driver->get_scanout_position(dev, pipe, + in_vblank_irq, &vpos, &hpos, &stime, &etime, mode); /* Return as no-op if scanout query unsupported or failed. */ - if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { - DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", - pipe, vbl_status); + if (!vbl_status) { + DRM_DEBUG("crtc %u : scanoutpos query failed.\n", + pipe); return false; } @@ -838,8 +838,8 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, etime = ktime_sub_ns(etime, delta_ns); *vblank_time = ktime_to_timeval(etime); - DRM_DEBUG_VBL("crtc %u : v 0x%x p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", - pipe, vbl_status, hpos, vpos, + DRM_DEBUG_VBL("crtc %u : v p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", + pipe, hpos, vpos, (long)tv_etime.tv_sec, (long)tv_etime.tv_usec, (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, duration_ns/1000, i); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6d279b8e897f..c9b53c93b4ed 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -827,10 +827,10 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) return (position + crtc->scanline_offset) % vtotal; } -static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv, @@ -838,13 +838,12 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, int position; int vbl_start, vbl_end, hsync_start, htotal, vtotal; bool in_vbl = true; - int ret = 0; unsigned long irqflags; if (WARN_ON(!mode->crtc_clock)) { DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " "pipe %c\n", pipe_name(pipe)); - return 0; + return false; } htotal = mode->crtc_htotal; @@ -859,8 +858,6 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, vtotal /= 2; } - ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; - /* * Lock uncore.lock, as we will do multiple timing critical raw * register reads, potentially with preemption disabled, so the @@ -944,11 +941,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, *hpos = position - (*vpos * htotal); } - /* In vblank? */ - if (in_vbl) - ret |= DRM_SCANOUTPOS_IN_VBLANK; - - return ret; + return true; } int intel_get_crtc_scanline(struct intel_crtc *crtc) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 6ba216b8bba9..959b826123a2 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -530,31 +530,28 @@ static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc) return NULL; } -static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +static bool mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc; struct drm_encoder *encoder; int line, vsw, vbp, vactive_start, vactive_end, vfp_end; - int ret = 0; crtc = priv->crtcs[pipe]; if (!crtc) { DRM_ERROR("Invalid crtc %d\n", pipe); - return 0; + return false; } encoder = get_encoder_from_crtc(crtc); if (!encoder) { DRM_ERROR("no encoder found for crtc %d\n", pipe); - return 0; + return false; } - ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; - vsw = mode->crtc_vsync_end - mode->crtc_vsync_start; vbp = mode->crtc_vtotal - mode->crtc_vsync_end; @@ -578,10 +575,8 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, if (line < vactive_start) { line -= vactive_start; - ret |= DRM_SCANOUTPOS_IN_VBLANK; } else if (line > vactive_end) { line = line - vfp_end - vactive_start; - ret |= DRM_SCANOUTPOS_IN_VBLANK; } else { line -= vactive_start; } @@ -592,7 +587,7 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, if (etime) *etime = ktime_get(); - return ret; + return true; } static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index e4bdac13d4e9..e1829761fdf2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -98,7 +98,7 @@ calc(int blanks, int blanke, int total, int line) return line; } -static int +static bool nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) { @@ -111,16 +111,16 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, }; struct nouveau_display *disp = nouveau_display(crtc->dev); struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)]; - int ret, retry = 1; + int retry = 1; + bool ret = false; do { ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args)); if (ret != 0) - return 0; + return false; if (args.scan.vline) { - ret |= DRM_SCANOUTPOS_ACCURATE; - ret |= DRM_SCANOUTPOS_VALID; + ret = true; break; } @@ -133,14 +133,12 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, if (stime) *stime = ns_to_ktime(args.scan.time[0]); if (etime) *etime = ns_to_ktime(args.scan.time[1]); - if (*vpos < 0) - ret |= DRM_SCANOUTPOS_IN_VBLANK; return ret; } -int +bool nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, + bool in_vblank_irq, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode) { @@ -153,7 +151,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, } } - return 0; + return false; } static void diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 8360a85ed5ef..b76b65c7c8da 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -68,9 +68,9 @@ int nouveau_display_suspend(struct drm_device *dev, bool runtime); void nouveau_display_resume(struct drm_device *dev, bool runtime); int nouveau_display_vblank_enable(struct drm_device *, unsigned int); void nouveau_display_vblank_disable(struct drm_device *, unsigned int); -int nouveau_display_scanoutpos(struct drm_device *, unsigned int, - unsigned int, int *, int *, ktime_t *, - ktime_t *, const struct drm_display_mode *); +bool nouveau_display_scanoutpos(struct drm_device *, unsigned int, + bool, int *, int *, ktime_t *, + ktime_t *, const struct drm_display_mode *); int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index a4bf09cd33f7..669ebfda8038 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -525,6 +525,16 @@ static const struct file_operations radeon_driver_kms_fops = { #endif }; +static bool +radeon_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +{ + return radeon_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos, + stime, etime, mode); +} + static struct drm_driver kms_driver = { .driver_features = DRIVER_USE_AGP | @@ -540,7 +550,7 @@ static struct drm_driver kms_driver = { .enable_vblank = radeon_enable_vblank_kms, .disable_vblank = radeon_disable_vblank_kms, .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, - .get_scanout_position = radeon_get_crtc_scanoutpos, + .get_scanout_position = radeon_get_crtc_scanout_position, .irq_preinstall = radeon_driver_irq_preinstall_kms, .irq_postinstall = radeon_driver_irq_postinstall_kms, .irq_uninstall = radeon_driver_irq_uninstall_kms, diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index ad282648fc8b..00f5ec5c12c7 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -691,6 +691,9 @@ struct atom_voltage_table }; /* Driver internal use only flags of radeon_get_crtc_scanoutpos() */ +#define DRM_SCANOUTPOS_VALID (1 << 0) +#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) +#define DRM_SCANOUTPOS_ACCURATE (1 << 2) #define USE_REAL_VBLANKSTART (1 << 30) #define GET_DISTANCE_TO_VBLANKSTART (1 << 31) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 2567d6c9a4ee..e871862a21b8 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -151,10 +151,10 @@ int vc4_crtc_debugfs_regs(struct seq_file *m, void *unused) } #endif -int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { struct vc4_dev *vc4 = to_vc4_dev(dev); struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); @@ -162,7 +162,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, u32 val; int fifo_lines; int vblank_lines; - int ret = 0; + bool ret = false; /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ @@ -198,7 +198,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, fifo_lines = vc4_crtc->cob_size / mode->crtc_hdisplay; if (fifo_lines > 0) - ret |= DRM_SCANOUTPOS_VALID; + ret = true; /* HVS more than fifo_lines into frame for compositing? */ if (*vpos > fifo_lines) { @@ -216,7 +216,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, */ *vpos -= fifo_lines + 1; - ret |= DRM_SCANOUTPOS_ACCURATE; return ret; } @@ -229,10 +228,9 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, * We can't get meaningful readings wrt. scanline position of the PV * and need to make things up in a approximative but consistent way. */ - ret |= DRM_SCANOUTPOS_IN_VBLANK; vblank_lines = mode->vtotal - mode->vdisplay; - if (flags & DRM_CALLED_FROM_VBLIRQ) { + if (in_vblank_irq) { /* * Assume the irq handler got called close to first * line of vblank, so PV has about a full vblank @@ -254,9 +252,10 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, * we are at the very beginning of vblank, as the hvs just * started refilling, and the stime and etime timestamps * truly correspond to start of vblank. + * + * Unfortunately there's no way to report this to upper levels + * and make it more useful. */ - if ((val & SCALER_DISPSTATX_FULL) != SCALER_DISPSTATX_FULL) - ret |= DRM_SCANOUTPOS_ACCURATE; } else { /* * No clue where we are inside vblank. Return a vpos of zero, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 64c92e0eb8f7..c34a0915e49d 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -446,10 +446,10 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *arg); extern struct platform_driver vc4_crtc_driver; bool vc4_event_pending(struct drm_crtc *crtc); int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg); -int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode); +bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode); /* vc4_debugfs.c */ int vc4_debugfs_init(struct drm_minor *minor); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 6304de7e041e..952c080e6b28 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -320,14 +320,6 @@ struct pci_controller; #define DRM_IF_VERSION(maj, min) (maj << 16 | min) -/* Flags and return codes for get_vblank_timestamp() driver function. */ -#define DRM_CALLED_FROM_VBLIRQ 1 - -/* get_scanout_position() return flags */ -#define DRM_SCANOUTPOS_VALID (1 << 0) -#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) -#define DRM_SCANOUTPOS_ACCURATE (1 << 2) - /** * DRM device structure. This structure represent a complete card that * may contain multiple heads. diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 0a367cf5d8d5..e64e33b9dd26 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -241,8 +241,10 @@ struct drm_driver { * DRM device. * pipe: * Id of the crtc to query. - * flags: - * Flags from the caller (DRM_CALLED_FROM_VBLIRQ or 0). + * in_vblank_irq: + * True when called from drm_crtc_handle_vblank(). Some drivers + * need to apply some workarounds for gpu-specific vblank irq quirks + * if flag is set. * vpos: * Target location for current vertical scanout position. * hpos: @@ -263,16 +265,8 @@ struct drm_driver { * * Returns: * - * Flags, or'ed together as follows: - * - * DRM_SCANOUTPOS_VALID: - * Query successful. - * DRM_SCANOUTPOS_INVBL: - * Inside vblank. - * DRM_SCANOUTPOS_ACCURATE: Returned position is accurate. A lack of - * this flag means that returned position may be offset by a - * constant but unknown small number of scanlines wrt. real scanout - * position. + * True on success, false if a reliable scanout position counter could + * not be read out. * * FIXME: * @@ -280,10 +274,10 @@ struct drm_driver { * move it to &struct drm_crtc_helper_funcs, like all the other * helper-internal hooks. */ - int (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode); + bool (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode); /** * @get_vblank_timestamp: -- 2.11.0 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 12/16] drm/vblank: Switch to bool in_vblank_irq in get_vblank_timestamp [not found] <20170322083617.13361-1-daniel.vetter@ffwll.ch> [not found] ` <20170322083617.13361-1-daniel.vetter-/w4YWyX8dFk@public.gmane.org> @ 2017-03-22 8:36 ` Daniel Vetter 2017-03-22 18:23 ` Ville Syrjälä 2017-03-22 8:36 ` [PATCH 14/16] drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos Daniel Vetter 2 siblings, 1 reply; 19+ messages in thread From: Daniel Vetter @ 2017-03-22 8:36 UTC (permalink / raw) To: Intel Graphics Development Cc: DRI Development, Daniel Vetter, Mario Kleiner, Eric Anholt, Rob Clark, linux-arm-msm, freedreno, Alex Deucher, Christian König, Ben Skeggs, Daniel Vetter It's overkill to have a flag parameter which is essentially used just as a boolean. This takes care of core + adjusting drivers. Adjusting the scanout position callback is a bit harder, since radeon also supplies it's own driver-private flags in there. 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> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 6 ++--- drivers/gpu/drm/drm_irq.c | 41 +++++++++++++++++-------------- drivers/gpu/drm/i915/i915_irq.c | 4 +-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 4 +-- drivers/gpu/drm/nouveau/nouveau_display.c | 5 ++-- drivers/gpu/drm/nouveau/nouveau_display.h | 2 +- drivers/gpu/drm/radeon/radeon_drv.c | 2 +- drivers/gpu/drm/radeon/radeon_kms.c | 4 +-- drivers/gpu/drm/vc4/vc4_crtc.c | 4 +-- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- include/drm/drm_drv.h | 11 ++++----- include/drm/drm_irq.h | 2 +- 13 files changed, 46 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index acd8631d8024..edb3bb83e1a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1771,7 +1771,7 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags); + bool in_vblank_irq); long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index ac42f707c046..ad295e822d45 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -834,7 +834,7 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) * @crtc: crtc to get the timestamp for * @max_error: max error * @vblank_time: time value - * @flags: flags passed to the driver + * @in_vblank_irq: called from drm_handle_vblank() * * Gets the timestamp on the requested crtc based on the * scanout position. (all asics). @@ -843,7 +843,7 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags) + bool in_vblank_irq) { struct drm_crtc *crtc; struct amdgpu_device *adev = dev->dev_private; @@ -864,7 +864,7 @@ bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, /* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, flags, + vblank_time, in_vblank_irq, &crtc->hwmode); } diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 2121ea29e1b2..059c3346db68 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -54,7 +54,7 @@ static bool drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, - struct timeval *tvblank, unsigned flags); + struct timeval *tvblank, bool in_vblank_irq); static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ @@ -138,7 +138,7 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe */ do { cur_vblank = __get_vblank_counter(dev, pipe); - rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, 0); + rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false); } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0); /* @@ -171,7 +171,7 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe * device vblank fields. */ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, - unsigned long flags) + bool in_vblank_irq) { struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; u32 cur_vblank, diff; @@ -194,7 +194,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, */ do { cur_vblank = __get_vblank_counter(dev, pipe); - rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, flags); + rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, in_vblank_irq); } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0); if (dev->max_vblank_count != 0) { @@ -214,13 +214,13 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, */ diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns); - if (diff == 0 && flags & DRM_CALLED_FROM_VBLIRQ) + if (diff == 0 && in_vblank_irq) DRM_DEBUG_VBL("crtc %u: Redundant vblirq ignored." " diff_ns = %lld, framedur_ns = %d)\n", pipe, (long long) diff_ns, framedur_ns); } else { /* some kind of default for drivers w/o accurate vbl timestamping */ - diff = (flags & DRM_CALLED_FROM_VBLIRQ) != 0; + diff = in_vblank_irq ? 1 : 0; } /* @@ -253,7 +253,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, * Otherwise reinitialize delayed at next vblank interrupt and assign 0 * for now, to mark the vblanktimestamp as invalid. */ - if (!rc && (flags & DRM_CALLED_FROM_VBLIRQ) == 0) + if (!rc && in_vblank_irq) t_vblank = (struct timeval) {0, 0}; store_vblank(dev, pipe, diff, &t_vblank, cur_vblank); @@ -291,7 +291,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc) spin_lock_irqsave(&dev->vblank_time_lock, flags); - drm_update_vblank_count(dev, pipe, 0); + drm_update_vblank_count(dev, pipe, false); vblank = drm_vblank_count(dev, pipe); spin_unlock_irqrestore(&dev->vblank_time_lock, flags); @@ -347,7 +347,7 @@ static void vblank_disable_and_save(struct drm_device *dev, unsigned int pipe) * this time. This makes the count account for the entire time * between drm_crtc_vblank_on() and drm_crtc_vblank_off(). */ - drm_update_vblank_count(dev, pipe, 0); + drm_update_vblank_count(dev, pipe, false); spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); } @@ -698,9 +698,10 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * @max_error: Desired maximum allowable error in timestamps (nanosecs) * On return contains true maximum error of timestamp * @vblank_time: Pointer to struct timeval which should receive the timestamp - * @flags: Flags to pass to driver: - * 0 = Default, - * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler + * @in_vblank_irq: + * True when called from drm_crtc_handle_vblank(). Some drivers + * need to apply some workarounds for gpu-specific vblank irq quirks + * if flag is set. * @mode: mode which defines the scanout timings * * Implements calculation of exact vblank timestamps from given drm_display_mode @@ -730,7 +731,7 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags, + bool in_vblank_irq, const struct drm_display_mode *mode) { struct timeval tv_etime; @@ -738,6 +739,7 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int vbl_status; int vpos, hpos, i; int delta_ns, duration_ns; + unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0; if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe); @@ -841,9 +843,10 @@ static struct timeval get_drm_timestamp(void) * @dev: DRM device * @pipe: index of CRTC whose vblank timestamp to retrieve * @tvblank: Pointer to target struct timeval which should receive the timestamp - * @flags: Flags to pass to driver: - * 0 = Default, - * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler + * @in_vblank_irq: + * True when called from drm_crtc_handle_vblank(). Some drivers + * need to apply some workarounds for gpu-specific vblank irq quirks + * if flag is set. * * Fetches the system timestamp corresponding to the time of the most recent * vblank interval on specified CRTC. May call into kms-driver to @@ -857,7 +860,7 @@ static struct timeval get_drm_timestamp(void) */ static bool drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, - struct timeval *tvblank, unsigned flags) + struct timeval *tvblank, bool in_vblank_irq) { int ret; @@ -867,7 +870,7 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, /* Query driver if possible and precision timestamping enabled. */ if (dev->driver->get_vblank_timestamp && (max_error > 0)) { ret = dev->driver->get_vblank_timestamp(dev, pipe, &max_error, - tvblank, flags); + tvblank, in_vblank_irq); if (ret > 0) return true; } @@ -1710,7 +1713,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe) return false; } - drm_update_vblank_count(dev, pipe, DRM_CALLED_FROM_VBLIRQ); + drm_update_vblank_count(dev, pipe, true); spin_unlock(&dev->vblank_time_lock); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index df149d159ce7..6c8a7e1284c3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -967,7 +967,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags) + bool in_vblank_irq) { struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc; @@ -991,7 +991,7 @@ static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, /* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, flags, + vblank_time, in_vblank_irq, &crtc->base.hwmode); } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 655700eb42ba..16184ccbdd3b 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -598,7 +598,7 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags) + bool in_vblank_irq) { struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc; @@ -615,7 +615,7 @@ static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, } return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, flags, + vblank_time, in_vblank_irq, &crtc->mode); } diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 42f18b0b9c43..be8ec18ba126 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -158,7 +158,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, bool nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, - int *max_error, struct timeval *time, unsigned flags) + int *max_error, struct timeval *time, bool in_vblank_irq) { struct drm_crtc *crtc; @@ -170,7 +170,8 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, else mode = &crtc->hwmode; return drm_calc_vbltimestamp_from_scanoutpos(dev, - pipe, max_error, time, flags, mode); + pipe, max_error, time, in_vblank_irq, + mode); } } diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index bc9d1e7b0117..f821fc9e2de3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -72,7 +72,7 @@ int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, - struct timeval *, unsigned); + struct timeval *, bool); int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 6d79b5c2805b..5fbbc6ac165d 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -117,7 +117,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags); + bool in_vblank_irq); void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 9afe72010c64..41765d18f863 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -873,7 +873,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, int *max_error, struct timeval *vblank_time, - unsigned flags) + bool in_vblank_irq) { struct drm_crtc *drmcrtc; struct radeon_device *rdev = dev->dev_private; @@ -890,7 +890,7 @@ bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, /* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, - vblank_time, flags, + vblank_time, in_vblank_irq, &drmcrtc->hwmode); } diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 74260990b6bf..18bd0d816fe3 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -272,14 +272,14 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, - unsigned flags) + bool in_vblank_irq) { struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); struct drm_crtc_state *state = crtc->state; /* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc_id, max_error, - vblank_time, flags, + vblank_time, in_vblank_irq, &state->adjusted_mode); } diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 8a5d0e12ee02..815cdeb54971 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -452,7 +452,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, const struct drm_display_mode *mode); bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, - unsigned flags); + bool in_vblank_irq); /* vc4_debugfs.c */ int vc4_debugfs_init(struct drm_minor *minor); diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index da78e248d9d8..9fe6301edd6a 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -308,11 +308,10 @@ struct drm_driver { * Returns true upper bound on error for timestamp. * vblank_time: * Target location for returned vblank timestamp. - * flags: - * 0 = Defaults, no special treatment needed. - * DRM_CALLED_FROM_VBLIRQ = Function is called from vblank - * irq handler. Some drivers need to apply some workarounds - * for gpu-specific vblank irq quirks if flag is set. + * in_vblank_irq: + * True when called from drm_crtc_handle_vblank(). Some drivers + * need to apply some workarounds for gpu-specific vblank irq quirks + * if flag is set. * * Returns: * @@ -322,7 +321,7 @@ struct drm_driver { bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags); + bool in_vblank_irq); /* these have to be filled in */ diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index f0d5ccf9b282..445406efb8dc 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -156,7 +156,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc); bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags, + bool in_vblank_irq, const struct drm_display_mode *mode); void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode); -- 2.11.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 12/16] drm/vblank: Switch to bool in_vblank_irq in get_vblank_timestamp 2017-03-22 8:36 ` [PATCH 12/16] drm/vblank: Switch to bool in_vblank_irq in get_vblank_timestamp Daniel Vetter @ 2017-03-22 18:23 ` Ville Syrjälä 0 siblings, 0 replies; 19+ messages in thread From: Ville Syrjälä @ 2017-03-22 18:23 UTC (permalink / raw) To: Daniel Vetter Cc: Intel Graphics Development, linux-arm-msm, DRI Development, Ben Skeggs, Mario Kleiner, Alex Deucher, Daniel Vetter, freedreno, Christian König On Wed, Mar 22, 2017 at 09:36:13AM +0100, Daniel Vetter wrote: > It's overkill to have a flag parameter which is essentially used just > as a boolean. This takes care of core + adjusting drivers. > > Adjusting the scanout position callback is a bit harder, since radeon > also supplies it's own driver-private flags in there. This part worried me, but indeed radeon only passes the custom flag to the scanout position hook. Patch lgtm Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > > 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> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 6 ++--- > drivers/gpu/drm/drm_irq.c | 41 +++++++++++++++++-------------- > drivers/gpu/drm/i915/i915_irq.c | 4 +-- > drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 4 +-- > drivers/gpu/drm/nouveau/nouveau_display.c | 5 ++-- > drivers/gpu/drm/nouveau/nouveau_display.h | 2 +- > drivers/gpu/drm/radeon/radeon_drv.c | 2 +- > drivers/gpu/drm/radeon/radeon_kms.c | 4 +-- > drivers/gpu/drm/vc4/vc4_crtc.c | 4 +-- > drivers/gpu/drm/vc4/vc4_drv.h | 2 +- > include/drm/drm_drv.h | 11 ++++----- > include/drm/drm_irq.h | 2 +- > 13 files changed, 46 insertions(+), 43 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index acd8631d8024..edb3bb83e1a9 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -1771,7 +1771,7 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); > bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > int *max_error, > struct timeval *vblank_time, > - unsigned flags); > + bool in_vblank_irq); > long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, > unsigned long arg); > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > index ac42f707c046..ad295e822d45 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > @@ -834,7 +834,7 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) > * @crtc: crtc to get the timestamp for > * @max_error: max error > * @vblank_time: time value > - * @flags: flags passed to the driver > + * @in_vblank_irq: called from drm_handle_vblank() > * > * Gets the timestamp on the requested crtc based on the > * scanout position. (all asics). > @@ -843,7 +843,7 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) > bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > int *max_error, > struct timeval *vblank_time, > - unsigned flags) > + bool in_vblank_irq) > { > struct drm_crtc *crtc; > struct amdgpu_device *adev = dev->dev_private; > @@ -864,7 +864,7 @@ bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > > /* Helper routine in DRM core does all the work: */ > return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, > - vblank_time, flags, > + vblank_time, in_vblank_irq, > &crtc->hwmode); > } > > diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c > index 2121ea29e1b2..059c3346db68 100644 > --- a/drivers/gpu/drm/drm_irq.c > +++ b/drivers/gpu/drm/drm_irq.c > @@ -54,7 +54,7 @@ > > static bool > drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, > - struct timeval *tvblank, unsigned flags); > + struct timeval *tvblank, bool in_vblank_irq); > > static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ > > @@ -138,7 +138,7 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe > */ > do { > cur_vblank = __get_vblank_counter(dev, pipe); > - rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, 0); > + rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false); > } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0); > > /* > @@ -171,7 +171,7 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe > * device vblank fields. > */ > static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, > - unsigned long flags) > + bool in_vblank_irq) > { > struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; > u32 cur_vblank, diff; > @@ -194,7 +194,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, > */ > do { > cur_vblank = __get_vblank_counter(dev, pipe); > - rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, flags); > + rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, in_vblank_irq); > } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0); > > if (dev->max_vblank_count != 0) { > @@ -214,13 +214,13 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, > */ > diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns); > > - if (diff == 0 && flags & DRM_CALLED_FROM_VBLIRQ) > + if (diff == 0 && in_vblank_irq) > DRM_DEBUG_VBL("crtc %u: Redundant vblirq ignored." > " diff_ns = %lld, framedur_ns = %d)\n", > pipe, (long long) diff_ns, framedur_ns); > } else { > /* some kind of default for drivers w/o accurate vbl timestamping */ > - diff = (flags & DRM_CALLED_FROM_VBLIRQ) != 0; > + diff = in_vblank_irq ? 1 : 0; > } > > /* > @@ -253,7 +253,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, > * Otherwise reinitialize delayed at next vblank interrupt and assign 0 > * for now, to mark the vblanktimestamp as invalid. > */ > - if (!rc && (flags & DRM_CALLED_FROM_VBLIRQ) == 0) > + if (!rc && in_vblank_irq) > t_vblank = (struct timeval) {0, 0}; > > store_vblank(dev, pipe, diff, &t_vblank, cur_vblank); > @@ -291,7 +291,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc) > > spin_lock_irqsave(&dev->vblank_time_lock, flags); > > - drm_update_vblank_count(dev, pipe, 0); > + drm_update_vblank_count(dev, pipe, false); > vblank = drm_vblank_count(dev, pipe); > > spin_unlock_irqrestore(&dev->vblank_time_lock, flags); > @@ -347,7 +347,7 @@ static void vblank_disable_and_save(struct drm_device *dev, unsigned int pipe) > * this time. This makes the count account for the entire time > * between drm_crtc_vblank_on() and drm_crtc_vblank_off(). > */ > - drm_update_vblank_count(dev, pipe, 0); > + drm_update_vblank_count(dev, pipe, false); > > spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); > } > @@ -698,9 +698,10 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); > * @max_error: Desired maximum allowable error in timestamps (nanosecs) > * On return contains true maximum error of timestamp > * @vblank_time: Pointer to struct timeval which should receive the timestamp > - * @flags: Flags to pass to driver: > - * 0 = Default, > - * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler > + * @in_vblank_irq: > + * True when called from drm_crtc_handle_vblank(). Some drivers > + * need to apply some workarounds for gpu-specific vblank irq quirks > + * if flag is set. > * @mode: mode which defines the scanout timings > * > * Implements calculation of exact vblank timestamps from given drm_display_mode > @@ -730,7 +731,7 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > unsigned int pipe, > int *max_error, > struct timeval *vblank_time, > - unsigned flags, > + bool in_vblank_irq, > const struct drm_display_mode *mode) > { > struct timeval tv_etime; > @@ -738,6 +739,7 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > unsigned int vbl_status; > int vpos, hpos, i; > int delta_ns, duration_ns; > + unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0; > > if (pipe >= dev->num_crtcs) { > DRM_ERROR("Invalid crtc %u\n", pipe); > @@ -841,9 +843,10 @@ static struct timeval get_drm_timestamp(void) > * @dev: DRM device > * @pipe: index of CRTC whose vblank timestamp to retrieve > * @tvblank: Pointer to target struct timeval which should receive the timestamp > - * @flags: Flags to pass to driver: > - * 0 = Default, > - * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler > + * @in_vblank_irq: > + * True when called from drm_crtc_handle_vblank(). Some drivers > + * need to apply some workarounds for gpu-specific vblank irq quirks > + * if flag is set. > * > * Fetches the system timestamp corresponding to the time of the most recent > * vblank interval on specified CRTC. May call into kms-driver to > @@ -857,7 +860,7 @@ static struct timeval get_drm_timestamp(void) > */ > static bool > drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, > - struct timeval *tvblank, unsigned flags) > + struct timeval *tvblank, bool in_vblank_irq) > { > int ret; > > @@ -867,7 +870,7 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, > /* Query driver if possible and precision timestamping enabled. */ > if (dev->driver->get_vblank_timestamp && (max_error > 0)) { > ret = dev->driver->get_vblank_timestamp(dev, pipe, &max_error, > - tvblank, flags); > + tvblank, in_vblank_irq); > if (ret > 0) > return true; > } > @@ -1710,7 +1713,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe) > return false; > } > > - drm_update_vblank_count(dev, pipe, DRM_CALLED_FROM_VBLIRQ); > + drm_update_vblank_count(dev, pipe, true); > > spin_unlock(&dev->vblank_time_lock); > > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > index df149d159ce7..6c8a7e1284c3 100644 > --- a/drivers/gpu/drm/i915/i915_irq.c > +++ b/drivers/gpu/drm/i915/i915_irq.c > @@ -967,7 +967,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) > static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > int *max_error, > struct timeval *vblank_time, > - unsigned flags) > + bool in_vblank_irq) > { > struct drm_i915_private *dev_priv = to_i915(dev); > struct intel_crtc *crtc; > @@ -991,7 +991,7 @@ static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > > /* Helper routine in DRM core does all the work: */ > return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, > - vblank_time, flags, > + vblank_time, in_vblank_irq, > &crtc->base.hwmode); > } > > diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > index 655700eb42ba..16184ccbdd3b 100644 > --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > @@ -598,7 +598,7 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, > static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > int *max_error, > struct timeval *vblank_time, > - unsigned flags) > + bool in_vblank_irq) > { > struct msm_drm_private *priv = dev->dev_private; > struct drm_crtc *crtc; > @@ -615,7 +615,7 @@ static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > } > > return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, > - vblank_time, flags, > + vblank_time, in_vblank_irq, > &crtc->mode); > } > > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c > index 42f18b0b9c43..be8ec18ba126 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_display.c > +++ b/drivers/gpu/drm/nouveau/nouveau_display.c > @@ -158,7 +158,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, > > bool > nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, > - int *max_error, struct timeval *time, unsigned flags) > + int *max_error, struct timeval *time, bool in_vblank_irq) > { > struct drm_crtc *crtc; > > @@ -170,7 +170,8 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, > else > mode = &crtc->hwmode; > return drm_calc_vbltimestamp_from_scanoutpos(dev, > - pipe, max_error, time, flags, mode); > + pipe, max_error, time, in_vblank_irq, > + mode); > } > } > > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h > index bc9d1e7b0117..f821fc9e2de3 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_display.h > +++ b/drivers/gpu/drm/nouveau/nouveau_display.h > @@ -72,7 +72,7 @@ int nouveau_display_scanoutpos(struct drm_device *, unsigned int, > unsigned int, int *, int *, ktime_t *, > ktime_t *, const struct drm_display_mode *); > bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, > - struct timeval *, unsigned); > + struct timeval *, bool); > > int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, > struct drm_pending_vblank_event *event, > diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c > index 6d79b5c2805b..5fbbc6ac165d 100644 > --- a/drivers/gpu/drm/radeon/radeon_drv.c > +++ b/drivers/gpu/drm/radeon/radeon_drv.c > @@ -117,7 +117,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); > bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > int *max_error, > struct timeval *vblank_time, > - unsigned flags); > + bool in_vblank_irq); > void radeon_driver_irq_preinstall_kms(struct drm_device *dev); > int radeon_driver_irq_postinstall_kms(struct drm_device *dev); > void radeon_driver_irq_uninstall_kms(struct drm_device *dev); > diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c > index 9afe72010c64..41765d18f863 100644 > --- a/drivers/gpu/drm/radeon/radeon_kms.c > +++ b/drivers/gpu/drm/radeon/radeon_kms.c > @@ -873,7 +873,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) > bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, > int *max_error, > struct timeval *vblank_time, > - unsigned flags) > + bool in_vblank_irq) > { > struct drm_crtc *drmcrtc; > struct radeon_device *rdev = dev->dev_private; > @@ -890,7 +890,7 @@ bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, > > /* Helper routine in DRM core does all the work: */ > return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, > - vblank_time, flags, > + vblank_time, in_vblank_irq, > &drmcrtc->hwmode); > } > > diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c > index 74260990b6bf..18bd0d816fe3 100644 > --- a/drivers/gpu/drm/vc4/vc4_crtc.c > +++ b/drivers/gpu/drm/vc4/vc4_crtc.c > @@ -272,14 +272,14 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, > > bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > int *max_error, struct timeval *vblank_time, > - unsigned flags) > + bool in_vblank_irq) > { > struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); > struct drm_crtc_state *state = crtc->state; > > /* Helper routine in DRM core does all the work: */ > return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc_id, max_error, > - vblank_time, flags, > + vblank_time, in_vblank_irq, > &state->adjusted_mode); > } > > diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h > index 8a5d0e12ee02..815cdeb54971 100644 > --- a/drivers/gpu/drm/vc4/vc4_drv.h > +++ b/drivers/gpu/drm/vc4/vc4_drv.h > @@ -452,7 +452,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, > const struct drm_display_mode *mode); > bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > int *max_error, struct timeval *vblank_time, > - unsigned flags); > + bool in_vblank_irq); > > /* vc4_debugfs.c */ > int vc4_debugfs_init(struct drm_minor *minor); > diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h > index da78e248d9d8..9fe6301edd6a 100644 > --- a/include/drm/drm_drv.h > +++ b/include/drm/drm_drv.h > @@ -308,11 +308,10 @@ struct drm_driver { > * Returns true upper bound on error for timestamp. > * vblank_time: > * Target location for returned vblank timestamp. > - * flags: > - * 0 = Defaults, no special treatment needed. > - * DRM_CALLED_FROM_VBLIRQ = Function is called from vblank > - * irq handler. Some drivers need to apply some workarounds > - * for gpu-specific vblank irq quirks if flag is set. > + * in_vblank_irq: > + * True when called from drm_crtc_handle_vblank(). Some drivers > + * need to apply some workarounds for gpu-specific vblank irq quirks > + * if flag is set. > * > * Returns: > * > @@ -322,7 +321,7 @@ struct drm_driver { > bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, > int *max_error, > struct timeval *vblank_time, > - unsigned flags); > + bool in_vblank_irq); > > /* these have to be filled in */ > > diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h > index f0d5ccf9b282..445406efb8dc 100644 > --- a/include/drm/drm_irq.h > +++ b/include/drm/drm_irq.h > @@ -156,7 +156,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc); > bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > unsigned int pipe, int *max_error, > struct timeval *vblank_time, > - unsigned flags, > + bool in_vblank_irq, > const struct drm_display_mode *mode); > void drm_calc_timestamping_constants(struct drm_crtc *crtc, > const struct drm_display_mode *mode); > -- > 2.11.0 > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Ville Syrjälä Intel OTC ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 14/16] drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos [not found] <20170322083617.13361-1-daniel.vetter@ffwll.ch> [not found] ` <20170322083617.13361-1-daniel.vetter-/w4YWyX8dFk@public.gmane.org> 2017-03-22 8:36 ` [PATCH 12/16] drm/vblank: Switch to bool in_vblank_irq in get_vblank_timestamp Daniel Vetter @ 2017-03-22 8:36 ` Daniel Vetter [not found] ` <20170322083617.13361-15-daniel.vetter-/w4YWyX8dFk@public.gmane.org> 2 siblings, 1 reply; 19+ messages in thread From: Daniel Vetter @ 2017-03-22 8:36 UTC (permalink / raw) To: Intel Graphics Development Cc: DRI Development, Daniel Vetter, Mario Kleiner, Eric Anholt, Rob Clark, linux-arm-msm, freedreno, Alex Deucher, Christian König, Ben Skeggs, Daniel Vetter 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 update 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. 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> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 41 ------------------------------- drivers/gpu/drm/drm_irq.c | 29 +++++++++++++++++++--- drivers/gpu/drm/i915/i915_irq.c | 33 +------------------------ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 26 +------------------- drivers/gpu/drm/nouveau/nouveau_display.c | 22 ----------------- drivers/gpu/drm/nouveau/nouveau_display.h | 2 -- drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +- drivers/gpu/drm/radeon/radeon_drv.c | 6 +---- drivers/gpu/drm/radeon/radeon_kms.c | 37 ---------------------------- drivers/gpu/drm/vc4/vc4_crtc.c | 13 ---------- drivers/gpu/drm/vc4/vc4_drv.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 3 --- include/drm/drm_irq.h | 15 +++++++++-- 15 files changed, 44 insertions(+), 193 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index edb3bb83e1a9..61bef9609b24 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1768,10 +1768,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq); long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 8a61296fd4cc..ba169a0699d5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -692,7 +692,7 @@ static struct drm_driver kms_driver = { .get_vblank_counter = amdgpu_get_vblank_counter_kms, .enable_vblank = amdgpu_enable_vblank_kms, .disable_vblank = amdgpu_disable_vblank_kms, - .get_vblank_timestamp = amdgpu_get_vblank_timestamp_kms, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .get_scanout_position = amdgpu_get_crtc_scanoutpos, #if defined(CONFIG_DEBUG_FS) .debugfs_init = amdgpu_debugfs_init, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index ad295e822d45..32a492bd4e51 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -827,47 +827,6 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) amdgpu_irq_put(adev, &adev->crtc_irq, idx); } -/** - * amdgpu_get_vblank_timestamp_kms - get vblank timestamp - * - * @dev: drm dev pointer - * @crtc: crtc to get the timestamp for - * @max_error: max error - * @vblank_time: time value - * @in_vblank_irq: called from drm_handle_vblank() - * - * Gets the timestamp on the requested crtc based on the - * scanout position. (all asics). - * Returns true on success, false on failure. - */ -bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_crtc *crtc; - struct amdgpu_device *adev = dev->dev_private; - - if (pipe >= dev->num_crtcs) { - DRM_ERROR("Invalid crtc %u\n", pipe); - return false; - } - - /* Get associated drm_crtc: */ - crtc = &adev->mode_info.crtcs[pipe]->base; - if (!crtc) { - /* This can occur on driver load if some component fails to - * initialize completely and driver is unloaded */ - DRM_ERROR("Uninitialized crtc %d\n", pipe); - return false; - } - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, in_vblank_irq, - &crtc->hwmode); -} - const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 059c3346db68..61d726b1f810 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -659,6 +659,8 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc, if (WARN_ON(pipe >= dev->num_crtcs)) return; + WARN_ON(drm_drv_uses_atomic_modeset(dev) && vblank->enabled); + /* Valid dotclock? */ if (dotclock > 0) { int frame_size = mode->crtc_htotal * mode->crtc_vtotal; @@ -682,6 +684,7 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc, vblank->linedur_ns = linedur_ns; vblank->framedur_ns = framedur_ns; + vblank->hwmode = *mode; DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n", crtc->base.id, mode->crtc_htotal, @@ -702,7 +705,6 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * True when called from drm_crtc_handle_vblank(). Some drivers * need to apply some workarounds for gpu-specific vblank irq quirks * if flag is set. - * @mode: mode which defines the scanout timings * * Implements calculation of exact vblank timestamps from given drm_display_mode * timings and current video scanout position of a CRTC. This can be called from @@ -722,6 +724,13 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * returns as no operation if a doublescan or interlaced video mode is * active. Higher level code is expected to handle this. * + * This function can be used to implement the &drm_driver.get_vblank_timestamp + * directly, if the driver implements the &drm_driver.get_scanout_position hook. + * + * Note that atomic drivers must call drm_calc_timestamping_constants() before + * enabling a CRTC. The atomic helpers already take care of that in + * drm_atomic_helper_update_legacy_modeset_state(). + * * Returns: * * Returns true on success, and false on failure, i.e. when no accurate @@ -731,17 +740,24 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - bool in_vblank_irq, - const struct drm_display_mode *mode) + bool in_vblank_irq) { struct timeval tv_etime; ktime_t stime, etime; unsigned int vbl_status; + struct drm_crtc *crtc; + const struct drm_display_mode *mode; + struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; int vpos, hpos, i; int delta_ns, duration_ns; unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0; - if (pipe >= dev->num_crtcs) { + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return false; + + crtc = drm_crtc_from_index(dev, pipe); + + if (pipe >= dev->num_crtcs || !crtc) { DRM_ERROR("Invalid crtc %u\n", pipe); return false; } @@ -752,6 +768,11 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, return false; } + if (drm_drv_uses_atomic_modeset(dev)) + mode = &vblank->hwmode; + else + mode = &crtc->hwmode; + /* If mode timing undefined, just return as no-op: * Happens during initial modesetting of a crtc. */ diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6c8a7e1284c3..feadfea77354 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -964,37 +964,6 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) return position; } -static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_crtc *crtc; - - if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { - DRM_ERROR("Invalid crtc %u\n", pipe); - return false; - } - - /* Get drm_crtc to timestamp: */ - crtc = intel_get_crtc_for_pipe(dev_priv, pipe); - if (crtc == NULL) { - DRM_ERROR("Invalid crtc %u\n", pipe); - return false; - } - - if (!crtc->base.hwmode.crtc_clock) { - DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); - return false; - } - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, in_vblank_irq, - &crtc->base.hwmode); -} - static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) { u32 busy_up, busy_down, max_avg, min_avg; @@ -4328,7 +4297,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv) dev_priv->hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD; - dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; + dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; if (IS_CHERRYVIEW(dev_priv)) { diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 16184ccbdd3b..6ba216b8bba9 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -595,30 +595,6 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, return ret; } -static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct msm_drm_private *priv = dev->dev_private; - struct drm_crtc *crtc; - - if (pipe < 0 || pipe >= priv->num_crtcs) { - DRM_ERROR("Invalid crtc %d\n", pipe); - return false; - } - - crtc = priv->crtcs[pipe]; - if (!crtc) { - DRM_ERROR("Invalid crtc %d\n", pipe); - return false; - } - - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, in_vblank_irq, - &crtc->mode); -} - static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { struct msm_drm_private *priv = dev->dev_private; @@ -728,7 +704,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) dev->mode_config.max_width = 0xffff; dev->mode_config.max_height = 0xffff; - dev->driver->get_vblank_timestamp = mdp5_get_vblank_timestamp; + dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; dev->driver->get_scanout_position = mdp5_get_scanoutpos; dev->driver->get_vblank_counter = mdp5_get_vblank_counter; dev->max_vblank_count = 0xffffffff; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index be8ec18ba126..e4bdac13d4e9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -156,28 +156,6 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, return 0; } -bool -nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, - int *max_error, struct timeval *time, bool in_vblank_irq) -{ - struct drm_crtc *crtc; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (nouveau_crtc(crtc)->index == pipe) { - struct drm_display_mode *mode; - if (drm_drv_uses_atomic_modeset(dev)) - mode = &crtc->state->adjusted_mode; - else - mode = &crtc->hwmode; - return drm_calc_vbltimestamp_from_scanoutpos(dev, - pipe, max_error, time, in_vblank_irq, - mode); - } - } - - return false; -} - static void nouveau_display_vblank_fini(struct drm_device *dev) { diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index f821fc9e2de3..8360a85ed5ef 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -71,8 +71,6 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); -bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, - struct timeval *, bool); int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index ec719df619a6..1f751a3f570c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -978,7 +978,7 @@ driver_stub = { .enable_vblank = nouveau_display_vblank_enable, .disable_vblank = nouveau_display_vblank_disable, .get_scanout_position = nouveau_display_scanoutpos, - .get_vblank_timestamp = nouveau_display_vblstamp, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .ioctls = nouveau_ioctls, .num_ioctls = ARRAY_SIZE(nouveau_ioctls), diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 5fbbc6ac165d..a4bf09cd33f7 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,10 +114,6 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq); void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); @@ -543,7 +539,7 @@ static struct drm_driver kms_driver = { .get_vblank_counter = radeon_get_vblank_counter_kms, .enable_vblank = radeon_enable_vblank_kms, .disable_vblank = radeon_disable_vblank_kms, - .get_vblank_timestamp = radeon_get_vblank_timestamp_kms, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .get_scanout_position = radeon_get_crtc_scanoutpos, .irq_preinstall = radeon_driver_irq_preinstall_kms, .irq_postinstall = radeon_driver_irq_postinstall_kms, diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 41765d18f863..33b8b3d22969 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -857,43 +857,6 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) spin_unlock_irqrestore(&rdev->irq.lock, irqflags); } -/** - * radeon_get_vblank_timestamp_kms - get vblank timestamp - * - * @dev: drm dev pointer - * @crtc: crtc to get the timestamp for - * @max_error: max error - * @vblank_time: time value - * @flags: flags passed to the driver - * - * Gets the timestamp on the requested crtc based on the - * scanout position. (all asics). - * Returns true on success, false on failure. - */ -bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_crtc *drmcrtc; - struct radeon_device *rdev = dev->dev_private; - - if (crtc < 0 || crtc >= dev->num_crtcs) { - DRM_ERROR("Invalid crtc %d\n", crtc); - return false; - } - - /* Get associated drm_crtc: */ - drmcrtc = &rdev->mode_info.crtcs[crtc]->base; - if (!drmcrtc) - return false; - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, - vblank_time, in_vblank_irq, - &drmcrtc->hwmode); -} - const struct drm_ioctl_desc radeon_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(RADEON_CP_START, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 18bd0d816fe3..2567d6c9a4ee 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -270,19 +270,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, return ret; } -bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, - int *max_error, struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); - struct drm_crtc_state *state = crtc->state; - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc_id, max_error, - vblank_time, in_vblank_irq, - &state->adjusted_mode); -} - static void vc4_crtc_destroy(struct drm_crtc *crtc) { drm_crtc_cleanup(crtc); diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 61e674baf3a6..e864256e12e5 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -154,7 +154,7 @@ static struct drm_driver vc4_drm_driver = { .irq_uninstall = vc4_irq_uninstall, .get_scanout_position = vc4_crtc_get_scanoutpos, - .get_vblank_timestamp = vc4_crtc_get_vblank_timestamp, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, #if defined(CONFIG_DEBUG_FS) .debugfs_init = vc4_debugfs_init, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 815cdeb54971..64c92e0eb8f7 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -450,9 +450,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); -bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, - int *max_error, struct timeval *vblank_time, - bool in_vblank_irq); /* vc4_debugfs.c */ int vc4_debugfs_init(struct drm_minor *minor); diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index 445406efb8dc..b489cc856e7a 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -121,6 +121,18 @@ struct drm_vblank_crtc { * drm_calc_timestamping_constants(). */ int linedur_ns; + + /** + * @hwmode: + * + * Cache of the current hardware display mode. Only valide when @enabled + * is set. This is used by helpers like + * drm_calc_vbltimestamp_from_scanoutpos(). We can't just access the + * hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode, + * because that one is really hard to get at from interrupt context. + */ + struct drm_display_mode hwmode; + /** * @enabled: Tracks the enabling state of the corresponding &drm_crtc to * avoid double-disabling and hence corrupting saved state. Needed by @@ -156,8 +168,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc); bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - bool in_vblank_irq, - const struct drm_display_mode *mode); + bool in_vblank_irq); void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode); -- 2.11.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
[parent not found: <20170322083617.13361-15-daniel.vetter-/w4YWyX8dFk@public.gmane.org>]
* [PATCH] drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos [not found] ` <20170322083617.13361-15-daniel.vetter-/w4YWyX8dFk@public.gmane.org> @ 2017-03-22 20:56 ` Daniel Vetter 2017-03-30 12:03 ` Ville Syrjälä 0 siblings, 1 reply; 19+ messages in thread From: Daniel Vetter @ 2017-03-22 20:56 UTC (permalink / raw) To: Intel Graphics Development Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, DRI Development, Eric Anholt, Rob Clark, Ben Skeggs, Mario Kleiner, Daniel Vetter, Alex Deucher, Daniel Vetter, freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Christian König 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 update 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. 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> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 41 ------------------------------- drivers/gpu/drm/drm_irq.c | 27 +++++++++++++++++--- drivers/gpu/drm/i915/i915_irq.c | 33 +------------------------ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 26 +------------------- drivers/gpu/drm/nouveau/nouveau_display.c | 22 ----------------- drivers/gpu/drm/nouveau/nouveau_display.h | 2 -- drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +- drivers/gpu/drm/radeon/radeon_drv.c | 6 +---- drivers/gpu/drm/radeon/radeon_kms.c | 37 ---------------------------- drivers/gpu/drm/vc4/vc4_crtc.c | 13 ---------- drivers/gpu/drm/vc4/vc4_drv.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 3 --- include/drm/drm_irq.h | 15 +++++++++-- 15 files changed, 42 insertions(+), 193 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index edb3bb83e1a9..61bef9609b24 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1768,10 +1768,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq); long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 8a61296fd4cc..ba169a0699d5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -692,7 +692,7 @@ static struct drm_driver kms_driver = { .get_vblank_counter = amdgpu_get_vblank_counter_kms, .enable_vblank = amdgpu_enable_vblank_kms, .disable_vblank = amdgpu_disable_vblank_kms, - .get_vblank_timestamp = amdgpu_get_vblank_timestamp_kms, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .get_scanout_position = amdgpu_get_crtc_scanoutpos, #if defined(CONFIG_DEBUG_FS) .debugfs_init = amdgpu_debugfs_init, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index ad295e822d45..32a492bd4e51 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -827,47 +827,6 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) amdgpu_irq_put(adev, &adev->crtc_irq, idx); } -/** - * amdgpu_get_vblank_timestamp_kms - get vblank timestamp - * - * @dev: drm dev pointer - * @crtc: crtc to get the timestamp for - * @max_error: max error - * @vblank_time: time value - * @in_vblank_irq: called from drm_handle_vblank() - * - * Gets the timestamp on the requested crtc based on the - * scanout position. (all asics). - * Returns true on success, false on failure. - */ -bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_crtc *crtc; - struct amdgpu_device *adev = dev->dev_private; - - if (pipe >= dev->num_crtcs) { - DRM_ERROR("Invalid crtc %u\n", pipe); - return false; - } - - /* Get associated drm_crtc: */ - crtc = &adev->mode_info.crtcs[pipe]->base; - if (!crtc) { - /* This can occur on driver load if some component fails to - * initialize completely and driver is unloaded */ - DRM_ERROR("Uninitialized crtc %d\n", pipe); - return false; - } - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, in_vblank_irq, - &crtc->hwmode); -} - const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index cdb064b46d04..46c923848c16 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -682,6 +682,7 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc, vblank->linedur_ns = linedur_ns; vblank->framedur_ns = framedur_ns; + vblank->hwmode = *mode; DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n", crtc->base.id, mode->crtc_htotal, @@ -702,7 +703,6 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * True when called from drm_crtc_handle_vblank(). Some drivers * need to apply some workarounds for gpu-specific vblank irq quirks * if flag is set. - * @mode: mode which defines the scanout timings * * Implements calculation of exact vblank timestamps from given drm_display_mode * timings and current video scanout position of a CRTC. This can be called from @@ -722,6 +722,13 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * returns as no operation if a doublescan or interlaced video mode is * active. Higher level code is expected to handle this. * + * This function can be used to implement the &drm_driver.get_vblank_timestamp + * directly, if the driver implements the &drm_driver.get_scanout_position hook. + * + * Note that atomic drivers must call drm_calc_timestamping_constants() before + * enabling a CRTC. The atomic helpers already take care of that in + * drm_atomic_helper_update_legacy_modeset_state(). + * * Returns: * * Returns true on success, and false on failure, i.e. when no accurate @@ -731,17 +738,24 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - bool in_vblank_irq, - const struct drm_display_mode *mode) + bool in_vblank_irq) { struct timeval tv_etime; ktime_t stime, etime; unsigned int vbl_status; + struct drm_crtc *crtc; + const struct drm_display_mode *mode; + struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; int vpos, hpos, i; int delta_ns, duration_ns; unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0; - if (pipe >= dev->num_crtcs) { + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return false; + + crtc = drm_crtc_from_index(dev, pipe); + + if (pipe >= dev->num_crtcs || !crtc) { DRM_ERROR("Invalid crtc %u\n", pipe); return false; } @@ -752,6 +766,11 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, return false; } + if (drm_drv_uses_atomic_modeset(dev)) + mode = &vblank->hwmode; + else + mode = &crtc->hwmode; + /* If mode timing undefined, just return as no-op: * Happens during initial modesetting of a crtc. */ diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6c8a7e1284c3..feadfea77354 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -964,37 +964,6 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) return position; } -static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_crtc *crtc; - - if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { - DRM_ERROR("Invalid crtc %u\n", pipe); - return false; - } - - /* Get drm_crtc to timestamp: */ - crtc = intel_get_crtc_for_pipe(dev_priv, pipe); - if (crtc == NULL) { - DRM_ERROR("Invalid crtc %u\n", pipe); - return false; - } - - if (!crtc->base.hwmode.crtc_clock) { - DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); - return false; - } - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, in_vblank_irq, - &crtc->base.hwmode); -} - static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) { u32 busy_up, busy_down, max_avg, min_avg; @@ -4328,7 +4297,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv) dev_priv->hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD; - dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; + dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; if (IS_CHERRYVIEW(dev_priv)) { diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 16184ccbdd3b..6ba216b8bba9 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -595,30 +595,6 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, return ret; } -static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct msm_drm_private *priv = dev->dev_private; - struct drm_crtc *crtc; - - if (pipe < 0 || pipe >= priv->num_crtcs) { - DRM_ERROR("Invalid crtc %d\n", pipe); - return false; - } - - crtc = priv->crtcs[pipe]; - if (!crtc) { - DRM_ERROR("Invalid crtc %d\n", pipe); - return false; - } - - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, in_vblank_irq, - &crtc->mode); -} - static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { struct msm_drm_private *priv = dev->dev_private; @@ -728,7 +704,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) dev->mode_config.max_width = 0xffff; dev->mode_config.max_height = 0xffff; - dev->driver->get_vblank_timestamp = mdp5_get_vblank_timestamp; + dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; dev->driver->get_scanout_position = mdp5_get_scanoutpos; dev->driver->get_vblank_counter = mdp5_get_vblank_counter; dev->max_vblank_count = 0xffffffff; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index be8ec18ba126..e4bdac13d4e9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -156,28 +156,6 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, return 0; } -bool -nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, - int *max_error, struct timeval *time, bool in_vblank_irq) -{ - struct drm_crtc *crtc; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (nouveau_crtc(crtc)->index == pipe) { - struct drm_display_mode *mode; - if (drm_drv_uses_atomic_modeset(dev)) - mode = &crtc->state->adjusted_mode; - else - mode = &crtc->hwmode; - return drm_calc_vbltimestamp_from_scanoutpos(dev, - pipe, max_error, time, in_vblank_irq, - mode); - } - } - - return false; -} - static void nouveau_display_vblank_fini(struct drm_device *dev) { diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index f821fc9e2de3..8360a85ed5ef 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -71,8 +71,6 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); -bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, - struct timeval *, bool); int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index ec719df619a6..1f751a3f570c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -978,7 +978,7 @@ driver_stub = { .enable_vblank = nouveau_display_vblank_enable, .disable_vblank = nouveau_display_vblank_disable, .get_scanout_position = nouveau_display_scanoutpos, - .get_vblank_timestamp = nouveau_display_vblstamp, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .ioctls = nouveau_ioctls, .num_ioctls = ARRAY_SIZE(nouveau_ioctls), diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 5fbbc6ac165d..a4bf09cd33f7 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,10 +114,6 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq); void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); @@ -543,7 +539,7 @@ static struct drm_driver kms_driver = { .get_vblank_counter = radeon_get_vblank_counter_kms, .enable_vblank = radeon_enable_vblank_kms, .disable_vblank = radeon_disable_vblank_kms, - .get_vblank_timestamp = radeon_get_vblank_timestamp_kms, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .get_scanout_position = radeon_get_crtc_scanoutpos, .irq_preinstall = radeon_driver_irq_preinstall_kms, .irq_postinstall = radeon_driver_irq_postinstall_kms, diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 41765d18f863..33b8b3d22969 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -857,43 +857,6 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) spin_unlock_irqrestore(&rdev->irq.lock, irqflags); } -/** - * radeon_get_vblank_timestamp_kms - get vblank timestamp - * - * @dev: drm dev pointer - * @crtc: crtc to get the timestamp for - * @max_error: max error - * @vblank_time: time value - * @flags: flags passed to the driver - * - * Gets the timestamp on the requested crtc based on the - * scanout position. (all asics). - * Returns true on success, false on failure. - */ -bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_crtc *drmcrtc; - struct radeon_device *rdev = dev->dev_private; - - if (crtc < 0 || crtc >= dev->num_crtcs) { - DRM_ERROR("Invalid crtc %d\n", crtc); - return false; - } - - /* Get associated drm_crtc: */ - drmcrtc = &rdev->mode_info.crtcs[crtc]->base; - if (!drmcrtc) - return false; - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, - vblank_time, in_vblank_irq, - &drmcrtc->hwmode); -} - const struct drm_ioctl_desc radeon_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(RADEON_CP_START, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 18bd0d816fe3..2567d6c9a4ee 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -270,19 +270,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, return ret; } -bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, - int *max_error, struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); - struct drm_crtc_state *state = crtc->state; - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc_id, max_error, - vblank_time, in_vblank_irq, - &state->adjusted_mode); -} - static void vc4_crtc_destroy(struct drm_crtc *crtc) { drm_crtc_cleanup(crtc); diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 61e674baf3a6..e864256e12e5 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -154,7 +154,7 @@ static struct drm_driver vc4_drm_driver = { .irq_uninstall = vc4_irq_uninstall, .get_scanout_position = vc4_crtc_get_scanoutpos, - .get_vblank_timestamp = vc4_crtc_get_vblank_timestamp, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, #if defined(CONFIG_DEBUG_FS) .debugfs_init = vc4_debugfs_init, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 815cdeb54971..64c92e0eb8f7 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -450,9 +450,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); -bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, - int *max_error, struct timeval *vblank_time, - bool in_vblank_irq); /* vc4_debugfs.c */ int vc4_debugfs_init(struct drm_minor *minor); diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index 445406efb8dc..b489cc856e7a 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -121,6 +121,18 @@ struct drm_vblank_crtc { * drm_calc_timestamping_constants(). */ int linedur_ns; + + /** + * @hwmode: + * + * Cache of the current hardware display mode. Only valide when @enabled + * is set. This is used by helpers like + * drm_calc_vbltimestamp_from_scanoutpos(). We can't just access the + * hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode, + * because that one is really hard to get at from interrupt context. + */ + struct drm_display_mode hwmode; + /** * @enabled: Tracks the enabling state of the corresponding &drm_crtc to * avoid double-disabling and hence corrupting saved state. Needed by @@ -156,8 +168,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc); bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - bool in_vblank_irq, - const struct drm_display_mode *mode); + bool in_vblank_irq); void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode); -- 2.11.0 _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH] drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos 2017-03-22 20:56 ` [PATCH] " Daniel Vetter @ 2017-03-30 12:03 ` Ville Syrjälä [not found] ` <20170330120326.GG30290-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> 0 siblings, 1 reply; 19+ messages in thread From: Ville Syrjälä @ 2017-03-30 12:03 UTC (permalink / raw) To: Daniel Vetter Cc: linux-arm-msm, Intel Graphics Development, DRI Development, Ben Skeggs, Mario Kleiner, Alex Deucher, Daniel Vetter, freedreno, Christian König On Wed, Mar 22, 2017 at 09:56:12PM +0100, Daniel Vetter wrote: > 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 update 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(). i915 clear crtc->hwmode.crtc_clock when turning the crtc off, which this does not do for the new vblank->hwmode. I guess no one should really end up in these codepaths with a disabled crtc, but parts of drm_irq.c sort of look like they're expecting it to happen. So should we have some way to clear out the vblank->hwmode.crtc_clock for disabled crtcs? And then maybe make some of these crtc_clock checks WARN and eventually just nuke it all if it looks like nothing is hitting those? > 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. > > 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> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 --- > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 41 ------------------------------- > drivers/gpu/drm/drm_irq.c | 27 +++++++++++++++++--- > drivers/gpu/drm/i915/i915_irq.c | 33 +------------------------ > drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 26 +------------------- > drivers/gpu/drm/nouveau/nouveau_display.c | 22 ----------------- > drivers/gpu/drm/nouveau/nouveau_display.h | 2 -- > drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +- > drivers/gpu/drm/radeon/radeon_drv.c | 6 +---- > drivers/gpu/drm/radeon/radeon_kms.c | 37 ---------------------------- > drivers/gpu/drm/vc4/vc4_crtc.c | 13 ---------- > drivers/gpu/drm/vc4/vc4_drv.c | 2 +- > drivers/gpu/drm/vc4/vc4_drv.h | 3 --- > include/drm/drm_irq.h | 15 +++++++++-- > 15 files changed, 42 insertions(+), 193 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index edb3bb83e1a9..61bef9609b24 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -1768,10 +1768,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); > u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); > int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); > void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); > -bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > - int *max_error, > - struct timeval *vblank_time, > - bool in_vblank_irq); > long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, > unsigned long arg); > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > index 8a61296fd4cc..ba169a0699d5 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > @@ -692,7 +692,7 @@ static struct drm_driver kms_driver = { > .get_vblank_counter = amdgpu_get_vblank_counter_kms, > .enable_vblank = amdgpu_enable_vblank_kms, > .disable_vblank = amdgpu_disable_vblank_kms, > - .get_vblank_timestamp = amdgpu_get_vblank_timestamp_kms, > + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, > .get_scanout_position = amdgpu_get_crtc_scanoutpos, > #if defined(CONFIG_DEBUG_FS) > .debugfs_init = amdgpu_debugfs_init, > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > index ad295e822d45..32a492bd4e51 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > @@ -827,47 +827,6 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) > amdgpu_irq_put(adev, &adev->crtc_irq, idx); > } > > -/** > - * amdgpu_get_vblank_timestamp_kms - get vblank timestamp > - * > - * @dev: drm dev pointer > - * @crtc: crtc to get the timestamp for > - * @max_error: max error > - * @vblank_time: time value > - * @in_vblank_irq: called from drm_handle_vblank() > - * > - * Gets the timestamp on the requested crtc based on the > - * scanout position. (all asics). > - * Returns true on success, false on failure. > - */ > -bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > - int *max_error, > - struct timeval *vblank_time, > - bool in_vblank_irq) > -{ > - struct drm_crtc *crtc; > - struct amdgpu_device *adev = dev->dev_private; > - > - if (pipe >= dev->num_crtcs) { > - DRM_ERROR("Invalid crtc %u\n", pipe); > - return false; > - } > - > - /* Get associated drm_crtc: */ > - crtc = &adev->mode_info.crtcs[pipe]->base; > - if (!crtc) { > - /* This can occur on driver load if some component fails to > - * initialize completely and driver is unloaded */ > - DRM_ERROR("Uninitialized crtc %d\n", pipe); > - return false; > - } > - > - /* Helper routine in DRM core does all the work: */ > - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, > - vblank_time, in_vblank_irq, > - &crtc->hwmode); > -} > - > const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { > DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), > DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), > diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c > index cdb064b46d04..46c923848c16 100644 > --- a/drivers/gpu/drm/drm_irq.c > +++ b/drivers/gpu/drm/drm_irq.c > @@ -682,6 +682,7 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc, > > vblank->linedur_ns = linedur_ns; > vblank->framedur_ns = framedur_ns; > + vblank->hwmode = *mode; > > DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n", > crtc->base.id, mode->crtc_htotal, > @@ -702,7 +703,6 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); > * True when called from drm_crtc_handle_vblank(). Some drivers > * need to apply some workarounds for gpu-specific vblank irq quirks > * if flag is set. > - * @mode: mode which defines the scanout timings > * > * Implements calculation of exact vblank timestamps from given drm_display_mode > * timings and current video scanout position of a CRTC. This can be called from > @@ -722,6 +722,13 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); > * returns as no operation if a doublescan or interlaced video mode is > * active. Higher level code is expected to handle this. > * > + * This function can be used to implement the &drm_driver.get_vblank_timestamp > + * directly, if the driver implements the &drm_driver.get_scanout_position hook. > + * > + * Note that atomic drivers must call drm_calc_timestamping_constants() before > + * enabling a CRTC. The atomic helpers already take care of that in > + * drm_atomic_helper_update_legacy_modeset_state(). > + * > * Returns: > * > * Returns true on success, and false on failure, i.e. when no accurate > @@ -731,17 +738,24 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > unsigned int pipe, > int *max_error, > struct timeval *vblank_time, > - bool in_vblank_irq, > - const struct drm_display_mode *mode) > + bool in_vblank_irq) > { > struct timeval tv_etime; > ktime_t stime, etime; > unsigned int vbl_status; > + struct drm_crtc *crtc; > + const struct drm_display_mode *mode; > + struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; > int vpos, hpos, i; > int delta_ns, duration_ns; > unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0; > > - if (pipe >= dev->num_crtcs) { > + if (!drm_core_check_feature(dev, DRIVER_MODESET)) > + return false; > + > + crtc = drm_crtc_from_index(dev, pipe); > + > + if (pipe >= dev->num_crtcs || !crtc) { > DRM_ERROR("Invalid crtc %u\n", pipe); > return false; > } > @@ -752,6 +766,11 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > return false; > } > > + if (drm_drv_uses_atomic_modeset(dev)) > + mode = &vblank->hwmode; > + else > + mode = &crtc->hwmode; > + > /* If mode timing undefined, just return as no-op: > * Happens during initial modesetting of a crtc. > */ > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > index 6c8a7e1284c3..feadfea77354 100644 > --- a/drivers/gpu/drm/i915/i915_irq.c > +++ b/drivers/gpu/drm/i915/i915_irq.c > @@ -964,37 +964,6 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) > return position; > } > > -static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > - int *max_error, > - struct timeval *vblank_time, > - bool in_vblank_irq) > -{ > - struct drm_i915_private *dev_priv = to_i915(dev); > - struct intel_crtc *crtc; > - > - if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { > - DRM_ERROR("Invalid crtc %u\n", pipe); > - return false; > - } > - > - /* Get drm_crtc to timestamp: */ > - crtc = intel_get_crtc_for_pipe(dev_priv, pipe); > - if (crtc == NULL) { > - DRM_ERROR("Invalid crtc %u\n", pipe); > - return false; > - } > - > - if (!crtc->base.hwmode.crtc_clock) { > - DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); > - return false; > - } > - > - /* Helper routine in DRM core does all the work: */ > - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, > - vblank_time, in_vblank_irq, > - &crtc->base.hwmode); > -} > - > static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) > { > u32 busy_up, busy_down, max_avg, min_avg; > @@ -4328,7 +4297,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv) > > dev_priv->hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD; > > - dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; > + dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; > dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; > > if (IS_CHERRYVIEW(dev_priv)) { > diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > index 16184ccbdd3b..6ba216b8bba9 100644 > --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c > @@ -595,30 +595,6 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, > return ret; > } > > -static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, > - int *max_error, > - struct timeval *vblank_time, > - bool in_vblank_irq) > -{ > - struct msm_drm_private *priv = dev->dev_private; > - struct drm_crtc *crtc; > - > - if (pipe < 0 || pipe >= priv->num_crtcs) { > - DRM_ERROR("Invalid crtc %d\n", pipe); > - return false; > - } > - > - crtc = priv->crtcs[pipe]; > - if (!crtc) { > - DRM_ERROR("Invalid crtc %d\n", pipe); > - return false; > - } > - > - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, > - vblank_time, in_vblank_irq, > - &crtc->mode); > -} > - > static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) > { > struct msm_drm_private *priv = dev->dev_private; > @@ -728,7 +704,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) > dev->mode_config.max_width = 0xffff; > dev->mode_config.max_height = 0xffff; > > - dev->driver->get_vblank_timestamp = mdp5_get_vblank_timestamp; > + dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; > dev->driver->get_scanout_position = mdp5_get_scanoutpos; > dev->driver->get_vblank_counter = mdp5_get_vblank_counter; > dev->max_vblank_count = 0xffffffff; > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c > index be8ec18ba126..e4bdac13d4e9 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_display.c > +++ b/drivers/gpu/drm/nouveau/nouveau_display.c > @@ -156,28 +156,6 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, > return 0; > } > > -bool > -nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, > - int *max_error, struct timeval *time, bool in_vblank_irq) > -{ > - struct drm_crtc *crtc; > - > - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { > - if (nouveau_crtc(crtc)->index == pipe) { > - struct drm_display_mode *mode; > - if (drm_drv_uses_atomic_modeset(dev)) > - mode = &crtc->state->adjusted_mode; > - else > - mode = &crtc->hwmode; > - return drm_calc_vbltimestamp_from_scanoutpos(dev, > - pipe, max_error, time, in_vblank_irq, > - mode); > - } > - } > - > - return false; > -} > - > static void > nouveau_display_vblank_fini(struct drm_device *dev) > { > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h > index f821fc9e2de3..8360a85ed5ef 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_display.h > +++ b/drivers/gpu/drm/nouveau/nouveau_display.h > @@ -71,8 +71,6 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); > int nouveau_display_scanoutpos(struct drm_device *, unsigned int, > unsigned int, int *, int *, ktime_t *, > ktime_t *, const struct drm_display_mode *); > -bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, > - struct timeval *, bool); > > int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, > struct drm_pending_vblank_event *event, > diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c > index ec719df619a6..1f751a3f570c 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_drm.c > +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c > @@ -978,7 +978,7 @@ driver_stub = { > .enable_vblank = nouveau_display_vblank_enable, > .disable_vblank = nouveau_display_vblank_disable, > .get_scanout_position = nouveau_display_scanoutpos, > - .get_vblank_timestamp = nouveau_display_vblstamp, > + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, > > .ioctls = nouveau_ioctls, > .num_ioctls = ARRAY_SIZE(nouveau_ioctls), > diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c > index 5fbbc6ac165d..a4bf09cd33f7 100644 > --- a/drivers/gpu/drm/radeon/radeon_drv.c > +++ b/drivers/gpu/drm/radeon/radeon_drv.c > @@ -114,10 +114,6 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); > u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); > int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); > void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); > -bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, > - int *max_error, > - struct timeval *vblank_time, > - bool in_vblank_irq); > void radeon_driver_irq_preinstall_kms(struct drm_device *dev); > int radeon_driver_irq_postinstall_kms(struct drm_device *dev); > void radeon_driver_irq_uninstall_kms(struct drm_device *dev); > @@ -543,7 +539,7 @@ static struct drm_driver kms_driver = { > .get_vblank_counter = radeon_get_vblank_counter_kms, > .enable_vblank = radeon_enable_vblank_kms, > .disable_vblank = radeon_disable_vblank_kms, > - .get_vblank_timestamp = radeon_get_vblank_timestamp_kms, > + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, > .get_scanout_position = radeon_get_crtc_scanoutpos, > .irq_preinstall = radeon_driver_irq_preinstall_kms, > .irq_postinstall = radeon_driver_irq_postinstall_kms, > diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c > index 41765d18f863..33b8b3d22969 100644 > --- a/drivers/gpu/drm/radeon/radeon_kms.c > +++ b/drivers/gpu/drm/radeon/radeon_kms.c > @@ -857,43 +857,6 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) > spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > } > > -/** > - * radeon_get_vblank_timestamp_kms - get vblank timestamp > - * > - * @dev: drm dev pointer > - * @crtc: crtc to get the timestamp for > - * @max_error: max error > - * @vblank_time: time value > - * @flags: flags passed to the driver > - * > - * Gets the timestamp on the requested crtc based on the > - * scanout position. (all asics). > - * Returns true on success, false on failure. > - */ > -bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, > - int *max_error, > - struct timeval *vblank_time, > - bool in_vblank_irq) > -{ > - struct drm_crtc *drmcrtc; > - struct radeon_device *rdev = dev->dev_private; > - > - if (crtc < 0 || crtc >= dev->num_crtcs) { > - DRM_ERROR("Invalid crtc %d\n", crtc); > - return false; > - } > - > - /* Get associated drm_crtc: */ > - drmcrtc = &rdev->mode_info.crtcs[crtc]->base; > - if (!drmcrtc) > - return false; > - > - /* Helper routine in DRM core does all the work: */ > - return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, > - vblank_time, in_vblank_irq, > - &drmcrtc->hwmode); > -} > - > const struct drm_ioctl_desc radeon_ioctls_kms[] = { > DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), > DRM_IOCTL_DEF_DRV(RADEON_CP_START, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), > diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c > index 18bd0d816fe3..2567d6c9a4ee 100644 > --- a/drivers/gpu/drm/vc4/vc4_crtc.c > +++ b/drivers/gpu/drm/vc4/vc4_crtc.c > @@ -270,19 +270,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, > return ret; > } > > -bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > - int *max_error, struct timeval *vblank_time, > - bool in_vblank_irq) > -{ > - struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); > - struct drm_crtc_state *state = crtc->state; > - > - /* Helper routine in DRM core does all the work: */ > - return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc_id, max_error, > - vblank_time, in_vblank_irq, > - &state->adjusted_mode); > -} > - > static void vc4_crtc_destroy(struct drm_crtc *crtc) > { > drm_crtc_cleanup(crtc); > diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c > index 61e674baf3a6..e864256e12e5 100644 > --- a/drivers/gpu/drm/vc4/vc4_drv.c > +++ b/drivers/gpu/drm/vc4/vc4_drv.c > @@ -154,7 +154,7 @@ static struct drm_driver vc4_drm_driver = { > .irq_uninstall = vc4_irq_uninstall, > > .get_scanout_position = vc4_crtc_get_scanoutpos, > - .get_vblank_timestamp = vc4_crtc_get_vblank_timestamp, > + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, > > #if defined(CONFIG_DEBUG_FS) > .debugfs_init = vc4_debugfs_init, > diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h > index 815cdeb54971..64c92e0eb8f7 100644 > --- a/drivers/gpu/drm/vc4/vc4_drv.h > +++ b/drivers/gpu/drm/vc4/vc4_drv.h > @@ -450,9 +450,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, > unsigned int flags, int *vpos, int *hpos, > ktime_t *stime, ktime_t *etime, > const struct drm_display_mode *mode); > -bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, > - int *max_error, struct timeval *vblank_time, > - bool in_vblank_irq); > > /* vc4_debugfs.c */ > int vc4_debugfs_init(struct drm_minor *minor); > diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h > index 445406efb8dc..b489cc856e7a 100644 > --- a/include/drm/drm_irq.h > +++ b/include/drm/drm_irq.h > @@ -121,6 +121,18 @@ struct drm_vblank_crtc { > * drm_calc_timestamping_constants(). > */ > int linedur_ns; > + > + /** > + * @hwmode: > + * > + * Cache of the current hardware display mode. Only valide when @enabled > + * is set. This is used by helpers like > + * drm_calc_vbltimestamp_from_scanoutpos(). We can't just access the > + * hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode, > + * because that one is really hard to get at from interrupt context. > + */ > + struct drm_display_mode hwmode; > + > /** > * @enabled: Tracks the enabling state of the corresponding &drm_crtc to > * avoid double-disabling and hence corrupting saved state. Needed by > @@ -156,8 +168,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc); > bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > unsigned int pipe, int *max_error, > struct timeval *vblank_time, > - bool in_vblank_irq, > - const struct drm_display_mode *mode); > + bool in_vblank_irq); > void drm_calc_timestamping_constants(struct drm_crtc *crtc, > const struct drm_display_mode *mode); > > -- > 2.11.0 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 19+ messages in thread
[parent not found: <20170330120326.GG30290-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>]
* Re: [Intel-gfx] [PATCH] drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos [not found] ` <20170330120326.GG30290-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> @ 2017-03-30 13:27 ` Daniel Vetter 2017-03-30 13:41 ` Ville Syrjälä 0 siblings, 1 reply; 19+ messages in thread From: Daniel Vetter @ 2017-03-30 13:27 UTC (permalink / raw) To: Ville Syrjälä Cc: linux-arm-msm, Intel Graphics Development, DRI Development, Ben Skeggs, Mario Kleiner, Alex Deucher, Daniel Vetter, freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Christian König On Thu, Mar 30, 2017 at 2:03 PM, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote: > On Wed, Mar 22, 2017 at 09:56:12PM +0100, Daniel Vetter wrote: >> 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 update 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(). > > i915 clear crtc->hwmode.crtc_clock when turning the crtc off, which > this does not do for the new vblank->hwmode. I guess no one should > really end up in these codepaths with a disabled crtc, but parts of > drm_irq.c sort of look like they're expecting it to happen. > > So should we have some way to clear out the vblank->hwmode.crtc_clock > for disabled crtcs? And then maybe make some of these crtc_clock checks > WARN and eventually just nuke it all if it looks like nothing is hitting > those? So the trouble is that with a pile of dpms on/off/on/off you could run drm_crtc_vblank_on/off a lot, without ever calling the drm_calc_vbltimestamps helper again to re-upload the mode. So I don't think we can clear vblank->hwmode.crtc_clock unfortunately in drm_crtc_vblank_off. But what we could do (at least with atomic) is WARN in the vblank helper if it's called outside of drm_vblank_on/off ... Not sure how useful that is (it won't catch when a driver outright forgets to call these) or whether we have enough checks already. Would be a separate patch (can do ofc if we agree on what exactly). -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [Intel-gfx] [PATCH] drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos 2017-03-30 13:27 ` [Intel-gfx] " Daniel Vetter @ 2017-03-30 13:41 ` Ville Syrjälä [not found] ` <20170330134157.GI30290-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> 0 siblings, 1 reply; 19+ messages in thread From: Ville Syrjälä @ 2017-03-30 13:41 UTC (permalink / raw) To: Daniel Vetter Cc: Intel Graphics Development, linux-arm-msm, DRI Development, Ben Skeggs, Mario Kleiner, Alex Deucher, Daniel Vetter, freedreno, Christian König On Thu, Mar 30, 2017 at 03:27:57PM +0200, Daniel Vetter wrote: > On Thu, Mar 30, 2017 at 2:03 PM, Ville Syrjälä > <ville.syrjala@linux.intel.com> wrote: > > On Wed, Mar 22, 2017 at 09:56:12PM +0100, Daniel Vetter wrote: > >> 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 update 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(). > > > > i915 clear crtc->hwmode.crtc_clock when turning the crtc off, which > > this does not do for the new vblank->hwmode. I guess no one should > > really end up in these codepaths with a disabled crtc, but parts of > > drm_irq.c sort of look like they're expecting it to happen. > > > > So should we have some way to clear out the vblank->hwmode.crtc_clock > > for disabled crtcs? And then maybe make some of these crtc_clock checks > > WARN and eventually just nuke it all if it looks like nothing is hitting > > those? > > So the trouble is that with a pile of dpms on/off/on/off you could run > drm_crtc_vblank_on/off a lot, without ever calling the > drm_calc_vbltimestamps helper again to re-upload the mode. So I don't > think we can clear vblank->hwmode.crtc_clock unfortunately in > drm_crtc_vblank_off. I was thinking that we'd just try to avoid making pontetially functional changes here. Ie. reset where we currently reset, which I think is somewhere in the atomic commit for i915, but definitely not in drm_crtc_vblank_off(). > > But what we could do (at least with atomic) is WARN in the vblank > helper if it's called outside of drm_vblank_on/off ... Not sure how > useful that is (it won't catch when a driver outright forgets to call > these) or whether we have enough checks already. Would be a separate > patch (can do ofc if we agree on what exactly). > -Daniel > -- > Daniel Vetter > Software Engineer, Intel Corporation > +41 (0) 79 365 57 48 - http://blog.ffwll.ch -- Ville Syrjälä Intel OTC ^ permalink raw reply [flat|nested] 19+ messages in thread
[parent not found: <20170330134157.GI30290-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>]
* Re: [Intel-gfx] [PATCH] drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos [not found] ` <20170330134157.GI30290-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> @ 2017-03-30 18:27 ` Daniel Vetter [not found] ` <20170330182740.p4joh3spt4ghxco4-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org> 0 siblings, 1 reply; 19+ messages in thread From: Daniel Vetter @ 2017-03-30 18:27 UTC (permalink / raw) To: Ville Syrjälä Cc: Daniel Vetter, Intel Graphics Development, DRI Development, Ben Skeggs, Mario Kleiner, linux-arm-msm, Alex Deucher, Daniel Vetter, freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Christian König On Thu, Mar 30, 2017 at 04:41:57PM +0300, Ville Syrjälä wrote: > On Thu, Mar 30, 2017 at 03:27:57PM +0200, Daniel Vetter wrote: > > On Thu, Mar 30, 2017 at 2:03 PM, Ville Syrjälä > > <ville.syrjala@linux.intel.com> wrote: > > > On Wed, Mar 22, 2017 at 09:56:12PM +0100, Daniel Vetter wrote: > > >> 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 update 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(). > > > > > > i915 clear crtc->hwmode.crtc_clock when turning the crtc off, which > > > this does not do for the new vblank->hwmode. I guess no one should > > > really end up in these codepaths with a disabled crtc, but parts of > > > drm_irq.c sort of look like they're expecting it to happen. > > > > > > So should we have some way to clear out the vblank->hwmode.crtc_clock > > > for disabled crtcs? And then maybe make some of these crtc_clock checks > > > WARN and eventually just nuke it all if it looks like nothing is hitting > > > those? > > > > So the trouble is that with a pile of dpms on/off/on/off you could run > > drm_crtc_vblank_on/off a lot, without ever calling the > > drm_calc_vbltimestamps helper again to re-upload the mode. So I don't > > think we can clear vblank->hwmode.crtc_clock unfortunately in > > drm_crtc_vblank_off. > > I was thinking that we'd just try to avoid making pontetially functional > changes here. Ie. reset where we currently reset, which I think is somewhere > in the atomic commit for i915, but definitely not in drm_crtc_vblank_off(). Hm, sounds like a good idea. I'll try to shuffle things around. Upon re-reading all that stuff I also noticed that atm i915 only calls the helper that would update vblank->hwmode when we do a full modeset, but not when we just fastset. Shouldn't matter, because the hwmode will match, but better safe than sorry. I'll re-read all that stuff again and will try to lock it down fully, like we have now, and remove the i915 crtc->hwmode access maybe entirely while at it. -Daniel > > > > > But what we could do (at least with atomic) is WARN in the vblank > > helper if it's called outside of drm_vblank_on/off ... Not sure how > > useful that is (it won't catch when a driver outright forgets to call > > these) or whether we have enough checks already. Would be a separate > > patch (can do ofc if we agree on what exactly). > > -Daniel > > -- > > Daniel Vetter > > Software Engineer, Intel Corporation > > +41 (0) 79 365 57 48 - http://blog.ffwll.ch > > -- > Ville Syrjälä > Intel OTC -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno ^ permalink raw reply [flat|nested] 19+ messages in thread
[parent not found: <20170330182740.p4joh3spt4ghxco4-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>]
* Re: [Intel-gfx] [PATCH] drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos [not found] ` <20170330182740.p4joh3spt4ghxco4-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org> @ 2017-04-04 9:54 ` Daniel Vetter 0 siblings, 0 replies; 19+ messages in thread From: Daniel Vetter @ 2017-04-04 9:54 UTC (permalink / raw) To: Ville Syrjälä Cc: Daniel Vetter, Intel Graphics Development, DRI Development, Ben Skeggs, Mario Kleiner, linux-arm-msm, Alex Deucher, Daniel Vetter, freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Christian König On Thu, Mar 30, 2017 at 08:27:40PM +0200, Daniel Vetter wrote: > On Thu, Mar 30, 2017 at 04:41:57PM +0300, Ville Syrjälä wrote: > > On Thu, Mar 30, 2017 at 03:27:57PM +0200, Daniel Vetter wrote: > > > On Thu, Mar 30, 2017 at 2:03 PM, Ville Syrjälä > > > <ville.syrjala@linux.intel.com> wrote: > > > > On Wed, Mar 22, 2017 at 09:56:12PM +0100, Daniel Vetter wrote: > > > >> 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 update 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(). > > > > > > > > i915 clear crtc->hwmode.crtc_clock when turning the crtc off, which > > > > this does not do for the new vblank->hwmode. I guess no one should > > > > really end up in these codepaths with a disabled crtc, but parts of > > > > drm_irq.c sort of look like they're expecting it to happen. > > > > > > > > So should we have some way to clear out the vblank->hwmode.crtc_clock > > > > for disabled crtcs? And then maybe make some of these crtc_clock checks > > > > WARN and eventually just nuke it all if it looks like nothing is hitting > > > > those? > > > > > > So the trouble is that with a pile of dpms on/off/on/off you could run > > > drm_crtc_vblank_on/off a lot, without ever calling the > > > drm_calc_vbltimestamps helper again to re-upload the mode. So I don't > > > think we can clear vblank->hwmode.crtc_clock unfortunately in > > > drm_crtc_vblank_off. > > > > I was thinking that we'd just try to avoid making pontetially functional > > changes here. Ie. reset where we currently reset, which I think is somewhere > > in the atomic commit for i915, but definitely not in drm_crtc_vblank_off(). > > Hm, sounds like a good idea. I'll try to shuffle things around. Upon > re-reading all that stuff I also noticed that atm i915 only calls the > helper that would update vblank->hwmode when we do a full modeset, but not > when we just fastset. Shouldn't matter, because the hwmode will match, but > better safe than sorry. > > I'll re-read all that stuff again and will try to lock it down fully, like > we have now, and remove the i915 crtc->hwmode access maybe entirely while > at it. Ok, I stitched something together which I think should work well. Done as a follow-up patch though since this refactoring patch here was already pretty big. Resend the entire pile for CI to double-check, review from you on the vblank stuff would be much appreciated. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2017-04-04 9:54 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <20170322083617.13361-1-daniel.vetter@ffwll.ch> [not found] ` <20170322083617.13361-1-daniel.vetter-/w4YWyX8dFk@public.gmane.org> 2017-03-22 8:36 ` [PATCH 11/16] drm/vblank: Switch drm_driver->get_vblank_timestamp to return a bool Daniel Vetter [not found] ` <20170322083617.13361-12-daniel.vetter-/w4YWyX8dFk@public.gmane.org> 2017-03-22 10:33 ` [Intel-gfx] " Jani Nikula 2017-03-22 13:23 ` Daniel Vetter [not found] ` <20170322132305.zdtehgbox6erdhbq-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org> 2017-03-22 14:05 ` [Intel-gfx] " Jani Nikula [not found] ` <87d1d98kzc.fsf-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> 2017-03-22 17:52 ` Daniel Vetter 2017-03-22 20:55 ` [PATCH] " Daniel Vetter 2017-03-22 8:36 ` [PATCH 15/16] drm/vblank: Simplify the get_scanout_position helper hook Daniel Vetter 2017-03-24 21:28 ` [PATCH] drm/vblank: fix boolreturn.cocci warnings kbuild test robot 2017-03-24 21:28 ` [PATCH 15/16] drm/vblank: Simplify the get_scanout_position helper hook kbuild test robot 2017-03-25 21:37 ` [PATCH] " Daniel Vetter 2017-03-22 8:36 ` [PATCH 12/16] drm/vblank: Switch to bool in_vblank_irq in get_vblank_timestamp Daniel Vetter 2017-03-22 18:23 ` Ville Syrjälä 2017-03-22 8:36 ` [PATCH 14/16] drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos Daniel Vetter [not found] ` <20170322083617.13361-15-daniel.vetter-/w4YWyX8dFk@public.gmane.org> 2017-03-22 20:56 ` [PATCH] " Daniel Vetter 2017-03-30 12:03 ` Ville Syrjälä [not found] ` <20170330120326.GG30290-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> 2017-03-30 13:27 ` [Intel-gfx] " Daniel Vetter 2017-03-30 13:41 ` Ville Syrjälä [not found] ` <20170330134157.GI30290-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> 2017-03-30 18:27 ` Daniel Vetter [not found] ` <20170330182740.p4joh3spt4ghxco4-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org> 2017-04-04 9:54 ` Daniel Vetter
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).