Rev 6660 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6660 | Rev 6937 | ||
---|---|---|---|
Line 63... | Line 63... | ||
63 | /* TODO legacy paths should maybe do a better job about |
63 | /* TODO legacy paths should maybe do a better job about |
64 | * setting this appropriately? |
64 | * setting this appropriately? |
65 | */ |
65 | */ |
66 | state->allow_modeset = true; |
66 | state->allow_modeset = true; |
Line 67... | Line -... | ||
67 | - | ||
68 | state->num_connector = ACCESS_ONCE(dev->mode_config.num_connector); |
- | |
69 | 67 | ||
70 | state->crtcs = kcalloc(dev->mode_config.num_crtc, |
68 | state->crtcs = kcalloc(dev->mode_config.num_crtc, |
71 | sizeof(*state->crtcs), GFP_KERNEL); |
69 | sizeof(*state->crtcs), GFP_KERNEL); |
72 | if (!state->crtcs) |
70 | if (!state->crtcs) |
73 | goto fail; |
71 | goto fail; |
Line 81... | Line 79... | ||
81 | goto fail; |
79 | goto fail; |
82 | state->plane_states = kcalloc(dev->mode_config.num_total_plane, |
80 | state->plane_states = kcalloc(dev->mode_config.num_total_plane, |
83 | sizeof(*state->plane_states), GFP_KERNEL); |
81 | sizeof(*state->plane_states), GFP_KERNEL); |
84 | if (!state->plane_states) |
82 | if (!state->plane_states) |
85 | goto fail; |
83 | goto fail; |
86 | state->connectors = kcalloc(state->num_connector, |
- | |
87 | sizeof(*state->connectors), |
- | |
88 | GFP_KERNEL); |
- | |
89 | if (!state->connectors) |
- | |
90 | goto fail; |
- | |
91 | state->connector_states = kcalloc(state->num_connector, |
- | |
92 | sizeof(*state->connector_states), |
- | |
93 | GFP_KERNEL); |
- | |
94 | if (!state->connector_states) |
- | |
95 | goto fail; |
- | |
Line 96... | Line 84... | ||
96 | 84 | ||
Line 97... | Line 85... | ||
97 | state->dev = dev; |
85 | state->dev = dev; |
Line 286... | Line 274... | ||
286 | 274 | ||
287 | state->crtc_states[index] = crtc_state; |
275 | state->crtc_states[index] = crtc_state; |
288 | state->crtcs[index] = crtc; |
276 | state->crtcs[index] = crtc; |
Line 289... | Line 277... | ||
289 | crtc_state->state = state; |
277 | crtc_state->state = state; |
290 | 278 | ||
Line 291... | Line 279... | ||
291 | DRM_DEBUG_ATOMIC("Added [CRTC:%d] %p state to %p\n", |
279 | DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n", |
292 | crtc->base.id, crtc_state, state); |
280 | crtc->base.id, crtc->name, crtc_state, state); |
293 | 281 | ||
Line 314... | Line 302... | ||
314 | 302 | ||
315 | /* Early return for no change. */ |
303 | /* Early return for no change. */ |
316 | if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0) |
304 | if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0) |
Line 317... | Line -... | ||
317 | return 0; |
- | |
318 | 305 | return 0; |
|
319 | if (state->mode_blob) |
306 | |
Line 320... | Line 307... | ||
320 | drm_property_unreference_blob(state->mode_blob); |
307 | drm_property_unreference_blob(state->mode_blob); |
321 | state->mode_blob = NULL; |
308 | state->mode_blob = NULL; |
Line 361... | Line 348... | ||
361 | struct drm_property_blob *blob) |
348 | struct drm_property_blob *blob) |
362 | { |
349 | { |
363 | if (blob == state->mode_blob) |
350 | if (blob == state->mode_blob) |
364 | return 0; |
351 | return 0; |
Line 365... | Line -... | ||
365 | - | ||
366 | if (state->mode_blob) |
352 | |
367 | drm_property_unreference_blob(state->mode_blob); |
353 | drm_property_unreference_blob(state->mode_blob); |
Line 368... | Line -... | ||
368 | state->mode_blob = NULL; |
- | |
369 | - | ||
370 | memset(&state->mode, 0, sizeof(state->mode)); |
354 | state->mode_blob = NULL; |
371 | 355 | ||
372 | if (blob) { |
356 | if (blob) { |
373 | if (blob->length != sizeof(struct drm_mode_modeinfo) || |
357 | if (blob->length != sizeof(struct drm_mode_modeinfo) || |
374 | drm_mode_convert_umode(&state->mode, |
358 | drm_mode_convert_umode(&state->mode, |
Line 379... | Line 363... | ||
379 | state->mode_blob = drm_property_reference_blob(blob); |
363 | state->mode_blob = drm_property_reference_blob(blob); |
380 | state->enable = true; |
364 | state->enable = true; |
381 | DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n", |
365 | DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n", |
382 | state->mode.name, state); |
366 | state->mode.name, state); |
383 | } else { |
367 | } else { |
- | 368 | memset(&state->mode, 0, sizeof(state->mode)); |
|
384 | state->enable = false; |
369 | state->enable = false; |
385 | DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n", |
370 | DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n", |
386 | state); |
371 | state); |
387 | } |
372 | } |
Line 418... | Line 403... | ||
418 | state->active = val; |
403 | state->active = val; |
419 | else if (property == config->prop_mode_id) { |
404 | else if (property == config->prop_mode_id) { |
420 | struct drm_property_blob *mode = |
405 | struct drm_property_blob *mode = |
421 | drm_property_lookup_blob(dev, val); |
406 | drm_property_lookup_blob(dev, val); |
422 | ret = drm_atomic_set_mode_prop_for_crtc(state, mode); |
407 | ret = drm_atomic_set_mode_prop_for_crtc(state, mode); |
423 | if (mode) |
- | |
424 | drm_property_unreference_blob(mode); |
408 | drm_property_unreference_blob(mode); |
425 | return ret; |
409 | return ret; |
426 | } |
410 | } |
427 | else if (crtc->funcs->atomic_set_property) |
411 | else if (crtc->funcs->atomic_set_property) |
428 | return crtc->funcs->atomic_set_property(crtc, state, property, val); |
412 | return crtc->funcs->atomic_set_property(crtc, state, property, val); |
Line 431... | Line 415... | ||
431 | 415 | ||
432 | return 0; |
416 | return 0; |
433 | } |
417 | } |
Line 434... | Line 418... | ||
434 | EXPORT_SYMBOL(drm_atomic_crtc_set_property); |
418 | EXPORT_SYMBOL(drm_atomic_crtc_set_property); |
- | 419 | ||
- | 420 | /** |
|
- | 421 | * drm_atomic_crtc_get_property - get property value from CRTC state |
|
- | 422 | * @crtc: the drm CRTC to set a property on |
|
- | 423 | * @state: the state object to get the property value from |
|
- | 424 | * @property: the property to set |
|
435 | 425 | * @val: return location for the property value |
|
436 | /* |
426 | * |
437 | * This function handles generic/core properties and calls out to |
427 | * This function handles generic/core properties and calls out to |
438 | * driver's ->atomic_get_property() for driver properties. To ensure |
428 | * driver's ->atomic_get_property() for driver properties. To ensure |
- | 429 | * consistent behavior you must call this function rather than the |
|
- | 430 | * driver hook directly. |
|
- | 431 | * |
|
439 | * consistent behavior you must call this function rather than the |
432 | * RETURNS: |
440 | * driver hook directly. |
433 | * Zero on success, error code on failure |
441 | */ |
434 | */ |
442 | static int |
435 | static int |
443 | drm_atomic_crtc_get_property(struct drm_crtc *crtc, |
436 | drm_atomic_crtc_get_property(struct drm_crtc *crtc, |
Line 479... | Line 472... | ||
479 | * |
472 | * |
480 | * TODO: Add generic modeset state checks once we support those. |
473 | * TODO: Add generic modeset state checks once we support those. |
481 | */ |
474 | */ |
Line 482... | Line 475... | ||
482 | 475 | ||
483 | if (state->active && !state->enable) { |
476 | if (state->active && !state->enable) { |
484 | DRM_DEBUG_ATOMIC("[CRTC:%d] active without enabled\n", |
477 | DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active without enabled\n", |
485 | crtc->base.id); |
478 | crtc->base.id, crtc->name); |
486 | return -EINVAL; |
479 | return -EINVAL; |
Line 487... | Line 480... | ||
487 | } |
480 | } |
488 | 481 | ||
489 | /* The state->enable vs. state->mode_blob checks can be WARN_ON, |
482 | /* The state->enable vs. state->mode_blob checks can be WARN_ON, |
490 | * as this is a kernel-internal detail that userspace should never |
483 | * as this is a kernel-internal detail that userspace should never |
491 | * be able to trigger. */ |
484 | * be able to trigger. */ |
492 | if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) && |
485 | if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) && |
493 | WARN_ON(state->enable && !state->mode_blob)) { |
486 | WARN_ON(state->enable && !state->mode_blob)) { |
494 | DRM_DEBUG_ATOMIC("[CRTC:%d] enabled without mode blob\n", |
487 | DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled without mode blob\n", |
495 | crtc->base.id); |
488 | crtc->base.id, crtc->name); |
Line 496... | Line 489... | ||
496 | return -EINVAL; |
489 | return -EINVAL; |
497 | } |
490 | } |
498 | 491 | ||
- | 492 | if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) && |
|
- | 493 | WARN_ON(!state->enable && state->mode_blob)) { |
|
- | 494 | DRM_DEBUG_ATOMIC("[CRTC:%d:%s] disabled with mode blob\n", |
|
- | 495 | crtc->base.id, crtc->name); |
|
- | 496 | return -EINVAL; |
|
- | 497 | } |
|
- | 498 | ||
- | 499 | /* |
|
- | 500 | * Reject event generation for when a CRTC is off and stays off. |
|
- | 501 | * It wouldn't be hard to implement this, but userspace has a track |
|
- | 502 | * record of happily burning through 100% cpu (or worse, crash) when the |
|
- | 503 | * display pipe is suspended. To avoid all that fun just reject updates |
|
- | 504 | * that ask for events since likely that indicates a bug in the |
|
- | 505 | * compositor's drawing loop. This is consistent with the vblank IOCTL |
|
- | 506 | * and legacy page_flip IOCTL which also reject service on a disabled |
|
- | 507 | * pipe. |
|
499 | if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) && |
508 | */ |
500 | WARN_ON(!state->enable && state->mode_blob)) { |
509 | if (state->event && !state->active && !crtc->state->active) { |
501 | DRM_DEBUG_ATOMIC("[CRTC:%d] disabled with mode blob\n", |
510 | DRM_DEBUG_ATOMIC("[CRTC:%d] requesting event but off\n", |
Line 502... | Line 511... | ||
502 | crtc->base.id); |
511 | crtc->base.id); |
Line 542... | Line 551... | ||
542 | 551 | ||
543 | state->plane_states[index] = plane_state; |
552 | state->plane_states[index] = plane_state; |
544 | state->planes[index] = plane; |
553 | state->planes[index] = plane; |
Line 545... | Line 554... | ||
545 | plane_state->state = state; |
554 | plane_state->state = state; |
546 | 555 | ||
Line 547... | Line 556... | ||
547 | DRM_DEBUG_ATOMIC("Added [PLANE:%d] %p state to %p\n", |
556 | DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n", |
548 | plane->base.id, plane_state, state); |
557 | plane->base.id, plane->name, plane_state, state); |
Line 549... | Line 558... | ||
549 | 558 | ||
Line 618... | Line 627... | ||
618 | 627 | ||
619 | return 0; |
628 | return 0; |
620 | } |
629 | } |
Line 621... | Line 630... | ||
621 | EXPORT_SYMBOL(drm_atomic_plane_set_property); |
630 | EXPORT_SYMBOL(drm_atomic_plane_set_property); |
- | 631 | ||
- | 632 | /** |
|
- | 633 | * drm_atomic_plane_get_property - get property value from plane state |
|
- | 634 | * @plane: the drm plane to set a property on |
|
- | 635 | * @state: the state object to get the property value from |
|
- | 636 | * @property: the property to set |
|
622 | 637 | * @val: return location for the property value |
|
623 | /* |
638 | * |
624 | * This function handles generic/core properties and calls out to |
639 | * This function handles generic/core properties and calls out to |
625 | * driver's ->atomic_get_property() for driver properties. To ensure |
640 | * driver's ->atomic_get_property() for driver properties. To ensure |
- | 641 | * consistent behavior you must call this function rather than the |
|
- | 642 | * driver hook directly. |
|
- | 643 | * |
|
626 | * consistent behavior you must call this function rather than the |
644 | * RETURNS: |
627 | * driver hook directly. |
645 | * Zero on success, error code on failure |
628 | */ |
646 | */ |
629 | static int |
647 | static int |
630 | drm_atomic_plane_get_property(struct drm_plane *plane, |
648 | drm_atomic_plane_get_property(struct drm_plane *plane, |
Line 754... | Line 772... | ||
754 | state->src_y >> 16, ((state->src_y & 0xffff) * 15625) >> 10); |
772 | state->src_y >> 16, ((state->src_y & 0xffff) * 15625) >> 10); |
755 | return -ENOSPC; |
773 | return -ENOSPC; |
756 | } |
774 | } |
Line 757... | Line 775... | ||
757 | 775 | ||
758 | if (plane_switching_crtc(state->state, plane, state)) { |
776 | if (plane_switching_crtc(state->state, plane, state)) { |
759 | DRM_DEBUG_ATOMIC("[PLANE:%d] switching CRTC directly\n", |
777 | DRM_DEBUG_ATOMIC("[PLANE:%d:%s] switching CRTC directly\n", |
760 | plane->base.id); |
778 | plane->base.id, plane->name); |
761 | return -EINVAL; |
779 | return -EINVAL; |
Line 762... | Line 780... | ||
762 | } |
780 | } |
763 | 781 | ||
Line 791... | Line 809... | ||
791 | if (ret) |
809 | if (ret) |
792 | return ERR_PTR(ret); |
810 | return ERR_PTR(ret); |
Line 793... | Line 811... | ||
793 | 811 | ||
Line 794... | Line -... | ||
794 | index = drm_connector_index(connector); |
- | |
795 | - | ||
796 | /* |
- | |
797 | * Construction of atomic state updates can race with a connector |
- | |
798 | * hot-add which might overflow. In this case flip the table and just |
- | |
799 | * restart the entire ioctl - no one is fast enough to livelock a cpu |
- | |
800 | * with physical hotplug events anyway. |
- | |
801 | * |
- | |
802 | * Note that we only grab the indexes once we have the right lock to |
- | |
803 | * prevent hotplug/unplugging of connectors. So removal is no problem, |
- | |
804 | * at most the array is a bit too large. |
812 | index = drm_connector_index(connector); |
- | 813 | ||
- | 814 | if (index >= state->num_connector) { |
|
- | 815 | struct drm_connector **c; |
|
- | 816 | struct drm_connector_state **cs; |
|
- | 817 | int alloc = max(index + 1, config->num_connector); |
|
- | 818 | ||
- | 819 | c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL); |
|
- | 820 | if (!c) |
|
- | 821 | return ERR_PTR(-ENOMEM); |
|
- | 822 | ||
805 | */ |
823 | state->connectors = c; |
- | 824 | memset(&state->connectors[state->num_connector], 0, |
|
- | 825 | sizeof(*state->connectors) * (alloc - state->num_connector)); |
|
- | 826 | ||
806 | if (index >= state->num_connector) { |
827 | cs = krealloc(state->connector_states, alloc * sizeof(*state->connector_states), GFP_KERNEL); |
- | 828 | if (!cs) |
|
- | 829 | return ERR_PTR(-ENOMEM); |
|
- | 830 | ||
- | 831 | state->connector_states = cs; |
|
- | 832 | memset(&state->connector_states[state->num_connector], 0, |
|
807 | DRM_DEBUG_ATOMIC("Hot-added connector would overflow state array, restarting\n"); |
833 | sizeof(*state->connector_states) * (alloc - state->num_connector)); |
Line 808... | Line 834... | ||
808 | return ERR_PTR(-EAGAIN); |
834 | state->num_connector = alloc; |
809 | } |
835 | } |
Line 874... | Line 900... | ||
874 | return -EINVAL; |
900 | return -EINVAL; |
875 | } |
901 | } |
876 | } |
902 | } |
877 | EXPORT_SYMBOL(drm_atomic_connector_set_property); |
903 | EXPORT_SYMBOL(drm_atomic_connector_set_property); |
Line 878... | Line 904... | ||
878 | 904 | ||
- | 905 | /** |
|
- | 906 | * drm_atomic_connector_get_property - get property value from connector state |
|
- | 907 | * @connector: the drm connector to set a property on |
|
- | 908 | * @state: the state object to get the property value from |
|
- | 909 | * @property: the property to set |
|
- | 910 | * @val: return location for the property value |
|
879 | /* |
911 | * |
880 | * This function handles generic/core properties and calls out to |
912 | * This function handles generic/core properties and calls out to |
881 | * driver's ->atomic_get_property() for driver properties. To ensure |
913 | * driver's ->atomic_get_property() for driver properties. To ensure |
882 | * consistent behavior you must call this function rather than the |
914 | * consistent behavior you must call this function rather than the |
- | 915 | * driver hook directly. |
|
- | 916 | * |
|
- | 917 | * RETURNS: |
|
883 | * driver hook directly. |
918 | * Zero on success, error code on failure |
884 | */ |
919 | */ |
885 | static int |
920 | static int |
886 | drm_atomic_connector_get_property(struct drm_connector *connector, |
921 | drm_atomic_connector_get_property(struct drm_connector *connector, |
887 | const struct drm_connector_state *state, |
922 | const struct drm_connector_state *state, |
Line 979... | Line 1014... | ||
979 | return PTR_ERR(crtc_state); |
1014 | return PTR_ERR(crtc_state); |
980 | crtc_state->plane_mask |= (1 << drm_plane_index(plane)); |
1015 | crtc_state->plane_mask |= (1 << drm_plane_index(plane)); |
981 | } |
1016 | } |
Line 982... | Line 1017... | ||
982 | 1017 | ||
983 | if (crtc) |
1018 | if (crtc) |
984 | DRM_DEBUG_ATOMIC("Link plane state %p to [CRTC:%d]\n", |
1019 | DRM_DEBUG_ATOMIC("Link plane state %p to [CRTC:%d:%s]\n", |
985 | plane_state, crtc->base.id); |
1020 | plane_state, crtc->base.id, crtc->name); |
986 | else |
1021 | else |
987 | DRM_DEBUG_ATOMIC("Link plane state %p to [NOCRTC]\n", |
1022 | DRM_DEBUG_ATOMIC("Link plane state %p to [NOCRTC]\n", |
Line 988... | Line 1023... | ||
988 | plane_state); |
1023 | plane_state); |
Line 1038... | Line 1073... | ||
1038 | drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, |
1073 | drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, |
1039 | struct drm_crtc *crtc) |
1074 | struct drm_crtc *crtc) |
1040 | { |
1075 | { |
1041 | struct drm_crtc_state *crtc_state; |
1076 | struct drm_crtc_state *crtc_state; |
Line -... | Line 1077... | ||
- | 1077 | ||
- | 1078 | if (conn_state->crtc && conn_state->crtc != crtc) { |
|
- | 1079 | crtc_state = drm_atomic_get_existing_crtc_state(conn_state->state, |
|
- | 1080 | conn_state->crtc); |
|
- | 1081 | ||
- | 1082 | crtc_state->connector_mask &= |
|
- | 1083 | ~(1 << drm_connector_index(conn_state->connector)); |
|
- | 1084 | } |
|
1042 | 1085 | ||
1043 | if (crtc) { |
1086 | if (crtc) { |
1044 | crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc); |
1087 | crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc); |
1045 | if (IS_ERR(crtc_state)) |
1088 | if (IS_ERR(crtc_state)) |
- | 1089 | return PTR_ERR(crtc_state); |
|
- | 1090 | ||
- | 1091 | crtc_state->connector_mask |= |
|
1046 | return PTR_ERR(crtc_state); |
1092 | 1 << drm_connector_index(conn_state->connector); |
Line 1047... | Line 1093... | ||
1047 | } |
1093 | } |
Line 1048... | Line 1094... | ||
1048 | 1094 | ||
1049 | conn_state->crtc = crtc; |
1095 | conn_state->crtc = crtc; |
1050 | 1096 | ||
1051 | if (crtc) |
1097 | if (crtc) |
1052 | DRM_DEBUG_ATOMIC("Link connector state %p to [CRTC:%d]\n", |
1098 | DRM_DEBUG_ATOMIC("Link connector state %p to [CRTC:%d:%s]\n", |
1053 | conn_state, crtc->base.id); |
1099 | conn_state, crtc->base.id, crtc->name); |
Line 1054... | Line 1100... | ||
1054 | else |
1100 | else |
Line 1087... | Line 1133... | ||
1087 | 1133 | ||
1088 | ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx); |
1134 | ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx); |
1089 | if (ret) |
1135 | if (ret) |
Line 1090... | Line 1136... | ||
1090 | return ret; |
1136 | return ret; |
1091 | 1137 | ||
Line 1092... | Line 1138... | ||
1092 | DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d] to %p\n", |
1138 | DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d:%s] to %p\n", |
1093 | crtc->base.id, state); |
1139 | crtc->base.id, crtc->name, state); |
1094 | 1140 | ||
1095 | /* |
1141 | /* |
Line 1147... | Line 1193... | ||
1147 | return 0; |
1193 | return 0; |
1148 | } |
1194 | } |
1149 | EXPORT_SYMBOL(drm_atomic_add_affected_planes); |
1195 | EXPORT_SYMBOL(drm_atomic_add_affected_planes); |
Line 1150... | Line 1196... | ||
1150 | 1196 | ||
1151 | /** |
- | |
1152 | * drm_atomic_connectors_for_crtc - count number of connected outputs |
- | |
1153 | * @state: atomic state |
- | |
1154 | * @crtc: DRM crtc |
- | |
1155 | * |
- | |
1156 | * This function counts all connectors which will be connected to @crtc |
- | |
1157 | * according to @state. Useful to recompute the enable state for @crtc. |
- | |
1158 | */ |
- | |
1159 | int |
- | |
1160 | drm_atomic_connectors_for_crtc(struct drm_atomic_state *state, |
- | |
1161 | struct drm_crtc *crtc) |
- | |
1162 | { |
- | |
1163 | struct drm_connector *connector; |
- | |
1164 | struct drm_connector_state *conn_state; |
- | |
1165 | - | ||
1166 | int i, num_connected_connectors = 0; |
- | |
1167 | - | ||
1168 | for_each_connector_in_state(state, connector, conn_state, i) { |
- | |
1169 | if (conn_state->crtc == crtc) |
- | |
1170 | num_connected_connectors++; |
- | |
1171 | } |
- | |
1172 | - | ||
1173 | DRM_DEBUG_ATOMIC("State %p has %i connectors for [CRTC:%d]\n", |
- | |
1174 | state, num_connected_connectors, crtc->base.id); |
- | |
1175 | - | ||
1176 | return num_connected_connectors; |
- | |
1177 | } |
- | |
1178 | EXPORT_SYMBOL(drm_atomic_connectors_for_crtc); |
- | |
1179 | - | ||
1180 | /** |
1197 | /** |
1181 | * drm_atomic_legacy_backoff - locking backoff for legacy ioctls |
1198 | * drm_atomic_legacy_backoff - locking backoff for legacy ioctls |
1182 | * @state: atomic state |
1199 | * @state: atomic state |
1183 | * |
1200 | * |
1184 | * This function should be used by legacy entry points which don't understand |
1201 | * This function should be used by legacy entry points which don't understand |
Line 1190... | Line 1207... | ||
1190 | int ret; |
1207 | int ret; |
Line 1191... | Line 1208... | ||
1191 | 1208 | ||
1192 | retry: |
1209 | retry: |
Line 1193... | Line -... | ||
1193 | drm_modeset_backoff(state->acquire_ctx); |
- | |
1194 | - | ||
1195 | ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex, |
- | |
1196 | state->acquire_ctx); |
- | |
1197 | if (ret) |
1210 | drm_modeset_backoff(state->acquire_ctx); |
1198 | goto retry; |
- | |
1199 | ret = drm_modeset_lock_all_crtcs(state->dev, |
1211 | |
1200 | state->acquire_ctx); |
1212 | ret = drm_modeset_lock_all_ctx(state->dev, state->acquire_ctx); |
1201 | if (ret) |
1213 | if (ret) |
1202 | goto retry; |
1214 | goto retry; |
Line 1227... | Line 1239... | ||
1227 | DRM_DEBUG_ATOMIC("checking %p\n", state); |
1239 | DRM_DEBUG_ATOMIC("checking %p\n", state); |
Line 1228... | Line 1240... | ||
1228 | 1240 | ||
1229 | for_each_plane_in_state(state, plane, plane_state, i) { |
1241 | for_each_plane_in_state(state, plane, plane_state, i) { |
1230 | ret = drm_atomic_plane_check(plane, plane_state); |
1242 | ret = drm_atomic_plane_check(plane, plane_state); |
1231 | if (ret) { |
1243 | if (ret) { |
1232 | DRM_DEBUG_ATOMIC("[PLANE:%d] atomic core check failed\n", |
1244 | DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic core check failed\n", |
1233 | plane->base.id); |
1245 | plane->base.id, plane->name); |
1234 | return ret; |
1246 | return ret; |
1235 | } |
1247 | } |
Line 1236... | Line 1248... | ||
1236 | } |
1248 | } |
1237 | 1249 | ||
1238 | for_each_crtc_in_state(state, crtc, crtc_state, i) { |
1250 | for_each_crtc_in_state(state, crtc, crtc_state, i) { |
1239 | ret = drm_atomic_crtc_check(crtc, crtc_state); |
1251 | ret = drm_atomic_crtc_check(crtc, crtc_state); |
1240 | if (ret) { |
1252 | if (ret) { |
1241 | DRM_DEBUG_ATOMIC("[CRTC:%d] atomic core check failed\n", |
1253 | DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic core check failed\n", |
1242 | crtc->base.id); |
1254 | crtc->base.id, crtc->name); |
1243 | return ret; |
1255 | return ret; |
Line 1244... | Line 1256... | ||
1244 | } |
1256 | } |
1245 | } |
1257 | } |
Line 1246... | Line 1258... | ||
1246 | 1258 | ||
1247 | if (config->funcs->atomic_check) |
1259 | if (config->funcs->atomic_check) |
1248 | ret = config->funcs->atomic_check(state->dev, state); |
1260 | ret = config->funcs->atomic_check(state->dev, state); |
1249 | 1261 | ||
1250 | if (!state->allow_modeset) { |
1262 | if (!state->allow_modeset) { |
1251 | for_each_crtc_in_state(state, crtc, crtc_state, i) { |
1263 | for_each_crtc_in_state(state, crtc, crtc_state, i) { |
1252 | if (drm_atomic_crtc_needs_modeset(crtc_state)) { |
1264 | if (drm_atomic_crtc_needs_modeset(crtc_state)) { |
1253 | DRM_DEBUG_ATOMIC("[CRTC:%d] requires full modeset\n", |
1265 | DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requires full modeset\n", |
1254 | crtc->base.id); |
1266 | crtc->base.id, crtc->name); |
Line 1432... | Line 1444... | ||
1432 | drm_property_change_valid_put(prop, ref); |
1444 | drm_property_change_valid_put(prop, ref); |
1433 | return ret; |
1445 | return ret; |
1434 | } |
1446 | } |
Line 1435... | Line 1447... | ||
1435 | 1447 | ||
1436 | /** |
1448 | /** |
1437 | * drm_atomic_update_old_fb -- Unset old_fb pointers and set plane->fb pointers. |
1449 | * drm_atomic_clean_old_fb -- Unset old_fb pointers and set plane->fb pointers. |
1438 | * |
1450 | * |
1439 | * @dev: drm device to check. |
1451 | * @dev: drm device to check. |
1440 | * @plane_mask: plane mask for planes that were updated. |
1452 | * @plane_mask: plane mask for planes that were updated. |
1441 | * @ret: return value, can be -EDEADLK for a retry. |
1453 | * @ret: return value, can be -EDEADLK for a retry. |