aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrzej Hajda <a.hajda@samsung.com>2017-03-14 04:27:56 -0400
committerInki Dae <inki.dae@samsung.com>2017-03-21 00:17:21 -0400
commita392276d1dec63e5aabe6f527c37de29a729559a (patch)
tree0569a35d4495efa5704c3d265102d03ef82c406b
parent6bdc92ee4980ca10171a8de338fad612f00bb48f (diff)
drm/exynos: move crtc event handling to drivers callbacks
CRTC event is currently send with next vblank, or instantly in case crtc is being disabled. This approach usually works, but in corner cases it can result in premature event generation. Only device driver is able to verify if the event can be sent. This patch is a first step in that direction - it moves event handling to the drivers. Signed-off-by: Andrzej Hajda <a.hajda@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
-rw-r--r--drivers/gpu/drm/exynos/exynos5433_drm_decon.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos7_drm_decon.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c29
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.h2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c1
7 files changed, 24 insertions, 13 deletions
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index cca32a4fdab3..2130ccf1e036 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -378,6 +378,7 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
378 378
379 if (ctx->out_type & IFTYPE_I80) 379 if (ctx->out_type & IFTYPE_I80)
380 set_bit(BIT_WIN_UPDATED, &ctx->flags); 380 set_bit(BIT_WIN_UPDATED, &ctx->flags);
381 exynos_crtc_handle_event(crtc);
381} 382}
382 383
383static void decon_swreset(struct decon_context *ctx) 384static void decon_swreset(struct decon_context *ctx)
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index f9ab19e205e2..48811806fa27 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -526,6 +526,7 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
526 526
527 for (i = 0; i < WINDOWS_NR; i++) 527 for (i = 0; i < WINDOWS_NR; i++)
528 decon_shadow_protect_win(ctx, i, false); 528 decon_shadow_protect_win(ctx, i, false);
529 exynos_crtc_handle_event(crtc);
529} 530}
530 531
531static void decon_init(struct decon_context *ctx) 532static void decon_init(struct decon_context *ctx)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 5367b6664fe3..c65f4509932c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -85,16 +85,28 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
85 struct drm_crtc_state *old_crtc_state) 85 struct drm_crtc_state *old_crtc_state)
86{ 86{
87 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 87 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
88 struct drm_pending_vblank_event *event;
89 unsigned long flags;
90 88
91 if (exynos_crtc->ops->atomic_flush) 89 if (exynos_crtc->ops->atomic_flush)
92 exynos_crtc->ops->atomic_flush(exynos_crtc); 90 exynos_crtc->ops->atomic_flush(exynos_crtc);
91}
92
93static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
94 .enable = exynos_drm_crtc_enable,
95 .disable = exynos_drm_crtc_disable,
96 .mode_set_nofb = exynos_drm_crtc_mode_set_nofb,
97 .atomic_check = exynos_crtc_atomic_check,
98 .atomic_begin = exynos_crtc_atomic_begin,
99 .atomic_flush = exynos_crtc_atomic_flush,
100};
101
102void exynos_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc)
103{
104 struct drm_crtc *crtc = &exynos_crtc->base;
105 struct drm_pending_vblank_event *event = crtc->state->event;
106 unsigned long flags;
93 107
94 event = crtc->state->event;
95 if (event) { 108 if (event) {
96 crtc->state->event = NULL; 109 crtc->state->event = NULL;
97
98 spin_lock_irqsave(&crtc->dev->event_lock, flags); 110 spin_lock_irqsave(&crtc->dev->event_lock, flags);
99 if (drm_crtc_vblank_get(crtc) == 0) 111 if (drm_crtc_vblank_get(crtc) == 0)
100 drm_crtc_arm_vblank_event(crtc, event); 112 drm_crtc_arm_vblank_event(crtc, event);
@@ -105,15 +117,6 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
105 117
106} 118}
107 119
108static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
109 .enable = exynos_drm_crtc_enable,
110 .disable = exynos_drm_crtc_disable,
111 .mode_set_nofb = exynos_drm_crtc_mode_set_nofb,
112 .atomic_check = exynos_crtc_atomic_check,
113 .atomic_begin = exynos_crtc_atomic_begin,
114 .atomic_flush = exynos_crtc_atomic_flush,
115};
116
117static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) 120static void exynos_drm_crtc_destroy(struct drm_crtc *crtc)
118{ 121{
119 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 122 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
index 6a581a8af465..abd5d6ceac0c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
@@ -40,4 +40,6 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
40 */ 40 */
41void exynos_drm_crtc_te_handler(struct drm_crtc *crtc); 41void exynos_drm_crtc_te_handler(struct drm_crtc *crtc);
42 42
43void exynos_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc);
44
43#endif 45#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 661b9fe049e2..a3162a4566ce 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -709,6 +709,8 @@ static void fimd_atomic_flush(struct exynos_drm_crtc *crtc)
709 709
710 for (i = 0; i < WINDOWS_NR; i++) 710 for (i = 0; i < WINDOWS_NR; i++)
711 fimd_shadow_protect_win(ctx, i, false); 711 fimd_shadow_protect_win(ctx, i, false);
712
713 exynos_crtc_handle_event(crtc);
712} 714}
713 715
714static void fimd_update_plane(struct exynos_drm_crtc *crtc, 716static void fimd_update_plane(struct exynos_drm_crtc *crtc,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 57fe514d5c5b..5d9a62a87eec 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -170,6 +170,7 @@ static const struct exynos_drm_crtc_ops vidi_crtc_ops = {
170 .enable_vblank = vidi_enable_vblank, 170 .enable_vblank = vidi_enable_vblank,
171 .disable_vblank = vidi_disable_vblank, 171 .disable_vblank = vidi_disable_vblank,
172 .update_plane = vidi_update_plane, 172 .update_plane = vidi_update_plane,
173 .atomic_flush = exynos_crtc_handle_event,
173}; 174};
174 175
175static void vidi_fake_vblank_timer(unsigned long arg) 176static void vidi_fake_vblank_timer(unsigned long arg)
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 72143ac10525..25edb635a197 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1012,6 +1012,7 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc)
1012 return; 1012 return;
1013 1013
1014 mixer_vsync_set_update(mixer_ctx, true); 1014 mixer_vsync_set_update(mixer_ctx, true);
1015 exynos_crtc_handle_event(crtc);
1015} 1016}
1016 1017
1017static void mixer_enable(struct exynos_drm_crtc *crtc) 1018static void mixer_enable(struct exynos_drm_crtc *crtc)