Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7dd67c0d authored by Evan Quan's avatar Evan Quan Committed by Alex Deucher
Browse files

drm/amd/powerplay: initialize vega20 overdrive settings



The initialized overdrive settings are taken from vbios and SMU(
by PPSMC_MSG_TransferTableSmu2Dram).

Signed-off-by: default avatarEvan Quan <evan.quan@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent bc9b8c45
Loading
Loading
Loading
Loading
+274 −19
Original line number Diff line number Diff line
@@ -103,7 +103,7 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr)
	data->registry_data.quick_transition_support = 0;
	data->registry_data.zrpm_start_temp = 0xffff;
	data->registry_data.zrpm_stop_temp = 0xffff;
	data->registry_data.odn_feature_enable = 1;
	data->registry_data.od8_feature_enable = 1;
	data->registry_data.disable_water_mark = 0;
	data->registry_data.disable_pp_tuning = 0;
	data->registry_data.disable_xlpp_tuning = 0;
@@ -150,15 +150,9 @@ static int vega20_set_features_platform_caps(struct pp_hwmgr *hwmgr)
	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
			PHM_PlatformCaps_UnTabledHardwareInterface);

	if (data->registry_data.odn_feature_enable)
	if (data->registry_data.od8_feature_enable)
		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
				PHM_PlatformCaps_ODNinACSupport);
	else {
		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
				PHM_PlatformCaps_OD6inACSupport);
		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
				PHM_PlatformCaps_OD6PlusinACSupport);
	}
				PHM_PlatformCaps_OD8inACSupport);

	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
			PHM_PlatformCaps_ActivityReporting);
@@ -166,15 +160,9 @@ static int vega20_set_features_platform_caps(struct pp_hwmgr *hwmgr)
			PHM_PlatformCaps_FanSpeedInTableIsRPM);

	if (data->registry_data.od_state_in_dc_support) {
		if (data->registry_data.odn_feature_enable)
			phm_cap_set(hwmgr->platform_descriptor.platformCaps,
					PHM_PlatformCaps_ODNinDCSupport);
		else {
			phm_cap_set(hwmgr->platform_descriptor.platformCaps,
					PHM_PlatformCaps_OD6inDCSupport);
		if (data->registry_data.od8_feature_enable)
			phm_cap_set(hwmgr->platform_descriptor.platformCaps,
					PHM_PlatformCaps_OD6PlusinDCSupport);
		}
					PHM_PlatformCaps_OD8inDCSupport);
	}

	if (data->registry_data.thermal_support &&
@@ -840,9 +828,276 @@ static int vega20_disable_all_smu_features(struct pp_hwmgr *hwmgr)
	return 0;
}

static int vega20_odn_initialize_default_settings(
static int vega20_od8_set_feature_capabilities(
		struct pp_hwmgr *hwmgr)
{
	struct phm_ppt_v3_information *pptable_information =
		(struct phm_ppt_v3_information *)hwmgr->pptable;
	struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
	struct vega20_od8_settings *od_settings = &(data->od8_settings);

	od_settings->overdrive8_capabilities = 0;

	if (data->smu_features[GNLD_DPM_GFXCLK].enabled) {
		if (pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_GFXCLKFMAX] > 0 &&
		    pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_GFXCLKFMAX] > 0 &&
		    pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_GFXCLKFMIN] > 0 &&
		    pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_GFXCLKFMIN] > 0)
			od_settings->overdrive8_capabilities |= OD8_GFXCLK_LIMITS;

		if (pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_VDDGFXCURVEFREQ_P1] > 0 &&
		    pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_VDDGFXCURVEFREQ_P2] > 0 &&
		    pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_VDDGFXCURVEFREQ_P3] > 0 &&
		    pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_VDDGFXCURVEFREQ_P1] > 0 &&
		    pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_VDDGFXCURVEFREQ_P2] > 0 &&
		    pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_VDDGFXCURVEFREQ_P3] > 0 &&
		    pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P1] > 0 &&
		    pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P2] > 0 &&
		    pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P3] > 0 &&
		    pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P1] > 0 &&
		    pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P2] > 0 &&
		    pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P3] > 0)
			od_settings->overdrive8_capabilities |= OD8_GFXCLK_CURVE;
	}

	if (data->smu_features[GNLD_DPM_UCLK].enabled) {
		if (pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_UCLKFMAX] > 0 &&
		    pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_UCLKFMAX] > 0)
			od_settings->overdrive8_capabilities |= OD8_UCLK_MAX;
	}

	if (pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_POWERPERCENTAGE] > 0 &&
	    pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_POWERPERCENTAGE] <= 100)
		od_settings->overdrive8_capabilities |= OD8_POWER_LIMIT;

	if (data->smu_features[GNLD_FAN_CONTROL].enabled) {
		if (pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_FANRPMMIN] > 0)
			od_settings->overdrive8_capabilities |= OD8_FAN_SPEED_MIN;

		if (pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_FANRPMACOUSTICLIMIT] > 0)
			od_settings->overdrive8_capabilities |= OD8_ACOUSTIC_LIMIT_SCLK;
	}

	if (data->smu_features[GNLD_THERMAL].enabled) {
		if (pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_FANTARGETTEMPERATURE] > 0)
			od_settings->overdrive8_capabilities |= OD8_TEMPERATURE_FAN;

		if (pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_OPERATINGTEMPMAX] > 0)
			od_settings->overdrive8_capabilities |= OD8_TEMPERATURE_SYSTEM;
	}

	return 0;
}

