Commit a392276d1dec63e5aabe6f527c37de29a729559a

Authored by Andrzej Hajda
Committed by Inki Dae
1 parent 6bdc92ee49

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>

Showing 7 changed files with 24 additions and 13 deletions Side-by-side Diff

drivers/gpu/drm/exynos/exynos5433_drm_decon.c
... ... @@ -378,6 +378,7 @@
378 378  
379 379 if (ctx->out_type & IFTYPE_I80)
380 380 set_bit(BIT_WIN_UPDATED, &ctx->flags);
  381 + exynos_crtc_handle_event(crtc);
381 382 }
382 383  
383 384 static void decon_swreset(struct decon_context *ctx)
drivers/gpu/drm/exynos/exynos7_drm_decon.c
... ... @@ -526,6 +526,7 @@
526 526  
527 527 for (i = 0; i < WINDOWS_NR; i++)
528 528 decon_shadow_protect_win(ctx, i, false);
  529 + exynos_crtc_handle_event(crtc);
529 530 }
530 531  
531 532 static void decon_init(struct decon_context *ctx)
drivers/gpu/drm/exynos/exynos_drm_crtc.c
... ... @@ -85,16 +85,28 @@
85 85 struct drm_crtc_state *old_crtc_state)
86 86 {
87 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 89 if (exynos_crtc->ops->atomic_flush)
92 90 exynos_crtc->ops->atomic_flush(exynos_crtc);
  91 +}
93 92  
94   - event = crtc->state->event;
  93 +static 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 +
  102 +void 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;
  107 +
95 108 if (event) {
96 109 crtc->state->event = NULL;
97   -
98 110 spin_lock_irqsave(&crtc->dev->event_lock, flags);
99 111 if (drm_crtc_vblank_get(crtc) == 0)
100 112 drm_crtc_arm_vblank_event(crtc, event);
... ... @@ -104,15 +116,6 @@
104 116 }
105 117  
106 118 }
107   -
108   -static 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 119  
117 120 static void exynos_drm_crtc_destroy(struct drm_crtc *crtc)
118 121 {
drivers/gpu/drm/exynos/exynos_drm_crtc.h
... ... @@ -40,5 +40,7 @@
40 40 */
41 41 void exynos_drm_crtc_te_handler(struct drm_crtc *crtc);
42 42  
  43 +void exynos_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc);
  44 +
43 45 #endif
drivers/gpu/drm/exynos/exynos_drm_fimd.c
... ... @@ -709,6 +709,8 @@
709 709  
710 710 for (i = 0; i < WINDOWS_NR; i++)
711 711 fimd_shadow_protect_win(ctx, i, false);
  712 +
  713 + exynos_crtc_handle_event(crtc);
712 714 }
713 715  
714 716 static void fimd_update_plane(struct exynos_drm_crtc *crtc,
drivers/gpu/drm/exynos/exynos_drm_vidi.c
... ... @@ -170,6 +170,7 @@
170 170 .enable_vblank = vidi_enable_vblank,
171 171 .disable_vblank = vidi_disable_vblank,
172 172 .update_plane = vidi_update_plane,
  173 + .atomic_flush = exynos_crtc_handle_event,
173 174 };
174 175  
175 176 static void vidi_fake_vblank_timer(unsigned long arg)
drivers/gpu/drm/exynos/exynos_mixer.c
... ... @@ -1012,6 +1012,7 @@
1012 1012 return;
1013 1013  
1014 1014 mixer_vsync_set_update(mixer_ctx, true);
  1015 + exynos_crtc_handle_event(crtc);
1015 1016 }
1016 1017  
1017 1018 static void mixer_enable(struct exynos_drm_crtc *crtc)