On Tue, Jan 8, 2013 at 4:18 AM, Mandeep Singh Baines <msb@xxxxxxxxxxxx> wrote:
On Wed, Dec 26, 2012 at 3:27 AM, Prathyush K <prathyush.k@xxxxxxxxxxx> wrote:
> The wait_for_vblank interface is modified to the complete_scanoutWith this series, you have a race if the rmfb happens before the flip
> function in fimd. This patch adds the fimd_complete_scanout function
>
has completed.
How will there be a race? Can you explain the scenario in more detail?
If the current fb (fb1) is being removed, (i.e the shadow register has fb1),
then we wait for vblank before returning. This ensures that the flip has been handled
before remove fb is complete.
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.
Will look into it. Thanks.
Regards,
Prathyush
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@xxxxxxxxxxx>
> ---
> 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@xxxxxxxxxxxxxxxxxxxxx
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel