Commit 2b7947bd authored by Simon Ser's avatar Simon Ser

drm/atomic-helper: relax unregistered connector check

The driver might pull connectors which weren't submitted by
user-space into the atomic state. For instance,
intel_dp_mst_atomic_master_trans_check() pulls in connectors
sharing the same DP-MST stream. However, if the connector is
unregistered, this later fails with:

    [  559.425658] i915 0000:00:02.0: [drm:drm_atomic_helper_check_modeset] [CONNECTOR:378:DP-7] is not registered

Skip the unregistered connector check to allow user-space to turn
off connectors one-by-one.

See this wlroots issue:
https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3407

Previous discussion:
https://lore.kernel.org/intel-gfx/Y6GX7z17WmDSKwta@ideak-desk.fi.intel.com/Signed-off-by: default avatarSimon Ser <contact@emersion.fr>
Cc: stable@vger.kernel.org
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231005131623.114379-1-contact@emersion.fr
parent 258dd5e6
...@@ -290,7 +290,8 @@ static int ...@@ -290,7 +290,8 @@ static int
update_connector_routing(struct drm_atomic_state *state, update_connector_routing(struct drm_atomic_state *state,
struct drm_connector *connector, struct drm_connector *connector,
struct drm_connector_state *old_connector_state, struct drm_connector_state *old_connector_state,
struct drm_connector_state *new_connector_state) struct drm_connector_state *new_connector_state,
bool added_by_user)
{ {
const struct drm_connector_helper_funcs *funcs; const struct drm_connector_helper_funcs *funcs;
struct drm_encoder *new_encoder; struct drm_encoder *new_encoder;
...@@ -339,9 +340,13 @@ update_connector_routing(struct drm_atomic_state *state, ...@@ -339,9 +340,13 @@ update_connector_routing(struct drm_atomic_state *state,
* there's a chance the connector may have been destroyed during the * there's a chance the connector may have been destroyed during the
* process, but it's better to ignore that then cause * process, but it's better to ignore that then cause
* drm_atomic_helper_resume() to fail. * drm_atomic_helper_resume() to fail.
*
* Last, we want to ignore connector registration when the connector
* was not pulled in the atomic state by user-space (ie, was pulled
* in by the driver, e.g. when updating a DP-MST stream).
*/ */
if (!state->duplicated && drm_connector_is_unregistered(connector) && if (!state->duplicated && drm_connector_is_unregistered(connector) &&
crtc_state->active) { added_by_user && crtc_state->active) {
drm_dbg_atomic(connector->dev, drm_dbg_atomic(connector->dev,
"[CONNECTOR:%d:%s] is not registered\n", "[CONNECTOR:%d:%s] is not registered\n",
connector->base.id, connector->name); connector->base.id, connector->name);
...@@ -620,7 +625,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, ...@@ -620,7 +625,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_state *old_connector_state, *new_connector_state; struct drm_connector_state *old_connector_state, *new_connector_state;
int i, ret; int i, ret;
unsigned int connectors_mask = 0; unsigned int connectors_mask = 0, user_connectors_mask = 0;
for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i)
user_connectors_mask |= BIT(i);
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
bool has_connectors = bool has_connectors =
...@@ -685,7 +693,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, ...@@ -685,7 +693,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
*/ */
ret = update_connector_routing(state, connector, ret = update_connector_routing(state, connector,
old_connector_state, old_connector_state,
new_connector_state); new_connector_state,
BIT(i) & user_connectors_mask);
if (ret) if (ret)
return ret; return ret;
if (old_connector_state->crtc) { if (old_connector_state->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