Skip to content

Commit d591284

Browse files
Sung Joon Kimalexdeucher
authored andcommitted
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>
1 parent d5f9a92 commit d591284

7 files changed

Lines changed: 34 additions & 7 deletions

File tree

drivers/gpu/drm/amd/display/dc/core/dc.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4884,6 +4884,9 @@ void dc_allow_idle_optimizations(struct dc *dc, bool allow)
48844884
if (dc->debug.disable_idle_power_optimizations)
48854885
return;
48864886

4887+
if (dc->caps.ips_support && dc->config.disable_ips)
4888+
return;
4889+
48874890
if (dc->clk_mgr != NULL && dc->clk_mgr->funcs->is_smu_present)
48884891
if (!dc->clk_mgr->funcs->is_smu_present(dc->clk_mgr))
48894892
return;
@@ -4895,6 +4898,26 @@ void dc_allow_idle_optimizations(struct dc *dc, bool allow)
48954898
dc->idle_optimizations_allowed = allow;
48964899
}
48974900

4901+
bool dc_dmub_is_ips_idle_state(struct dc *dc)
4902+
{
4903+
uint32_t idle_state = 0;
4904+
4905+
if (dc->debug.disable_idle_power_optimizations)
4906+
return false;
4907+
4908+
if (!dc->caps.ips_support || dc->config.disable_ips)
4909+
return false;
4910+
4911+
if (dc->hwss.get_idle_state)
4912+
idle_state = dc->hwss.get_idle_state(dc);
4913+
4914+
if ((idle_state & DMUB_IPS1_ALLOW_MASK) ||
4915+
(idle_state & DMUB_IPS2_ALLOW_MASK))
4916+
return true;
4917+
4918+
return false;
4919+
}
4920+
48984921
/* set min and max memory clock to lowest and highest DPM level, respectively */
48994922
void dc_unlock_memory_clock_frequency(struct dc *dc)
49004923
{

drivers/gpu/drm/amd/display/dc/dc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2315,6 +2315,7 @@ bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, struct dc_plane_
23152315
struct dc_cursor_attributes *cursor_attr);
23162316

23172317
void dc_allow_idle_optimizations(struct dc *dc, bool allow);
2318+
bool dc_dmub_is_ips_idle_state(struct dc *dc);
23182319

23192320
/* set min and max memory clock to lowest and highest DPM level, respectively */
23202321
void dc_unlock_memory_clock_frequency(struct dc *dc);

drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,9 @@ void dcn31_reset_hw_ctx_wrap(
585585
struct clock_source *old_clk = pipe_ctx_old->clock_source;
586586

587587
/* Reset pipe which is seamless boot stream. */
588-
if (!pipe_ctx_old->plane_state) {
588+
if (!pipe_ctx_old->plane_state &&
589+
dc->res_pool->hubbub->funcs->program_det_size &&
590+
dc->res_pool->hubbub->funcs->wait_for_det_apply) {
589591
dc->res_pool->hubbub->funcs->program_det_size(
590592
dc->res_pool->hubbub, pipe_ctx_old->plane_res.hubp->inst, 0);
591593
/* Wait det size changed. */

drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -629,12 +629,8 @@ void dcn35_power_down_on_boot(struct dc *dc)
629629
if (dc->clk_mgr->funcs->set_low_power_state)
630630
dc->clk_mgr->funcs->set_low_power_state(dc->clk_mgr);
631631

632-
if (dc->clk_mgr->clks.pwr_state == DCN_PWR_STATE_LOW_POWER) {
633-
if (!dc->idle_optimizations_allowed) {
634-
dc_dmub_srv_notify_idle(dc, true);
635-
dc->idle_optimizations_allowed = true;
636-
}
637-
}
632+
if (dc->clk_mgr->clks.pwr_state == DCN_PWR_STATE_LOW_POWER)
633+
dc_allow_idle_optimizations(dc, true);
638634
}
639635

640636
bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable)

drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,8 @@ struct hw_sequencer_funcs {
418418
struct pg_block_update *update_state, bool power_on);
419419
void (*root_clock_control)(struct dc *dc,
420420
struct pg_block_update *update_state, bool power_on);
421+
void (*set_idle_state)(const struct dc *dc, bool allow_idle);
422+
uint32_t (*get_idle_state)(const struct dc *dc);
421423

422424
bool (*is_pipe_topology_transition_seamless)(struct dc *dc,
423425
const struct dc_state *cur_ctx,

drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ struct clk_mgr_funcs {
262262
void (*set_low_power_state)(struct clk_mgr *clk_mgr);
263263
void (*exit_low_power_state)(struct clk_mgr *clk_mgr);
264264
bool (*is_ips_supported)(struct clk_mgr *clk_mgr);
265+
void (*set_idle_state)(struct clk_mgr *clk_mgr, bool allow_idle);
266+
uint32_t (*get_idle_state)(struct clk_mgr *clk_mgr);
265267

266268
void (*init_clocks)(struct clk_mgr *clk_mgr);
267269

drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
352352
funcs->init_reg_offsets = dmub_srv_dcn35_regs_init;
353353

354354
funcs->is_hw_powered_up = dmub_dcn35_is_hw_powered_up;
355+
funcs->should_detect = dmub_dcn35_should_detect;
355356
break;
356357

357358
default:

0 commit comments

Comments
 (0)