[PATCH 7/7] drm/exynos: clear windows in fimd dpms off
Stéphane Marchesin
stephane.marchesin at gmail.com
Wed Dec 12 13:09:44 PST 2012
On Thu, Dec 6, 2012 at 6:46 AM, Prathyush K <prathyush.k at samsung.com> wrote:
> 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>
Hi Prathyush,
I think you removed my signed-off/ownership on this patch. See:
http://git.chromium.org/gitweb/?p=chromiumos/third_party/kernel.git;a=commitdiff;h=cfa22e49b7408547c73532c4bb03de47cc034a05
Stephane
> ---
> 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
More information about the dri-devel
mailing list