|
@@ -1270,6 +1270,9 @@ static enum surface_update_type check_update_surfaces_for_stream(
|
|
|
|
|
|
if (stream_update->abm_level)
|
|
|
return UPDATE_TYPE_FULL;
|
|
|
+
|
|
|
+ if (stream_update->dpms_off)
|
|
|
+ return UPDATE_TYPE_FULL;
|
|
|
}
|
|
|
|
|
|
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 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,
|
|
|
struct dc_surface_update *srf_updates,
|
|
|
int surface_count,
|
|
@@ -1340,15 +1408,20 @@ static void commit_planes_for_stream(struct dc *dc,
|
|
|
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) {
|
|
|
/*
|
|
|
* 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;
|
|
|
}
|
|
|
|
|
|
+ // Update Type FULL, Surface updates
|
|
|
for (j = 0; j < dc->res_pool->pipe_count; 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)
|
|
|
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*/
|
|
|
if (update_type == UPDATE_TYPE_FAST)
|
|
|
continue;
|
|
@@ -1378,34 +1444,18 @@ static void commit_planes_for_stream(struct dc *dc,
|
|
|
|
|
|
dc->hwss.apply_ctx_for_surface(
|
|
|
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)
|
|
|
context_timing_trace(dc, &context->res_ctx);
|
|
|
|
|
|
- /* Lock the top pipe while updating plane addrs, since freesync requires
|
|
|
- * plane addr update event triggers to be synchronized.
|
|
|
- * top_pipe_to_program is expected to never be NULL
|
|
|
- */
|
|
|
+ // Update Type FAST, Surface updates
|
|
|
if (update_type == UPDATE_TYPE_FAST) {
|
|
|
+ /* Lock the top pipe while updating plane addrs, since freesync requires
|
|
|
+ * plane addr update event triggers to be synchronized.
|
|
|
+ * top_pipe_to_program is expected to never be NULL
|
|
|
+ */
|
|
|
dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true);
|
|
|
|
|
|
/* 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);
|
|
|
}
|
|
|
-
|
|
|
- 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,
|