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_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@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