[PATCH 8/8] drm/exynos: fimd: add complete_scanout function
Mandeep Singh Baines
msb at chromium.org
Wed Jan 9 10:39:50 PST 2013
On Tue, Jan 8, 2013 at 9:43 PM, Prathyush K <prathyush at chromium.org> wrote:
>
>
>
> On Tue, Jan 8, 2013 at 4:18 AM, Mandeep Singh Baines <msb at chromium.org>
> wrote:
>>
>> 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.
>>
> How will there be a race? Can you explain the scenario in more detail?
>
I'm sorry. There's no race. I had misunderstood something.
Reference counting might still be preferable to avoid blocking the
Xserver till vblank.
You can implement it by grabbing a reference on page_flip and release
the reference
on finish_page_flip (when flipping to a new fb).
Regards,
Mandeep
> 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 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
>> _______________________________________________
>> 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