Reviewed-by: Yannick Fertré <yannick.fertre@xxxxxx> Tested-by: Yannick Fertré <yannick.fertre@xxxxxx> On 09/27/2018 10:15 AM, Yannick FERTRE wrote: > Reviewed-by/tested-by: yannick.fertre@xxxxxx > > -------- Forwarded Message -------- > Subject: [PATCH] drm: stm: implement get_scanout_position function > Date: Fri, 29 Jun 2018 15:01:40 +0200 > From: Benjamin Gaignard <benjamin.gaignard@xxxxxxxxxx> > To: yannick.fertre@xxxxxx, philippe.cornu@xxxxxx, airlied@xxxxxxxx > CC: dri-devel@xxxxxxxxxxxxxxxxxxxxx, linux-kernel@xxxxxxxxxxxxxxx, > Benjamin Gaignard <benjamin.gaignard@xxxxxxxxxx>, Benjamin Gaignard > <benjamin.gaignard@xxxxxx> > > Hardware allow to read the position in scanout buffer so > we can use this information to make wait of vblank more accurate. > > Active area bounds (start, end, total height) have already been > computed and written in ltdc registers, read them and get the > current line position to compute vpos value. > > Signed-off-by: Benjamin Gaignard <benjamin.gaignard@xxxxxx> > --- > drivers/gpu/drm/stm/drv.c | 2 ++ > drivers/gpu/drm/stm/ltdc.c | 45 > +++++++++++++++++++++++++++++++++++++++++++++ > drivers/gpu/drm/stm/ltdc.h | 5 +++++ > 3 files changed, 52 insertions(+) > > diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c > index 8698e08313e1..ac53383350e3 100644 > --- a/drivers/gpu/drm/stm/drv.c > +++ b/drivers/gpu/drm/stm/drv.c > @@ -72,6 +72,8 @@ static struct drm_driver drv_driver = { > .gem_prime_vmap = drm_gem_cma_prime_vmap, > .gem_prime_vunmap = drm_gem_cma_prime_vunmap, > .gem_prime_mmap = drm_gem_cma_prime_mmap, > + .get_scanout_position = ltdc_crtc_scanoutpos, > + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, > }; > static int drv_load(struct drm_device *ddev) > diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c > index d997a6014d6c..05b714673042 100644 > --- a/drivers/gpu/drm/stm/ltdc.c > +++ b/drivers/gpu/drm/stm/ltdc.c > @@ -148,6 +148,8 @@ > #define IER_TERRIE BIT(2) /* Transfer ERRor Interrupt > Enable */ > #define IER_RRIE BIT(3) /* Register Reload Interrupt > enable */ > +#define CPSR_CYPOS GENMASK(15, 0) /* Current Y position */ > + > #define ISR_LIF BIT(0) /* Line Interrupt Flag */ > #define ISR_FUIF BIT(1) /* Fifo Underrun Interrupt Flag */ > #define ISR_TERRIF BIT(2) /* Transfer ERRor Interrupt Flag */ > @@ -622,6 +624,49 @@ static void ltdc_crtc_disable_vblank(struct > drm_crtc *crtc) > reg_clear(ldev->regs, LTDC_IER, IER_LIE); > } > +bool ltdc_crtc_scanoutpos(struct drm_device *ddev, unsigned int pipe, > + bool in_vblank_irq, int *vpos, int *hpos, > + ktime_t *stime, ktime_t *etime, > + const struct drm_display_mode *mode) > +{ > + struct ltdc_device *ldev = ddev->dev_private; > + int line, vactive_start, vactive_end, vtotal; > + > + if (stime) > + *stime = ktime_get(); > + > + /* The active area starts after vsync + front porch and ends > + * at vsync + front porc + display size. > + * The total height also include back porch. > + * We have 3 possible cases to handle: > + * - line < vactive_start: vpos = line - vactive_start and will be > + * negative > + * - vactive_start < line < vactive_end: vpos = line - vactive_start > + * and will be positive > + * - line > vactive_end: vpos = line - vtotal - vactive_start > + * and will negative > + * > + * Computation for the two first cases are identical so we can > + * simplify the code and only test if line > vactive_end > + */ > + line = reg_read(ldev->regs, LTDC_CPSR) & CPSR_CYPOS; > + vactive_start = reg_read(ldev->regs, LTDC_BPCR) & BPCR_AVBP; > + vactive_end = reg_read(ldev->regs, LTDC_AWCR) & AWCR_AAH; > + vtotal = reg_read(ldev->regs, LTDC_TWCR) & TWCR_TOTALH; > + > + if (line > vactive_end) > + *vpos = line - vtotal - vactive_start; > + else > + *vpos = line - vactive_start; > + > + *hpos = 0; > + > + if (etime) > + *etime = ktime_get(); > + > + return true; > +} > + > static const struct drm_crtc_funcs ltdc_crtc_funcs = { > .destroy = drm_crtc_cleanup, > .set_config = drm_atomic_helper_set_config, > diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h > index 1e16d6afb0d2..b8c5cc41e17a 100644 > --- a/drivers/gpu/drm/stm/ltdc.h > +++ b/drivers/gpu/drm/stm/ltdc.h > @@ -37,6 +37,11 @@ struct ltdc_device { > struct fps_info plane_fpsi[LTDC_MAX_LAYER]; > }; > +bool ltdc_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); > + > int ltdc_load(struct drm_device *ddev); > void ltdc_unload(struct drm_device *ddev); > -- 2.15.0 > -- Yannick Fertré | TINA: 166 7152 | Tel: +33 244027152 | Mobile: +33 620600270 Microcontrollers and Digital ICs Group | Microcontrolleurs Division _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel