Commit d389d607 authored by Rex Zhu's avatar Rex Zhu Committed by Alex Deucher
Browse files

drm/amd/pp: Change voltage/clk range for OD feature on VI



read vddc range from vbios.

Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarRex Zhu <Rex.Zhu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ca6e0c5b
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -1505,3 +1505,31 @@ int atomctrl_get_leakage_vddc_base_on_leakage(struct pp_hwmgr *hwmgr,

	return 0;
}

void atomctrl_get_voltage_range(struct pp_hwmgr *hwmgr, uint32_t *max_vddc,
							uint32_t *min_vddc)
{
	void *profile;

	profile = smu_atom_get_data_table(hwmgr->adev,
					GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo),
					NULL, NULL, NULL);

	if (profile) {
		switch (hwmgr->chip_id) {
		case CHIP_TONGA:
		case CHIP_FIJI:
			*max_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_3 *)profile)->ulMaxVddc/4);
			*min_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_3 *)profile)->ulMinVddc/4);
			break;
		case CHIP_POLARIS11:
		case CHIP_POLARIS10:
		case CHIP_POLARIS12:
			*max_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_6 *)profile)->ulMaxVddc/100);
			*min_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_6 *)profile)->ulMinVddc/100);
			break;
		default:
			return;
		}
	}
}
+3 −0
Original line number Diff line number Diff line
@@ -320,5 +320,8 @@ extern int atomctrl_get_leakage_vddc_base_on_leakage(struct pp_hwmgr *hwmgr,
					uint16_t virtual_voltage_id,
					uint16_t efuse_voltage_id);
extern int atomctrl_get_leakage_id_from_efuse(struct pp_hwmgr *hwmgr, uint16_t *virtual_voltage_id);

extern void atomctrl_get_voltage_range(struct pp_hwmgr *hwmgr, uint32_t *max_vddc,
							uint32_t *min_vddc);
#endif
+40 −20
Original line number Diff line number Diff line
@@ -838,6 +838,33 @@ static int smu7_odn_initial_default_setting(struct pp_hwmgr *hwmgr)
	return 0;
}

static void smu7_setup_voltage_range_from_vbios(struct pp_hwmgr *hwmgr)
{
	struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
	struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table;
	struct phm_ppt_v1_information *table_info =
			(struct phm_ppt_v1_information *)(hwmgr->pptable);
	uint32_t min_vddc, max_vddc;

	if (!table_info)
		return;

	dep_sclk_table = table_info->vdd_dep_on_sclk;

	atomctrl_get_voltage_range(hwmgr, &max_vddc, &min_vddc);

	if (min_vddc == 0 || min_vddc > 2000
		|| min_vddc > dep_sclk_table->entries[0].vddc)
		min_vddc = dep_sclk_table->entries[0].vddc;

	if (max_vddc == 0 || max_vddc > 2000
		|| max_vddc < dep_sclk_table->entries[dep_sclk_table->count-1].vddc)
		max_vddc = dep_sclk_table->entries[dep_sclk_table->count-1].vddc;

	data->odn_dpm_table.min_vddc = min_vddc;
	data->odn_dpm_table.max_vddc = max_vddc;
}

static int smu7_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
{
	struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
@@ -856,8 +883,10 @@ static int smu7_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
			sizeof(struct smu7_dpm_table));

	/* initialize ODN table */
	if (hwmgr->od_enabled)
	if (hwmgr->od_enabled) {
		smu7_setup_voltage_range_from_vbios(hwmgr);
		smu7_odn_initial_default_setting(hwmgr);
	}

	return 0;
}
@@ -4605,35 +4634,26 @@ static bool smu7_check_clk_voltage_valid(struct pp_hwmgr *hwmgr,
{
	struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);

	struct phm_ppt_v1_information *table_info =
			(struct phm_ppt_v1_information *)(hwmgr->pptable);
	uint32_t min_vddc;
	struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table;

	if (table_info == NULL)
		return false;

	dep_sclk_table = table_info->vdd_dep_on_sclk;
	min_vddc = dep_sclk_table->entries[0].vddc;

	if (voltage < min_vddc || voltage > 2000) {
		pr_info("OD voltage is out of range [%d - 2000] mV\n", min_vddc);
	if (voltage < data->odn_dpm_table.min_vddc || voltage > data->odn_dpm_table.max_vddc) {
		pr_info("OD voltage is out of range [%d - %d] mV\n",
						data->odn_dpm_table.min_vddc,
						data->odn_dpm_table.max_vddc);
		return false;
	}

	if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) {
		if (data->vbios_boot_state.sclk_bootup_value > clk ||
		if (data->golden_dpm_table.sclk_table.dpm_levels[0].value > clk ||
			hwmgr->platform_descriptor.overdriveLimit.engineClock < clk) {
			pr_info("OD engine clock is out of range [%d - %d] MHz\n",
				data->vbios_boot_state.sclk_bootup_value,
				data->golden_dpm_table.sclk_table.dpm_levels[0].value/100,
				hwmgr->platform_descriptor.overdriveLimit.engineClock/100);
			return false;
		}
	} else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) {
		if (data->vbios_boot_state.mclk_bootup_value > clk ||
		if (data->golden_dpm_table.mclk_table.dpm_levels[0].value > clk ||
			hwmgr->platform_descriptor.overdriveLimit.memoryClock < clk) {
			pr_info("OD memory clock is out of range [%d - %d] MHz\n",
				data->vbios_boot_state.mclk_bootup_value/100,
				data->golden_dpm_table.mclk_table.dpm_levels[0].value/100,
				hwmgr->platform_descriptor.overdriveLimit.memoryClock/100);
			return false;
		}
+2 −0
Original line number Diff line number Diff line
@@ -184,6 +184,8 @@ struct smu7_odn_dpm_table {
	struct smu7_odn_clock_voltage_dependency_table	vdd_dependency_on_sclk;
	struct smu7_odn_clock_voltage_dependency_table	vdd_dependency_on_mclk;
	uint32_t					odn_mclk_min_limit;
	uint32_t min_vddc;
	uint32_t max_vddc;
};

struct profile_mode_setting {