diff options
-rw-r--r-- | drivers/gpu/drm/drm_atomic_helper.c | 74 |
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 | ||
109 | static struct drm_crtc * | ||
110 | get_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 | |||
128 | static void | 109 | static void |
129 | set_best_encoder(struct drm_atomic_state *state, | 110 | set_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 | ||
169 | static int | 150 | static int |
170 | steal_encoder(struct drm_atomic_state *state, | 151 | steal_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)) |