Commit a392276d authored by Andrzej Hajda's avatar Andrzej Hajda Committed by Inki Dae

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: default avatarAndrzej Hajda <a.hajda@samsung.com>
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
parent 6bdc92ee
...@@ -378,6 +378,7 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc) ...@@ -378,6 +378,7 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
if (ctx->out_type & IFTYPE_I80) if (ctx->out_type & IFTYPE_I80)
set_bit(BIT_WIN_UPDATED, &ctx->flags); set_bit(BIT_WIN_UPDATED, &ctx->flags);
exynos_crtc_handle_event(crtc);
} }
static void decon_swreset(struct decon_context *ctx) static void decon_swreset(struct decon_context *ctx)
......
...@@ -526,6 +526,7 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc) ...@@ -526,6 +526,7 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
for (i = 0; i < WINDOWS_NR; i++) for (i = 0; i < WINDOWS_NR; i++)
decon_shadow_protect_win(ctx, i, false); decon_shadow_protect_win(ctx, i, false);
exynos_crtc_handle_event(crtc);
} }
static void decon_init(struct decon_context *ctx) static void decon_init(struct decon_context *ctx)
......
...@@ -85,16 +85,28 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc, ...@@ -85,16 +85,28 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state) struct drm_crtc_state *old_crtc_state)
{ {
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
struct drm_pending_vblank_event *event;
unsigned long flags;
if (exynos_crtc->ops->atomic_flush) if (exynos_crtc->ops->atomic_flush)
exynos_crtc->ops->atomic_flush(exynos_crtc); exynos_crtc->ops->atomic_flush(exynos_crtc);
}
static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
.enable = exynos_drm_crtc_enable,
.disable = exynos_drm_crtc_disable,
.mode_set_nofb = exynos_drm_crtc_mode_set_nofb,
.atomic_check = exynos_crtc_atomic_check,
.atomic_begin = exynos_crtc_atomic_begin,
.atomic_flush = exynos_crtc_atomic_flush,
};
void exynos_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc)
{
struct drm_crtc *crtc = &exynos_crtc->base;
struct drm_pending_vblank_event *event = crtc->state->event;
unsigned long flags;
event = crtc->state->event;
if (event) { if (event) {
crtc->state->event = NULL; crtc->state->event = NULL;
spin_lock_irqsave(&crtc->dev->event_lock, flags); spin_lock_irqsave(&crtc->dev->event_lock, flags);
if (drm_crtc_vblank_get(crtc) == 0) if (drm_crtc_vblank_get(crtc) == 0)
drm_crtc_arm_vblank_event(crtc, event); drm_crtc_arm_vblank_event(crtc, event);
...@@ -105,15 +117,6 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc, ...@@ -105,15 +117,6 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
} }
static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
.enable = exynos_drm_crtc_enable,
.disable = exynos_drm_crtc_disable,
.mode_set_nofb = exynos_drm_crtc_mode_set_nofb,
.atomic_check = exynos_crtc_atomic_check,
.atomic_begin = exynos_crtc_atomic_begin,
.atomic_flush = exynos_crtc_atomic_flush,
};
static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) static void exynos_drm_crtc_destroy(struct drm_crtc *crtc)
{ {
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
......
...@@ -40,4 +40,6 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev, ...@@ -40,4 +40,6 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
*/ */
void exynos_drm_crtc_te_handler(struct drm_crtc *crtc); void exynos_drm_crtc_te_handler(struct drm_crtc *crtc);
void exynos_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc);
#endif #endif
...@@ -709,6 +709,8 @@ static void fimd_atomic_flush(struct exynos_drm_crtc *crtc) ...@@ -709,6 +709,8 @@ static void fimd_atomic_flush(struct exynos_drm_crtc *crtc)
for (i = 0; i < WINDOWS_NR; i++) for (i = 0; i < WINDOWS_NR; i++)
fimd_shadow_protect_win(ctx, i, false); fimd_shadow_protect_win(ctx, i, false);
exynos_crtc_handle_event(crtc);
} }
static void fimd_update_plane(struct exynos_drm_crtc *crtc, static void fimd_update_plane(struct exynos_drm_crtc *crtc,
......
...@@ -170,6 +170,7 @@ static const struct exynos_drm_crtc_ops vidi_crtc_ops = { ...@@ -170,6 +170,7 @@ static const struct exynos_drm_crtc_ops vidi_crtc_ops = {
.enable_vblank = vidi_enable_vblank, .enable_vblank = vidi_enable_vblank,
.disable_vblank = vidi_disable_vblank, .disable_vblank = vidi_disable_vblank,
.update_plane = vidi_update_plane, .update_plane = vidi_update_plane,
.atomic_flush = exynos_crtc_handle_event,
}; };
static void vidi_fake_vblank_timer(unsigned long arg) static void vidi_fake_vblank_timer(unsigned long arg)
......
...@@ -1012,6 +1012,7 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc) ...@@ -1012,6 +1012,7 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc)
return; return;
mixer_vsync_set_update(mixer_ctx, true); mixer_vsync_set_update(mixer_ctx, true);
exynos_crtc_handle_event(crtc);
} }
static void mixer_enable(struct exynos_drm_crtc *crtc) static void mixer_enable(struct exynos_drm_crtc *crtc)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment