Skip to content

Commit

Permalink
drm/amd/display: update navi to use new surface programming behaviour
Browse files Browse the repository at this point in the history
New behaviour will track global updates and update any hw that isn't
related to current stream being updated.

This should fix any issues caused by pipe split pipes being taken
by other streams.

Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  • Loading branch information
Dmytro Laktyushkin authored and Alex Deucher committed Sep 13, 2019
1 parent 25409b3 commit b6e881c
Show file tree
Hide file tree
Showing 5 changed files with 510 additions and 198 deletions.
6 changes: 4 additions & 2 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -5866,6 +5866,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
/* Update the planes if changed or disable if we don't have any. */
if ((planes_count || acrtc_state->active_planes == 0) &&
acrtc_state->stream) {
bundle->stream_update.stream = acrtc_state->stream;
if (new_pcrtc_state->mode_changed) {
bundle->stream_update.src = acrtc_state->stream->src;
bundle->stream_update.dst = acrtc_state->stream->dst;
Expand Down Expand Up @@ -6287,9 +6288,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
if (!scaling_changed && !abm_changed && !hdr_changed)
continue;

stream_update.stream = dm_new_crtc_state->stream;
if (scaling_changed) {
update_stream_scaling_settings(&dm_new_con_state->base.crtc->mode,
dm_new_con_state, (struct dc_stream_state *)dm_new_crtc_state->stream);
dm_new_con_state, dm_new_crtc_state->stream);

stream_update.src = dm_new_crtc_state->stream->src;
stream_update.dst = dm_new_crtc_state->stream->dst;
Expand Down Expand Up @@ -7158,7 +7160,7 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,

status = dc_stream_get_status_from_state(old_dm_state->context,
new_dm_crtc_state->stream);

stream_update.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.
Expand Down
105 changes: 67 additions & 38 deletions drivers/gpu/drm/amd/display/dc/core/dc.c
Original file line number Diff line number Diff line change
Expand Up @@ -761,8 +761,13 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);
#endif
dc->hwss.apply_ctx_for_surface(dc, old_stream, 0, dangling_context);
if (dc->hwss.apply_ctx_for_surface)
dc->hwss.apply_ctx_for_surface(dc, old_stream, 0, dangling_context);
}
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
if (dc->hwss.program_front_end_for_ctx)
dc->hwss.program_front_end_for_ctx(dc, dangling_context);
#endif
}

current_ctx = dc->current_state;
Expand Down Expand Up @@ -1073,15 +1078,20 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
/* re-program planes for existing stream, in case we need to
* free up plane resource for later use
*/
for (i = 0; i < context->stream_count; i++) {
if (context->streams[i]->mode_changed)
continue;
if (dc->hwss.apply_ctx_for_surface)
for (i = 0; i < context->stream_count; i++) {
if (context->streams[i]->mode_changed)
continue;

dc->hwss.apply_ctx_for_surface(
dc, context->streams[i],
context->stream_status[i].plane_count,
context); /* use new pipe config in new context */
}
dc->hwss.apply_ctx_for_surface(
dc, context->streams[i],
context->stream_status[i].plane_count,
context); /* use new pipe config in new context */
}
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
if (dc->hwss.program_front_end_for_ctx)
dc->hwss.program_front_end_for_ctx(dc, context);
#endif

/* Program hardware */
for (i = 0; i < dc->res_pool->pipe_count; i++) {
Expand All @@ -1100,16 +1110,21 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
}

