Commit 19f89e23 authored by Andrey Grodzovsky's avatar Andrey Grodzovsky Committed by Alex Deucher

drm/amd/display: Per plane validation context build.

Introduce add/remove plane to/from context.
Make DC wrapper to use them in WIndows/Diags.
Use them in dc_update_surface_to_stream.
Call add/remove plane from Linux DM.

Remove dc_validation_set from dc_validate_global_state interface
and by this remove clean Linux DM from using it.
Signed-off-by: default avatarAndrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <Harry.Wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 577b5c2b
......@@ -4304,77 +4304,6 @@ void dm_restore_drm_connector_state(struct drm_device *dev, struct drm_connector
dm_force_atomic_commit(&aconnector->base);
}
static uint32_t add_val_sets_plane(
struct dc_validation_set *val_sets,
uint32_t set_count,
const struct dc_stream_state *stream,
struct dc_plane_state *plane_state)
{
uint32_t i = 0, j = 0;
while (i < set_count) {
if (val_sets[i].stream == stream) {
while (val_sets[i].plane_states[j])
j++;
break;
}
++i;
}
val_sets[i].plane_states[j] = plane_state;
val_sets[i].plane_count++;
return val_sets[i].plane_count;
}
static uint32_t update_in_val_sets_stream(
struct dc_validation_set *val_sets,
uint32_t set_count,
struct dc_stream_state *old_stream,
struct dc_stream_state *new_stream,
struct drm_crtc *crtc)
{
uint32_t i = 0;
while (i < set_count) {
if (val_sets[i].stream == old_stream)
break;
++i;
}
val_sets[i].stream = new_stream;
if (i == set_count)
/* nothing found. add new one to the end */
return set_count + 1;
return set_count;
}
static uint32_t remove_from_val_sets(
struct dc_validation_set *val_sets,
uint32_t set_count,
const struct dc_stream_state *stream)
{
int i;
for (i = 0; i < set_count; i++)
if (val_sets[i].stream == stream)
break;
if (i == set_count) {
/* nothing found */
return set_count;
}
set_count--;
for (; i < set_count; i++)
val_sets[i] = val_sets[i + 1];
return set_count;
}
/*`
* Grabs all modesetting locks to serialize against any blocking commits,
* Waits for completion of all non blocking commits.
......@@ -4438,10 +4367,9 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
struct dc *dc = adev->dm.dc;
struct drm_connector *connector;
struct drm_connector_state *conn_state;
int set_count;
struct dc_validation_set set[MAX_STREAMS] = { { 0 } };
struct dm_crtc_state *old_acrtc_state, *new_acrtc_state;
struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
bool pflip_needed = !state->allow_modeset;
/*
* This bool will be set for true for any modeset/reset
......@@ -4460,16 +4388,44 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
ASSERT(dm_state->context);
dc_resource_validate_ctx_copy_construct_current(dc, dm_state->context);
/* copy existing configuration */
set_count = 0;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
/* Remove exiting planes if they are disabled or their CRTC is updated */
for_each_crtc_in_state(state, crtc, crtc_state, i) {
new_acrtc_state = to_dm_crtc_state(crtc_state);
old_acrtc_state = to_dm_crtc_state(crtc->state);
if (pflip_needed)
continue;
for_each_plane_in_state(state, plane, plane_state, j) {
struct drm_crtc *plane_crtc = plane_state->crtc;
struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
if (old_acrtc_state->stream) {
dc_stream_retain(old_acrtc_state->stream);
set[set_count].stream = old_acrtc_state->stream;
++set_count;
if (plane->type == DRM_PLANE_TYPE_CURSOR)
continue;
if (crtc != plane_crtc || !dm_plane_state->dc_state)
continue;
WARN_ON(!new_acrtc_state->stream);
if (drm_atomic_plane_disabling(plane->state, plane_state) ||
drm_atomic_crtc_needs_modeset(crtc_state)) {
if (!dc_remove_plane_from_context(
dc,
new_acrtc_state->stream,
dm_plane_state->dc_state,
dm_state->context)) {
ret = EINVAL;
goto fail;
}
}
dc_plane_state_release(dm_plane_state->dc_state);
dm_plane_state->dc_state = NULL;
DRM_DEBUG_KMS("Disabling DRM plane: %d on DRM crtc %d\n",
plane->base.id, crtc->base.id);
}
}
......@@ -4513,11 +4469,6 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
goto fail;
}
set_count = remove_from_val_sets(
set,
set_count,
new_acrtc_state->stream);
dc_stream_release(new_acrtc_state->stream);
new_acrtc_state->stream = NULL;
......@@ -4576,13 +4527,6 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
new_acrtc_state->stream = new_stream;
set_count = update_in_val_sets_stream(
set,
set_count,
old_acrtc_state->stream,
new_acrtc_state->stream,
crtc);
if (!dc_add_stream_to_ctx(
dc,
dm_state->context,
......@@ -4639,32 +4583,32 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
lock_and_validation_needed = true;
}
/* Add new planes */
for_each_crtc_in_state(state, crtc, crtc_state, i) {
new_acrtc_state = to_dm_crtc_state(crtc_state);
if (pflip_needed)
continue;
for_each_plane_in_state(state, plane, plane_state, j) {
struct drm_crtc *plane_crtc = plane_state->crtc;
struct drm_framebuffer *fb = plane_state->fb;
bool pflip_needed;
struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
/*TODO Implement atomic check for cursor plane */
if (plane->type == DRM_PLANE_TYPE_CURSOR)
continue;
if (!fb || !plane_crtc || crtc != plane_crtc || !crtc_state->active)
if (crtc != plane_crtc)
continue;
WARN_ON(!new_acrtc_state->stream);
pflip_needed = !state->allow_modeset;
if (!pflip_needed) {
if (!drm_atomic_plane_disabling(plane->state, plane_state)) {
struct dc_plane_state *dc_plane_state;
WARN_ON(!new_acrtc_state->stream);
dc_plane_state = dc_create_plane_state(dc);
if (dm_plane_state->dc_state)
dc_plane_state_release(dm_plane_state->dc_state);
WARN_ON(dm_plane_state->dc_state);
dm_plane_state->dc_state = dc_plane_state;
......@@ -4677,10 +4621,17 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
if (ret)
goto fail;
add_val_sets_plane(set,
set_count,
if (!dc_add_plane_to_context(
dc,
new_acrtc_state->stream,
dc_plane_state);
dc_plane_state,
dm_state->context)) {
ret = EINVAL;
goto fail;
}
lock_and_validation_needed = true;
}
......@@ -4708,7 +4659,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
if (ret)
goto fail;
if (!dc_validate_global_state(dc, set, set_count, dm_state->context)) {
if (!dc_validate_global_state(dc, dm_state->context)) {
ret = -EINVAL;
goto fail;
}
......
......@@ -1305,10 +1305,16 @@ void dc_update_planes_and_stream(struct dc *dc,
dc_resource_validate_ctx_copy_construct(
core_dc->current_context, context);
/*remove old surfaces from context */
if (!dc_rem_all_planes_for_stream(dc, stream, context)) {
BREAK_TO_DEBUGGER();
goto fail;
}
/* add surface to context */
if (!resource_attach_surfaces_to_context(
new_planes, surface_count, stream,
context, core_dc->res_pool)) {
if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) {
BREAK_TO_DEBUGGER();
goto fail;
}
......
......@@ -619,16 +619,41 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream,
uint32_t *h_position,
uint32_t *v_position);
bool dc_remove_stream_from_ctx(
bool dc_add_stream_to_ctx(
struct dc *dc,
struct validate_context *new_ctx,
struct dc_stream_state *stream);
bool dc_add_stream_to_ctx(
bool dc_remove_stream_from_ctx(
struct dc *dc,
struct validate_context *new_ctx,
struct dc_stream_state *stream);
bool dc_add_plane_to_context(
const struct dc *dc,
struct dc_stream_state *stream,
struct dc_plane_state *plane_state,
struct validate_context *context);
bool dc_remove_plane_from_context(
const struct dc *dc,
struct dc_stream_state *stream,
struct dc_plane_state *plane_state,
struct validate_context *context);
bool dc_rem_all_planes_for_stream(
const struct dc *dc,
struct dc_stream_state *stream,
struct validate_context *context);
bool dc_add_all_planes_for_stream(
const struct dc *dc,
struct dc_stream_state *stream,
struct dc_plane_state * const *plane_states,
int plane_count,
struct validate_context *context);
/*
* Structure to store surface/stream associations for validation
*/
......@@ -644,8 +669,6 @@ bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state);
bool dc_validate_global_state(
struct dc *dc,
const struct dc_validation_set set[],
int set_count,
struct validate_context *new_ctx);
/*
......
......@@ -684,19 +684,18 @@ bool dce100_validate_bandwidth(
}
static bool dce100_validate_surface_sets(
const struct dc_validation_set set[],
int set_count)
struct validate_context *context)
{
int i;
for (i = 0; i < set_count; i++) {
if (set[i].plane_count == 0)
for (i = 0; i < context->stream_count; i++) {
if (context->stream_status[i].plane_count == 0)
continue;
if (set[i].plane_count > 1)
if (context->stream_status[i].plane_count > 1)
return false;
if (set[i].plane_states[0]->format
if (context->stream_status[i].plane_states[0]->format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
return false;
}
......@@ -706,12 +705,9 @@ static bool dce100_validate_surface_sets(
enum dc_status dce100_validate_global(
struct dc *dc,
const struct dc_validation_set set[],
int set_count,
struct validate_context *old_context,
struct validate_context *context)
{
if (!dce100_validate_surface_sets(set, set_count))
if (!dce100_validate_surface_sets(context))
return DC_FAIL_SURFACE_VALIDATE;
return DC_OK;
......
......@@ -880,31 +880,30 @@ static bool dce110_validate_bandwidth(
}
static bool dce110_validate_surface_sets(
const struct dc_validation_set set[],
int set_count)
struct validate_context *context)
{
int i;
for (i = 0; i < set_count; i++) {
if (set[i].plane_count == 0)
for (i = 0; i < context->stream_count; i++) {
if (context->stream_status[i].plane_count == 0)
continue;
if (set[i].plane_count > 2)
if (context->stream_status[i].plane_count > 2)
return false;
if (set[i].plane_states[0]->format
if (context->stream_status[i].plane_states[0]->format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
return false;
if (set[i].plane_count == 2) {
if (set[i].plane_states[1]->format
if (context->stream_status[i].plane_count == 2) {
if (context->stream_status[i].plane_states[1]->format
< SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
return false;
if (set[i].plane_states[1]->src_rect.width > 1920
|| set[i].plane_states[1]->src_rect.height > 1080)
if (context->stream_status[i].plane_states[1]->src_rect.width > 1920
|| context->stream_status[i].plane_states[1]->src_rect.height > 1080)
return false;
if (set[i].stream->timing.pixel_encoding != PIXEL_ENCODING_RGB)
if (context->streams[i]->timing.pixel_encoding != PIXEL_ENCODING_RGB)
return false;
}
}
......@@ -914,12 +913,9 @@ static bool dce110_validate_surface_sets(
enum dc_status dce110_validate_global(
struct dc *dc,
const struct dc_validation_set set[],
int set_count,
struct validate_context *old_context,
struct validate_context *context)
{
if (!dce110_validate_surface_sets(set, set_count))
if (!dce110_validate_surface_sets(context))
return DC_FAIL_SURFACE_VALIDATE;
return DC_OK;
......
......@@ -855,19 +855,18 @@ enum dc_status resource_map_phy_clock_resources(
}
static bool dce112_validate_surface_sets(
const struct dc_validation_set set[],
int set_count)
struct validate_context *context)
{
int i;
for (i = 0; i < set_count; i++) {
if (set[i].plane_count == 0)
for (i = 0; i < context->stream_count; i++) {
if (context->stream_status[i].plane_count == 0)
continue;
if (set[i].plane_count > 1)
if (context->stream_status[i].plane_count > 1)
return false;
if (set[i].plane_states[0]->format
if (context->stream_status[i].plane_states[0]->format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
return false;
}
......@@ -928,12 +927,9 @@ enum dc_status dce112_validate_guaranteed(
enum dc_status dce112_validate_global(
struct dc *dc,
const struct dc_validation_set set[],
int set_count,
struct validate_context *old_context,
struct validate_context *context)
{
if (!dce112_validate_surface_sets(set, set_count))
if (!dce112_validate_surface_sets(context))
return DC_FAIL_SURFACE_VALIDATE;
return DC_OK;
......
......@@ -716,19 +716,18 @@ bool dce80_validate_bandwidth(
}
static bool dce80_validate_surface_sets(
const struct dc_validation_set set[],
int set_count)
struct validate_context *context)
{
int i;
for (i = 0; i < set_count; i++) {
if (set[i].plane_count == 0)
for (i = 0; i < context->stream_count; i++) {
if (context->stream_status[i].plane_count == 0)
continue;
if (set[i].plane_count > 1)
if (context->stream_status[i].plane_count > 1)
return false;
if (set[i].plane_states[0]->format
if (context->stream_status[i].plane_states[0]->format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
return false;
}
......@@ -738,12 +737,9 @@ static bool dce80_validate_surface_sets(
enum dc_status dce80_validate_global(
struct dc *dc,
const struct dc_validation_set set[],
int set_count,
struct validate_context *old_context,
struct validate_context *context)
{
if (!dce80_validate_surface_sets(set, set_count))
if (!dce80_validate_surface_sets(context))
return DC_FAIL_SURFACE_VALIDATE;
return DC_OK;
......
......@@ -99,9 +99,6 @@ struct resource_funcs {
enum dc_status (*validate_global)(
struct dc *dc,
const struct dc_validation_set set[],
int set_count,
struct validate_context *old_context,
struct validate_context *context);
struct pipe_ctx *(*acquire_idle_pipe_for_layer)(
......
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