Commit 0430d52b authored by Shirish S's avatar Shirish S Committed by Alex Deucher

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: default avatarHarry Wentland <Harry.Wentland@amd.com>
Signed-off-by: default avatarShirish S <shirish.s@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 110ff543
...@@ -730,19 +730,20 @@ static void update_stream_scaling_settings( ...@@ -730,19 +730,20 @@ static void update_stream_scaling_settings(
} }
static void dm_dc_surface_commit( static void add_surface(struct dc *dc,
struct dc *dc, struct drm_crtc *crtc,
struct drm_crtc *crtc) struct drm_plane *plane,
const struct dc_surface **dc_surfaces)
{ {
struct dc_surface *dc_surface; struct dc_surface *dc_surface;
const struct dc_surface *dc_surfaces[1];
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
const struct dc_stream *dc_stream = acrtc->stream; const struct dc_stream *dc_stream = acrtc->stream;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&crtc->dev->event_lock, flags); spin_lock_irqsave(&crtc->dev->event_lock, flags);
if (acrtc->pflip_status != AMDGPU_FLIP_NONE) { 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); spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
/* In comit tail framework this cannot happen */ /* In comit tail framework this cannot happen */
BUG_ON(0); BUG_ON(0);
...@@ -770,22 +771,11 @@ static void dm_dc_surface_commit( ...@@ -770,22 +771,11 @@ static void dm_dc_surface_commit(
fill_plane_attributes( fill_plane_attributes(
crtc->dev->dev_private, crtc->dev->dev_private,
dc_surface, dc_surface,
crtc->primary->state, plane->state,
true); true);
dc_surfaces[0] = dc_surface; *dc_surfaces = 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_surface_release(dc_surface);
fail: fail:
return; return;
} }
...@@ -2385,11 +2375,16 @@ static void amdgpu_dm_do_flip( ...@@ -2385,11 +2375,16 @@ static void amdgpu_dm_do_flip(
} }
void dc_commit_surfaces(struct drm_atomic_state *state, 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; uint32_t i;
struct drm_plane *plane; struct drm_plane *plane;
struct drm_plane_state *old_plane_state; 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 */ /* update planes when needed */
for_each_plane_in_state(state, plane, old_plane_state, i) { for_each_plane_in_state(state, plane, old_plane_state, i) {
...@@ -2398,6 +2393,7 @@ void dc_commit_surfaces(struct drm_atomic_state *state, ...@@ -2398,6 +2393,7 @@ void dc_commit_surfaces(struct drm_atomic_state *state,
struct drm_framebuffer *fb = plane_state->fb; struct drm_framebuffer *fb = plane_state->fb;
struct drm_connector *connector; struct drm_connector *connector;
struct dm_connector_state *dm_state = NULL; struct dm_connector_state *dm_state = NULL;
struct amdgpu_crtc *acrtc_attach;
enum dm_commit_action action; enum dm_commit_action action;
bool pflip_needed; bool pflip_needed;
...@@ -2439,9 +2435,26 @@ void dc_commit_surfaces(struct drm_atomic_state *state, ...@@ -2439,9 +2435,26 @@ void dc_commit_surfaces(struct drm_atomic_state *state,
*/ */
if (!dm_state) if (!dm_state)
continue; 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]);
} }
} }
...@@ -2453,10 +2466,10 @@ void amdgpu_dm_atomic_commit_tail( ...@@ -2453,10 +2466,10 @@ void amdgpu_dm_atomic_commit_tail(
struct amdgpu_display_manager *dm = &adev->dm; struct amdgpu_display_manager *dm = &adev->dm;
struct drm_plane *plane; struct drm_plane *plane;
struct drm_plane_state *old_plane_state; struct drm_plane_state *old_plane_state;
uint32_t i; uint32_t i, j;
uint32_t commit_streams_count = 0; uint32_t commit_streams_count = 0;
uint32_t new_crtcs_count = 0; uint32_t new_crtcs_count = 0;
struct drm_crtc *crtc; struct drm_crtc *crtc, *pcrtc;
struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *old_crtc_state;
const struct dc_stream *commit_streams[MAX_STREAMS]; const struct dc_stream *commit_streams[MAX_STREAMS];
struct amdgpu_crtc *new_crtcs[MAX_STREAMS]; struct amdgpu_crtc *new_crtcs[MAX_STREAMS];
...@@ -2615,8 +2628,9 @@ void amdgpu_dm_atomic_commit_tail( ...@@ -2615,8 +2628,9 @@ void amdgpu_dm_atomic_commit_tail(
dc_stream_get_status(acrtc->stream)->primary_otg_inst; dc_stream_get_status(acrtc->stream)->primary_otg_inst;
} }
/* update planes when needed */ /* update planes when needed per crtc*/
dc_commit_surfaces(state, dev, dm); 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++) { for (i = 0; i < new_crtcs_count; i++) {
/* /*
...@@ -2793,15 +2807,18 @@ static uint32_t add_val_sets_surface( ...@@ -2793,15 +2807,18 @@ static uint32_t add_val_sets_surface(
const struct dc_stream *stream, const struct dc_stream *stream,
const struct dc_surface *surface) const struct dc_surface *surface)
{ {
uint32_t i = 0; uint32_t i = 0, j = 0;
while (i < set_count) { while (i < set_count) {
if (val_sets[i].stream == stream) if (val_sets[i].stream == stream) {
while (val_sets[i].surfaces[j])
j++;
break; break;
}
++i; ++i;
} }
val_sets[i].surfaces[val_sets[i].surface_count] = surface; val_sets[i].surfaces[j] = surface;
val_sets[i].surface_count++; val_sets[i].surface_count++;
return val_sets[i].surface_count; return val_sets[i].surface_count;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment