[PATCH 7/7] drm/exynos: clear windows in fimd dpms off

Inki Dae inki.dae at samsung.com
Thu Dec 6 21:07:06 PST 2012


2012/12/6 Prathyush K <prathyush.k at samsung.com>

> When fimd is turned off, we disable the clocks which will stop
> the dma. Now if we remove the current framebuffer, we cannot
> disable the overlay but the current framebuffer will still be freed.
>

I think that if fimd was turned off by dpms operation (off only clock and
display power) then rmfb request from user should be failed. Otherwise,
someone(drm core or specific driver) should turn hw power on and disable
hardware overlay and then turn hw power off again so that such exception
codes aren't added to specific driver. I'm not sure but there is something
to should be considered in drm core.


> When fimd resumes, the dma will continue from where it left off
> and will throw a PAGE FAULT since the memory was freed.
>
> This patch fixes the above problem by disabling the fimd windows
> before disabling the fimd clocks. It also keeps track of which
> windows were currently active by setting the 'resume' flag. When
> fimd resumes, the window with a resume flag set is enabled again.
>
> Now if a current fb is removed when fimd is off, fimd_win_disable
> will set the 'resume' flag of that window to zero and return.
> So when fimd resumes, that window will not be resumed.
>
> Signed-off-by: Prathyush K <prathyush.k at samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c |   40
> +++++++++++++++++++++++++++++-
>  1 files changed, 39 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> index 1517d15..7e66032 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> @@ -83,6 +83,7 @@ struct fimd_win_data {
>         unsigned int            buf_offsize;
>         unsigned int            line_size;      /* bytes */
>         bool                    enabled;
> +       bool                    resume;
>  };
>
>  struct fimd_context {
> @@ -596,6 +597,12 @@ static void fimd_win_disable(struct device *dev, int
> zpos)
>
>         win_data = &ctx->win_data[win];
>
> +       if (ctx->suspended) {
> +               /* do not resume this window*/
> +               win_data->resume = false;
> +               return;
> +       }
> +
>         /* protect windows */
>         val = readl(ctx->regs + SHADOWCON);
>         val |= SHADOWCON_WINx_PROTECT(win);
> @@ -809,11 +816,38 @@ static int fimd_clock(struct fimd_context *ctx, bool
> enable)
>         return 0;
>  }
>
> +static void fimd_window_suspend(struct device *dev)
> +{
> +       struct fimd_context *ctx = get_fimd_context(dev);
> +       struct fimd_win_data *win_data;
> +       int i;
> +
> +       for (i = 0; i < WINDOWS_NR; i++) {
> +               win_data = &ctx->win_data[i];
> +               win_data->resume = win_data->enabled;
> +               fimd_win_disable(dev, i);
> +       }
> +       fimd_wait_for_vblank(dev);
> +}
> +
> +static void fimd_window_resume(struct device *dev)
> +{
> +       struct fimd_context *ctx = get_fimd_context(dev);
> +       struct fimd_win_data *win_data;
> +       int i;
> +
> +       for (i = 0; i < WINDOWS_NR; i++) {
> +               win_data = &ctx->win_data[i];
> +               win_data->enabled = win_data->resume;
> +               win_data->resume = false;
> +       }
> +}
> +
>  static int fimd_activate(struct fimd_context *ctx, bool enable)
>  {
> +       struct device *dev = ctx->subdrv.dev;
>         if (enable) {
>                 int ret;
> -               struct device *dev = ctx->subdrv.dev;
>
>                 ret = fimd_clock(ctx, true);
>                 if (ret < 0)
> @@ -824,7 +858,11 @@ static int fimd_activate(struct fimd_context *ctx,
> bool enable)
>                 /* if vblank was enabled status, enable it again. */
>                 if (test_and_clear_bit(0, &ctx->irq_flags))
>                         fimd_enable_vblank(dev);
> +
> +               fimd_window_resume(dev);
>         } else {
> +               fimd_window_suspend(dev);
> +
>                 fimd_clock(ctx, false);
>                 ctx->suspended = true;
>         }
> --
> 1.7.0.4
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20121207/22e0eca4/attachment-0001.html>


More information about the dri-devel mailing list