tilcdc_crtc_disable(crtc);
}
+static void tilcdc_crtc_atomic_flush(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
+{
+ if (!crtc->state->event)
+ return;
+
+ spin_lock_irq(&crtc->dev->event_lock);
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ crtc->state->event = NULL;
+ spin_unlock_irq(&crtc->dev->event_lock);
+}
+
void tilcdc_crtc_shutdown(struct drm_crtc *crtc)
{
tilcdc_crtc_off(crtc, true);
.atomic_check = tilcdc_crtc_atomic_check,
.atomic_enable = tilcdc_crtc_atomic_enable,
.atomic_disable = tilcdc_crtc_atomic_disable,
+ .atomic_flush = tilcdc_crtc_atomic_flush,
};
void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc,
return ret;
}
-static int tilcdc_commit(struct drm_device *dev,
- struct drm_atomic_state *state,
- bool async)
-{
- int ret;
-
- ret = drm_atomic_helper_prepare_planes(dev, state);
- if (ret)
- return ret;
-
- ret = drm_atomic_helper_swap_state(state, true);
- if (ret) {
- drm_atomic_helper_cleanup_planes(dev, state);
- return ret;
- }
-
- /*
- * Everything below can be run asynchronously without the need to grab
- * any modeset locks at all under one condition: It must be guaranteed
- * that the asynchronous work has either been cancelled (if the driver
- * supports it, which at least requires that the framebuffers get
- * cleaned up with drm_atomic_helper_cleanup_planes()) or completed
- * before the new state gets committed on the software side with
- * drm_atomic_helper_swap_state().
- *
- * This scheme allows new atomic state updates to be prepared and
- * checked in parallel to the asynchronous completion of the previous
- * update. Which is important since compositors need to figure out the
- * composition of the next frame right after having submitted the
- * current layout.
- */
-
- drm_atomic_helper_commit_modeset_disables(dev, state);
-
- drm_atomic_helper_commit_planes(dev, state, 0);
-
- drm_atomic_helper_commit_modeset_enables(dev, state);
-
- drm_atomic_helper_wait_for_vblanks(dev, state);
-
- drm_atomic_helper_cleanup_planes(dev, state);
-
- return 0;
-}
-
static const struct drm_mode_config_funcs mode_config_funcs = {
.fb_create = drm_gem_fb_create,
.atomic_check = tilcdc_atomic_check,
- .atomic_commit = tilcdc_commit,
+ .atomic_commit = drm_atomic_helper_commit,
};
static void modeset_init(struct drm_device *dev)
if (WARN_ON(!state->fb || !state->crtc->state))
return;
- tilcdc_crtc_update_fb(state->crtc,
- state->fb,
- state->crtc->state->event);
+ if (tilcdc_crtc_update_fb(state->crtc,
+ state->fb,
+ state->crtc->state->event) == 0) {
+ state->crtc->state->event = NULL;
+ }
}
static const struct drm_plane_helper_funcs plane_helper_funcs = {