drm/amd/display: Add a check for idle power optimization
[why] Need a helper function to check idle power is allowed so that dc doesn't access any registers that are power-gated. [how] Implement helper function to check idle power optimization. Enable a hook to check if detection is allowed. V2: Add function hooks for set and get idle states. Check if function hook was properly initialized. Reviewed-by: Aric Cyr <aric.cyr@amd.com> Reviewed-by: Nicholas Choi <nicholas.choi@amd.com> Acked-by: Roman Li <roman.li@amd.com> Signed-off-by: Sung Joon Kim <sungkim@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
d5f9a92bd1
commit
d591284288
@ -4884,6 +4884,9 @@ void dc_allow_idle_optimizations(struct dc *dc, bool allow)
|
||||
if (dc->debug.disable_idle_power_optimizations)
|
||||
return;
|
||||
|
||||
if (dc->caps.ips_support && dc->config.disable_ips)
|
||||
return;
|
||||
|
||||
if (dc->clk_mgr != NULL && dc->clk_mgr->funcs->is_smu_present)
|
||||
if (!dc->clk_mgr->funcs->is_smu_present(dc->clk_mgr))
|
||||
return;
|
||||
@ -4895,6 +4898,26 @@ void dc_allow_idle_optimizations(struct dc *dc, bool allow)
|
||||
dc->idle_optimizations_allowed = allow;
|
||||
}
|
||||
|
||||
bool dc_dmub_is_ips_idle_state(struct dc *dc)
|
||||
{
|
||||
uint32_t idle_state = 0;
|
||||
|
||||
if (dc->debug.disable_idle_power_optimizations)
|
||||
return false;
|
||||
|
||||
if (!dc->caps.ips_support || dc->config.disable_ips)
|
||||
return false;
|
||||
|
||||
if (dc->hwss.get_idle_state)
|
||||
idle_state = dc->hwss.get_idle_state(dc);
|
||||
|
||||
if ((idle_state & DMUB_IPS1_ALLOW_MASK) ||
|
||||
(idle_state & DMUB_IPS2_ALLOW_MASK))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* set min and max memory clock to lowest and highest DPM level, respectively */
|
||||
void dc_unlock_memory_clock_frequency(struct dc *dc)
|
||||
{
|
||||
|
@ -2315,6 +2315,7 @@ bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, struct dc_plane_
|
||||
struct dc_cursor_attributes *cursor_attr);
|
||||
|
||||
void dc_allow_idle_optimizations(struct dc *dc, bool allow);
|
||||
bool dc_dmub_is_ips_idle_state(struct dc *dc);
|
||||
|
||||
/* set min and max memory clock to lowest and highest DPM level, respectively */
|
||||
void dc_unlock_memory_clock_frequency(struct dc *dc);
|
||||
|
@ -585,7 +585,9 @@ void dcn31_reset_hw_ctx_wrap(
|
||||
struct clock_source *old_clk = pipe_ctx_old->clock_source;
|
||||
|
||||
/* Reset pipe which is seamless boot stream. */
|
||||
if (!pipe_ctx_old->plane_state) {
|
||||
if (!pipe_ctx_old->plane_state &&
|
||||
dc->res_pool->hubbub->funcs->program_det_size &&
|
||||
dc->res_pool->hubbub->funcs->wait_for_det_apply) {
|
||||
dc->res_pool->hubbub->funcs->program_det_size(
|
||||
dc->res_pool->hubbub, pipe_ctx_old->plane_res.hubp->inst, 0);
|
||||
/* Wait det size changed. */
|
||||
|
@ -629,12 +629,8 @@ void dcn35_power_down_on_boot(struct dc *dc)
|
||||
if (dc->clk_mgr->funcs->set_low_power_state)
|
||||
dc->clk_mgr->funcs->set_low_power_state(dc->clk_mgr);
|
||||
|
||||
if (dc->clk_mgr->clks.pwr_state == DCN_PWR_STATE_LOW_POWER) {
|
||||
if (!dc->idle_optimizations_allowed) {
|
||||
dc_dmub_srv_notify_idle(dc, true);
|
||||
dc->idle_optimizations_allowed = true;
|
||||
}
|
||||
}
|
||||
if (dc->clk_mgr->clks.pwr_state == DCN_PWR_STATE_LOW_POWER)
|
||||
dc_allow_idle_optimizations(dc, true);
|
||||
}
|
||||
|
||||
bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable)
|
||||
|
@ -418,6 +418,8 @@ struct hw_sequencer_funcs {
|
||||
struct pg_block_update *update_state, bool power_on);
|
||||
void (*root_clock_control)(struct dc *dc,
|
||||
struct pg_block_update *update_state, bool power_on);
|
||||
void (*set_idle_state)(const struct dc *dc, bool allow_idle);
|
||||
uint32_t (*get_idle_state)(const struct dc *dc);
|
||||
|
||||
bool (*is_pipe_topology_transition_seamless)(struct dc *dc,
|
||||
const struct dc_state *cur_ctx,
|
||||
|
@ -262,6 +262,8 @@ struct clk_mgr_funcs {
|
||||
void (*set_low_power_state)(struct clk_mgr *clk_mgr);
|
||||
void (*exit_low_power_state)(struct clk_mgr *clk_mgr);
|
||||
bool (*is_ips_supported)(struct clk_mgr *clk_mgr);
|
||||
void (*set_idle_state)(struct clk_mgr *clk_mgr, bool allow_idle);
|
||||
uint32_t (*get_idle_state)(struct clk_mgr *clk_mgr);
|
||||
|
||||
void (*init_clocks)(struct clk_mgr *clk_mgr);
|
||||
|
||||
|
@ -352,6 +352,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
|
||||
funcs->init_reg_offsets = dmub_srv_dcn35_regs_init;
|
||||
|
||||
funcs->is_hw_powered_up = dmub_dcn35_is_hw_powered_up;
|
||||
funcs->should_detect = dmub_dcn35_should_detect;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
Loading…
x
Reference in New Issue
Block a user