Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -378,6 +378,7 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)

	if (ctx->out_type & IFTYPE_I80)
		set_bit(BIT_WIN_UPDATED, &ctx->flags);
	exynos_crtc_handle_event(crtc);
}

static void decon_swreset(struct decon_context *ctx)
+1 −0
Original line number Diff line number Diff line
@@ -526,6 +526,7 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)

	for (i = 0; i < WINDOWS_NR; i++)
		decon_shadow_protect_win(ctx, i, false);
	exynos_crtc_handle_event(crtc);
}

static void decon_init(struct decon_context *ctx)
+16 −13
Original line number Diff line number Diff line
@@ -85,16 +85,28 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
				     struct drm_crtc_state *old_crtc_state)
{
	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)
		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) {
		crtc->state->event = NULL;

		spin_lock_irqsave(&crtc->dev->event_lock, flags);
		if (drm_crtc_vblank_get(crtc) == 0)
			drm_crtc_arm_vblank_event(crtc, event);
@@ -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)
{
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+2 −0
Original line number Diff line number Diff line
@@ -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_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc);

#endif
+2 −0
Original line number Diff line number Diff line
@@ -709,6 +709,8 @@ static void fimd_atomic_flush(struct exynos_drm_crtc *crtc)

	for (i = 0; i < WINDOWS_NR; i++)
		fimd_shadow_protect_win(ctx, i, false);

	exynos_crtc_handle_event(crtc);
}

static void fimd_update_plane(struct exynos_drm_crtc *crtc,
Loading