static int vega20_od8_set_feature_id(
		struct pp_hwmgr *hwmgr)
{
	struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
	struct vega20_od8_settings *od_settings = &(data->od8_settings);

	if (od_settings->overdrive8_capabilities & OD8_GFXCLK_LIMITS) {
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMIN].feature_id =
			OD8_GFXCLK_LIMITS;
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMAX].feature_id =
			OD8_GFXCLK_LIMITS;
	} else {
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMIN].feature_id =
			0;
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMAX].feature_id =
			0;
	}

	if (od_settings->overdrive8_capabilities & OD8_GFXCLK_CURVE) {
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ1].feature_id =
			OD8_GFXCLK_CURVE;
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id =
			OD8_GFXCLK_CURVE;
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ2].feature_id =
			OD8_GFXCLK_CURVE;
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id =
			OD8_GFXCLK_CURVE;
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ3].feature_id =
			OD8_GFXCLK_CURVE;
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id =
			OD8_GFXCLK_CURVE;
	} else {
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ1].feature_id =
			0;
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id =
			0;
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ2].feature_id =
			0;
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id =
			0;
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ3].feature_id =
			0;
		od_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id =
			0;
	}

	if (od_settings->overdrive8_capabilities & OD8_UCLK_MAX)
		od_settings->od8_settings_array[OD8_SETTING_UCLK_FMAX].feature_id = OD8_UCLK_MAX;
	else
		od_settings->od8_settings_array[OD8_SETTING_UCLK_FMAX].feature_id = 0;

	if (od_settings->overdrive8_capabilities & OD8_POWER_LIMIT)
		od_settings->od8_settings_array[OD8_SETTING_POWER_PERCENTAGE].feature_id = OD8_POWER_LIMIT;
	else
		od_settings->od8_settings_array[OD8_SETTING_POWER_PERCENTAGE].feature_id = 0;

	if (od_settings->overdrive8_capabilities & OD8_ACOUSTIC_LIMIT_SCLK)
		od_settings->od8_settings_array[OD8_SETTING_FAN_ACOUSTIC_LIMIT].feature_id =
			OD8_ACOUSTIC_LIMIT_SCLK;
	else
		od_settings->od8_settings_array[OD8_SETTING_FAN_ACOUSTIC_LIMIT].feature_id =
			0;

	if (od_settings->overdrive8_capabilities & OD8_FAN_SPEED_MIN)
		od_settings->od8_settings_array[OD8_SETTING_FAN_MIN_SPEED].feature_id =
			OD8_FAN_SPEED_MIN;
	else
		od_settings->od8_settings_array[OD8_SETTING_FAN_MIN_SPEED].feature_id =
			0;

	if (od_settings->overdrive8_capabilities & OD8_TEMPERATURE_FAN)
		od_settings->od8_settings_array[OD8_SETTING_FAN_TARGET_TEMP].feature_id =
			OD8_TEMPERATURE_FAN;
	else
		od_settings->od8_settings_array[OD8_SETTING_FAN_TARGET_TEMP].feature_id =
			0;

	if (od_settings->overdrive8_capabilities & OD8_TEMPERATURE_SYSTEM)
		od_settings->od8_settings_array[OD8_SETTING_OPERATING_TEMP_MAX].feature_id =
			OD8_TEMPERATURE_SYSTEM;
	else
		od_settings->od8_settings_array[OD8_SETTING_OPERATING_TEMP_MAX].feature_id =
			0;

	return 0;
}

