aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/5135-drm-amd-powerplay-initialize-vega20-overdrive-settin.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/5135-drm-amd-powerplay-initialize-vega20-overdrive-settin.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/5135-drm-amd-powerplay-initialize-vega20-overdrive-settin.patch635
1 files changed, 635 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/5135-drm-amd-powerplay-initialize-vega20-overdrive-settin.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/5135-drm-amd-powerplay-initialize-vega20-overdrive-settin.patch
new file mode 100644
index 00000000..1c6a8e8d
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/5135-drm-amd-powerplay-initialize-vega20-overdrive-settin.patch
@@ -0,0 +1,635 @@
+From 00267b5af20fbf9d573ebac9f6d9943f86909487 Mon Sep 17 00:00:00 2001
+From: Evan Quan <evan.quan@amd.com>
+Date: Mon, 21 May 2018 10:16:41 +0800
+Subject: [PATCH 5135/5725] drm/amd/powerplay: initialize vega20 overdrive
+ settings
+
+The initialized overdrive settings are taken from vbios and SMU(
+by PPSMC_MSG_TransferTableSmu2Dram).
+
+Signed-off-by: Evan Quan <evan.quan@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 293 +++++++++++++++++++--
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h | 53 +++-
+ .../amd/powerplay/hwmgr/vega20_processpptables.c | 103 ++++++--
+ .../gpu/drm/amd/powerplay/inc/hardwaremanager.h | 2 +
+ drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 1 +
+ 5 files changed, 403 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+index 182f25c..51bc05d 100644
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+@@ -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)
++ if (data->registry_data.od8_feature_enable)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+- PHM_PlatformCaps_ODNinDCSupport);
+- else {
+- phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+- PHM_PlatformCaps_OD6inDCSupport);
+- 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);
+diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h
+index 59a59bc..130052a 100644
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h
+@@ -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;
+
+diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c
+index 379ac3d..32d24a4 100644
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c
+@@ -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;
+
+diff --git a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
+index 429c9c4..54fd012 100644
+--- a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
++++ b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
+@@ -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,
+diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+index 7e58a0d..e0cb7d0 100644
+--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
++++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+@@ -584,6 +584,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;
+
+--
+2.7.4
+