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 #include <drm/drm_atomic.h>
0028 #include <drm/drm_atomic_state_helper.h>
0029 #include <drm/drm_blend.h>
0030 #include <drm/drm_bridge.h>
0031 #include <drm/drm_connector.h>
0032 #include <drm/drm_crtc.h>
0033 #include <drm/drm_device.h>
0034 #include <drm/drm_framebuffer.h>
0035 #include <drm/drm_plane.h>
0036 #include <drm/drm_print.h>
0037 #include <drm/drm_vblank.h>
0038 #include <drm/drm_writeback.h>
0039
0040 #include <linux/slab.h>
0041 #include <linux/dma-fence.h>
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 void
0073 __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state,
0074 struct drm_crtc *crtc)
0075 {
0076 crtc_state->crtc = crtc;
0077 }
0078 EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset);
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 void
0093 __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
0094 struct drm_crtc_state *crtc_state)
0095 {
0096 if (crtc_state)
0097 __drm_atomic_helper_crtc_state_reset(crtc_state, crtc);
0098
0099 if (drm_dev_has_vblank(crtc->dev))
0100 drm_crtc_vblank_reset(crtc);
0101
0102 crtc->state = crtc_state;
0103 }
0104 EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset);
0105
0106
0107
0108
0109
0110
0111
0112
0113 void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
0114 {
0115 struct drm_crtc_state *crtc_state =
0116 kzalloc(sizeof(*crtc->state), GFP_KERNEL);
0117
0118 if (crtc->state)
0119 crtc->funcs->atomic_destroy_state(crtc, crtc->state);
0120
0121 __drm_atomic_helper_crtc_reset(crtc, crtc_state);
0122 }
0123 EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
0134 struct drm_crtc_state *state)
0135 {
0136 memcpy(state, crtc->state, sizeof(*state));
0137
0138 if (state->mode_blob)
0139 drm_property_blob_get(state->mode_blob);
0140 if (state->degamma_lut)
0141 drm_property_blob_get(state->degamma_lut);
0142 if (state->ctm)
0143 drm_property_blob_get(state->ctm);
0144 if (state->gamma_lut)
0145 drm_property_blob_get(state->gamma_lut);
0146 state->mode_changed = false;
0147 state->active_changed = false;
0148 state->planes_changed = false;
0149 state->connectors_changed = false;
0150 state->color_mgmt_changed = false;
0151 state->zpos_changed = false;
0152 state->commit = NULL;
0153 state->event = NULL;
0154 state->async_flip = false;
0155
0156
0157 state->active = drm_atomic_crtc_effectively_active(state);
0158 state->self_refresh_active = false;
0159 }
0160 EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
0161
0162
0163
0164
0165
0166
0167
0168
0169 struct drm_crtc_state *
0170 drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
0171 {
0172 struct drm_crtc_state *state;
0173
0174 if (WARN_ON(!crtc->state))
0175 return NULL;
0176
0177 state = kmalloc(sizeof(*state), GFP_KERNEL);
0178 if (state)
0179 __drm_atomic_helper_crtc_duplicate_state(crtc, state);
0180
0181 return state;
0182 }
0183 EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193 void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
0194 {
0195 if (state->commit) {
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205 if (state->event && state->commit->abort_completion)
0206 drm_crtc_commit_put(state->commit);
0207
0208 kfree(state->commit->event);
0209 state->commit->event = NULL;
0210
0211 drm_crtc_commit_put(state->commit);
0212 }
0213
0214 drm_property_blob_put(state->mode_blob);
0215 drm_property_blob_put(state->degamma_lut);
0216 drm_property_blob_put(state->ctm);
0217 drm_property_blob_put(state->gamma_lut);
0218 }
0219 EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229 void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
0230 struct drm_crtc_state *state)
0231 {
0232 __drm_atomic_helper_crtc_destroy_state(state);
0233 kfree(state);
0234 }
0235 EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245 void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
0246 struct drm_plane *plane)
0247 {
0248 u64 val;
0249
0250 plane_state->plane = plane;
0251 plane_state->rotation = DRM_MODE_ROTATE_0;
0252
0253 plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
0254 plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
0255
0256 if (plane->color_encoding_property) {
0257 if (!drm_object_property_get_default_value(&plane->base,
0258 plane->color_encoding_property,
0259 &val))
0260 plane_state->color_encoding = val;
0261 }
0262
0263 if (plane->color_range_property) {
0264 if (!drm_object_property_get_default_value(&plane->base,
0265 plane->color_range_property,
0266 &val))
0267 plane_state->color_range = val;
0268 }
0269
0270 if (plane->zpos_property) {
0271 if (!drm_object_property_get_default_value(&plane->base,
0272 plane->zpos_property,
0273 &val)) {
0274 plane_state->zpos = val;
0275 plane_state->normalized_zpos = val;
0276 }
0277 }
0278 }
0279 EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset);
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293 void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
0294 struct drm_plane_state *plane_state)
0295 {
0296 if (plane_state)
0297 __drm_atomic_helper_plane_state_reset(plane_state, plane);
0298
0299 plane->state = plane_state;
0300 }
0301 EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
0302
0303
0304
0305
0306
0307
0308
0309
0310 void drm_atomic_helper_plane_reset(struct drm_plane *plane)
0311 {
0312 if (plane->state)
0313 __drm_atomic_helper_plane_destroy_state(plane->state);
0314
0315 kfree(plane->state);
0316 plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
0317 if (plane->state)
0318 __drm_atomic_helper_plane_reset(plane, plane->state);
0319 }
0320 EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330 void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
0331 struct drm_plane_state *state)
0332 {
0333 memcpy(state, plane->state, sizeof(*state));
0334
0335 if (state->fb)
0336 drm_framebuffer_get(state->fb);
0337
0338 state->fence = NULL;
0339 state->commit = NULL;
0340 state->fb_damage_clips = NULL;
0341 }
0342 EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
0343
0344
0345
0346
0347
0348
0349
0350
0351 struct drm_plane_state *
0352 drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
0353 {
0354 struct drm_plane_state *state;
0355
0356 if (WARN_ON(!plane->state))
0357 return NULL;
0358
0359 state = kmalloc(sizeof(*state), GFP_KERNEL);
0360 if (state)
0361 __drm_atomic_helper_plane_duplicate_state(plane, state);
0362
0363 return state;
0364 }
0365 EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375 void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
0376 {
0377 if (state->fb)
0378 drm_framebuffer_put(state->fb);
0379
0380 if (state->fence)
0381 dma_fence_put(state->fence);
0382
0383 if (state->commit)
0384 drm_crtc_commit_put(state->commit);
0385
0386 drm_property_blob_put(state->fb_damage_clips);
0387 }
0388 EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398 void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
0399 struct drm_plane_state *state)
0400 {
0401 __drm_atomic_helper_plane_destroy_state(state);
0402 kfree(state);
0403 }
0404 EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414 void
0415 __drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_state,
0416 struct drm_connector *connector)
0417 {
0418 conn_state->connector = connector;
0419 }
0420 EXPORT_SYMBOL(__drm_atomic_helper_connector_state_reset);
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434 void
0435 __drm_atomic_helper_connector_reset(struct drm_connector *connector,
0436 struct drm_connector_state *conn_state)
0437 {
0438 if (conn_state)
0439 __drm_atomic_helper_connector_state_reset(conn_state, connector);
0440
0441 connector->state = conn_state;
0442 }
0443 EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453 void drm_atomic_helper_connector_reset(struct drm_connector *connector)
0454 {
0455 struct drm_connector_state *conn_state =
0456 kzalloc(sizeof(*conn_state), GFP_KERNEL);
0457
0458 if (connector->state)
0459 __drm_atomic_helper_connector_destroy_state(connector->state);
0460
0461 kfree(connector->state);
0462 __drm_atomic_helper_connector_reset(connector, conn_state);
0463 }
0464 EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
0465
0466
0467
0468
0469
0470
0471
0472 void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
0473 {
0474 struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
0475 struct drm_connector_state *state = connector->state;
0476
0477 state->tv.margins.left = cmdline->tv_margins.left;
0478 state->tv.margins.right = cmdline->tv_margins.right;
0479 state->tv.margins.top = cmdline->tv_margins.top;
0480 state->tv.margins.bottom = cmdline->tv_margins.bottom;
0481 }
0482 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492 void
0493 __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
0494 struct drm_connector_state *state)
0495 {
0496 memcpy(state, connector->state, sizeof(*state));
0497 if (state->crtc)
0498 drm_connector_get(connector);
0499 state->commit = NULL;
0500
0501 if (state->hdr_output_metadata)
0502 drm_property_blob_get(state->hdr_output_metadata);
0503
0504
0505 state->writeback_job = NULL;
0506 }
0507 EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
0508
0509
0510
0511
0512
0513
0514
0515
0516 struct drm_connector_state *
0517 drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
0518 {
0519 struct drm_connector_state *state;
0520
0521 if (WARN_ON(!connector->state))
0522 return NULL;
0523
0524 state = kmalloc(sizeof(*state), GFP_KERNEL);
0525 if (state)
0526 __drm_atomic_helper_connector_duplicate_state(connector, state);
0527
0528 return state;
0529 }
0530 EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540 void
0541 __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
0542 {
0543 if (state->crtc)
0544 drm_connector_put(state->connector);
0545
0546 if (state->commit)
0547 drm_crtc_commit_put(state->commit);
0548
0549 if (state->writeback_job)
0550 drm_writeback_cleanup_job(state->writeback_job);
0551
0552 drm_property_blob_put(state->hdr_output_metadata);
0553 }
0554 EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564 void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
0565 struct drm_connector_state *state)
0566 {
0567 __drm_atomic_helper_connector_destroy_state(state);
0568 kfree(state);
0569 }
0570 EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580 void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
0581 struct drm_private_state *state)
0582 {
0583 memcpy(state, obj->state, sizeof(*state));
0584 }
0585 EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state);
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595 void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge,
0596 struct drm_bridge_state *state)
0597 {
0598 __drm_atomic_helper_private_obj_duplicate_state(&bridge->base,
0599 &state->base);
0600 state->bridge = bridge;
0601 }
0602 EXPORT_SYMBOL(__drm_atomic_helper_bridge_duplicate_state);
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613 struct drm_bridge_state *
0614 drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge)
0615 {
0616 struct drm_bridge_state *new;
0617
0618 if (WARN_ON(!bridge->base.state))
0619 return NULL;
0620
0621 new = kzalloc(sizeof(*new), GFP_KERNEL);
0622 if (new)
0623 __drm_atomic_helper_bridge_duplicate_state(bridge, new);
0624
0625 return new;
0626 }
0627 EXPORT_SYMBOL(drm_atomic_helper_bridge_duplicate_state);
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640 void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge,
0641 struct drm_bridge_state *state)
0642 {
0643 kfree(state);
0644 }
0645 EXPORT_SYMBOL(drm_atomic_helper_bridge_destroy_state);
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657 void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge,
0658 struct drm_bridge_state *state)
0659 {
0660 memset(state, 0, sizeof(*state));
0661 state->bridge = bridge;
0662 }
0663 EXPORT_SYMBOL(__drm_atomic_helper_bridge_reset);
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674 struct drm_bridge_state *
0675 drm_atomic_helper_bridge_reset(struct drm_bridge *bridge)
0676 {
0677 struct drm_bridge_state *bridge_state;
0678
0679 bridge_state = kzalloc(sizeof(*bridge_state), GFP_KERNEL);
0680 if (!bridge_state)
0681 return ERR_PTR(-ENOMEM);
0682
0683 __drm_atomic_helper_bridge_reset(bridge, bridge_state);
0684 return bridge_state;
0685 }
0686 EXPORT_SYMBOL(drm_atomic_helper_bridge_reset);