diff options
Diffstat (limited to 'drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c')
-rw-r--r-- | drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 737 |
1 files changed, 603 insertions, 134 deletions
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c index 35629140fc7a..82676c086ce4 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c @@ -49,6 +49,8 @@ #include "processpptables.h" #include "pp_thermal.h" #include "smu7_baco.h" +#include "smu7_smumgr.h" +#include "polaris10_smumgr.h" #include "ivsrcid/ivsrcid_vislands30.h" @@ -97,6 +99,9 @@ static struct profile_mode_setting smu7_profiling[7] = #define PWR_SVI2_PLANE1_LOAD__PSI1__SHIFT 0x00000005 #define PWR_SVI2_PLANE1_LOAD__PSI0_EN__SHIFT 0x00000006 +#define STRAP_EVV_REVISION_MSB 2211 +#define STRAP_EVV_REVISION_LSB 2208 + /** Values for the CG_THERMAL_CTRL::DPM_EVENT_SRC field. */ enum DPM_EVENT_SRC { DPM_EVENT_SRC_ANALOG = 0, @@ -106,9 +111,66 @@ enum DPM_EVENT_SRC { DPM_EVENT_SRC_DIGITAL_OR_EXTERNAL = 4 }; +#define ixDIDT_SQ_EDC_CTRL 0x0013 +#define ixDIDT_SQ_EDC_THRESHOLD 0x0014 +#define ixDIDT_SQ_EDC_STALL_PATTERN_1_2 0x0015 +#define ixDIDT_SQ_EDC_STALL_PATTERN_3_4 0x0016 +#define ixDIDT_SQ_EDC_STALL_PATTERN_5_6 0x0017 +#define ixDIDT_SQ_EDC_STALL_PATTERN_7 0x0018 + +#define ixDIDT_TD_EDC_CTRL 0x0053 +#define ixDIDT_TD_EDC_THRESHOLD 0x0054 +#define ixDIDT_TD_EDC_STALL_PATTERN_1_2 0x0055 +#define ixDIDT_TD_EDC_STALL_PATTERN_3_4 0x0056 +#define ixDIDT_TD_EDC_STALL_PATTERN_5_6 0x0057 +#define ixDIDT_TD_EDC_STALL_PATTERN_7 0x0058 + +#define ixDIDT_TCP_EDC_CTRL 0x0073 +#define ixDIDT_TCP_EDC_THRESHOLD 0x0074 +#define ixDIDT_TCP_EDC_STALL_PATTERN_1_2 0x0075 +#define ixDIDT_TCP_EDC_STALL_PATTERN_3_4 0x0076 +#define ixDIDT_TCP_EDC_STALL_PATTERN_5_6 0x0077 +#define ixDIDT_TCP_EDC_STALL_PATTERN_7 0x0078 + +#define ixDIDT_DB_EDC_CTRL 0x0033 +#define ixDIDT_DB_EDC_THRESHOLD 0x0034 +#define ixDIDT_DB_EDC_STALL_PATTERN_1_2 0x0035 +#define ixDIDT_DB_EDC_STALL_PATTERN_3_4 0x0036 +#define ixDIDT_DB_EDC_STALL_PATTERN_5_6 0x0037 +#define ixDIDT_DB_EDC_STALL_PATTERN_7 0x0038 + +uint32_t DIDTEDCConfig_P12[] = { + ixDIDT_SQ_EDC_STALL_PATTERN_1_2, + ixDIDT_SQ_EDC_STALL_PATTERN_3_4, + ixDIDT_SQ_EDC_STALL_PATTERN_5_6, + ixDIDT_SQ_EDC_STALL_PATTERN_7, + ixDIDT_SQ_EDC_THRESHOLD, + ixDIDT_SQ_EDC_CTRL, + ixDIDT_TD_EDC_STALL_PATTERN_1_2, + ixDIDT_TD_EDC_STALL_PATTERN_3_4, + ixDIDT_TD_EDC_STALL_PATTERN_5_6, + ixDIDT_TD_EDC_STALL_PATTERN_7, + ixDIDT_TD_EDC_THRESHOLD, + ixDIDT_TD_EDC_CTRL, + ixDIDT_TCP_EDC_STALL_PATTERN_1_2, + ixDIDT_TCP_EDC_STALL_PATTERN_3_4, + ixDIDT_TCP_EDC_STALL_PATTERN_5_6, + ixDIDT_TCP_EDC_STALL_PATTERN_7, + ixDIDT_TCP_EDC_THRESHOLD, + ixDIDT_TCP_EDC_CTRL, + ixDIDT_DB_EDC_STALL_PATTERN_1_2, + ixDIDT_DB_EDC_STALL_PATTERN_3_4, + ixDIDT_DB_EDC_STALL_PATTERN_5_6, + ixDIDT_DB_EDC_STALL_PATTERN_7, + ixDIDT_DB_EDC_THRESHOLD, + ixDIDT_DB_EDC_CTRL, + 0xFFFFFFFF // End of list +}; + static const unsigned long PhwVIslands_Magic = (unsigned long)(PHM_VIslands_Magic); static int smu7_force_clock_level(struct pp_hwmgr *hwmgr, enum pp_clock_type type, uint32_t mask); +static int smu7_notify_has_display(struct pp_hwmgr *hwmgr); static struct smu7_power_state *cast_phw_smu7_power_state( struct pp_hw_power_state *hw_ps) @@ -131,10 +193,10 @@ static const struct smu7_power_state *cast_const_phw_smu7_power_state( } /** - * Find the MC microcode version and store it in the HwMgr struct + * smu7_get_mc_microcode_version - Find the MC microcode version and store it in the HwMgr struct * - * @param hwmgr the address of the powerplay hardware manager. - * @return always 0 + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 */ static int smu7_get_mc_microcode_version(struct pp_hwmgr *hwmgr) { @@ -171,14 +233,15 @@ static int smu7_get_current_pcie_lane_number(struct pp_hwmgr *hwmgr) } /** -* Enable voltage control -* -* @param pHwMgr the address of the powerplay hardware manager. -* @return always PP_Result_OK -*/ + * smu7_enable_smc_voltage_controller - Enable voltage control + * + * @hwmgr the address of the powerplay hardware manager. + * Return: always PP_Result_OK + */ static int smu7_enable_smc_voltage_controller(struct pp_hwmgr *hwmgr) { - if (hwmgr->chip_id == CHIP_VEGAM) { + if (hwmgr->chip_id >= CHIP_POLARIS10 && + hwmgr->chip_id <= CHIP_VEGAM) { PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_SVI2_PLANE1_LOAD, PSI1, 0); PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, @@ -192,10 +255,10 @@ static int smu7_enable_smc_voltage_controller(struct pp_hwmgr *hwmgr) } /** -* Checks if we want to support voltage control -* -* @param hwmgr the address of the powerplay hardware manager. -*/ + * smu7_voltage_control - Checks if we want to support voltage control + * + * @hwmgr: the address of the powerplay hardware manager. + */ static bool smu7_voltage_control(const struct pp_hwmgr *hwmgr) { const struct smu7_hwmgr *data = @@ -205,11 +268,11 @@ static bool smu7_voltage_control(const struct pp_hwmgr *hwmgr) } /** -* Enable voltage control -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ + * smu7_enable_voltage_control - Enable voltage control + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 + */ static int smu7_enable_voltage_control(struct pp_hwmgr *hwmgr) { /* enable voltage control */ @@ -243,11 +306,11 @@ static int phm_get_svi2_voltage_table_v0(pp_atomctrl_voltage_table *voltage_tabl /** -* Create Voltage Tables. -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ + * smu7_construct_voltage_tables - Create Voltage Tables. + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 + */ static int smu7_construct_voltage_tables(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); @@ -355,11 +418,11 @@ static int smu7_construct_voltage_tables(struct pp_hwmgr *hwmgr) } /** -* Programs static screed detection parameters -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ + * smu7_program_static_screen_threshold_parameters - Programs static screed detection parameters + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 + */ static int smu7_program_static_screen_threshold_parameters( struct pp_hwmgr *hwmgr) { @@ -378,11 +441,11 @@ static int smu7_program_static_screen_threshold_parameters( } /** -* Setup display gap for glitch free memory clock switching. -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ + * smu7_enable_display_gap - Setup display gap for glitch free memory clock switching. + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 + */ static int smu7_enable_display_gap(struct pp_hwmgr *hwmgr) { uint32_t display_gap = @@ -402,11 +465,11 @@ static int smu7_enable_display_gap(struct pp_hwmgr *hwmgr) } /** -* Programs activity state transition voting clients -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ + * smu7_program_voting_clients - Programs activity state transition voting clients + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 + */ static int smu7_program_voting_clients(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); @@ -497,12 +560,12 @@ static int smu7_reset_to_default(struct pp_hwmgr *hwmgr) } /** -* Initial switch from ARB F0->F1 -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -* This function is to be called from the SetPowerState table. -*/ + * smu7_initial_switch_from_arbf0_to_f1 - Initial switch from ARB F0->F1 + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 + * This function is to be called from the SetPowerState table. + */ static int smu7_initial_switch_from_arbf0_to_f1(struct pp_hwmgr *hwmgr) { return smu7_copy_and_switch_arb_sets(hwmgr, @@ -1088,7 +1151,8 @@ static int smu7_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) /* enable SCLK dpm */ if (!data->sclk_dpm_key_disabled) { - if (hwmgr->chip_id == CHIP_VEGAM) + if (hwmgr->chip_id >= CHIP_POLARIS10 && + hwmgr->chip_id <= CHIP_VEGAM) smu7_disable_sclk_vce_handshake(hwmgr); PP_ASSERT_WITH_CODE( @@ -1109,7 +1173,11 @@ static int smu7_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) "Failed to enable MCLK DPM during DPM Start Function!", return -EINVAL); - if (hwmgr->chip_family != CHIP_VEGAM) + if ((hwmgr->chip_family == AMDGPU_FAMILY_CI) || + (hwmgr->chip_id == CHIP_POLARIS10) || + (hwmgr->chip_id == CHIP_POLARIS11) || + (hwmgr->chip_id == CHIP_POLARIS12) || + (hwmgr->chip_id == CHIP_TONGA)) PHM_WRITE_FIELD(hwmgr->device, MC_SEQ_CNTL_3, CAC_EN, 0x1); @@ -1331,6 +1399,50 @@ static int smu7_pcie_performance_request(struct pp_hwmgr *hwmgr) return 0; } +static int smu7_program_edc_didt_registers(struct pp_hwmgr *hwmgr, + uint32_t *cac_config_regs, + AtomCtrl_EDCLeakgeTable *edc_leakage_table) +{ + uint32_t data, i = 0; + + while (cac_config_regs[i] != 0xFFFFFFFF) { + data = edc_leakage_table->DIDT_REG[i]; + cgs_write_ind_register(hwmgr->device, + CGS_IND_REG__DIDT, + cac_config_regs[i], + data); + i++; + } + + return 0; +} + +static int smu7_populate_edc_leakage_registers(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + int ret = 0; + + if (!data->disable_edc_leakage_controller && + data->edc_hilo_leakage_offset_from_vbios.usEdcDidtLoDpm7TableOffset && + data->edc_hilo_leakage_offset_from_vbios.usEdcDidtHiDpm7TableOffset) { + ret = smu7_program_edc_didt_registers(hwmgr, + DIDTEDCConfig_P12, + &data->edc_leakage_table); + if (ret) + return ret; + + ret = smum_send_msg_to_smc(hwmgr, + (PPSMC_Msg)PPSMC_MSG_EnableEDCController, + NULL); + } else { + ret = smum_send_msg_to_smc(hwmgr, + (PPSMC_Msg)PPSMC_MSG_DisableEDCController, + NULL); + } + + return ret; +} + static int smu7_enable_dpm_tasks(struct pp_hwmgr *hwmgr) { int tmp_result = 0; @@ -1395,7 +1507,21 @@ static int smu7_enable_dpm_tasks(struct pp_hwmgr *hwmgr) PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to enable VR hot GPIO interrupt!", result = tmp_result); - smum_send_msg_to_smc(hwmgr, (PPSMC_Msg)PPSMC_NoDisplay, NULL); + if (hwmgr->chip_id >= CHIP_POLARIS10 && + hwmgr->chip_id <= CHIP_VEGAM) { + tmp_result = smu7_notify_has_display(hwmgr); + PP_ASSERT_WITH_CODE((0 == tmp_result), + "Failed to enable display setting!", result = tmp_result); + } else { + smum_send_msg_to_smc(hwmgr, (PPSMC_Msg)PPSMC_NoDisplay, NULL); + } + + if (hwmgr->chip_id >= CHIP_POLARIS10 && + hwmgr->chip_id <= CHIP_VEGAM) { + tmp_result = smu7_populate_edc_leakage_registers(hwmgr); + PP_ASSERT_WITH_CODE((0 == tmp_result), + "Failed to populate edc leakage registers!", result = tmp_result); + } tmp_result = smu7_enable_sclk_control(hwmgr); PP_ASSERT_WITH_CODE((0 == tmp_result), @@ -1558,6 +1684,8 @@ static void smu7_init_dpm_defaults(struct pp_hwmgr *hwmgr) struct phm_ppt_v1_information *table_info = (struct phm_ppt_v1_information *)(hwmgr->pptable); struct amdgpu_device *adev = hwmgr->adev; + uint8_t tmp1, tmp2; + uint16_t tmp3 = 0; data->dll_default_on = false; data->mclk_dpm0_activity_target = 0xa; @@ -1612,19 +1740,6 @@ static void smu7_init_dpm_defaults(struct pp_hwmgr *hwmgr) hwmgr->power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D; hwmgr->default_power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D; - if (hwmgr->chip_id == CHIP_POLARIS12 || hwmgr->is_kicker) { - uint8_t tmp1, tmp2; - uint16_t tmp3 = 0; - atomctrl_get_svi2_info(hwmgr, VOLTAGE_TYPE_VDDC, &tmp1, &tmp2, - &tmp3); - tmp3 = (tmp3 >> 5) & 0x3; - data->vddc_phase_shed_control = ((tmp3 << 1) | (tmp3 >> 1)) & 0x3; - } else if (hwmgr->chip_family == AMDGPU_FAMILY_CI) { - data->vddc_phase_shed_control = 1; - } else { - data->vddc_phase_shed_control = 0; - } - if (hwmgr->chip_id == CHIP_HAWAII) { data->thermal_temp_setting.temperature_low = 94500; data->thermal_temp_setting.temperature_high = 95000; @@ -1683,6 +1798,22 @@ static void smu7_init_dpm_defaults(struct pp_hwmgr *hwmgr) phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_ControlVDDCI); + data->vddc_phase_shed_control = 1; + if ((hwmgr->chip_id == CHIP_POLARIS12) || + ASICID_IS_P20(adev->pdev->device, adev->pdev->revision) || + ASICID_IS_P21(adev->pdev->device, adev->pdev->revision) || + ASICID_IS_P30(adev->pdev->device, adev->pdev->revision) || + ASICID_IS_P31(adev->pdev->device, adev->pdev->revision)) { + if (data->voltage_control == SMU7_VOLTAGE_CONTROL_BY_SVID2) { + atomctrl_get_svi2_info(hwmgr, VOLTAGE_TYPE_VDDC, &tmp1, &tmp2, + &tmp3); + tmp3 = (tmp3 >> 5) & 0x3; + data->vddc_phase_shed_control = ((tmp3 << 1) | (tmp3 >> 1)) & 0x3; + } + } else if (hwmgr->chip_family == AMDGPU_FAMILY_CI) { + data->vddc_phase_shed_control = 1; + } + if ((hwmgr->pp_table_version != PP_TABLE_V0) && (hwmgr->feature_mask & PP_CLOCK_STRETCH_MASK) && (table_info->cac_dtp_table->usClockStretchAmount != 0)) phm_cap_set(hwmgr->platform_descriptor.platformCaps, @@ -1704,14 +1835,93 @@ static void smu7_init_dpm_defaults(struct pp_hwmgr *hwmgr) if (adev->pg_flags & AMD_PG_SUPPORT_VCE) phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEPowerGating); + + data->disable_edc_leakage_controller = true; + if (((adev->asic_type == CHIP_POLARIS10) && hwmgr->is_kicker) || + ((adev->asic_type == CHIP_POLARIS11) && hwmgr->is_kicker) || + (adev->asic_type == CHIP_POLARIS12) || + (adev->asic_type == CHIP_VEGAM)) + data->disable_edc_leakage_controller = false; + + if (!atomctrl_is_asic_internal_ss_supported(hwmgr)) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MemorySpreadSpectrumSupport); + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_EngineSpreadSpectrumSupport); + } + + if ((adev->pdev->device == 0x699F) && + (adev->pdev->revision == 0xCF)) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_PowerContainment); + data->enable_tdc_limit_feature = false; + data->enable_pkg_pwr_tracking_feature = false; + data->disable_edc_leakage_controller = true; + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_ClockStretcher); + } +} + +static int smu7_calculate_ro_range(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct amdgpu_device *adev = hwmgr->adev; + uint32_t asicrev1, evv_revision, max = 0, min = 0; + + atomctrl_read_efuse(hwmgr, STRAP_EVV_REVISION_LSB, STRAP_EVV_REVISION_MSB, + &evv_revision); + + atomctrl_read_efuse(hwmgr, 568, 579, &asicrev1); + + if (ASICID_IS_P20(adev->pdev->device, adev->pdev->revision) || + ASICID_IS_P30(adev->pdev->device, adev->pdev->revision)) { + min = 1200; + max = 2500; + } else if (ASICID_IS_P21(adev->pdev->device, adev->pdev->revision) || + ASICID_IS_P31(adev->pdev->device, adev->pdev->revision)) { + min = 900; + max= 2100; + } else if (hwmgr->chip_id == CHIP_POLARIS10) { + if (adev->pdev->subsystem_vendor == 0x106B) { + min = 1000; + max = 2300; + } else { + if (evv_revision == 0) { + min = 1000; + max = 2300; + } else if (evv_revision == 1) { + if (asicrev1 == 326) { + min = 1200; + max = 2500; + /* TODO: PATCH RO in VBIOS */ + } else { + min = 1200; + max = 2000; + } + } else if (evv_revision == 2) { + min = 1200; + max = 2500; + } + } + } else { + min = 1100; + max = 2100; + } + + data->ro_range_minimum = min; + data->ro_range_maximum = max; + + /* TODO: PATCH RO in VBIOS here */ + + return 0; } /** -* Get Leakage VDDC based on leakage ID. -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ + * smu7_get_evv_voltages - Get Leakage VDDC based on leakage ID. + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 + */ static int smu7_get_evv_voltages(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); @@ -1724,6 +1934,10 @@ static int smu7_get_evv_voltages(struct pp_hwmgr *hwmgr) (struct phm_ppt_v1_information *)hwmgr->pptable; struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = NULL; + if (hwmgr->chip_id == CHIP_POLARIS10 || + hwmgr->chip_id == CHIP_POLARIS11 || + hwmgr->chip_id == CHIP_POLARIS12) + smu7_calculate_ro_range(hwmgr); for (i = 0; i < SMU7_MAX_LEAKAGE_COUNT; i++) { vv_id = ATOM_VIRTUAL_VOLTAGE_ID0 + i; @@ -1803,11 +2017,11 @@ static int smu7_get_evv_voltages(struct pp_hwmgr *hwmgr) } /** - * Change virtual leakage voltage to actual value. + * smu7_patch_ppt_v1_with_vdd_leakage - Change virtual leakage voltage to actual value. * - * @param hwmgr the address of the powerplay hardware manager. - * @param pointer to changing voltage - * @param pointer to leakage table + * @hwmgr: the address of the powerplay hardware manager. + * @voltage: pointer to changing voltage + * @leakage_table: pointer to leakage table */ static void smu7_patch_ppt_v1_with_vdd_leakage(struct pp_hwmgr *hwmgr, uint16_t *voltage, struct smu7_leakage_voltage *leakage_table) @@ -1829,13 +2043,13 @@ static void smu7_patch_ppt_v1_with_vdd_leakage(struct pp_hwmgr *hwmgr, } /** -* Patch voltage lookup table by EVV leakages. -* -* @param hwmgr the address of the powerplay hardware manager. -* @param pointer to voltage lookup table -* @param pointer to leakage table -* @return always 0 -*/ + * smu7_patch_lookup_table_with_leakage - Patch voltage lookup table by EVV leakages. + * + * @hwmgr: the address of the powerplay hardware manager. + * @lookup_table: pointer to voltage lookup table + * @leakage_table: pointer to leakage table + * Return: always 0 + */ static int smu7_patch_lookup_table_with_leakage(struct pp_hwmgr *hwmgr, phm_ppt_v1_voltage_lookup_table *lookup_table, struct smu7_leakage_voltage *leakage_table) @@ -2087,6 +2301,28 @@ static int smu7_complete_dependency_tables(struct pp_hwmgr *hwmgr) return result; } +static int smu7_find_highest_vddc(struct pp_hwmgr *hwmgr) +{ + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_clock_voltage_dependency_table *allowed_sclk_vdd_table = + table_info->vdd_dep_on_sclk; + struct phm_ppt_v1_voltage_lookup_table *lookup_table = + table_info->vddc_lookup_table; + uint16_t highest_voltage; + uint32_t i; + + highest_voltage = allowed_sclk_vdd_table->entries[allowed_sclk_vdd_table->count - 1].vddc; + + for (i = 0; i < lookup_table->count; i++) { + if (lookup_table->entries[i].us_vdd < ATOM_VIRTUAL_VOLTAGE_ID0 && + lookup_table->entries[i].us_vdd > highest_voltage) + highest_voltage = lookup_table->entries[i].us_vdd; + } + + return highest_voltage; +} + static int smu7_set_private_data_based_on_pptable_v1(struct pp_hwmgr *hwmgr) { struct phm_ppt_v1_information *table_info = @@ -2115,8 +2351,12 @@ static int smu7_set_private_data_based_on_pptable_v1(struct pp_hwmgr *hwmgr) allowed_sclk_vdd_table->entries[allowed_sclk_vdd_table->count - 1].clk; table_info->max_clock_voltage_on_ac.mclk = allowed_mclk_vdd_table->entries[allowed_mclk_vdd_table->count - 1].clk; - table_info->max_clock_voltage_on_ac.vddc = - allowed_sclk_vdd_table->entries[allowed_sclk_vdd_table->count - 1].vddc; + if (hwmgr->chip_id >= CHIP_POLARIS10 && hwmgr->chip_id <= CHIP_VEGAM) + table_info->max_clock_voltage_on_ac.vddc = + smu7_find_highest_vddc(hwmgr); + else + table_info->max_clock_voltage_on_ac.vddc = + allowed_sclk_vdd_table->entries[allowed_sclk_vdd_table->count - 1].vddc; table_info->max_clock_voltage_on_ac.vddci = allowed_mclk_vdd_table->entries[allowed_mclk_vdd_table->count - 1].vddci; @@ -2148,10 +2388,17 @@ static int smu7_patch_voltage_workaround(struct pp_hwmgr *hwmgr) sub_sys_id = adev->pdev->subsystem_device; sub_vendor_id = adev->pdev->subsystem_vendor; - if (hwmgr->chip_id == CHIP_POLARIS10 && hw_revision == 0xC7 && - ((sub_sys_id == 0xb37 && sub_vendor_id == 0x1002) || - (sub_sys_id == 0x4a8 && sub_vendor_id == 0x1043) || - (sub_sys_id == 0x9480 && sub_vendor_id == 0x1682))) { + if (adev->pdev->device == 0x67DF && hw_revision == 0xC7 && + ((sub_sys_id == 0xb37 && sub_vendor_id == 0x1002) || + (sub_sys_id == 0x4a8 && sub_vendor_id == 0x1043) || + (sub_sys_id == 0x9480 && sub_vendor_id == 0x1682))) { + + PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, + CGS_IND_REG__SMC, + PWR_CKS_CNTL, + CKS_STRETCH_AMOUNT, + 0x3); + if (lookup_table->entries[dep_mclk_table->entries[dep_mclk_table->count-1].vddInd].us_vdd >= 1000) return 0; @@ -2253,11 +2500,11 @@ static int smu7_thermal_parameter_init(struct pp_hwmgr *hwmgr) } /** - * Change virtual leakage voltage to actual value. + * smu7_patch_ppt_v0_with_vdd_leakage - Change virtual leakage voltage to actual value. * - * @param hwmgr the address of the powerplay hardware manager. - * @param pointer to changing voltage - * @param pointer to leakage table + * @hwmgr: the address of the powerplay hardware manager. + * @voltage: pointer to changing voltage + * @leakage_table: pointer to leakage table */ static void smu7_patch_ppt_v0_with_vdd_leakage(struct pp_hwmgr *hwmgr, uint32_t *voltage, struct smu7_leakage_voltage *leakage_table) @@ -2552,6 +2799,42 @@ static int smu7_get_elb_voltages(struct pp_hwmgr *hwmgr) return 0; } +#define LEAKAGE_ID_MSB 463 +#define LEAKAGE_ID_LSB 454 + +static int smu7_update_edc_leakage_table(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t efuse; + uint16_t offset; + int ret = 0; + + if (data->disable_edc_leakage_controller) + return 0; + + ret = atomctrl_get_edc_hilo_leakage_offset_table(hwmgr, + &data->edc_hilo_leakage_offset_from_vbios); + if (ret) + return ret; + + if (data->edc_hilo_leakage_offset_from_vbios.usEdcDidtLoDpm7TableOffset && + data->edc_hilo_leakage_offset_from_vbios.usEdcDidtHiDpm7TableOffset) { + atomctrl_read_efuse(hwmgr, LEAKAGE_ID_LSB, LEAKAGE_ID_MSB, &efuse); + if (efuse < data->edc_hilo_leakage_offset_from_vbios.usHiLoLeakageThreshold) + offset = data->edc_hilo_leakage_offset_from_vbios.usEdcDidtLoDpm7TableOffset; + else + offset = data->edc_hilo_leakage_offset_from_vbios.usEdcDidtHiDpm7TableOffset; + + ret = atomctrl_get_edc_leakage_table(hwmgr, + &data->edc_leakage_table, + offset); + if (ret) + return ret; + } + + return ret; +} + static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data; @@ -2601,6 +2884,8 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) data->pcie_gen_cap = adev->pm.pcie_gen_mask; if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) data->pcie_spc_cap = 20; + else + data->pcie_spc_cap = 16; data->pcie_lane_cap = adev->pm.pcie_mlw_mask; hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */ @@ -2613,6 +2898,10 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) smu7_hwmgr_backend_fini(hwmgr); } + result = smu7_update_edc_leakage_table(hwmgr); + if (result) + return result; + return 0; } @@ -2890,7 +3179,7 @@ static int smu7_vblank_too_short(struct pp_hwmgr *hwmgr, case CHIP_POLARIS10: case CHIP_POLARIS11: case CHIP_POLARIS12: - if (hwmgr->is_kicker) + if (hwmgr->is_kicker || (hwmgr->chip_id == CHIP_POLARIS12)) switch_limit_us = data->is_memory_gddr5 ? 450 : 150; else switch_limit_us = data->is_memory_gddr5 ? 200 : 150; @@ -2921,6 +3210,7 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, struct PP_Clocks minimum_clocks = {0}; bool disable_mclk_switching; bool disable_mclk_switching_for_frame_lock; + bool disable_mclk_switching_for_display; const struct phm_clock_and_voltage_limits *max_limits; uint32_t i; struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); @@ -2928,9 +3218,12 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, (struct phm_ppt_v1_information *)(hwmgr->pptable); int32_t count; int32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0; + uint32_t latency; + bool latency_allowed = false; data->battery_state = (PP_StateUILabel_Battery == request_ps->classification.ui_label); + data->mclk_ignore_signal = false; PP_ASSERT_WITH_CODE(smu7_ps->performance_level_count == 2, "VI should always have 2 performance levels", @@ -2981,19 +3274,26 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMclkSwitchingForFrameLock); + disable_mclk_switching_for_display = ((1 < hwmgr->display_config->num_display) && + !hwmgr->display_config->multi_monitor_in_sync) || + smu7_vblank_too_short(hwmgr, hwmgr->display_config->min_vblank_time); - if (hwmgr->display_config->num_display == 0) - disable_mclk_switching = false; - else - disable_mclk_switching = ((1 < hwmgr->display_config->num_display) && - !hwmgr->display_config->multi_monitor_in_sync) || - disable_mclk_switching_for_frame_lock || - smu7_vblank_too_short(hwmgr, hwmgr->display_config->min_vblank_time); + disable_mclk_switching = disable_mclk_switching_for_frame_lock || + disable_mclk_switching_for_display; + + if (hwmgr->display_config->num_display == 0) { + if (hwmgr->chip_id >= CHIP_POLARIS10 && hwmgr->chip_id <= CHIP_VEGAM) + data->mclk_ignore_signal = true; + else + disable_mclk_switching = false; + } sclk = smu7_ps->performance_levels[0].engine_clock; mclk = smu7_ps->performance_levels[0].memory_clock; - if (disable_mclk_switching) + if (disable_mclk_switching && + (!(hwmgr->chip_id >= CHIP_POLARIS10 && + hwmgr->chip_id <= CHIP_VEGAM))) mclk = smu7_ps->performance_levels [smu7_ps->performance_level_count - 1].memory_clock; @@ -3018,8 +3318,41 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, if (mclk < smu7_ps->performance_levels[1].memory_clock) mclk = smu7_ps->performance_levels[1].memory_clock; + if (hwmgr->chip_id >= CHIP_POLARIS10 && hwmgr->chip_id <= CHIP_VEGAM) { + if (disable_mclk_switching_for_display) { + /* Find the lowest MCLK frequency that is within + * the tolerable latency defined in DAL + */ + latency = hwmgr->display_config->dce_tolerable_mclk_in_active_latency; + for (i = 0; i < data->mclk_latency_table.count; i++) { + if (data->mclk_latency_table.entries[i].latency <= latency) { + latency_allowed = true; + + if ((data->mclk_latency_table.entries[i].frequency >= + smu7_ps->performance_levels[0].memory_clock) && + (data->mclk_latency_table.entries[i].frequency <= + smu7_ps->performance_levels[1].memory_clock)) { + mclk = data->mclk_latency_table.entries[i].frequency; + break; + } + } + } + if ((i >= data->mclk_latency_table.count - 1) && !latency_allowed) { + data->mclk_ignore_signal = true; + } else { + data->mclk_ignore_signal = false; + } + } + + if (disable_mclk_switching_for_frame_lock) + mclk = smu7_ps->performance_levels[1].memory_clock; + } + smu7_ps->performance_levels[0].memory_clock = mclk; - smu7_ps->performance_levels[1].memory_clock = mclk; + + if (!(hwmgr->chip_id >= CHIP_POLARIS10 && + hwmgr->chip_id <= CHIP_VEGAM)) + smu7_ps->performance_levels[1].memory_clock = mclk; } else { if (smu7_ps->performance_levels[1].memory_clock < smu7_ps->performance_levels[0].memory_clock) @@ -3765,6 +4098,7 @@ static int smu7_freeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) } if ((0 == data->mclk_dpm_key_disabled) && + !data->mclk_ignore_signal && (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) { PP_ASSERT_WITH_CODE(true == smum_is_dpm_running(hwmgr), @@ -3921,6 +4255,7 @@ static int smu7_unfreeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) } if ((0 == data->mclk_dpm_key_disabled) && + !data->mclk_ignore_signal && (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) { PP_ASSERT_WITH_CODE(true == smum_is_dpm_running(hwmgr), @@ -3974,7 +4309,12 @@ static int smu7_notify_link_speed_change_after_state_change( return 0; } -static int smu7_notify_smc_display(struct pp_hwmgr *hwmgr) +static int smu7_notify_no_display(struct pp_hwmgr *hwmgr) +{ + return (smum_send_msg_to_smc(hwmgr, (PPSMC_Msg)PPSMC_NoDisplay, NULL) == 0) ? 0 : -EINVAL; +} + +static int smu7_notify_has_display(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); @@ -3987,10 +4327,25 @@ static int smu7_notify_smc_display(struct pp_hwmgr *hwmgr) smum_send_msg_to_smc_with_parameter(hwmgr, (PPSMC_Msg)PPSMC_MSG_SetVBITimeout, data->frame_time_x2, NULL); + data->last_sent_vbi_timeout = data->frame_time_x2; } + return (smum_send_msg_to_smc(hwmgr, (PPSMC_Msg)PPSMC_HasDisplay, NULL) == 0) ? 0 : -EINVAL; } +static int smu7_notify_smc_display(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + int result = 0; + + if (data->mclk_ignore_signal) + result = smu7_notify_no_display(hwmgr); + else + result = smu7_notify_has_display(hwmgr); + + return result; +} + static int smu7_set_power_state_tasks(struct pp_hwmgr *hwmgr, const void *input) { int tmp_result, result = 0; @@ -4041,11 +4396,6 @@ static int smu7_set_power_state_tasks(struct pp_hwmgr *hwmgr, const void *input) "Failed to update SCLK threshold!", result = tmp_result); - tmp_result = smu7_notify_smc_display(hwmgr); - PP_ASSERT_WITH_CODE((0 == tmp_result), - "Failed to notify smc display settings!", - result = tmp_result); - tmp_result = smu7_unfreeze_sclk_mclk_dpm(hwmgr); PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to unfreeze SCLK MCLK DPM!", @@ -4056,6 +4406,11 @@ static int smu7_set_power_state_tasks(struct pp_hwmgr *hwmgr, const void *input) "Failed to upload DPM level enabled mask!", result = tmp_result); + tmp_result = smu7_notify_smc_display(hwmgr); + PP_ASSERT_WITH_CODE((0 == tmp_result), + "Failed to notify smc display settings!", + result = tmp_result); + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest)) { tmp_result = @@ -4079,29 +4434,17 @@ static int smu7_set_max_fan_pwm_output(struct pp_hwmgr *hwmgr, uint16_t us_max_f } static int -smu7_notify_smc_display_change(struct pp_hwmgr *hwmgr, bool has_display) -{ - PPSMC_Msg msg = has_display ? (PPSMC_Msg)PPSMC_HasDisplay : (PPSMC_Msg)PPSMC_NoDisplay; - - return (smum_send_msg_to_smc(hwmgr, msg, NULL) == 0) ? 0 : -1; -} - -static int smu7_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr) { - if (hwmgr->display_config->num_display > 1 && - !hwmgr->display_config->multi_monitor_in_sync) - smu7_notify_smc_display_change(hwmgr, false); - return 0; } /** -* Programs the display gap -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always OK -*/ + * smu7_program_display_gap - Programs the display gap + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always OK + */ static int smu7_program_display_gap(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); @@ -4155,12 +4498,12 @@ static int smu7_display_configuration_changed_task(struct pp_hwmgr *hwmgr) } /** -* Set maximum target operating fan output RPM -* -* @param hwmgr: the address of the powerplay hardware manager. -* @param usMaxFanRpm: max operating fan RPM value. -* @return The response that came from the SMC. -*/ + * smu7_set_max_fan_rpm_output - Set maximum target operating fan output RPM + * + * @hwmgr: the address of the powerplay hardware manager. + * @usMaxFanRpm: max operating fan RPM value. + * Return: The response that came from the SMC. + */ static int smu7_set_max_fan_rpm_output(struct pp_hwmgr *hwmgr, uint16_t us_max_fan_rpm) { hwmgr->thermal_controller. @@ -4215,6 +4558,11 @@ smu7_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr) if (data->display_timing.vrefresh != hwmgr->display_config->vrefresh) is_update_required = true; + if (hwmgr->chip_id >= CHIP_POLARIS10 && + hwmgr->chip_id <= CHIP_VEGAM && + data->last_sent_vbi_timeout != data->frame_time_x2) + is_update_required = true; + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) { if (data->display_timing.min_clock_in_sr != hwmgr->display_config->min_core_set_clock_in_sr && (data->display_timing.min_clock_in_sr >= SMU7_MINIMUM_ENGINE_CLOCK || @@ -4350,10 +4698,10 @@ static int smu7_read_clock_registers(struct pp_hwmgr *hwmgr) } /** - * Find out if memory is GDDR5. + * smu7_get_memory_type - Find out if memory is GDDR5. * - * @param hwmgr the address of the powerplay hardware manager. - * @return always 0 + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 */ static int smu7_get_memory_type(struct pp_hwmgr *hwmgr) { @@ -4366,10 +4714,10 @@ static int smu7_get_memory_type(struct pp_hwmgr *hwmgr) } /** - * Enables Dynamic Power Management by SMC + * smu7_enable_acpi_power_management - Enables Dynamic Power Management by SMC * - * @param hwmgr the address of the powerplay hardware manager. - * @return always 0 + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 */ static int smu7_enable_acpi_power_management(struct pp_hwmgr *hwmgr) { @@ -4380,10 +4728,10 @@ static int smu7_enable_acpi_power_management(struct pp_hwmgr *hwmgr) } /** - * Initialize PowerGating States for different engines + * smu7_init_power_gate_state - Initialize PowerGating States for different engines * - * @param hwmgr the address of the powerplay hardware manager. - * @return always 0 + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 */ static int smu7_init_power_gate_state(struct pp_hwmgr *hwmgr) { @@ -4771,6 +5119,125 @@ static int smu7_get_clock_by_type(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type return 0; } +static int smu7_get_sclks_with_latency(struct pp_hwmgr *hwmgr, + struct pp_clock_levels_with_latency *clocks) +{ + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)hwmgr->pptable; + struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table = + table_info->vdd_dep_on_sclk; + int i; + + clocks->num_levels = 0; + for (i = 0; i < dep_sclk_table->count; i++) { + if (dep_sclk_table->entries[i].clk) { + clocks->data[clocks->num_levels].clocks_in_khz = + dep_sclk_table->entries[i].clk * 10; + clocks->num_levels++; + } + } + + return 0; +} + +static int smu7_get_mclks_with_latency(struct pp_hwmgr *hwmgr, + struct pp_clock_levels_with_latency *clocks) +{ + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)hwmgr->pptable; + struct phm_ppt_v1_clock_voltage_dependency_table *dep_mclk_table = + table_info->vdd_dep_on_mclk; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + int i; + + clocks->num_levels = 0; + data->mclk_latency_table.count = 0; + for (i = 0; i < dep_mclk_table->count; i++) { + if (dep_mclk_table->entries[i].clk) { + clocks->data[clocks->num_levels].clocks_in_khz = + dep_mclk_table->entries[i].clk * 10; + data->mclk_latency_table.entries[data->mclk_latency_table.count].frequency = + dep_mclk_table->entries[i].clk; + clocks->data[clocks->num_levels].latency_in_us = + data->mclk_latency_table.entries[data->mclk_latency_table.count].latency = + smu7_get_mem_latency(hwmgr, dep_mclk_table->entries[i].clk); + clocks->num_levels++; + data->mclk_latency_table.count++; + } + } + + return 0; +} + +static int smu7_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr, + enum amd_pp_clock_type type, + struct pp_clock_levels_with_latency *clocks) +{ + if (!(hwmgr->chip_id >= CHIP_POLARIS10 && + hwmgr->chip_id <= CHIP_VEGAM)) + return -EINVAL; + + switch (type) { + case amd_pp_sys_clock: + smu7_get_sclks_with_latency(hwmgr, clocks); + break; + case amd_pp_mem_clock: + smu7_get_mclks_with_latency(hwmgr, clocks); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int smu7_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, + void *clock_range) +{ + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)hwmgr->pptable; + struct phm_ppt_v1_clock_voltage_dependency_table *dep_mclk_table = + table_info->vdd_dep_on_mclk; + struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table = + table_info->vdd_dep_on_sclk; + struct polaris10_smumgr *smu_data = + (struct polaris10_smumgr *)(hwmgr->smu_backend); + SMU74_Discrete_DpmTable *table = &(smu_data->smc_state_table); + struct dm_pp_wm_sets_with_clock_ranges *watermarks = + (struct dm_pp_wm_sets_with_clock_ranges *)clock_range; + uint32_t i, j, k; + bool valid_entry; + + if (!(hwmgr->chip_id >= CHIP_POLARIS10 && + hwmgr->chip_id <= CHIP_VEGAM)) + return -EINVAL; + + for (i = 0; i < dep_mclk_table->count; i++) { + for (j = 0; j < dep_sclk_table->count; j++) { + valid_entry = false; + for (k = 0; k < watermarks->num_wm_sets; k++) { + if (dep_sclk_table->entries[i].clk / 10 >= watermarks->wm_clk_ranges[k].wm_min_eng_clk_in_khz && + dep_sclk_table->entries[i].clk / 10 < watermarks->wm_clk_ranges[k].wm_max_eng_clk_in_khz && + dep_mclk_table->entries[i].clk / 10 >= watermarks->wm_clk_ranges[k].wm_min_mem_clk_in_khz && + dep_mclk_table->entries[i].clk / 10 < watermarks->wm_clk_ranges[k].wm_max_mem_clk_in_khz) { + valid_entry = true; + table->DisplayWatermark[i][j] = watermarks->wm_clk_ranges[k].wm_set_id; + break; + } + } + PP_ASSERT_WITH_CODE(valid_entry, + "Clock is not in range of specified clock range for watermark from DAL! Using highest water mark set.", + table->DisplayWatermark[i][j] = watermarks->wm_clk_ranges[k - 1].wm_set_id); + } + } + + return smu7_copy_bytes_to_smc(hwmgr, + smu_data->smu7_data.dpm_table_start + offsetof(SMU74_Discrete_DpmTable, DisplayWatermark), + (uint8_t *)table->DisplayWatermark, + sizeof(uint8_t) * SMU74_MAX_LEVELS_MEMORY * SMU74_MAX_LEVELS_GRAPHICS, + SMC_RAM_END); +} + static int smu7_notify_cac_buffer_info(struct pp_hwmgr *hwmgr, uint32_t virtual_addr_low, uint32_t virtual_addr_hi, @@ -5188,6 +5655,8 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = { .get_mclk_od = smu7_get_mclk_od, .set_mclk_od = smu7_set_mclk_od, .get_clock_by_type = smu7_get_clock_by_type, + .get_clock_by_type_with_latency = smu7_get_clock_by_type_with_latency, + .set_watermarks_for_clocks_ranges = smu7_set_watermarks_for_clocks_ranges, .read_sensor = smu7_read_sensor, .dynamic_state_management_disable = smu7_disable_dpm_tasks, .avfs_control = smu7_avfs_control, |