/* Program all planes within new context*/
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
if (dc->hwss.program_front_end_for_ctx)
dc->hwss.program_front_end_for_ctx(dc, context);
#endif
for (i = 0; i < context->stream_count; i++) {
const struct dc_link *link = context->streams[i]->link;

if (!context->streams[i]->mode_changed)
continue;

dc->hwss.apply_ctx_for_surface(
dc, context->streams[i],
context->stream_status[i].plane_count,
context);
if (dc->hwss.apply_ctx_for_surface)
dc->hwss.apply_ctx_for_surface(
dc, context->streams[i],
context->stream_status[i].plane_count,
context);

/*
* enable stereo
Expand Down Expand Up @@ -1492,20 +1507,15 @@ static enum surface_update_type det_surface_update(const struct dc *dc,
enum surface_update_type overall_type = UPDATE_TYPE_FAST;
union surface_update_flags *update_flags = &u->surface->update_flags;

update_flags->raw = 0; // Reset all flags

if (u->flip_addr)
update_flags->bits.addr_update = 1;

if (!is_surface_in_context(context, u->surface)) {
update_flags->bits.new_plane = 1;
if (!is_surface_in_context(context, u->surface) || u->surface->force_full_update) {
update_flags->raw = 0xFFFFFFFF;
return UPDATE_TYPE_FULL;
}

if (u->surface->force_full_update) {
update_flags->bits.full_update = 1;
return UPDATE_TYPE_FULL;
}
update_flags->raw = 0; // Reset all flags

type = get_plane_info_update_type(u);
elevate_update_type(&overall_type, type);
Expand Down Expand Up @@ -1563,40 +1573,43 @@ static enum surface_update_type check_update_surfaces_for_stream(
enum surface_update_type overall_type = UPDATE_TYPE_FAST;

if (stream_status == NULL || stream_status->plane_count != surface_count)
return UPDATE_TYPE_FULL;
overall_type = UPDATE_TYPE_FULL;

/* some stream updates require passive update */
if (stream_update) {
if ((stream_update->src.height != 0) &&
(stream_update->src.width != 0))
return UPDATE_TYPE_FULL;
union stream_update_flags *su_flags = &stream_update->stream->update_flags;

if ((stream_update->dst.height != 0) &&
(stream_update->dst.width != 0))
return UPDATE_TYPE_FULL;
if ((stream_update->src.height != 0 && stream_update->src.width != 0) ||
(stream_update->dst.height != 0 && stream_update->dst.width != 0))
su_flags->bits.scaling = 1;

if (stream_update->out_transfer_func)
return UPDATE_TYPE_FULL;
su_flags->bits.out_tf = 1;

if (stream_update->abm_level)
return UPDATE_TYPE_FULL;
su_flags->bits.abm_level = 1;

if (stream_update->dpms_off)
return UPDATE_TYPE_FULL;
su_flags->bits.dpms_off = 1;

if (stream_update->gamut_remap)
su_flags->bits.gamut_remap = 1;

#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
if (stream_update->wb_update)
return UPDATE_TYPE_FULL;
su_flags->bits.wb_update = 1;
#endif
if (su_flags->raw != 0)
overall_type = UPDATE_TYPE_FULL;

if (stream_update->output_csc_transform || stream_update->output_color_space)
su_flags->bits.out_csc = 1;
}

for (i = 0 ; i < surface_count; i++) {
enum surface_update_type type =
det_surface_update(dc, &updates[i]);

if (type == UPDATE_TYPE_FULL)
return type;

elevate_update_type(&overall_type, type);
}

Expand All @@ -1618,13 +1631,18 @@ enum surface_update_type dc_check_update_surfaces_for_stream(
int i;
enum surface_update_type type;

if (stream_update)
stream_update->stream->update_flags.raw = 0;
for (i = 0; i < surface_count; i++)
updates[i].surface->update_flags.raw = 0;

type = check_update_surfaces_for_stream(dc, updates, surface_count, stream_update, stream_status);
if (type == UPDATE_TYPE_FULL)
if (type == UPDATE_TYPE_FULL) {
if (stream_update)
stream_update->stream->update_flags.raw = 0xFFFFFFFF;
for (i = 0; i < surface_count; i++)
updates[i].surface->update_flags.raw = 0xFFFFFFFF;
}

if (type == UPDATE_TYPE_FAST && memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0)
dc->optimized_required = true;
Expand Down Expand Up @@ -2000,7 +2018,13 @@ static void commit_planes_for_stream(struct dc *dc,
* In case of turning off screen, no need to program front end a second time.
* just return after program blank.
*/
dc->hwss.apply_ctx_for_surface(dc, stream, 0, context);
if (dc->hwss.apply_ctx_for_surface)
dc->hwss.apply_ctx_for_surface(dc, stream, 0, context);
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
if (dc->hwss.program_front_end_for_ctx)
dc->hwss.program_front_end_for_ctx(dc, context);
#endif

return;
}

Expand Down Expand Up @@ -2060,10 +2084,15 @@ static void commit_planes_for_stream(struct dc *dc,
stream_status =
stream_get_status(context, pipe_ctx->stream);

dc->hwss.apply_ctx_for_surface(
if (dc->hwss.apply_ctx_for_surface)
dc->hwss.apply_ctx_for_surface(
dc, pipe_ctx->stream, stream_status->plane_count, context);
}
}
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
if (dc->hwss.program_front_end_for_ctx && update_type != UPDATE_TYPE_FAST)
dc->hwss.program_front_end_for_ctx(dc, context);
#endif

// Update Type FAST, Surface updates
if (update_type == UPDATE_TYPE_FAST) {
Expand Down
18 changes: 18 additions & 0 deletions drivers/gpu/drm/amd/display/dc/dc_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,21 @@ struct periodic_interrupt_config {
int lines_offset;
};

union stream_update_flags {
struct {
uint32_t scaling:1;
uint32_t out_tf:1;
uint32_t out_csc:1;
uint32_t abm_level:1;
uint32_t dpms_off:1;
uint32_t gamut_remap:1;
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
uint32_t wb_update:1;
#endif
} bits;

uint32_t raw;
};

struct dc_stream_state {
// sink is deprecated, new code should not reference
Expand Down Expand Up @@ -214,9 +229,12 @@ struct dc_stream_state {
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
bool is_dsc_enabled;
#endif
union stream_update_flags update_flags;
};

struct dc_stream_update {
struct dc_stream_state *stream;

struct rect src;
struct rect dst;
struct dc_transfer_func *out_transfer_func;
Expand Down
Loading

0 comments on commit b6e881c

Please sign in to comment.