drm/amd/display: Use surface directly when checking update type
[Why] DC expects the surface memory address to identify the surface. This doesn't work with what we're doing with the temporary surfaces, it will always assume this is a full update because the surface isn't in the current context. [How] Use the surface directly. This doesn't give us much improvement yet, since we always create a new dc_plane_state when state->allow_modeset is true. The call into dc_check_update_surfaces_for_stream also needs to be locked, for two reasons: 1. It checks the current DC state 2. It modifies the surface update flags Both of which could be currently in the middle of commit work from commit tail. A TODO here is to pass the context explicitly into this function and find a way to get the surface update flags out of it without modifying the surface in place. Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Reviewed-by: David Francis <David.Francis@amd.com> Acked-by: Bhawanpreet Lakha <Bhawanpreet Lakha@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
6491f0c05a
commit
f843b308ad
|
@ -6282,10 +6282,11 @@ static int dm_update_plane_state(struct dc *dc,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dm_determine_update_type_for_commit(struct dc *dc,
|
dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,
|
||||||
struct drm_atomic_state *state,
|
struct drm_atomic_state *state,
|
||||||
enum surface_update_type *out_type)
|
enum surface_update_type *out_type)
|
||||||
{
|
{
|
||||||
|
struct dc *dc = dm->dc;
|
||||||
struct dm_atomic_state *dm_state = NULL, *old_dm_state = NULL;
|
struct dm_atomic_state *dm_state = NULL, *old_dm_state = NULL;
|
||||||
int i, j, num_plane, ret = 0;
|
int i, j, num_plane, ret = 0;
|
||||||
struct drm_plane_state *old_plane_state, *new_plane_state;
|
struct drm_plane_state *old_plane_state, *new_plane_state;
|
||||||
|
@ -6299,14 +6300,12 @@ dm_determine_update_type_for_commit(struct dc *dc,
|
||||||
struct dc_stream_status *status = NULL;
|
struct dc_stream_status *status = NULL;
|
||||||
|
|
||||||
struct dc_surface_update *updates;
|
struct dc_surface_update *updates;
|
||||||
struct dc_plane_state *surface;
|
|
||||||
enum surface_update_type update_type = UPDATE_TYPE_FAST;
|
enum surface_update_type update_type = UPDATE_TYPE_FAST;
|
||||||
|
|
||||||
updates = kcalloc(MAX_SURFACES, sizeof(*updates), GFP_KERNEL);
|
updates = kcalloc(MAX_SURFACES, sizeof(*updates), GFP_KERNEL);
|
||||||
surface = kcalloc(MAX_SURFACES, sizeof(*surface), GFP_KERNEL);
|
|
||||||
|
|
||||||
if (!updates || !surface) {
|
if (!updates) {
|
||||||
DRM_ERROR("Plane or surface update failed to allocate");
|
DRM_ERROR("Failed to allocate plane updates\n");
|
||||||
/* Set type to FULL to avoid crashing in DC*/
|
/* Set type to FULL to avoid crashing in DC*/
|
||||||
update_type = UPDATE_TYPE_FULL;
|
update_type = UPDATE_TYPE_FULL;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -6349,17 +6348,9 @@ dm_determine_update_type_for_commit(struct dc *dc,
|
||||||
if (crtc != new_plane_crtc)
|
if (crtc != new_plane_crtc)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
updates[num_plane].surface = &surface[num_plane];
|
updates[num_plane].surface = new_dm_plane_state->dc_state;
|
||||||
|
|
||||||
if (new_crtc_state->mode_changed) {
|
if (new_crtc_state->mode_changed) {
|
||||||
updates[num_plane].surface->src_rect =
|
|
||||||
new_dm_plane_state->dc_state->src_rect;
|
|
||||||
updates[num_plane].surface->dst_rect =
|
|
||||||
new_dm_plane_state->dc_state->dst_rect;
|
|
||||||
updates[num_plane].surface->rotation =
|
|
||||||
new_dm_plane_state->dc_state->rotation;
|
|
||||||
updates[num_plane].surface->in_transfer_func =
|
|
||||||
new_dm_plane_state->dc_state->in_transfer_func;
|
|
||||||
stream_update.dst = new_dm_crtc_state->stream->dst;
|
stream_update.dst = new_dm_crtc_state->stream->dst;
|
||||||
stream_update.src = new_dm_crtc_state->stream->src;
|
stream_update.src = new_dm_crtc_state->stream->src;
|
||||||
}
|
}
|
||||||
|
@ -6394,8 +6385,14 @@ dm_determine_update_type_for_commit(struct dc *dc,
|
||||||
status = dc_stream_get_status_from_state(old_dm_state->context,
|
status = dc_stream_get_status_from_state(old_dm_state->context,
|
||||||
new_dm_crtc_state->stream);
|
new_dm_crtc_state->stream);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: DC modifies the surface during this call so we need
|
||||||
|
* to lock here - find a way to do this without locking.
|
||||||
|
*/
|
||||||
|
mutex_lock(&dm->dc_lock);
|
||||||
update_type = dc_check_update_surfaces_for_stream(dc, updates, num_plane,
|
update_type = dc_check_update_surfaces_for_stream(dc, updates, num_plane,
|
||||||
&stream_update, status);
|
&stream_update, status);
|
||||||
|
mutex_unlock(&dm->dc_lock);
|
||||||
|
|
||||||
if (update_type > UPDATE_TYPE_MED) {
|
if (update_type > UPDATE_TYPE_MED) {
|
||||||
update_type = UPDATE_TYPE_FULL;
|
update_type = UPDATE_TYPE_FULL;
|
||||||
|
@ -6405,7 +6402,6 @@ dm_determine_update_type_for_commit(struct dc *dc,
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
kfree(updates);
|
kfree(updates);
|
||||||
kfree(surface);
|
|
||||||
|
|
||||||
*out_type = update_type;
|
*out_type = update_type;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -6589,7 +6585,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||||
lock_and_validation_needed = true;
|
lock_and_validation_needed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = dm_determine_update_type_for_commit(dc, state, &update_type);
|
ret = dm_determine_update_type_for_commit(&adev->dm, state, &update_type);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue