mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
drm/amd/display: Allow DTBCLK disable for DCN35
[Why] DTBCLK is enabled on idle and it will burn power. [How] There's a few issues here: - Always enabling DTBCLK on clock manager init - Setting refclk when DTBCLK is supposed to be disabled - Not applying the correct calculated version refclk, but instead the base value which might be zero On dtbclk_en change we'll message PMFW to enable or disable the clock accordingly. The DTBDTO will be then based on refclk, but it will be set to the default fixed value if there was nothing calculated in DML despite the clock being considered enabled. Reviewed-by: Charlene Liu <charlene.liu@amd.com> Acked-by: Tom Chung <chiahsuan.chung@amd.com> Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
2161e09cd0
commit
27750e176a
1 changed files with 12 additions and 15 deletions
|
@ -232,6 +232,10 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||
if (dc->work_arounds.skip_clock_update)
|
||||
return;
|
||||
|
||||
/* DTBCLK is fixed, so set a default if unspecified. */
|
||||
if (new_clocks->dtbclk_en && !new_clocks->ref_dtbclk_khz)
|
||||
new_clocks->ref_dtbclk_khz = 600000;
|
||||
|
||||
/*
|
||||
* if it is safe to lower, but we are already in the lower state, we don't have to do anything
|
||||
* also if safe to lower is false, we just go in the higher state
|
||||
|
@ -265,8 +269,10 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||
|
||||
if (!clk_mgr_base->clks.dtbclk_en && new_clocks->dtbclk_en) {
|
||||
dcn35_smu_set_dtbclk(clk_mgr, true);
|
||||
dcn35_update_clocks_update_dtb_dto(clk_mgr, context, clk_mgr_base->clks.ref_dtbclk_khz);
|
||||
clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en;
|
||||
|
||||
dcn35_update_clocks_update_dtb_dto(clk_mgr, context, new_clocks->ref_dtbclk_khz);
|
||||
clk_mgr_base->clks.ref_dtbclk_khz = new_clocks->ref_dtbclk_khz;
|
||||
}
|
||||
|
||||
/* check that we're not already in D0 */
|
||||
|
@ -314,17 +320,12 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||
update_dispclk = true;
|
||||
}
|
||||
|
||||
if (!new_clocks->dtbclk_en) {
|
||||
new_clocks->ref_dtbclk_khz = 600000;
|
||||
}
|
||||
|
||||
/* clock limits are received with MHz precision, divide by 1000 to prevent setting clocks at every call */
|
||||
if (!dc->debug.disable_dtb_ref_clk_switch &&
|
||||
should_set_clock(safe_to_lower, new_clocks->ref_dtbclk_khz / 1000, clk_mgr_base->clks.ref_dtbclk_khz / 1000)) {
|
||||
/* DCCG requires KHz precision for DTBCLK */
|
||||
dcn35_smu_set_dtbclk(clk_mgr, true);
|
||||
|
||||
dcn35_update_clocks_update_dtb_dto(clk_mgr, context, clk_mgr_base->clks.ref_dtbclk_khz);
|
||||
should_set_clock(safe_to_lower, new_clocks->ref_dtbclk_khz / 1000,
|
||||
clk_mgr_base->clks.ref_dtbclk_khz / 1000)) {
|
||||
dcn35_update_clocks_update_dtb_dto(clk_mgr, context, new_clocks->ref_dtbclk_khz);
|
||||
clk_mgr_base->clks.ref_dtbclk_khz = new_clocks->ref_dtbclk_khz;
|
||||
}
|
||||
|
||||
if (dpp_clock_lowered) {
|
||||
|
@ -1048,12 +1049,8 @@ void dcn35_clk_mgr_construct(
|
|||
dcn35_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, &clk_mgr->base.base, &log_info);
|
||||
|
||||
clk_mgr->base.base.dprefclk_khz = dcn35_smu_get_dprefclk(&clk_mgr->base);
|
||||
clk_mgr->base.base.clks.ref_dtbclk_khz = dcn35_smu_get_dtbclk(&clk_mgr->base);
|
||||
clk_mgr->base.base.clks.ref_dtbclk_khz = 600000;
|
||||
|
||||
if (!clk_mgr->base.base.clks.ref_dtbclk_khz)
|
||||
dcn35_smu_set_dtbclk(&clk_mgr->base, true);
|
||||
|
||||
clk_mgr->base.base.clks.dtbclk_en = true;
|
||||
dce_clock_read_ss_info(&clk_mgr->base);
|
||||
/*when clk src is from FCH, it could have ss, same clock src as DPREF clk*/
|
||||
|
||||
|
|
Loading…
Reference in a new issue