Commit d5912842 authored by Sung Joon Kim's avatar Sung Joon Kim Committed by Alex Deucher
Browse files

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: default avatarAric Cyr <aric.cyr@amd.com>
Reviewed-by: default avatarNicholas Choi <nicholas.choi@amd.com>
Acked-by: default avatarRoman Li <roman.li@amd.com>
Signed-off-by: default avatarSung Joon Kim <sungkim@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent d5f9a92b
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -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)
{
+1 −0
Original line number Diff line number Diff line
@@ -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);
+3 −1
Original line number Diff line number Diff line
@@ -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. */
+2 −6
Original line number Diff line number Diff line
@@ -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)
+2 −0
Original line number Diff line number Diff line
@@ -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,
Loading