<br><br><div class="gmail_quote">2012/12/6 Prathyush K <span dir="ltr"><<a href="mailto:prathyush.k@samsung.com" target="_blank">prathyush.k@samsung.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
When fimd is turned off, we disable the clocks which will stop<br>
the dma. Now if we remove the current framebuffer, we cannot<br>
disable the overlay but the current framebuffer will still be freed.<br>
When fimd resumes, the dma will continue from where it left off<br>
and will throw a PAGE FAULT since the memory was freed.<br>
<br>
This patch fixes the above problem by disabling the fimd windows<br>
before disabling the fimd clocks. It also keeps track of which<br>
windows were currently active by setting the 'resume' flag. When<br>
fimd resumes, the window with a resume flag set is enabled again.<br>
<br>
Now if a current fb is removed when fimd is off, fimd_win_disable<br>
will set the 'resume' flag of that window to zero and return.<br>
So when fimd resumes, that window will not be resumed.<br>
<br>
Signed-off-by: Prathyush K <<a href="mailto:prathyush.k@samsung.com">prathyush.k@samsung.com</a>><br>
---<br>
drivers/gpu/drm/exynos/exynos_drm_fimd.c | 40 +++++++++++++++++++++++++++++-<br>
1 files changed, 39 insertions(+), 1 deletions(-)<br>
<br>
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c<br>
index 1517d15..7e66032 100644<br>
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c<br>
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c<br>
@@ -83,6 +83,7 @@ struct fimd_win_data {<br>
unsigned int buf_offsize;<br>
unsigned int line_size; /* bytes */<br>
bool enabled;<br>
+ bool resume;<br>
};<br>
<br>
struct fimd_context {<br>
@@ -596,6 +597,12 @@ static void fimd_win_disable(struct device *dev, int zpos)<br>
<br>
win_data = &ctx->win_data[win];<br>
</blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ if (ctx->suspended) {<br></blockquote><div><br>Ok, add the below comment,<br>"if disabling hw overlay is tried when fimd was disabled already then do not access the hardware."<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ /* do not resume this window*/<br>
+ win_data->resume = false;<br>
+ return;<br>
+ }<br>
+<br>
/* protect windows */<br>
val = readl(ctx->regs + SHADOWCON);<br>
val |= SHADOWCON_WINx_PROTECT(win);<br>
@@ -809,11 +816,38 @@ static int fimd_clock(struct fimd_context *ctx, bool enable)<br>
return 0;<br>
}<br>
<br>
+static void fimd_window_suspend(struct device *dev)<br>
+{<br>
+ struct fimd_context *ctx = get_fimd_context(dev);<br>
+ struct fimd_win_data *win_data;<br>
+ int i;<br>
+<br>
+ for (i = 0; i < WINDOWS_NR; i++) {<br>
+ win_data = &ctx->win_data[i];<br>
+ win_data->resume = win_data->enabled;<br>
+ fimd_win_disable(dev, i);<br>
+ }<br>
+ fimd_wait_for_vblank(dev);<br>
+}<br>
+<br>
+static void fimd_window_resume(struct device *dev)<br>
+{<br>
+ struct fimd_context *ctx = get_fimd_context(dev);<br>
+ struct fimd_win_data *win_data;<br>
+ int i;<br>
+<br>
+ for (i = 0; i < WINDOWS_NR; i++) {<br>
+ win_data = &ctx->win_data[i];<br>
+ win_data->enabled = win_data->resume;<br>
+ win_data->resume = false;<br></blockquote><div><br>shouldn't the below code be added?<br>fimd_win_enable(dev, i);<br><br>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?<br>
<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ }<br>
+}<br>
+<br>
static int fimd_activate(struct fimd_context *ctx, bool enable)<br>
{<br>
+ struct device *dev = ctx->subdrv.dev;<br>
if (enable) {<br>
int ret;<br>
- struct device *dev = ctx->subdrv.dev;<br>
<br>
ret = fimd_clock(ctx, true);<br>
if (ret < 0)<br>
@@ -824,7 +858,11 @@ static int fimd_activate(struct fimd_context *ctx, bool enable)<br>
/* if vblank was enabled status, enable it again. */<br>
if (test_and_clear_bit(0, &ctx->irq_flags))<br>
fimd_enable_vblank(dev);<br>
+<br>
+ fimd_window_resume(dev);<br>
} else {<br>
+ fimd_window_suspend(dev);<br>
+<br>
fimd_clock(ctx, false);<br>
ctx->suspended = true;<br>
}<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.0.4<br>
<br>
_______________________________________________<br>
dri-devel mailing list<br>
<a href="mailto:dri-devel@lists.freedesktop.org">dri-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/dri-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/dri-devel</a><br>
</font></span></blockquote></div><br>