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