summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c')
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c224
1 files changed, 156 insertions, 68 deletions
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
index 0eaf86b5e698..1ba42b69ce74 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
@@ -80,10 +80,10 @@ static struct cmn2asic_msg_mapping navi10_message_map[SMU_MSG_MAX_COUNT] = {
MSG_MAP(SetAllowedFeaturesMaskHigh, PPSMC_MSG_SetAllowedFeaturesMaskHigh, 0),
MSG_MAP(EnableAllSmuFeatures, PPSMC_MSG_EnableAllSmuFeatures, 0),
MSG_MAP(DisableAllSmuFeatures, PPSMC_MSG_DisableAllSmuFeatures, 0),
- MSG_MAP(EnableSmuFeaturesLow, PPSMC_MSG_EnableSmuFeaturesLow, 1),
- MSG_MAP(EnableSmuFeaturesHigh, PPSMC_MSG_EnableSmuFeaturesHigh, 1),
- MSG_MAP(DisableSmuFeaturesLow, PPSMC_MSG_DisableSmuFeaturesLow, 1),
- MSG_MAP(DisableSmuFeaturesHigh, PPSMC_MSG_DisableSmuFeaturesHigh, 1),
+ MSG_MAP(EnableSmuFeaturesLow, PPSMC_MSG_EnableSmuFeaturesLow, 0),
+ MSG_MAP(EnableSmuFeaturesHigh, PPSMC_MSG_EnableSmuFeaturesHigh, 0),
+ MSG_MAP(DisableSmuFeaturesLow, PPSMC_MSG_DisableSmuFeaturesLow, 0),
+ MSG_MAP(DisableSmuFeaturesHigh, PPSMC_MSG_DisableSmuFeaturesHigh, 0),
MSG_MAP(GetEnabledSmuFeaturesLow, PPSMC_MSG_GetEnabledSmuFeaturesLow, 1),
MSG_MAP(GetEnabledSmuFeaturesHigh, PPSMC_MSG_GetEnabledSmuFeaturesHigh, 1),
MSG_MAP(SetWorkloadMask, PPSMC_MSG_SetWorkloadMask, 1),
@@ -238,6 +238,28 @@ static struct cmn2asic_mapping navi10_workload_map[PP_SMC_POWER_PROFILE_COUNT] =
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT),
};
+static const uint8_t navi1x_throttler_map[] = {
+ [THROTTLER_TEMP_EDGE_BIT] = (SMU_THROTTLER_TEMP_EDGE_BIT),
+ [THROTTLER_TEMP_HOTSPOT_BIT] = (SMU_THROTTLER_TEMP_HOTSPOT_BIT),
+ [THROTTLER_TEMP_MEM_BIT] = (SMU_THROTTLER_TEMP_MEM_BIT),
+ [THROTTLER_TEMP_VR_GFX_BIT] = (SMU_THROTTLER_TEMP_VR_GFX_BIT),
+ [THROTTLER_TEMP_VR_MEM0_BIT] = (SMU_THROTTLER_TEMP_VR_MEM0_BIT),
+ [THROTTLER_TEMP_VR_MEM1_BIT] = (SMU_THROTTLER_TEMP_VR_MEM1_BIT),
+ [THROTTLER_TEMP_VR_SOC_BIT] = (SMU_THROTTLER_TEMP_VR_SOC_BIT),
+ [THROTTLER_TEMP_LIQUID0_BIT] = (SMU_THROTTLER_TEMP_LIQUID0_BIT),
+ [THROTTLER_TEMP_LIQUID1_BIT] = (SMU_THROTTLER_TEMP_LIQUID1_BIT),
+ [THROTTLER_TDC_GFX_BIT] = (SMU_THROTTLER_TDC_GFX_BIT),
+ [THROTTLER_TDC_SOC_BIT] = (SMU_THROTTLER_TDC_SOC_BIT),
+ [THROTTLER_PPT0_BIT] = (SMU_THROTTLER_PPT0_BIT),
+ [THROTTLER_PPT1_BIT] = (SMU_THROTTLER_PPT1_BIT),
+ [THROTTLER_PPT2_BIT] = (SMU_THROTTLER_PPT2_BIT),
+ [THROTTLER_PPT3_BIT] = (SMU_THROTTLER_PPT3_BIT),
+ [THROTTLER_FIT_BIT] = (SMU_THROTTLER_FIT_BIT),
+ [THROTTLER_PPM_BIT] = (SMU_THROTTLER_PPM_BIT),
+ [THROTTLER_APCC_BIT] = (SMU_THROTTLER_APCC_BIT),
+};
+
+
static bool is_asic_secure(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
@@ -340,19 +362,34 @@ navi10_get_allowed_feature_mask(struct smu_context *smu,
return 0;
}
-static int navi10_check_powerplay_table(struct smu_context *smu)
+static void navi10_check_bxco_support(struct smu_context *smu)
{
struct smu_table_context *table_context = &smu->smu_table;
struct smu_11_0_powerplay_table *powerplay_table =
table_context->power_play_table;
struct smu_baco_context *smu_baco = &smu->smu_baco;
+ struct amdgpu_device *adev = smu->adev;
+ uint32_t val;
+
+ if (powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_BACO ||
+ powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_MACO) {
+ val = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP0);
+ smu_baco->platform_support =
+ (val & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK) ? true :
+ false;
+ }
+}
+
+static int navi10_check_powerplay_table(struct smu_context *smu)
+{
+ struct smu_table_context *table_context = &smu->smu_table;
+ struct smu_11_0_powerplay_table *powerplay_table =
+ table_context->power_play_table;
if (powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_HARDWAREDC)
smu->dc_controlled_by_gpio = true;
- if (powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_BACO ||
- powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_MACO)
- smu_baco->platform_support = true;
+ navi10_check_bxco_support(smu);
table_context->thermal_controller_type =
powerplay_table->thermal_controller_type;
@@ -431,30 +468,6 @@ static int navi10_store_powerplay_table(struct smu_context *smu)
return 0;
}
-static int navi10_set_mp1_state(struct smu_context *smu,
- enum pp_mp1_state mp1_state)
-{
- struct amdgpu_device *adev = smu->adev;
- uint32_t mp1_fw_flags;
- int ret = 0;
-
- ret = smu_cmn_set_mp1_state(smu, mp1_state);
- if (ret)
- return ret;
-
- if (mp1_state == PP_MP1_STATE_UNLOAD) {
- mp1_fw_flags = RREG32_PCIE(MP1_Public |
- (smnMP1_FIRMWARE_FLAGS & 0xffffffff));
-
- mp1_fw_flags &= ~MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK;
-
- WREG32_PCIE(MP1_Public |
- (smnMP1_FIRMWARE_FLAGS & 0xffffffff), mp1_fw_flags);
- }
-
- return 0;
-}
-
static int navi10_setup_pptable(struct smu_context *smu)
{
int ret = 0;
@@ -505,7 +518,7 @@ static int navi10_tables_init(struct smu_context *smu)
goto err0_out;
smu_table->metrics_time = 0;
- smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_1);
+ smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_3);
smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
if (!smu_table->gpu_metrics_table)
goto err1_out;
@@ -1273,6 +1286,8 @@ static int navi10_print_clk_levels(struct smu_context *smu,
case SMU_MCLK:
case SMU_UCLK:
case SMU_FCLK:
+ case SMU_VCLK:
+ case SMU_DCLK:
case SMU_DCEFCLK:
ret = navi10_get_current_clk_freq_by_table(smu, clk_type, &cur_value);
if (ret)
@@ -2121,7 +2136,10 @@ static int navi10_display_disable_memory_clock_switch(struct smu_context *smu,
return ret;
}
-static int navi10_get_power_limit(struct smu_context *smu)
+static int navi10_get_power_limit(struct smu_context *smu,
+ uint32_t *current_power_limit,
+ uint32_t *default_power_limit,
+ uint32_t *max_power_limit)
{
struct smu_11_0_powerplay_table *powerplay_table =
(struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
@@ -2138,18 +2156,25 @@ static int navi10_get_power_limit(struct smu_context *smu)
power_limit =
pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
}
- smu->current_power_limit = smu->default_power_limit = power_limit;
- if (smu->od_enabled &&
- navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) {
- od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
+ if (current_power_limit)
+ *current_power_limit = power_limit;
+ if (default_power_limit)
+ *default_power_limit = power_limit;
+
+ if (max_power_limit) {
+ if (smu->od_enabled &&
+ navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) {
+ od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
+
+ dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
- dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
+ power_limit *= (100 + od_percent);
+ power_limit /= 100;
+ }
- power_limit *= (100 + od_percent);
- power_limit /= 100;
+ *max_power_limit = power_limit;
}
- smu->max_power_limit = power_limit;
return 0;
}
@@ -2240,16 +2265,27 @@ static int navi10_overdrive_get_gfx_clk_base_voltage(struct smu_context *smu,
return 0;
}
-static bool navi10_is_baco_supported(struct smu_context *smu)
+static int navi10_baco_enter(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
- uint32_t val;
- if (amdgpu_sriov_vf(adev) || (!smu_v11_0_baco_is_support(smu)))
- return false;
+ if (adev->in_runpm)
+ return smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_BACO);
+ else
+ return smu_v11_0_baco_enter(smu);
+}
+
+static int navi10_baco_exit(struct smu_context *smu)
+{
+ struct amdgpu_device *adev = smu->adev;
- val = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP0);
- return (val & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK) ? true : false;
+ if (adev->in_runpm) {
+ /* Wait for PMFW handling for the Dstate change */
+ msleep(10);
+ return smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
+ } else {
+ return smu_v11_0_baco_exit(smu);
+ }
}
static int navi10_set_default_od_settings(struct smu_context *smu)
@@ -2627,8 +2663,8 @@ static ssize_t navi10_get_legacy_gpu_metrics(struct smu_context *smu,
void **table)
{
struct smu_table_context *smu_table = &smu->smu_table;
- struct gpu_metrics_v1_1 *gpu_metrics =
- (struct gpu_metrics_v1_1 *)smu_table->gpu_metrics_table;
+ struct gpu_metrics_v1_3 *gpu_metrics =
+ (struct gpu_metrics_v1_3 *)smu_table->gpu_metrics_table;
SmuMetrics_legacy_t metrics;
int ret = 0;
@@ -2646,7 +2682,7 @@ static ssize_t navi10_get_legacy_gpu_metrics(struct smu_context *smu,
mutex_unlock(&smu->metrics_lock);
- smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 1);
+ smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3);
gpu_metrics->temperature_edge = metrics.TemperatureEdge;
gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot;
@@ -2671,6 +2707,9 @@ static ssize_t navi10_get_legacy_gpu_metrics(struct smu_context *smu,
gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK];
gpu_metrics->throttle_status = metrics.ThrottlerStatus;
+ gpu_metrics->indep_throttle_status =
+ smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
+ navi1x_throttler_map);
gpu_metrics->current_fan_speed = metrics.CurrFanSpeed;
@@ -2681,17 +2720,27 @@ static ssize_t navi10_get_legacy_gpu_metrics(struct smu_context *smu,
gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
+ if (metrics.CurrGfxVoltageOffset)
+ gpu_metrics->voltage_gfx =
+ (155000 - 625 * metrics.CurrGfxVoltageOffset) / 100;
+ if (metrics.CurrMemVidOffset)
+ gpu_metrics->voltage_mem =
+ (155000 - 625 * metrics.CurrMemVidOffset) / 100;
+ if (metrics.CurrSocVoltageOffset)
+ gpu_metrics->voltage_soc =
+ (155000 - 625 * metrics.CurrSocVoltageOffset) / 100;
+
*table = (void *)gpu_metrics;
- return sizeof(struct gpu_metrics_v1_1);
+ return sizeof(struct gpu_metrics_v1_3);
}
static ssize_t navi10_get_gpu_metrics(struct smu_context *smu,
void **table)
{
struct smu_table_context *smu_table = &smu->smu_table;
- struct gpu_metrics_v1_1 *gpu_metrics =
- (struct gpu_metrics_v1_1 *)smu_table->gpu_metrics_table;
+ struct gpu_metrics_v1_3 *gpu_metrics =
+ (struct gpu_metrics_v1_3 *)smu_table->gpu_metrics_table;
SmuMetrics_t metrics;
int ret = 0;
@@ -2709,7 +2758,7 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu,
mutex_unlock(&smu->metrics_lock);
- smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 1);
+ smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3);
gpu_metrics->temperature_edge = metrics.TemperatureEdge;
gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot;
@@ -2738,6 +2787,9 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK];
gpu_metrics->throttle_status = metrics.ThrottlerStatus;
+ gpu_metrics->indep_throttle_status =
+ smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
+ navi1x_throttler_map);
gpu_metrics->current_fan_speed = metrics.CurrFanSpeed;
@@ -2746,17 +2798,27 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
+ if (metrics.CurrGfxVoltageOffset)
+ gpu_metrics->voltage_gfx =
+ (155000 - 625 * metrics.CurrGfxVoltageOffset) / 100;
+ if (metrics.CurrMemVidOffset)
+ gpu_metrics->voltage_mem =
+ (155000 - 625 * metrics.CurrMemVidOffset) / 100;
+ if (metrics.CurrSocVoltageOffset)
+ gpu_metrics->voltage_soc =
+ (155000 - 625 * metrics.CurrSocVoltageOffset) / 100;
+
*table = (void *)gpu_metrics;
- return sizeof(struct gpu_metrics_v1_1);
+ return sizeof(struct gpu_metrics_v1_3);
}
static ssize_t navi12_get_legacy_gpu_metrics(struct smu_context *smu,
void **table)
{
struct smu_table_context *smu_table = &smu->smu_table;
- struct gpu_metrics_v1_1 *gpu_metrics =
- (struct gpu_metrics_v1_1 *)smu_table->gpu_metrics_table;
+ struct gpu_metrics_v1_3 *gpu_metrics =
+ (struct gpu_metrics_v1_3 *)smu_table->gpu_metrics_table;
SmuMetrics_NV12_legacy_t metrics;
int ret = 0;
@@ -2774,7 +2836,7 @@ static ssize_t navi12_get_legacy_gpu_metrics(struct smu_context *smu,
mutex_unlock(&smu->metrics_lock);
- smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 1);
+ smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3);
gpu_metrics->temperature_edge = metrics.TemperatureEdge;
gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot;
@@ -2804,6 +2866,9 @@ static ssize_t navi12_get_legacy_gpu_metrics(struct smu_context *smu,
gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK];
gpu_metrics->throttle_status = metrics.ThrottlerStatus;
+ gpu_metrics->indep_throttle_status =
+ smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
+ navi1x_throttler_map);
gpu_metrics->current_fan_speed = metrics.CurrFanSpeed;
@@ -2814,17 +2879,27 @@ static ssize_t navi12_get_legacy_gpu_metrics(struct smu_context *smu,
gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
+ if (metrics.CurrGfxVoltageOffset)
+ gpu_metrics->voltage_gfx =
+ (155000 - 625 * metrics.CurrGfxVoltageOffset) / 100;
+ if (metrics.CurrMemVidOffset)
+ gpu_metrics->voltage_mem =
+ (155000 - 625 * metrics.CurrMemVidOffset) / 100;
+ if (metrics.CurrSocVoltageOffset)
+ gpu_metrics->voltage_soc =
+ (155000 - 625 * metrics.CurrSocVoltageOffset) / 100;
+
*table = (void *)gpu_metrics;
- return sizeof(struct gpu_metrics_v1_1);
+ return sizeof(struct gpu_metrics_v1_3);
}
static ssize_t navi12_get_gpu_metrics(struct smu_context *smu,
void **table)
{
struct smu_table_context *smu_table = &smu->smu_table;
- struct gpu_metrics_v1_1 *gpu_metrics =
- (struct gpu_metrics_v1_1 *)smu_table->gpu_metrics_table;
+ struct gpu_metrics_v1_3 *gpu_metrics =
+ (struct gpu_metrics_v1_3 *)smu_table->gpu_metrics_table;
SmuMetrics_NV12_t metrics;
int ret = 0;
@@ -2842,7 +2917,7 @@ static ssize_t navi12_get_gpu_metrics(struct smu_context *smu,
mutex_unlock(&smu->metrics_lock);
- smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 1);
+ smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3);
gpu_metrics->temperature_edge = metrics.TemperatureEdge;
gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot;
@@ -2876,6 +2951,9 @@ static ssize_t navi12_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK];
gpu_metrics->throttle_status = metrics.ThrottlerStatus;
+ gpu_metrics->indep_throttle_status =
+ smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
+ navi1x_throttler_map);
gpu_metrics->current_fan_speed = metrics.CurrFanSpeed;
@@ -2884,9 +2962,19 @@ static ssize_t navi12_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
+ if (metrics.CurrGfxVoltageOffset)
+ gpu_metrics->voltage_gfx =
+ (155000 - 625 * metrics.CurrGfxVoltageOffset) / 100;
+ if (metrics.CurrMemVidOffset)
+ gpu_metrics->voltage_mem =
+ (155000 - 625 * metrics.CurrMemVidOffset) / 100;
+ if (metrics.CurrSocVoltageOffset)
+ gpu_metrics->voltage_soc =
+ (155000 - 625 * metrics.CurrSocVoltageOffset) / 100;
+
*table = (void *)gpu_metrics;
- return sizeof(struct gpu_metrics_v1_1);
+ return sizeof(struct gpu_metrics_v1_3);
}
static ssize_t navi1x_get_gpu_metrics(struct smu_context *smu,
@@ -3047,11 +3135,11 @@ static const struct pptable_funcs navi10_ppt_funcs = {
.register_irq_handler = smu_v11_0_register_irq_handler,
.set_azalia_d3_pme = smu_v11_0_set_azalia_d3_pme,
.get_max_sustainable_clocks_by_dc = smu_v11_0_get_max_sustainable_clocks_by_dc,
- .baco_is_support= navi10_is_baco_supported,
+ .baco_is_support = smu_v11_0_baco_is_support,
.baco_get_state = smu_v11_0_baco_get_state,
.baco_set_state = smu_v11_0_baco_set_state,
- .baco_enter = smu_v11_0_baco_enter,
- .baco_exit = smu_v11_0_baco_exit,
+ .baco_enter = navi10_baco_enter,
+ .baco_exit = navi10_baco_exit,
.get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq,
.set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
.set_default_od_settings = navi10_set_default_od_settings,
@@ -3067,7 +3155,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
.get_fan_parameters = navi10_get_fan_parameters,
.post_init = navi10_post_smu_init,
.interrupt_work = smu_v11_0_interrupt_work,
- .set_mp1_state = navi10_set_mp1_state,
+ .set_mp1_state = smu_cmn_set_mp1_state,
};
void navi10_set_ppt_funcs(struct smu_context *smu)