/* * Copyright 2018 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. *
*/
if (data->registry_data.od_state_in_dc_support) { if (data->registry_data.od8_feature_enable)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_OD8inDCSupport);
}
if (data->registry_data.thermal_support &&
data->registry_data.fuzzy_fan_control_support &&
hwmgr->thermal_controller.advanceFanControlParameters.usTMax)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_ODFuzzyFanControlSupport);
if (data->registry_data.sclk_throttle_low_notification)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_SclkThrottleLowNotification);
if (data->registry_data.didt_support) {
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_DiDtSupport); if (data->registry_data.sq_ramping_support)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_SQRamping); if (data->registry_data.db_ramping_support)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_DBRamping); if (data->registry_data.td_ramping_support)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_TDRamping); if (data->registry_data.tcp_ramping_support)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_TCPRamping); if (data->registry_data.dbr_ramping_support)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_DBRRamping); if (data->registry_data.edc_didt_support)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_DiDtEDCEnable); if (data->registry_data.gc_didt_support)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_GCEDC); if (data->registry_data.psm_didt_support)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_PSM);
}
/* need to set voltage control types before EVV patching */
data->vddc_control = VEGA20_VOLTAGE_CONTROL_NONE;
data->mvdd_control = VEGA20_VOLTAGE_CONTROL_NONE;
data->vddci_control = VEGA20_VOLTAGE_CONTROL_NONE;
hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */ /* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */
hwmgr->platform_descriptor.clockStep.engineClock = 500;
hwmgr->platform_descriptor.clockStep.memoryClock = 500;
ret = vega20_init_sclk_threshold(hwmgr);
PP_ASSERT_WITH_CODE(!ret, "Failed to init sclk threshold!", return ret);
if (use_baco) {
ret = vega20_baco_apply_vdci_flush_workaround(hwmgr); if (ret)
pr_err("Failed to apply vega20 baco workaround!\n");
}
return ret;
}
/* * @fn vega20_init_dpm_state * @brief Function to initialize all Soft Min/Max and Hard Min/Max to 0xff. * * @param dpm_state - the address of the DPM Table to initiailize. * @return None.
*/ staticvoid vega20_init_dpm_state(struct vega20_dpm_state *dpm_state)
{
dpm_state->soft_min_level = 0x0;
dpm_state->soft_max_level = VG20_CLOCK_MAX_DEFAULT;
dpm_state->hard_min_level = 0x0;
dpm_state->hard_max_level = VG20_CLOCK_MAX_DEFAULT;
}
staticint vega20_get_number_of_dpm_level(struct pp_hwmgr *hwmgr,
PPCLK_e clk_id, uint32_t *num_of_levels)
{ int ret = 0;
ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_GetDpmFreqByIndex,
(clk_id << 16 | 0xFF),
num_of_levels);
PP_ASSERT_WITH_CODE(!ret, "[GetNumOfDpmLevel] failed to get dpm levels!", return ret);
return ret;
}
staticint vega20_get_dpm_frequency_by_index(struct pp_hwmgr *hwmgr,
PPCLK_e clk_id, uint32_t index, uint32_t *clk)
{ int ret = 0;
ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_GetDpmFreqByIndex,
(clk_id << 16 | index),
clk);
PP_ASSERT_WITH_CODE(!ret, "[GetDpmFreqByIndex] failed to get dpm freq by index!", return ret);
return ret;
}
staticint vega20_setup_single_dpm_table(struct pp_hwmgr *hwmgr, struct vega20_single_dpm_table *dpm_table, PPCLK_e clk_id)
{ int ret = 0;
uint32_t i, num_of_levels, clk;
ret = vega20_get_number_of_dpm_level(hwmgr, clk_id, &num_of_levels);
PP_ASSERT_WITH_CODE(!ret, "[SetupSingleDpmTable] failed to get clk levels!", return ret);
dpm_table->count = num_of_levels;
for (i = 0; i < num_of_levels; i++) {
ret = vega20_get_dpm_frequency_by_index(hwmgr, clk_id, i, &clk);
PP_ASSERT_WITH_CODE(!ret, "[SetupSingleDpmTable] failed to get clk of specific level!", return ret);
dpm_table->dpm_levels[i].value = clk;
dpm_table->dpm_levels[i].enabled = true;
}
return ret;
}
staticint vega20_setup_gfxclk_dpm_table(struct pp_hwmgr *hwmgr)
{ struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend); struct vega20_single_dpm_table *dpm_table; int ret = 0;
dpm_table = &(data->dpm_table.gfx_table); if (data->smu_features[GNLD_DPM_GFXCLK].enabled) {
ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_GFXCLK);
PP_ASSERT_WITH_CODE(!ret, "[SetupDefaultDpmTable] failed to get gfxclk dpm levels!", return ret);
} else {
dpm_table->count = 1;
dpm_table->dpm_levels[0].value = data->vbios_boot_state.gfx_clock / 100;
}
return ret;
}
staticint vega20_setup_memclk_dpm_table(struct pp_hwmgr *hwmgr)
{ struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend); struct vega20_single_dpm_table *dpm_table; int ret = 0;
dpm_table = &(data->dpm_table.mem_table); if (data->smu_features[GNLD_DPM_UCLK].enabled) {
ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_UCLK);
PP_ASSERT_WITH_CODE(!ret, "[SetupDefaultDpmTable] failed to get memclk dpm levels!", return ret);
} else {
dpm_table->count = 1;
dpm_table->dpm_levels[0].value = data->vbios_boot_state.mem_clock / 100;
}
return ret;
}
/* * This function is to initialize all DPM state tables * for SMU based on the dependency table. * Dynamic state patching function will then trim these * state tables to the allowed range based * on the power policy or external client requests, * such as UVD request, etc.
*/ staticint vega20_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
{ struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend); struct vega20_single_dpm_table *dpm_table; int ret = 0;
/* socclk */
dpm_table = &(data->dpm_table.soc_table); if (data->smu_features[GNLD_DPM_SOCCLK].enabled) {
ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_SOCCLK);
PP_ASSERT_WITH_CODE(!ret, "[SetupDefaultDpmTable] failed to get socclk dpm levels!", return ret);
} else {
dpm_table->count = 1;
dpm_table->dpm_levels[0].value = data->vbios_boot_state.soc_clock / 100;
}
vega20_init_dpm_state(&(dpm_table->dpm_state));
/* gfxclk */
dpm_table = &(data->dpm_table.gfx_table);
ret = vega20_setup_gfxclk_dpm_table(hwmgr); if (ret) return ret;
vega20_init_dpm_state(&(dpm_table->dpm_state));
/* memclk */
dpm_table = &(data->dpm_table.mem_table);
ret = vega20_setup_memclk_dpm_table(hwmgr); if (ret) return ret;
vega20_init_dpm_state(&(dpm_table->dpm_state));
/* eclk */
dpm_table = &(data->dpm_table.eclk_table); if (data->smu_features[GNLD_DPM_VCE].enabled) {
ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_ECLK);
PP_ASSERT_WITH_CODE(!ret, "[SetupDefaultDpmTable] failed to get eclk dpm levels!", return ret);
} else {
dpm_table->count = 1;
dpm_table->dpm_levels[0].value = data->vbios_boot_state.eclock / 100;
}
vega20_init_dpm_state(&(dpm_table->dpm_state));
/* vclk */
dpm_table = &(data->dpm_table.vclk_table); if (data->smu_features[GNLD_DPM_UVD].enabled) {
ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_VCLK);
PP_ASSERT_WITH_CODE(!ret, "[SetupDefaultDpmTable] failed to get vclk dpm levels!", return ret);
} else {
dpm_table->count = 1;
dpm_table->dpm_levels[0].value = data->vbios_boot_state.vclock / 100;
}
vega20_init_dpm_state(&(dpm_table->dpm_state));
/* dclk */
dpm_table = &(data->dpm_table.dclk_table); if (data->smu_features[GNLD_DPM_UVD].enabled) {
ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_DCLK);
PP_ASSERT_WITH_CODE(!ret, "[SetupDefaultDpmTable] failed to get dclk dpm levels!", return ret);
} else {
dpm_table->count = 1;
dpm_table->dpm_levels[0].value = data->vbios_boot_state.dclock / 100;
}
vega20_init_dpm_state(&(dpm_table->dpm_state));
/* dcefclk */
dpm_table = &(data->dpm_table.dcef_table); if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) {
ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_DCEFCLK);
PP_ASSERT_WITH_CODE(!ret, "[SetupDefaultDpmTable] failed to get dcefclk dpm levels!", return ret);
} else {
dpm_table->count = 1;
dpm_table->dpm_levels[0].value = data->vbios_boot_state.dcef_clock / 100;
}
vega20_init_dpm_state(&(dpm_table->dpm_state));
/* pixclk */
dpm_table = &(data->dpm_table.pixel_table); if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) {
ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_PIXCLK);
PP_ASSERT_WITH_CODE(!ret, "[SetupDefaultDpmTable] failed to get pixclk dpm levels!", return ret);
} else
dpm_table->count = 0;
vega20_init_dpm_state(&(dpm_table->dpm_state));
/* dispclk */
dpm_table = &(data->dpm_table.display_table); if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) {
ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_DISPCLK);
PP_ASSERT_WITH_CODE(!ret, "[SetupDefaultDpmTable] failed to get dispclk dpm levels!", return ret);
} else
dpm_table->count = 0;
vega20_init_dpm_state(&(dpm_table->dpm_state));
/* phyclk */
dpm_table = &(data->dpm_table.phy_table); if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) {
ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_PHYCLK);
PP_ASSERT_WITH_CODE(!ret, "[SetupDefaultDpmTable] failed to get phyclk dpm levels!", return ret);
} else
dpm_table->count = 0;
vega20_init_dpm_state(&(dpm_table->dpm_state));
/* fclk */
dpm_table = &(data->dpm_table.fclk_table); if (data->smu_features[GNLD_DPM_FCLK].enabled) {
ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_FCLK);
PP_ASSERT_WITH_CODE(!ret, "[SetupDefaultDpmTable] failed to get fclk dpm levels!", return ret);
} else {
dpm_table->count = 1;
dpm_table->dpm_levels[0].value = data->vbios_boot_state.fclock / 100;
}
vega20_init_dpm_state(&(dpm_table->dpm_state));
/* save a copy of the default DPM table */
memcpy(&(data->golden_dpm_table), &(data->dpm_table), sizeof(struct vega20_dpm_table));
return 0;
}
/** * vega20_init_smc_table - Initializes the SMC table and uploads it * * @hwmgr: the address of the powerplay hardware manager. * return: always 0
*/ staticint vega20_init_smc_table(struct pp_hwmgr *hwmgr)
{ int result; struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend);
PPTable_t *pp_table = &(data->smc_state_table.pp_table); struct pp_atomfwctrl_bios_boot_up_values boot_up_values; struct phm_ppt_v3_information *pptable_information =
(struct phm_ppt_v3_information *)hwmgr->pptable;
result = pp_atomfwctrl_get_vbios_bootup_values(hwmgr, &boot_up_values);
PP_ASSERT_WITH_CODE(!result, "[InitSMCTable] Failed to get vbios bootup values!", return result);
result = smum_smc_table_manager(hwmgr,
(uint8_t *)pp_table, TABLE_PPTABLE, false);
PP_ASSERT_WITH_CODE(!result, "[InitSMCTable] Failed to upload PPtable!", return result);
return 0;
}
/* * Override PCIe link speed and link width for DPM Level 1. PPTable entries * reflect the ASIC capabilities and not the system capabilities. For e.g. * Vega20 board in a PCI Gen3 system. In this case, when SMU's tries to switch * to DPM1, it fails as system doesn't support Gen4.
*/ staticint vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr)
{ struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend);
uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg;
PPTable_t *pp_table = &(data->smc_state_table.pp_table); int i; int ret;
/* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1 * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32
*/ for (i = 0; i < NUM_LINK_LEVELS; i++) {
pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen :
pp_table->PcieGenSpeed[i];
pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width :
pp_table->PcieLaneCount[i];
if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg !=
pp_table->PcieLaneCount[i]) {
smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg;
ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_OverridePcieParameters, smu_pcie_arg,
NULL);
PP_ASSERT_WITH_CODE(!ret, "[OverridePcieParameters] Attempt to override pcie params failed!", return ret);
}
/* override to the highest if it's disabled from ppfeaturmask */ if (data->registry_data.pcie_dpm_key_disabled) { for (i = 0; i < NUM_LINK_LEVELS; i++) {
smu_pcie_arg = (i << 16) | (pcie_gen << 8) | pcie_width;
ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_OverridePcieParameters, smu_pcie_arg,
NULL);
PP_ASSERT_WITH_CODE(!ret, "[OverridePcieParameters] Attempt to override pcie params failed!", return ret);
pp_table->PcieGenSpeed[i] = pcie_gen;
pp_table->PcieLaneCount[i] = pcie_width;
}
ret = vega20_enable_smc_features(hwmgr, false,
data->smu_features[GNLD_DPM_LINK].smu_feature_bitmap);
PP_ASSERT_WITH_CODE(!ret, "Attempt to Disable DPM LINK Failed!", return ret);
data->smu_features[GNLD_DPM_LINK].enabled = false;
data->smu_features[GNLD_DPM_LINK].supported = false;
}
return 0;
}
staticint vega20_set_allowed_featuresmask(struct pp_hwmgr *hwmgr)
{ struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend);
uint32_t allowed_features_low = 0, allowed_features_high = 0; int i; int ret = 0;
for (i = 0; i < GNLD_FEATURES_MAX; i++) if (data->smu_features[i].allowed)
data->smu_features[i].smu_feature_id > 31 ?
(allowed_features_high |=
((data->smu_features[i].smu_feature_bitmap >> SMU_FEATURES_HIGH_SHIFT)
& 0xFFFFFFFF)) :
(allowed_features_low |=
((data->smu_features[i].smu_feature_bitmap >> SMU_FEATURES_LOW_SHIFT)
& 0xFFFFFFFF));
ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetAllowedFeaturesMaskHigh, allowed_features_high, NULL);
PP_ASSERT_WITH_CODE(!ret, "[SetAllowedFeaturesMask] Attempt to set allowed features mask(high) failed!", return ret);
ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetAllowedFeaturesMaskLow, allowed_features_low, NULL);
PP_ASSERT_WITH_CODE(!ret, "[SetAllowedFeaturesMask] Attempt to set allowed features mask (low) failed!", return ret);
staticint vega20_enable_all_smu_features(struct pp_hwmgr *hwmgr)
{ struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend);
uint64_t features_enabled; int i; bool enabled; int ret = 0;
PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr,
PPSMC_MSG_EnableAllSmuFeatures,
NULL)) == 0, "[EnableAllSMUFeatures] Failed to enable all smu features!", return ret);
ret = vega20_get_enabled_smc_features(hwmgr, &features_enabled);
PP_ASSERT_WITH_CODE(!ret, "[EnableAllSmuFeatures] Failed to get enabled smc features!", return ret);
for (i = 0; i < GNLD_FEATURES_MAX; i++) {
enabled = (features_enabled & data->smu_features[i].smu_feature_bitmap) ? true : false;
data->smu_features[i].enabled = enabled;
data->smu_features[i].supported = enabled;
#if 0 if (data->smu_features[i].allowed && !enabled)
pr_info("[EnableAllSMUFeatures] feature %d is expected enabled!", i); elseif (!data->smu_features[i].allowed && enabled)
pr_info("[EnableAllSMUFeatures] feature %d is expected disabled!", i); #endif
}
if (pptable_information->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_MEMORY_TIMING_TUNE])
od_settings->overdrive8_capabilities |= OD8_MEMORY_TIMING_TUNE;
if (pptable_information->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_FAN_ZERO_RPM_CONTROL] &&
pp_table->FanZeroRpmEnable)
od_settings->overdrive8_capabilities |= OD8_FAN_ZERO_RPM_CONTROL;
if (!od_settings->overdrive8_capabilities)
hwmgr->od_enabled = false;
PP_ASSERT_WITH_CODE(!vega20_od8_get_gfx_clock_base_voltage(hwmgr,
&(od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].default_value),
od_table->GfxclkFreq1), "[PhwVega20_OD8_InitializeDefaultSettings] Failed to get Base clock voltage from SMU!",
od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].default_value = 0);
od_table->GfxclkVolt1 = od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].default_value
* VOLTAGE_SCALE;
PP_ASSERT_WITH_CODE(!vega20_od8_get_gfx_clock_base_voltage(hwmgr,
&(od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].default_value),
od_table->GfxclkFreq2), "[PhwVega20_OD8_InitializeDefaultSettings] Failed to get Base clock voltage from SMU!",
od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].default_value = 0);
od_table->GfxclkVolt2 = od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].default_value
* VOLTAGE_SCALE;
PP_ASSERT_WITH_CODE(!vega20_od8_get_gfx_clock_base_voltage(hwmgr,
&(od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].default_value),
od_table->GfxclkFreq3), "[PhwVega20_OD8_InitializeDefaultSettings] Failed to get Base clock voltage from SMU!",
od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].default_value = 0);
od_table->GfxclkVolt3 = od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].default_value
* VOLTAGE_SCALE;
} 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;
}
staticint vega20_get_max_sustainable_clock(struct pp_hwmgr *hwmgr,
PP_Clock *clock, PPCLK_e clock_select)
{ int ret = 0;
PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_GetDcModeMaxDpmFreq,
(clock_select << 16),
clock)) == 0, "[GetMaxSustainableClock] Failed to get max DC clock from SMC!", return ret);
/* if DC limit is zero, return AC limit */ if (*clock == 0) {
PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_GetMaxDpmFreq,
(clock_select << 16),
clock)) == 0, "[GetMaxSustainableClock] failed to get max AC clock from SMC!", return ret);
}
if (data->smu_features[GNLD_DPM_UCLK].enabled)
PP_ASSERT_WITH_CODE((ret = vega20_get_max_sustainable_clock(hwmgr,
&(max_sustainable_clocks->uclock),
PPCLK_UCLK)) == 0, "[InitMaxSustainableClocks] failed to get max UCLK from SMC!", return ret);
if (data->smu_features[GNLD_DPM_SOCCLK].enabled)
PP_ASSERT_WITH_CODE((ret = vega20_get_max_sustainable_clock(hwmgr,
&(max_sustainable_clocks->soc_clock),
PPCLK_SOCCLK)) == 0, "[InitMaxSustainableClocks] failed to get max SOCCLK from SMC!", return ret);
if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) {
PP_ASSERT_WITH_CODE((ret = vega20_get_max_sustainable_clock(hwmgr,
&(max_sustainable_clocks->dcef_clock),
PPCLK_DCEFCLK)) == 0, "[InitMaxSustainableClocks] failed to get max DCEFCLK from SMC!", return ret);
PP_ASSERT_WITH_CODE((ret = vega20_get_max_sustainable_clock(hwmgr,
&(max_sustainable_clocks->display_clock),
PPCLK_DISPCLK)) == 0, "[InitMaxSustainableClocks] failed to get max DISPCLK from SMC!", return ret);
PP_ASSERT_WITH_CODE((ret = vega20_get_max_sustainable_clock(hwmgr,
&(max_sustainable_clocks->phy_clock),
PPCLK_PHYCLK)) == 0, "[InitMaxSustainableClocks] failed to get max PHYCLK from SMC!", return ret);
PP_ASSERT_WITH_CODE((ret = vega20_get_max_sustainable_clock(hwmgr,
&(max_sustainable_clocks->pixel_clock),
PPCLK_PIXCLK)) == 0, "[InitMaxSustainableClocks] failed to get max PIXCLK from SMC!", return ret);
}
if (max_sustainable_clocks->soc_clock < max_sustainable_clocks->uclock)
max_sustainable_clocks->uclock = max_sustainable_clocks->soc_clock;
return 0;
}
staticint vega20_enable_mgpu_fan_boost(struct pp_hwmgr *hwmgr)
{ int result;
result = smum_send_msg_to_smc(hwmgr,
PPSMC_MSG_SetMGpuFanBoostLimitRpm,
NULL);
PP_ASSERT_WITH_CODE(!result, "[EnableMgpuFan] Failed to enable mgpu fan boost!", return result);
result = vega20_set_allowed_featuresmask(hwmgr);
PP_ASSERT_WITH_CODE(!result, "[EnableDPMTasks] Failed to set allowed featuresmask!\n", return result);
result = vega20_init_smc_table(hwmgr);
PP_ASSERT_WITH_CODE(!result, "[EnableDPMTasks] Failed to initialize SMC table!", return result);
result = vega20_run_btc(hwmgr);
PP_ASSERT_WITH_CODE(!result, "[EnableDPMTasks] Failed to run btc!", return result);
result = vega20_run_btc_afll(hwmgr);
PP_ASSERT_WITH_CODE(!result, "[EnableDPMTasks] Failed to run btc afll!", return result);
result = vega20_enable_all_smu_features(hwmgr);
PP_ASSERT_WITH_CODE(!result, "[EnableDPMTasks] Failed to enable all smu features!", return result);
result = vega20_override_pcie_parameters(hwmgr);
PP_ASSERT_WITH_CODE(!result, "[EnableDPMTasks] Failed to override pcie parameters!", return result);
result = vega20_notify_smc_display_change(hwmgr);
PP_ASSERT_WITH_CODE(!result, "[EnableDPMTasks] Failed to notify smc display change!", return result);
result = vega20_send_clock_ratio(hwmgr);
PP_ASSERT_WITH_CODE(!result, "[EnableDPMTasks] Failed to send clock ratio!", return result);
/* Initialize UVD/VCE powergating state */
vega20_init_powergate_state(hwmgr);
result = vega20_setup_default_dpm_tables(hwmgr);
PP_ASSERT_WITH_CODE(!result, "[EnableDPMTasks] Failed to setup default DPM tables!", return result);
result = vega20_init_max_sustainable_clocks(hwmgr);
PP_ASSERT_WITH_CODE(!result, "[EnableDPMTasks] Failed to get maximum sustainable clocks!", return result);
result = vega20_power_control_set_level(hwmgr);
PP_ASSERT_WITH_CODE(!result, "[EnableDPMTasks] Failed to power control set level!", return result);
result = vega20_od8_initialize_default_settings(hwmgr);
PP_ASSERT_WITH_CODE(!result, "[EnableDPMTasks] Failed to initialize odn settings!", return result);
vega20_populate_umdpstate_clocks(hwmgr);
result = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetPptLimit,
POWER_SOURCE_AC << 16, &hwmgr->default_power_limit);
PP_ASSERT_WITH_CODE(!result, "[GetPptLimit] get default PPT limit failed!", return result);
hwmgr->power_limit =
hwmgr->default_power_limit;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.