Commit 70fef574 authored by Evan Quan's avatar Evan Quan Committed by Alex Deucher
Browse files

drm/amd/powerplay: retrieve all clock ranges on startup



So that we do not need to use PPSMC_MSG_GetMin/MaxDpmFreq to
get the clock ranges on runtime. Since that causes some problems.

Signed-off-by: default avatarEvan Quan <evan.quan@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 3b579c54
Loading
Loading
Loading
Loading
+53 −16
Original line number Diff line number Diff line
@@ -856,6 +856,48 @@ static int vega12_power_control_set_level(struct pp_hwmgr *hwmgr)
	return result;
}

static int vega12_get_all_clock_ranges_helper(struct pp_hwmgr *hwmgr,
		PPCLK_e clkid, struct vega12_clock_range *clock)
{
	/* AC Max */
	PP_ASSERT_WITH_CODE(
		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMaxDpmFreq, (clkid << 16)) == 0,
		"[GetClockRanges] Failed to get max ac clock from SMC!",
		return -EINVAL);
	vega12_read_arg_from_smc(hwmgr, &(clock->ACMax));

	/* AC Min */
	PP_ASSERT_WITH_CODE(
		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMinDpmFreq, (clkid << 16)) == 0,
		"[GetClockRanges] Failed to get min ac clock from SMC!",
		return -EINVAL);
	vega12_read_arg_from_smc(hwmgr, &(clock->ACMin));

	/* DC Max */
	PP_ASSERT_WITH_CODE(
		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetDcModeMaxDpmFreq, (clkid << 16)) == 0,
		"[GetClockRanges] Failed to get max dc clock from SMC!",
		return -EINVAL);
	vega12_read_arg_from_smc(hwmgr, &(clock->DCMax));

	return 0;
}

static int vega12_get_all_clock_ranges(struct pp_hwmgr *hwmgr)
{
	struct vega12_hwmgr *data =
			(struct vega12_hwmgr *)(hwmgr->backend);
	uint32_t i;

	for (i = 0; i < PPCLK_COUNT; i++)
		PP_ASSERT_WITH_CODE(!vega12_get_all_clock_ranges_helper(hwmgr,
					i, &(data->clk_range[i])),
				"Failed to get clk range from SMC!",
				return -EINVAL);

	return 0;
}

static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
{
	int tmp_result, result = 0;
@@ -883,6 +925,11 @@ static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
			"Failed to power control set level!",
			result = tmp_result);

	result = vega12_get_all_clock_ranges(hwmgr);
	PP_ASSERT_WITH_CODE(!result,
			"Failed to get all clock ranges!",
			return result);

	result = vega12_odn_initialize_default_settings(hwmgr);
	PP_ASSERT_WITH_CODE(!result,
			"Failed to power control set level!",
@@ -1472,24 +1519,14 @@ static int vega12_get_clock_ranges(struct pp_hwmgr *hwmgr,
		PPCLK_e clock_select,
		bool max)
{
	int result;
	*clock = 0;
	struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);

	if (max) {
		 PP_ASSERT_WITH_CODE(
			smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMaxDpmFreq, (clock_select << 16)) == 0,
			"[GetClockRanges] Failed to get max clock from SMC!",
			return -1);
		result = vega12_read_arg_from_smc(hwmgr, clock);
	} else {
		PP_ASSERT_WITH_CODE(
			smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMinDpmFreq, (clock_select << 16)) == 0,
			"[GetClockRanges] Failed to get min clock from SMC!",
			return -1);
		result = vega12_read_arg_from_smc(hwmgr, clock);
	}
	if (max)
		*clock = data->clk_range[clock_select].ACMax;
	else
		*clock = data->clk_range[clock_select].ACMin;

	return result;
	return 0;
}

static int vega12_get_sclks(struct pp_hwmgr *hwmgr,
+8 −0
Original line number Diff line number Diff line
@@ -304,6 +304,12 @@ struct vega12_odn_fan_table {
	bool		force_fan_pwm;
};

struct vega12_clock_range {
	uint32_t	ACMax;
	uint32_t	ACMin;
	uint32_t	DCMax;
};

struct vega12_hwmgr {
	struct vega12_dpm_table          dpm_table;
	struct vega12_dpm_table          golden_dpm_table;
@@ -385,6 +391,8 @@ struct vega12_hwmgr {
	uint32_t                       smu_version;
	struct smu_features            smu_features[GNLD_FEATURES_MAX];
	struct vega12_smc_state_table  smc_state_table;

	struct vega12_clock_range      clk_range[PPCLK_COUNT];
};

#define VEGA12_DPM2_NEAR_TDP_DEC                      10