Commit 76ec6927 authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Flag purely internal commits to not clear crtc_state->inherited

If we have to force the hardware to go through a full modeset
due to eg. cdclk reprogramming, we need to preserve
crtc_state->inherited for all crtcs that have not otherwise
gone through the whole compute_config() stuff after connectors
have been detected.

Otherwise eg. cdclk induced modeset glk_force_audio_cdclk()
will clear the inherited flag, and thus the first real commit
coming from userspace later on will not be forced through
the full .compute_config() path and so eg. audio state may
not get properly recomputed.

But instead of adding all kinds of ad-hoc crtc_state->inherited
preservation hacks all over, let's change things so that we
only clear it for the crtcs directly included in userspace/client
initiated commits.

Should be far less fragile since now we just need to remember
to flag the internal commits, and not worry about where new
crtcs might get pulled in.

Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5260Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230328122357.1697-1-ville.syrjala@linux.intel.comReviewed-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 1af1d188
...@@ -3447,9 +3447,10 @@ void ilk_wm_sanitize(struct drm_i915_private *dev_priv) ...@@ -3447,9 +3447,10 @@ void ilk_wm_sanitize(struct drm_i915_private *dev_priv)
drm_modeset_acquire_init(&ctx, 0); drm_modeset_acquire_init(&ctx, 0);
retry:
state->acquire_ctx = &ctx; state->acquire_ctx = &ctx;
to_intel_atomic_state(state)->internal = true;
retry:
/* /*
* Hardware readout is the only time we don't want to calculate * Hardware readout is the only time we don't want to calculate
* intermediate watermarks (since we don't trust the current * intermediate watermarks (since we don't trust the current
......
...@@ -265,7 +265,6 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc) ...@@ -265,7 +265,6 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
crtc_state->update_wm_post = false; crtc_state->update_wm_post = false;
crtc_state->fifo_changed = false; crtc_state->fifo_changed = false;
crtc_state->preload_luts = false; crtc_state->preload_luts = false;
crtc_state->inherited = false;
crtc_state->wm.need_postvbl_update = false; crtc_state->wm.need_postvbl_update = false;
crtc_state->do_async_flip = false; crtc_state->do_async_flip = false;
crtc_state->fb_bits = 0; crtc_state->fb_bits = 0;
...@@ -599,6 +598,8 @@ void intel_atomic_state_clear(struct drm_atomic_state *s) ...@@ -599,6 +598,8 @@ void intel_atomic_state_clear(struct drm_atomic_state *s)
drm_atomic_state_default_clear(&state->base); drm_atomic_state_default_clear(&state->base);
intel_atomic_clear_global_state(state); intel_atomic_clear_global_state(state);
/* state->internal not reset on purpose */
state->dpll_set = state->modeset = false; state->dpll_set = state->modeset = false;
} }
......
...@@ -1039,6 +1039,7 @@ static void glk_force_audio_cdclk(struct drm_i915_private *i915, ...@@ -1039,6 +1039,7 @@ static void glk_force_audio_cdclk(struct drm_i915_private *i915,
return; return;
state->acquire_ctx = &ctx; state->acquire_ctx = &ctx;
to_intel_atomic_state(state)->internal = true;
retry: retry:
ret = glk_force_audio_cdclk_commit(to_intel_atomic_state(state), crtc, ret = glk_force_audio_cdclk_commit(to_intel_atomic_state(state), crtc,
......
...@@ -3903,6 +3903,7 @@ static int modeset_pipe(struct drm_crtc *crtc, ...@@ -3903,6 +3903,7 @@ static int modeset_pipe(struct drm_crtc *crtc,
return -ENOMEM; return -ENOMEM;
state->acquire_ctx = ctx; state->acquire_ctx = ctx;
to_intel_atomic_state(state)->internal = true;
crtc_state = drm_atomic_get_crtc_state(state, crtc); crtc_state = drm_atomic_get_crtc_state(state, crtc);
if (IS_ERR(crtc_state)) { if (IS_ERR(crtc_state)) {
......
...@@ -4137,7 +4137,10 @@ int intel_get_load_detect_pipe(struct drm_connector *connector, ...@@ -4137,7 +4137,10 @@ int intel_get_load_detect_pipe(struct drm_connector *connector,
} }
state->acquire_ctx = ctx; state->acquire_ctx = ctx;
to_intel_atomic_state(state)->internal = true;
restore_state->acquire_ctx = ctx; restore_state->acquire_ctx = ctx;
to_intel_atomic_state(restore_state)->internal = true;
connector_state = drm_atomic_get_connector_state(state, connector); connector_state = drm_atomic_get_connector_state(state, connector);
if (IS_ERR(connector_state)) { if (IS_ERR(connector_state)) {
...@@ -6585,6 +6588,13 @@ int intel_atomic_check(struct drm_device *dev, ...@@ -6585,6 +6588,13 @@ int intel_atomic_check(struct drm_device *dev,
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
new_crtc_state, i) { new_crtc_state, i) {
/*
* crtc's state no longer considered to be inherited
* after the first userspace/client initiated commit.
*/
if (!state->internal)
new_crtc_state->inherited = false;
if (new_crtc_state->inherited != old_crtc_state->inherited) if (new_crtc_state->inherited != old_crtc_state->inherited)
new_crtc_state->uapi.mode_changed = true; new_crtc_state->uapi.mode_changed = true;
...@@ -8285,9 +8295,10 @@ static int intel_initial_commit(struct drm_device *dev) ...@@ -8285,9 +8295,10 @@ static int intel_initial_commit(struct drm_device *dev)
drm_modeset_acquire_init(&ctx, 0); drm_modeset_acquire_init(&ctx, 0);
retry:
state->acquire_ctx = &ctx; state->acquire_ctx = &ctx;
to_intel_atomic_state(state)->internal = true;
retry:
for_each_intel_crtc(dev, crtc) { for_each_intel_crtc(dev, crtc) {
struct intel_crtc_state *crtc_state = struct intel_crtc_state *crtc_state =
intel_atomic_get_crtc_state(state, crtc); intel_atomic_get_crtc_state(state, crtc);
...@@ -8300,15 +8311,6 @@ static int intel_initial_commit(struct drm_device *dev) ...@@ -8300,15 +8311,6 @@ static int intel_initial_commit(struct drm_device *dev)
if (crtc_state->hw.active) { if (crtc_state->hw.active) {
struct intel_encoder *encoder; struct intel_encoder *encoder;
/*
* We've not yet detected sink capabilities
* (audio,infoframes,etc.) and thus we don't want to
* force a full state recomputation yet. We want that to
* happen only for the first real commit from userspace.
* So preserve the inherited flag for the time being.
*/
crtc_state->inherited = true;
ret = drm_atomic_add_affected_planes(state, &crtc->base); ret = drm_atomic_add_affected_planes(state, &crtc->base);
if (ret) if (ret)
goto out; goto out;
......
...@@ -643,6 +643,9 @@ struct intel_atomic_state { ...@@ -643,6 +643,9 @@ struct intel_atomic_state {
struct __intel_global_objs_state *global_objs; struct __intel_global_objs_state *global_objs;
int num_global_objs; int num_global_objs;
/* Internal commit, as opposed to userspace/client initiated one */
bool internal;
bool dpll_set, modeset; bool dpll_set, modeset;
struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS]; struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS];
......
...@@ -69,6 +69,7 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc, ...@@ -69,6 +69,7 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc,
} }
state->acquire_ctx = ctx; state->acquire_ctx = ctx;
to_intel_atomic_state(state)->internal = true;
/* Everything's already locked, -EDEADLK can't happen. */ /* Everything's already locked, -EDEADLK can't happen. */
temp_crtc_state = intel_atomic_get_crtc_state(state, crtc); temp_crtc_state = intel_atomic_get_crtc_state(state, crtc);
......
...@@ -293,6 +293,7 @@ intel_crtc_crc_setup_workarounds(struct intel_crtc *crtc, bool enable) ...@@ -293,6 +293,7 @@ intel_crtc_crc_setup_workarounds(struct intel_crtc *crtc, bool enable)
} }
state->acquire_ctx = &ctx; state->acquire_ctx = &ctx;
to_intel_atomic_state(state)->internal = true;
retry: retry:
pipe_config = intel_atomic_get_crtc_state(state, crtc); pipe_config = intel_atomic_get_crtc_state(state, crtc);
......
...@@ -2149,10 +2149,11 @@ static int intel_psr_fastset_force(struct drm_i915_private *dev_priv) ...@@ -2149,10 +2149,11 @@ static int intel_psr_fastset_force(struct drm_i915_private *dev_priv)
return -ENOMEM; return -ENOMEM;
drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
state->acquire_ctx = &ctx; state->acquire_ctx = &ctx;
to_intel_atomic_state(state)->internal = true;
retry: retry:
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
drm_for_each_connector_iter(conn, &conn_iter) { drm_for_each_connector_iter(conn, &conn_iter) {
struct drm_connector_state *conn_state; struct drm_connector_state *conn_state;
......
...@@ -86,6 +86,7 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, ...@@ -86,6 +86,7 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
goto out; goto out;
} }
state->acquire_ctx = &ctx; state->acquire_ctx = &ctx;
to_intel_atomic_state(state)->internal = true;
while (1) { while (1) {
plane_state = drm_atomic_get_plane_state(state, plane); plane_state = drm_atomic_get_plane_state(state, plane);
......
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