diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 126 |
1 files changed, 57 insertions, 69 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index a444fed94184..22f421e82733 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -307,7 +307,8 @@ void dcn20_init_blank( COLOR_DEPTH_UNDEFINED, &black_color, otg_active_width, - otg_active_height); + otg_active_height, + 0); if (num_opps == 2) { bottom_opp->funcs->opp_set_disp_pattern_generator( @@ -317,7 +318,8 @@ void dcn20_init_blank( COLOR_DEPTH_UNDEFINED, &black_color, otg_active_width, - otg_active_height); + otg_active_height, + 0); } hws->funcs.wait_for_blank_complete(opp); @@ -645,6 +647,9 @@ enum dc_status dcn20_enable_stream_timing( return DC_ERROR_UNEXPECTED; } + if (dc->hwseq->funcs.PLAT_58856_wa && (!dc_is_dp_signal(stream->signal))) + dc->hwseq->funcs.PLAT_58856_wa(context, pipe_ctx); + pipe_ctx->stream_res.tg->funcs->program_timing( pipe_ctx->stream_res.tg, &stream->timing, @@ -974,7 +979,8 @@ void dcn20_blank_pixel_data( stream->timing.display_color_depth, &black_color, width, - height); + height, + 0); for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { odm_pipe->stream_res.opp->funcs->opp_set_disp_pattern_generator( @@ -985,7 +991,8 @@ void dcn20_blank_pixel_data( stream->timing.display_color_depth, &black_color, width, - height); + height, + 0); } if (!blank) @@ -1088,29 +1095,6 @@ void dcn20_enable_plane( // } } - -void dcn20_pipe_control_lock_global( - struct dc *dc, - struct pipe_ctx *pipe, - bool lock) -{ - if (lock) { - pipe->stream_res.tg->funcs->lock_doublebuffer_enable( - pipe->stream_res.tg); - pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg); - } else { - pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg); - pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, - CRTC_STATE_VACTIVE); - pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, - CRTC_STATE_VBLANK); - pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, - CRTC_STATE_VACTIVE); - pipe->stream_res.tg->funcs->lock_doublebuffer_disable( - pipe->stream_res.tg); - } -} - void dcn20_pipe_control_lock( struct dc *dc, struct pipe_ctx *pipe, @@ -1121,7 +1105,7 @@ void dcn20_pipe_control_lock( /* use TG master update lock to lock everything on the TG * therefore only top pipe need to lock */ - if (pipe->top_pipe) + if (!pipe || pipe->top_pipe) return; if (pipe->plane_state != NULL) @@ -1389,6 +1373,7 @@ static void dcn20_update_dchubp_dpp( } if (pipe_ctx->update_flags.bits.viewport || + (context == dc->current_state && plane_state->update_flags.bits.position_change) || (context == dc->current_state && plane_state->update_flags.bits.scaling_change) || (context == dc->current_state && pipe_ctx->stream->update_flags.bits.scaling)) { @@ -1536,48 +1521,32 @@ static void dcn20_program_pipe( } } -static bool does_pipe_need_lock(struct pipe_ctx *pipe) -{ - if ((pipe->plane_state && pipe->plane_state->update_flags.raw) - || pipe->update_flags.raw) - return true; - if (pipe->bottom_pipe) - return does_pipe_need_lock(pipe->bottom_pipe); - - return false; -} - void dcn20_program_front_end_for_ctx( struct dc *dc, struct dc_state *context) { - const unsigned int TIMEOUT_FOR_PIPE_ENABLE_MS = 100; int i; struct dce_hwseq *hws = dc->hwseq; - bool pipe_locked[MAX_PIPES] = {false}; DC_LOGGER_INIT(dc->ctx->logger); - /* Carry over GSL groups in case the context is changing. */ - for (i = 0; i < dc->res_pool->pipe_count; i++) - if (context->res_ctx.pipe_ctx[i].stream == dc->current_state->res_ctx.pipe_ctx[i].stream) - context->res_ctx.pipe_ctx[i].stream_res.gsl_group = - dc->current_state->res_ctx.pipe_ctx[i].stream_res.gsl_group; + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; + + if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe && pipe_ctx->plane_state) { + ASSERT(!pipe_ctx->plane_state->triplebuffer_flips); + if (dc->hwss.program_triplebuffer != NULL && + !dc->debug.disable_tri_buf) { + /*turn off triple buffer for full update*/ + dc->hwss.program_triplebuffer( + dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips); + } + } + } /* Set pipe update flags and lock pipes */ for (i = 0; i < dc->res_pool->pipe_count; i++) dcn20_detect_pipe_changes(&dc->current_state->res_ctx.pipe_ctx[i], &context->res_ctx.pipe_ctx[i]); - for (i = 0; i < dc->res_pool->pipe_count; i++) - if (!context->res_ctx.pipe_ctx[i].top_pipe && - does_pipe_need_lock(&context->res_ctx.pipe_ctx[i])) { - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; - - if (pipe_ctx->update_flags.bits.tg_changed || pipe_ctx->update_flags.bits.enable) - dc->hwss.pipe_control_lock(dc, pipe_ctx, true); - if (!pipe_ctx->update_flags.bits.enable) - dc->hwss.pipe_control_lock(dc, &dc->current_state->res_ctx.pipe_ctx[i], true); - pipe_locked[i] = true; - } /* OTG blank before disabling all front ends */ for (i = 0; i < dc->res_pool->pipe_count; i++) @@ -1615,17 +1584,17 @@ void dcn20_program_front_end_for_ctx( hws->funcs.program_all_writeback_pipes_in_tree(dc, pipe->stream, context); } } +} - /* Unlock all locked pipes */ - for (i = 0; i < dc->res_pool->pipe_count; i++) - if (pipe_locked[i]) { - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; +void dcn20_post_unlock_program_front_end( + struct dc *dc, + struct dc_state *context) +{ + int i; + const unsigned int TIMEOUT_FOR_PIPE_ENABLE_MS = 100; + struct dce_hwseq *hwseq = dc->hwseq; - if (pipe_ctx->update_flags.bits.tg_changed || pipe_ctx->update_flags.bits.enable) - dc->hwss.pipe_control_lock(dc, pipe_ctx, false); - if (!pipe_ctx->update_flags.bits.enable) - dc->hwss.pipe_control_lock(dc, &dc->current_state->res_ctx.pipe_ctx[i], false); - } + DC_LOGGER_INIT(dc->ctx->logger); for (i = 0; i < dc->res_pool->pipe_count; i++) if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable) @@ -1651,11 +1620,26 @@ void dcn20_program_front_end_for_ctx( } /* WA to apply WM setting*/ - if (dc->hwseq->wa.DEGVIDCN21) + if (hwseq->wa.DEGVIDCN21) dc->res_pool->hubbub->funcs->apply_DEDCN21_147_wa(dc->res_pool->hubbub); -} + /* WA for stutter underflow during MPO transitions when adding 2nd plane */ + if (hwseq->wa.disallow_self_refresh_during_multi_plane_transition) { + + if (dc->current_state->stream_status[0].plane_count == 1 && + context->stream_status[0].plane_count > 1) { + + struct timing_generator *tg = dc->res_pool->timing_generators[0]; + + dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub, false); + + hwseq->wa_state.disallow_self_refresh_during_multi_plane_transition_applied = true; + hwseq->wa_state.disallow_self_refresh_during_multi_plane_transition_applied_on_frame = tg->funcs->get_frame_count(tg); + } + } +} + void dcn20_prepare_bandwidth( struct dc *dc, struct dc_state *context) @@ -1668,7 +1652,7 @@ void dcn20_prepare_bandwidth( false); /* program dchubbub watermarks */ - hubbub->funcs->program_watermarks(hubbub, + dc->wm_optimized_required = hubbub->funcs->program_watermarks(hubbub, &context->bw_ctx.bw.dcn.watermarks, dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000, false); @@ -2052,6 +2036,10 @@ static void dcn20_reset_back_end_for_pipe( * parent pipe. */ if (pipe_ctx->top_pipe == NULL) { + + if (pipe_ctx->stream_res.abm) + pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm); + pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg); pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false); |