Commit e127306d authored by Jun Lei's avatar Jun Lei Committed by Alex Deucher
Browse files

drm/amd/display: Introduce new update_clocks logic



[why]
DCN has sidebands to control some clocks, it is useful for clk_mgr to
always update the clocks it explicitly controls rather than skip them
because it enables more configurations to work without SMU

[how]
only skip handling clocks where SMU manages the frequency for clocks
with DENTIST sideband (DISP/DPP), only skip the voltage request when SMU
not available, but otherwise proceed normally

Signed-off-by: default avatarJun Lei <Jun.Lei@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6ea843e0
Loading
Loading
Loading
Loading
+73 −52
Original line number Original line Diff line number Diff line
@@ -310,6 +310,7 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
	if (display_count == 0)
	if (display_count == 0)
		enter_display_off = true;
		enter_display_off = true;


	if (clk_mgr->smu_present) {
		if (enter_display_off == safe_to_lower)
		if (enter_display_off == safe_to_lower)
			dcn30_smu_set_num_of_displays(clk_mgr, display_count);
			dcn30_smu_set_num_of_displays(clk_mgr, display_count);


@@ -333,6 +334,13 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,


		clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support;
		clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support;
		clk_mgr_base->clks.fclk_prev_p_state_change_support = clk_mgr_base->clks.fclk_p_state_change_support;
		clk_mgr_base->clks.fclk_prev_p_state_change_support = clk_mgr_base->clks.fclk_p_state_change_support;
		clk_mgr_base->clks.prev_num_ways = clk_mgr_base->clks.num_ways;

		if (clk_mgr_base->clks.num_ways != new_clocks->num_ways &&
				clk_mgr_base->clks.num_ways < new_clocks->num_ways) {
			clk_mgr_base->clks.num_ways = new_clocks->num_ways;
			dcn32_smu_send_cab_for_uclk_message(clk_mgr, clk_mgr_base->clks.num_ways);
		}


		total_plane_count = clk_mgr_helper_get_active_plane_cnt(dc, context);
		total_plane_count = clk_mgr_helper_get_active_plane_cnt(dc, context);
		p_state_change_support = new_clocks->p_state_change_support || (total_plane_count == 0);
		p_state_change_support = new_clocks->p_state_change_support || (total_plane_count == 0);
@@ -368,25 +376,38 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
				(update_uclk || !clk_mgr_base->clks.prev_p_state_change_support))
				(update_uclk || !clk_mgr_base->clks.prev_p_state_change_support))
			dcn30_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz));
			dcn30_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz));


	if (clk_mgr_base->ctx->dce_version != DCN_VERSION_3_21 &&
		if (clk_mgr_base->clks.fclk_p_state_change_support &&
			clk_mgr_base->clks.fclk_p_state_change_support &&
				(update_uclk || !clk_mgr_base->clks.fclk_prev_p_state_change_support)) {
				(update_uclk || !clk_mgr_base->clks.fclk_prev_p_state_change_support)) {

			/* Handle the code for sending a message to PMFW that FCLK P-state change is supported */
			/* Handle the code for sending a message to PMFW that FCLK P-state change is supported */
			dcn32_smu_send_fclk_pstate_message(clk_mgr, FCLK_PSTATE_SUPPORTED);
			dcn32_smu_send_fclk_pstate_message(clk_mgr, FCLK_PSTATE_SUPPORTED);
		}
		}


		if (clk_mgr_base->clks.num_ways != new_clocks->num_ways &&
				clk_mgr_base->clks.num_ways > new_clocks->num_ways) {
			clk_mgr_base->clks.num_ways = new_clocks->num_ways;
			dcn32_smu_send_cab_for_uclk_message(clk_mgr, clk_mgr_base->clks.num_ways);
		}
	}

	if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr_base->clks.dppclk_khz)) {
	if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr_base->clks.dppclk_khz)) {
		if (clk_mgr_base->clks.dppclk_khz > new_clocks->dppclk_khz)
		if (clk_mgr_base->clks.dppclk_khz > new_clocks->dppclk_khz)
			dpp_clock_lowered = true;
			dpp_clock_lowered = true;


		clk_mgr_base->clks.dppclk_khz = new_clocks->dppclk_khz;
		clk_mgr_base->clks.dppclk_khz = new_clocks->dppclk_khz;

		if (clk_mgr->smu_present)
			dcn30_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DPPCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dppclk_khz));
			dcn30_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DPPCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dppclk_khz));

		update_dppclk = true;
		update_dppclk = true;
	}
	}


	if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
	if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
		clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
		clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;

		if (clk_mgr->smu_present)
			dcn30_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DISPCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dispclk_khz));
			dcn30_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DISPCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dispclk_khz));

		update_dispclk = true;
		update_dispclk = true;
	}
	}