aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_atomic_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_atomic_helper.c')
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c99
1 files changed, 70 insertions, 29 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 01d936b7be43..9203f3e933f7 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -322,10 +322,11 @@ update_connector_routing(struct drm_atomic_state *state,
322 } 322 }
323 323
324 if (!drm_encoder_crtc_ok(new_encoder, connector_state->crtc)) { 324 if (!drm_encoder_crtc_ok(new_encoder, connector_state->crtc)) {
325 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] incompatible with [CRTC:%d]\n", 325 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] incompatible with [CRTC:%d:%s]\n",
326 new_encoder->base.id, 326 new_encoder->base.id,
327 new_encoder->name, 327 new_encoder->name,
328 connector_state->crtc->base.id); 328 connector_state->crtc->base.id,
329 connector_state->crtc->name);
329 return -EINVAL; 330 return -EINVAL;
330 } 331 }
331 332
@@ -1119,7 +1120,8 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
1119 drm_crtc_vblank_count(crtc), 1120 drm_crtc_vblank_count(crtc),
1120 msecs_to_jiffies(50)); 1121 msecs_to_jiffies(50));
1121 1122
1122 WARN(!ret, "[CRTC:%d] vblank wait timed out\n", crtc->base.id); 1123 WARN(!ret, "[CRTC:%d:%s] vblank wait timed out\n",
1124 crtc->base.id, crtc->name);
1123 1125
1124 drm_crtc_vblank_put(crtc); 1126 drm_crtc_vblank_put(crtc);
1125 } 1127 }
@@ -1170,7 +1172,7 @@ EXPORT_SYMBOL(drm_atomic_helper_commit_tail);
1170static void commit_tail(struct drm_atomic_state *old_state) 1172static void commit_tail(struct drm_atomic_state *old_state)
1171{ 1173{
1172 struct drm_device *dev = old_state->dev; 1174 struct drm_device *dev = old_state->dev;
1173 struct drm_mode_config_helper_funcs *funcs; 1175 const struct drm_mode_config_helper_funcs *funcs;
1174 1176
1175 funcs = dev->mode_config.helper_private; 1177 funcs = dev->mode_config.helper_private;
1176 1178
@@ -1977,11 +1979,11 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
1977 int i; 1979 int i;
1978 long ret; 1980 long ret;
1979 struct drm_connector *connector; 1981 struct drm_connector *connector;
1980 struct drm_connector_state *conn_state; 1982 struct drm_connector_state *conn_state, *old_conn_state;
1981 struct drm_crtc *crtc; 1983 struct drm_crtc *crtc;
1982 struct drm_crtc_state *crtc_state; 1984 struct drm_crtc_state *crtc_state, *old_crtc_state;
1983 struct drm_plane *plane; 1985 struct drm_plane *plane;
1984 struct drm_plane_state *plane_state; 1986 struct drm_plane_state *plane_state, *old_plane_state;
1985 struct drm_crtc_commit *commit; 1987 struct drm_crtc_commit *commit;
1986 1988
1987 if (stall) { 1989 if (stall) {
@@ -2005,13 +2007,17 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
2005 } 2007 }
2006 } 2008 }
2007 2009
2008 for_each_connector_in_state(state, connector, conn_state, i) { 2010 for_each_oldnew_connector_in_state(state, connector, old_conn_state, conn_state, i) {
2011 WARN_ON(connector->state != old_conn_state);
2012
2009 connector->state->state = state; 2013 connector->state->state = state;
2010 swap(state->connectors[i].state, connector->state); 2014 swap(state->connectors[i].state, connector->state);
2011 connector->state->state = NULL; 2015 connector->state->state = NULL;
2012 } 2016 }
2013 2017
2014 for_each_crtc_in_state(state, crtc, crtc_state, i) { 2018 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, crtc_state, i) {
2019 WARN_ON(crtc->state != old_crtc_state);
2020
2015 crtc->state->state = state; 2021 crtc->state->state = state;
2016 swap(state->crtcs[i].state, crtc->state); 2022 swap(state->crtcs[i].state, crtc->state);
2017 crtc->state->state = NULL; 2023 crtc->state->state = NULL;
@@ -2026,7 +2032,9 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
2026 } 2032 }
2027 } 2033 }
2028 2034
2029 for_each_plane_in_state(state, plane, plane_state, i) { 2035 for_each_oldnew_plane_in_state(state, plane, old_plane_state, plane_state, i) {
2036 WARN_ON(plane->state != old_plane_state);
2037
2030 plane->state->state = state; 2038 plane->state->state = state;
2031 swap(state->planes[i].state, plane->state); 2039 swap(state->planes[i].state, plane->state);
2032 plane->state->state = NULL; 2040 plane->state->state = NULL;
@@ -2477,7 +2485,7 @@ EXPORT_SYMBOL(drm_atomic_helper_disable_all);
2477 * 2485 *
2478 * See also: 2486 * See also:
2479 * drm_atomic_helper_duplicate_state(), drm_atomic_helper_disable_all(), 2487 * drm_atomic_helper_duplicate_state(), drm_atomic_helper_disable_all(),
2480 * drm_atomic_helper_resume() 2488 * drm_atomic_helper_resume(), drm_atomic_helper_commit_duplicated_state()
2481 */ 2489 */
2482struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev) 2490struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev)
2483{ 2491{
@@ -2518,6 +2526,47 @@ unlock:
2518EXPORT_SYMBOL(drm_atomic_helper_suspend); 2526EXPORT_SYMBOL(drm_atomic_helper_suspend);
2519 2527
2520/** 2528/**
2529 * drm_atomic_helper_commit_duplicated_state - commit duplicated state
2530 * @state: duplicated atomic state to commit
2531 * @ctx: pointer to acquire_ctx to use for commit.
2532 *
2533 * The state returned by drm_atomic_helper_duplicate_state() and
2534 * drm_atomic_helper_suspend() is partially invalid, and needs to
2535 * be fixed up before commit.
2536 *
2537 * Returns:
2538 * 0 on success or a negative error code on failure.
2539 *
2540 * See also:
2541 * drm_atomic_helper_suspend()
2542 */
2543int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
2544 struct drm_modeset_acquire_ctx *ctx)
2545{
2546 int i;
2547 struct drm_plane *plane;
2548 struct drm_plane_state *plane_state;
2549 struct drm_connector *connector;
2550 struct drm_connector_state *conn_state;
2551 struct drm_crtc *crtc;
2552 struct drm_crtc_state *crtc_state;
2553
2554 state->acquire_ctx = ctx;
2555
2556 for_each_new_plane_in_state(state, plane, plane_state, i)
2557 state->planes[i].old_state = plane->state;
2558
2559 for_each_new_crtc_in_state(state, crtc, crtc_state, i)
2560 state->crtcs[i].old_state = crtc->state;
2561
2562 for_each_new_connector_in_state(state, connector, conn_state, i)
2563 state->connectors[i].old_state = connector->state;
2564
2565 return drm_atomic_commit(state);
2566}
2567EXPORT_SYMBOL(drm_atomic_helper_commit_duplicated_state);
2568
2569/**
2521 * drm_atomic_helper_resume - subsystem-level resume helper 2570 * drm_atomic_helper_resume - subsystem-level resume helper
2522 * @dev: DRM device 2571 * @dev: DRM device
2523 * @state: atomic state to resume to 2572 * @state: atomic state to resume to
@@ -2540,9 +2589,9 @@ int drm_atomic_helper_resume(struct drm_device *dev,
2540 int err; 2589 int err;
2541 2590
2542 drm_mode_config_reset(dev); 2591 drm_mode_config_reset(dev);
2592
2543 drm_modeset_lock_all(dev); 2593 drm_modeset_lock_all(dev);
2544 state->acquire_ctx = config->acquire_ctx; 2594 err = drm_atomic_helper_commit_duplicated_state(state, config->acquire_ctx);
2545 err = drm_atomic_commit(state);
2546 drm_modeset_unlock_all(dev); 2595 drm_modeset_unlock_all(dev);
2547 2596
2548 return err; 2597 return err;
@@ -2718,7 +2767,8 @@ static int page_flip_common(
2718 struct drm_atomic_state *state, 2767 struct drm_atomic_state *state,
2719 struct drm_crtc *crtc, 2768 struct drm_crtc *crtc,
2720 struct drm_framebuffer *fb, 2769 struct drm_framebuffer *fb,
2721 struct drm_pending_vblank_event *event) 2770 struct drm_pending_vblank_event *event,
2771 uint32_t flags)
2722{ 2772{
2723 struct drm_plane *plane = crtc->primary; 2773 struct drm_plane *plane = crtc->primary;
2724 struct drm_plane_state *plane_state; 2774 struct drm_plane_state *plane_state;
@@ -2730,12 +2780,12 @@ static int page_flip_common(
2730 return PTR_ERR(crtc_state); 2780 return PTR_ERR(crtc_state);
2731 2781
2732 crtc_state->event = event; 2782 crtc_state->event = event;
2783 crtc_state->pageflip_flags = flags;
2733 2784
2734 plane_state = drm_atomic_get_plane_state(state, plane); 2785 plane_state = drm_atomic_get_plane_state(state, plane);
2735 if (IS_ERR(plane_state)) 2786 if (IS_ERR(plane_state))
2736 return PTR_ERR(plane_state); 2787 return PTR_ERR(plane_state);
2737 2788
2738
2739 ret = drm_atomic_set_crtc_for_plane(plane_state, crtc); 2789 ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
2740 if (ret != 0) 2790 if (ret != 0)
2741 return ret; 2791 return ret;
@@ -2744,8 +2794,8 @@ static int page_flip_common(
2744 /* Make sure we don't accidentally do a full modeset. */ 2794 /* Make sure we don't accidentally do a full modeset. */
2745 state->allow_modeset = false; 2795 state->allow_modeset = false;
2746 if (!crtc_state->active) { 2796 if (!crtc_state->active) {
2747 DRM_DEBUG_ATOMIC("[CRTC:%d] disabled, rejecting legacy flip\n", 2797 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] disabled, rejecting legacy flip\n",
2748 crtc->base.id); 2798 crtc->base.id, crtc->name);
2749 return -EINVAL; 2799 return -EINVAL;
2750 } 2800 }
2751 2801
@@ -2762,10 +2812,6 @@ static int page_flip_common(
2762 * Provides a default &drm_crtc_funcs.page_flip implementation 2812 * Provides a default &drm_crtc_funcs.page_flip implementation
2763 * using the atomic driver interface. 2813 * using the atomic driver interface.
2764 * 2814 *
2765 * Note that for now so called async page flips (i.e. updates which are not
2766 * synchronized to vblank) are not supported, since the atomic interfaces have
2767 * no provisions for this yet.
2768 *
2769 * Returns: 2815 * Returns:
2770 * Returns 0 on success, negative errno numbers on failure. 2816 * Returns 0 on success, negative errno numbers on failure.
2771 * 2817 *
@@ -2781,9 +2827,6 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
2781 struct drm_atomic_state *state; 2827 struct drm_atomic_state *state;
2782 int ret = 0; 2828 int ret = 0;
2783 2829
2784 if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
2785 return -EINVAL;
2786
2787 state = drm_atomic_state_alloc(plane->dev); 2830 state = drm_atomic_state_alloc(plane->dev);
2788 if (!state) 2831 if (!state)
2789 return -ENOMEM; 2832 return -ENOMEM;
@@ -2791,7 +2834,7 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
2791 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); 2834 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
2792 2835
2793retry: 2836retry:
2794 ret = page_flip_common(state, crtc, fb, event); 2837 ret = page_flip_common(state, crtc, fb, event, flags);
2795 if (ret != 0) 2838 if (ret != 0)
2796 goto fail; 2839 goto fail;
2797 2840
@@ -2846,9 +2889,6 @@ int drm_atomic_helper_page_flip_target(
2846 struct drm_crtc_state *crtc_state; 2889 struct drm_crtc_state *crtc_state;
2847 int ret = 0; 2890 int ret = 0;
2848 2891
2849 if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
2850 return -EINVAL;
2851
2852 state = drm_atomic_state_alloc(plane->dev); 2892 state = drm_atomic_state_alloc(plane->dev);
2853 if (!state) 2893 if (!state)
2854 return -ENOMEM; 2894 return -ENOMEM;
@@ -2856,7 +2896,7 @@ int drm_atomic_helper_page_flip_target(
2856 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); 2896 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
2857 2897
2858retry: 2898retry:
2859 ret = page_flip_common(state, crtc, fb, event); 2899 ret = page_flip_common(state, crtc, fb, event, flags);
2860 if (ret != 0) 2900 if (ret != 0)
2861 goto fail; 2901 goto fail;
2862 2902
@@ -3056,6 +3096,7 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
3056 state->color_mgmt_changed = false; 3096 state->color_mgmt_changed = false;
3057 state->zpos_changed = false; 3097 state->zpos_changed = false;
3058 state->event = NULL; 3098 state->event = NULL;
3099 state->pageflip_flags = 0;
3059} 3100}
3060EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state); 3101EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
3061 3102