[PATCH 8/8] drm/exynos: fimd: add complete_scanout function

Mandeep Singh Baines msb at chromium.org
Mon Jan 7 14:48:56 PST 2013


On Wed, Dec 26, 2012 at 3:27 AM, Prathyush K <prathyush.k at samsung.com> wrote:
> The wait_for_vblank interface is modified to the complete_scanout
> function in fimd. This patch adds the fimd_complete_scanout function
>

With this series, you have a race if the rmfb happens before the flip
has completed.

Why not just use reference counts as is done in the i915 driver: see unpin_work.
The reference counts also allow you to avoid blocking in rmfb.

Regards,
Mandeep

> Inside fimd_complete_scanout, we read the shadow register for each
> window and compare it with the dma address of the framebuffer. If
> the dma_address is in the shadow register, then the function waits
> for the next vblank and returns.
>
> Signed-off-by: Prathyush K <prathyush.k at samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c | 32 +++++++++++++++++++++++++++++++-
>  include/video/samsung_fimd.h             |  1 +
>  2 files changed, 32 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> index 3aeedf5..190ffde9 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> @@ -46,6 +46,7 @@
>  #define VIDOSD_D(win)          (VIDOSD_BASE + 0x0C + (win) * 16)
>
>  #define VIDWx_BUF_START(win, buf)      (VIDW_BUF_START(buf) + (win) * 8)
> +#define VIDWx_BUF_START_S(win, buf)    (VIDW_BUF_START_S(buf) + (win) * 8)
>  #define VIDWx_BUF_END(win, buf)                (VIDW_BUF_END(buf) + (win) * 8)
>  #define VIDWx_BUF_SIZE(win, buf)       (VIDW_BUF_SIZE(buf) + (win) * 4)
>
> @@ -363,13 +364,42 @@ static void fimd_wait_for_vblank(struct device *dev)
>                 fimd_disable_vblank(dev);
>  }
>
> +static void fimd_complete_scanout(struct device *dev, dma_addr_t dma_addr,
> +                                       unsigned long size)
> +{
> +       struct fimd_context *ctx = get_fimd_context(dev);
> +       int win;
> +       bool in_use = false;
> +
> +       if (ctx->suspended)
> +               return;
> +
> +       for (win = 0; win < WINDOWS_NR; win++) {
> +               dma_addr_t dma_addr_in_use;
> +
> +               if (!ctx->win_data[win].enabled)
> +                       continue;
> +
> +               dma_addr_in_use = readl(ctx->regs + VIDWx_BUF_START_S(win, 0));
> +               if (dma_addr_in_use >= dma_addr &&
> +                       dma_addr_in_use < (dma_addr + size)) {
> +                               in_use = true;
> +                               break;
> +               }
> +       }
> +
> +       if (in_use)
> +               fimd_wait_for_vblank(dev);
> +       return;
> +}
> +
>  static struct exynos_drm_manager_ops fimd_manager_ops = {
>         .dpms = fimd_dpms,
>         .apply = fimd_apply,
>         .commit = fimd_commit,
>         .enable_vblank = fimd_enable_vblank,
>         .disable_vblank = fimd_disable_vblank,
> -       .wait_for_vblank = fimd_wait_for_vblank,
> +       .complete_scanout = fimd_complete_scanout,
>  };
>
>  static void fimd_win_mode_set(struct device *dev,
> diff --git a/include/video/samsung_fimd.h b/include/video/samsung_fimd.h
> index 7ae6c07..382eaec 100644
> --- a/include/video/samsung_fimd.h
> +++ b/include/video/samsung_fimd.h
> @@ -274,6 +274,7 @@
>
>  /* Video buffer addresses */
>  #define VIDW_BUF_START(_buff)                  (0xA0 + ((_buff) * 8))
> +#define VIDW_BUF_START_S(_buff)                        (0x40A0 + ((_buff) * 8))
>  #define VIDW_BUF_START1(_buff)                 (0xA4 + ((_buff) * 8))
>  #define VIDW_BUF_END(_buff)                    (0xD0 + ((_buff) * 8))
>  #define VIDW_BUF_END1(_buff)                   (0xD4 + ((_buff) * 8))
> --
> 1.8.0
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the dri-devel mailing list