diff options
author | Marek Szyprowski <m.szyprowski@samsung.com> | 2014-09-01 09:27:10 -0400 |
---|---|---|
committer | Inki Dae <daeinki@gmail.com> | 2014-09-19 11:56:09 -0400 |
commit | eb8a3bf73ecd894597dad2ded9aca43b53db167d (patch) | |
tree | 001dbc1cd162cb8d4f02646d6903b0c546701000 | |
parent | 71b1f1956b4466b47551e73d4dd2145df4241eb8 (diff) |
drm/exynos: fimd: fix window clear code
To correctly disable hardware window during driver init, both enable bits
(WINCONx_ENWIN in WINCON and SHADOWCON_CHx_ENABLE in SHADOWCON) must be
cleared, otherwise hardware fails to re-enable such window later.
While touching this function, also temporarily disable ctx->suspended flag
to let fimd_wait_for_vblank function really to do its job.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fimd.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 909e6478d7d5..2f896df2a734 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -214,7 +214,6 @@ static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr) | |||
214 | DRM_DEBUG_KMS("vblank wait timed out.\n"); | 214 | DRM_DEBUG_KMS("vblank wait timed out.\n"); |
215 | } | 215 | } |
216 | 216 | ||
217 | |||
218 | static void fimd_clear_channel(struct exynos_drm_manager *mgr) | 217 | static void fimd_clear_channel(struct exynos_drm_manager *mgr) |
219 | { | 218 | { |
220 | struct fimd_context *ctx = mgr->ctx; | 219 | struct fimd_context *ctx = mgr->ctx; |
@@ -224,17 +223,31 @@ static void fimd_clear_channel(struct exynos_drm_manager *mgr) | |||
224 | 223 | ||
225 | /* Check if any channel is enabled. */ | 224 | /* Check if any channel is enabled. */ |
226 | for (win = 0; win < WINDOWS_NR; win++) { | 225 | for (win = 0; win < WINDOWS_NR; win++) { |
227 | u32 val = readl(ctx->regs + SHADOWCON); | 226 | u32 val = readl(ctx->regs + WINCON(win)); |
228 | if (val & SHADOWCON_CHx_ENABLE(win)) { | 227 | |
229 | val &= ~SHADOWCON_CHx_ENABLE(win); | 228 | if (val & WINCONx_ENWIN) { |
230 | writel(val, ctx->regs + SHADOWCON); | 229 | /* wincon */ |
230 | val &= ~WINCONx_ENWIN; | ||
231 | writel(val, ctx->regs + WINCON(win)); | ||
232 | |||
233 | /* unprotect windows */ | ||
234 | if (ctx->driver_data->has_shadowcon) { | ||
235 | val = readl(ctx->regs + SHADOWCON); | ||
236 | val &= ~SHADOWCON_CHx_ENABLE(win); | ||
237 | writel(val, ctx->regs + SHADOWCON); | ||
238 | } | ||
231 | ch_enabled = 1; | 239 | ch_enabled = 1; |
232 | } | 240 | } |
233 | } | 241 | } |
234 | 242 | ||
235 | /* Wait for vsync, as disable channel takes effect at next vsync */ | 243 | /* Wait for vsync, as disable channel takes effect at next vsync */ |
236 | if (ch_enabled) | 244 | if (ch_enabled) { |
245 | unsigned int state = ctx->suspended; | ||
246 | |||
247 | ctx->suspended = 0; | ||
237 | fimd_wait_for_vblank(mgr); | 248 | fimd_wait_for_vblank(mgr); |
249 | ctx->suspended = state; | ||
250 | } | ||
238 | } | 251 | } |
239 | 252 | ||
240 | static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, | 253 | static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, |