This source file includes following definitions.
- __drm_crtc_commit_free
- drm_atomic_state_default_release
- drm_atomic_state_init
- drm_atomic_state_alloc
- drm_atomic_state_default_clear
- drm_atomic_state_clear
- __drm_atomic_state_free
- drm_atomic_get_crtc_state
- drm_atomic_crtc_check
- drm_atomic_crtc_print_state
- drm_atomic_connector_check
- drm_atomic_get_plane_state
- plane_switching_crtc
- drm_atomic_plane_check
- drm_atomic_plane_print_state
- drm_atomic_private_obj_init
- drm_atomic_private_obj_fini
- drm_atomic_get_private_obj_state
- drm_atomic_get_old_private_obj_state
- drm_atomic_get_new_private_obj_state
- drm_atomic_get_old_connector_for_encoder
- drm_atomic_get_new_connector_for_encoder
- drm_atomic_get_connector_state
- drm_atomic_connector_print_state
- drm_atomic_add_affected_connectors
- drm_atomic_add_affected_planes
- drm_atomic_check_only
- drm_atomic_commit
- drm_atomic_nonblocking_commit
- __drm_atomic_helper_disable_plane
- update_output_state
- __drm_atomic_helper_set_config
- drm_atomic_print_state
- __drm_state_dump
- drm_state_dump
- drm_state_info
- drm_atomic_debugfs_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <linux/sync_file.h>
30
31 #include <drm/drm_atomic.h>
32 #include <drm/drm_atomic_uapi.h>
33 #include <drm/drm_debugfs.h>
34 #include <drm/drm_device.h>
35 #include <drm/drm_drv.h>
36 #include <drm/drm_file.h>
37 #include <drm/drm_fourcc.h>
38 #include <drm/drm_mode.h>
39 #include <drm/drm_print.h>
40 #include <drm/drm_writeback.h>
41
42 #include "drm_crtc_internal.h"
43 #include "drm_internal.h"
44
45 void __drm_crtc_commit_free(struct kref *kref)
46 {
47 struct drm_crtc_commit *commit =
48 container_of(kref, struct drm_crtc_commit, ref);
49
50 kfree(commit);
51 }
52 EXPORT_SYMBOL(__drm_crtc_commit_free);
53
54
55
56
57
58
59
60
61
62
63 void drm_atomic_state_default_release(struct drm_atomic_state *state)
64 {
65 kfree(state->connectors);
66 kfree(state->crtcs);
67 kfree(state->planes);
68 kfree(state->private_objs);
69 }
70 EXPORT_SYMBOL(drm_atomic_state_default_release);
71
72
73
74
75
76
77
78
79
80
81 int
82 drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
83 {
84 kref_init(&state->ref);
85
86
87
88
89 state->allow_modeset = true;
90
91 state->crtcs = kcalloc(dev->mode_config.num_crtc,
92 sizeof(*state->crtcs), GFP_KERNEL);
93 if (!state->crtcs)
94 goto fail;
95 state->planes = kcalloc(dev->mode_config.num_total_plane,
96 sizeof(*state->planes), GFP_KERNEL);
97 if (!state->planes)
98 goto fail;
99
100 state->dev = dev;
101
102 DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
103
104 return 0;
105 fail:
106 drm_atomic_state_default_release(state);
107 return -ENOMEM;
108 }
109 EXPORT_SYMBOL(drm_atomic_state_init);
110
111
112
113
114
115
116
117 struct drm_atomic_state *
118 drm_atomic_state_alloc(struct drm_device *dev)
119 {
120 struct drm_mode_config *config = &dev->mode_config;
121
122 if (!config->funcs->atomic_state_alloc) {
123 struct drm_atomic_state *state;
124
125 state = kzalloc(sizeof(*state), GFP_KERNEL);
126 if (!state)
127 return NULL;
128 if (drm_atomic_state_init(dev, state) < 0) {
129 kfree(state);
130 return NULL;
131 }
132 return state;
133 }
134
135 return config->funcs->atomic_state_alloc(dev);
136 }
137 EXPORT_SYMBOL(drm_atomic_state_alloc);
138
139
140
141
142
143
144
145
146
147 void drm_atomic_state_default_clear(struct drm_atomic_state *state)
148 {
149 struct drm_device *dev = state->dev;
150 struct drm_mode_config *config = &dev->mode_config;
151 int i;
152
153 DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
154
155 for (i = 0; i < state->num_connector; i++) {
156 struct drm_connector *connector = state->connectors[i].ptr;
157
158 if (!connector)
159 continue;
160
161 connector->funcs->atomic_destroy_state(connector,
162 state->connectors[i].state);
163 state->connectors[i].ptr = NULL;
164 state->connectors[i].state = NULL;
165 state->connectors[i].old_state = NULL;
166 state->connectors[i].new_state = NULL;
167 drm_connector_put(connector);
168 }
169
170 for (i = 0; i < config->num_crtc; i++) {
171 struct drm_crtc *crtc = state->crtcs[i].ptr;
172
173 if (!crtc)
174 continue;
175
176 crtc->funcs->atomic_destroy_state(crtc,
177 state->crtcs[i].state);
178
179 state->crtcs[i].ptr = NULL;
180 state->crtcs[i].state = NULL;
181 state->crtcs[i].old_state = NULL;
182 state->crtcs[i].new_state = NULL;
183
184 if (state->crtcs[i].commit) {
185 drm_crtc_commit_put(state->crtcs[i].commit);
186 state->crtcs[i].commit = NULL;
187 }
188 }
189
190 for (i = 0; i < config->num_total_plane; i++) {
191 struct drm_plane *plane = state->planes[i].ptr;
192
193 if (!plane)
194 continue;
195
196 plane->funcs->atomic_destroy_state(plane,
197 state->planes[i].state);
198 state->planes[i].ptr = NULL;
199 state->planes[i].state = NULL;
200 state->planes[i].old_state = NULL;
201 state->planes[i].new_state = NULL;
202 }
203
204 for (i = 0; i < state->num_private_objs; i++) {
205 struct drm_private_obj *obj = state->private_objs[i].ptr;
206
207 obj->funcs->atomic_destroy_state(obj,
208 state->private_objs[i].state);
209 state->private_objs[i].ptr = NULL;
210 state->private_objs[i].state = NULL;
211 state->private_objs[i].old_state = NULL;
212 state->private_objs[i].new_state = NULL;
213 }
214 state->num_private_objs = 0;
215
216 if (state->fake_commit) {
217 drm_crtc_commit_put(state->fake_commit);
218 state->fake_commit = NULL;
219 }
220 }
221 EXPORT_SYMBOL(drm_atomic_state_default_clear);
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237 void drm_atomic_state_clear(struct drm_atomic_state *state)
238 {
239 struct drm_device *dev = state->dev;
240 struct drm_mode_config *config = &dev->mode_config;
241
242 if (config->funcs->atomic_state_clear)
243 config->funcs->atomic_state_clear(state);
244 else
245 drm_atomic_state_default_clear(state);
246 }
247 EXPORT_SYMBOL(drm_atomic_state_clear);
248
249
250
251
252
253
254
255
256 void __drm_atomic_state_free(struct kref *ref)
257 {
258 struct drm_atomic_state *state = container_of(ref, typeof(*state), ref);
259 struct drm_mode_config *config = &state->dev->mode_config;
260
261 drm_atomic_state_clear(state);
262
263 DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state);
264
265 if (config->funcs->atomic_state_free) {
266 config->funcs->atomic_state_free(state);
267 } else {
268 drm_atomic_state_default_release(state);
269 kfree(state);
270 }
271 }
272 EXPORT_SYMBOL(__drm_atomic_state_free);
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289 struct drm_crtc_state *
290 drm_atomic_get_crtc_state(struct drm_atomic_state *state,
291 struct drm_crtc *crtc)
292 {
293 int ret, index = drm_crtc_index(crtc);
294 struct drm_crtc_state *crtc_state;
295
296 WARN_ON(!state->acquire_ctx);
297
298 crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
299 if (crtc_state)
300 return crtc_state;
301
302 ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
303 if (ret)
304 return ERR_PTR(ret);
305
306 crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
307 if (!crtc_state)
308 return ERR_PTR(-ENOMEM);
309
310 state->crtcs[index].state = crtc_state;
311 state->crtcs[index].old_state = crtc->state;
312 state->crtcs[index].new_state = crtc_state;
313 state->crtcs[index].ptr = crtc;
314 crtc_state->state = state;
315
316 DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
317 crtc->base.id, crtc->name, crtc_state, state);
318
319 return crtc_state;
320 }
321 EXPORT_SYMBOL(drm_atomic_get_crtc_state);
322
323 static int drm_atomic_crtc_check(const struct drm_crtc_state *old_crtc_state,
324 const struct drm_crtc_state *new_crtc_state)
325 {
326 struct drm_crtc *crtc = new_crtc_state->crtc;
327
328
329
330
331
332
333
334
335
336 if (new_crtc_state->active && !new_crtc_state->enable) {
337 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active without enabled\n",
338 crtc->base.id, crtc->name);
339 return -EINVAL;
340 }
341
342
343
344
345 if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
346 WARN_ON(new_crtc_state->enable && !new_crtc_state->mode_blob)) {
347 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled without mode blob\n",
348 crtc->base.id, crtc->name);
349 return -EINVAL;
350 }
351
352 if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
353 WARN_ON(!new_crtc_state->enable && new_crtc_state->mode_blob)) {
354 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] disabled with mode blob\n",
355 crtc->base.id, crtc->name);
356 return -EINVAL;
357 }
358
359
360
361
362
363
364
365
366
367
368
369 if (new_crtc_state->event &&
370 !new_crtc_state->active && !old_crtc_state->active) {
371 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requesting event but off\n",
372 crtc->base.id, crtc->name);
373 return -EINVAL;
374 }
375
376 return 0;
377 }
378
379 static void drm_atomic_crtc_print_state(struct drm_printer *p,
380 const struct drm_crtc_state *state)
381 {
382 struct drm_crtc *crtc = state->crtc;
383
384 drm_printf(p, "crtc[%u]: %s\n", crtc->base.id, crtc->name);
385 drm_printf(p, "\tenable=%d\n", state->enable);
386 drm_printf(p, "\tactive=%d\n", state->active);
387 drm_printf(p, "\tself_refresh_active=%d\n", state->self_refresh_active);
388 drm_printf(p, "\tplanes_changed=%d\n", state->planes_changed);
389 drm_printf(p, "\tmode_changed=%d\n", state->mode_changed);
390 drm_printf(p, "\tactive_changed=%d\n", state->active_changed);
391 drm_printf(p, "\tconnectors_changed=%d\n", state->connectors_changed);
392 drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
393 drm_printf(p, "\tplane_mask=%x\n", state->plane_mask);
394 drm_printf(p, "\tconnector_mask=%x\n", state->connector_mask);
395 drm_printf(p, "\tencoder_mask=%x\n", state->encoder_mask);
396 drm_printf(p, "\tmode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&state->mode));
397
398 if (crtc->funcs->atomic_print_state)
399 crtc->funcs->atomic_print_state(p, state);
400 }
401
402 static int drm_atomic_connector_check(struct drm_connector *connector,
403 struct drm_connector_state *state)
404 {
405 struct drm_crtc_state *crtc_state;
406 struct drm_writeback_job *writeback_job = state->writeback_job;
407 const struct drm_display_info *info = &connector->display_info;
408
409 state->max_bpc = info->bpc ? info->bpc : 8;
410 if (connector->max_bpc_property)
411 state->max_bpc = min(state->max_bpc, state->max_requested_bpc);
412
413 if ((connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) || !writeback_job)
414 return 0;
415
416 if (writeback_job->fb && !state->crtc) {
417 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] framebuffer without CRTC\n",
418 connector->base.id, connector->name);
419 return -EINVAL;
420 }
421
422 if (state->crtc)
423 crtc_state = drm_atomic_get_existing_crtc_state(state->state,
424 state->crtc);
425
426 if (writeback_job->fb && !crtc_state->active) {
427 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] has framebuffer, but [CRTC:%d] is off\n",
428 connector->base.id, connector->name,
429 state->crtc->base.id);
430 return -EINVAL;
431 }
432
433 if (!writeback_job->fb) {
434 if (writeback_job->out_fence) {
435 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] requesting out-fence without framebuffer\n",
436 connector->base.id, connector->name);
437 return -EINVAL;
438 }
439
440 drm_writeback_cleanup_job(writeback_job);
441 state->writeback_job = NULL;
442 }
443
444 return 0;
445 }
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462 struct drm_plane_state *
463 drm_atomic_get_plane_state(struct drm_atomic_state *state,
464 struct drm_plane *plane)
465 {
466 int ret, index = drm_plane_index(plane);
467 struct drm_plane_state *plane_state;
468
469 WARN_ON(!state->acquire_ctx);
470
471
472 WARN_ON(plane->fb);
473 WARN_ON(plane->old_fb);
474 WARN_ON(plane->crtc);
475
476 plane_state = drm_atomic_get_existing_plane_state(state, plane);
477 if (plane_state)
478 return plane_state;
479
480 ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx);
481 if (ret)
482 return ERR_PTR(ret);
483
484 plane_state = plane->funcs->atomic_duplicate_state(plane);
485 if (!plane_state)
486 return ERR_PTR(-ENOMEM);
487
488 state->planes[index].state = plane_state;
489 state->planes[index].ptr = plane;
490 state->planes[index].old_state = plane->state;
491 state->planes[index].new_state = plane_state;
492 plane_state->state = state;
493
494 DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n",
495 plane->base.id, plane->name, plane_state, state);
496
497 if (plane_state->crtc) {
498 struct drm_crtc_state *crtc_state;
499
500 crtc_state = drm_atomic_get_crtc_state(state,
501 plane_state->crtc);
502 if (IS_ERR(crtc_state))
503 return ERR_CAST(crtc_state);
504 }
505
506 return plane_state;
507 }
508 EXPORT_SYMBOL(drm_atomic_get_plane_state);
509
510 static bool
511 plane_switching_crtc(const struct drm_plane_state *old_plane_state,
512 const struct drm_plane_state *new_plane_state)
513 {
514 if (!old_plane_state->crtc || !new_plane_state->crtc)
515 return false;
516
517 if (old_plane_state->crtc == new_plane_state->crtc)
518 return false;
519
520
521
522
523
524
525 return true;
526 }
527
528
529
530
531
532
533
534
535
536
537
538 static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
539 const struct drm_plane_state *new_plane_state)
540 {
541 struct drm_plane *plane = new_plane_state->plane;
542 struct drm_crtc *crtc = new_plane_state->crtc;
543 const struct drm_framebuffer *fb = new_plane_state->fb;
544 unsigned int fb_width, fb_height;
545 struct drm_mode_rect *clips;
546 uint32_t num_clips;
547 int ret;
548
549
550 if (crtc && !fb) {
551 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] CRTC set but no FB\n",
552 plane->base.id, plane->name);
553 return -EINVAL;
554 } else if (fb && !crtc) {
555 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] FB set but no CRTC\n",
556 plane->base.id, plane->name);
557 return -EINVAL;
558 }
559
560
561 if (!crtc)
562 return 0;
563
564
565 if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
566 DRM_DEBUG_ATOMIC("Invalid [CRTC:%d:%s] for [PLANE:%d:%s]\n",
567 crtc->base.id, crtc->name,
568 plane->base.id, plane->name);
569 return -EINVAL;
570 }
571
572
573 ret = drm_plane_check_pixel_format(plane, fb->format->format,
574 fb->modifier);
575 if (ret) {
576 struct drm_format_name_buf format_name;
577 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid pixel format %s, modifier 0x%llx\n",
578 plane->base.id, plane->name,
579 drm_get_format_name(fb->format->format,
580 &format_name),
581 fb->modifier);
582 return ret;
583 }
584
585
586 if (new_plane_state->crtc_w > INT_MAX ||
587 new_plane_state->crtc_x > INT_MAX - (int32_t) new_plane_state->crtc_w ||
588 new_plane_state->crtc_h > INT_MAX ||
589 new_plane_state->crtc_y > INT_MAX - (int32_t) new_plane_state->crtc_h) {
590 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid CRTC coordinates %ux%u+%d+%d\n",
591 plane->base.id, plane->name,
592 new_plane_state->crtc_w, new_plane_state->crtc_h,
593 new_plane_state->crtc_x, new_plane_state->crtc_y);
594 return -ERANGE;
595 }
596
597 fb_width = fb->width << 16;
598 fb_height = fb->height << 16;
599
600
601 if (new_plane_state->src_w > fb_width ||
602 new_plane_state->src_x > fb_width - new_plane_state->src_w ||
603 new_plane_state->src_h > fb_height ||
604 new_plane_state->src_y > fb_height - new_plane_state->src_h) {
605 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid source coordinates "
606 "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
607 plane->base.id, plane->name,
608 new_plane_state->src_w >> 16,
609 ((new_plane_state->src_w & 0xffff) * 15625) >> 10,
610 new_plane_state->src_h >> 16,
611 ((new_plane_state->src_h & 0xffff) * 15625) >> 10,
612 new_plane_state->src_x >> 16,
613 ((new_plane_state->src_x & 0xffff) * 15625) >> 10,
614 new_plane_state->src_y >> 16,
615 ((new_plane_state->src_y & 0xffff) * 15625) >> 10,
616 fb->width, fb->height);
617 return -ENOSPC;
618 }
619
620 clips = drm_plane_get_damage_clips(new_plane_state);
621 num_clips = drm_plane_get_damage_clips_count(new_plane_state);
622
623
624 while (num_clips > 0) {
625 if (clips->x1 >= clips->x2 ||
626 clips->y1 >= clips->y2 ||
627 clips->x1 < 0 ||
628 clips->y1 < 0 ||
629 clips->x2 > fb_width ||
630 clips->y2 > fb_height) {
631 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
632 plane->base.id, plane->name, clips->x1,
633 clips->y1, clips->x2, clips->y2);
634 return -EINVAL;
635 }
636 clips++;
637 num_clips--;
638 }
639
640 if (plane_switching_crtc(old_plane_state, new_plane_state)) {
641 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] switching CRTC directly\n",
642 plane->base.id, plane->name);
643 return -EINVAL;
644 }
645
646 return 0;
647 }
648
649 static void drm_atomic_plane_print_state(struct drm_printer *p,
650 const struct drm_plane_state *state)
651 {
652 struct drm_plane *plane = state->plane;
653 struct drm_rect src = drm_plane_state_src(state);
654 struct drm_rect dest = drm_plane_state_dest(state);
655
656 drm_printf(p, "plane[%u]: %s\n", plane->base.id, plane->name);
657 drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
658 drm_printf(p, "\tfb=%u\n", state->fb ? state->fb->base.id : 0);
659 if (state->fb)
660 drm_framebuffer_print_info(p, 2, state->fb);
661 drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest));
662 drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src));
663 drm_printf(p, "\trotation=%x\n", state->rotation);
664 drm_printf(p, "\tnormalized-zpos=%x\n", state->normalized_zpos);
665 drm_printf(p, "\tcolor-encoding=%s\n",
666 drm_get_color_encoding_name(state->color_encoding));
667 drm_printf(p, "\tcolor-range=%s\n",
668 drm_get_color_range_name(state->color_range));
669
670 if (plane->funcs->atomic_print_state)
671 plane->funcs->atomic_print_state(p, state);
672 }
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721 void
722 drm_atomic_private_obj_init(struct drm_device *dev,
723 struct drm_private_obj *obj,
724 struct drm_private_state *state,
725 const struct drm_private_state_funcs *funcs)
726 {
727 memset(obj, 0, sizeof(*obj));
728
729 drm_modeset_lock_init(&obj->lock);
730
731 obj->state = state;
732 obj->funcs = funcs;
733 list_add_tail(&obj->head, &dev->mode_config.privobj_list);
734 }
735 EXPORT_SYMBOL(drm_atomic_private_obj_init);
736
737
738
739
740
741
742
743 void
744 drm_atomic_private_obj_fini(struct drm_private_obj *obj)
745 {
746 list_del(&obj->head);
747 obj->funcs->atomic_destroy_state(obj, obj->state);
748 drm_modeset_lock_fini(&obj->lock);
749 }
750 EXPORT_SYMBOL(drm_atomic_private_obj_fini);
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765 struct drm_private_state *
766 drm_atomic_get_private_obj_state(struct drm_atomic_state *state,
767 struct drm_private_obj *obj)
768 {
769 int index, num_objs, i, ret;
770 size_t size;
771 struct __drm_private_objs_state *arr;
772 struct drm_private_state *obj_state;
773
774 for (i = 0; i < state->num_private_objs; i++)
775 if (obj == state->private_objs[i].ptr)
776 return state->private_objs[i].state;
777
778 ret = drm_modeset_lock(&obj->lock, state->acquire_ctx);
779 if (ret)
780 return ERR_PTR(ret);
781
782 num_objs = state->num_private_objs + 1;
783 size = sizeof(*state->private_objs) * num_objs;
784 arr = krealloc(state->private_objs, size, GFP_KERNEL);
785 if (!arr)
786 return ERR_PTR(-ENOMEM);
787
788 state->private_objs = arr;
789 index = state->num_private_objs;
790 memset(&state->private_objs[index], 0, sizeof(*state->private_objs));
791
792 obj_state = obj->funcs->atomic_duplicate_state(obj);
793 if (!obj_state)
794 return ERR_PTR(-ENOMEM);
795
796 state->private_objs[index].state = obj_state;
797 state->private_objs[index].old_state = obj->state;
798 state->private_objs[index].new_state = obj_state;
799 state->private_objs[index].ptr = obj;
800 obj_state->state = state;
801
802 state->num_private_objs = num_objs;
803
804 DRM_DEBUG_ATOMIC("Added new private object %p state %p to %p\n",
805 obj, obj_state, state);
806
807 return obj_state;
808 }
809 EXPORT_SYMBOL(drm_atomic_get_private_obj_state);
810
811
812
813
814
815
816
817
818
819 struct drm_private_state *
820 drm_atomic_get_old_private_obj_state(struct drm_atomic_state *state,
821 struct drm_private_obj *obj)
822 {
823 int i;
824
825 for (i = 0; i < state->num_private_objs; i++)
826 if (obj == state->private_objs[i].ptr)
827 return state->private_objs[i].old_state;
828
829 return NULL;
830 }
831 EXPORT_SYMBOL(drm_atomic_get_old_private_obj_state);
832
833
834
835
836
837
838
839
840
841 struct drm_private_state *
842 drm_atomic_get_new_private_obj_state(struct drm_atomic_state *state,
843 struct drm_private_obj *obj)
844 {
845 int i;
846
847 for (i = 0; i < state->num_private_objs; i++)
848 if (obj == state->private_objs[i].ptr)
849 return state->private_objs[i].new_state;
850
851 return NULL;
852 }
853 EXPORT_SYMBOL(drm_atomic_get_new_private_obj_state);
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873 struct drm_connector *
874 drm_atomic_get_old_connector_for_encoder(struct drm_atomic_state *state,
875 struct drm_encoder *encoder)
876 {
877 struct drm_connector_state *conn_state;
878 struct drm_connector *connector;
879 unsigned int i;
880
881 for_each_old_connector_in_state(state, connector, conn_state, i) {
882 if (conn_state->best_encoder == encoder)
883 return connector;
884 }
885
886 return NULL;
887 }
888 EXPORT_SYMBOL(drm_atomic_get_old_connector_for_encoder);
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907 struct drm_connector *
908 drm_atomic_get_new_connector_for_encoder(struct drm_atomic_state *state,
909 struct drm_encoder *encoder)
910 {
911 struct drm_connector_state *conn_state;
912 struct drm_connector *connector;
913 unsigned int i;
914
915 for_each_new_connector_in_state(state, connector, conn_state, i) {
916 if (conn_state->best_encoder == encoder)
917 return connector;
918 }
919
920 return NULL;
921 }
922 EXPORT_SYMBOL(drm_atomic_get_new_connector_for_encoder);
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939 struct drm_connector_state *
940 drm_atomic_get_connector_state(struct drm_atomic_state *state,
941 struct drm_connector *connector)
942 {
943 int ret, index;
944 struct drm_mode_config *config = &connector->dev->mode_config;
945 struct drm_connector_state *connector_state;
946
947 WARN_ON(!state->acquire_ctx);
948
949 ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
950 if (ret)
951 return ERR_PTR(ret);
952
953 index = drm_connector_index(connector);
954
955 if (index >= state->num_connector) {
956 struct __drm_connnectors_state *c;
957 int alloc = max(index + 1, config->num_connector);
958
959 c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL);
960 if (!c)
961 return ERR_PTR(-ENOMEM);
962
963 state->connectors = c;
964 memset(&state->connectors[state->num_connector], 0,
965 sizeof(*state->connectors) * (alloc - state->num_connector));
966
967 state->num_connector = alloc;
968 }
969
970 if (state->connectors[index].state)
971 return state->connectors[index].state;
972
973 connector_state = connector->funcs->atomic_duplicate_state(connector);
974 if (!connector_state)
975 return ERR_PTR(-ENOMEM);
976
977 drm_connector_get(connector);
978 state->connectors[index].state = connector_state;
979 state->connectors[index].old_state = connector->state;
980 state->connectors[index].new_state = connector_state;
981 state->connectors[index].ptr = connector;
982 connector_state->state = state;
983
984 DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d:%s] %p state to %p\n",
985 connector->base.id, connector->name,
986 connector_state, state);
987
988 if (connector_state->crtc) {
989 struct drm_crtc_state *crtc_state;
990
991 crtc_state = drm_atomic_get_crtc_state(state,
992 connector_state->crtc);
993 if (IS_ERR(crtc_state))
994 return ERR_CAST(crtc_state);
995 }
996
997 return connector_state;
998 }
999 EXPORT_SYMBOL(drm_atomic_get_connector_state);
1000
1001 static void drm_atomic_connector_print_state(struct drm_printer *p,
1002 const struct drm_connector_state *state)
1003 {
1004 struct drm_connector *connector = state->connector;
1005
1006 drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name);
1007 drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
1008 drm_printf(p, "\tself_refresh_aware=%d\n", state->self_refresh_aware);
1009
1010 if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
1011 if (state->writeback_job && state->writeback_job->fb)
1012 drm_printf(p, "\tfb=%d\n", state->writeback_job->fb->base.id);
1013
1014 if (connector->funcs->atomic_print_state)
1015 connector->funcs->atomic_print_state(p, state);
1016 }
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035 int
1036 drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
1037 struct drm_crtc *crtc)
1038 {
1039 struct drm_mode_config *config = &state->dev->mode_config;
1040 struct drm_connector *connector;
1041 struct drm_connector_state *conn_state;
1042 struct drm_connector_list_iter conn_iter;
1043 struct drm_crtc_state *crtc_state;
1044 int ret;
1045
1046 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1047 if (IS_ERR(crtc_state))
1048 return PTR_ERR(crtc_state);
1049
1050 ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
1051 if (ret)
1052 return ret;
1053
1054 DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d:%s] to %p\n",
1055 crtc->base.id, crtc->name, state);
1056
1057
1058
1059
1060
1061 drm_connector_list_iter_begin(state->dev, &conn_iter);
1062 drm_for_each_connector_iter(connector, &conn_iter) {
1063 if (!(crtc_state->connector_mask & drm_connector_mask(connector)))
1064 continue;
1065
1066 conn_state = drm_atomic_get_connector_state(state, connector);
1067 if (IS_ERR(conn_state)) {
1068 drm_connector_list_iter_end(&conn_iter);
1069 return PTR_ERR(conn_state);
1070 }
1071 }
1072 drm_connector_list_iter_end(&conn_iter);
1073
1074 return 0;
1075 }
1076 EXPORT_SYMBOL(drm_atomic_add_affected_connectors);
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098 int
1099 drm_atomic_add_affected_planes(struct drm_atomic_state *state,
1100 struct drm_crtc *crtc)
1101 {
1102 const struct drm_crtc_state *old_crtc_state =
1103 drm_atomic_get_old_crtc_state(state, crtc);
1104 struct drm_plane *plane;
1105
1106 WARN_ON(!drm_atomic_get_new_crtc_state(state, crtc));
1107
1108 DRM_DEBUG_ATOMIC("Adding all current planes for [CRTC:%d:%s] to %p\n",
1109 crtc->base.id, crtc->name, state);
1110
1111 drm_for_each_plane_mask(plane, state->dev, old_crtc_state->plane_mask) {
1112 struct drm_plane_state *plane_state =
1113 drm_atomic_get_plane_state(state, plane);
1114
1115 if (IS_ERR(plane_state))
1116 return PTR_ERR(plane_state);
1117 }
1118 return 0;
1119 }
1120 EXPORT_SYMBOL(drm_atomic_add_affected_planes);
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133 int drm_atomic_check_only(struct drm_atomic_state *state)
1134 {
1135 struct drm_device *dev = state->dev;
1136 struct drm_mode_config *config = &dev->mode_config;
1137 struct drm_plane *plane;
1138 struct drm_plane_state *old_plane_state;
1139 struct drm_plane_state *new_plane_state;
1140 struct drm_crtc *crtc;
1141 struct drm_crtc_state *old_crtc_state;
1142 struct drm_crtc_state *new_crtc_state;
1143 struct drm_connector *conn;
1144 struct drm_connector_state *conn_state;
1145 int i, ret = 0;
1146
1147 DRM_DEBUG_ATOMIC("checking %p\n", state);
1148
1149 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
1150 ret = drm_atomic_plane_check(old_plane_state, new_plane_state);
1151 if (ret) {
1152 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic core check failed\n",
1153 plane->base.id, plane->name);
1154 return ret;
1155 }
1156 }
1157
1158 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
1159 ret = drm_atomic_crtc_check(old_crtc_state, new_crtc_state);
1160 if (ret) {
1161 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic core check failed\n",
1162 crtc->base.id, crtc->name);
1163 return ret;
1164 }
1165 }
1166
1167 for_each_new_connector_in_state(state, conn, conn_state, i) {
1168 ret = drm_atomic_connector_check(conn, conn_state);
1169 if (ret) {
1170 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] atomic core check failed\n",
1171 conn->base.id, conn->name);
1172 return ret;
1173 }
1174 }
1175
1176 if (config->funcs->atomic_check) {
1177 ret = config->funcs->atomic_check(state->dev, state);
1178
1179 if (ret) {
1180 DRM_DEBUG_ATOMIC("atomic driver check for %p failed: %d\n",
1181 state, ret);
1182 return ret;
1183 }
1184 }
1185
1186 if (!state->allow_modeset) {
1187 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
1188 if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
1189 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requires full modeset\n",
1190 crtc->base.id, crtc->name);
1191 return -EINVAL;
1192 }
1193 }
1194 }
1195
1196 return 0;
1197 }
1198 EXPORT_SYMBOL(drm_atomic_check_only);
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214 int drm_atomic_commit(struct drm_atomic_state *state)
1215 {
1216 struct drm_mode_config *config = &state->dev->mode_config;
1217 int ret;
1218
1219 ret = drm_atomic_check_only(state);
1220 if (ret)
1221 return ret;
1222
1223 DRM_DEBUG_ATOMIC("committing %p\n", state);
1224
1225 return config->funcs->atomic_commit(state->dev, state, false);
1226 }
1227 EXPORT_SYMBOL(drm_atomic_commit);
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243 int drm_atomic_nonblocking_commit(struct drm_atomic_state *state)
1244 {
1245 struct drm_mode_config *config = &state->dev->mode_config;
1246 int ret;
1247
1248 ret = drm_atomic_check_only(state);
1249 if (ret)
1250 return ret;
1251
1252 DRM_DEBUG_ATOMIC("committing %p nonblocking\n", state);
1253
1254 return config->funcs->atomic_commit(state->dev, state, true);
1255 }
1256 EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
1257
1258
1259 int __drm_atomic_helper_disable_plane(struct drm_plane *plane,
1260 struct drm_plane_state *plane_state)
1261 {
1262 int ret;
1263
1264 ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
1265 if (ret != 0)
1266 return ret;
1267
1268 drm_atomic_set_fb_for_plane(plane_state, NULL);
1269 plane_state->crtc_x = 0;
1270 plane_state->crtc_y = 0;
1271 plane_state->crtc_w = 0;
1272 plane_state->crtc_h = 0;
1273 plane_state->src_x = 0;
1274 plane_state->src_y = 0;
1275 plane_state->src_w = 0;
1276 plane_state->src_h = 0;
1277
1278 return 0;
1279 }
1280 EXPORT_SYMBOL(__drm_atomic_helper_disable_plane);
1281
1282 static int update_output_state(struct drm_atomic_state *state,
1283 struct drm_mode_set *set)
1284 {
1285 struct drm_device *dev = set->crtc->dev;
1286 struct drm_crtc *crtc;
1287 struct drm_crtc_state *new_crtc_state;
1288 struct drm_connector *connector;
1289 struct drm_connector_state *new_conn_state;
1290 int ret, i;
1291
1292 ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
1293 state->acquire_ctx);
1294 if (ret)
1295 return ret;
1296
1297
1298 ret = drm_atomic_add_affected_connectors(state, set->crtc);
1299 if (ret)
1300 return ret;
1301
1302 for_each_new_connector_in_state(state, connector, new_conn_state, i) {
1303 if (new_conn_state->crtc == set->crtc) {
1304 ret = drm_atomic_set_crtc_for_connector(new_conn_state,
1305 NULL);
1306 if (ret)
1307 return ret;
1308
1309
1310 new_conn_state->link_status = DRM_LINK_STATUS_GOOD;
1311 }
1312 }
1313
1314
1315 for (i = 0; i < set->num_connectors; i++) {
1316 new_conn_state = drm_atomic_get_connector_state(state,
1317 set->connectors[i]);
1318 if (IS_ERR(new_conn_state))
1319 return PTR_ERR(new_conn_state);
1320
1321 ret = drm_atomic_set_crtc_for_connector(new_conn_state,
1322 set->crtc);
1323 if (ret)
1324 return ret;
1325 }
1326
1327 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
1328
1329
1330
1331
1332
1333
1334 if (crtc == set->crtc)
1335 continue;
1336
1337 if (!new_crtc_state->connector_mask) {
1338 ret = drm_atomic_set_mode_prop_for_crtc(new_crtc_state,
1339 NULL);
1340 if (ret < 0)
1341 return ret;
1342
1343 new_crtc_state->active = false;
1344 }
1345 }
1346
1347 return 0;
1348 }
1349
1350
1351 int __drm_atomic_helper_set_config(struct drm_mode_set *set,
1352 struct drm_atomic_state *state)
1353 {
1354 struct drm_crtc_state *crtc_state;
1355 struct drm_plane_state *primary_state;
1356 struct drm_crtc *crtc = set->crtc;
1357 int hdisplay, vdisplay;
1358 int ret;
1359
1360 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1361 if (IS_ERR(crtc_state))
1362 return PTR_ERR(crtc_state);
1363
1364 primary_state = drm_atomic_get_plane_state(state, crtc->primary);
1365 if (IS_ERR(primary_state))
1366 return PTR_ERR(primary_state);
1367
1368 if (!set->mode) {
1369 WARN_ON(set->fb);
1370 WARN_ON(set->num_connectors);
1371
1372 ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
1373 if (ret != 0)
1374 return ret;
1375
1376 crtc_state->active = false;
1377
1378 ret = drm_atomic_set_crtc_for_plane(primary_state, NULL);
1379 if (ret != 0)
1380 return ret;
1381
1382 drm_atomic_set_fb_for_plane(primary_state, NULL);
1383
1384 goto commit;
1385 }
1386
1387 WARN_ON(!set->fb);
1388 WARN_ON(!set->num_connectors);
1389
1390 ret = drm_atomic_set_mode_for_crtc(crtc_state, set->mode);
1391 if (ret != 0)
1392 return ret;
1393
1394 crtc_state->active = true;
1395
1396 ret = drm_atomic_set_crtc_for_plane(primary_state, crtc);
1397 if (ret != 0)
1398 return ret;
1399
1400 drm_mode_get_hv_timing(set->mode, &hdisplay, &vdisplay);
1401
1402 drm_atomic_set_fb_for_plane(primary_state, set->fb);
1403 primary_state->crtc_x = 0;
1404 primary_state->crtc_y = 0;
1405 primary_state->crtc_w = hdisplay;
1406 primary_state->crtc_h = vdisplay;
1407 primary_state->src_x = set->x << 16;
1408 primary_state->src_y = set->y << 16;
1409 if (drm_rotation_90_or_270(primary_state->rotation)) {
1410 primary_state->src_w = vdisplay << 16;
1411 primary_state->src_h = hdisplay << 16;
1412 } else {
1413 primary_state->src_w = hdisplay << 16;
1414 primary_state->src_h = vdisplay << 16;
1415 }
1416
1417 commit:
1418 ret = update_output_state(state, set);
1419 if (ret)
1420 return ret;
1421
1422 return 0;
1423 }
1424 EXPORT_SYMBOL(__drm_atomic_helper_set_config);
1425
1426 void drm_atomic_print_state(const struct drm_atomic_state *state)
1427 {
1428 struct drm_printer p = drm_info_printer(state->dev->dev);
1429 struct drm_plane *plane;
1430 struct drm_plane_state *plane_state;
1431 struct drm_crtc *crtc;
1432 struct drm_crtc_state *crtc_state;
1433 struct drm_connector *connector;
1434 struct drm_connector_state *connector_state;
1435 int i;
1436
1437 DRM_DEBUG_ATOMIC("checking %p\n", state);
1438
1439 for_each_new_plane_in_state(state, plane, plane_state, i)
1440 drm_atomic_plane_print_state(&p, plane_state);
1441
1442 for_each_new_crtc_in_state(state, crtc, crtc_state, i)
1443 drm_atomic_crtc_print_state(&p, crtc_state);
1444
1445 for_each_new_connector_in_state(state, connector, connector_state, i)
1446 drm_atomic_connector_print_state(&p, connector_state);
1447 }
1448
1449 static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p,
1450 bool take_locks)
1451 {
1452 struct drm_mode_config *config = &dev->mode_config;
1453 struct drm_plane *plane;
1454 struct drm_crtc *crtc;
1455 struct drm_connector *connector;
1456 struct drm_connector_list_iter conn_iter;
1457
1458 if (!drm_drv_uses_atomic_modeset(dev))
1459 return;
1460
1461 list_for_each_entry(plane, &config->plane_list, head) {
1462 if (take_locks)
1463 drm_modeset_lock(&plane->mutex, NULL);
1464 drm_atomic_plane_print_state(p, plane->state);
1465 if (take_locks)
1466 drm_modeset_unlock(&plane->mutex);
1467 }
1468
1469 list_for_each_entry(crtc, &config->crtc_list, head) {
1470 if (take_locks)
1471 drm_modeset_lock(&crtc->mutex, NULL);
1472 drm_atomic_crtc_print_state(p, crtc->state);
1473 if (take_locks)
1474 drm_modeset_unlock(&crtc->mutex);
1475 }
1476
1477 drm_connector_list_iter_begin(dev, &conn_iter);
1478 if (take_locks)
1479 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1480 drm_for_each_connector_iter(connector, &conn_iter)
1481 drm_atomic_connector_print_state(p, connector->state);
1482 if (take_locks)
1483 drm_modeset_unlock(&dev->mode_config.connection_mutex);
1484 drm_connector_list_iter_end(&conn_iter);
1485 }
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502 void drm_state_dump(struct drm_device *dev, struct drm_printer *p)
1503 {
1504 __drm_state_dump(dev, p, false);
1505 }
1506 EXPORT_SYMBOL(drm_state_dump);
1507
1508 #ifdef CONFIG_DEBUG_FS
1509 static int drm_state_info(struct seq_file *m, void *data)
1510 {
1511 struct drm_info_node *node = (struct drm_info_node *) m->private;
1512 struct drm_device *dev = node->minor->dev;
1513 struct drm_printer p = drm_seq_file_printer(m);
1514
1515 __drm_state_dump(dev, &p, true);
1516
1517 return 0;
1518 }
1519
1520
1521 static const struct drm_info_list drm_atomic_debugfs_list[] = {
1522 {"state", drm_state_info, 0},
1523 };
1524
1525 int drm_atomic_debugfs_init(struct drm_minor *minor)
1526 {
1527 return drm_debugfs_create_files(drm_atomic_debugfs_list,
1528 ARRAY_SIZE(drm_atomic_debugfs_list),
1529 minor->debugfs_root, minor);
1530 }
1531 #endif