aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorInki Dae <inki.dae@samsung.com>2012-11-22 03:41:23 -0500
committerInki Dae <inki.dae@samsung.com>2012-12-05 00:39:19 -0500
commit1daa892c1df5c329375d791ca169db22f18e5c28 (patch)
treebfb8c9f267db09f61e5d01a6cba464dded4a1d7e
parent5b07c66059313fc998d28cf6775fd1a8bbb034aa (diff)
drm/exynos: make sure that overlay data are updated
Changelog v2: fix a little bit performance issue to previous patch. - When drm framebuffer is destroyed, make sure that overlay data are updated to real hardwrae for all encoders instead of waiting for vblank every page flip request. For this, it adds a new function, exynos_drm_encoder_complete_scanout function. Changelog v1: This patch removes wait_for_vblank call from exynos_drm_encoder_plane_disable function and move it to exynos_drm_encoder_plane_commit function. Disabling dma channel to each plane doens't need vblank signal to update data to real hardware. But updating overlay data to real hardware does need vblank signal. Signed-off-by: Inki Dae <inki.dae@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
-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++) {