[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