static int vega20_od8_initialize_default_settings(
		struct pp_hwmgr *hwmgr)
{
	struct phm_ppt_v3_information *pptable_information =
		(struct phm_ppt_v3_information *)hwmgr->pptable;
	struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
	struct vega20_od8_settings *od8_settings = &(data->od8_settings);
	OverDriveTable_t *od_table = &(data->smc_state_table.overdrive_table);
	int i, ret = 0;

	/* Set Feature Capabilities */
	vega20_od8_set_feature_capabilities(hwmgr);

	/* Map FeatureID to individual settings */
	vega20_od8_set_feature_id(hwmgr);

	/* Set default values */
	ret = vega20_copy_table_from_smc(hwmgr, (uint8_t *)od_table, TABLE_OVERDRIVE);
	PP_ASSERT_WITH_CODE(!ret,
			"Failed to export over drive table!",
			return ret);

	if (od8_settings->overdrive8_capabilities & OD8_GFXCLK_LIMITS) {
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMIN].default_value =
			od_table->GfxclkFmin;
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMAX].default_value =
			od_table->GfxclkFmax;
	} else {
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMIN].default_value =
			0;
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMAX].default_value =
			0;
	}

	if (od8_settings->overdrive8_capabilities & OD8_GFXCLK_CURVE) {
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ1].default_value =
			od_table->GfxclkFreq1;
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].default_value =
			od_table->GfxclkOffsetVolt1;
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ2].default_value =
			od_table->GfxclkFreq2;
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].default_value =
			od_table->GfxclkOffsetVolt2;
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ3].default_value =
			od_table->GfxclkFreq3;
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].default_value =
			od_table->GfxclkOffsetVolt3;
	} else {
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ1].default_value =
			0;
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].default_value =
			0;
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ2].default_value =
			0;
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].default_value =
			0;
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ3].default_value =
			0;
		od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].default_value =
			0;
	}

	if (od8_settings->overdrive8_capabilities & OD8_UCLK_MAX)
		od8_settings->od8_settings_array[OD8_SETTING_UCLK_FMAX].default_value =
			od_table->UclkFmax;
	else
		od8_settings->od8_settings_array[OD8_SETTING_UCLK_FMAX].default_value =
			0;

	if (od8_settings->overdrive8_capabilities & OD8_POWER_LIMIT)
		od8_settings->od8_settings_array[OD8_SETTING_POWER_PERCENTAGE].default_value =
			od_table->OverDrivePct;
	else
		od8_settings->od8_settings_array[OD8_SETTING_POWER_PERCENTAGE].default_value =
			0;

	if (od8_settings->overdrive8_capabilities & OD8_ACOUSTIC_LIMIT_SCLK)
		od8_settings->od8_settings_array[OD8_SETTING_FAN_ACOUSTIC_LIMIT].default_value =
			od_table->FanMaximumRpm;
	else
		od8_settings->od8_settings_array[OD8_SETTING_FAN_ACOUSTIC_LIMIT].default_value =
			0;

	if (od8_settings->overdrive8_capabilities & OD8_FAN_SPEED_MIN)
		od8_settings->od8_settings_array[OD8_SETTING_FAN_MIN_SPEED].default_value =
			od_table->FanMinimumPwm;
	else
		od8_settings->od8_settings_array[OD8_SETTING_FAN_MIN_SPEED].default_value =
			0;

	if (od8_settings->overdrive8_capabilities & OD8_TEMPERATURE_FAN)
		od8_settings->od8_settings_array[OD8_SETTING_FAN_TARGET_TEMP].default_value =
			od_table->FanTargetTemperature;
	else
		od8_settings->od8_settings_array[OD8_SETTING_FAN_TARGET_TEMP].default_value =
			0;

	if (od8_settings->overdrive8_capabilities & OD8_TEMPERATURE_SYSTEM)
		od8_settings->od8_settings_array[OD8_SETTING_OPERATING_TEMP_MAX].default_value =
			od_table->MaxOpTemp;
	else
		od8_settings->od8_settings_array[OD8_SETTING_OPERATING_TEMP_MAX].default_value =
			0;

	for (i = 0; i < OD8_SETTING_COUNT; i++) {
		if (od8_settings->od8_settings_array[i].feature_id) {
			od8_settings->od8_settings_array[i].min_value =
				pptable_information->od_settings_min[i];
			od8_settings->od8_settings_array[i].max_value =
				pptable_information->od_settings_max[i];
			od8_settings->od8_settings_array[i].current_value =
				od8_settings->od8_settings_array[i].default_value;
		} else {
			od8_settings->od8_settings_array[i].min_value =
				0;
			od8_settings->od8_settings_array[i].max_value =
				0;
			od8_settings->od8_settings_array[i].current_value =
				0;
		}
	}

	return 0;
}

