diff options
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_encoder.c | 43 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_encoder.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fb.c | 4 |
3 files changed, 38 insertions, 10 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index f2df06c603f7..d9afb11aac76 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c | |||
@@ -234,6 +234,39 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder) | |||
234 | exynos_encoder->dpms = DRM_MODE_DPMS_ON; | 234 | exynos_encoder->dpms = DRM_MODE_DPMS_ON; |
235 | } | 235 | } |
236 | 236 | ||
237 | void exynos_drm_encoder_complete_scanout(struct drm_framebuffer *fb) | ||
238 | { | ||
239 | struct exynos_drm_encoder *exynos_encoder; | ||
240 | struct exynos_drm_overlay_ops *overlay_ops; | ||
241 | struct exynos_drm_manager *manager; | ||
242 | struct drm_device *dev = fb->dev; | ||
243 | struct drm_encoder *encoder; | ||
244 | |||
245 | /* | ||
246 | * make sure that overlay data are updated to real hardware | ||
247 | * for all encoders. | ||
248 | */ | ||
249 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
250 | exynos_encoder = to_exynos_encoder(encoder); | ||
251 | |||
252 | /* if exynos was disabled, just ignor it. */ | ||
253 | if (exynos_encoder->dpms > DRM_MODE_DPMS_ON) | ||
254 | continue; | ||
255 | |||
256 | manager = exynos_encoder->manager; | ||
257 | overlay_ops = manager->overlay_ops; | ||
258 | |||
259 | /* | ||
260 | * wait for vblank interrupt | ||
261 | * - this makes sure that overlay data are updated to | ||
262 | * real hardware. | ||
263 | */ | ||
264 | if (overlay_ops->wait_for_vblank) | ||
265 | overlay_ops->wait_for_vblank(manager->dev); | ||
266 | } | ||
267 | } | ||
268 | |||
269 | |||
237 | static void exynos_drm_encoder_disable(struct drm_encoder *encoder) | 270 | static void exynos_drm_encoder_disable(struct drm_encoder *encoder) |
238 | { | 271 | { |
239 | struct drm_plane *plane; | 272 | struct drm_plane *plane; |
@@ -505,14 +538,4 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data) | |||
505 | 538 | ||
506 | if (overlay_ops && overlay_ops->disable) | 539 | if (overlay_ops && overlay_ops->disable) |
507 | overlay_ops->disable(manager->dev, zpos); | 540 | overlay_ops->disable(manager->dev, zpos); |
508 | |||
509 | /* | ||
510 | * wait for vblank interrupt | ||
511 | * - this makes sure that hardware overlay is disabled to avoid | ||
512 | * for the dma accesses to memory after gem buffer was released | ||
513 | * because the setting for disabling the overlay will be updated | ||
514 | * at vsync. | ||
515 | */ | ||
516 | if (overlay_ops && overlay_ops->wait_for_vblank) | ||
517 | overlay_ops->wait_for_vblank(manager->dev); | ||
518 | } | 541 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h index 6470d9ddf5a1..88bb25a2a917 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.h | |||
@@ -46,5 +46,6 @@ void exynos_drm_encoder_plane_mode_set(struct drm_encoder *encoder, void *data); | |||
46 | void exynos_drm_encoder_plane_commit(struct drm_encoder *encoder, void *data); | 46 | void exynos_drm_encoder_plane_commit(struct drm_encoder *encoder, void *data); |
47 | void exynos_drm_encoder_plane_enable(struct drm_encoder *encoder, void *data); | 47 | void exynos_drm_encoder_plane_enable(struct drm_encoder *encoder, void *data); |
48 | void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data); | 48 | void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data); |
49 | void exynos_drm_encoder_complete_scanout(struct drm_framebuffer *fb); | ||
49 | 50 | ||
50 | #endif | 51 | #endif |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 7190b64a368b..7413f4b729b0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "exynos_drm_fb.h" | 36 | #include "exynos_drm_fb.h" |
37 | #include "exynos_drm_gem.h" | 37 | #include "exynos_drm_gem.h" |
38 | #include "exynos_drm_iommu.h" | 38 | #include "exynos_drm_iommu.h" |
39 | #include "exynos_drm_encoder.h" | ||
39 | 40 | ||
40 | #define to_exynos_fb(x) container_of(x, struct exynos_drm_fb, fb) | 41 | #define to_exynos_fb(x) container_of(x, struct exynos_drm_fb, fb) |
41 | 42 | ||
@@ -85,6 +86,9 @@ static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) | |||
85 | 86 | ||
86 | DRM_DEBUG_KMS("%s\n", __FILE__); | 87 | DRM_DEBUG_KMS("%s\n", __FILE__); |
87 | 88 | ||
89 | /* make sure that overlay data are updated before relesing fb. */ | ||
90 | exynos_drm_encoder_complete_scanout(fb); | ||
91 | |||
88 | drm_framebuffer_cleanup(fb); | 92 | drm_framebuffer_cleanup(fb); |
89 | 93 | ||
90 | for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem_obj); i++) { | 94 | for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem_obj); i++) { |