aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c67
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h8
2 files changed, 73 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index ad0848dbd909..c13856a46d8e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -57,6 +57,7 @@
57 57
58#include <drm/drmP.h> 58#include <drm/drmP.h>
59#include <drm/drm_atomic.h> 59#include <drm/drm_atomic.h>
60#include <drm/drm_atomic_uapi.h>
60#include <drm/drm_atomic_helper.h> 61#include <drm/drm_atomic_helper.h>
61#include <drm/drm_dp_mst_helper.h> 62#include <drm/drm_dp_mst_helper.h>
62#include <drm/drm_fb_helper.h> 63#include <drm/drm_fb_helper.h>
@@ -133,6 +134,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state);
133static int amdgpu_dm_atomic_check(struct drm_device *dev, 134static int amdgpu_dm_atomic_check(struct drm_device *dev,
134 struct drm_atomic_state *state); 135 struct drm_atomic_state *state);
135 136
137static void handle_cursor_update(struct drm_plane *plane,
138 struct drm_plane_state *old_plane_state);
136 139
137 140
138 141
@@ -402,6 +405,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
402 /* Zero all the fields */ 405 /* Zero all the fields */
403 memset(&init_data, 0, sizeof(init_data)); 406 memset(&init_data, 0, sizeof(init_data));
404 407
408 mutex_init(&adev->dm.dc_lock);
409
405 if(amdgpu_dm_irq_init(adev)) { 410 if(amdgpu_dm_irq_init(adev)) {
406 DRM_ERROR("amdgpu: failed to initialize DM IRQ support.\n"); 411 DRM_ERROR("amdgpu: failed to initialize DM IRQ support.\n");
407 goto error; 412 goto error;
@@ -516,6 +521,9 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
516 /* DC Destroy TODO: Replace destroy DAL */ 521 /* DC Destroy TODO: Replace destroy DAL */
517 if (adev->dm.dc) 522 if (adev->dm.dc)
518 dc_destroy(&adev->dm.dc); 523 dc_destroy(&adev->dm.dc);
524
525 mutex_destroy(&adev->dm.dc_lock);
526
519 return; 527 return;
520} 528}
521 529
@@ -3617,10 +3625,43 @@ static int dm_plane_atomic_check(struct drm_plane *plane,
3617 return -EINVAL; 3625 return -EINVAL;
3618} 3626}
3619 3627
3628static int dm_plane_atomic_async_check(struct drm_plane *plane,
3629 struct drm_plane_state *new_plane_state)
3630{
3631 /* Only support async updates on cursor planes. */
3632 if (plane->type != DRM_PLANE_TYPE_CURSOR)
3633 return -EINVAL;
3634
3635 return 0;
3636}
3637
3638static void dm_plane_atomic_async_update(struct drm_plane *plane,
3639 struct drm_plane_state *new_state)
3640{
3641 struct drm_plane_state *old_state =
3642 drm_atomic_get_old_plane_state(new_state->state, plane);
3643
3644 if (plane->state->fb != new_state->fb)
3645 drm_atomic_set_fb_for_plane(plane->state, new_state->fb);
3646
3647 plane->state->src_x = new_state->src_x;
3648 plane->state->src_y = new_state->src_y;
3649 plane->state->src_w = new_state->src_w;
3650 plane->state->src_h = new_state->src_h;
3651 plane->state->crtc_x = new_state->crtc_x;
3652 plane->state->crtc_y = new_state->crtc_y;
3653 plane->state->crtc_w = new_state->crtc_w;
3654 plane->state->crtc_h = new_state->crtc_h;
3655
3656 handle_cursor_update(plane, old_state);
3657}
3658
3620static const struct drm_plane_helper_funcs dm_plane_helper_funcs = { 3659static const struct drm_plane_helper_funcs dm_plane_helper_funcs = {
3621 .prepare_fb = dm_plane_helper_prepare_fb, 3660 .prepare_fb = dm_plane_helper_prepare_fb,
3622 .cleanup_fb = dm_plane_helper_cleanup_fb, 3661 .cleanup_fb = dm_plane_helper_cleanup_fb,
3623 .atomic_check = dm_plane_atomic_check, 3662 .atomic_check = dm_plane_atomic_check,
3663 .atomic_async_check = dm_plane_atomic_async_check,
3664 .atomic_async_update = dm_plane_atomic_async_update
3624}; 3665};
3625 3666
3626/* 3667/*
@@ -4309,6 +4350,7 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc,
4309static void handle_cursor_update(struct drm_plane *plane, 4350static void handle_cursor_update(struct drm_plane *plane,
4310 struct drm_plane_state *old_plane_state) 4351 struct drm_plane_state *old_plane_state)
4311{ 4352{
4353 struct amdgpu_device *adev = plane->dev->dev_private;
4312 struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(plane->state->fb); 4354 struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(plane->state->fb);
4313 struct drm_crtc *crtc = afb ? plane->state->crtc : old_plane_state->crtc; 4355 struct drm_crtc *crtc = afb ? plane->state->crtc : old_plane_state->crtc;
4314 struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL; 4356 struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL;
@@ -4333,9 +4375,12 @@ static void handle_cursor_update(struct drm_plane *plane,
4333 4375
4334 if (!position.enable) { 4376 if (!position.enable) {
4335 /* turn off cursor */ 4377 /* turn off cursor */
4336 if (crtc_state && crtc_state->stream) 4378 if (crtc_state && crtc_state->stream) {
4379 mutex_lock(&adev->dm.dc_lock);
4337 dc_stream_set_cursor_position(crtc_state->stream, 4380 dc_stream_set_cursor_position(crtc_state->stream,
4338 &position); 4381 &position);
4382 mutex_unlock(&adev->dm.dc_lock);
4383 }
4339 return; 4384 return;
4340 } 4385 }
4341 4386
@@ -4353,6 +4398,7 @@ static void handle_cursor_update(struct drm_plane *plane,
4353 attributes.pitch = attributes.width; 4398 attributes.pitch = attributes.width;
4354 4399
4355 if (crtc_state->stream) { 4400 if (crtc_state->stream) {
4401 mutex_lock(&adev->dm.dc_lock);
4356 if (!dc_stream_set_cursor_attributes(crtc_state->stream, 4402 if (!dc_stream_set_cursor_attributes(crtc_state->stream,
4357 &attributes)) 4403 &attributes))
4358 DRM_ERROR("DC failed to set cursor attributes\n"); 4404 DRM_ERROR("DC failed to set cursor attributes\n");
@@ -4360,6 +4406,7 @@ static void handle_cursor_update(struct drm_plane *plane,
4360 if (!dc_stream_set_cursor_position(crtc_state->stream, 4406 if (!dc_stream_set_cursor_position(crtc_state->stream,
4361 &position)) 4407 &position))
4362 DRM_ERROR("DC failed to set cursor position\n"); 4408 DRM_ERROR("DC failed to set cursor position\n");
4409 mutex_unlock(&adev->dm.dc_lock);
4363 } 4410 }
4364} 4411}
4365 4412
@@ -4575,6 +4622,7 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
4575 &acrtc_state->stream->vrr_infopacket; 4622 &acrtc_state->stream->vrr_infopacket;
4576 } 4623 }
4577 4624
4625 mutex_lock(&adev->dm.dc_lock);
4578 dc_commit_updates_for_stream(adev->dm.dc, 4626 dc_commit_updates_for_stream(adev->dm.dc,
4579 surface_updates, 4627 surface_updates,
4580 1, 4628 1,
@@ -4582,6 +4630,7 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
4582 &stream_update, 4630 &stream_update,
4583 &surface_updates->surface, 4631 &surface_updates->surface,
4584 state); 4632 state);
4633 mutex_unlock(&adev->dm.dc_lock);
4585 4634
4586 DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x \n", 4635 DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x \n",
4587 __func__, 4636 __func__,
@@ -4596,6 +4645,7 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
4596 * with a dc_plane_state and follow the atomic model a bit more closely here. 4645 * with a dc_plane_state and follow the atomic model a bit more closely here.
4597 */ 4646 */
4598static bool commit_planes_to_stream( 4647static bool commit_planes_to_stream(
4648 struct amdgpu_display_manager *dm,
4599 struct dc *dc, 4649 struct dc *dc,
4600 struct dc_plane_state **plane_states, 4650 struct dc_plane_state **plane_states,
4601 uint8_t new_plane_count, 4651 uint8_t new_plane_count,
@@ -4672,11 +4722,13 @@ static bool commit_planes_to_stream(
4672 updates[i].scaling_info = &scaling_info[i]; 4722 updates[i].scaling_info = &scaling_info[i];
4673 } 4723 }
4674 4724
4725 mutex_lock(&dm->dc_lock);
4675 dc_commit_updates_for_stream( 4726 dc_commit_updates_for_stream(
4676 dc, 4727 dc,
4677 updates, 4728 updates,
4678 new_plane_count, 4729 new_plane_count,
4679 dc_stream, stream_update, plane_states, state); 4730 dc_stream, stream_update, plane_states, state);
4731 mutex_unlock(&dm->dc_lock);
4680 4732
4681 kfree(flip_addr); 4733 kfree(flip_addr);
4682 kfree(plane_info); 4734 kfree(plane_info);
@@ -4782,7 +4834,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
4782 4834
4783 dc_stream_attach->abm_level = acrtc_state->abm_level; 4835 dc_stream_attach->abm_level = acrtc_state->abm_level;
4784 4836
4785 if (false == commit_planes_to_stream(dm->dc, 4837 if (false == commit_planes_to_stream(dm,
4838 dm->dc,
4786 plane_states_constructed, 4839 plane_states_constructed,
4787 planes_count, 4840 planes_count,
4788 acrtc_state, 4841 acrtc_state,
@@ -4952,7 +5005,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
4952 5005
4953 if (dc_state) { 5006 if (dc_state) {
4954 dm_enable_per_frame_crtc_master_sync(dc_state); 5007 dm_enable_per_frame_crtc_master_sync(dc_state);
5008 mutex_lock(&dm->dc_lock);
4955 WARN_ON(!dc_commit_state(dm->dc, dc_state)); 5009 WARN_ON(!dc_commit_state(dm->dc, dc_state));
5010 mutex_unlock(&dm->dc_lock);
4956 } 5011 }
4957 5012
4958 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { 5013 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
@@ -5014,6 +5069,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
5014 5069
5015 /*TODO How it works with MPO ?*/ 5070 /*TODO How it works with MPO ?*/
5016 if (!commit_planes_to_stream( 5071 if (!commit_planes_to_stream(
5072 dm,
5017 dm->dc, 5073 dm->dc,
5018 status->plane_states, 5074 status->plane_states,
5019 status->plane_count, 5075 status->plane_count,
@@ -5906,6 +5962,13 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
5906 ret = -EINVAL; 5962 ret = -EINVAL;
5907 goto fail; 5963 goto fail;
5908 } 5964 }
5965 } else if (state->legacy_cursor_update) {
5966 /*
5967 * This is a fast cursor update coming from the plane update
5968 * helper, check if it can be done asynchronously for better
5969 * performance.
5970 */
5971 state->async_update = !drm_atomic_helper_async_check(dev, state);
5909 } 5972 }
5910 5973
5911 /* Must be success */ 5974 /* Must be success */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 4326dc256491..25bb91ee80ba 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -135,6 +135,14 @@ struct amdgpu_display_manager {
135 struct drm_modeset_lock atomic_obj_lock; 135 struct drm_modeset_lock atomic_obj_lock;
136 136
137 /** 137 /**
138 * @dc_lock:
139 *
140 * Guards access to DC functions that can issue register write
141 * sequences.
142 */
143 struct mutex dc_lock;
144
145 /**
138 * @irq_handler_list_low_tab: 146 * @irq_handler_list_low_tab:
139 * 147 *
140 * Low priority IRQ handler table. 148 * Low priority IRQ handler table.