diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0080-drm-amd-powerplay-initialize-vega20-overdrive-settin.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0080-drm-amd-powerplay-initialize-vega20-overdrive-settin.patch | 635 |
1 files changed, 635 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0080-drm-amd-powerplay-initialize-vega20-overdrive-settin.patch b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0080-drm-amd-powerplay-initialize-vega20-overdrive-settin.patch new file mode 100644 index 00000000..093721cf --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0080-drm-amd-powerplay-initialize-vega20-overdrive-settin.patch @@ -0,0 +1,635 @@ +From 6b7311f88d16c58fd1284b2d811fc5a375cdff25 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 0080/2940] 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> +--- + .../drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 293 ++++++++++++++++-- + .../drm/amd/powerplay/hwmgr/vega20_hwmgr.h | 53 +++- + .../powerplay/hwmgr/vega20_processpptables.c | 103 ++++-- + .../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 182f25ccc61b..51bc05dea8e1 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 59a59bcdad3a..130052a330b3 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 379ac3d1da03..32d24a48a947 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 429c9c4322da..54fd0125d9cf 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 88f451764da9..a6d92128b19c 100644 +--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h ++++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +@@ -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; + +-- +2.17.1 + |