@@ -1009,7 +1264,7 @@ static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
			"[EnableDPMTasks] Failed to power control set level!",
			return result);

	result = vega20_odn_initialize_default_settings(hwmgr);
	result = vega20_od8_initialize_default_settings(hwmgr);
	PP_ASSERT_WITH_CODE(!result,
			"[EnableDPMTasks] Failed to initialize odn settings!",
			return result);
+52 −1
Original line number Diff line number Diff line
@@ -306,7 +306,7 @@ struct vega20_registry_data {
	uint8_t   led_dpm_enabled;
	uint8_t   fan_control_support;
	uint8_t   ulv_support;
	uint8_t   odn_feature_enable;
	uint8_t   od8_feature_enable;
	uint8_t   disable_water_mark;
	uint8_t   disable_workload_policy;
	uint32_t  force_workload_policy_mask;
@@ -377,6 +377,54 @@ struct vega20_odn_data {
	struct vega20_odn_temp_table	odn_temp_table;
};

enum OD8_FEATURE_ID
{
	OD8_GFXCLK_LIMITS               = 1 << 0,
	OD8_GFXCLK_CURVE                = 1 << 1,
	OD8_UCLK_MAX                    = 1 << 2,
	OD8_POWER_LIMIT                 = 1 << 3,
	OD8_ACOUSTIC_LIMIT_SCLK         = 1 << 4,   //FanMaximumRpm
	OD8_FAN_SPEED_MIN               = 1 << 5,   //FanMinimumPwm
	OD8_TEMPERATURE_FAN             = 1 << 6,   //FanTargetTemperature
	OD8_TEMPERATURE_SYSTEM          = 1 << 7,   //MaxOpTemp
	OD8_MEMORY_TIMING_TUNE          = 1 << 8,
	OD8_FAN_ZERO_RPM_CONTROL        = 1 << 9
};

enum OD8_SETTING_ID
{
	OD8_SETTING_GFXCLK_FMIN = 0,
	OD8_SETTING_GFXCLK_FMAX,
	OD8_SETTING_GFXCLK_FREQ1,
	OD8_SETTING_GFXCLK_VOLTAGE1,
	OD8_SETTING_GFXCLK_FREQ2,
	OD8_SETTING_GFXCLK_VOLTAGE2,
	OD8_SETTING_GFXCLK_FREQ3,
	OD8_SETTING_GFXCLK_VOLTAGE3,
	OD8_SETTING_UCLK_FMAX,
	OD8_SETTING_POWER_PERCENTAGE,
	OD8_SETTING_FAN_ACOUSTIC_LIMIT,
	OD8_SETTING_FAN_MIN_SPEED,
	OD8_SETTING_FAN_TARGET_TEMP,
	OD8_SETTING_OPERATING_TEMP_MAX,
	OD8_SETTING_AC_TIMING,
	OD8_SETTING_FAN_ZERO_RPM_CONTROL,
	OD8_SETTING_COUNT
};

struct vega20_od8_single_setting {
	uint32_t	feature_id;
	int32_t		min_value;
	int32_t		max_value;
	int32_t		current_value;
	int32_t		default_value;
};

struct vega20_od8_settings {
	uint32_t	overdrive8_capabilities;
	struct vega20_od8_single_setting	od8_settings_array[OD8_SETTING_COUNT];
};

struct vega20_hwmgr {
	struct vega20_dpm_table          dpm_table;
	struct vega20_dpm_table          golden_dpm_table;
@@ -452,6 +500,9 @@ struct vega20_hwmgr {
	/* ---- Overdrive next setting ---- */
	struct vega20_odn_data         odn_data;

	/* ---- Overdrive8 Setting ---- */
	struct vega20_od8_settings     od8_settings;

	/* ---- Workload Mask ---- */
	uint32_t                       workload_mask;

+74 −29
Original line number Diff line number Diff line
@@ -664,18 +664,18 @@ static int set_platform_caps(struct pp_hwmgr *hwmgr, uint32_t powerplay_caps)
static int copy_clock_limits_array(
	struct pp_hwmgr *hwmgr,
	uint32_t **pptable_info_array,
	const uint32_t *pptable_array)
	const uint32_t *pptable_array,
	uint32_t power_saving_clock_count)
{
	uint32_t array_size, i;
	uint32_t *table;

	array_size = sizeof(uint32_t) * ATOM_VEGA20_PPCLOCK_COUNT;

	array_size = sizeof(uint32_t) * power_saving_clock_count;
	table = kzalloc(array_size, GFP_KERNEL);
	if (NULL == table)
		return -ENOMEM;

	for (i = 0; i < ATOM_VEGA20_PPCLOCK_COUNT; i++)
	for (i = 0; i < power_saving_clock_count; i++)
		table[i] = pptable_array[i];

	*pptable_info_array = table;
@@ -686,22 +686,52 @@ static int copy_clock_limits_array(
static int copy_overdrive_settings_limits_array(
		struct pp_hwmgr *hwmgr,
		uint32_t **pptable_info_array,
		const uint32_t *pptable_array)
		const uint32_t *pptable_array,
		uint32_t od_setting_count)
{
	uint32_t array_size, i;
	uint32_t *table;

	array_size = sizeof(uint32_t) * ATOM_VEGA20_ODSETTING_COUNT;
	array_size = sizeof(uint32_t) * od_setting_count;
	table = kzalloc(array_size, GFP_KERNEL);
	if (NULL == table)
		return -ENOMEM;

	for (i = 0; i < od_setting_count; i++)
		table[i] = pptable_array[i];

	*pptable_info_array = table;

	return 0;
}

static int copy_overdrive_feature_capabilities_array(
		struct pp_hwmgr *hwmgr,
		uint8_t **pptable_info_array,
		const uint8_t *pptable_array,
		uint8_t od_feature_count)
{
	uint32_t array_size, i;
	uint8_t *table;
	bool od_supported = false;

	array_size = sizeof(uint8_t) * od_feature_count;
	table = kzalloc(array_size, GFP_KERNEL);
	if (NULL == table)
		return -ENOMEM;

	for (i = 0; i < ATOM_VEGA20_ODSETTING_COUNT; i++)
	for (i = 0; i < od_feature_count; i++) {
		table[i] = pptable_array[i];
		if (table[i])
			od_supported = true;
	}

	*pptable_info_array = table;

	if (od_supported)
		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
				PHM_PlatformCaps_ACOverdriveSupport);

	return 0;
}

@@ -799,6 +829,7 @@ static int init_powerplay_table_information(
	struct phm_ppt_v3_information *pptable_information =
		(struct phm_ppt_v3_information *)hwmgr->pptable;
	uint32_t disable_power_control = 0;
	uint32_t od_feature_count, od_setting_count, power_saving_clock_count;
	int result;

	hwmgr->thermal_controller.ucType = powerplay_table->ucThermalControllerType;
@@ -810,22 +841,25 @@ static int init_powerplay_table_information(

	phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl);

	if (powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_GFXCLKFMAX] > VEGA20_ENGINECLOCK_HARDMAX)
		hwmgr->platform_descriptor.overdriveLimit.engineClock = VEGA20_ENGINECLOCK_HARDMAX;
	else
		hwmgr->platform_descriptor.overdriveLimit.engineClock = powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_GFXCLKFMAX];
	hwmgr->platform_descriptor.overdriveLimit.memoryClock = powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_UCLKFMAX];

	copy_overdrive_settings_limits_array(hwmgr, &pptable_information->od_settings_max, powerplay_table->OverDrive8Table.ODSettingsMax);
	copy_overdrive_settings_limits_array(hwmgr, &pptable_information->od_settings_min, powerplay_table->OverDrive8Table.ODSettingsMin);

	/* hwmgr->platformDescriptor.minOverdriveVDDC = 0;
	hwmgr->platformDescriptor.maxOverdriveVDDC = 0;
	hwmgr->platformDescriptor.overdriveVDDCStep = 0; */

	if (hwmgr->platform_descriptor.overdriveLimit.engineClock > 0
		&& hwmgr->platform_descriptor.overdriveLimit.memoryClock > 0)
		phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_ACOverdriveSupport);
	if (powerplay_table->OverDrive8Table.ucODTableRevision == 1) {
		od_feature_count = (powerplay_table->OverDrive8Table.ODFeatureCount > ATOM_VEGA20_ODFEATURE_COUNT) ?
				ATOM_VEGA20_ODFEATURE_COUNT : powerplay_table->OverDrive8Table.ODFeatureCount;
		od_setting_count = (powerplay_table->OverDrive8Table.ODSettingCount > ATOM_VEGA20_ODSETTING_COUNT) ?
				ATOM_VEGA20_ODSETTING_COUNT : powerplay_table->OverDrive8Table.ODSettingCount;

		copy_overdrive_feature_capabilities_array(hwmgr,
				&pptable_information->od_feature_capabilities,
				powerplay_table->OverDrive8Table.ODFeatureCapabilities,
				od_feature_count);
		copy_overdrive_settings_limits_array(hwmgr,
				&pptable_information->od_settings_max,
				powerplay_table->OverDrive8Table.ODSettingsMax,
				od_setting_count);
		copy_overdrive_settings_limits_array(hwmgr,
				&pptable_information->od_settings_min,
				powerplay_table->OverDrive8Table.ODSettingsMin,
				od_setting_count);
	}

	pptable_information->us_small_power_limit1 = powerplay_table->usSmallPowerLimit1;
	pptable_information->us_small_power_limit2 = powerplay_table->usSmallPowerLimit2;
