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

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
...@@ -103,7 +103,7 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr) ...@@ -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.quick_transition_support = 0;
data->registry_data.zrpm_start_temp = 0xffff; data->registry_data.zrpm_start_temp = 0xffff;
data->registry_data.zrpm_stop_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_water_mark = 0;
data->registry_data.disable_pp_tuning = 0; data->registry_data.disable_pp_tuning = 0;
data->registry_data.disable_xlpp_tuning = 0; data->registry_data.disable_xlpp_tuning = 0;
...@@ -150,15 +150,9 @@ static int vega20_set_features_platform_caps(struct pp_hwmgr *hwmgr) ...@@ -150,15 +150,9 @@ static int vega20_set_features_platform_caps(struct pp_hwmgr *hwmgr)
phm_cap_set(hwmgr->platform_descriptor.platformCaps, phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_UnTabledHardwareInterface); 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_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_ODNinACSupport); PHM_PlatformCaps_OD8inACSupport);
else {
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_OD6inACSupport);
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_OD6PlusinACSupport);
}
phm_cap_set(hwmgr->platform_descriptor.platformCaps, phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_ActivityReporting); PHM_PlatformCaps_ActivityReporting);
...@@ -166,15 +160,9 @@ static int vega20_set_features_platform_caps(struct pp_hwmgr *hwmgr) ...@@ -166,15 +160,9 @@ static int vega20_set_features_platform_caps(struct pp_hwmgr *hwmgr)
PHM_PlatformCaps_FanSpeedInTableIsRPM); PHM_PlatformCaps_FanSpeedInTableIsRPM);
if (data->registry_data.od_state_in_dc_support) { if (data->registry_data.od_state_in_dc_support) {
if (data->registry_data.odn_feature_enable) if (data->registry_data.od8_feature_enable)
phm_cap_set(hwmgr->platform_descriptor.platformCaps, phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_ODNinDCSupport); PHM_PlatformCaps_OD8inDCSupport);
else {
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_OD6inDCSupport);
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_OD6PlusinDCSupport);
}
} }
if (data->registry_data.thermal_support && if (data->registry_data.thermal_support &&
...@@ -840,9 +828,276 @@ static int vega20_disable_all_smu_features(struct pp_hwmgr *hwmgr) ...@@ -840,9 +828,276 @@ static int vega20_disable_all_smu_features(struct pp_hwmgr *hwmgr)
return 0; 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 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; return 0;
} }
...@@ -1009,7 +1264,7 @@ static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr) ...@@ -1009,7 +1264,7 @@ static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
"[EnableDPMTasks] Failed to power control set level!", "[EnableDPMTasks] Failed to power control set level!",
return result); return result);
result = vega20_odn_initialize_default_settings(hwmgr); result = vega20_od8_initialize_default_settings(hwmgr);
PP_ASSERT_WITH_CODE(!result, PP_ASSERT_WITH_CODE(!result,
"[EnableDPMTasks] Failed to initialize odn settings!", "[EnableDPMTasks] Failed to initialize odn settings!",
return result); return result);
......
...@@ -306,7 +306,7 @@ struct vega20_registry_data { ...@@ -306,7 +306,7 @@ struct vega20_registry_data {
uint8_t led_dpm_enabled; uint8_t led_dpm_enabled;
uint8_t fan_control_support; uint8_t fan_control_support;
uint8_t ulv_support; uint8_t ulv_support;
uint8_t odn_feature_enable; uint8_t od8_feature_enable;
uint8_t disable_water_mark; uint8_t disable_water_mark;
uint8_t disable_workload_policy; uint8_t disable_workload_policy;
uint32_t force_workload_policy_mask; uint32_t force_workload_policy_mask;
...@@ -377,6 +377,54 @@ struct vega20_odn_data { ...@@ -377,6 +377,54 @@ struct vega20_odn_data {
struct vega20_odn_temp_table odn_temp_table; 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_hwmgr {
struct vega20_dpm_table dpm_table; struct vega20_dpm_table dpm_table;
struct vega20_dpm_table golden_dpm_table; struct vega20_dpm_table golden_dpm_table;
...@@ -452,6 +500,9 @@ struct vega20_hwmgr { ...@@ -452,6 +500,9 @@ struct vega20_hwmgr {
/* ---- Overdrive next setting ---- */ /* ---- Overdrive next setting ---- */
struct vega20_odn_data odn_data; struct vega20_odn_data odn_data;
/* ---- Overdrive8 Setting ---- */
struct vega20_od8_settings od8_settings;
/* ---- Workload Mask ---- */ /* ---- Workload Mask ---- */
uint32_t workload_mask; uint32_t workload_mask;
......
...@@ -664,18 +664,18 @@ static int set_platform_caps(struct pp_hwmgr *hwmgr, uint32_t powerplay_caps) ...@@ -664,18 +664,18 @@ static int set_platform_caps(struct pp_hwmgr *hwmgr, uint32_t powerplay_caps)
static int copy_clock_limits_array( static int copy_clock_limits_array(
struct pp_hwmgr *hwmgr, struct pp_hwmgr *hwmgr,
uint32_t **pptable_info_array, 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 array_size, i;
uint32_t *table; 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); table = kzalloc(array_size, GFP_KERNEL);
if (NULL == table) if (NULL == table)
return -ENOMEM; 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]; table[i] = pptable_array[i];
*pptable_info_array = table; *pptable_info_array = table;
...@@ -686,22 +686,52 @@ static int copy_clock_limits_array( ...@@ -686,22 +686,52 @@ static int copy_clock_limits_array(
static int copy_overdrive_settings_limits_array( static int copy_overdrive_settings_limits_array(
struct pp_hwmgr *hwmgr, struct pp_hwmgr *hwmgr,
uint32_t **pptable_info_array, 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 array_size, i;
uint32_t *table; 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); table = kzalloc(array_size, GFP_KERNEL);
if (NULL == table) if (NULL == table)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < ATOM_VEGA20_ODSETTING_COUNT; i++) for (i = 0; i < od_feature_count; i++) {
table[i] = pptable_array[i]; table[i] = pptable_array[i];
if (table[i])
od_supported = true;
}
*pptable_info_array = table; *pptable_info_array = table;
if (od_supported)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_ACOverdriveSupport);
return 0; return 0;
} }
...@@ -799,6 +829,7 @@ static int init_powerplay_table_information( ...@@ -799,6 +829,7 @@ static int init_powerplay_table_information(
struct phm_ppt_v3_information *pptable_information = struct phm_ppt_v3_information *pptable_information =
(struct phm_ppt_v3_information *)hwmgr->pptable; (struct phm_ppt_v3_information *)hwmgr->pptable;
uint32_t disable_power_control = 0; uint32_t disable_power_control = 0;
uint32_t od_feature_count, od_setting_count, power_saving_clock_count;
int result; int result;
hwmgr->thermal_controller.ucType = powerplay_table->ucThermalControllerType; hwmgr->thermal_controller.ucType = powerplay_table->ucThermalControllerType;
...@@ -810,22 +841,25 @@ static int init_powerplay_table_information( ...@@ -810,22 +841,25 @@ static int init_powerplay_table_information(
phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl); phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl);
if (powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_GFXCLKFMAX] > VEGA20_ENGINECLOCK_HARDMAX) if (powerplay_table->OverDrive8Table.ucODTableRevision == 1) {
hwmgr->platform_descriptor.overdriveLimit.engineClock = VEGA20_ENGINECLOCK_HARDMAX; od_feature_count = (powerplay_table->OverDrive8Table.ODFeatureCount > ATOM_VEGA20_ODFEATURE_COUNT) ?
else ATOM_VEGA20_ODFEATURE_COUNT : powerplay_table->OverDrive8Table.ODFeatureCount;
hwmgr->platform_descriptor.overdriveLimit.engineClock = powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_GFXCLKFMAX]; od_setting_count = (powerplay_table->OverDrive8Table.ODSettingCount > ATOM_VEGA20_ODSETTING_COUNT) ?
hwmgr->platform_descriptor.overdriveLimit.memoryClock = powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_UCLKFMAX]; ATOM_VEGA20_ODSETTING_COUNT : powerplay_table->OverDrive8Table.ODSettingCount;
copy_overdrive_settings_limits_array(hwmgr, &pptable_information->od_settings_max, powerplay_table->OverDrive8Table.ODSettingsMax); copy_overdrive_feature_capabilities_array(hwmgr,
copy_overdrive_settings_limits_array(hwmgr, &pptable_information->od_settings_min, powerplay_table->OverDrive8Table.ODSettingsMin); &pptable_information->od_feature_capabilities,
powerplay_table->OverDrive8Table.ODFeatureCapabilities,
/* hwmgr->platformDescriptor.minOverdriveVDDC = 0; od_feature_count);
hwmgr->platformDescriptor.maxOverdriveVDDC = 0; copy_overdrive_settings_limits_array(hwmgr,
hwmgr->platformDescriptor.overdriveVDDCStep = 0; */ &pptable_information->od_settings_max,
powerplay_table->OverDrive8Table.ODSettingsMax,
if (hwmgr->platform_descriptor.overdriveLimit.engineClock > 0 od_setting_count);
&& hwmgr->platform_descriptor.overdriveLimit.memoryClock > 0) copy_overdrive_settings_limits_array(hwmgr,
phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_ACOverdriveSupport); &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_limit1 = powerplay_table->usSmallPowerLimit1;
pptable_information->us_small_power_limit2 = powerplay_table->usSmallPowerLimit2; pptable_information->us_small_power_limit2 = powerplay_table->usSmallPowerLimit2;
...@@ -838,15 +872,23 @@ static int init_powerplay_table_information( ...@@ -838,15 +872,23 @@ static int init_powerplay_table_information(
hwmgr->platform_descriptor.TDPODLimit = (uint16_t)powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_POWERPERCENTAGE]; hwmgr->platform_descriptor.TDPODLimit = (uint16_t)powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_POWERPERCENTAGE];
disable_power_control = 0; 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 */ /* enable TDP overdrive (PowerControl) feature as well if supported */
phm_cap_set(hwmgr->platform_descriptor.platformCaps, phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PowerControl);
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); pptable_information->smc_pptable = (PPTable_t *)kmalloc(sizeof(PPTable_t), GFP_KERNEL);
if (pptable_information->smc_pptable == NULL) if (pptable_information->smc_pptable == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -898,6 +940,9 @@ static int vega20_pp_tables_uninitialize(struct pp_hwmgr *hwmgr) ...@@ -898,6 +940,9 @@ static int vega20_pp_tables_uninitialize(struct pp_hwmgr *hwmgr)
kfree(pp_table_info->power_saving_clock_min); kfree(pp_table_info->power_saving_clock_min);
pp_table_info->power_saving_clock_min = NULL; 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); kfree(pp_table_info->od_settings_max);
pp_table_info->od_settings_max = NULL; pp_table_info->od_settings_max = NULL;
......
...@@ -232,6 +232,8 @@ enum phm_platform_caps { ...@@ -232,6 +232,8 @@ enum phm_platform_caps {
PHM_PlatformCaps_UVDClientMCTuning, PHM_PlatformCaps_UVDClientMCTuning,
PHM_PlatformCaps_ODNinACSupport, PHM_PlatformCaps_ODNinACSupport,
PHM_PlatformCaps_ODNinDCSupport, PHM_PlatformCaps_ODNinDCSupport,
PHM_PlatformCaps_OD8inACSupport,
PHM_PlatformCaps_OD8inDCSupport,
PHM_PlatformCaps_UMDPState, PHM_PlatformCaps_UMDPState,
PHM_PlatformCaps_AutoWattmanSupport, PHM_PlatformCaps_AutoWattmanSupport,
PHM_PlatformCaps_AutoWattmanEnable_CCCState, PHM_PlatformCaps_AutoWattmanEnable_CCCState,
......
...@@ -583,6 +583,7 @@ struct phm_ppt_v3_information ...@@ -583,6 +583,7 @@ struct phm_ppt_v3_information
uint32_t *power_saving_clock_max; uint32_t *power_saving_clock_max;
uint32_t *power_saving_clock_min; uint32_t *power_saving_clock_min;
uint8_t *od_feature_capabilities;
uint32_t *od_settings_max; uint32_t *od_settings_max;
uint32_t *od_settings_min; uint32_t *od_settings_min;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment