summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c')
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c93
1 files changed, 57 insertions, 36 deletions
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
index 97b3ad369046..baf251fe5d82 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
@@ -22,7 +22,6 @@
*/
#include <linux/delay.h>
-#include <linux/fb.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -329,12 +328,12 @@ static int vega20_set_features_platform_caps(struct pp_hwmgr *hwmgr)
return 0;
}
-static void vega20_init_dpm_defaults(struct pp_hwmgr *hwmgr)
+static int vega20_init_dpm_defaults(struct pp_hwmgr *hwmgr)
{
struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
struct amdgpu_device *adev = hwmgr->adev;
uint32_t top32, bottom32;
- int i;
+ int i, ret;
data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_id =
FEATURE_DPM_PREFETCHER_BIT;
@@ -405,10 +404,17 @@ static void vega20_init_dpm_defaults(struct pp_hwmgr *hwmgr)
}
/* Get the SN to turn into a Unique ID */
- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32);
+ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
+ if (ret)
+ return ret;
+
+ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32);
+ if (ret)
+ return ret;
adev->unique_id = ((uint64_t)bottom32 << 32) | top32;
+
+ return 0;
}
static int vega20_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr)
@@ -428,6 +434,7 @@ static int vega20_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
{
struct vega20_hwmgr *data;
struct amdgpu_device *adev = hwmgr->adev;
+ int result;
data = kzalloc(sizeof(struct vega20_hwmgr), GFP_KERNEL);
if (data == NULL)
@@ -453,8 +460,11 @@ static int vega20_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
vega20_set_features_platform_caps(hwmgr);
- vega20_init_dpm_defaults(hwmgr);
-
+ result = vega20_init_dpm_defaults(hwmgr);
+ if (result) {
+ pr_err("%s failed\n", __func__);
+ return result;
+ }
/* Parse pptable data read from VBIOS */
vega20_set_private_data_based_on_pptable(hwmgr);
@@ -1403,7 +1413,7 @@ static int vega20_od8_set_settings(
"Failed to export over drive table!",
return ret);
- switch(index) {
+ switch (index) {
case OD8_SETTING_GFXCLK_FMIN:
od_table.GfxclkFmin = (uint16_t)value;
break;
@@ -1555,26 +1565,23 @@ static int vega20_set_mclk_od(
return 0;
}
-static int vega20_populate_umdpstate_clocks(
- struct pp_hwmgr *hwmgr)
+static void vega20_populate_umdpstate_clocks(struct pp_hwmgr *hwmgr)
{
struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
struct vega20_single_dpm_table *gfx_table = &(data->dpm_table.gfx_table);
struct vega20_single_dpm_table *mem_table = &(data->dpm_table.mem_table);
- hwmgr->pstate_sclk = gfx_table->dpm_levels[0].value;
- hwmgr->pstate_mclk = mem_table->dpm_levels[0].value;
-
if (gfx_table->count > VEGA20_UMD_PSTATE_GFXCLK_LEVEL &&
mem_table->count > VEGA20_UMD_PSTATE_MCLK_LEVEL) {
hwmgr->pstate_sclk = gfx_table->dpm_levels[VEGA20_UMD_PSTATE_GFXCLK_LEVEL].value;
hwmgr->pstate_mclk = mem_table->dpm_levels[VEGA20_UMD_PSTATE_MCLK_LEVEL].value;
+ } else {
+ hwmgr->pstate_sclk = gfx_table->dpm_levels[0].value;
+ hwmgr->pstate_mclk = mem_table->dpm_levels[0].value;
}
- hwmgr->pstate_sclk = hwmgr->pstate_sclk * 100;
- hwmgr->pstate_mclk = hwmgr->pstate_mclk * 100;
-
- return 0;
+ hwmgr->pstate_sclk_peak = gfx_table->dpm_levels[gfx_table->count - 1].value;
+ hwmgr->pstate_mclk_peak = mem_table->dpm_levels[mem_table->count - 1].value;
}
static int vega20_get_max_sustainable_clock(struct pp_hwmgr *hwmgr,
@@ -1753,10 +1760,7 @@ static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
"[EnableDPMTasks] Failed to initialize odn settings!",
return result);
- result = vega20_populate_umdpstate_clocks(hwmgr);
- PP_ASSERT_WITH_CODE(!result,
- "[EnableDPMTasks] Failed to populate umdpstate clocks!",
- 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);
@@ -2136,7 +2140,7 @@ static int vega20_get_metrics_table(struct pp_hwmgr *hwmgr,
return ret;
}
-static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr,
+static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr, int idx,
uint32_t *query)
{
int ret = 0;
@@ -2147,10 +2151,17 @@ static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr,
return ret;
/* For the 40.46 release, they changed the value name */
- if (hwmgr->smu_version == 0x282e00)
- *query = metrics_table.AverageSocketPower << 8;
- else
+ switch (idx) {
+ case AMDGPU_PP_SENSOR_GPU_AVG_POWER:
+ if (hwmgr->smu_version == 0x282e00)
+ *query = metrics_table.AverageSocketPower << 8;
+ else
+ ret = -EOPNOTSUPP;
+ break;
+ case AMDGPU_PP_SENSOR_GPU_INPUT_POWER:
*query = metrics_table.CurrSocketPower << 8;
+ break;
+ }
return ret;
}
@@ -2260,9 +2271,10 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int idx,
*((uint32_t *)value) = data->vce_power_gated ? 0 : 1;
*size = 4;
break;
- case AMDGPU_PP_SENSOR_GPU_POWER:
+ case AMDGPU_PP_SENSOR_GPU_AVG_POWER:
+ case AMDGPU_PP_SENSOR_GPU_INPUT_POWER:
*size = 16;
- ret = vega20_get_gpu_power(hwmgr, (uint32_t *)value);
+ ret = vega20_get_gpu_power(hwmgr, idx, (uint32_t *)value);
break;
case AMDGPU_PP_SENSOR_VDDGFX:
val_vid = (RREG32_SOC15(SMUIO, 0, mmSMUSVI0_TEL_PLANE0) &
@@ -2367,7 +2379,7 @@ static int vega20_notify_smc_display_config_after_ps_adjustment(
dpm_table->dpm_state.hard_min_level = min_clocks.memoryClock / 100;
PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetHardMinByFreq,
- (PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level,
+ (PPCLK_UCLK << 16) | dpm_table->dpm_state.hard_min_level,
NULL)),
"[SetHardMinFreq] Set hard min uclk failed!",
return ret);
@@ -2961,7 +2973,8 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
data->od8_settings.od8_settings_array;
OverDriveTable_t *od_table =
&(data->smc_state_table.overdrive_table);
- int32_t input_index, input_clk, input_vol, i;
+ int32_t input_clk, input_vol, i;
+ uint32_t input_index;
int od8_id;
int ret;
@@ -3585,7 +3598,7 @@ static int vega20_set_uclk_to_highest_dpm_level(struct pp_hwmgr *hwmgr,
dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value;
PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetHardMinByFreq,
- (PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level,
+ (PPCLK_UCLK << 16) | dpm_table->dpm_state.hard_min_level,
NULL)),
"[SetUclkToHightestDpmLevel] Set hard min uclk failed!",
return ret);
@@ -3611,7 +3624,7 @@ static int vega20_set_fclk_to_highest_dpm_level(struct pp_hwmgr *hwmgr)
dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value;
PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetSoftMinByFreq,
- (PPCLK_FCLK << 16 ) | dpm_table->dpm_state.soft_min_level,
+ (PPCLK_FCLK << 16) | dpm_table->dpm_state.soft_min_level,
NULL)),
"[SetFclkToHightestDpmLevel] Set soft min fclk failed!",
return ret);
@@ -3733,8 +3746,8 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)
uint32_t i, latency;
disable_mclk_switching = ((1 < hwmgr->display_config->num_display) &&
- !hwmgr->display_config->multi_monitor_in_sync) ||
- vblank_too_short;
+ !hwmgr->display_config->multi_monitor_in_sync) ||
+ vblank_too_short;
latency = hwmgr->display_config->dce_tolerable_mclk_in_active_latency;
/* gfxclk */
@@ -4089,9 +4102,11 @@ static int vega20_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui
if (power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend);
- if (size == 0 && !data->is_custom_profile_set)
+
+ if (size != 10 && size != 0)
return -EINVAL;
- if (size < 10 && size != 0)
+
+ if (size == 0 && !data->is_custom_profile_set)
return -EINVAL;
result = vega20_get_activity_monitor_coeff(hwmgr,
@@ -4153,6 +4168,8 @@ static int vega20_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui
activity_monitor.Fclk_PD_Data_error_coeff = input[8];
activity_monitor.Fclk_PD_Data_error_rate_coeff = input[9];
break;
+ default:
+ return -EINVAL;
}
result = vega20_set_activity_monitor_coeff(hwmgr,
@@ -4212,6 +4229,8 @@ static int vega20_notify_cac_buffer_info(struct pp_hwmgr *hwmgr,
static int vega20_get_thermal_temperature_range(struct pp_hwmgr *hwmgr,
struct PP_TemperatureRange *thermal_data)
{
+ struct phm_ppt_v3_information *pptable_information =
+ (struct phm_ppt_v3_information *)hwmgr->pptable;
struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend);
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
@@ -4230,6 +4249,8 @@ static int vega20_get_thermal_temperature_range(struct pp_hwmgr *hwmgr,
PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
thermal_data->mem_emergency_max = (pp_table->ThbmLimit + CTF_OFFSET_HBM)*
PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+ thermal_data->sw_ctf_threshold = pptable_information->us_software_shutdown_temp *
+ PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
return 0;
}
@@ -4416,7 +4437,7 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
.notify_cac_buffer_info = vega20_notify_cac_buffer_info,
.enable_mgpu_fan_boost = vega20_enable_mgpu_fan_boost,
/* BACO related */
- .get_asic_baco_capability = vega20_baco_get_capability,
+ .get_bamaco_support = vega20_get_bamaco_support,
.get_asic_baco_state = vega20_baco_get_state,
.set_asic_baco_state = vega20_baco_set_state,
.set_mp1_state = vega20_set_mp1_state,