aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.c43
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.h1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fb.c4
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
237void 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
237static void exynos_drm_encoder_disable(struct drm_encoder *encoder) 270static 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);
46void exynos_drm_encoder_plane_commit(struct drm_encoder *encoder, void *data); 46void exynos_drm_encoder_plane_commit(struct drm_encoder *encoder, void *data);
47void exynos_drm_encoder_plane_enable(struct drm_encoder *encoder, void *data); 47void exynos_drm_encoder_plane_enable(struct drm_encoder *encoder, void *data);
48void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data); 48void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data);
49void 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++) {