LGTM. This one is Reviewed-by: Mario Kleiner <mario.kleiner...@gmail.com>
-mario On Mon, Feb 27, 2023 at 8:36 PM Rob Clark <robdcl...@gmail.com> wrote: > From: Rob Clark <robdcl...@chromium.org> > > Will be used in the next commit to set a deadline on fences that an > atomic update is waiting on. > > v2: Calculate time at *start* of vblank period, not end > v3: Fix kbuild complaints > > Signed-off-by: Rob Clark <robdcl...@chromium.org> > --- > drivers/gpu/drm/drm_vblank.c | 53 ++++++++++++++++++++++++++++++------ > include/drm/drm_vblank.h | 1 + > 2 files changed, 45 insertions(+), 9 deletions(-) > > diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c > index 2ff31717a3de..299fa2a19a90 100644 > --- a/drivers/gpu/drm/drm_vblank.c > +++ b/drivers/gpu/drm/drm_vblank.c > @@ -844,10 +844,9 @@ bool > drm_crtc_vblank_helper_get_vblank_timestamp(struct drm_crtc *crtc, > EXPORT_SYMBOL(drm_crtc_vblank_helper_get_vblank_timestamp); > > /** > - * drm_get_last_vbltimestamp - retrieve raw timestamp for the most recent > - * vblank interval > - * @dev: DRM device > - * @pipe: index of CRTC whose vblank timestamp to retrieve > + * drm_crtc_get_last_vbltimestamp - retrieve raw timestamp for the most > + * recent vblank interval > + * @crtc: CRTC whose vblank timestamp to retrieve > * @tvblank: Pointer to target time which should receive the timestamp > * @in_vblank_irq: > * True when called from drm_crtc_handle_vblank(). Some drivers > @@ -865,10 +864,9 @@ > EXPORT_SYMBOL(drm_crtc_vblank_helper_get_vblank_timestamp); > * True if timestamp is considered to be very precise, false otherwise. > */ > static bool > -drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, > - ktime_t *tvblank, bool in_vblank_irq) > +drm_crtc_get_last_vbltimestamp(struct drm_crtc *crtc, ktime_t *tvblank, > + bool in_vblank_irq) > { > - struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); > bool ret = false; > > /* Define requested maximum error on timestamps (nanoseconds). */ > @@ -876,8 +874,6 @@ drm_get_last_vbltimestamp(struct drm_device *dev, > unsigned int pipe, > > /* Query driver if possible and precision timestamping enabled. */ > if (crtc && crtc->funcs->get_vblank_timestamp && max_error > 0) { > - struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); > - > ret = crtc->funcs->get_vblank_timestamp(crtc, &max_error, > tvblank, > in_vblank_irq); > } > @@ -891,6 +887,15 @@ drm_get_last_vbltimestamp(struct drm_device *dev, > unsigned int pipe, > return ret; > } > > +static bool > +drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, > + ktime_t *tvblank, bool in_vblank_irq) > +{ > + struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); > + > + return drm_crtc_get_last_vbltimestamp(crtc, tvblank, > in_vblank_irq); > +} > + > /** > * drm_crtc_vblank_count - retrieve "cooked" vblank counter value > * @crtc: which counter to retrieve > @@ -980,6 +985,36 @@ u64 drm_crtc_vblank_count_and_time(struct drm_crtc > *crtc, > } > EXPORT_SYMBOL(drm_crtc_vblank_count_and_time); > > +/** > + * drm_crtc_next_vblank_start - calculate the time of the next vblank > + * @crtc: the crtc for which to calculate next vblank time > + * @vblanktime: pointer to time to receive the next vblank timestamp. > + * > + * Calculate the expected time of the start of the next vblank period, > + * based on time of previous vblank and frame duration > + */ > +int drm_crtc_next_vblank_start(struct drm_crtc *crtc, ktime_t *vblanktime) > +{ > + unsigned int pipe = drm_crtc_index(crtc); > + struct drm_vblank_crtc *vblank = &crtc->dev->vblank[pipe]; > + struct drm_display_mode *mode = &vblank->hwmode; > + u64 vblank_start; > + > + if (!vblank->framedur_ns || !vblank->linedur_ns) > + return -EINVAL; > + > + if (!drm_crtc_get_last_vbltimestamp(crtc, vblanktime, false)) > + return -EINVAL; > + > + vblank_start = DIV_ROUND_DOWN_ULL( > + (u64)vblank->framedur_ns * mode->crtc_vblank_start, > + mode->crtc_vtotal); > + *vblanktime = ktime_add(*vblanktime, ns_to_ktime(vblank_start)); > + > + return 0; > +} > +EXPORT_SYMBOL(drm_crtc_next_vblank_start); > + > static void send_vblank_event(struct drm_device *dev, > struct drm_pending_vblank_event *e, > u64 seq, ktime_t now) > diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h > index 733a3e2d1d10..7f3957943dd1 100644 > --- a/include/drm/drm_vblank.h > +++ b/include/drm/drm_vblank.h > @@ -230,6 +230,7 @@ bool drm_dev_has_vblank(const struct drm_device *dev); > u64 drm_crtc_vblank_count(struct drm_crtc *crtc); > u64 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, > ktime_t *vblanktime); > +int drm_crtc_next_vblank_start(struct drm_crtc *crtc, ktime_t > *vblanktime); > void drm_crtc_send_vblank_event(struct drm_crtc *crtc, > struct drm_pending_vblank_event *e); > void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, > -- > 2.39.1 > >