drm/amd/display: decouple front and backend pgm using dpms_off as backend enable flag
Signed-off-by: Samson Tam <Samson.Tam@amd.com> Reviewed-by: Anthony Koo <Anthony.Koo@amd.com> Acked-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
69ff884526
commit
1e7e86c43f
|
@ -1270,6 +1270,9 @@ static enum surface_update_type check_update_surfaces_for_stream(
|
||||||
|
|
||||||
if (stream_update->abm_level)
|
if (stream_update->abm_level)
|
||||||
return UPDATE_TYPE_FULL;
|
return UPDATE_TYPE_FULL;
|
||||||
|
|
||||||
|
if (stream_update->dpms_off)
|
||||||
|
return UPDATE_TYPE_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0 ; i < surface_count; i++) {
|
for (i = 0 ; i < surface_count; i++) {
|
||||||
|
@ -1324,6 +1327,71 @@ static struct dc_stream_status *stream_get_status(
|
||||||
static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL;
|
static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL;
|
||||||
|
|
||||||
|
|
||||||
|
static void commit_planes_do_stream_update(struct dc *dc,
|
||||||
|
struct dc_stream_state *stream,
|
||||||
|
struct dc_stream_update *stream_update,
|
||||||
|
enum surface_update_type update_type,
|
||||||
|
struct dc_state *context)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
|
||||||
|
// Stream updates
|
||||||
|
for (j = 0; j < dc->res_pool->pipe_count; j++) {
|
||||||
|
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
|
||||||
|
|
||||||
|
if (!pipe_ctx->top_pipe &&
|
||||||
|
pipe_ctx->stream &&
|
||||||
|
pipe_ctx->stream == stream) {
|
||||||
|
|
||||||
|
/* Fast update*/
|
||||||
|
// VRR program can be done as part of FAST UPDATE
|
||||||
|
if (stream_update->adjust)
|
||||||
|
dc->hwss.set_drr(&pipe_ctx, 1,
|
||||||
|
stream_update->adjust->v_total_min,
|
||||||
|
stream_update->adjust->v_total_max);
|
||||||
|
|
||||||
|
/* Full fe update*/
|
||||||
|
if (update_type == UPDATE_TYPE_FAST)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (stream_update->dpms_off) {
|
||||||
|
if (*stream_update->dpms_off) {
|
||||||
|
core_link_disable_stream(pipe_ctx, KEEP_ACQUIRED_RESOURCE);
|
||||||
|
dc->hwss.pplib_apply_display_requirements(
|
||||||
|
dc, dc->current_state);
|
||||||
|
} else {
|
||||||
|
dc->hwss.pplib_apply_display_requirements(
|
||||||
|
dc, dc->current_state);
|
||||||
|
core_link_enable_stream(dc->current_state, pipe_ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream_update->abm_level && pipe_ctx->stream_res.abm) {
|
||||||
|
if (pipe_ctx->stream_res.tg->funcs->is_blanked) {
|
||||||
|
// if otg funcs defined check if blanked before programming
|
||||||
|
if (!pipe_ctx->stream_res.tg->funcs->is_blanked(pipe_ctx->stream_res.tg))
|
||||||
|
pipe_ctx->stream_res.abm->funcs->set_abm_level(
|
||||||
|
pipe_ctx->stream_res.abm, stream->abm_level);
|
||||||
|
} else
|
||||||
|
pipe_ctx->stream_res.abm->funcs->set_abm_level(
|
||||||
|
pipe_ctx->stream_res.abm, stream->abm_level);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream_update->periodic_fn_vsync_delta &&
|
||||||
|
pipe_ctx->stream_res.tg->funcs->program_vline_interrupt)
|
||||||
|
pipe_ctx->stream_res.tg->funcs->program_vline_interrupt(
|
||||||
|
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing,
|
||||||
|
pipe_ctx->stream->periodic_fn_vsync_delta);
|
||||||
|
|
||||||
|
if (stream_update->hdr_static_metadata ||
|
||||||
|
stream_update->vrr_infopacket) {
|
||||||
|
resource_build_info_frame(pipe_ctx);
|
||||||
|
dc->hwss.update_info_frame(pipe_ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void commit_planes_for_stream(struct dc *dc,
|
static void commit_planes_for_stream(struct dc *dc,
|
||||||
struct dc_surface_update *srf_updates,
|
struct dc_surface_update *srf_updates,
|
||||||
int surface_count,
|
int surface_count,
|
||||||
|
@ -1340,15 +1408,20 @@ static void commit_planes_for_stream(struct dc *dc,
|
||||||
context_clock_trace(dc, context);
|
context_clock_trace(dc, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stream updates
|
||||||
|
if (stream_update)
|
||||||
|
commit_planes_do_stream_update(dc, stream, stream_update, update_type, context);
|
||||||
|
|
||||||
if (surface_count == 0) {
|
if (surface_count == 0) {
|
||||||
/*
|
/*
|
||||||
* In case of turning off screen, no need to program front end a second time.
|
* In case of turning off screen, no need to program front end a second time.
|
||||||
* just return after program front end.
|
* just return after program blank.
|
||||||
*/
|
*/
|
||||||
dc->hwss.apply_ctx_for_surface(dc, stream, surface_count, context);
|
dc->hwss.apply_ctx_for_surface(dc, stream, 0, context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update Type FULL, Surface updates
|
||||||
for (j = 0; j < dc->res_pool->pipe_count; j++) {
|
for (j = 0; j < dc->res_pool->pipe_count; j++) {
|
||||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
|
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
|
||||||
|
|
||||||
|
@ -1362,13 +1435,6 @@ static void commit_planes_for_stream(struct dc *dc,
|
||||||
if (!pipe_ctx->plane_state)
|
if (!pipe_ctx->plane_state)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Fast update*/
|
|
||||||
// VRR program can be done as part of FAST UPDATE
|
|
||||||
if (stream_update && stream_update->adjust)
|
|
||||||
dc->hwss.set_drr(&pipe_ctx, 1,
|
|
||||||
stream_update->adjust->v_total_min,
|
|
||||||
stream_update->adjust->v_total_max);
|
|
||||||
|
|
||||||
/* Full fe update*/
|
/* Full fe update*/
|
||||||
if (update_type == UPDATE_TYPE_FAST)
|
if (update_type == UPDATE_TYPE_FAST)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1378,34 +1444,18 @@ static void commit_planes_for_stream(struct dc *dc,
|
||||||
|
|
||||||
dc->hwss.apply_ctx_for_surface(
|
dc->hwss.apply_ctx_for_surface(
|
||||||
dc, pipe_ctx->stream, stream_status->plane_count, context);
|
dc, pipe_ctx->stream, stream_status->plane_count, context);
|
||||||
|
|
||||||
if (stream_update && stream_update->abm_level && pipe_ctx->stream_res.abm) {
|
|
||||||
if (pipe_ctx->stream_res.tg->funcs->is_blanked) {
|
|
||||||
// if otg funcs defined check if blanked before programming
|
|
||||||
if (!pipe_ctx->stream_res.tg->funcs->is_blanked(pipe_ctx->stream_res.tg))
|
|
||||||
pipe_ctx->stream_res.abm->funcs->set_abm_level(
|
|
||||||
pipe_ctx->stream_res.abm, stream->abm_level);
|
|
||||||
} else
|
|
||||||
pipe_ctx->stream_res.abm->funcs->set_abm_level(
|
|
||||||
pipe_ctx->stream_res.abm, stream->abm_level);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream_update && stream_update->periodic_fn_vsync_delta &&
|
|
||||||
pipe_ctx->stream_res.tg->funcs->program_vline_interrupt)
|
|
||||||
pipe_ctx->stream_res.tg->funcs->program_vline_interrupt(
|
|
||||||
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing,
|
|
||||||
pipe_ctx->stream->periodic_fn_vsync_delta);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update_type == UPDATE_TYPE_FULL)
|
if (update_type == UPDATE_TYPE_FULL)
|
||||||
context_timing_trace(dc, &context->res_ctx);
|
context_timing_trace(dc, &context->res_ctx);
|
||||||
|
|
||||||
|
// Update Type FAST, Surface updates
|
||||||
|
if (update_type == UPDATE_TYPE_FAST) {
|
||||||
/* Lock the top pipe while updating plane addrs, since freesync requires
|
/* Lock the top pipe while updating plane addrs, since freesync requires
|
||||||
* plane addr update event triggers to be synchronized.
|
* plane addr update event triggers to be synchronized.
|
||||||
* top_pipe_to_program is expected to never be NULL
|
* top_pipe_to_program is expected to never be NULL
|
||||||
*/
|
*/
|
||||||
if (update_type == UPDATE_TYPE_FAST) {
|
|
||||||
dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true);
|
dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true);
|
||||||
|
|
||||||
/* Perform requested Updates */
|
/* Perform requested Updates */
|
||||||
|
@ -1428,21 +1478,6 @@ static void commit_planes_for_stream(struct dc *dc,
|
||||||
|
|
||||||
dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
|
dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream && stream_update)
|
|
||||||
for (j = 0; j < dc->res_pool->pipe_count; j++) {
|
|
||||||
struct pipe_ctx *pipe_ctx =
|
|
||||||
&context->res_ctx.pipe_ctx[j];
|
|
||||||
|
|
||||||
if (pipe_ctx->stream != stream)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (stream_update->hdr_static_metadata ||
|
|
||||||
(stream_update->vrr_infopacket)) {
|
|
||||||
resource_build_info_frame(pipe_ctx);
|
|
||||||
dc->hwss.update_info_frame(pipe_ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dc_commit_updates_for_stream(struct dc *dc,
|
void dc_commit_updates_for_stream(struct dc *dc,
|
||||||
|
|
|
@ -2458,9 +2458,43 @@ void core_link_enable_stream(
|
||||||
struct pipe_ctx *pipe_ctx)
|
struct pipe_ctx *pipe_ctx)
|
||||||
{
|
{
|
||||||
struct dc *core_dc = pipe_ctx->stream->ctx->dc;
|
struct dc *core_dc = pipe_ctx->stream->ctx->dc;
|
||||||
|
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||||
enum dc_status status;
|
enum dc_status status;
|
||||||
DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
|
DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
|
||||||
|
|
||||||
|
if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) {
|
||||||
|
stream->sink->link->link_enc->funcs->setup(
|
||||||
|
stream->sink->link->link_enc,
|
||||||
|
pipe_ctx->stream->signal);
|
||||||
|
pipe_ctx->stream_res.stream_enc->funcs->setup_stereo_sync(
|
||||||
|
pipe_ctx->stream_res.stream_enc,
|
||||||
|
pipe_ctx->stream_res.tg->inst,
|
||||||
|
stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||||
|
pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(
|
||||||
|
pipe_ctx->stream_res.stream_enc,
|
||||||
|
&stream->timing,
|
||||||
|
stream->output_color_space);
|
||||||
|
|
||||||
|
if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
|
||||||
|
pipe_ctx->stream_res.stream_enc->funcs->hdmi_set_stream_attribute(
|
||||||
|
pipe_ctx->stream_res.stream_enc,
|
||||||
|
&stream->timing,
|
||||||
|
stream->phy_pix_clk,
|
||||||
|
pipe_ctx->stream_res.audio != NULL);
|
||||||
|
|
||||||
|
if (dc_is_dvi_signal(pipe_ctx->stream->signal))
|
||||||
|
pipe_ctx->stream_res.stream_enc->funcs->dvi_set_stream_attribute(
|
||||||
|
pipe_ctx->stream_res.stream_enc,
|
||||||
|
&stream->timing,
|
||||||
|
(pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ?
|
||||||
|
true : false);
|
||||||
|
|
||||||
|
resource_build_info_frame(pipe_ctx);
|
||||||
|
core_dc->hwss.update_info_frame(pipe_ctx);
|
||||||
|
|
||||||
/* eDP lit up by bios already, no need to enable again. */
|
/* eDP lit up by bios already, no need to enable again. */
|
||||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
|
if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
|
||||||
core_dc->apply_edp_fast_boot_optimization) {
|
core_dc->apply_edp_fast_boot_optimization) {
|
||||||
|
|
|
@ -1615,6 +1615,9 @@ static bool are_stream_backends_same(
|
||||||
if (is_hdr_static_meta_changed(stream_a, stream_b))
|
if (is_hdr_static_meta_changed(stream_a, stream_b))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (stream_a->dpms_off != stream_b->dpms_off)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2716,6 +2719,9 @@ bool pipe_need_reprogram(
|
||||||
if (is_hdr_static_meta_changed(pipe_ctx_old->stream, pipe_ctx->stream))
|
if (is_hdr_static_meta_changed(pipe_ctx_old->stream, pipe_ctx->stream))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (pipe_ctx_old->stream->dpms_off != pipe_ctx->stream->dpms_off)
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,8 @@ struct dc_stream_update {
|
||||||
unsigned long long *periodic_fn_vsync_delta;
|
unsigned long long *periodic_fn_vsync_delta;
|
||||||
struct dc_crtc_timing_adjust *adjust;
|
struct dc_crtc_timing_adjust *adjust;
|
||||||
struct dc_info_packet *vrr_infopacket;
|
struct dc_info_packet *vrr_infopacket;
|
||||||
|
|
||||||
|
bool *dpms_off;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool dc_is_stream_unchanged(
|
bool dc_is_stream_unchanged(
|
||||||
|
|
|
@ -1349,8 +1349,6 @@ static enum dc_status apply_single_controller_ctx_to_hw(
|
||||||
struct dc *dc)
|
struct dc *dc)
|
||||||
{
|
{
|
||||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||||
struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx.
|
|
||||||
pipe_ctx[pipe_ctx->pipe_idx];
|
|
||||||
|
|
||||||
if (pipe_ctx->stream_res.audio != NULL) {
|
if (pipe_ctx->stream_res.audio != NULL) {
|
||||||
struct audio_output audio_output;
|
struct audio_output audio_output;
|
||||||
|
@ -1405,46 +1403,12 @@ static enum dc_status apply_single_controller_ctx_to_hw(
|
||||||
stream->timing.display_color_depth,
|
stream->timing.display_color_depth,
|
||||||
pipe_ctx->stream->signal);
|
pipe_ctx->stream->signal);
|
||||||
|
|
||||||
if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL)
|
|
||||||
stream->sink->link->link_enc->funcs->setup(
|
|
||||||
stream->sink->link->link_enc,
|
|
||||||
pipe_ctx->stream->signal);
|
|
||||||
|
|
||||||
if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL)
|
|
||||||
pipe_ctx->stream_res.stream_enc->funcs->setup_stereo_sync(
|
|
||||||
pipe_ctx->stream_res.stream_enc,
|
|
||||||
pipe_ctx->stream_res.tg->inst,
|
|
||||||
stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE);
|
|
||||||
|
|
||||||
|
|
||||||
pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
|
pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
|
||||||
pipe_ctx->stream_res.opp,
|
pipe_ctx->stream_res.opp,
|
||||||
&stream->bit_depth_params,
|
&stream->bit_depth_params,
|
||||||
&stream->clamping);
|
&stream->clamping);
|
||||||
|
|
||||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
if (!stream->dpms_off)
|
||||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(
|
|
||||||
pipe_ctx->stream_res.stream_enc,
|
|
||||||
&stream->timing,
|
|
||||||
stream->output_color_space);
|
|
||||||
|
|
||||||
if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
|
|
||||||
pipe_ctx->stream_res.stream_enc->funcs->hdmi_set_stream_attribute(
|
|
||||||
pipe_ctx->stream_res.stream_enc,
|
|
||||||
&stream->timing,
|
|
||||||
stream->phy_pix_clk,
|
|
||||||
pipe_ctx->stream_res.audio != NULL);
|
|
||||||
|
|
||||||
if (dc_is_dvi_signal(pipe_ctx->stream->signal))
|
|
||||||
pipe_ctx->stream_res.stream_enc->funcs->dvi_set_stream_attribute(
|
|
||||||
pipe_ctx->stream_res.stream_enc,
|
|
||||||
&stream->timing,
|
|
||||||
(pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ?
|
|
||||||
true : false);
|
|
||||||
|
|
||||||
resource_build_info_frame(pipe_ctx);
|
|
||||||
dce110_update_info_frame(pipe_ctx);
|
|
||||||
if (!pipe_ctx_old->stream)
|
|
||||||
core_link_enable_stream(context, pipe_ctx);
|
core_link_enable_stream(context, pipe_ctx);
|
||||||
|
|
||||||
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
|
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
|
||||||
|
|
Loading…
Reference in New Issue