0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #include <linux/sync_file.h>
0031
0032 #include <drm/drm_atomic.h>
0033 #include <drm/drm_atomic_uapi.h>
0034 #include <drm/drm_blend.h>
0035 #include <drm/drm_bridge.h>
0036 #include <drm/drm_debugfs.h>
0037 #include <drm/drm_device.h>
0038 #include <drm/drm_drv.h>
0039 #include <drm/drm_file.h>
0040 #include <drm/drm_fourcc.h>
0041 #include <drm/drm_framebuffer.h>
0042 #include <drm/drm_mode.h>
0043 #include <drm/drm_print.h>
0044 #include <drm/drm_writeback.h>
0045
0046 #include "drm_crtc_internal.h"
0047 #include "drm_internal.h"
0048
0049 void __drm_crtc_commit_free(struct kref *kref)
0050 {
0051 struct drm_crtc_commit *commit =
0052 container_of(kref, struct drm_crtc_commit, ref);
0053
0054 kfree(commit);
0055 }
0056 EXPORT_SYMBOL(__drm_crtc_commit_free);
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 int drm_crtc_commit_wait(struct drm_crtc_commit *commit)
0070 {
0071 unsigned long timeout = 10 * HZ;
0072 int ret;
0073
0074 if (!commit)
0075 return 0;
0076
0077 ret = wait_for_completion_timeout(&commit->hw_done, timeout);
0078 if (!ret) {
0079 drm_err(commit->crtc->dev, "hw_done timed out\n");
0080 return -ETIMEDOUT;
0081 }
0082
0083
0084
0085
0086
0087 ret = wait_for_completion_timeout(&commit->flip_done, timeout);
0088 if (!ret) {
0089 drm_err(commit->crtc->dev, "flip_done timed out\n");
0090 return -ETIMEDOUT;
0091 }
0092
0093 return 0;
0094 }
0095 EXPORT_SYMBOL(drm_crtc_commit_wait);
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 void drm_atomic_state_default_release(struct drm_atomic_state *state)
0107 {
0108 kfree(state->connectors);
0109 kfree(state->crtcs);
0110 kfree(state->planes);
0111 kfree(state->private_objs);
0112 }
0113 EXPORT_SYMBOL(drm_atomic_state_default_release);
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124 int
0125 drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
0126 {
0127 kref_init(&state->ref);
0128
0129
0130
0131
0132 state->allow_modeset = true;
0133
0134 state->crtcs = kcalloc(dev->mode_config.num_crtc,
0135 sizeof(*state->crtcs), GFP_KERNEL);
0136 if (!state->crtcs)
0137 goto fail;
0138 state->planes = kcalloc(dev->mode_config.num_total_plane,
0139 sizeof(*state->planes), GFP_KERNEL);
0140 if (!state->planes)
0141 goto fail;
0142
0143 state->dev = dev;
0144
0145 drm_dbg_atomic(dev, "Allocated atomic state %p\n", state);
0146
0147 return 0;
0148 fail:
0149 drm_atomic_state_default_release(state);
0150 return -ENOMEM;
0151 }
0152 EXPORT_SYMBOL(drm_atomic_state_init);
0153
0154
0155
0156
0157
0158
0159
0160 struct drm_atomic_state *
0161 drm_atomic_state_alloc(struct drm_device *dev)
0162 {
0163 struct drm_mode_config *config = &dev->mode_config;
0164
0165 if (!config->funcs->atomic_state_alloc) {
0166 struct drm_atomic_state *state;
0167
0168 state = kzalloc(sizeof(*state), GFP_KERNEL);
0169 if (!state)
0170 return NULL;
0171 if (drm_atomic_state_init(dev, state) < 0) {
0172 kfree(state);
0173 return NULL;
0174 }
0175 return state;
0176 }
0177
0178 return config->funcs->atomic_state_alloc(dev);
0179 }
0180 EXPORT_SYMBOL(drm_atomic_state_alloc);
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190 void drm_atomic_state_default_clear(struct drm_atomic_state *state)
0191 {
0192 struct drm_device *dev = state->dev;
0193 struct drm_mode_config *config = &dev->mode_config;
0194 int i;
0195
0196 drm_dbg_atomic(dev, "Clearing atomic state %p\n", state);
0197
0198 for (i = 0; i < state->num_connector; i++) {
0199 struct drm_connector *connector = state->connectors[i].ptr;
0200
0201 if (!connector)
0202 continue;
0203
0204 connector->funcs->atomic_destroy_state(connector,
0205 state->connectors[i].state);
0206 state->connectors[i].ptr = NULL;
0207 state->connectors[i].state = NULL;
0208 state->connectors[i].old_state = NULL;
0209 state->connectors[i].new_state = NULL;
0210 drm_connector_put(connector);
0211 }
0212
0213 for (i = 0; i < config->num_crtc; i++) {
0214 struct drm_crtc *crtc = state->crtcs[i].ptr;
0215
0216 if (!crtc)
0217 continue;
0218
0219 crtc->funcs->atomic_destroy_state(crtc,
0220 state->crtcs[i].state);
0221
0222 state->crtcs[i].ptr = NULL;
0223 state->crtcs[i].state = NULL;
0224 state->crtcs[i].old_state = NULL;
0225 state->crtcs[i].new_state = NULL;
0226
0227 if (state->crtcs[i].commit) {
0228 drm_crtc_commit_put(state->crtcs[i].commit);
0229 state->crtcs[i].commit = NULL;
0230 }
0231 }
0232
0233 for (i = 0; i < config->num_total_plane; i++) {
0234 struct drm_plane *plane = state->planes[i].ptr;
0235
0236 if (!plane)
0237 continue;
0238
0239 plane->funcs->atomic_destroy_state(plane,
0240 state->planes[i].state);
0241 state->planes[i].ptr = NULL;
0242 state->planes[i].state = NULL;
0243 state->planes[i].old_state = NULL;
0244 state->planes[i].new_state = NULL;
0245 }
0246
0247 for (i = 0; i < state->num_private_objs; i++) {
0248 struct drm_private_obj *obj = state->private_objs[i].ptr;
0249
0250 obj->funcs->atomic_destroy_state(obj,
0251 state->private_objs[i].state);
0252 state->private_objs[i].ptr = NULL;
0253 state->private_objs[i].state = NULL;
0254 state->private_objs[i].old_state = NULL;
0255 state->private_objs[i].new_state = NULL;
0256 }
0257 state->num_private_objs = 0;
0258
0259 if (state->fake_commit) {
0260 drm_crtc_commit_put(state->fake_commit);
0261 state->fake_commit = NULL;
0262 }
0263 }
0264 EXPORT_SYMBOL(drm_atomic_state_default_clear);
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280 void drm_atomic_state_clear(struct drm_atomic_state *state)
0281 {
0282 struct drm_device *dev = state->dev;
0283 struct drm_mode_config *config = &dev->mode_config;
0284
0285 if (config->funcs->atomic_state_clear)
0286 config->funcs->atomic_state_clear(state);
0287 else
0288 drm_atomic_state_default_clear(state);
0289 }
0290 EXPORT_SYMBOL(drm_atomic_state_clear);
0291
0292
0293
0294
0295
0296
0297
0298
0299 void __drm_atomic_state_free(struct kref *ref)
0300 {
0301 struct drm_atomic_state *state = container_of(ref, typeof(*state), ref);
0302 struct drm_mode_config *config = &state->dev->mode_config;
0303
0304 drm_atomic_state_clear(state);
0305
0306 drm_dbg_atomic(state->dev, "Freeing atomic state %p\n", state);
0307
0308 if (config->funcs->atomic_state_free) {
0309 config->funcs->atomic_state_free(state);
0310 } else {
0311 drm_atomic_state_default_release(state);
0312 kfree(state);
0313 }
0314 }
0315 EXPORT_SYMBOL(__drm_atomic_state_free);
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336 struct drm_crtc_state *
0337 drm_atomic_get_crtc_state(struct drm_atomic_state *state,
0338 struct drm_crtc *crtc)
0339 {
0340 int ret, index = drm_crtc_index(crtc);
0341 struct drm_crtc_state *crtc_state;
0342
0343 WARN_ON(!state->acquire_ctx);
0344
0345 crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
0346 if (crtc_state)
0347 return crtc_state;
0348
0349 ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
0350 if (ret)
0351 return ERR_PTR(ret);
0352
0353 crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
0354 if (!crtc_state)
0355 return ERR_PTR(-ENOMEM);
0356
0357 state->crtcs[index].state = crtc_state;
0358 state->crtcs[index].old_state = crtc->state;
0359 state->crtcs[index].new_state = crtc_state;
0360 state->crtcs[index].ptr = crtc;
0361 crtc_state->state = state;
0362
0363 drm_dbg_atomic(state->dev, "Added [CRTC:%d:%s] %p state to %p\n",
0364 crtc->base.id, crtc->name, crtc_state, state);
0365
0366 return crtc_state;
0367 }
0368 EXPORT_SYMBOL(drm_atomic_get_crtc_state);
0369
0370 static int drm_atomic_crtc_check(const struct drm_crtc_state *old_crtc_state,
0371 const struct drm_crtc_state *new_crtc_state)
0372 {
0373 struct drm_crtc *crtc = new_crtc_state->crtc;
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383 if (new_crtc_state->active && !new_crtc_state->enable) {
0384 drm_dbg_atomic(crtc->dev,
0385 "[CRTC:%d:%s] active without enabled\n",
0386 crtc->base.id, crtc->name);
0387 return -EINVAL;
0388 }
0389
0390
0391
0392
0393
0394 if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
0395 WARN_ON(new_crtc_state->enable && !new_crtc_state->mode_blob)) {
0396 drm_dbg_atomic(crtc->dev,
0397 "[CRTC:%d:%s] enabled without mode blob\n",
0398 crtc->base.id, crtc->name);
0399 return -EINVAL;
0400 }
0401
0402 if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
0403 WARN_ON(!new_crtc_state->enable && new_crtc_state->mode_blob)) {
0404 drm_dbg_atomic(crtc->dev,
0405 "[CRTC:%d:%s] disabled with mode blob\n",
0406 crtc->base.id, crtc->name);
0407 return -EINVAL;
0408 }
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420 if (new_crtc_state->event &&
0421 !new_crtc_state->active && !old_crtc_state->active) {
0422 drm_dbg_atomic(crtc->dev,
0423 "[CRTC:%d:%s] requesting event but off\n",
0424 crtc->base.id, crtc->name);
0425 return -EINVAL;
0426 }
0427
0428 return 0;
0429 }
0430
0431 static void drm_atomic_crtc_print_state(struct drm_printer *p,
0432 const struct drm_crtc_state *state)
0433 {
0434 struct drm_crtc *crtc = state->crtc;
0435
0436 drm_printf(p, "crtc[%u]: %s\n", crtc->base.id, crtc->name);
0437 drm_printf(p, "\tenable=%d\n", state->enable);
0438 drm_printf(p, "\tactive=%d\n", state->active);
0439 drm_printf(p, "\tself_refresh_active=%d\n", state->self_refresh_active);
0440 drm_printf(p, "\tplanes_changed=%d\n", state->planes_changed);
0441 drm_printf(p, "\tmode_changed=%d\n", state->mode_changed);
0442 drm_printf(p, "\tactive_changed=%d\n", state->active_changed);
0443 drm_printf(p, "\tconnectors_changed=%d\n", state->connectors_changed);
0444 drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
0445 drm_printf(p, "\tplane_mask=%x\n", state->plane_mask);
0446 drm_printf(p, "\tconnector_mask=%x\n", state->connector_mask);
0447 drm_printf(p, "\tencoder_mask=%x\n", state->encoder_mask);
0448 drm_printf(p, "\tmode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&state->mode));
0449
0450 if (crtc->funcs->atomic_print_state)
0451 crtc->funcs->atomic_print_state(p, state);
0452 }
0453
0454 static int drm_atomic_connector_check(struct drm_connector *connector,
0455 struct drm_connector_state *state)
0456 {
0457 struct drm_crtc_state *crtc_state;
0458 struct drm_writeback_job *writeback_job = state->writeback_job;
0459 const struct drm_display_info *info = &connector->display_info;
0460
0461 state->max_bpc = info->bpc ? info->bpc : 8;
0462 if (connector->max_bpc_property)
0463 state->max_bpc = min(state->max_bpc, state->max_requested_bpc);
0464
0465 if ((connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) || !writeback_job)
0466 return 0;
0467
0468 if (writeback_job->fb && !state->crtc) {
0469 drm_dbg_atomic(connector->dev,
0470 "[CONNECTOR:%d:%s] framebuffer without CRTC\n",
0471 connector->base.id, connector->name);
0472 return -EINVAL;
0473 }
0474
0475 if (state->crtc)
0476 crtc_state = drm_atomic_get_existing_crtc_state(state->state,
0477 state->crtc);
0478
0479 if (writeback_job->fb && !crtc_state->active) {
0480 drm_dbg_atomic(connector->dev,
0481 "[CONNECTOR:%d:%s] has framebuffer, but [CRTC:%d] is off\n",
0482 connector->base.id, connector->name,
0483 state->crtc->base.id);
0484 return -EINVAL;
0485 }
0486
0487 if (!writeback_job->fb) {
0488 if (writeback_job->out_fence) {
0489 drm_dbg_atomic(connector->dev,
0490 "[CONNECTOR:%d:%s] requesting out-fence without framebuffer\n",
0491 connector->base.id, connector->name);
0492 return -EINVAL;
0493 }
0494
0495 drm_writeback_cleanup_job(writeback_job);
0496 state->writeback_job = NULL;
0497 }
0498
0499 return 0;
0500 }
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517 struct drm_plane_state *
0518 drm_atomic_get_plane_state(struct drm_atomic_state *state,
0519 struct drm_plane *plane)
0520 {
0521 int ret, index = drm_plane_index(plane);
0522 struct drm_plane_state *plane_state;
0523
0524 WARN_ON(!state->acquire_ctx);
0525
0526
0527 WARN_ON(plane->fb);
0528 WARN_ON(plane->old_fb);
0529 WARN_ON(plane->crtc);
0530
0531 plane_state = drm_atomic_get_existing_plane_state(state, plane);
0532 if (plane_state)
0533 return plane_state;
0534
0535 ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx);
0536 if (ret)
0537 return ERR_PTR(ret);
0538
0539 plane_state = plane->funcs->atomic_duplicate_state(plane);
0540 if (!plane_state)
0541 return ERR_PTR(-ENOMEM);
0542
0543 state->planes[index].state = plane_state;
0544 state->planes[index].ptr = plane;
0545 state->planes[index].old_state = plane->state;
0546 state->planes[index].new_state = plane_state;
0547 plane_state->state = state;
0548
0549 drm_dbg_atomic(plane->dev, "Added [PLANE:%d:%s] %p state to %p\n",
0550 plane->base.id, plane->name, plane_state, state);
0551
0552 if (plane_state->crtc) {
0553 struct drm_crtc_state *crtc_state;
0554
0555 crtc_state = drm_atomic_get_crtc_state(state,
0556 plane_state->crtc);
0557 if (IS_ERR(crtc_state))
0558 return ERR_CAST(crtc_state);
0559 }
0560
0561 return plane_state;
0562 }
0563 EXPORT_SYMBOL(drm_atomic_get_plane_state);
0564
0565 static bool
0566 plane_switching_crtc(const struct drm_plane_state *old_plane_state,
0567 const struct drm_plane_state *new_plane_state)
0568 {
0569 if (!old_plane_state->crtc || !new_plane_state->crtc)
0570 return false;
0571
0572 if (old_plane_state->crtc == new_plane_state->crtc)
0573 return false;
0574
0575
0576
0577
0578
0579
0580 return true;
0581 }
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593 static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
0594 const struct drm_plane_state *new_plane_state)
0595 {
0596 struct drm_plane *plane = new_plane_state->plane;
0597 struct drm_crtc *crtc = new_plane_state->crtc;
0598 const struct drm_framebuffer *fb = new_plane_state->fb;
0599 unsigned int fb_width, fb_height;
0600 struct drm_mode_rect *clips;
0601 uint32_t num_clips;
0602 int ret;
0603
0604
0605 if (crtc && !fb) {
0606 drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no FB\n",
0607 plane->base.id, plane->name);
0608 return -EINVAL;
0609 } else if (fb && !crtc) {
0610 drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] FB set but no CRTC\n",
0611 plane->base.id, plane->name);
0612 return -EINVAL;
0613 }
0614
0615
0616 if (!crtc)
0617 return 0;
0618
0619
0620 if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
0621 drm_dbg_atomic(plane->dev,
0622 "Invalid [CRTC:%d:%s] for [PLANE:%d:%s]\n",
0623 crtc->base.id, crtc->name,
0624 plane->base.id, plane->name);
0625 return -EINVAL;
0626 }
0627
0628
0629 ret = drm_plane_check_pixel_format(plane, fb->format->format,
0630 fb->modifier);
0631 if (ret) {
0632 drm_dbg_atomic(plane->dev,
0633 "[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n",
0634 plane->base.id, plane->name,
0635 &fb->format->format, fb->modifier);
0636 return ret;
0637 }
0638
0639
0640 if (new_plane_state->crtc_w > INT_MAX ||
0641 new_plane_state->crtc_x > INT_MAX - (int32_t) new_plane_state->crtc_w ||
0642 new_plane_state->crtc_h > INT_MAX ||
0643 new_plane_state->crtc_y > INT_MAX - (int32_t) new_plane_state->crtc_h) {
0644 drm_dbg_atomic(plane->dev,
0645 "[PLANE:%d:%s] invalid CRTC coordinates %ux%u+%d+%d\n",
0646 plane->base.id, plane->name,
0647 new_plane_state->crtc_w, new_plane_state->crtc_h,
0648 new_plane_state->crtc_x, new_plane_state->crtc_y);
0649 return -ERANGE;
0650 }
0651
0652 fb_width = fb->width << 16;
0653 fb_height = fb->height << 16;
0654
0655
0656 if (new_plane_state->src_w > fb_width ||
0657 new_plane_state->src_x > fb_width - new_plane_state->src_w ||
0658 new_plane_state->src_h > fb_height ||
0659 new_plane_state->src_y > fb_height - new_plane_state->src_h) {
0660 drm_dbg_atomic(plane->dev,
0661 "[PLANE:%d:%s] invalid source coordinates "
0662 "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
0663 plane->base.id, plane->name,
0664 new_plane_state->src_w >> 16,
0665 ((new_plane_state->src_w & 0xffff) * 15625) >> 10,
0666 new_plane_state->src_h >> 16,
0667 ((new_plane_state->src_h & 0xffff) * 15625) >> 10,
0668 new_plane_state->src_x >> 16,
0669 ((new_plane_state->src_x & 0xffff) * 15625) >> 10,
0670 new_plane_state->src_y >> 16,
0671 ((new_plane_state->src_y & 0xffff) * 15625) >> 10,
0672 fb->width, fb->height);
0673 return -ENOSPC;
0674 }
0675
0676 clips = __drm_plane_get_damage_clips(new_plane_state);
0677 num_clips = drm_plane_get_damage_clips_count(new_plane_state);
0678
0679
0680 while (num_clips > 0) {
0681 if (clips->x1 >= clips->x2 ||
0682 clips->y1 >= clips->y2 ||
0683 clips->x1 < 0 ||
0684 clips->y1 < 0 ||
0685 clips->x2 > fb_width ||
0686 clips->y2 > fb_height) {
0687 drm_dbg_atomic(plane->dev,
0688 "[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
0689 plane->base.id, plane->name, clips->x1,
0690 clips->y1, clips->x2, clips->y2);
0691 return -EINVAL;
0692 }
0693 clips++;
0694 num_clips--;
0695 }
0696
0697 if (plane_switching_crtc(old_plane_state, new_plane_state)) {
0698 drm_dbg_atomic(plane->dev,
0699 "[PLANE:%d:%s] switching CRTC directly\n",
0700 plane->base.id, plane->name);
0701 return -EINVAL;
0702 }
0703
0704 return 0;
0705 }
0706
0707 static void drm_atomic_plane_print_state(struct drm_printer *p,
0708 const struct drm_plane_state *state)
0709 {
0710 struct drm_plane *plane = state->plane;
0711 struct drm_rect src = drm_plane_state_src(state);
0712 struct drm_rect dest = drm_plane_state_dest(state);
0713
0714 drm_printf(p, "plane[%u]: %s\n", plane->base.id, plane->name);
0715 drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
0716 drm_printf(p, "\tfb=%u\n", state->fb ? state->fb->base.id : 0);
0717 if (state->fb)
0718 drm_framebuffer_print_info(p, 2, state->fb);
0719 drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest));
0720 drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src));
0721 drm_printf(p, "\trotation=%x\n", state->rotation);
0722 drm_printf(p, "\tnormalized-zpos=%x\n", state->normalized_zpos);
0723 drm_printf(p, "\tcolor-encoding=%s\n",
0724 drm_get_color_encoding_name(state->color_encoding));
0725 drm_printf(p, "\tcolor-range=%s\n",
0726 drm_get_color_range_name(state->color_range));
0727
0728 if (plane->funcs->atomic_print_state)
0729 plane->funcs->atomic_print_state(p, state);
0730 }
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781 void
0782 drm_atomic_private_obj_init(struct drm_device *dev,
0783 struct drm_private_obj *obj,
0784 struct drm_private_state *state,
0785 const struct drm_private_state_funcs *funcs)
0786 {
0787 memset(obj, 0, sizeof(*obj));
0788
0789 drm_modeset_lock_init(&obj->lock);
0790
0791 obj->state = state;
0792 obj->funcs = funcs;
0793 list_add_tail(&obj->head, &dev->mode_config.privobj_list);
0794
0795 state->obj = obj;
0796 }
0797 EXPORT_SYMBOL(drm_atomic_private_obj_init);
0798
0799
0800
0801
0802
0803
0804
0805 void
0806 drm_atomic_private_obj_fini(struct drm_private_obj *obj)
0807 {
0808 list_del(&obj->head);
0809 obj->funcs->atomic_destroy_state(obj, obj->state);
0810 drm_modeset_lock_fini(&obj->lock);
0811 }
0812 EXPORT_SYMBOL(drm_atomic_private_obj_fini);
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827 struct drm_private_state *
0828 drm_atomic_get_private_obj_state(struct drm_atomic_state *state,
0829 struct drm_private_obj *obj)
0830 {
0831 int index, num_objs, i, ret;
0832 size_t size;
0833 struct __drm_private_objs_state *arr;
0834 struct drm_private_state *obj_state;
0835
0836 for (i = 0; i < state->num_private_objs; i++)
0837 if (obj == state->private_objs[i].ptr)
0838 return state->private_objs[i].state;
0839
0840 ret = drm_modeset_lock(&obj->lock, state->acquire_ctx);
0841 if (ret)
0842 return ERR_PTR(ret);
0843
0844 num_objs = state->num_private_objs + 1;
0845 size = sizeof(*state->private_objs) * num_objs;
0846 arr = krealloc(state->private_objs, size, GFP_KERNEL);
0847 if (!arr)
0848 return ERR_PTR(-ENOMEM);
0849
0850 state->private_objs = arr;
0851 index = state->num_private_objs;
0852 memset(&state->private_objs[index], 0, sizeof(*state->private_objs));
0853
0854 obj_state = obj->funcs->atomic_duplicate_state(obj);
0855 if (!obj_state)
0856 return ERR_PTR(-ENOMEM);
0857
0858 state->private_objs[index].state = obj_state;
0859 state->private_objs[index].old_state = obj->state;
0860 state->private_objs[index].new_state = obj_state;
0861 state->private_objs[index].ptr = obj;
0862 obj_state->state = state;
0863
0864 state->num_private_objs = num_objs;
0865
0866 drm_dbg_atomic(state->dev,
0867 "Added new private object %p state %p to %p\n",
0868 obj, obj_state, state);
0869
0870 return obj_state;
0871 }
0872 EXPORT_SYMBOL(drm_atomic_get_private_obj_state);
0873
0874
0875
0876
0877
0878
0879
0880
0881
0882 struct drm_private_state *
0883 drm_atomic_get_old_private_obj_state(struct drm_atomic_state *state,
0884 struct drm_private_obj *obj)
0885 {
0886 int i;
0887
0888 for (i = 0; i < state->num_private_objs; i++)
0889 if (obj == state->private_objs[i].ptr)
0890 return state->private_objs[i].old_state;
0891
0892 return NULL;
0893 }
0894 EXPORT_SYMBOL(drm_atomic_get_old_private_obj_state);
0895
0896
0897
0898
0899
0900
0901
0902
0903
0904 struct drm_private_state *
0905 drm_atomic_get_new_private_obj_state(struct drm_atomic_state *state,
0906 struct drm_private_obj *obj)
0907 {
0908 int i;
0909
0910 for (i = 0; i < state->num_private_objs; i++)
0911 if (obj == state->private_objs[i].ptr)
0912 return state->private_objs[i].new_state;
0913
0914 return NULL;
0915 }
0916 EXPORT_SYMBOL(drm_atomic_get_new_private_obj_state);
0917
0918
0919
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929
0930
0931
0932
0933
0934
0935
0936 struct drm_connector *
0937 drm_atomic_get_old_connector_for_encoder(struct drm_atomic_state *state,
0938 struct drm_encoder *encoder)
0939 {
0940 struct drm_connector_state *conn_state;
0941 struct drm_connector *connector;
0942 unsigned int i;
0943
0944 for_each_old_connector_in_state(state, connector, conn_state, i) {
0945 if (conn_state->best_encoder == encoder)
0946 return connector;
0947 }
0948
0949 return NULL;
0950 }
0951 EXPORT_SYMBOL(drm_atomic_get_old_connector_for_encoder);
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970 struct drm_connector *
0971 drm_atomic_get_new_connector_for_encoder(struct drm_atomic_state *state,
0972 struct drm_encoder *encoder)
0973 {
0974 struct drm_connector_state *conn_state;
0975 struct drm_connector *connector;
0976 unsigned int i;
0977
0978 for_each_new_connector_in_state(state, connector, conn_state, i) {
0979 if (conn_state->best_encoder == encoder)
0980 return connector;
0981 }
0982
0983 return NULL;
0984 }
0985 EXPORT_SYMBOL(drm_atomic_get_new_connector_for_encoder);
0986
0987
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999
1000
1001
1002 struct drm_connector_state *
1003 drm_atomic_get_connector_state(struct drm_atomic_state *state,
1004 struct drm_connector *connector)
1005 {
1006 int ret, index;
1007 struct drm_mode_config *config = &connector->dev->mode_config;
1008 struct drm_connector_state *connector_state;
1009
1010 WARN_ON(!state->acquire_ctx);
1011
1012 ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
1013 if (ret)
1014 return ERR_PTR(ret);
1015
1016 index = drm_connector_index(connector);
1017
1018 if (index >= state->num_connector) {
1019 struct __drm_connnectors_state *c;
1020 int alloc = max(index + 1, config->num_connector);
1021
1022 c = krealloc_array(state->connectors, alloc,
1023 sizeof(*state->connectors), GFP_KERNEL);
1024 if (!c)
1025 return ERR_PTR(-ENOMEM);
1026
1027 state->connectors = c;
1028 memset(&state->connectors[state->num_connector], 0,
1029 sizeof(*state->connectors) * (alloc - state->num_connector));
1030
1031 state->num_connector = alloc;
1032 }
1033
1034 if (state->connectors[index].state)
1035 return state->connectors[index].state;
1036
1037 connector_state = connector->funcs->atomic_duplicate_state(connector);
1038 if (!connector_state)
1039 return ERR_PTR(-ENOMEM);
1040
1041 drm_connector_get(connector);
1042 state->connectors[index].state = connector_state;
1043 state->connectors[index].old_state = connector->state;
1044 state->connectors[index].new_state = connector_state;
1045 state->connectors[index].ptr = connector;
1046 connector_state->state = state;
1047
1048 drm_dbg_atomic(connector->dev, "Added [CONNECTOR:%d:%s] %p state to %p\n",
1049 connector->base.id, connector->name,
1050 connector_state, state);
1051
1052 if (connector_state->crtc) {
1053 struct drm_crtc_state *crtc_state;
1054
1055 crtc_state = drm_atomic_get_crtc_state(state,
1056 connector_state->crtc);
1057 if (IS_ERR(crtc_state))
1058 return ERR_CAST(crtc_state);
1059 }
1060
1061 return connector_state;
1062 }
1063 EXPORT_SYMBOL(drm_atomic_get_connector_state);
1064
1065 static void drm_atomic_connector_print_state(struct drm_printer *p,
1066 const struct drm_connector_state *state)
1067 {
1068 struct drm_connector *connector = state->connector;
1069
1070 drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name);
1071 drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
1072 drm_printf(p, "\tself_refresh_aware=%d\n", state->self_refresh_aware);
1073
1074 if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
1075 if (state->writeback_job && state->writeback_job->fb)
1076 drm_printf(p, "\tfb=%d\n", state->writeback_job->fb->base.id);
1077
1078 if (connector->funcs->atomic_print_state)
1079 connector->funcs->atomic_print_state(p, state);
1080 }
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097 struct drm_bridge_state *
1098 drm_atomic_get_bridge_state(struct drm_atomic_state *state,
1099 struct drm_bridge *bridge)
1100 {
1101 struct drm_private_state *obj_state;
1102
1103 obj_state = drm_atomic_get_private_obj_state(state, &bridge->base);
1104 if (IS_ERR(obj_state))
1105 return ERR_CAST(obj_state);
1106
1107 return drm_priv_to_bridge_state(obj_state);
1108 }
1109 EXPORT_SYMBOL(drm_atomic_get_bridge_state);
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119 struct drm_bridge_state *
1120 drm_atomic_get_old_bridge_state(struct drm_atomic_state *state,
1121 struct drm_bridge *bridge)
1122 {
1123 struct drm_private_state *obj_state;
1124
1125 obj_state = drm_atomic_get_old_private_obj_state(state, &bridge->base);
1126 if (!obj_state)
1127 return NULL;
1128
1129 return drm_priv_to_bridge_state(obj_state);
1130 }
1131 EXPORT_SYMBOL(drm_atomic_get_old_bridge_state);
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141 struct drm_bridge_state *
1142 drm_atomic_get_new_bridge_state(struct drm_atomic_state *state,
1143 struct drm_bridge *bridge)
1144 {
1145 struct drm_private_state *obj_state;
1146
1147 obj_state = drm_atomic_get_new_private_obj_state(state, &bridge->base);
1148 if (!obj_state)
1149 return NULL;
1150
1151 return drm_priv_to_bridge_state(obj_state);
1152 }
1153 EXPORT_SYMBOL(drm_atomic_get_new_bridge_state);
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171 int
1172 drm_atomic_add_encoder_bridges(struct drm_atomic_state *state,
1173 struct drm_encoder *encoder)
1174 {
1175 struct drm_bridge_state *bridge_state;
1176 struct drm_bridge *bridge;
1177
1178 if (!encoder)
1179 return 0;
1180
1181 drm_dbg_atomic(encoder->dev,
1182 "Adding all bridges for [encoder:%d:%s] to %p\n",
1183 encoder->base.id, encoder->name, state);
1184
1185 drm_for_each_bridge_in_chain(encoder, bridge) {
1186
1187 if (!bridge->funcs->atomic_duplicate_state)
1188 continue;
1189
1190 bridge_state = drm_atomic_get_bridge_state(state, bridge);
1191 if (IS_ERR(bridge_state))
1192 return PTR_ERR(bridge_state);
1193 }
1194
1195 return 0;
1196 }
1197 EXPORT_SYMBOL(drm_atomic_add_encoder_bridges);
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216 int
1217 drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
1218 struct drm_crtc *crtc)
1219 {
1220 struct drm_mode_config *config = &state->dev->mode_config;
1221 struct drm_connector *connector;
1222 struct drm_connector_state *conn_state;
1223 struct drm_connector_list_iter conn_iter;
1224 struct drm_crtc_state *crtc_state;
1225 int ret;
1226
1227 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1228 if (IS_ERR(crtc_state))
1229 return PTR_ERR(crtc_state);
1230
1231 ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
1232 if (ret)
1233 return ret;
1234
1235 drm_dbg_atomic(crtc->dev,
1236 "Adding all current connectors for [CRTC:%d:%s] to %p\n",
1237 crtc->base.id, crtc->name, state);
1238
1239
1240
1241
1242
1243 drm_connector_list_iter_begin(state->dev, &conn_iter);
1244 drm_for_each_connector_iter(connector, &conn_iter) {
1245 if (!(crtc_state->connector_mask & drm_connector_mask(connector)))
1246 continue;
1247
1248 conn_state = drm_atomic_get_connector_state(state, connector);
1249 if (IS_ERR(conn_state)) {
1250 drm_connector_list_iter_end(&conn_iter);
1251 return PTR_ERR(conn_state);
1252 }
1253 }
1254 drm_connector_list_iter_end(&conn_iter);
1255
1256 return 0;
1257 }
1258 EXPORT_SYMBOL(drm_atomic_add_affected_connectors);
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280 int
1281 drm_atomic_add_affected_planes(struct drm_atomic_state *state,
1282 struct drm_crtc *crtc)
1283 {
1284 const struct drm_crtc_state *old_crtc_state =
1285 drm_atomic_get_old_crtc_state(state, crtc);
1286 struct drm_plane *plane;
1287
1288 WARN_ON(!drm_atomic_get_new_crtc_state(state, crtc));
1289
1290 drm_dbg_atomic(crtc->dev,
1291 "Adding all current planes for [CRTC:%d:%s] to %p\n",
1292 crtc->base.id, crtc->name, state);
1293
1294 drm_for_each_plane_mask(plane, state->dev, old_crtc_state->plane_mask) {
1295 struct drm_plane_state *plane_state =
1296 drm_atomic_get_plane_state(state, plane);
1297
1298 if (IS_ERR(plane_state))
1299 return PTR_ERR(plane_state);
1300 }
1301 return 0;
1302 }
1303 EXPORT_SYMBOL(drm_atomic_add_affected_planes);
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316 int drm_atomic_check_only(struct drm_atomic_state *state)
1317 {
1318 struct drm_device *dev = state->dev;
1319 struct drm_mode_config *config = &dev->mode_config;
1320 struct drm_plane *plane;
1321 struct drm_plane_state *old_plane_state;
1322 struct drm_plane_state *new_plane_state;
1323 struct drm_crtc *crtc;
1324 struct drm_crtc_state *old_crtc_state;
1325 struct drm_crtc_state *new_crtc_state;
1326 struct drm_connector *conn;
1327 struct drm_connector_state *conn_state;
1328 unsigned int requested_crtc = 0;
1329 unsigned int affected_crtc = 0;
1330 int i, ret = 0;
1331
1332 drm_dbg_atomic(dev, "checking %p\n", state);
1333
1334 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
1335 if (new_crtc_state->enable)
1336 requested_crtc |= drm_crtc_mask(crtc);
1337 }
1338
1339 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
1340 ret = drm_atomic_plane_check(old_plane_state, new_plane_state);
1341 if (ret) {
1342 drm_dbg_atomic(dev, "[PLANE:%d:%s] atomic core check failed\n",
1343 plane->base.id, plane->name);
1344 return ret;
1345 }
1346 }
1347
1348 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
1349 ret = drm_atomic_crtc_check(old_crtc_state, new_crtc_state);
1350 if (ret) {
1351 drm_dbg_atomic(dev, "[CRTC:%d:%s] atomic core check failed\n",
1352 crtc->base.id, crtc->name);
1353 return ret;
1354 }
1355 }
1356
1357 for_each_new_connector_in_state(state, conn, conn_state, i) {
1358 ret = drm_atomic_connector_check(conn, conn_state);
1359 if (ret) {
1360 drm_dbg_atomic(dev, "[CONNECTOR:%d:%s] atomic core check failed\n",
1361 conn->base.id, conn->name);
1362 return ret;
1363 }
1364 }
1365
1366 if (config->funcs->atomic_check) {
1367 ret = config->funcs->atomic_check(state->dev, state);
1368
1369 if (ret) {
1370 drm_dbg_atomic(dev, "atomic driver check for %p failed: %d\n",
1371 state, ret);
1372 return ret;
1373 }
1374 }
1375
1376 if (!state->allow_modeset) {
1377 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
1378 if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
1379 drm_dbg_atomic(dev, "[CRTC:%d:%s] requires full modeset\n",
1380 crtc->base.id, crtc->name);
1381 return -EINVAL;
1382 }
1383 }
1384 }
1385
1386 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
1387 if (new_crtc_state->enable)
1388 affected_crtc |= drm_crtc_mask(crtc);
1389 }
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401 if (affected_crtc != requested_crtc) {
1402 drm_dbg_atomic(dev,
1403 "driver added CRTC to commit: requested 0x%x, affected 0x%0x\n",
1404 requested_crtc, affected_crtc);
1405 WARN(!state->allow_modeset, "adding CRTC not allowed without modesets: requested 0x%x, affected 0x%0x\n",
1406 requested_crtc, affected_crtc);
1407 }
1408
1409 return 0;
1410 }
1411 EXPORT_SYMBOL(drm_atomic_check_only);
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427 int drm_atomic_commit(struct drm_atomic_state *state)
1428 {
1429 struct drm_mode_config *config = &state->dev->mode_config;
1430 struct drm_printer p = drm_info_printer(state->dev->dev);
1431 int ret;
1432
1433 if (drm_debug_enabled(DRM_UT_STATE))
1434 drm_atomic_print_new_state(state, &p);
1435
1436 ret = drm_atomic_check_only(state);
1437 if (ret)
1438 return ret;
1439
1440 drm_dbg_atomic(state->dev, "committing %p\n", state);
1441
1442 return config->funcs->atomic_commit(state->dev, state, false);
1443 }
1444 EXPORT_SYMBOL(drm_atomic_commit);
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460 int drm_atomic_nonblocking_commit(struct drm_atomic_state *state)
1461 {
1462 struct drm_mode_config *config = &state->dev->mode_config;
1463 int ret;
1464
1465 ret = drm_atomic_check_only(state);
1466 if (ret)
1467 return ret;
1468
1469 drm_dbg_atomic(state->dev, "committing %p nonblocking\n", state);
1470
1471 return config->funcs->atomic_commit(state->dev, state, true);
1472 }
1473 EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
1474
1475
1476 int __drm_atomic_helper_disable_plane(struct drm_plane *plane,
1477 struct drm_plane_state *plane_state)
1478 {
1479 int ret;
1480
1481 ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
1482 if (ret != 0)
1483 return ret;
1484
1485 drm_atomic_set_fb_for_plane(plane_state, NULL);
1486 plane_state->crtc_x = 0;
1487 plane_state->crtc_y = 0;
1488 plane_state->crtc_w = 0;
1489 plane_state->crtc_h = 0;
1490 plane_state->src_x = 0;
1491 plane_state->src_y = 0;
1492 plane_state->src_w = 0;
1493 plane_state->src_h = 0;
1494
1495 return 0;
1496 }
1497 EXPORT_SYMBOL(__drm_atomic_helper_disable_plane);
1498
1499 static int update_output_state(struct drm_atomic_state *state,
1500 struct drm_mode_set *set)
1501 {
1502 struct drm_device *dev = set->crtc->dev;
1503 struct drm_crtc *crtc;
1504 struct drm_crtc_state *new_crtc_state;
1505 struct drm_connector *connector;
1506 struct drm_connector_state *new_conn_state;
1507 int ret, i;
1508
1509 ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
1510 state->acquire_ctx);
1511 if (ret)
1512 return ret;
1513
1514
1515 ret = drm_atomic_add_affected_connectors(state, set->crtc);
1516 if (ret)
1517 return ret;
1518
1519 for_each_new_connector_in_state(state, connector, new_conn_state, i) {
1520 if (new_conn_state->crtc == set->crtc) {
1521 ret = drm_atomic_set_crtc_for_connector(new_conn_state,
1522 NULL);
1523 if (ret)
1524 return ret;
1525
1526
1527 new_conn_state->link_status = DRM_LINK_STATUS_GOOD;
1528 }
1529 }
1530
1531
1532 for (i = 0; i < set->num_connectors; i++) {
1533 new_conn_state = drm_atomic_get_connector_state(state,
1534 set->connectors[i]);
1535 if (IS_ERR(new_conn_state))
1536 return PTR_ERR(new_conn_state);
1537
1538 ret = drm_atomic_set_crtc_for_connector(new_conn_state,
1539 set->crtc);
1540 if (ret)
1541 return ret;
1542 }
1543
1544 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
1545
1546
1547
1548
1549
1550
1551 if (crtc == set->crtc)
1552 continue;
1553
1554 if (!new_crtc_state->connector_mask) {
1555 ret = drm_atomic_set_mode_prop_for_crtc(new_crtc_state,
1556 NULL);
1557 if (ret < 0)
1558 return ret;
1559
1560 new_crtc_state->active = false;
1561 }
1562 }
1563
1564 return 0;
1565 }
1566
1567
1568 int __drm_atomic_helper_set_config(struct drm_mode_set *set,
1569 struct drm_atomic_state *state)
1570 {
1571 struct drm_crtc_state *crtc_state;
1572 struct drm_plane_state *primary_state;
1573 struct drm_crtc *crtc = set->crtc;
1574 int hdisplay, vdisplay;
1575 int ret;
1576
1577 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1578 if (IS_ERR(crtc_state))
1579 return PTR_ERR(crtc_state);
1580
1581 primary_state = drm_atomic_get_plane_state(state, crtc->primary);
1582 if (IS_ERR(primary_state))
1583 return PTR_ERR(primary_state);
1584
1585 if (!set->mode) {
1586 WARN_ON(set->fb);
1587 WARN_ON(set->num_connectors);
1588
1589 ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
1590 if (ret != 0)
1591 return ret;
1592
1593 crtc_state->active = false;
1594
1595 ret = drm_atomic_set_crtc_for_plane(primary_state, NULL);
1596 if (ret != 0)
1597 return ret;
1598
1599 drm_atomic_set_fb_for_plane(primary_state, NULL);
1600
1601 goto commit;
1602 }
1603
1604 WARN_ON(!set->fb);
1605 WARN_ON(!set->num_connectors);
1606
1607 ret = drm_atomic_set_mode_for_crtc(crtc_state, set->mode);
1608 if (ret != 0)
1609 return ret;
1610
1611 crtc_state->active = true;
1612
1613 ret = drm_atomic_set_crtc_for_plane(primary_state, crtc);
1614 if (ret != 0)
1615 return ret;
1616
1617 drm_mode_get_hv_timing(set->mode, &hdisplay, &vdisplay);
1618
1619 drm_atomic_set_fb_for_plane(primary_state, set->fb);
1620 primary_state->crtc_x = 0;
1621 primary_state->crtc_y = 0;
1622 primary_state->crtc_w = hdisplay;
1623 primary_state->crtc_h = vdisplay;
1624 primary_state->src_x = set->x << 16;
1625 primary_state->src_y = set->y << 16;
1626 if (drm_rotation_90_or_270(primary_state->rotation)) {
1627 primary_state->src_w = vdisplay << 16;
1628 primary_state->src_h = hdisplay << 16;
1629 } else {
1630 primary_state->src_w = hdisplay << 16;
1631 primary_state->src_h = vdisplay << 16;
1632 }
1633
1634 commit:
1635 ret = update_output_state(state, set);
1636 if (ret)
1637 return ret;
1638
1639 return 0;
1640 }
1641 EXPORT_SYMBOL(__drm_atomic_helper_set_config);
1642
1643 static void drm_atomic_private_obj_print_state(struct drm_printer *p,
1644 const struct drm_private_state *state)
1645 {
1646 struct drm_private_obj *obj = state->obj;
1647
1648 if (obj->funcs->atomic_print_state)
1649 obj->funcs->atomic_print_state(p, state);
1650 }
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663 void drm_atomic_print_new_state(const struct drm_atomic_state *state,
1664 struct drm_printer *p)
1665 {
1666 struct drm_plane *plane;
1667 struct drm_plane_state *plane_state;
1668 struct drm_crtc *crtc;
1669 struct drm_crtc_state *crtc_state;
1670 struct drm_connector *connector;
1671 struct drm_connector_state *connector_state;
1672 struct drm_private_obj *obj;
1673 struct drm_private_state *obj_state;
1674 int i;
1675
1676 if (!p) {
1677 drm_err(state->dev, "invalid drm printer\n");
1678 return;
1679 }
1680
1681 drm_dbg_atomic(state->dev, "checking %p\n", state);
1682
1683 for_each_new_plane_in_state(state, plane, plane_state, i)
1684 drm_atomic_plane_print_state(p, plane_state);
1685
1686 for_each_new_crtc_in_state(state, crtc, crtc_state, i)
1687 drm_atomic_crtc_print_state(p, crtc_state);
1688
1689 for_each_new_connector_in_state(state, connector, connector_state, i)
1690 drm_atomic_connector_print_state(p, connector_state);
1691
1692 for_each_new_private_obj_in_state(state, obj, obj_state, i)
1693 drm_atomic_private_obj_print_state(p, obj_state);
1694 }
1695 EXPORT_SYMBOL(drm_atomic_print_new_state);
1696
1697 static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p,
1698 bool take_locks)
1699 {
1700 struct drm_mode_config *config = &dev->mode_config;
1701 struct drm_plane *plane;
1702 struct drm_crtc *crtc;
1703 struct drm_connector *connector;
1704 struct drm_connector_list_iter conn_iter;
1705
1706 if (!drm_drv_uses_atomic_modeset(dev))
1707 return;
1708
1709 list_for_each_entry(plane, &config->plane_list, head) {
1710 if (take_locks)
1711 drm_modeset_lock(&plane->mutex, NULL);
1712 drm_atomic_plane_print_state(p, plane->state);
1713 if (take_locks)
1714 drm_modeset_unlock(&plane->mutex);
1715 }
1716
1717 list_for_each_entry(crtc, &config->crtc_list, head) {
1718 if (take_locks)
1719 drm_modeset_lock(&crtc->mutex, NULL);
1720 drm_atomic_crtc_print_state(p, crtc->state);
1721 if (take_locks)
1722 drm_modeset_unlock(&crtc->mutex);
1723 }
1724
1725 drm_connector_list_iter_begin(dev, &conn_iter);
1726 if (take_locks)
1727 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1728 drm_for_each_connector_iter(connector, &conn_iter)
1729 drm_atomic_connector_print_state(p, connector->state);
1730 if (take_locks)
1731 drm_modeset_unlock(&dev->mode_config.connection_mutex);
1732 drm_connector_list_iter_end(&conn_iter);
1733 }
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750 void drm_state_dump(struct drm_device *dev, struct drm_printer *p)
1751 {
1752 __drm_state_dump(dev, p, false);
1753 }
1754 EXPORT_SYMBOL(drm_state_dump);
1755
1756 #ifdef CONFIG_DEBUG_FS
1757 static int drm_state_info(struct seq_file *m, void *data)
1758 {
1759 struct drm_info_node *node = (struct drm_info_node *) m->private;
1760 struct drm_device *dev = node->minor->dev;
1761 struct drm_printer p = drm_seq_file_printer(m);
1762
1763 __drm_state_dump(dev, &p, true);
1764
1765 return 0;
1766 }
1767
1768
1769 static const struct drm_info_list drm_atomic_debugfs_list[] = {
1770 {"state", drm_state_info, 0},
1771 };
1772
1773 void drm_atomic_debugfs_init(struct drm_minor *minor)
1774 {
1775 drm_debugfs_create_files(drm_atomic_debugfs_list,
1776 ARRAY_SIZE(drm_atomic_debugfs_list),
1777 minor->debugfs_root, minor);
1778 }
1779 #endif