aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/powerplay/hwmgr
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay/hwmgr')
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c10
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c49
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h39
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c64
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c9
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c408
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h3
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c27
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h1
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c4
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c80
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h2
13 files changed, 433 insertions, 265 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
index 23bba2c8b18e..fcc722ea7649 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
@@ -501,3 +501,13 @@ int phm_get_max_high_clocks(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_i
return hwmgr->hwmgr_func->get_max_high_clocks(hwmgr, clocks);
}
+
+int phm_disable_smc_firmware_ctf(struct pp_hwmgr *hwmgr)
+{
+ PHM_FUNC_CHECK(hwmgr);
+
+ if (hwmgr->hwmgr_func->disable_smc_firmware_ctf == NULL)
+ return -EINVAL;
+
+ return hwmgr->hwmgr_func->disable_smc_firmware_ctf(hwmgr);
+}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c
index b71525f838e6..56023114ad6f 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c
@@ -314,52 +314,45 @@ int pp_atomfwctrl_get_avfs_information(struct pp_hwmgr *hwmgr,
le32_to_cpu(profile->gb_vdroop_table_ckson_a2);
param->ulGbFuseTableCksoffM1 =
le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m1);
- param->usGbFuseTableCksoffM2 =
+ param->ulGbFuseTableCksoffM2 =
le16_to_cpu(profile->avfsgb_fuse_table_cksoff_m2);
param->ulGbFuseTableCksoffB =
le32_to_cpu(profile->avfsgb_fuse_table_cksoff_b);
param->ulGbFuseTableCksonM1 =
le32_to_cpu(profile->avfsgb_fuse_table_ckson_m1);
- param->usGbFuseTableCksonM2 =
+ param->ulGbFuseTableCksonM2 =
le16_to_cpu(profile->avfsgb_fuse_table_ckson_m2);
param->ulGbFuseTableCksonB =
le32_to_cpu(profile->avfsgb_fuse_table_ckson_b);
- param->usMaxVoltage025mv =
- le16_to_cpu(profile->max_voltage_0_25mv);
- param->ucEnableGbVdroopTableCksoff =
- profile->enable_gb_vdroop_table_cksoff;
+
param->ucEnableGbVdroopTableCkson =
profile->enable_gb_vdroop_table_ckson;
- param->ucEnableGbFuseTableCksoff =
- profile->enable_gb_fuse_table_cksoff;
param->ucEnableGbFuseTableCkson =
profile->enable_gb_fuse_table_ckson;
param->usPsmAgeComfactor =
le16_to_cpu(profile->psm_age_comfactor);
- param->ucEnableApplyAvfsCksoffVoltage =
- profile->enable_apply_avfs_cksoff_voltage;
param->ulDispclk2GfxclkM1 =
le32_to_cpu(profile->dispclk2gfxclk_a);
- param->usDispclk2GfxclkM2 =
+ param->ulDispclk2GfxclkM2 =
le16_to_cpu(profile->dispclk2gfxclk_b);
param->ulDispclk2GfxclkB =
le32_to_cpu(profile->dispclk2gfxclk_c);
param->ulDcefclk2GfxclkM1 =
le32_to_cpu(profile->dcefclk2gfxclk_a);
- param->usDcefclk2GfxclkM2 =
+ param->ulDcefclk2GfxclkM2 =
le16_to_cpu(profile->dcefclk2gfxclk_b);
param->ulDcefclk2GfxclkB =
le32_to_cpu(profile->dcefclk2gfxclk_c);
param->ulPixelclk2GfxclkM1 =
le32_to_cpu(profile->pixclk2gfxclk_a);
- param->usPixelclk2GfxclkM2 =
+ param->ulPixelclk2GfxclkM2 =
le16_to_cpu(profile->pixclk2gfxclk_b);
param->ulPixelclk2GfxclkB =
le32_to_cpu(profile->pixclk2gfxclk_c);
param->ulPhyclk2GfxclkM1 =
le32_to_cpu(profile->phyclk2gfxclk_a);
- param->usPhyclk2GfxclkM2 =
+ param->ulPhyclk2GfxclkM2 =
le16_to_cpu(profile->phyclk2gfxclk_b);
param->ulPhyclk2GfxclkB =
le32_to_cpu(profile->phyclk2gfxclk_c);
@@ -394,3 +387,31 @@ int pp_atomfwctrl_get_gpio_information(struct pp_hwmgr *hwmgr,
return 0;
}
+
+int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,
+ struct pp_atomfwctrl_bios_boot_up_values *boot_values)
+{
+ struct atom_firmware_info_v3_1 *info = NULL;
+ uint16_t ix;
+
+ ix = GetIndexIntoMasterDataTable(firmwareinfo);
+ info = (struct atom_firmware_info_v3_1 *)
+ cgs_atom_get_data_table(hwmgr->device,
+ ix, NULL, NULL, NULL);
+
+ if (!info) {
+ pr_info("Error retrieving BIOS firmwareinfo!");
+ return -EINVAL;
+ }
+
+ boot_values->ulRevision = info->firmware_revision;
+ boot_values->ulGfxClk = info->bootup_sclk_in10khz;
+ boot_values->ulUClk = info->bootup_mclk_in10khz;
+ boot_values->ulSocClk = 0;
+ boot_values->usVddc = info->bootup_vddc_mv;
+ boot_values->usVddci = info->bootup_vddci_mv;
+ boot_values->usMvddc = info->bootup_mvddc_mv;
+ boot_values->usVddGfx = info->bootup_vddgfx_mv;
+
+ return 0;
+} \ No newline at end of file
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h
index 7efe9b96cb33..43a6711e3c06 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h
@@ -69,7 +69,7 @@ struct pp_atomfwctrl_clock_dividers_soc15 {
struct pp_atomfwctrl_avfs_parameters {
uint32_t ulMaxVddc;
uint32_t ulMinVddc;
- uint8_t ucMaxVidStep;
+
uint32_t ulMeanNsigmaAcontant0;
uint32_t ulMeanNsigmaAcontant1;
uint32_t ulMeanNsigmaAcontant2;
@@ -82,30 +82,30 @@ struct pp_atomfwctrl_avfs_parameters {
uint32_t ulGbVdroopTableCksonA0;
uint32_t ulGbVdroopTableCksonA1;
uint32_t ulGbVdroopTableCksonA2;
+
uint32_t ulGbFuseTableCksoffM1;
- uint16_t usGbFuseTableCksoffM2;
- uint32_t ulGbFuseTableCksoffB;\
+ uint32_t ulGbFuseTableCksoffM2;
+ uint32_t ulGbFuseTableCksoffB;
+
uint32_t ulGbFuseTableCksonM1;
- uint16_t usGbFuseTableCksonM2;
+ uint32_t ulGbFuseTableCksonM2;
uint32_t ulGbFuseTableCksonB;
- uint16_t usMaxVoltage025mv;
- uint8_t ucEnableGbVdroopTableCksoff;
+
uint8_t ucEnableGbVdroopTableCkson;
- uint8_t ucEnableGbFuseTableCksoff;
uint8_t ucEnableGbFuseTableCkson;
uint16_t usPsmAgeComfactor;
- uint8_t ucEnableApplyAvfsCksoffVoltage;
+
uint32_t ulDispclk2GfxclkM1;
- uint16_t usDispclk2GfxclkM2;
+ uint32_t ulDispclk2GfxclkM2;
uint32_t ulDispclk2GfxclkB;
uint32_t ulDcefclk2GfxclkM1;
- uint16_t usDcefclk2GfxclkM2;
+ uint32_t ulDcefclk2GfxclkM2;
uint32_t ulDcefclk2GfxclkB;
uint32_t ulPixelclk2GfxclkM1;
- uint16_t usPixelclk2GfxclkM2;
+ uint32_t ulPixelclk2GfxclkM2;
uint32_t ulPixelclk2GfxclkB;
uint32_t ulPhyclk2GfxclkM1;
- uint16_t usPhyclk2GfxclkM2;
+ uint32_t ulPhyclk2GfxclkM2;
uint32_t ulPhyclk2GfxclkB;
};
@@ -119,6 +119,18 @@ struct pp_atomfwctrl_gpio_parameters {
uint8_t ucFwCtfGpio;
uint8_t ucFwCtfPolarity;
};
+
+struct pp_atomfwctrl_bios_boot_up_values {
+ uint32_t ulRevision;
+ uint32_t ulGfxClk;
+ uint32_t ulUClk;
+ uint32_t ulSocClk;
+ uint16_t usVddc;
+ uint16_t usVddci;
+ uint16_t usMvddc;
+ uint16_t usVddGfx;
+};
+
int pp_atomfwctrl_get_gpu_pll_dividers_vega10(struct pp_hwmgr *hwmgr,
uint32_t clock_type, uint32_t clock_value,
struct pp_atomfwctrl_clock_dividers_soc15 *dividers);
@@ -136,5 +148,8 @@ int pp_atomfwctrl_get_avfs_information(struct pp_hwmgr *hwmgr,
int pp_atomfwctrl_get_gpio_information(struct pp_hwmgr *hwmgr,
struct pp_atomfwctrl_gpio_parameters *param);
+int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,
+ struct pp_atomfwctrl_bios_boot_up_values *boot_values);
+
#endif
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
index 8f663ab56a80..a74a3db3056c 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
@@ -4334,26 +4334,31 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
static int smu7_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
{
- if (mode) {
- /* stop auto-manage */
- if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
- PHM_PlatformCaps_MicrocodeFanControl))
- smu7_fan_ctrl_stop_smc_fan_control(hwmgr);
- smu7_fan_ctrl_set_static_mode(hwmgr, mode);
- } else
- /* restart auto-manage */
- smu7_fan_ctrl_reset_fan_speed_to_default(hwmgr);
+ int result = 0;
- return 0;
+ switch (mode) {
+ case AMD_FAN_CTRL_NONE:
+ result = smu7_fan_ctrl_set_fan_speed_percent(hwmgr, 100);
+ break;
+ case AMD_FAN_CTRL_MANUAL:
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_MicrocodeFanControl))
+ result = smu7_fan_ctrl_stop_smc_fan_control(hwmgr);
+ break;
+ case AMD_FAN_CTRL_AUTO:
+ result = smu7_fan_ctrl_set_static_mode(hwmgr, mode);
+ if (!result)
+ result = smu7_fan_ctrl_start_smc_fan_control(hwmgr);
+ break;
+ default:
+ break;
+ }
+ return result;
}
static int smu7_get_fan_control_mode(struct pp_hwmgr *hwmgr)
{
- if (hwmgr->fan_ctrl_is_in_default_mode)
- return hwmgr->fan_ctrl_default_mode;
- else
- return PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
- CG_FDO_CTRL2, FDO_PWM_MODE);
+ return hwmgr->fan_ctrl_enabled ? AMD_FAN_CTRL_AUTO : AMD_FAN_CTRL_MANUAL;
}
static int smu7_get_sclk_od(struct pp_hwmgr *hwmgr)
@@ -4522,32 +4527,6 @@ static int smu7_get_clock_by_type(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type
return 0;
}
-static int smu7_request_firmware(struct pp_hwmgr *hwmgr)
-{
- int ret;
- struct cgs_firmware_info info = {0};
-
- ret = cgs_get_firmware_info(hwmgr->device,
- smu7_convert_fw_type_to_cgs(UCODE_ID_SMU),
- &info);
- if (ret || !info.kptr)
- return -EINVAL;
-
- return 0;
-}
-
-static int smu7_release_firmware(struct pp_hwmgr *hwmgr)
-{
- int ret;
-
- ret = cgs_rel_firmware(hwmgr->device,
- smu7_convert_fw_type_to_cgs(UCODE_ID_SMU));
- if (ret)
- return -EINVAL;
-
- return 0;
-}
-
static void smu7_find_min_clock_masks(struct pp_hwmgr *hwmgr,
uint32_t *sclk_mask, uint32_t *mclk_mask,
uint32_t min_sclk, uint32_t min_mclk)
@@ -4691,10 +4670,9 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = {
.get_clock_by_type = smu7_get_clock_by_type,
.read_sensor = smu7_read_sensor,
.dynamic_state_management_disable = smu7_disable_dpm_tasks,
- .request_firmware = smu7_request_firmware,
- .release_firmware = smu7_release_firmware,
.set_power_profile_state = smu7_set_power_profile_state,
.avfs_control = smu7_avfs_control,
+ .disable_smc_firmware_ctf = smu7_thermal_disable_alert,
};
uint8_t smu7_get_sleep_divider_id_from_clock(uint32_t clock,
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c
index 436ca5ce8248..baddb569a8b8 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c
@@ -112,10 +112,9 @@ int smu7_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
*/
int smu7_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
{
-
if (hwmgr->fan_ctrl_is_in_default_mode) {
hwmgr->fan_ctrl_default_mode =
- PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+ PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
CG_FDO_CTRL2, FDO_PWM_MODE);
hwmgr->tmin =
PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
@@ -149,7 +148,7 @@ int smu7_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr)
return 0;
}
-static int smu7_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
+int smu7_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
{
int result;
@@ -179,6 +178,7 @@ static int smu7_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
PPSMC_MSG_SetFanTemperatureTarget,
hwmgr->thermal_controller.
advanceFanControlParameters.ucTargetTemperature);
+ hwmgr->fan_ctrl_enabled = true;
return result;
}
@@ -186,6 +186,7 @@ static int smu7_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
int smu7_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr)
{
+ hwmgr->fan_ctrl_enabled = false;
return smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_StopFanControl);
}
@@ -280,7 +281,7 @@ int smu7_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
CG_TACH_STATUS, TACH_PERIOD, tach_period);
- return smu7_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
+ return smu7_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC_RPM);
}
/**
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.h b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.h
index 2ed774db42c7..ba71b608fa75 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.h
@@ -54,6 +54,6 @@ extern int smu7_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *spe
extern int smu7_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr);
extern int smu7_thermal_enable_alert(struct pp_hwmgr *hwmgr);
extern int smu7_thermal_disable_alert(struct pp_hwmgr *hwmgr);
-
+extern int smu7_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr);
#endif
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
index 83949550edac..ad30f5d3a10d 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
@@ -111,6 +111,8 @@ static void vega10_set_default_registry_data(struct pp_hwmgr *hwmgr)
hwmgr->feature_mask & PP_SOCCLK_DPM_MASK ? false : true;
data->registry_data.mclk_dpm_key_disabled =
hwmgr->feature_mask & PP_MCLK_DPM_MASK ? false : true;
+ data->registry_data.pcie_dpm_key_disabled =
+ hwmgr->feature_mask & PP_PCIE_DPM_MASK ? false : true;
data->registry_data.dcefclk_dpm_key_disabled =
hwmgr->feature_mask & PP_DCEFCLK_DPM_MASK ? false : true;
@@ -121,7 +123,9 @@ static void vega10_set_default_registry_data(struct pp_hwmgr *hwmgr)
data->registry_data.enable_tdc_limit_feature = 1;
}
- data->registry_data.pcie_dpm_key_disabled = 1;
+ data->registry_data.clock_stretcher_support =
+ hwmgr->feature_mask & PP_CLOCK_STRETCH_MASK ? false : true;
+
data->registry_data.disable_water_mark = 0;
data->registry_data.fan_control_support = 1;
@@ -1133,7 +1137,7 @@ static void vega10_setup_default_single_dpm_table(struct pp_hwmgr *hwmgr,
int i;
for (i = 0; i < dep_table->count; i++) {
- if (i == 0 || dpm_table->dpm_levels[dpm_table->count - 1].value !=
+ if (i == 0 || dpm_table->dpm_levels[dpm_table->count - 1].value <=
dep_table->entries[i].clk) {
dpm_table->dpm_levels[dpm_table->count].value =
dep_table->entries[i].clk;
@@ -1178,29 +1182,9 @@ static int vega10_setup_default_pcie_table(struct pp_hwmgr *hwmgr)
else
pcie_table->lclk[i] =
bios_pcie_table->entries[i].pcie_sclk;
-
- pcie_table->count++;
}
- if (data->registry_data.pcieSpeedOverride)
- pcie_table->pcie_gen[i] = data->registry_data.pcieSpeedOverride;
- else
- pcie_table->pcie_gen[i] =
- bios_pcie_table->entries[bios_pcie_table->count - 1].gen_speed;
-
- if (data->registry_data.pcieLaneOverride)
- pcie_table->pcie_lane[i] = data->registry_data.pcieLaneOverride;
- else
- pcie_table->pcie_lane[i] =
- bios_pcie_table->entries[bios_pcie_table->count - 1].lane_width;
-
- if (data->registry_data.pcieClockOverride)
- pcie_table->lclk[i] = data->registry_data.pcieClockOverride;
- else
- pcie_table->lclk[i] =
- bios_pcie_table->entries[bios_pcie_table->count - 1].pcie_sclk;
-
- pcie_table->count++;
+ pcie_table->count = NUM_LINK_LEVELS;
return 0;
}
@@ -1290,7 +1274,7 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
dpm_table = &(data->dpm_table.eclk_table);
for (i = 0; i < dep_mm_table->count; i++) {
if (i == 0 || dpm_table->dpm_levels
- [dpm_table->count - 1].value !=
+ [dpm_table->count - 1].value <=
dep_mm_table->entries[i].eclk) {
dpm_table->dpm_levels[dpm_table->count].value =
dep_mm_table->entries[i].eclk;
@@ -1306,7 +1290,7 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
dpm_table = &(data->dpm_table.vclk_table);
for (i = 0; i < dep_mm_table->count; i++) {
if (i == 0 || dpm_table->dpm_levels
- [dpm_table->count - 1].value !=
+ [dpm_table->count - 1].value <=
dep_mm_table->entries[i].vclk) {
dpm_table->dpm_levels[dpm_table->count].value =
dep_mm_table->entries[i].vclk;
@@ -1320,7 +1304,7 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
dpm_table = &(data->dpm_table.dclk_table);
for (i = 0; i < dep_mm_table->count; i++) {
if (i == 0 || dpm_table->dpm_levels
- [dpm_table->count - 1].value !=
+ [dpm_table->count - 1].value <=
dep_mm_table->entries[i].dclk) {
dpm_table->dpm_levels[dpm_table->count].value =
dep_mm_table->entries[i].dclk;
@@ -1432,9 +1416,7 @@ static int vega10_populate_ulv_state(struct pp_hwmgr *hwmgr)
(struct phm_ppt_v2_information *)(hwmgr->pptable);
data->smc_state_table.pp_table.UlvOffsetVid =
- (uint8_t)(table_info->us_ulv_voltage_offset *
- VOLTAGE_VID_OFFSET_SCALE2 /
- VOLTAGE_VID_OFFSET_SCALE1);
+ (uint8_t)table_info->us_ulv_voltage_offset;
data->smc_state_table.pp_table.UlvSmnclkDid =
(uint8_t)(table_info->us_ulv_smnclk_did);
@@ -1553,7 +1535,11 @@ static int vega10_populate_single_gfx_level(struct pp_hwmgr *hwmgr,
current_gfxclk_level->FbMult =
cpu_to_le32(dividers.ulPll_fb_mult);
/* Spread FB Multiplier bit: bit 0:8 int, bit 31:16 frac */
- current_gfxclk_level->SsOn = dividers.ucPll_ss_enable;
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_EngineSpreadSpectrumSupport))
+ current_gfxclk_level->SsOn = dividers.ucPll_ss_enable;
+ else
+ current_gfxclk_level->SsOn = 0;
current_gfxclk_level->SsFbMult =
cpu_to_le32(dividers.ulPll_ss_fbsmult);
current_gfxclk_level->SsSlewFrac =
@@ -2044,10 +2030,10 @@ static int vega10_populate_clock_stretcher_table(struct pp_hwmgr *hwmgr)
table_info->vdd_dep_on_sclk;
uint32_t i;
- for (i = 0; dep_table->count; i++) {
+ for (i = 0; i < dep_table->count; i++) {
pp_table->CksEnable[i] = dep_table->entries[i].cks_enable;
- pp_table->CksVidOffset[i] = convert_to_vid(
- dep_table->entries[i].cks_voffset);
+ pp_table->CksVidOffset[i] = (uint8_t)(dep_table->entries[i].cks_voffset
+ * VOLTAGE_VID_OFFSET_SCALE2 / VOLTAGE_VID_OFFSET_SCALE1);
}
return 0;
@@ -2073,66 +2059,70 @@ static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
result = pp_atomfwctrl_get_avfs_information(hwmgr, &avfs_params);
if (!result) {
pp_table->MinVoltageVid = (uint8_t)
- convert_to_vid((uint16_t)(avfs_params.ulMaxVddc));
- pp_table->MaxVoltageVid = (uint8_t)
convert_to_vid((uint16_t)(avfs_params.ulMinVddc));
- pp_table->BtcGbVdroopTableCksOn.a0 =
- cpu_to_le32(avfs_params.ulGbVdroopTableCksonA0);
- pp_table->BtcGbVdroopTableCksOn.a1 =
- cpu_to_le32(avfs_params.ulGbVdroopTableCksonA1);
- pp_table->BtcGbVdroopTableCksOn.a2 =
- cpu_to_le32(avfs_params.ulGbVdroopTableCksonA2);
+ pp_table->MaxVoltageVid = (uint8_t)
+ convert_to_vid((uint16_t)(avfs_params.ulMaxVddc));
+
+ pp_table->AConstant[0] = cpu_to_le32(avfs_params.ulMeanNsigmaAcontant0);
+ pp_table->AConstant[1] = cpu_to_le32(avfs_params.ulMeanNsigmaAcontant1);
+ pp_table->AConstant[2] = cpu_to_le32(avfs_params.ulMeanNsigmaAcontant2);
+ pp_table->DC_tol_sigma = cpu_to_le16(avfs_params.usMeanNsigmaDcTolSigma);
+ pp_table->Platform_mean = cpu_to_le16(avfs_params.usMeanNsigmaPlatformMean);
+ pp_table->Platform_sigma = cpu_to_le16(avfs_params.usMeanNsigmaDcTolSigma);
+ pp_table->PSM_Age_CompFactor = cpu_to_le16(avfs_params.usPsmAgeComfactor);
pp_table->BtcGbVdroopTableCksOff.a0 =
cpu_to_le32(avfs_params.ulGbVdroopTableCksoffA0);
+ pp_table->BtcGbVdroopTableCksOff.a0_shift = 20;
pp_table->BtcGbVdroopTableCksOff.a1 =
cpu_to_le32(avfs_params.ulGbVdroopTableCksoffA1);
+ pp_table->BtcGbVdroopTableCksOff.a1_shift = 20;
pp_table->BtcGbVdroopTableCksOff.a2 =
cpu_to_le32(avfs_params.ulGbVdroopTableCksoffA2);
+ pp_table->BtcGbVdroopTableCksOff.a2_shift = 20;
+
+ pp_table->OverrideBtcGbCksOn = avfs_params.ucEnableGbVdroopTableCkson;
+ pp_table->BtcGbVdroopTableCksOn.a0 =
+ cpu_to_le32(avfs_params.ulGbVdroopTableCksonA0);
+ pp_table->BtcGbVdroopTableCksOn.a0_shift = 20;
+ pp_table->BtcGbVdroopTableCksOn.a1 =
+ cpu_to_le32(avfs_params.ulGbVdroopTableCksonA1);
+ pp_table->BtcGbVdroopTableCksOn.a1_shift = 20;
+ pp_table->BtcGbVdroopTableCksOn.a2 =
+ cpu_to_le32(avfs_params.ulGbVdroopTableCksonA2);
+ pp_table->BtcGbVdroopTableCksOn.a2_shift = 20;
pp_table->AvfsGbCksOn.m1 =
cpu_to_le32(avfs_params.ulGbFuseTableCksonM1);
pp_table->AvfsGbCksOn.m2 =
- cpu_to_le16(avfs_params.usGbFuseTableCksonM2);
+ cpu_to_le16(avfs_params.ulGbFuseTableCksonM2);
pp_table->AvfsGbCksOn.b =
cpu_to_le32(avfs_params.ulGbFuseTableCksonB);
pp_table->AvfsGbCksOn.m1_shift = 24;
pp_table->AvfsGbCksOn.m2_shift = 12;
+ pp_table->AvfsGbCksOn.b_shift = 0;
+ pp_table->OverrideAvfsGbCksOn =
+ avfs_params.ucEnableGbFuseTableCkson;
pp_table->AvfsGbCksOff.m1 =
cpu_to_le32(avfs_params.ulGbFuseTableCksoffM1);
pp_table->AvfsGbCksOff.m2 =
- cpu_to_le16(avfs_params.usGbFuseTableCksoffM2);
+ cpu_to_le16(avfs_params.ulGbFuseTableCksoffM2);
pp_table->AvfsGbCksOff.b =
cpu_to_le32(avfs_params.ulGbFuseTableCksoffB);
pp_table->AvfsGbCksOff.m1_shift = 24;
pp_table->AvfsGbCksOff.m2_shift = 12;
-
- pp_table->AConstant[0] =
- cpu_to_le32(avfs_params.ulMeanNsigmaAcontant0);
- pp_table->AConstant[1] =
- cpu_to_le32(avfs_params.ulMeanNsigmaAcontant1);
- pp_table->AConstant[2] =
- cpu_to_le32(avfs_params.ulMeanNsigmaAcontant2);
- pp_table->DC_tol_sigma =
- cpu_to_le16(avfs_params.usMeanNsigmaDcTolSigma);
- pp_table->Platform_mean =
- cpu_to_le16(avfs_params.usMeanNsigmaPlatformMean);
- pp_table->PSM_Age_CompFactor =
- cpu_to_le16(avfs_params.usPsmAgeComfactor);
- pp_table->Platform_sigma =
- cpu_to_le16(avfs_params.usMeanNsigmaDcTolSigma);
-
- for (i = 0; i < dep_table->count; i++)
- pp_table->StaticVoltageOffsetVid[i] = (uint8_t)
- (dep_table->entries[i].sclk_offset *
+ pp_table->AvfsGbCksOff.b_shift = 0;
+
+ for (i = 0; i < dep_table->count; i++) {
+ if (dep_table->entries[i].sclk_offset == 0)
+ pp_table->StaticVoltageOffsetVid[i] = 248;
+ else
+ pp_table->StaticVoltageOffsetVid[i] =
+ (uint8_t)(dep_table->entries[i].sclk_offset *
VOLTAGE_VID_OFFSET_SCALE2 /
VOLTAGE_VID_OFFSET_SCALE1);
-
- pp_table->OverrideBtcGbCksOn =
- avfs_params.ucEnableGbVdroopTableCkson;
- pp_table->OverrideAvfsGbCksOn =
- avfs_params.ucEnableGbFuseTableCkson;
+ }
if ((PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
data->disp_clk_quad_eqn_a) &&
@@ -2141,20 +2131,21 @@ static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].m1 =
(int32_t)data->disp_clk_quad_eqn_a;
pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].m2 =
- (int16_t)data->disp_clk_quad_eqn_b;
+ (int32_t)data->disp_clk_quad_eqn_b;
pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].b =
(int32_t)data->disp_clk_quad_eqn_c;
} else {
pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].m1 =
(int32_t)avfs_params.ulDispclk2GfxclkM1;
pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].m2 =
- (int16_t)avfs_params.usDispclk2GfxclkM2;
+ (int32_t)avfs_params.ulDispclk2GfxclkM2;
pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].b =
(int32_t)avfs_params.ulDispclk2GfxclkB;
}
pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].m1_shift = 24;
pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].m2_shift = 12;
+ pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].b_shift = 12;
if ((PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
data->dcef_clk_quad_eqn_a) &&
@@ -2163,20 +2154,21 @@ static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].m1 =
(int32_t)data->dcef_clk_quad_eqn_a;
pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].m2 =
- (int16_t)data->dcef_clk_quad_eqn_b;
+ (int32_t)data->dcef_clk_quad_eqn_b;
pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].b =
(int32_t)data->dcef_clk_quad_eqn_c;
} else {
pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].m1 =
(int32_t)avfs_params.ulDcefclk2GfxclkM1;
pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].m2 =
- (int16_t)avfs_params.usDcefclk2GfxclkM2;
+ (int32_t)avfs_params.ulDcefclk2GfxclkM2;
pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].b =
(int32_t)avfs_params.ulDcefclk2GfxclkB;
}
pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].m1_shift = 24;
pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].m2_shift = 12;
+ pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].b_shift = 12;
if ((PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
data->pixel_clk_quad_eqn_a) &&
@@ -2185,21 +2177,21 @@ static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].m1 =
(int32_t)data->pixel_clk_quad_eqn_a;
pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].m2 =
- (int16_t)data->pixel_clk_quad_eqn_b;
+ (int32_t)data->pixel_clk_quad_eqn_b;
pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].b =
(int32_t)data->pixel_clk_quad_eqn_c;
} else {
pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].m1 =
(int32_t)avfs_params.ulPixelclk2GfxclkM1;
pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].m2 =
- (int16_t)avfs_params.usPixelclk2GfxclkM2;
+ (int32_t)avfs_params.ulPixelclk2GfxclkM2;
pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].b =
(int32_t)avfs_params.ulPixelclk2GfxclkB;
}
pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].m1_shift = 24;
pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].m2_shift = 12;
-
+ pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].b_shift = 12;
if ((PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
data->phy_clk_quad_eqn_a) &&
(PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
@@ -2207,20 +2199,21 @@ static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m1 =
(int32_t)data->phy_clk_quad_eqn_a;
pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m2 =
- (int16_t)data->phy_clk_quad_eqn_b;
+ (int32_t)data->phy_clk_quad_eqn_b;
pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].b =
(int32_t)data->phy_clk_quad_eqn_c;
} else {
pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m1 =
(int32_t)avfs_params.ulPhyclk2GfxclkM1;
pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m2 =
- (int16_t)avfs_params.usPhyclk2GfxclkM2;
+ (int32_t)avfs_params.ulPhyclk2GfxclkM2;
pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].b =
(int32_t)avfs_params.ulPhyclk2GfxclkB;
}
pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m1_shift = 24;
pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m2_shift = 12;
+ pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].b_shift = 12;
} else {
data->smu_features[GNLD_AVFS].supported = false;
}
@@ -2309,6 +2302,7 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
(struct phm_ppt_v2_information *)(hwmgr->pptable);
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
struct pp_atomfwctrl_voltage_table voltage_table;
+ struct pp_atomfwctrl_bios_boot_up_values boot_up_values;
result = vega10_setup_default_dpm_tables(hwmgr);
PP_ASSERT_WITH_CODE(!result,
@@ -2331,6 +2325,7 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
(uint8_t)(table_info->uc_vce_dpm_voltage_mode);
pp_table->Mp0DpmVoltageMode =
(uint8_t)(table_info->uc_mp0_dpm_voltage_mode);
+
pp_table->DisplayDpmVoltageMode =
(uint8_t)(table_info->uc_dcef_dpm_voltage_mode);
@@ -2372,14 +2367,31 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
"Failed to initialize UVD Level!",
return result);
- if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
- PHM_PlatformCaps_ClockStretcher)) {
+ if (data->registry_data.clock_stretcher_support) {
result = vega10_populate_clock_stretcher_table(hwmgr);
PP_ASSERT_WITH_CODE(!result,
"Failed to populate Clock Stretcher Table!",
return result);
}
+ result = pp_atomfwctrl_get_vbios_bootup_values(hwmgr, &boot_up_values);
+ if (!result) {
+ data->vbios_boot_state.vddc = boot_up_values.usVddc;
+ data->vbios_boot_state.vddci = boot_up_values.usVddci;
+ data->vbios_boot_state.mvddc = boot_up_values.usMvddc;
+ data->vbios_boot_state.gfx_clock = boot_up_values.ulGfxClk;
+ data->vbios_boot_state.mem_clock = boot_up_values.ulUClk;
+ data->vbios_boot_state.soc_clock = boot_up_values.ulSocClk;
+ if (0 != boot_up_values.usVddc) {
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetFloorSocVoltage,
+ (boot_up_values.usVddc * 4));
+ data->vbios_boot_state.bsoc_vddc_lock = true;
+ } else {
+ data->vbios_boot_state.bsoc_vddc_lock = false;
+ }
+ }
+
result = vega10_populate_avfs_parameters(hwmgr);
PP_ASSERT_WITH_CODE(!result,
"Failed to initialize AVFS Parameters!",
@@ -2404,35 +2416,9 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
PP_ASSERT_WITH_CODE(!result,
"Failed to upload PPtable!", return result);
- if (data->smu_features[GNLD_AVFS].supported) {
- uint32_t features_enabled;
- result = vega10_get_smc_features(hwmgr->smumgr, &features_enabled);
- PP_ASSERT_WITH_CODE(!result,
- "Failed to Retrieve Enabled Features!",
- return result);
- if (!(features_enabled & (1 << FEATURE_AVFS_BIT))) {
- result = vega10_perform_btc(hwmgr->smumgr);
- PP_ASSERT_WITH_CODE(!result,
- "Failed to Perform BTC!",
- return result);
- result = vega10_avfs_enable(hwmgr, true);
- PP_ASSERT_WITH_CODE(!result,
- "Attempt to enable AVFS feature Failed!",
- return result);
- result = vega10_save_vft_table(hwmgr->smumgr,
- (uint8_t *)&(data->smc_state_table.avfs_table));
- PP_ASSERT_WITH_CODE(!result,
- "Attempt to save VFT table Failed!",
+ result = vega10_avfs_enable(hwmgr, true);
+ PP_ASSERT_WITH_CODE(!result, "Attempt to enable AVFS feature Failed!",
return result);
- } else {
- data->smu_features[GNLD_AVFS].enabled = true;
- result = vega10_restore_vft_table(hwmgr->smumgr,
- (uint8_t *)&(data->smc_state_table.avfs_table));
- PP_ASSERT_WITH_CODE(!result,
- "Attempt to restore VFT table Failed!",
- return result;);
- }
- }
return 0;
}
@@ -2457,6 +2443,26 @@ static int vega10_enable_thermal_protection(struct pp_hwmgr *hwmgr)
return 0;
}
+static int vega10_disable_thermal_protection(struct pp_hwmgr *hwmgr)
+{
+ struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
+
+ if (data->smu_features[GNLD_THERMAL].supported) {
+ if (!data->smu_features[GNLD_THERMAL].enabled)
+ pr_info("THERMAL Feature Already disabled!");
+
+ PP_ASSERT_WITH_CODE(
+ !vega10_enable_smc_features(hwmgr->smumgr,
+ false,
+ data->smu_features[GNLD_THERMAL].smu_feature_bitmap),
+ "disable THERMAL Feature Failed!",
+ return -1);
+ data->smu_features[GNLD_THERMAL].enabled = false;
+ }
+
+ return 0;
+}
+
static int vega10_enable_vrhot_feature(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
@@ -2535,6 +2541,37 @@ static int vega10_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
return 0;
}
+static int vega10_stop_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap)
+{
+ struct vega10_hwmgr *data =
+ (struct vega10_hwmgr *)(hwmgr->backend);
+ uint32_t i, feature_mask = 0;
+
+
+ if(data->smu_features[GNLD_LED_DISPLAY].supported == true){
+ PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr->smumgr,
+ true, data->smu_features[GNLD_LED_DISPLAY].smu_feature_bitmap),
+ "Attempt to Enable LED DPM feature Failed!", return -EINVAL);
+ data->smu_features[GNLD_LED_DISPLAY].enabled = true;
+ }
+
+ for (i = 0; i < GNLD_DPM_MAX; i++) {
+ if (data->smu_features[i].smu_feature_bitmap & bitmap) {
+ if (data->smu_features[i].supported) {
+ if (data->smu_features[i].enabled) {
+ feature_mask |= data->smu_features[i].
+ smu_feature_bitmap;
+ data->smu_features[i].enabled = false;
+ }
+ }
+ }
+ }
+
+ vega10_enable_smc_features(hwmgr->smumgr, false, feature_mask);
+
+ return 0;
+}
+
/**
* @brief Tell SMC to enabled the supported DPMs.
*
@@ -2576,6 +2613,12 @@ static int vega10_start_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap)
data->smu_features[GNLD_LED_DISPLAY].enabled = true;
}
+ if (data->vbios_boot_state.bsoc_vddc_lock) {
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetFloorSocVoltage, 0);
+ data->vbios_boot_state.bsoc_vddc_lock = false;
+ }
+
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_Falcon_QuickTransition)) {
if (data->smu_features[GNLD_ACDC].supported) {
@@ -2602,8 +2645,6 @@ static int vega10_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
"Failed to configure telemetry!",
return tmp_result);
- vega10_set_tools_address(hwmgr->smumgr);
-
smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
PPSMC_MSG_NumOfDisplays, 0);
@@ -3880,32 +3921,36 @@ static int vega10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
static int vega10_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
{
- if (mode) {
- /* stop auto-manage */
- if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
- PHM_PlatformCaps_MicrocodeFanControl))
- vega10_fan_ctrl_stop_smc_fan_control(hwmgr);
- vega10_fan_ctrl_set_static_mode(hwmgr, mode);
- } else
- /* restart auto-manage */
- vega10_fan_ctrl_reset_fan_speed_to_default(hwmgr);
+ int result = 0;
- return 0;
+ switch (mode) {
+ case AMD_FAN_CTRL_NONE:
+ result = vega10_fan_ctrl_set_fan_speed_percent(hwmgr, 100);
+ break;
+ case AMD_FAN_CTRL_MANUAL:
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_MicrocodeFanControl))
+ result = vega10_fan_ctrl_stop_smc_fan_control(hwmgr);
+ break;
+ case AMD_FAN_CTRL_AUTO:
+ result = vega10_fan_ctrl_set_static_mode(hwmgr, mode);
+ if (!result)
+ result = vega10_fan_ctrl_start_smc_fan_control(hwmgr);
+ break;
+ default:
+ break;
+ }
+ return result;
}
static int vega10_get_fan_control_mode(struct pp_hwmgr *hwmgr)
{
- uint32_t reg;
+ struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
- if (hwmgr->fan_ctrl_is_in_default_mode) {
- return hwmgr->fan_ctrl_default_mode;
- } else {
- reg = soc15_get_register_offset(THM_HWID, 0,
- mmCG_FDO_CTRL2_BASE_IDX, mmCG_FDO_CTRL2);
- return (cgs_read_register(hwmgr->device, reg) &
- CG_FDO_CTRL2__FDO_PWM_MODE_MASK) >>
- CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT;
- }
+ if (data->smu_features[GNLD_FAN_CONTROL].enabled == false)
+ return AMD_FAN_CTRL_MANUAL;
+ else
+ return AMD_FAN_CTRL_AUTO;
}
static int vega10_get_dal_power_level(struct pp_hwmgr *hwmgr,
@@ -4148,55 +4193,56 @@ static int vega10_force_clock_level(struct pp_hwmgr *hwmgr,
switch (type) {
case PP_SCLK:
- if (data->registry_data.sclk_dpm_key_disabled)
- break;
-
for (i = 0; i < 32; i++) {
if (mask & (1 << i))
break;
}
+ data->smc_state_table.gfx_boot_level = i;
- PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc_with_parameter(
- hwmgr->smumgr,
- PPSMC_MSG_SetSoftMinGfxclkByIndex,
- i),
- "Failed to set soft min sclk index!",
- return -1);
+ for (i = 31; i >= 0; i--) {
+ if (mask & (1 << i))
+ break;
+ }
+ data->smc_state_table.gfx_max_level = i;
+
+ PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr),
+ "Failed to upload boot level to lowest!",
+ return -EINVAL);
+
+ PP_ASSERT_WITH_CODE(!vega10_upload_dpm_max_level(hwmgr),
+ "Failed to upload dpm max level to highest!",
+ return -EINVAL);
break;
case PP_MCLK:
- if (data->registry_data.mclk_dpm_key_disabled)
- break;
-
for (i = 0; i < 32; i++) {
if (mask & (1 << i))
break;
}
- PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc_with_parameter(
- hwmgr->smumgr,
- PPSMC_MSG_SetSoftMinUclkByIndex,
- i),
- "Failed to set soft min mclk index!",
- return -1);
- break;
-
- case PP_PCIE:
- if (data->registry_data.pcie_dpm_key_disabled)
- break;
-
for (i = 0; i < 32; i++) {
if (mask & (1 << i))
break;
}
+ data->smc_state_table.mem_boot_level = i;
+
+ for (i = 31; i >= 0; i--) {
+ if (mask & (1 << i))
+ break;
+ }
+ data->smc_state_table.mem_max_level = i;
+
+ PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr),
+ "Failed to upload boot level to lowest!",
+ return -EINVAL);
+
+ PP_ASSERT_WITH_CODE(!vega10_upload_dpm_max_level(hwmgr),
+ "Failed to upload dpm max level to highest!",
+ return -EINVAL);
- PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc_with_parameter(
- hwmgr->smumgr,
- PPSMC_MSG_SetMinLinkDpmByIndex,
- i),
- "Failed to set min pcie index!",
- return -1);
break;
+
+ case PP_PCIE:
default:
break;
}
@@ -4395,11 +4441,55 @@ vega10_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmg
return is_update_required;
}
+static int vega10_disable_dpm_tasks(struct pp_hwmgr *hwmgr)
+{
+ int tmp_result, result = 0;
+
+ tmp_result = (vega10_is_dpm_running(hwmgr)) ? 0 : -1;
+ PP_ASSERT_WITH_CODE(tmp_result == 0,
+ "DPM is not running right now, no need to disable DPM!",
+ return 0);
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_ThermalController))
+ vega10_disable_thermal_protection(hwmgr);
+
+ tmp_result = vega10_disable_power_containment(hwmgr);
+ PP_ASSERT_WITH_CODE((tmp_result == 0),
+ "Failed to disable power containment!", result = tmp_result);
+
+ tmp_result = vega10_avfs_enable(hwmgr, false);
+ PP_ASSERT_WITH_CODE((tmp_result == 0),
+ "Failed to disable AVFS!", result = tmp_result);
+
+ tmp_result = vega10_stop_dpm(hwmgr, SMC_DPM_FEATURES);
+ PP_ASSERT_WITH_CODE((tmp_result == 0),
+ "Failed to stop DPM!", result = tmp_result);
+
+ return result;
+}
+
+static int vega10_power_off_asic(struct pp_hwmgr *hwmgr)
+{
+ struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
+ int result;
+
+ result = vega10_disable_dpm_tasks(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result),
+ "[disable_dpm_tasks] Failed to disable DPM!",
+ );
+ data->water_marks_bitmap &= ~(WaterMarksLoaded);
+
+ return result;
+}
+
+
static const struct pp_hwmgr_func vega10_hwmgr_funcs = {
.backend_init = vega10_hwmgr_backend_init,
.backend_fini = vega10_hwmgr_backend_fini,
.asic_setup = vega10_setup_asic_task,
.dynamic_state_management_enable = vega10_enable_dpm_tasks,
+ .dynamic_state_management_disable = vega10_disable_dpm_tasks,
.get_num_of_pp_table_entries =
vega10_get_number_of_powerplay_table_entries,
.get_power_state_size = vega10_get_power_state_size,
@@ -4439,6 +4529,8 @@ static const struct pp_hwmgr_func vega10_hwmgr_funcs = {
.check_states_equal = vega10_check_states_equal,
.check_smc_update_required_for_display_configuration =
vega10_check_smc_update_required_for_display_configuration,
+ .power_off_asic = vega10_power_off_asic,
+ .disable_smc_firmware_ctf = vega10_thermal_disable_alert,
};
int vega10_hwmgr_init(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 83c67b9262ff..1912e086c0cf 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
@@ -177,8 +177,11 @@ struct vega10_dpmlevel_enable_mask {
};
struct vega10_vbios_boot_state {
+ bool bsoc_vddc_lock;
uint16_t vddc;
uint16_t vddci;
+ uint16_t mvddc;
+ uint16_t vdd_gfx;
uint32_t gfx_clock;
uint32_t mem_clock;
uint32_t soc_clock;
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
index f1e244cd2370..3f72268e99bb 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
@@ -48,8 +48,8 @@ void vega10_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
table->Tliquid1Limit = cpu_to_le16(tdp_table->usTemperatureLimitLiquid1);
table->Tliquid2Limit = cpu_to_le16(tdp_table->usTemperatureLimitLiquid2);
table->TplxLimit = cpu_to_le16(tdp_table->usTemperatureLimitPlx);
- table->LoadLineResistance = cpu_to_le16(
- hwmgr->platform_descriptor.LoadLineSlope);
+ table->LoadLineResistance =
+ hwmgr->platform_descriptor.LoadLineSlope * 256;
table->FitLimit = 0; /* Not used for Vega10 */
table->Liquid1_I2C_address = tdp_table->ucLiquid1_I2C_address;
@@ -113,6 +113,29 @@ int vega10_enable_power_containment(struct pp_hwmgr *hwmgr)
return result;
}
+int vega10_disable_power_containment(struct pp_hwmgr *hwmgr)
+{
+ struct vega10_hwmgr *data =
+ (struct vega10_hwmgr *)(hwmgr->backend);
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_PowerContainment)) {
+ if (data->smu_features[GNLD_PPT].supported)
+ PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr->smumgr,
+ false, data->smu_features[GNLD_PPT].smu_feature_bitmap),
+ "Attempt to disable PPT feature Failed!",
+ data->smu_features[GNLD_PPT].supported = false);
+
+ if (data->smu_features[GNLD_TDC].supported)
+ PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr->smumgr,
+ false, data->smu_features[GNLD_TDC].smu_feature_bitmap),
+ "Attempt to disable PPT feature Failed!",
+ data->smu_features[GNLD_TDC].supported = false);
+ }
+
+ return 0;
+}
+
static int vega10_set_overdrive_target_percentage(struct pp_hwmgr *hwmgr,
uint32_t adjust_percent)
{
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h
index d9662bf4a4b4..9ecaa27c0bb5 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h
@@ -60,6 +60,7 @@ int vega10_enable_smc_cac(struct pp_hwmgr *hwmgr);
int vega10_enable_power_containment(struct pp_hwmgr *hwmgr);
int vega10_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n);
int vega10_power_control_set_level(struct pp_hwmgr *hwmgr);
+int vega10_disable_power_containment(struct pp_hwmgr *hwmgr);
#endif /* _VEGA10_POWERTUNE_H_ */
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c
index 8b55ae01132d..00e95511e19a 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c
@@ -407,7 +407,7 @@ static int get_tdp_table(
tdp_table->ucPlx_I2C_address = power_tune_table->ucPlx_I2C_address;
tdp_table->ucPlx_I2C_Line = power_tune_table->ucPlx_I2C_LineSCL;
tdp_table->ucPlx_I2C_LineSDA = power_tune_table->ucPlx_I2C_LineSDA;
- hwmgr->platform_descriptor.LoadLineSlope = power_tune_table->usLoadLineResistance;
+ hwmgr->platform_descriptor.LoadLineSlope = le16_to_cpu(power_tune_table->usLoadLineResistance);
} else {
power_tune_table_v2 = (ATOM_Vega10_PowerTune_Table_V2 *)table;
tdp_table->usMaximumPowerDeliveryLimit = le16_to_cpu(power_tune_table_v2->usSocketPowerLimit);
@@ -453,7 +453,7 @@ static int get_tdp_table(
tdp_table->ucPlx_I2C_LineSDA = sda;
hwmgr->platform_descriptor.LoadLineSlope =
- power_tune_table_v2->usLoadLineResistance;
+ le16_to_cpu(power_tune_table_v2->usLoadLineResistance);
}
*info_tdp_table = tdp_table;
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
index f4d77b62e1ba..d5f53d04fa08 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
@@ -381,14 +381,10 @@ int vega10_thermal_get_temperature(struct pp_hwmgr *hwmgr)
temp = cgs_read_register(hwmgr->device, reg);
- temp = (temp & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >>
- CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT;
+ temp = (temp & CG_MULT_THERMAL_STATUS__ASIC_MAX_TEMP_MASK) >>
+ CG_MULT_THERMAL_STATUS__ASIC_MAX_TEMP__SHIFT;
- /* Bit 9 means the reading is lower than the lowest usable value. */
- if (temp & 0x200)
- temp = VEGA10_THERMAL_MAXIMUM_TEMP_READING;
- else
- temp = temp & 0x1ff;
+ temp = temp & 0x1ff;
temp *= PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
@@ -424,23 +420,28 @@ static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
mmTHM_THERMAL_INT_CTRL_BASE_IDX, mmTHM_THERMAL_INT_CTRL);
val = cgs_read_register(hwmgr->device, reg);
- val &= ~(THM_THERMAL_INT_CTRL__DIG_THERM_INTH_MASK);
- val |= (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES) <<
- THM_THERMAL_INT_CTRL__DIG_THERM_INTH__SHIFT;
- val &= ~(THM_THERMAL_INT_CTRL__DIG_THERM_INTL_MASK);
- val |= (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES) <<
- THM_THERMAL_INT_CTRL__DIG_THERM_INTL__SHIFT;
+
+ val &= (~THM_THERMAL_INT_CTRL__MAX_IH_CREDIT_MASK);
+ val |= (5 << THM_THERMAL_INT_CTRL__MAX_IH_CREDIT__SHIFT);
+
+ val &= (~THM_THERMAL_INT_CTRL__THERM_IH_HW_ENA_MASK);
+ val |= (1 << THM_THERMAL_INT_CTRL__THERM_IH_HW_ENA__SHIFT);
+
+ val &= (~THM_THERMAL_INT_CTRL__DIG_THERM_INTH_MASK);
+ val |= ((high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)
+ << THM_THERMAL_INT_CTRL__DIG_THERM_INTH__SHIFT);
+
+ val &= (~THM_THERMAL_INT_CTRL__DIG_THERM_INTL_MASK);
+ val |= ((low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)
+ << THM_THERMAL_INT_CTRL__DIG_THERM_INTL__SHIFT);
+
+ val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
+
cgs_write_register(hwmgr->device, reg, val);
reg = soc15_get_register_offset(THM_HWID, 0,
mmTHM_TCON_HTC_BASE_IDX, mmTHM_TCON_HTC);
- val = cgs_read_register(hwmgr->device, reg);
- val &= ~(THM_TCON_HTC__HTC_TMP_LMT_MASK);
- val |= (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES) <<
- THM_TCON_HTC__HTC_TMP_LMT__SHIFT;
- cgs_write_register(hwmgr->device, reg, val);
-
return 0;
}
@@ -482,18 +483,28 @@ static int vega10_thermal_initialize(struct pp_hwmgr *hwmgr)
static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
+ uint32_t val = 0;
+ uint32_t reg;
if (data->smu_features[GNLD_FW_CTF].supported) {
if (data->smu_features[GNLD_FW_CTF].enabled)
printk("[Thermal_EnableAlert] FW CTF Already Enabled!\n");
+
+ PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr->smumgr,
+ true,
+ data->smu_features[GNLD_FW_CTF].smu_feature_bitmap),
+ "Attempt to Enable FW CTF feature Failed!",
+ return -1);
+ data->smu_features[GNLD_FW_CTF].enabled = true;
}
- PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr->smumgr,
- true,
- data->smu_features[GNLD_FW_CTF].smu_feature_bitmap),
- "Attempt to Enable FW CTF feature Failed!",
- return -1);
- data->smu_features[GNLD_FW_CTF].enabled = true;
+ val |= (1 << THM_THERMAL_INT_ENA__THERM_INTH_CLR__SHIFT);
+ val |= (1 << THM_THERMAL_INT_ENA__THERM_INTL_CLR__SHIFT);
+ val |= (1 << THM_THERMAL_INT_ENA__THERM_TRIGGER_CLR__SHIFT);
+
+ reg = soc15_get_register_offset(THM_HWID, 0, mmTHM_THERMAL_INT_ENA_BASE_IDX, mmTHM_THERMAL_INT_ENA);
+ cgs_write_register(hwmgr->device, reg, val);
+
return 0;
}
@@ -501,21 +512,27 @@ static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr)
* Disable thermal alerts on the RV770 thermal controller.
* @param hwmgr The address of the hardware manager.
*/
-static int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr)
+int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
+ uint32_t reg;
if (data->smu_features[GNLD_FW_CTF].supported) {
if (!data->smu_features[GNLD_FW_CTF].enabled)
printk("[Thermal_EnableAlert] FW CTF Already disabled!\n");
- }
- PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr->smumgr,
+
+ PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr->smumgr,
false,
data->smu_features[GNLD_FW_CTF].smu_feature_bitmap),
"Attempt to disable FW CTF feature Failed!",
return -1);
- data->smu_features[GNLD_FW_CTF].enabled = false;
+ data->smu_features[GNLD_FW_CTF].enabled = false;
+ }
+
+ reg = soc15_get_register_offset(THM_HWID, 0, mmTHM_THERMAL_INT_ENA_BASE_IDX, mmTHM_THERMAL_INT_ENA);
+ cgs_write_register(hwmgr->device, reg, 0);
+
return 0;
}
@@ -561,6 +578,11 @@ int tf_vega10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr,
advanceFanControlParameters.ulMinFanSCLKAcousticLimit);
table->FanTargetTemperature = hwmgr->thermal_controller.
advanceFanControlParameters.usTMax;
+
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetFanTemperatureTarget,
+ (uint32_t)table->FanTargetTemperature);
+
table->FanPwmMin = hwmgr->thermal_controller.
advanceFanControlParameters.usPWMMin * 255 / 100;
table->FanTargetGfxclk = (uint16_t)(hwmgr->thermal_controller.
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h
index 8036808ec421..776f3a2effc0 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h
@@ -78,6 +78,8 @@ extern int vega10_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr,
uint32_t *speed);
extern int vega10_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr);
extern uint32_t smu7_get_xclk(struct pp_hwmgr *hwmgr);
+extern int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr);
+int vega10_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr);
#endif