@@ -838,15 +872,23 @@ static int init_powerplay_table_information(
	hwmgr->platform_descriptor.TDPODLimit = (uint16_t)powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_POWERPERCENTAGE];

	disable_power_control = 0;
	if (!disable_power_control && hwmgr->platform_descriptor.TDPODLimit) {
	if (!disable_power_control && hwmgr->platform_descriptor.TDPODLimit)
		/* enable TDP overdrive (PowerControl) feature as well if supported */
		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
				PHM_PlatformCaps_PowerControl);
		phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PowerControl);

	if (powerplay_table->PowerSavingClockTable.ucTableRevision == 1) {
		power_saving_clock_count = (powerplay_table->PowerSavingClockTable.PowerSavingClockCount >= ATOM_VEGA20_PPCLOCK_COUNT) ?
				ATOM_VEGA20_PPCLOCK_COUNT : powerplay_table->PowerSavingClockTable.PowerSavingClockCount;
		copy_clock_limits_array(hwmgr,
				&pptable_information->power_saving_clock_max,
				powerplay_table->PowerSavingClockTable.PowerSavingClockMax,
				power_saving_clock_count);
		copy_clock_limits_array(hwmgr,
				&pptable_information->power_saving_clock_min,
				powerplay_table->PowerSavingClockTable.PowerSavingClockMin,
				power_saving_clock_count);
	}

	copy_clock_limits_array(hwmgr, &pptable_information->power_saving_clock_max, powerplay_table->PowerSavingClockTable.PowerSavingClockMax);
	copy_clock_limits_array(hwmgr, &pptable_information->power_saving_clock_min, powerplay_table->PowerSavingClockTable.PowerSavingClockMin);

	pptable_information->smc_pptable = (PPTable_t *)kmalloc(sizeof(PPTable_t), GFP_KERNEL);
	if (pptable_information->smc_pptable == NULL)
		return -ENOMEM;
