Commit fc41c734 authored by Dillon Varone's avatar Dillon Varone Committed by Alex Deucher

drm/amd/display: Remove DISPCLK dentist programming for dcn32

[WHY?]
For dcn32, SMU handles DISPCLK dentist programming.

[HOW?]
Only use calls to SMU to set DISPCLK.
Tested-by: default avatarDaniel Wheeler <Daniel.Wheeler@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarDillon Varone <Dillon.Varone@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b5c397c8
......@@ -256,6 +256,94 @@ static void dcn32_update_dppclk_dispclk_freq(struct clk_mgr_internal *clk_mgr, s
}
}
static void dcn32_update_clocks_update_dentist(
struct clk_mgr_internal *clk_mgr,
struct dc_state *context,
uint32_t old_dispclk_khz)
{
uint32_t new_disp_divider = 0;
uint32_t old_disp_divider = 0;
uint32_t new_dispclk_wdivider = 0;
uint32_t old_dispclk_wdivider = 0;
uint32_t i;
if (old_dispclk_khz == 0 || clk_mgr->base.clks.dispclk_khz == 0)
return;
new_disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->base.dentist_vco_freq_khz / clk_mgr->base.clks.dispclk_khz;
old_disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->base.dentist_vco_freq_khz / old_dispclk_khz;
new_dispclk_wdivider = dentist_get_did_from_divider(new_disp_divider);
old_dispclk_wdivider = dentist_get_did_from_divider(old_disp_divider);
/* When changing divider to or from 127, some extra programming is required to prevent corruption */
if (old_dispclk_wdivider == 127 && new_dispclk_wdivider != 127) {
for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
uint32_t fifo_level;
struct dccg *dccg = clk_mgr->base.ctx->dc->res_pool->dccg;
struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
int32_t N;
int32_t j;
if (!pipe_ctx->stream)
continue;
/* Virtual encoders don't have this function */
if (!stream_enc->funcs->get_fifo_cal_average_level)
continue;
fifo_level = stream_enc->funcs->get_fifo_cal_average_level(
stream_enc);
N = fifo_level / 4;
dccg->funcs->set_fifo_errdet_ovr_en(
dccg,
true);
for (j = 0; j < N - 4; j++)
dccg->funcs->otg_drop_pixel(
dccg,
pipe_ctx->stream_res.tg->inst);
dccg->funcs->set_fifo_errdet_ovr_en(
dccg,
false);
}
} else if (new_dispclk_wdivider == 127 && old_dispclk_wdivider != 127) {
/* request clock with 126 divider first */
uint32_t temp_disp_divider = dentist_get_divider_from_did(126);
uint32_t temp_dispclk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR * clk_mgr->base.dentist_vco_freq_khz) / temp_disp_divider;
if (clk_mgr->smu_present)
dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DISPCLK, khz_to_mhz_ceil(temp_dispclk_khz));
for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
struct dccg *dccg = clk_mgr->base.ctx->dc->res_pool->dccg;
struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
uint32_t fifo_level;
int32_t N;
int32_t j;
if (!pipe_ctx->stream)
continue;
/* Virtual encoders don't have this function */
if (!stream_enc->funcs->get_fifo_cal_average_level)
continue;
fifo_level = stream_enc->funcs->get_fifo_cal_average_level(
stream_enc);
N = fifo_level / 4;
dccg->funcs->set_fifo_errdet_ovr_en(dccg, true);
for (j = 0; j < 12 - N; j++)
dccg->funcs->otg_add_pixel(dccg,
pipe_ctx->stream_res.tg->inst);
dccg->funcs->set_fifo_errdet_ovr_en(dccg, false);
}
}
/* do requested DISPCLK updates*/
if (clk_mgr->smu_present)
dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DISPCLK, khz_to_mhz_ceil(clk_mgr->base.clks.dispclk_khz));
}
static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
struct dc_state *context,
bool safe_to_lower)
......@@ -274,6 +362,7 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
bool p_state_change_support;
bool fclk_p_state_change_support;
int total_plane_count;
int old_dispclk_khz = clk_mgr_base->clks.dispclk_khz;
if (dc->work_arounds.skip_clock_update)
return;
......@@ -397,9 +486,6 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
if (clk_mgr->smu_present)
dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DISPCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dispclk_khz));
update_dispclk = true;
}
......@@ -419,13 +505,13 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
if (dpp_clock_lowered) {
/* if clock is being lowered, increase DTO before lowering refclk */
dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
dcn20_update_clocks_update_dentist(clk_mgr, context);
dcn32_update_clocks_update_dentist(clk_mgr, context, old_dispclk_khz);
if (clk_mgr->smu_present)
dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DPPCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dppclk_khz));
} else {
/* if clock is being raised, increase refclk before lowering DTO */
if (update_dppclk || update_dispclk)
dcn20_update_clocks_update_dentist(clk_mgr, context);
dcn32_update_clocks_update_dentist(clk_mgr, context, old_dispclk_khz);
/* There is a check inside dcn20_update_clocks_update_dpp_dto which ensures
* that we do not lower dto when it is not safe to lower. We do not need to
* compare the current and new dppclk before calling this function.
......
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