On Thu, Dec 6, 2012 at 6:46 AM, Prathyush K <prathyush.k@xxxxxxxxxxx> 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@xxxxxxxxxxx> 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@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/dri-devel _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel