diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4084-drm-amd-pp-Add-OVERDRIVE-support-on-Vega10.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4084-drm-amd-pp-Add-OVERDRIVE-support-on-Vega10.patch | 1038 |
1 files changed, 1038 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4084-drm-amd-pp-Add-OVERDRIVE-support-on-Vega10.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4084-drm-amd-pp-Add-OVERDRIVE-support-on-Vega10.patch new file mode 100644 index 00000000..6da6f73c --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4084-drm-amd-pp-Add-OVERDRIVE-support-on-Vega10.patch @@ -0,0 +1,1038 @@ +From c1921e381c2440062563f61dfcef84bef481b4df Mon Sep 17 00:00:00 2001 +From: Rex Zhu <Rex.Zhu@amd.com> +Date: Wed, 18 Apr 2018 18:46:07 +0800 +Subject: [PATCH 4084/4131] drm/amd/pp: Add OVERDRIVE support on Vega10 + +when bit14 in module parameter ppfeaturemask was set. +od feature will be enabled on Vega10 except vbios not support. + +user can read od range by reading sysfs pp_od_clk_voltage, +cat pp_od_clk_voltage +OD_SCLK: +0: 852Mhz 800mV +1: 991Mhz 900mV +2: 1138Mhz 950mV +3: 1269Mhz 1000mV +4: 1348Mhz 1050mV +5: 1399Mhz 1100mV +6: 1440Mhz 1150mV +7: 1500Mhz 1200mV +OD_MCLK: +0: 167Mhz 800mV +1: 500Mhz 800mV +2: 800Mhz 950mV +3: 945Mhz 1000mV +OD_RANGE: +SCLK: 852MHz 2200MHz +MCLK: 167MHz 1500MHz +VDDC: 800mV 1200mV + +and can configure the clock/voltage by writing pp_od_clk_voltage +for example: + +echo "s 0 900 820">pp_od_clk_voltage to change the sclk/vddc +to 900MHz and 820 mV in dpm level0. + +echo "r" to change the clk/voltage to default value. + +echo "c">pp_od_clk_voltage +to commit the change + +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Rex Zhu <Rex.Zhu@amd.com> +--- + drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 719 +++++++++++---------- + drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h | 26 +- + .../gpu/drm/amd/powerplay/inc/hardwaremanager.h | 6 +- + 3 files changed, 390 insertions(+), 361 deletions(-) + +diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +index 1905919..952c7dd 100644 +--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +@@ -285,6 +285,48 @@ static int vega10_set_features_platform_caps(struct pp_hwmgr *hwmgr) + return 0; + } + ++static int vega10_odn_initial_default_setting(struct pp_hwmgr *hwmgr) ++{ ++ struct vega10_hwmgr *data = hwmgr->backend; ++ struct phm_ppt_v2_information *table_info = ++ (struct phm_ppt_v2_information *)(hwmgr->pptable); ++ struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table); ++ struct vega10_odn_vddc_lookup_table *od_lookup_table; ++ struct phm_ppt_v1_voltage_lookup_table *vddc_lookup_table; ++ struct phm_ppt_v1_clock_voltage_dependency_table *dep_table[3]; ++ struct phm_ppt_v1_clock_voltage_dependency_table *od_table[3]; ++ uint32_t i; ++ ++ od_lookup_table = &odn_table->vddc_lookup_table; ++ vddc_lookup_table = table_info->vddc_lookup_table; ++ ++ for (i = 0; i < vddc_lookup_table->count; i++) ++ od_lookup_table->entries[i].us_vdd = vddc_lookup_table->entries[i].us_vdd; ++ ++ od_lookup_table->count = vddc_lookup_table->count; ++ ++ dep_table[0] = table_info->vdd_dep_on_sclk; ++ dep_table[1] = table_info->vdd_dep_on_mclk; ++ dep_table[2] = table_info->vdd_dep_on_socclk; ++ od_table[0] = (struct phm_ppt_v1_clock_voltage_dependency_table *)&odn_table->vdd_dep_on_sclk; ++ od_table[1] = (struct phm_ppt_v1_clock_voltage_dependency_table *)&odn_table->vdd_dep_on_mclk; ++ od_table[2] = (struct phm_ppt_v1_clock_voltage_dependency_table *)&odn_table->vdd_dep_on_socclk; ++ ++ for (i = 0; i < 3; i++) ++ smu_get_voltage_dependency_table_ppt_v1(dep_table[i], od_table[i]); ++ ++ if (odn_table->max_vddc == 0 || odn_table->max_vddc > 2000) ++ odn_table->max_vddc = dep_table[0]->entries[dep_table[0]->count - 1].vddc; ++ if (odn_table->min_vddc == 0 || odn_table->min_vddc > 2000) ++ odn_table->min_vddc = dep_table[0]->entries[0].vddc; ++ ++ i = od_table[2]->count - 1; ++ od_table[2]->entries[i].clk = hwmgr->platform_descriptor.overdriveLimit.memoryClock; ++ od_table[2]->entries[i].vddc = odn_table->max_vddc; ++ ++ return 0; ++} ++ + static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr) + { + struct vega10_hwmgr *data = hwmgr->backend; +@@ -421,7 +463,6 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr) + /* ACG firmware has major version 5 */ + if ((hwmgr->smu_version & 0xff000000) == 0x5000000) + data->smu_features[GNLD_ACG].supported = true; +- + if (data->registry_data.didt_support) + data->smu_features[GNLD_DIDT].supported = true; + +@@ -1360,48 +1401,6 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) + memcpy(&(data->golden_dpm_table), &(data->dpm_table), + sizeof(struct vega10_dpm_table)); + +- if (PP_CAP(PHM_PlatformCaps_ODNinACSupport) || +- PP_CAP(PHM_PlatformCaps_ODNinDCSupport)) { +- data->odn_dpm_table.odn_core_clock_dpm_levels.num_of_pl = +- data->dpm_table.gfx_table.count; +- for (i = 0; i < data->dpm_table.gfx_table.count; i++) { +- data->odn_dpm_table.odn_core_clock_dpm_levels.entries[i].clock = +- data->dpm_table.gfx_table.dpm_levels[i].value; +- data->odn_dpm_table.odn_core_clock_dpm_levels.entries[i].enabled = true; +- } +- +- data->odn_dpm_table.vdd_dependency_on_sclk.count = +- dep_gfx_table->count; +- for (i = 0; i < dep_gfx_table->count; i++) { +- data->odn_dpm_table.vdd_dependency_on_sclk.entries[i].clk = +- dep_gfx_table->entries[i].clk; +- data->odn_dpm_table.vdd_dependency_on_sclk.entries[i].vddInd = +- dep_gfx_table->entries[i].vddInd; +- data->odn_dpm_table.vdd_dependency_on_sclk.entries[i].cks_enable = +- dep_gfx_table->entries[i].cks_enable; +- data->odn_dpm_table.vdd_dependency_on_sclk.entries[i].cks_voffset = +- dep_gfx_table->entries[i].cks_voffset; +- } +- +- data->odn_dpm_table.odn_memory_clock_dpm_levels.num_of_pl = +- data->dpm_table.mem_table.count; +- for (i = 0; i < data->dpm_table.mem_table.count; i++) { +- data->odn_dpm_table.odn_memory_clock_dpm_levels.entries[i].clock = +- data->dpm_table.mem_table.dpm_levels[i].value; +- data->odn_dpm_table.odn_memory_clock_dpm_levels.entries[i].enabled = true; +- } +- +- data->odn_dpm_table.vdd_dependency_on_mclk.count = dep_mclk_table->count; +- for (i = 0; i < dep_mclk_table->count; i++) { +- data->odn_dpm_table.vdd_dependency_on_mclk.entries[i].clk = +- dep_mclk_table->entries[i].clk; +- data->odn_dpm_table.vdd_dependency_on_mclk.entries[i].vddInd = +- dep_mclk_table->entries[i].vddInd; +- data->odn_dpm_table.vdd_dependency_on_mclk.entries[i].vddci = +- dep_mclk_table->entries[i].vddci; +- } +- } +- + return 0; + } + +@@ -1504,18 +1503,18 @@ static int vega10_populate_single_gfx_level(struct pp_hwmgr *hwmgr, + { + struct phm_ppt_v2_information *table_info = + (struct phm_ppt_v2_information *)(hwmgr->pptable); +- struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_sclk = +- table_info->vdd_dep_on_sclk; ++ struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_sclk; + struct vega10_hwmgr *data = hwmgr->backend; + struct pp_atomfwctrl_clock_dividers_soc15 dividers; + uint32_t gfx_max_clock = + hwmgr->platform_descriptor.overdriveLimit.engineClock; + uint32_t i = 0; + +- if (data->apply_overdrive_next_settings_mask & +- DPMTABLE_OD_UPDATE_VDDC) ++ if (hwmgr->od_enabled) + dep_on_sclk = (struct phm_ppt_v1_clock_voltage_dependency_table *) +- &(data->odn_dpm_table.vdd_dependency_on_sclk); ++ &(data->odn_dpm_table.vdd_dep_on_sclk); ++ else ++ dep_on_sclk = table_info->vdd_dep_on_sclk; + + PP_ASSERT_WITH_CODE(dep_on_sclk, + "Invalid SOC_VDD-GFX_CLK Dependency Table!", +@@ -1567,23 +1566,32 @@ static int vega10_populate_single_soc_level(struct pp_hwmgr *hwmgr, + uint32_t soc_clock, uint8_t *current_soc_did, + uint8_t *current_vol_index) + { ++ struct vega10_hwmgr *data = hwmgr->backend; + struct phm_ppt_v2_information *table_info = + (struct phm_ppt_v2_information *)(hwmgr->pptable); +- struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_soc = +- table_info->vdd_dep_on_socclk; ++ struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_soc; + struct pp_atomfwctrl_clock_dividers_soc15 dividers; + uint32_t i; + +- PP_ASSERT_WITH_CODE(dep_on_soc, +- "Invalid SOC_VDD-SOC_CLK Dependency Table!", +- return -EINVAL); +- for (i = 0; i < dep_on_soc->count; i++) { +- if (dep_on_soc->entries[i].clk == soc_clock) +- break; ++ if (hwmgr->od_enabled) { ++ dep_on_soc = (struct phm_ppt_v1_clock_voltage_dependency_table *) ++ &data->odn_dpm_table.vdd_dep_on_socclk; ++ for (i = 0; i < dep_on_soc->count; i++) { ++ if (dep_on_soc->entries[i].clk >= soc_clock) ++ break; ++ } ++ } else { ++ dep_on_soc = table_info->vdd_dep_on_socclk; ++ for (i = 0; i < dep_on_soc->count; i++) { ++ if (dep_on_soc->entries[i].clk == soc_clock) ++ break; ++ } + } ++ + PP_ASSERT_WITH_CODE(dep_on_soc->count > i, + "Cannot find SOC_CLK in SOC_VDD-SOC_CLK Dependency Table", + return -EINVAL); ++ + PP_ASSERT_WITH_CODE(!pp_atomfwctrl_get_gpu_pll_dividers_vega10(hwmgr, + COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, + soc_clock, ÷rs), +@@ -1592,22 +1600,6 @@ static int vega10_populate_single_soc_level(struct pp_hwmgr *hwmgr, + + *current_soc_did = (uint8_t)dividers.ulDid; + *current_vol_index = (uint8_t)(dep_on_soc->entries[i].vddInd); +- +- return 0; +-} +- +-uint16_t vega10_locate_vddc_given_clock(struct pp_hwmgr *hwmgr, +- uint32_t clk, +- struct phm_ppt_v1_clock_voltage_dependency_table *dep_table) +-{ +- uint16_t i; +- +- for (i = 0; i < dep_table->count; i++) { +- if (dep_table->entries[i].clk == clk) +- return dep_table->entries[i].vddc; +- } +- +- pr_info("[LocateVddcGivenClock] Cannot locate SOC Vddc for this clock!"); + return 0; + } + +@@ -1621,8 +1613,6 @@ static int vega10_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) + struct vega10_hwmgr *data = hwmgr->backend; + struct phm_ppt_v2_information *table_info = + (struct phm_ppt_v2_information *)(hwmgr->pptable); +- struct phm_ppt_v1_clock_voltage_dependency_table *dep_table = +- table_info->vdd_dep_on_socclk; + PPTable_t *pp_table = &(data->smc_state_table.pp_table); + struct vega10_single_dpm_table *dpm_table = &(data->dpm_table.gfx_table); + int result = 0; +@@ -1653,11 +1643,6 @@ static int vega10_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) + + dpm_table = &(data->dpm_table.soc_table); + for (i = 0; i < dpm_table->count; i++) { +- pp_table->SocVid[i] = +- (uint8_t)convert_to_vid( +- vega10_locate_vddc_given_clock(hwmgr, +- dpm_table->dpm_levels[i].value, +- dep_table)); + result = vega10_populate_single_soc_level(hwmgr, + dpm_table->dpm_levels[i].value, + &(pp_table->SocclkDid[i]), +@@ -1668,7 +1653,6 @@ static int vega10_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) + + j = i - 1; + while (i < NUM_SOCCLK_DPM_LEVELS) { +- pp_table->SocVid[i] = pp_table->SocVid[j]; + result = vega10_populate_single_soc_level(hwmgr, + dpm_table->dpm_levels[j].value, + &(pp_table->SocclkDid[i]), +@@ -1681,6 +1665,32 @@ static int vega10_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) + return result; + } + ++static void vega10_populate_vddc_soc_levels(struct pp_hwmgr *hwmgr) ++{ ++ struct vega10_hwmgr *data = hwmgr->backend; ++ PPTable_t *pp_table = &(data->smc_state_table.pp_table); ++ struct phm_ppt_v2_information *table_info = hwmgr->pptable; ++ struct phm_ppt_v1_voltage_lookup_table *vddc_lookup_table; ++ ++ uint8_t soc_vid; ++ uint32_t i, max_vddc_level; ++ ++ if (hwmgr->od_enabled) ++ vddc_lookup_table = (struct phm_ppt_v1_voltage_lookup_table *)&data->odn_dpm_table.vddc_lookup_table; ++ else ++ vddc_lookup_table = table_info->vddc_lookup_table; ++ ++ max_vddc_level = vddc_lookup_table->count; ++ for (i = 0; i < max_vddc_level; i++) { ++ soc_vid = (uint8_t)convert_to_vid(vddc_lookup_table->entries[i].us_vdd); ++ pp_table->SocVid[i] = soc_vid; ++ } ++ while (i < MAX_REGULAR_DPM_NUMBER) { ++ pp_table->SocVid[i] = soc_vid; ++ i++; ++ } ++} ++ + /** + * @brief Populates single SMC GFXCLK structure using the provided clock. + * +@@ -1695,25 +1705,25 @@ static int vega10_populate_single_memory_level(struct pp_hwmgr *hwmgr, + struct vega10_hwmgr *data = hwmgr->backend; + struct phm_ppt_v2_information *table_info = + (struct phm_ppt_v2_information *)(hwmgr->pptable); +- struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_mclk = +- table_info->vdd_dep_on_mclk; ++ struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_mclk; + struct pp_atomfwctrl_clock_dividers_soc15 dividers; + uint32_t mem_max_clock = + hwmgr->platform_descriptor.overdriveLimit.memoryClock; + uint32_t i = 0; + +- if (data->apply_overdrive_next_settings_mask & +- DPMTABLE_OD_UPDATE_VDDC) ++ if (hwmgr->od_enabled) + dep_on_mclk = (struct phm_ppt_v1_clock_voltage_dependency_table *) +- &data->odn_dpm_table.vdd_dependency_on_mclk; ++ &data->odn_dpm_table.vdd_dep_on_mclk; ++ else ++ dep_on_mclk = table_info->vdd_dep_on_mclk; + + PP_ASSERT_WITH_CODE(dep_on_mclk, + "Invalid SOC_VDD-UCLK Dependency Table!", + return -EINVAL); + +- if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_MCLK) ++ if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_MCLK) { + mem_clock = mem_clock > mem_max_clock ? mem_max_clock : mem_clock; +- else { ++ } else { + for (i = 0; i < dep_on_mclk->count; i++) { + if (dep_on_mclk->entries[i].clk == mem_clock) + break; +@@ -2057,6 +2067,9 @@ static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr) + if (data->smu_features[GNLD_AVFS].supported) { + result = pp_atomfwctrl_get_avfs_information(hwmgr, &avfs_params); + if (!result) { ++ data->odn_dpm_table.max_vddc = avfs_params.ulMaxVddc; ++ data->odn_dpm_table.min_vddc = avfs_params.ulMinVddc; ++ + pp_table->MinVoltageVid = (uint8_t) + convert_to_vid((uint16_t)(avfs_params.ulMinVddc)); + pp_table->MaxVoltageVid = (uint8_t) +@@ -2335,6 +2348,22 @@ static int vega10_avfs_enable(struct pp_hwmgr *hwmgr, bool enable) + return 0; + } + ++static int vega10_update_avfs(struct pp_hwmgr *hwmgr) ++{ ++ struct vega10_hwmgr *data = hwmgr->backend; ++ ++ if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_VDDC) { ++ vega10_avfs_enable(hwmgr, false); ++ } else if (data->need_update_dpm_table) { ++ vega10_avfs_enable(hwmgr, false); ++ vega10_avfs_enable(hwmgr, true); ++ } else { ++ vega10_avfs_enable(hwmgr, true); ++ } ++ ++ return 0; ++} ++ + static int vega10_populate_and_upload_avfs_fuse_override(struct pp_hwmgr *hwmgr) + { + int result = 0; +@@ -2396,6 +2425,10 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr) + "Failed to setup default DPM tables!", + return result); + ++ /* initialize ODN table */ ++ if (hwmgr->od_enabled) ++ vega10_odn_initial_default_setting(hwmgr); ++ + pp_atomfwctrl_get_voltage_table_v4(hwmgr, VOLTAGE_TYPE_VDDC, + VOLTAGE_OBJ_SVID2, &voltage_table); + pp_table->MaxVidStep = voltage_table.max_vid_step; +@@ -2442,6 +2475,8 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr) + "Failed to initialize Memory Level!", + return result); + ++ vega10_populate_vddc_soc_levels(hwmgr); ++ + result = vega10_populate_all_display_clock_levels(hwmgr); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize Display Level!", +@@ -3163,82 +3198,11 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, + + static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input) + { +- const struct phm_set_power_state_input *states = +- (const struct phm_set_power_state_input *)input; +- const struct vega10_power_state *vega10_ps = +- cast_const_phw_vega10_power_state(states->pnew_state); + struct vega10_hwmgr *data = hwmgr->backend; +- struct vega10_single_dpm_table *sclk_table = +- &(data->dpm_table.gfx_table); +- uint32_t sclk = vega10_ps->performance_levels +- [vega10_ps->performance_level_count - 1].gfx_clock; +- struct vega10_single_dpm_table *mclk_table = +- &(data->dpm_table.mem_table); +- uint32_t mclk = vega10_ps->performance_levels +- [vega10_ps->performance_level_count - 1].mem_clock; +- struct PP_Clocks min_clocks = {0}; +- uint32_t i; +- +- data->need_update_dpm_table = 0; +- +- if (PP_CAP(PHM_PlatformCaps_ODNinACSupport) || +- PP_CAP(PHM_PlatformCaps_ODNinDCSupport)) { +- for (i = 0; i < sclk_table->count; i++) { +- if (sclk == sclk_table->dpm_levels[i].value) +- break; +- } +- +- if (!(data->apply_overdrive_next_settings_mask & +- DPMTABLE_OD_UPDATE_SCLK) && i >= sclk_table->count) { +- /* Check SCLK in DAL's minimum clocks +- * in case DeepSleep divider update is required. +- */ +- if (data->display_timing.min_clock_in_sr != +- min_clocks.engineClockInSR && +- (min_clocks.engineClockInSR >= +- VEGA10_MINIMUM_ENGINE_CLOCK || +- data->display_timing.min_clock_in_sr >= +- VEGA10_MINIMUM_ENGINE_CLOCK)) +- data->need_update_dpm_table |= DPMTABLE_UPDATE_SCLK; +- } +- +- if (data->display_timing.num_existing_displays != +- hwmgr->display_config->num_display) +- data->need_update_dpm_table |= DPMTABLE_UPDATE_MCLK; +- } else { +- for (i = 0; i < sclk_table->count; i++) { +- if (sclk == sclk_table->dpm_levels[i].value) +- break; +- } +- +- if (i >= sclk_table->count) +- data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; +- else { +- /* Check SCLK in DAL's minimum clocks +- * in case DeepSleep divider update is required. +- */ +- if (data->display_timing.min_clock_in_sr != +- min_clocks.engineClockInSR && +- (min_clocks.engineClockInSR >= +- VEGA10_MINIMUM_ENGINE_CLOCK || +- data->display_timing.min_clock_in_sr >= +- VEGA10_MINIMUM_ENGINE_CLOCK)) +- data->need_update_dpm_table |= DPMTABLE_UPDATE_SCLK; +- } + +- for (i = 0; i < mclk_table->count; i++) { +- if (mclk == mclk_table->dpm_levels[i].value) +- break; +- } +- +- if (i >= mclk_table->count) +- data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; ++ if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display) ++ data->need_update_dpm_table |= DPMTABLE_UPDATE_MCLK; + +- if (data->display_timing.num_existing_displays != +- hwmgr->display_config->num_display || +- i >= mclk_table->count) +- data->need_update_dpm_table |= DPMTABLE_UPDATE_MCLK; +- } + return 0; + } + +@@ -3246,194 +3210,29 @@ static int vega10_populate_and_upload_sclk_mclk_dpm_levels( + struct pp_hwmgr *hwmgr, const void *input) + { + int result = 0; +- const struct phm_set_power_state_input *states = +- (const struct phm_set_power_state_input *)input; +- const struct vega10_power_state *vega10_ps = +- cast_const_phw_vega10_power_state(states->pnew_state); + struct vega10_hwmgr *data = hwmgr->backend; +- uint32_t sclk = vega10_ps->performance_levels +- [vega10_ps->performance_level_count - 1].gfx_clock; +- uint32_t mclk = vega10_ps->performance_levels +- [vega10_ps->performance_level_count - 1].mem_clock; +- struct vega10_dpm_table *dpm_table = &data->dpm_table; +- struct vega10_dpm_table *golden_dpm_table = +- &data->golden_dpm_table; +- uint32_t dpm_count, clock_percent; +- uint32_t i; +- +- if (PP_CAP(PHM_PlatformCaps_ODNinACSupport) || +- PP_CAP(PHM_PlatformCaps_ODNinDCSupport)) { +- +- if (!data->need_update_dpm_table && +- !data->apply_optimized_settings && +- !data->apply_overdrive_next_settings_mask) +- return 0; + +- if (data->apply_overdrive_next_settings_mask & +- DPMTABLE_OD_UPDATE_SCLK) { +- for (dpm_count = 0; +- dpm_count < dpm_table->gfx_table.count; +- dpm_count++) { +- dpm_table->gfx_table.dpm_levels[dpm_count].enabled = +- data->odn_dpm_table.odn_core_clock_dpm_levels.entries[dpm_count].enabled; +- dpm_table->gfx_table.dpm_levels[dpm_count].value = +- data->odn_dpm_table.odn_core_clock_dpm_levels.entries[dpm_count].clock; +- } +- } +- +- if (data->apply_overdrive_next_settings_mask & +- DPMTABLE_OD_UPDATE_MCLK) { +- for (dpm_count = 0; +- dpm_count < dpm_table->mem_table.count; +- dpm_count++) { +- dpm_table->mem_table.dpm_levels[dpm_count].enabled = +- data->odn_dpm_table.odn_memory_clock_dpm_levels.entries[dpm_count].enabled; +- dpm_table->mem_table.dpm_levels[dpm_count].value = +- data->odn_dpm_table.odn_memory_clock_dpm_levels.entries[dpm_count].clock; +- } +- } +- +- if ((data->need_update_dpm_table & DPMTABLE_UPDATE_SCLK) || +- data->apply_optimized_settings || +- (data->apply_overdrive_next_settings_mask & +- DPMTABLE_OD_UPDATE_SCLK)) { +- result = vega10_populate_all_graphic_levels(hwmgr); +- PP_ASSERT_WITH_CODE(!result, +- "Failed to populate SCLK during PopulateNewDPMClocksStates Function!", +- return result); +- } +- +- if ((data->need_update_dpm_table & DPMTABLE_UPDATE_MCLK) || +- (data->apply_overdrive_next_settings_mask & +- DPMTABLE_OD_UPDATE_MCLK)){ +- result = vega10_populate_all_memory_levels(hwmgr); +- PP_ASSERT_WITH_CODE(!result, +- "Failed to populate MCLK during PopulateNewDPMClocksStates Function!", +- return result); +- } +- } else { +- if (!data->need_update_dpm_table && +- !data->apply_optimized_settings) +- return 0; +- +- if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_SCLK && +- data->smu_features[GNLD_DPM_GFXCLK].supported) { +- dpm_table-> +- gfx_table.dpm_levels[dpm_table->gfx_table.count - 1]. +- value = sclk; +- if (hwmgr->od_enabled) { +- /* Need to do calculation based on the golden DPM table +- * as the Heatmap GPU Clock axis is also based on +- * the default values +- */ +- PP_ASSERT_WITH_CODE( +- golden_dpm_table->gfx_table.dpm_levels +- [golden_dpm_table->gfx_table.count - 1].value, +- "Divide by 0!", +- return -1); +- +- dpm_count = dpm_table->gfx_table.count < 2 ? +- 0 : dpm_table->gfx_table.count - 2; +- for (i = dpm_count; i > 1; i--) { +- if (sclk > golden_dpm_table->gfx_table.dpm_levels +- [golden_dpm_table->gfx_table.count - 1].value) { +- clock_percent = +- ((sclk - golden_dpm_table->gfx_table.dpm_levels +- [golden_dpm_table->gfx_table.count - 1].value) * +- 100) / +- golden_dpm_table->gfx_table.dpm_levels +- [golden_dpm_table->gfx_table.count - 1].value; +- +- dpm_table->gfx_table.dpm_levels[i].value = +- golden_dpm_table->gfx_table.dpm_levels[i].value + +- (golden_dpm_table->gfx_table.dpm_levels[i].value * +- clock_percent) / 100; +- } else if (golden_dpm_table-> +- gfx_table.dpm_levels[dpm_table->gfx_table.count-1].value > +- sclk) { +- clock_percent = +- ((golden_dpm_table->gfx_table.dpm_levels +- [golden_dpm_table->gfx_table.count - 1].value - +- sclk) * 100) / +- golden_dpm_table->gfx_table.dpm_levels +- [golden_dpm_table->gfx_table.count-1].value; +- +- dpm_table->gfx_table.dpm_levels[i].value = +- golden_dpm_table->gfx_table.dpm_levels[i].value - +- (golden_dpm_table->gfx_table.dpm_levels[i].value * +- clock_percent) / 100; +- } else +- dpm_table->gfx_table.dpm_levels[i].value = +- golden_dpm_table->gfx_table.dpm_levels[i].value; +- } +- } +- } +- +- if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_MCLK && +- data->smu_features[GNLD_DPM_UCLK].supported) { +- dpm_table-> +- mem_table.dpm_levels[dpm_table->mem_table.count - 1]. +- value = mclk; ++ if (!data->need_update_dpm_table) ++ return 0; + +- if (hwmgr->od_enabled) { +- PP_ASSERT_WITH_CODE( +- golden_dpm_table->mem_table.dpm_levels +- [golden_dpm_table->mem_table.count - 1].value, +- "Divide by 0!", +- return -1); ++ if (data->need_update_dpm_table & ++ (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK + DPMTABLE_UPDATE_SOCCLK)) { ++ result = vega10_populate_all_graphic_levels(hwmgr); ++ PP_ASSERT_WITH_CODE((0 == result), ++ "Failed to populate SCLK during PopulateNewDPMClocksStates Function!", ++ return result); ++ } + +- dpm_count = dpm_table->mem_table.count < 2 ? +- 0 : dpm_table->mem_table.count - 2; +- for (i = dpm_count; i > 1; i--) { +- if (mclk > golden_dpm_table->mem_table.dpm_levels +- [golden_dpm_table->mem_table.count-1].value) { +- clock_percent = ((mclk - +- golden_dpm_table->mem_table.dpm_levels +- [golden_dpm_table->mem_table.count-1].value) * +- 100) / +- golden_dpm_table->mem_table.dpm_levels +- [golden_dpm_table->mem_table.count-1].value; +- +- dpm_table->mem_table.dpm_levels[i].value = +- golden_dpm_table->mem_table.dpm_levels[i].value + +- (golden_dpm_table->mem_table.dpm_levels[i].value * +- clock_percent) / 100; +- } else if (golden_dpm_table->mem_table.dpm_levels +- [dpm_table->mem_table.count-1].value > mclk) { +- clock_percent = ((golden_dpm_table->mem_table.dpm_levels +- [golden_dpm_table->mem_table.count-1].value - mclk) * +- 100) / +- golden_dpm_table->mem_table.dpm_levels +- [golden_dpm_table->mem_table.count-1].value; +- +- dpm_table->mem_table.dpm_levels[i].value = +- golden_dpm_table->mem_table.dpm_levels[i].value - +- (golden_dpm_table->mem_table.dpm_levels[i].value * +- clock_percent) / 100; +- } else +- dpm_table->mem_table.dpm_levels[i].value = +- golden_dpm_table->mem_table.dpm_levels[i].value; +- } +- } +- } ++ if (data->need_update_dpm_table & ++ (DPMTABLE_OD_UPDATE_MCLK + DPMTABLE_UPDATE_MCLK)) { ++ result = vega10_populate_all_memory_levels(hwmgr); ++ PP_ASSERT_WITH_CODE((0 == result), ++ "Failed to populate MCLK during PopulateNewDPMClocksStates Function!", ++ return result); ++ } + +- if ((data->need_update_dpm_table & +- (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK)) || +- data->apply_optimized_settings) { +- result = vega10_populate_all_graphic_levels(hwmgr); +- PP_ASSERT_WITH_CODE(!result, +- "Failed to populate SCLK during PopulateNewDPMClocksStates Function!", +- return result); +- } ++ vega10_populate_vddc_soc_levels(hwmgr); + +- if (data->need_update_dpm_table & +- (DPMTABLE_OD_UPDATE_MCLK + DPMTABLE_UPDATE_MCLK)) { +- result = vega10_populate_all_memory_levels(hwmgr); +- PP_ASSERT_WITH_CODE(!result, +- "Failed to populate MCLK during PopulateNewDPMClocksStates Function!", +- return result); +- } +- } + return result; + } + +@@ -3729,8 +3528,9 @@ static int vega10_set_power_state_tasks(struct pp_hwmgr *hwmgr, + PP_ASSERT_WITH_CODE(!result, + "Failed to upload PPtable!", return result); + +- data->apply_optimized_settings = false; +- data->apply_overdrive_next_settings_mask = 0; ++ vega10_update_avfs(hwmgr); ++ ++ data->need_update_dpm_table &= DPMTABLE_OD_UPDATE_VDDC; + + return 0; + } +@@ -4382,6 +4182,8 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, + struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); + struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); + struct vega10_pcie_table *pcie_table = &(data->dpm_table.pcie_table); ++ struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep = NULL; ++ + int i, now, size = 0; + + switch (type) { +@@ -4420,6 +4222,40 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, + (pcie_table->pcie_gen[i] == 2) ? "8.0GT/s, x16" : "", + (i == now) ? "*" : ""); + break; ++ case OD_SCLK: ++ if (hwmgr->od_enabled) { ++ size = sprintf(buf, "%s:\n", "OD_SCLK"); ++ podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk; ++ for (i = 0; i < podn_vdd_dep->count; i++) ++ size += sprintf(buf + size, "%d: %10uMhz %10umV\n", ++ i, podn_vdd_dep->entries[i].clk / 100, ++ podn_vdd_dep->entries[i].vddc); ++ } ++ break; ++ case OD_MCLK: ++ if (hwmgr->od_enabled) { ++ size = sprintf(buf, "%s:\n", "OD_MCLK"); ++ podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk; ++ for (i = 0; i < podn_vdd_dep->count; i++) ++ size += sprintf(buf + size, "%d: %10uMhz %10umV\n", ++ i, podn_vdd_dep->entries[i].clk/100, ++ podn_vdd_dep->entries[i].vddc); ++ } ++ break; ++ case OD_RANGE: ++ if (hwmgr->od_enabled) { ++ size = sprintf(buf, "%s:\n", "OD_RANGE"); ++ size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n", ++ data->golden_dpm_table.gfx_table.dpm_levels[0].value/100, ++ hwmgr->platform_descriptor.overdriveLimit.engineClock/100); ++ size += sprintf(buf + size, "MCLK: %7uMHz %10uMHz\n", ++ data->golden_dpm_table.mem_table.dpm_levels[0].value/100, ++ hwmgr->platform_descriptor.overdriveLimit.memoryClock/100); ++ size += sprintf(buf + size, "VDDC: %7umV %11umV\n", ++ data->odn_dpm_table.min_vddc, ++ data->odn_dpm_table.max_vddc); ++ } ++ break; + default: + break; + } +@@ -4807,6 +4643,200 @@ static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui + return 0; + } + ++ ++static bool vega10_check_clk_voltage_valid(struct pp_hwmgr *hwmgr, ++ enum PP_OD_DPM_TABLE_COMMAND type, ++ uint32_t clk, ++ uint32_t voltage) ++{ ++ struct vega10_hwmgr *data = hwmgr->backend; ++ struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table); ++ struct vega10_single_dpm_table *golden_table; ++ ++ if (voltage < odn_table->min_vddc || voltage > odn_table->max_vddc) { ++ pr_info("OD voltage is out of range [%d - %d] mV\n", odn_table->min_vddc, odn_table->max_vddc); ++ return false; ++ } ++ ++ if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) { ++ golden_table = &(data->golden_dpm_table.gfx_table); ++ if (golden_table->dpm_levels[0].value > clk || ++ hwmgr->platform_descriptor.overdriveLimit.engineClock < clk) { ++ pr_info("OD engine clock is out of range [%d - %d] MHz\n", ++ golden_table->dpm_levels[0].value/100, ++ hwmgr->platform_descriptor.overdriveLimit.engineClock/100); ++ return false; ++ } ++ } else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) { ++ golden_table = &(data->golden_dpm_table.mem_table); ++ if (golden_table->dpm_levels[0].value > clk || ++ hwmgr->platform_descriptor.overdriveLimit.memoryClock < clk) { ++ pr_info("OD memory clock is out of range [%d - %d] MHz\n", ++ golden_table->dpm_levels[0].value/100, ++ hwmgr->platform_descriptor.overdriveLimit.memoryClock/100); ++ return false; ++ } ++ } else { ++ return false; ++ } ++ ++ return true; ++} ++ ++static void vega10_check_dpm_table_updated(struct pp_hwmgr *hwmgr) ++{ ++ struct vega10_hwmgr *data = hwmgr->backend; ++ struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table); ++ struct phm_ppt_v2_information *table_info = hwmgr->pptable; ++ struct phm_ppt_v1_clock_voltage_dependency_table *dep_table; ++ struct phm_ppt_v1_clock_voltage_dependency_table *odn_dep_table; ++ uint32_t i; ++ ++ dep_table = table_info->vdd_dep_on_mclk; ++ odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dep_on_mclk); ++ ++ for (i = 0; i < dep_table->count; i++) { ++ if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) { ++ data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK; ++ return; ++ } ++ } ++ ++ dep_table = table_info->vdd_dep_on_sclk; ++ odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dep_on_sclk); ++ for (i = 0; i < dep_table->count; i++) { ++ if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) { ++ data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK; ++ return; ++ } ++ } ++ ++ if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_VDDC) { ++ data->need_update_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC; ++ data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK | DPMTABLE_OD_UPDATE_MCLK; ++ } ++} ++ ++static void vega10_odn_update_soc_table(struct pp_hwmgr *hwmgr, ++ enum PP_OD_DPM_TABLE_COMMAND type) ++{ ++ struct vega10_hwmgr *data = hwmgr->backend; ++ struct phm_ppt_v2_information *table_info = hwmgr->pptable; ++ struct phm_ppt_v1_clock_voltage_dependency_table *dep_table = table_info->vdd_dep_on_socclk; ++ struct vega10_single_dpm_table *dpm_table = &data->golden_dpm_table.soc_table; ++ ++ struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep_on_socclk = ++ &data->odn_dpm_table.vdd_dep_on_socclk; ++ struct vega10_odn_vddc_lookup_table *od_vddc_lookup_table = &data->odn_dpm_table.vddc_lookup_table; ++ ++ struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep; ++ uint8_t i, j; ++ ++ if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) { ++ podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk; ++ for (i = 0; i < podn_vdd_dep->count - 1; i++) ++ od_vddc_lookup_table->entries[i].us_vdd = podn_vdd_dep->entries[i].vddc; ++ if (od_vddc_lookup_table->entries[i].us_vdd < podn_vdd_dep->entries[i].vddc) ++ od_vddc_lookup_table->entries[i].us_vdd = podn_vdd_dep->entries[i].vddc; ++ } else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) { ++ podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk; ++ for (i = 0; i < dpm_table->count; i++) { ++ for (j = 0; j < od_vddc_lookup_table->count; j++) { ++ if (od_vddc_lookup_table->entries[j].us_vdd > ++ podn_vdd_dep->entries[i].vddc) ++ break; ++ } ++ if (j == od_vddc_lookup_table->count) { ++ od_vddc_lookup_table->entries[j-1].us_vdd = ++ podn_vdd_dep->entries[i].vddc; ++ data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC; ++ } ++ podn_vdd_dep->entries[i].vddInd = j; ++ } ++ dpm_table = &data->dpm_table.soc_table; ++ for (i = 0; i < dep_table->count; i++) { ++ if (dep_table->entries[i].vddInd == podn_vdd_dep->entries[dep_table->count-1].vddInd && ++ dep_table->entries[i].clk < podn_vdd_dep->entries[dep_table->count-1].clk) { ++ data->need_update_dpm_table |= DPMTABLE_UPDATE_SOCCLK; ++ podn_vdd_dep_on_socclk->entries[i].clk = podn_vdd_dep->entries[dep_table->count-1].clk; ++ dpm_table->dpm_levels[i].value = podn_vdd_dep_on_socclk->entries[i].clk; ++ } ++ } ++ if (podn_vdd_dep_on_socclk->entries[podn_vdd_dep_on_socclk->count - 1].clk < ++ podn_vdd_dep->entries[dep_table->count-1].clk) { ++ data->need_update_dpm_table |= DPMTABLE_UPDATE_SOCCLK; ++ podn_vdd_dep_on_socclk->entries[podn_vdd_dep_on_socclk->count - 1].clk = podn_vdd_dep->entries[dep_table->count-1].clk; ++ dpm_table->dpm_levels[podn_vdd_dep_on_socclk->count - 1].value = podn_vdd_dep->entries[dep_table->count-1].clk; ++ } ++ if (podn_vdd_dep_on_socclk->entries[podn_vdd_dep_on_socclk->count - 1].vddInd < ++ podn_vdd_dep->entries[dep_table->count-1].vddInd) { ++ data->need_update_dpm_table |= DPMTABLE_UPDATE_SOCCLK; ++ podn_vdd_dep_on_socclk->entries[podn_vdd_dep_on_socclk->count - 1].vddInd = podn_vdd_dep->entries[dep_table->count-1].vddInd; ++ } ++ } ++} ++ ++static int vega10_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, ++ enum PP_OD_DPM_TABLE_COMMAND type, ++ long *input, uint32_t size) ++{ ++ struct vega10_hwmgr *data = hwmgr->backend; ++ struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep_table; ++ struct vega10_single_dpm_table *dpm_table; ++ ++ uint32_t input_clk; ++ uint32_t input_vol; ++ uint32_t input_level; ++ uint32_t i; ++ ++ PP_ASSERT_WITH_CODE(input, "NULL user input for clock and voltage", ++ return -EINVAL); ++ ++ if (!hwmgr->od_enabled) { ++ pr_info("OverDrive feature not enabled\n"); ++ return -EINVAL; ++ } ++ ++ if (PP_OD_EDIT_SCLK_VDDC_TABLE == type) { ++ dpm_table = &data->dpm_table.gfx_table; ++ podn_vdd_dep_table = &data->odn_dpm_table.vdd_dep_on_sclk; ++ data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; ++ } else if (PP_OD_EDIT_MCLK_VDDC_TABLE == type) { ++ dpm_table = &data->dpm_table.mem_table; ++ podn_vdd_dep_table = &data->odn_dpm_table.vdd_dep_on_mclk; ++ data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; ++ } else if (PP_OD_RESTORE_DEFAULT_TABLE == type) { ++ memcpy(&(data->dpm_table), &(data->golden_dpm_table), sizeof(struct vega10_dpm_table)); ++ vega10_odn_initial_default_setting(hwmgr); ++ return 0; ++ } else if (PP_OD_COMMIT_DPM_TABLE == type) { ++ vega10_check_dpm_table_updated(hwmgr); ++ return 0; ++ } else { ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < size; i += 3) { ++ if (i + 3 > size || input[i] >= podn_vdd_dep_table->count) { ++ pr_info("invalid clock voltage input\n"); ++ return 0; ++ } ++ input_level = input[i]; ++ input_clk = input[i+1] * 100; ++ input_vol = input[i+2]; ++ ++ if (vega10_check_clk_voltage_valid(hwmgr, type, input_clk, input_vol)) { ++ dpm_table->dpm_levels[input_level].value = input_clk; ++ podn_vdd_dep_table->entries[input_level].clk = input_clk; ++ podn_vdd_dep_table->entries[input_level].vddc = input_vol; ++ } else { ++ return -EINVAL; ++ } ++ } ++ vega10_odn_update_soc_table(hwmgr, type); ++ return 0; ++} ++ + static const struct pp_hwmgr_func vega10_hwmgr_funcs = { + .backend_init = vega10_hwmgr_backend_init, + .backend_fini = vega10_hwmgr_backend_fini, +@@ -4865,6 +4895,7 @@ static const struct pp_hwmgr_func vega10_hwmgr_funcs = { + .get_power_profile_mode = vega10_get_power_profile_mode, + .set_power_profile_mode = vega10_set_power_profile_mode, + .set_power_limit = vega10_set_power_limit, ++ .odn_edit_dpm_table = vega10_odn_edit_dpm_table, + }; + + int vega10_enable_smc_features(struct pp_hwmgr *hwmgr, +diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h +index 5339ea1..aadd6cb 100644 +--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h +@@ -282,15 +282,21 @@ struct vega10_registry_data { + + struct vega10_odn_clock_voltage_dependency_table { + uint32_t count; +- struct phm_ppt_v1_clock_voltage_dependency_record +- entries[MAX_REGULAR_DPM_NUMBER]; ++ struct phm_ppt_v1_clock_voltage_dependency_record entries[MAX_REGULAR_DPM_NUMBER]; ++}; ++ ++struct vega10_odn_vddc_lookup_table { ++ uint32_t count; ++ struct phm_ppt_v1_voltage_lookup_record entries[MAX_REGULAR_DPM_NUMBER]; + }; + + struct vega10_odn_dpm_table { +- struct phm_odn_clock_levels odn_core_clock_dpm_levels; +- struct phm_odn_clock_levels odn_memory_clock_dpm_levels; +- struct vega10_odn_clock_voltage_dependency_table vdd_dependency_on_sclk; +- struct vega10_odn_clock_voltage_dependency_table vdd_dependency_on_mclk; ++ struct vega10_odn_clock_voltage_dependency_table vdd_dep_on_sclk; ++ struct vega10_odn_clock_voltage_dependency_table vdd_dep_on_mclk; ++ struct vega10_odn_clock_voltage_dependency_table vdd_dep_on_socclk; ++ struct vega10_odn_vddc_lookup_table vddc_lookup_table; ++ uint32_t max_vddc; ++ uint32_t min_vddc; + }; + + struct vega10_odn_fan_table { +@@ -301,8 +307,8 @@ struct vega10_odn_fan_table { + }; + + struct vega10_hwmgr { +- struct vega10_dpm_table dpm_table; +- struct vega10_dpm_table golden_dpm_table; ++ struct vega10_dpm_table dpm_table; ++ struct vega10_dpm_table golden_dpm_table; + struct vega10_registry_data registry_data; + struct vega10_vbios_boot_state vbios_boot_state; + struct vega10_mclk_latency_table mclk_latency_table; +@@ -368,12 +374,8 @@ struct vega10_hwmgr { + bool need_long_memory_training; + + /* Internal settings to apply the application power optimization parameters */ +- bool apply_optimized_settings; + uint32_t disable_dpm_mask; + +- /* ---- Overdrive next setting ---- */ +- uint32_t apply_overdrive_next_settings_mask; +- + /* ---- SMU9 ---- */ + struct smu_features smu_features[GNLD_FEATURES_MAX]; + struct vega10_smc_state_table smc_state_table; +diff --git a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h +index 8b78bbe..9bb8785 100644 +--- a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h ++++ b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h +@@ -377,11 +377,7 @@ struct phm_clocks { + #define DPMTABLE_UPDATE_SCLK 0x00000004 + #define DPMTABLE_UPDATE_MCLK 0x00000008 + #define DPMTABLE_OD_UPDATE_VDDC 0x00000010 +- +-/* To determine if sclk and mclk are in overdrive state */ +-#define SCLK_OVERDRIVE_ENABLED 0x00000001 +-#define MCLK_OVERDRIVE_ENABLED 0x00000002 +-#define VDDC_OVERDRIVE_ENABLED 0x00000010 ++#define DPMTABLE_UPDATE_SOCCLK 0x00000020 + + struct phm_odn_performance_level { + uint32_t clock; +-- +2.7.4 + |