From 4b9ef7c969dcb0a603a3cfcea620108cfa39ffe8 Mon Sep 17 00:00:00 2001 From: Shirish S Date: Wed, 12 Apr 2017 16:23:25 +0530 Subject: [PATCH 0358/4131] drm/amd/display: make dc_commit_surfaces_to_stream() re-entrant dc_commit_surfaces_to_stream() function currently is handle's only one plane at a time. This will not work if multiple planes have to be set to a crtc. The functionality of dc_commit_surfaces_to_stream() with this patch is slit into 1. Accumulate and initialise all the surfaces that needs to be set to a crtc. 2. Update the intialised set of surfaces to the steam in one go. Hence dc_commit_surfaces_to_stream() is renamed to init_surfaces(). Once all the planes requested by user space are initialised, dc_commit_surfaces_to_stream() shall sequentially populates *updates, *flip_addr, *plane_info and *scaling_info for all surfaces. BUG: SWDEV-119421 TEST: (On Chromium OS for Stoney Only) * Chromium UI comes up, on both eDP & DP. * 'new_surface_count' now changes as per user input for e.g for all below run tests its 2, without this patch for the below tests it used to be 1 * Executed below tests to see YUV(underlay) & RGB planes on eDP plane_test --format XR24 --size 500x100 -p --format YV12 --size 500x500 plane_test --format AR24 --size 500x50 -p --format YV12 --size 150x150 plane_test --format AR24 --size 500x50 -p --format YV12 --size 1366x768 Signed-off-by: Harry Wentland Signed-off-by: Shirish S Signed-off-by: Alex Deucher --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_types.c | 71 ++++++++++++++-------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c index c73918d..616f246 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c @@ -729,19 +729,20 @@ static void update_stream_scaling_settings( } -static void dm_dc_surface_commit( - struct dc *dc, - struct drm_crtc *crtc) +static void add_surface(struct dc *dc, + struct drm_crtc *crtc, + struct drm_plane *plane, + const struct dc_surface **dc_surfaces) { struct dc_surface *dc_surface; - const struct dc_surface *dc_surfaces[1]; struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); const struct dc_stream *dc_stream = acrtc->stream; unsigned long flags; spin_lock_irqsave(&crtc->dev->event_lock, flags); if (acrtc->pflip_status != AMDGPU_FLIP_NONE) { - DRM_ERROR("dm_dc_surface_commit: acrtc %d, already busy\n", acrtc->crtc_id); + DRM_ERROR("add_surface: acrtc %d, already busy\n", + acrtc->crtc_id); spin_unlock_irqrestore(&crtc->dev->event_lock, flags); /* In comit tail framework this cannot happen */ BUG_ON(0); @@ -769,22 +770,11 @@ static void dm_dc_surface_commit( fill_plane_attributes( crtc->dev->dev_private, dc_surface, - crtc->primary->state, + plane->state, true); - dc_surfaces[0] = dc_surface; - - if (false == dc_commit_surfaces_to_stream( - dc, - dc_surfaces, - 1, - dc_stream)) { - dm_error( - "%s: Failed to attach surface!\n", - __func__); - } + *dc_surfaces = dc_surface; - dc_surface_release(dc_surface); fail: return; } @@ -2566,11 +2556,16 @@ static void amdgpu_dm_do_flip( } void dc_commit_surfaces(struct drm_atomic_state *state, - struct drm_device *dev, struct amdgpu_display_manager *dm) + struct drm_device *dev, + struct amdgpu_display_manager *dm, + struct drm_crtc *pcrtc) { uint32_t i; struct drm_plane *plane; struct drm_plane_state *old_plane_state; + const struct dc_stream *dc_stream_attach; + const struct dc_surface *dc_surfaces_constructed[MAX_SURFACES]; + int planes_count = 0; /* update planes when needed */ for_each_plane_in_state(state, plane, old_plane_state, i) { @@ -2579,6 +2574,7 @@ void dc_commit_surfaces(struct drm_atomic_state *state, struct drm_framebuffer *fb = plane_state->fb; struct drm_connector *connector; struct dm_connector_state *dm_state = NULL; + struct amdgpu_crtc *acrtc_attach; enum dm_commit_action action; bool pflip_needed; @@ -2620,9 +2616,26 @@ void dc_commit_surfaces(struct drm_atomic_state *state, */ if (!dm_state) continue; + if (crtc == pcrtc) { + add_surface(dm->dc, crtc, plane, + &dc_surfaces_constructed[planes_count]); + acrtc_attach = to_amdgpu_crtc(crtc); + dc_stream_attach = acrtc_attach->stream; + planes_count++; + } + } + } - dm_dc_surface_commit(dm->dc, crtc); + if (planes_count) { + if (false == dc_commit_surfaces_to_stream(dm->dc, + dc_surfaces_constructed, + planes_count, + dc_stream_attach)) { + dm_error("%s: Failed to attach surface!\n", __func__); + return; } + for (i = 0; i < planes_count; i++) + dc_surface_release(dc_surfaces_constructed[i]); } } @@ -2634,10 +2647,10 @@ void amdgpu_dm_atomic_commit_tail( struct amdgpu_display_manager *dm = &adev->dm; struct drm_plane *plane; struct drm_plane_state *old_plane_state; - uint32_t i; + uint32_t i, j; uint32_t commit_streams_count = 0; uint32_t new_crtcs_count = 0; - struct drm_crtc *crtc; + struct drm_crtc *crtc, *pcrtc; struct drm_crtc_state *old_crtc_state; const struct dc_stream *commit_streams[MAX_STREAMS]; struct amdgpu_crtc *new_crtcs[MAX_STREAMS]; @@ -2796,8 +2809,9 @@ void amdgpu_dm_atomic_commit_tail( dc_stream_get_status(acrtc->stream)->primary_otg_inst; } - /* update planes when needed */ - dc_commit_surfaces(state, dev, dm); + /* update planes when needed per crtc*/ + for_each_crtc_in_state(state, pcrtc, old_crtc_state, j) + dc_commit_surfaces(state, dev, dm, pcrtc); for (i = 0; i < new_crtcs_count; i++) { /* @@ -2974,15 +2988,18 @@ static uint32_t add_val_sets_surface( const struct dc_stream *stream, const struct dc_surface *surface) { - uint32_t i = 0; + uint32_t i = 0, j = 0; while (i < set_count) { - if (val_sets[i].stream == stream) + if (val_sets[i].stream == stream) { + while (val_sets[i].surfaces[j]) + j++; break; + } ++i; } - val_sets[i].surfaces[val_sets[i].surface_count] = surface; + val_sets[i].surfaces[j] = surface; val_sets[i].surface_count++; return val_sets[i].surface_count; -- 2.7.4