|
|
|
|
@@ -257,25 +257,24 @@ 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)
|
|
|
|
|
struct dc_state *context)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
uint32_t dentist_dispclk_wdivider_readback = 0;
|
|
|
|
|
struct dc *dc = clk_mgr->base.ctx->dc;
|
|
|
|
|
|
|
|
|
|
if (old_dispclk_khz == 0 || clk_mgr->base.clks.dispclk_khz == 0)
|
|
|
|
|
if (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);
|
|
|
|
|
REG_GET(DENTIST_DISPCLK_CNTL,
|
|
|
|
|
DENTIST_DISPCLK_WDIVIDER, &old_dispclk_wdivider);
|
|
|
|
|
|
|
|
|
|
/* When changing divider to or from 127, some extra programming is required to prevent corruption */
|
|
|
|
|
if (old_dispclk_wdivider == 127 && new_dispclk_wdivider != 127) {
|
|
|
|
|
@@ -314,6 +313,17 @@ static void dcn32_update_clocks_update_dentist(
|
|
|
|
|
if (clk_mgr->smu_present)
|
|
|
|
|
dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DISPCLK, khz_to_mhz_ceil(temp_dispclk_khz));
|
|
|
|
|
|
|
|
|
|
if (dc->debug.override_dispclk_programming) {
|
|
|
|
|
REG_GET(DENTIST_DISPCLK_CNTL,
|
|
|
|
|
DENTIST_DISPCLK_WDIVIDER, &dentist_dispclk_wdivider_readback);
|
|
|
|
|
|
|
|
|
|
if (dentist_dispclk_wdivider_readback != 126) {
|
|
|
|
|
REG_UPDATE(DENTIST_DISPCLK_CNTL,
|
|
|
|
|
DENTIST_DISPCLK_WDIVIDER, 126);
|
|
|
|
|
REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
@@ -341,6 +351,18 @@ static void dcn32_update_clocks_update_dentist(
|
|
|
|
|
/* 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));
|
|
|
|
|
|
|
|
|
|
if (dc->debug.override_dispclk_programming) {
|
|
|
|
|
REG_GET(DENTIST_DISPCLK_CNTL,
|
|
|
|
|
DENTIST_DISPCLK_WDIVIDER, &dentist_dispclk_wdivider_readback);
|
|
|
|
|
|
|
|
|
|
if (dentist_dispclk_wdivider_readback > new_dispclk_wdivider) {
|
|
|
|
|
REG_UPDATE(DENTIST_DISPCLK_CNTL,
|
|
|
|
|
DENTIST_DISPCLK_WDIVIDER, new_dispclk_wdivider);
|
|
|
|
|
REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
|
|
|
|
|
@@ -361,7 +383,6 @@ 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;
|
|
|
|
|
@@ -504,13 +525,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);
|
|
|
|
|
dcn32_update_clocks_update_dentist(clk_mgr, context, old_dispclk_khz);
|
|
|
|
|
dcn32_update_clocks_update_dentist(clk_mgr, context);
|
|
|
|
|
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)
|
|
|
|
|
dcn32_update_clocks_update_dentist(clk_mgr, context, old_dispclk_khz);
|
|
|
|
|
dcn32_update_clocks_update_dentist(clk_mgr, context);
|
|
|
|
|
/* 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.
|
|
|
|
|
|