[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <dc2d8602-7a89-6926-2b2d-4aa069076fde@st.com>
Date: Thu, 27 Sep 2018 11:32:00 +0000
From: Yannick FERTRE <yannick.fertre@...com>
To: Philippe CORNU <philippe.cornu@...com>,
Benjamin GAIGNARD <benjamin.gaignard@...com>,
"airlied@...ux.ie" <airlied@...ux.ie>
CC: "dri-devel@...ts.freedesktop.org" <dri-devel@...ts.freedesktop.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH] drm: stm: implement get_scanout_position function
Reviewed-by: Yannick Fertré <yannick.fertre@...com>
Tested-by: Yannick Fertré <yannick.fertre@...com>
On 09/27/2018 10:15 AM, Yannick FERTRE wrote:
> Reviewed-by/tested-by: yannick.fertre@...com
>
> -------- 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@...aro.org>
> To: yannick.fertre@...com, philippe.cornu@...com, airlied@...ux.ie
> CC: dri-devel@...ts.freedesktop.org, linux-kernel@...r.kernel.org,
> Benjamin Gaignard <benjamin.gaignard@...aro.org>, Benjamin Gaignard
> <benjamin.gaignard@...com>
>
> 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@...com>
> ---
> 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
Powered by blists - more mailing lists