@@ -898,6 +940,9 @@ static int vega20_pp_tables_uninitialize(struct pp_hwmgr *hwmgr)
	kfree(pp_table_info->power_saving_clock_min);
	pp_table_info->power_saving_clock_min = NULL;

	kfree(pp_table_info->od_feature_capabilities);
	pp_table_info->od_feature_capabilities = NULL;

	kfree(pp_table_info->od_settings_max);
	pp_table_info->od_settings_max = NULL;

+2 −0
Original line number Diff line number Diff line
@@ -232,6 +232,8 @@ enum phm_platform_caps {
	PHM_PlatformCaps_UVDClientMCTuning,
	PHM_PlatformCaps_ODNinACSupport,
	PHM_PlatformCaps_ODNinDCSupport,
	PHM_PlatformCaps_OD8inACSupport,
	PHM_PlatformCaps_OD8inDCSupport,
	PHM_PlatformCaps_UMDPState,
	PHM_PlatformCaps_AutoWattmanSupport,
	PHM_PlatformCaps_AutoWattmanEnable_CCCState,
+1 −0
Original line number Diff line number Diff line
@@ -583,6 +583,7 @@ struct phm_ppt_v3_information
	uint32_t *power_saving_clock_max;
	uint32_t *power_saving_clock_min;

	uint8_t *od_feature_capabilities;
	uint32_t *od_settings_max;
	uint32_t *od_settings_min;