aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c74
1 files changed, 20 insertions, 54 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index ed28ca1fc494..32f6f57fc66e 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -106,25 +106,6 @@ check_pending_encoder_assignment(struct drm_atomic_state *state,
106 return true; 106 return true;
107} 107}
108 108
109static struct drm_crtc *
110get_current_crtc_for_encoder(struct drm_device *dev,
111 struct drm_encoder *encoder)
112{
113 struct drm_mode_config *config = &dev->mode_config;
114 struct drm_connector *connector;
115
116 WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
117
118 drm_for_each_connector(connector, dev) {
119 if (connector->state->best_encoder != encoder)
120 continue;
121
122 return connector->state->crtc;
123 }
124
125 return NULL;
126}
127
128static void 109static void
129set_best_encoder(struct drm_atomic_state *state, 110set_best_encoder(struct drm_atomic_state *state,
130 struct drm_connector_state *conn_state, 111 struct drm_connector_state *conn_state,
@@ -168,38 +149,18 @@ set_best_encoder(struct drm_atomic_state *state,
168 149
169static int 150static int
170steal_encoder(struct drm_atomic_state *state, 151steal_encoder(struct drm_atomic_state *state,
171 struct drm_encoder *encoder, 152 struct drm_encoder *encoder)
172 struct drm_crtc *encoder_crtc)
173{ 153{
174 struct drm_mode_config *config = &state->dev->mode_config;
175 struct drm_crtc_state *crtc_state; 154 struct drm_crtc_state *crtc_state;
176 struct drm_connector *connector; 155 struct drm_connector *connector;
177 struct drm_connector_state *connector_state; 156 struct drm_connector_state *connector_state;
178 157
179 /* 158 drm_for_each_connector(connector, state->dev) {
180 * We can only steal an encoder coming from a connector, which means we 159 struct drm_crtc *encoder_crtc;
181 * must already hold the connection_mutex.
182 */
183 WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
184
185 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n",
186 encoder->base.id, encoder->name,
187 encoder_crtc->base.id, encoder_crtc->name);
188 160
189 crtc_state = drm_atomic_get_crtc_state(state, encoder_crtc);
190 if (IS_ERR(crtc_state))
191 return PTR_ERR(crtc_state);
192
193 crtc_state->connectors_changed = true;
194
195 list_for_each_entry(connector, &config->connector_list, head) {
196 if (connector->state->best_encoder != encoder) 161 if (connector->state->best_encoder != encoder)
197 continue; 162 continue;
198 163
199 DRM_DEBUG_ATOMIC("Stealing encoder from [CONNECTOR:%d:%s]\n",
200 connector->base.id,
201 connector->name);
202
203 connector_state = drm_atomic_get_connector_state(state, 164 connector_state = drm_atomic_get_connector_state(state,
204 connector); 165 connector);
205 if (IS_ERR(connector_state)) 166 if (IS_ERR(connector_state))
@@ -208,7 +169,18 @@ steal_encoder(struct drm_atomic_state *state,
208 if (connector_state->best_encoder != encoder) 169 if (connector_state->best_encoder != encoder)
209 continue; 170 continue;
210 171
172 encoder_crtc = connector->state->crtc;
173
174 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n",
175 encoder->base.id, encoder->name,
176 encoder_crtc->base.id, encoder_crtc->name);
177
211 set_best_encoder(state, connector_state, NULL); 178 set_best_encoder(state, connector_state, NULL);
179
180 crtc_state = drm_atomic_get_existing_crtc_state(state, encoder_crtc);
181 crtc_state->connectors_changed = true;
182
183 return 0;
212 } 184 }
213 185
214 return 0; 186 return 0;
@@ -221,7 +193,6 @@ update_connector_routing(struct drm_atomic_state *state,
221{ 193{
222 const struct drm_connector_helper_funcs *funcs; 194 const struct drm_connector_helper_funcs *funcs;
223 struct drm_encoder *new_encoder; 195 struct drm_encoder *new_encoder;
224 struct drm_crtc *encoder_crtc;
225 struct drm_crtc_state *crtc_state; 196 struct drm_crtc_state *crtc_state;
226 int idx, ret; 197 int idx, ret;
227 198
@@ -299,17 +270,12 @@ update_connector_routing(struct drm_atomic_state *state,
299 return -EINVAL; 270 return -EINVAL;
300 } 271 }
301 272
302 encoder_crtc = get_current_crtc_for_encoder(state->dev, 273 ret = steal_encoder(state, new_encoder);
303 new_encoder); 274 if (ret) {
304 275 DRM_DEBUG_ATOMIC("Encoder stealing failed for [CONNECTOR:%d:%s]\n",
305 if (encoder_crtc) { 276 connector->base.id,
306 ret = steal_encoder(state, new_encoder, encoder_crtc); 277 connector->name);
307 if (ret) { 278 return ret;
308 DRM_DEBUG_ATOMIC("Encoder stealing failed for [CONNECTOR:%d:%s]\n",
309 connector->base.id,
310 connector->name);
311 return ret;
312 }
313 } 279 }
314 280
315 if (WARN_ON(!connector_state->crtc)) 281 if (WARN_ON(!connector_state->crtc))