drm: Introduce a drm_crtc_commit_wait helper
There's currently four users of the same logic to wait for a commit to be flipped: three for the CRTCs, connectors and planes in drm_atomic_helper_wait_for_dependencies, and one in vc4. Let's consolidate this a bit to avoid any code duplication. Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Link: https://patchwork.freedesktop.org/patch/msgid/20210111084401.117152-1-maxime@cerno.tech
This commit is contained in:
parent
d1a73c641a
commit
b99c2c9541
@ -52,6 +52,45 @@ void __drm_crtc_commit_free(struct kref *kref)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__drm_crtc_commit_free);
|
EXPORT_SYMBOL(__drm_crtc_commit_free);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_crtc_commit_wait - Waits for a commit to complete
|
||||||
|
* @commit: &drm_crtc_commit to wait for
|
||||||
|
*
|
||||||
|
* Waits for a given &drm_crtc_commit to be programmed into the
|
||||||
|
* hardware and flipped to.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
*
|
||||||
|
* 0 on success, a negative error code otherwise.
|
||||||
|
*/
|
||||||
|
int drm_crtc_commit_wait(struct drm_crtc_commit *commit)
|
||||||
|
{
|
||||||
|
unsigned long timeout = 10 * HZ;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!commit)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = wait_for_completion_timeout(&commit->hw_done, timeout);
|
||||||
|
if (!ret) {
|
||||||
|
DRM_ERROR("hw_done timed out\n");
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Currently no support for overwriting flips, hence
|
||||||
|
* stall for previous one to execute completely.
|
||||||
|
*/
|
||||||
|
ret = wait_for_completion_timeout(&commit->flip_done, timeout);
|
||||||
|
if (!ret) {
|
||||||
|
DRM_ERROR("flip_done timed out\n");
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_crtc_commit_wait);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_atomic_state_default_release -
|
* drm_atomic_state_default_release -
|
||||||
* release memory initialized by drm_atomic_state_init
|
* release memory initialized by drm_atomic_state_init
|
||||||
|
@ -2202,70 +2202,27 @@ void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state)
|
|||||||
struct drm_plane_state *old_plane_state;
|
struct drm_plane_state *old_plane_state;
|
||||||
struct drm_connector *conn;
|
struct drm_connector *conn;
|
||||||
struct drm_connector_state *old_conn_state;
|
struct drm_connector_state *old_conn_state;
|
||||||
struct drm_crtc_commit *commit;
|
|
||||||
int i;
|
int i;
|
||||||
long ret;
|
long ret;
|
||||||
|
|
||||||
for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
|
for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
|
||||||
commit = old_crtc_state->commit;
|
ret = drm_crtc_commit_wait(old_crtc_state->commit);
|
||||||
|
if (ret)
|
||||||
if (!commit)
|
DRM_ERROR("[CRTC:%d:%s] commit wait timed out\n",
|
||||||
continue;
|
|
||||||
|
|
||||||
ret = wait_for_completion_timeout(&commit->hw_done,
|
|
||||||
10*HZ);
|
|
||||||
if (ret == 0)
|
|
||||||
DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
|
|
||||||
crtc->base.id, crtc->name);
|
|
||||||
|
|
||||||
/* Currently no support for overwriting flips, hence
|
|
||||||
* stall for previous one to execute completely. */
|
|
||||||
ret = wait_for_completion_timeout(&commit->flip_done,
|
|
||||||
10*HZ);
|
|
||||||
if (ret == 0)
|
|
||||||
DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
|
|
||||||
crtc->base.id, crtc->name);
|
crtc->base.id, crtc->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for_each_old_connector_in_state(old_state, conn, old_conn_state, i) {
|
for_each_old_connector_in_state(old_state, conn, old_conn_state, i) {
|
||||||
commit = old_conn_state->commit;
|
ret = drm_crtc_commit_wait(old_conn_state->commit);
|
||||||
|
if (ret)
|
||||||
if (!commit)
|
DRM_ERROR("[CONNECTOR:%d:%s] commit wait timed out\n",
|
||||||
continue;
|
|
||||||
|
|
||||||
ret = wait_for_completion_timeout(&commit->hw_done,
|
|
||||||
10*HZ);
|
|
||||||
if (ret == 0)
|
|
||||||
DRM_ERROR("[CONNECTOR:%d:%s] hw_done timed out\n",
|
|
||||||
conn->base.id, conn->name);
|
|
||||||
|
|
||||||
/* Currently no support for overwriting flips, hence
|
|
||||||
* stall for previous one to execute completely. */
|
|
||||||
ret = wait_for_completion_timeout(&commit->flip_done,
|
|
||||||
10*HZ);
|
|
||||||
if (ret == 0)
|
|
||||||
DRM_ERROR("[CONNECTOR:%d:%s] flip_done timed out\n",
|
|
||||||
conn->base.id, conn->name);
|
conn->base.id, conn->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for_each_old_plane_in_state(old_state, plane, old_plane_state, i) {
|
for_each_old_plane_in_state(old_state, plane, old_plane_state, i) {
|
||||||
commit = old_plane_state->commit;
|
ret = drm_crtc_commit_wait(old_plane_state->commit);
|
||||||
|
if (ret)
|
||||||
if (!commit)
|
DRM_ERROR("[PLANE:%d:%s] commit wait timed out\n",
|
||||||
continue;
|
|
||||||
|
|
||||||
ret = wait_for_completion_timeout(&commit->hw_done,
|
|
||||||
10*HZ);
|
|
||||||
if (ret == 0)
|
|
||||||
DRM_ERROR("[PLANE:%d:%s] hw_done timed out\n",
|
|
||||||
plane->base.id, plane->name);
|
|
||||||
|
|
||||||
/* Currently no support for overwriting flips, hence
|
|
||||||
* stall for previous one to execute completely. */
|
|
||||||
ret = wait_for_completion_timeout(&commit->flip_done,
|
|
||||||
10*HZ);
|
|
||||||
if (ret == 0)
|
|
||||||
DRM_ERROR("[PLANE:%d:%s] flip_done timed out\n",
|
|
||||||
plane->base.id, plane->name);
|
plane->base.id, plane->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,9 +363,8 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state)
|
|||||||
for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
|
for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
|
||||||
struct vc4_crtc_state *vc4_crtc_state =
|
struct vc4_crtc_state *vc4_crtc_state =
|
||||||
to_vc4_crtc_state(old_crtc_state);
|
to_vc4_crtc_state(old_crtc_state);
|
||||||
struct drm_crtc_commit *commit;
|
|
||||||
unsigned int channel = vc4_crtc_state->assigned_channel;
|
unsigned int channel = vc4_crtc_state->assigned_channel;
|
||||||
unsigned long done;
|
int ret;
|
||||||
|
|
||||||
if (channel == VC4_HVS_CHANNEL_DISABLED)
|
if (channel == VC4_HVS_CHANNEL_DISABLED)
|
||||||
continue;
|
continue;
|
||||||
@ -373,17 +372,9 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state)
|
|||||||
if (!old_hvs_state->fifo_state[channel].in_use)
|
if (!old_hvs_state->fifo_state[channel].in_use)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
commit = old_hvs_state->fifo_state[i].pending_commit;
|
ret = drm_crtc_commit_wait(old_hvs_state->fifo_state[i].pending_commit);
|
||||||
if (!commit)
|
if (ret)
|
||||||
continue;
|
drm_err(dev, "Timed out waiting for commit\n");
|
||||||
|
|
||||||
done = wait_for_completion_timeout(&commit->hw_done, 10 * HZ);
|
|
||||||
if (!done)
|
|
||||||
drm_err(dev, "Timed out waiting for hw_done\n");
|
|
||||||
|
|
||||||
done = wait_for_completion_timeout(&commit->flip_done, 10 * HZ);
|
|
||||||
if (!done)
|
|
||||||
drm_err(dev, "Timed out waiting for flip_done\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_atomic_helper_commit_modeset_disables(dev, state);
|
drm_atomic_helper_commit_modeset_disables(dev, state);
|
||||||
|
@ -66,6 +66,8 @@
|
|||||||
*
|
*
|
||||||
* For an implementation of how to use this look at
|
* For an implementation of how to use this look at
|
||||||
* drm_atomic_helper_setup_commit() from the atomic helper library.
|
* drm_atomic_helper_setup_commit() from the atomic helper library.
|
||||||
|
*
|
||||||
|
* See also drm_crtc_commit_wait().
|
||||||
*/
|
*/
|
||||||
struct drm_crtc_commit {
|
struct drm_crtc_commit {
|
||||||
/**
|
/**
|
||||||
@ -436,6 +438,8 @@ static inline void drm_crtc_commit_put(struct drm_crtc_commit *commit)
|
|||||||
kref_put(&commit->ref, __drm_crtc_commit_free);
|
kref_put(&commit->ref, __drm_crtc_commit_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int drm_crtc_commit_wait(struct drm_crtc_commit *commit);
|
||||||
|
|
||||||
struct drm_atomic_state * __must_check
|
struct drm_atomic_state * __must_check
|
||||||
drm_atomic_state_alloc(struct drm_device *dev);
|
drm_atomic_state_alloc(struct drm_device *dev);
|
||||||
void drm_atomic_state_clear(struct drm_atomic_state *state);
|
void drm_atomic_state_clear(struct drm_atomic_state *state);
|
||||||
|
Loading…
Reference in New Issue
Block a user