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

Inki Dae inki.dae at samsung.com
Thu Dec 6 20:42:00 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.
> 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) {
>

Ok, add the below comment,
"if disabling hw overlay is tried when fimd was disabled already then do
not access the hardware."


> +               /* 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;
>

shouldn't the below code be added?
fimd_win_enable(dev, i);

you backed up overlay status before suspended but this patch doesn't enable
the overlays again. you supposed that the registers would be restored by
SoC specific pm framework?

+       }
> +}
> +
>  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/f0333488/attachment.html>


More information about the dri-devel mailing list