Rev 6937 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6937 | Rev 7144 | ||
---|---|---|---|
Line 65... | Line 65... | ||
65 | struct drm_plane *plane) |
65 | struct drm_plane *plane) |
66 | { |
66 | { |
67 | struct drm_crtc_state *crtc_state; |
67 | struct drm_crtc_state *crtc_state; |
Line 68... | Line 68... | ||
68 | 68 | ||
69 | if (plane->state->crtc) { |
69 | if (plane->state->crtc) { |
- | 70 | crtc_state = drm_atomic_get_existing_crtc_state(state, |
|
Line 70... | Line 71... | ||
70 | crtc_state = state->crtc_states[drm_crtc_index(plane->state->crtc)]; |
71 | plane->state->crtc); |
71 | 72 | ||
Line 72... | Line 73... | ||
72 | if (WARN_ON(!crtc_state)) |
73 | if (WARN_ON(!crtc_state)) |
73 | return; |
74 | return; |
Line 74... | Line 75... | ||
74 | 75 | ||
75 | crtc_state->planes_changed = true; |
76 | crtc_state->planes_changed = true; |
76 | } |
77 | } |
Line 77... | Line 78... | ||
77 | 78 | ||
78 | if (plane_state->crtc) { |
79 | if (plane_state->crtc) { |
Line 79... | Line 80... | ||
79 | crtc_state = |
80 | crtc_state = drm_atomic_get_existing_crtc_state(state, |
80 | state->crtc_states[drm_crtc_index(plane_state->crtc)]; |
81 | plane_state->crtc); |
81 | 82 | ||
Line 82... | Line -... | ||
82 | if (WARN_ON(!crtc_state)) |
- | |
83 | return; |
83 | if (WARN_ON(!crtc_state)) |
84 | 84 | return; |
|
85 | crtc_state->planes_changed = true; |
85 | |
86 | } |
- | |
87 | } |
86 | crtc_state->planes_changed = true; |
- | 87 | } |
|
- | 88 | } |
|
- | 89 | ||
88 | 90 | static int handle_conflicting_encoders(struct drm_atomic_state *state, |
|
Line -... | Line 91... | ||
- | 91 | bool disable_conflicting_encoders) |
|
- | 92 | { |
|
- | 93 | struct drm_connector_state *conn_state; |
|
- | 94 | struct drm_connector *connector; |
|
- | 95 | struct drm_encoder *encoder; |
|
89 | static bool |
96 | unsigned encoder_mask = 0; |
- | 97 | int i, ret; |
|
90 | check_pending_encoder_assignment(struct drm_atomic_state *state, |
98 | |
- | 99 | /* |
|
- | 100 | * First loop, find all newly assigned encoders from the connectors |
|
91 | struct drm_encoder *new_encoder) |
101 | * part of the state. If the same encoder is assigned to multiple |
Line -... | Line 102... | ||
- | 102 | * connectors bail out. |
|
92 | { |
103 | */ |
- | 104 | for_each_connector_in_state(state, connector, conn_state, i) { |
|
- | 105 | const struct drm_connector_helper_funcs *funcs = connector->helper_private; |
|
- | 106 | struct drm_encoder *new_encoder; |
|
- | 107 | ||
93 | struct drm_connector *connector; |
108 | if (!conn_state->crtc) |
- | 109 | continue; |
|
- | 110 | ||
- | 111 | if (funcs->atomic_best_encoder) |
|
- | 112 | new_encoder = funcs->atomic_best_encoder(connector, conn_state); |
|
94 | struct drm_connector_state *conn_state; |
113 | else |
95 | int i; |
114 | new_encoder = funcs->best_encoder(connector); |
Line -... | Line 115... | ||
- | 115 | ||
96 | 116 | if (new_encoder) { |
|
97 | for_each_connector_in_state(state, connector, conn_state, i) { |
117 | if (encoder_mask & (1 << drm_encoder_index(new_encoder))) { |
Line -... | Line 118... | ||
- | 118 | DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] on [CONNECTOR:%d:%s] already assigned\n", |
|
- | 119 | new_encoder->base.id, new_encoder->name, |
|
- | 120 | connector->base.id, connector->name); |
|
- | 121 | ||
- | 122 | return -EINVAL; |
|
- | 123 | } |
|
- | 124 | ||
- | 125 | encoder_mask |= 1 << drm_encoder_index(new_encoder); |
|
- | 126 | } |
|
- | 127 | } |
|
- | 128 | ||
- | 129 | if (!encoder_mask) |
|
- | 130 | return 0; |
|
- | 131 | ||
- | 132 | /* |
|
98 | if (conn_state->best_encoder != new_encoder) |
133 | * Second loop, iterate over all connectors not part of the state. |
- | 134 | * |
|
- | 135 | * If a conflicting encoder is found and disable_conflicting_encoders |
|
- | 136 | * is not set, an error is returned. Userspace can provide a solution |
|
- | 137 | * through the atomic ioctl. |
|
- | 138 | * |
|
- | 139 | * If the flag is set conflicting connectors are removed from the crtc |
|
- | 140 | * and the crtc is disabled if no encoder is left. This preserves |
|
- | 141 | * compatibility with the legacy set_config behavior. |
|
- | 142 | */ |
|
- | 143 | drm_for_each_connector(connector, state->dev) { |
|
- | 144 | struct drm_crtc_state *crtc_state; |
|
- | 145 | ||
- | 146 | if (drm_atomic_get_existing_connector_state(state, connector)) |
|
- | 147 | continue; |
|
- | 148 | ||
- | 149 | encoder = connector->state->best_encoder; |
|
- | 150 | if (!encoder || !(encoder_mask & (1 << drm_encoder_index(encoder)))) |
|
- | 151 | continue; |
|
- | 152 | ||
- | 153 | if (!disable_conflicting_encoders) { |
|
- | 154 | DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s] by [CONNECTOR:%d:%s]\n", |
|
- | 155 | encoder->base.id, encoder->name, |
|
- | 156 | connector->state->crtc->base.id, |
|
- | 157 | connector->state->crtc->name, |
|
- | 158 | connector->base.id, connector->name); |
|
- | 159 | return -EINVAL; |
|
- | 160 | } |
|
- | 161 | ||
- | 162 | conn_state = drm_atomic_get_connector_state(state, connector); |
|
- | 163 | if (IS_ERR(conn_state)) |
|
- | 164 | return PTR_ERR(conn_state); |
|
- | 165 | ||
- | 166 | DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n", |
|
- | 167 | encoder->base.id, encoder->name, |
|
- | 168 | conn_state->crtc->base.id, conn_state->crtc->name, |
|
- | 169 | connector->base.id, connector->name); |
|
- | 170 | ||
- | 171 | crtc_state = drm_atomic_get_existing_crtc_state(state, conn_state->crtc); |
|
- | 172 | ||
- | 173 | ret = drm_atomic_set_crtc_for_connector(conn_state, NULL); |
|
- | 174 | if (ret) |
|
- | 175 | return ret; |
|
- | 176 | ||
- | 177 | if (!crtc_state->connector_mask) { |
|
- | 178 | ret = drm_atomic_set_mode_prop_for_crtc(crtc_state, |
|
- | 179 | NULL); |
|
99 | continue; |
180 | if (ret < 0) |
- | 181 | return ret; |
|
100 | 182 | ||
101 | /* encoder already assigned and we're trying to re-steal it! */ |
183 | crtc_state->active = false; |
102 | if (connector->state->best_encoder != conn_state->best_encoder) |
184 | } |
103 | return false; |
185 | } |
Line -... | Line 186... | ||
- | 186 | ||
- | 187 | return 0; |
|
104 | } |
188 | } |
Line -... | Line 189... | ||
- | 189 | ||
- | 190 | static void |
|
105 | 191 | set_best_encoder(struct drm_atomic_state *state, |
|
- | 192 | struct drm_connector_state *conn_state, |
|
106 | return true; |
193 | struct drm_encoder *encoder) |
- | 194 | { |
|
- | 195 | struct drm_crtc_state *crtc_state; |
|
107 | } |
196 | struct drm_crtc *crtc; |
- | 197 | ||
- | 198 | if (conn_state->best_encoder) { |
|
- | 199 | /* Unset the encoder_mask in the old crtc state. */ |
|
- | 200 | crtc = conn_state->connector->state->crtc; |
|
- | 201 | ||
- | 202 | /* A NULL crtc is an error here because we should have |
|
Line -... | Line 203... | ||
- | 203 | * duplicated a NULL best_encoder when crtc was NULL. |
|
108 | 204 | * As an exception restoring duplicated atomic state |
|
- | 205 | * during resume is allowed, so don't warn when |
|
- | 206 | * best_encoder is equal to encoder we intend to set. |
|
- | 207 | */ |
|
- | 208 | WARN_ON(!crtc && encoder != conn_state->best_encoder); |
|
- | 209 | if (crtc) { |
|
- | 210 | crtc_state = drm_atomic_get_existing_crtc_state(state, crtc); |
|
- | 211 | ||
109 | static struct drm_crtc * |
212 | crtc_state->encoder_mask &= |
Line 110... | Line 213... | ||
110 | get_current_crtc_for_encoder(struct drm_device *dev, |
213 | ~(1 << drm_encoder_index(conn_state->best_encoder)); |
111 | struct drm_encoder *encoder) |
214 | } |
Line 112... | Line 215... | ||
112 | { |
215 | } |
113 | struct drm_mode_config *config = &dev->mode_config; |
216 | |
114 | struct drm_connector *connector; |
217 | if (encoder) { |
115 | - | ||
116 | WARN_ON(!drm_modeset_is_locked(&config->connection_mutex)); |
218 | crtc = conn_state->crtc; |
117 | - | ||
118 | drm_for_each_connector(connector, dev) { |
219 | WARN_ON(!crtc); |
119 | if (connector->state->best_encoder != encoder) |
220 | if (crtc) { |
120 | continue; |
221 | crtc_state = drm_atomic_get_existing_crtc_state(state, crtc); |
121 | 222 | ||
Line -... | Line 223... | ||
- | 223 | crtc_state->encoder_mask |= |
|
- | 224 | 1 << drm_encoder_index(encoder); |
|
122 | return connector->state->crtc; |
225 | } |
123 | } |
226 | } |
124 | 227 | ||
125 | return NULL; |
228 | conn_state->best_encoder = encoder; |
126 | } |
229 | } |
Line 127... | Line 230... | ||
127 | 230 | ||
128 | static int |
231 | static void |
129 | steal_encoder(struct drm_atomic_state *state, |
232 | steal_encoder(struct drm_atomic_state *state, |
Line 130... | Line 233... | ||
130 | struct drm_encoder *encoder, |
233 | struct drm_encoder *encoder) |
131 | struct drm_crtc *encoder_crtc) |
- | |
132 | { |
- | |
Line -... | Line 234... | ||
- | 234 | { |
|
133 | struct drm_mode_config *config = &state->dev->mode_config; |
235 | struct drm_crtc_state *crtc_state; |
Line 134... | Line -... | ||
134 | struct drm_crtc_state *crtc_state; |
- | |
135 | struct drm_connector *connector; |
- | |
136 | struct drm_connector_state *connector_state; |
- | |
137 | int ret; |
- | |
138 | - | ||
139 | /* |
- | |
140 | * We can only steal an encoder coming from a connector, which means we |
- | |
141 | * must already hold the connection_mutex. |
- | |
142 | */ |
- | |
143 | WARN_ON(!drm_modeset_is_locked(&config->connection_mutex)); |
- | |
144 | - | ||
145 | DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n", |
- | |
146 | encoder->base.id, encoder->name, |
- | |
147 | encoder_crtc->base.id, encoder_crtc->name); |
- | |
148 | - | ||
149 | crtc_state = drm_atomic_get_crtc_state(state, encoder_crtc); |
236 | struct drm_connector *connector; |
150 | if (IS_ERR(crtc_state)) |
- | |
151 | return PTR_ERR(crtc_state); |
237 | struct drm_connector_state *connector_state; |
152 | - | ||
153 | crtc_state->connectors_changed = true; |
- | |
154 | 238 | int i; |
|
Line 155... | Line 239... | ||
155 | list_for_each_entry(connector, &config->connector_list, head) { |
239 | |
156 | if (connector->state->best_encoder != encoder) |
240 | for_each_connector_in_state(state, connector, connector_state, i) { |
- | 241 | struct drm_crtc *encoder_crtc; |
|
- | 242 | ||
157 | continue; |
243 | if (connector_state->best_encoder != encoder) |
158 | 244 | continue; |
|
159 | DRM_DEBUG_ATOMIC("Stealing encoder from [CONNECTOR:%d:%s]\n", |
245 | |
160 | connector->base.id, |
- | |
161 | connector->name); |
- | |
162 | - | ||
163 | connector_state = drm_atomic_get_connector_state(state, |
246 | encoder_crtc = connector->state->crtc; |
164 | connector); |
- | |
165 | if (IS_ERR(connector_state)) |
- | |
166 | return PTR_ERR(connector_state); |
- | |
167 | - | ||
168 | ret = drm_atomic_set_crtc_for_connector(connector_state, NULL); |
- | |
169 | if (ret) |
- | |
170 | return ret; |
- | |
Line 171... | Line 247... | ||
171 | connector_state->best_encoder = NULL; |
247 | |
172 | } |
248 | DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n", |
173 | 249 | encoder->base.id, encoder->name, |
|
Line 174... | Line 250... | ||
174 | return 0; |
250 | encoder_crtc->base.id, encoder_crtc->name); |
175 | } |
251 | |
176 | 252 | set_best_encoder(state, connector_state, NULL); |
|
177 | static int |
- | |
178 | update_connector_routing(struct drm_atomic_state *state, int conn_idx) |
- | |
179 | { |
253 | |
180 | const struct drm_connector_helper_funcs *funcs; |
254 | crtc_state = drm_atomic_get_existing_crtc_state(state, encoder_crtc); |
Line 181... | Line 255... | ||
181 | struct drm_encoder *new_encoder; |
255 | crtc_state->connectors_changed = true; |
182 | struct drm_crtc *encoder_crtc; |
256 | |
183 | struct drm_connector *connector; |
- | |
184 | struct drm_connector_state *connector_state; |
- | |
185 | struct drm_crtc_state *crtc_state; |
257 | return; |
186 | int idx, ret; |
258 | } |
187 | 259 | } |
|
Line 188... | Line 260... | ||
188 | connector = state->connectors[conn_idx]; |
260 | |
189 | connector_state = state->connector_states[conn_idx]; |
261 | static int |
190 | 262 | update_connector_routing(struct drm_atomic_state *state, |
|
191 | if (!connector) |
263 | struct drm_connector *connector, |
Line 192... | Line 264... | ||
192 | return 0; |
264 | struct drm_connector_state *connector_state) |
Line 193... | Line 265... | ||
193 | 265 | { |
|
194 | DRM_DEBUG_ATOMIC("Updating routing for [CONNECTOR:%d:%s]\n", |
266 | const struct drm_connector_helper_funcs *funcs; |
Line 195... | Line 267... | ||
195 | connector->base.id, |
267 | struct drm_encoder *new_encoder; |
Line 243... | Line 315... | ||
243 | connector_state->crtc->base.id); |
315 | connector_state->crtc->base.id); |
244 | return -EINVAL; |
316 | return -EINVAL; |
245 | } |
317 | } |
Line 246... | Line 318... | ||
246 | 318 | ||
- | 319 | if (new_encoder == connector_state->best_encoder) { |
|
- | 320 | set_best_encoder(state, connector_state, new_encoder); |
|
247 | if (new_encoder == connector_state->best_encoder) { |
321 | |
248 | DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n", |
322 | DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n", |
249 | connector->base.id, |
323 | connector->base.id, |
250 | connector->name, |
324 | connector->name, |
251 | new_encoder->base.id, |
325 | new_encoder->base.id, |
Line 254... | Line 328... | ||
254 | connector_state->crtc->name); |
328 | connector_state->crtc->name); |
Line 255... | Line 329... | ||
255 | 329 | ||
256 | return 0; |
330 | return 0; |
Line 257... | Line 331... | ||
257 | } |
331 | } |
258 | - | ||
259 | if (!check_pending_encoder_assignment(state, new_encoder)) { |
- | |
260 | DRM_DEBUG_ATOMIC("Encoder for [CONNECTOR:%d:%s] already assigned\n", |
- | |
261 | connector->base.id, |
- | |
262 | connector->name); |
- | |
263 | return -EINVAL; |
- | |
264 | } |
- | |
265 | - | ||
Line 266... | Line -... | ||
266 | encoder_crtc = get_current_crtc_for_encoder(state->dev, |
- | |
267 | new_encoder); |
332 | |
268 | - | ||
269 | if (encoder_crtc) { |
- | |
270 | ret = steal_encoder(state, new_encoder, encoder_crtc); |
- | |
271 | if (ret) { |
- | |
272 | DRM_DEBUG_ATOMIC("Encoder stealing failed for [CONNECTOR:%d:%s]\n", |
- | |
273 | connector->base.id, |
- | |
274 | connector->name); |
- | |
Line 275... | Line -... | ||
275 | return ret; |
- | |
276 | } |
- | |
277 | } |
- | |
278 | - | ||
279 | if (WARN_ON(!connector_state->crtc)) |
333 | steal_encoder(state, new_encoder); |
280 | return -EINVAL; |
- | |
281 | - | ||
282 | connector_state->best_encoder = new_encoder; |
334 | |
Line 283... | Line 335... | ||
283 | idx = drm_crtc_index(connector_state->crtc); |
335 | set_best_encoder(state, connector_state, new_encoder); |
284 | 336 | ||
285 | crtc_state = state->crtc_states[idx]; |
337 | crtc_state = drm_atomic_get_existing_crtc_state(state, connector_state->crtc); |
Line 321... | Line 373... | ||
321 | WARN_ON(!!conn_state->best_encoder != !!conn_state->crtc); |
373 | WARN_ON(!!conn_state->best_encoder != !!conn_state->crtc); |
Line 322... | Line 374... | ||
322 | 374 | ||
323 | if (!conn_state->crtc || !conn_state->best_encoder) |
375 | if (!conn_state->crtc || !conn_state->best_encoder) |
Line 324... | Line 376... | ||
324 | continue; |
376 | continue; |
325 | 377 | ||
Line 326... | Line 378... | ||
326 | crtc_state = |
378 | crtc_state = drm_atomic_get_existing_crtc_state(state, |
327 | state->crtc_states[drm_crtc_index(conn_state->crtc)]; |
379 | conn_state->crtc); |
328 | 380 | ||
329 | /* |
381 | /* |
Line 443... | Line 495... | ||
443 | crtc_state->mode_changed = true; |
495 | crtc_state->mode_changed = true; |
444 | crtc_state->connectors_changed = true; |
496 | crtc_state->connectors_changed = true; |
445 | } |
497 | } |
446 | } |
498 | } |
Line -... | Line 499... | ||
- | 499 | ||
- | 500 | ret = handle_conflicting_encoders(state, state->legacy_set_config); |
|
- | 501 | if (ret) |
|
- | 502 | return ret; |
|
447 | 503 | ||
448 | for_each_connector_in_state(state, connector, connector_state, i) { |
504 | for_each_connector_in_state(state, connector, connector_state, i) { |
449 | /* |
505 | /* |
450 | * This only sets crtc->mode_changed for routing changes, |
506 | * This only sets crtc->mode_changed for routing changes, |
451 | * drivers must set crtc->mode_changed themselves when connector |
507 | * drivers must set crtc->mode_changed themselves when connector |
452 | * properties need to be updated. |
508 | * properties need to be updated. |
453 | */ |
509 | */ |
- | 510 | ret = update_connector_routing(state, connector, |
|
454 | ret = update_connector_routing(state, i); |
511 | connector_state); |
455 | if (ret) |
512 | if (ret) |
456 | return ret; |
513 | return ret; |
Line 457... | Line 514... | ||
457 | } |
514 | } |
Line 615... | Line 672... | ||
615 | int i; |
672 | int i; |
Line 616... | Line 673... | ||
616 | 673 | ||
617 | for_each_connector_in_state(old_state, connector, old_conn_state, i) { |
674 | for_each_connector_in_state(old_state, connector, old_conn_state, i) { |
618 | const struct drm_encoder_helper_funcs *funcs; |
675 | const struct drm_encoder_helper_funcs *funcs; |
619 | struct drm_encoder *encoder; |
- | |
Line 620... | Line 676... | ||
620 | struct drm_crtc_state *old_crtc_state; |
676 | struct drm_encoder *encoder; |
621 | 677 | ||
622 | /* Shut down everything that's in the changeset and currently |
678 | /* Shut down everything that's in the changeset and currently |
623 | * still on. So need to check the old, saved state. */ |
679 | * still on. So need to check the old, saved state. */ |
Line 624... | Line 680... | ||
624 | if (!old_conn_state->crtc) |
680 | if (!old_conn_state->crtc) |
- | 681 | continue; |
|
Line 625... | Line 682... | ||
625 | continue; |
682 | |
626 | 683 | old_crtc_state = drm_atomic_get_existing_crtc_state(old_state, |
|
627 | old_crtc_state = old_state->crtc_states[drm_crtc_index(old_conn_state->crtc)]; |
684 | old_conn_state->crtc); |
Line 1717... | Line 1774... | ||
1717 | struct drm_device *dev = set->crtc->dev; |
1774 | struct drm_device *dev = set->crtc->dev; |
1718 | struct drm_crtc *crtc; |
1775 | struct drm_crtc *crtc; |
1719 | struct drm_crtc_state *crtc_state; |
1776 | struct drm_crtc_state *crtc_state; |
1720 | struct drm_connector *connector; |
1777 | struct drm_connector *connector; |
1721 | struct drm_connector_state *conn_state; |
1778 | struct drm_connector_state *conn_state; |
1722 | int ret, i, j; |
1779 | int ret, i; |
Line 1723... | Line 1780... | ||
1723 | 1780 | ||
1724 | ret = drm_modeset_lock(&dev->mode_config.connection_mutex, |
1781 | ret = drm_modeset_lock(&dev->mode_config.connection_mutex, |
1725 | state->acquire_ctx); |
1782 | state->acquire_ctx); |
1726 | if (ret) |
1783 | if (ret) |
Line 1727... | Line 1784... | ||
1727 | return ret; |
1784 | return ret; |
1728 | - | ||
1729 | /* First grab all affected connector/crtc states. */ |
- | |
1730 | for (i = 0; i < set->num_connectors; i++) { |
- | |
1731 | conn_state = drm_atomic_get_connector_state(state, |
- | |
1732 | set->connectors[i]); |
- | |
1733 | if (IS_ERR(conn_state)) |
- | |
1734 | return PTR_ERR(conn_state); |
- | |
1735 | } |
- | |
1736 | 1785 | ||
1737 | for_each_crtc_in_state(state, crtc, crtc_state, i) { |
1786 | /* First disable all connectors on the target crtc. */ |
1738 | ret = drm_atomic_add_affected_connectors(state, crtc); |
1787 | ret = drm_atomic_add_affected_connectors(state, set->crtc); |
1739 | if (ret) |
- | |
Line 1740... | Line -... | ||
1740 | return ret; |
- | |
1741 | } |
1788 | if (ret) |
1742 | 1789 | return ret; |
|
1743 | /* Then recompute connector->crtc links and crtc enabling state. */ |
1790 | |
1744 | for_each_connector_in_state(state, connector, conn_state, i) { |
1791 | for_each_connector_in_state(state, connector, conn_state, i) { |
1745 | if (conn_state->crtc == set->crtc) { |
1792 | if (conn_state->crtc == set->crtc) { |
1746 | ret = drm_atomic_set_crtc_for_connector(conn_state, |
1793 | ret = drm_atomic_set_crtc_for_connector(conn_state, |
1747 | NULL); |
1794 | NULL); |
- | 1795 | if (ret) |
|
- | 1796 | return ret; |
|
- | 1797 | } |
|
- | 1798 | } |
|
- | 1799 | ||
- | 1800 | /* Then set all connectors from set->connectors on the target crtc */ |
|
- | 1801 | for (i = 0; i < set->num_connectors; i++) { |
|
- | 1802 | conn_state = drm_atomic_get_connector_state(state, |
|
Line 1748... | Line -... | ||
1748 | if (ret) |
- | |
1749 | return ret; |
- | |
1750 | } |
1803 | set->connectors[i]); |
1751 | 1804 | if (IS_ERR(conn_state)) |
|
1752 | for (j = 0; j < set->num_connectors; j++) { |
1805 | return PTR_ERR(conn_state); |
1753 | if (set->connectors[j] == connector) { |
1806 | |
1754 | ret = drm_atomic_set_crtc_for_connector(conn_state, |
- | |
1755 | set->crtc); |
- | |
1756 | if (ret) |
- | |
1757 | return ret; |
1807 | ret = drm_atomic_set_crtc_for_connector(conn_state, |
Line 1758... | Line 1808... | ||
1758 | break; |
1808 | set->crtc); |
1759 | } |
1809 | if (ret) |
1760 | } |
1810 | return ret; |
Line 1798... | Line 1848... | ||
1798 | 1848 | ||
1799 | state = drm_atomic_state_alloc(crtc->dev); |
1849 | state = drm_atomic_state_alloc(crtc->dev); |
1800 | if (!state) |
1850 | if (!state) |
Line -... | Line 1851... | ||
- | 1851 | return -ENOMEM; |
|
1801 | return -ENOMEM; |
1852 | |
1802 | 1853 | state->legacy_set_config = true; |
|
1803 | state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); |
1854 | state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); |
1804 | retry: |
1855 | retry: |
1805 | ret = __drm_atomic_helper_set_config(set, state); |
1856 | ret = __drm_atomic_helper_set_config(set, state); |
Line 2444... | Line 2495... | ||
2444 | * Resets the atomic state for @crtc by freeing the state pointer (which might |
2495 | * Resets the atomic state for @crtc by freeing the state pointer (which might |
2445 | * be NULL, e.g. at driver load time) and allocating a new empty state object. |
2496 | * be NULL, e.g. at driver load time) and allocating a new empty state object. |
2446 | */ |
2497 | */ |
2447 | void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc) |
2498 | void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc) |
2448 | { |
2499 | { |
2449 | if (crtc->state) |
2500 | if (crtc->state) { |
2450 | drm_property_unreference_blob(crtc->state->mode_blob); |
2501 | drm_property_unreference_blob(crtc->state->mode_blob); |
- | 2502 | drm_property_unreference_blob(crtc->state->degamma_lut); |
|
- | 2503 | drm_property_unreference_blob(crtc->state->ctm); |
|
- | 2504 | drm_property_unreference_blob(crtc->state->gamma_lut); |
|
- | 2505 | } |
|
2451 | kfree(crtc->state); |
2506 | kfree(crtc->state); |
2452 | crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL); |
2507 | crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL); |
Line 2453... | Line 2508... | ||
2453 | 2508 | ||
2454 | if (crtc->state) |
2509 | if (crtc->state) |
Line 2469... | Line 2524... | ||
2469 | { |
2524 | { |
2470 | memcpy(state, crtc->state, sizeof(*state)); |
2525 | memcpy(state, crtc->state, sizeof(*state)); |
Line 2471... | Line 2526... | ||
2471 | 2526 | ||
2472 | if (state->mode_blob) |
2527 | if (state->mode_blob) |
- | 2528 | drm_property_reference_blob(state->mode_blob); |
|
- | 2529 | if (state->degamma_lut) |
|
- | 2530 | drm_property_reference_blob(state->degamma_lut); |
|
- | 2531 | if (state->ctm) |
|
- | 2532 | drm_property_reference_blob(state->ctm); |
|
- | 2533 | if (state->gamma_lut) |
|
2473 | drm_property_reference_blob(state->mode_blob); |
2534 | drm_property_reference_blob(state->gamma_lut); |
2474 | state->mode_changed = false; |
2535 | state->mode_changed = false; |
2475 | state->active_changed = false; |
2536 | state->active_changed = false; |
2476 | state->planes_changed = false; |
2537 | state->planes_changed = false; |
- | 2538 | state->connectors_changed = false; |
|
2477 | state->connectors_changed = false; |
2539 | state->color_mgmt_changed = false; |
2478 | state->event = NULL; |
2540 | state->event = NULL; |
2479 | } |
2541 | } |
Line 2480... | Line 2542... | ||
2480 | EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state); |
2542 | EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state); |
Line 2513... | Line 2575... | ||
2513 | */ |
2575 | */ |
2514 | void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, |
2576 | void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, |
2515 | struct drm_crtc_state *state) |
2577 | struct drm_crtc_state *state) |
2516 | { |
2578 | { |
2517 | drm_property_unreference_blob(state->mode_blob); |
2579 | drm_property_unreference_blob(state->mode_blob); |
- | 2580 | drm_property_unreference_blob(state->degamma_lut); |
|
- | 2581 | drm_property_unreference_blob(state->ctm); |
|
- | 2582 | drm_property_unreference_blob(state->gamma_lut); |
|
2518 | } |
2583 | } |
2519 | EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state); |
2584 | EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state); |
Line 2520... | Line 2585... | ||
2520 | 2585 | ||
2521 | /** |
2586 | /** |
Line 2547... | Line 2612... | ||
2547 | drm_framebuffer_unreference(plane->state->fb); |
2612 | drm_framebuffer_unreference(plane->state->fb); |
Line 2548... | Line 2613... | ||
2548 | 2613 | ||
2549 | kfree(plane->state); |
2614 | kfree(plane->state); |
Line 2550... | Line 2615... | ||
2550 | plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL); |
2615 | plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL); |
2551 | 2616 | ||
- | 2617 | if (plane->state) { |
|
- | 2618 | plane->state->plane = plane; |
|
2552 | if (plane->state) |
2619 | plane->state->rotation = BIT(DRM_ROTATE_0); |
2553 | plane->state->plane = plane; |
2620 | } |
Line 2554... | Line 2621... | ||
2554 | } |
2621 | } |
2555 | EXPORT_SYMBOL(drm_atomic_helper_plane_reset); |
2622 | EXPORT_SYMBOL(drm_atomic_helper_plane_reset); |
Line 2824... | Line 2891... | ||
2824 | { |
2891 | { |
2825 | __drm_atomic_helper_connector_destroy_state(connector, state); |
2892 | __drm_atomic_helper_connector_destroy_state(connector, state); |
2826 | kfree(state); |
2893 | kfree(state); |
2827 | } |
2894 | } |
2828 | EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);>>>>><>><>><>><>><>><>>>>>>>> |
2895 | EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state); |
- | 2896 | ||
- | 2897 | /** |
|
- | 2898 | * drm_atomic_helper_legacy_gamma_set - set the legacy gamma correction table |
|
- | 2899 | * @crtc: CRTC object |
|
- | 2900 | * @red: red correction table |
|
- | 2901 | * @green: green correction table |
|
- | 2902 | * @blue: green correction table |
|
- | 2903 | * @start: |
|
- | 2904 | * @size: size of the tables |
|
- | 2905 | * |
|
- | 2906 | * Implements support for legacy gamma correction table for drivers |
|
- | 2907 | * that support color management through the DEGAMMA_LUT/GAMMA_LUT |
|
- | 2908 | * properties. |
|
- | 2909 | */ |
|
- | 2910 | void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, |
|
- | 2911 | u16 *red, u16 *green, u16 *blue, |
|
- | 2912 | uint32_t start, uint32_t size) |
|
- | 2913 | { |
|
- | 2914 | struct drm_device *dev = crtc->dev; |
|
- | 2915 | struct drm_mode_config *config = &dev->mode_config; |
|
- | 2916 | struct drm_atomic_state *state; |
|
- | 2917 | struct drm_crtc_state *crtc_state; |
|
- | 2918 | struct drm_property_blob *blob = NULL; |
|
- | 2919 | struct drm_color_lut *blob_data; |
|
- | 2920 | int i, ret = 0; |
|
- | 2921 | ||
- | 2922 | state = drm_atomic_state_alloc(crtc->dev); |
|
- | 2923 | if (!state) |
|
- | 2924 | return; |
|
- | 2925 | ||
- | 2926 | blob = drm_property_create_blob(dev, |
|
- | 2927 | sizeof(struct drm_color_lut) * size, |
|
- | 2928 | NULL); |
|
- | 2929 | if (IS_ERR(blob)) { |
|
- | 2930 | ret = PTR_ERR(blob); |
|
- | 2931 | blob = NULL; |
|
- | 2932 | goto fail; |
|
- | 2933 | } |
|
- | 2934 | ||
- | 2935 | /* Prepare GAMMA_LUT with the legacy values. */ |
|
- | 2936 | blob_data = (struct drm_color_lut *) blob->data; |
|
- | 2937 | for (i = 0; i < size; i++) { |
|
- | 2938 | blob_data[i].red = red[i]; |
|
- | 2939 | blob_data[i].green = green[i]; |
|
- | 2940 | blob_data[i].blue = blue[i]; |
|
- | 2941 | } |
|
- | 2942 | ||
- | 2943 | state->acquire_ctx = crtc->dev->mode_config.acquire_ctx; |
|
- | 2944 | retry: |
|
- | 2945 | crtc_state = drm_atomic_get_crtc_state(state, crtc); |
|
- | 2946 | if (IS_ERR(crtc_state)) { |
|
- | 2947 | ret = PTR_ERR(crtc_state); |
|
- | 2948 | goto fail; |
|
- | 2949 | } |
|
- | 2950 | ||
- | 2951 | /* Reset DEGAMMA_LUT and CTM properties. */ |
|
- | 2952 | ret = drm_atomic_crtc_set_property(crtc, crtc_state, |
|
- | 2953 | config->degamma_lut_property, 0); |
|
- | 2954 | if (ret) |
|
- | 2955 | goto fail; |
|
- | 2956 | ||
- | 2957 | ret = drm_atomic_crtc_set_property(crtc, crtc_state, |
|
- | 2958 | config->ctm_property, 0); |
|
- | 2959 | if (ret) |
|
- | 2960 | goto fail; |
|
- | 2961 | ||
- | 2962 | ret = drm_atomic_crtc_set_property(crtc, crtc_state, |
|
- | 2963 | config->gamma_lut_property, blob->base.id); |
|
- | 2964 | if (ret) |
|
- | 2965 | goto fail; |
|
- | 2966 | ||
- | 2967 | ret = drm_atomic_commit(state); |
|
- | 2968 | if (ret) |
|
- | 2969 | goto fail; |
|
- | 2970 | ||
- | 2971 | /* Driver takes ownership of state on successful commit. */ |
|
- | 2972 | ||
- | 2973 | drm_property_unreference_blob(blob); |
|
- | 2974 | ||
- | 2975 | return; |
|
- | 2976 | fail: |
|
- | 2977 | if (ret == -EDEADLK) |
|
- | 2978 | goto backoff; |
|
- | 2979 | ||
- | 2980 | drm_atomic_state_free(state); |
|
- | 2981 | drm_property_unreference_blob(blob); |
|
- | 2982 | ||
- | 2983 | return; |
|
- | 2984 | backoff: |
|
- | 2985 | drm_atomic_state_clear(state); |
|
- | 2986 | drm_atomic_legacy_backoff(state); |
|
- | 2987 | ||
- | 2988 | goto retry; |
|
- | 2989 | } |
|
- | 2990 | EXPORT_SYMBOL(drm_atomic_helper_legacy_gamma_set);>>>>>><>><>><>><>><>><>>>>>>>><>><>>><>><>><> |