summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c')
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c160
1 files changed, 72 insertions, 88 deletions
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index 124287cbbff8..8b7403ba89d7 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -96,6 +96,14 @@
*/
#define SUPPORT_ECCTABLE_SMU_13_0_10_VERSION 0x00502200
+#define PP_OD_FEATURE_GFXCLK_FMIN 0
+#define PP_OD_FEATURE_GFXCLK_FMAX 1
+#define PP_OD_FEATURE_UCLK_FMIN 2
+#define PP_OD_FEATURE_UCLK_FMAX 3
+#define PP_OD_FEATURE_GFX_VF_CURVE 4
+
+#define LINK_SPEED_MAX 3
+
static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] = {
MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1),
MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1),
@@ -332,10 +340,13 @@ static int smu_v13_0_0_check_powerplay_table(struct smu_context *smu)
table_context->power_play_table;
struct smu_baco_context *smu_baco = &smu->smu_baco;
PPTable_t *pptable = smu->smu_table.driver_pptable;
+#if 0
+ PPTable_t *pptable = smu->smu_table.driver_pptable;
const OverDriveLimits_t * const overdrive_upperlimits =
&pptable->SkuTable.OverDriveLimitsBasicMax;
const OverDriveLimits_t * const overdrive_lowerlimits =
&pptable->SkuTable.OverDriveLimitsMin;
+#endif
if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_HARDWAREDC)
smu->dc_controlled_by_gpio = true;
@@ -347,18 +358,30 @@ static int smu_v13_0_0_check_powerplay_table(struct smu_context *smu)
if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_MACO)
smu_baco->maco_support = true;
+ /*
+ * We are in the transition to a new OD mechanism.
+ * Disable the OD feature support for SMU13 temporarily.
+ * TODO: get this reverted when new OD mechanism online
+ */
+#if 0
if (!overdrive_lowerlimits->FeatureCtrlMask ||
!overdrive_upperlimits->FeatureCtrlMask)
smu->od_enabled = false;
- table_context->thermal_controller_type =
- powerplay_table->thermal_controller_type;
-
/*
* Instead of having its own buffer space and get overdrive_table copied,
* smu->od_settings just points to the actual overdrive_table
*/
smu->od_settings = &powerplay_table->overdrive_table;
+#else
+ smu->od_enabled = false;
+#endif
+
+ table_context->thermal_controller_type =
+ powerplay_table->thermal_controller_type;
+
+ smu->adev->pm.no_fan =
+ !(pptable->SkuTable.FeaturesToRun[0] & (1 << FEATURE_FAN_CONTROL_BIT));
return 0;
}
@@ -932,7 +955,7 @@ static int smu_v13_0_0_read_sensor(struct smu_context *smu,
(uint32_t *)data);
*size = 4;
break;
- case AMDGPU_PP_SENSOR_GPU_POWER:
+ case AMDGPU_PP_SENSOR_GPU_AVG_POWER:
ret = smu_v13_0_0_get_smu_metrics_data(smu,
METRICS_AVERAGE_SOCKETPOWER,
(uint32_t *)data);
@@ -976,6 +999,7 @@ static int smu_v13_0_0_read_sensor(struct smu_context *smu,
(uint32_t *)data);
*size = 4;
break;
+ case AMDGPU_PP_SENSOR_GPU_INPUT_POWER:
default:
ret = -EOPNOTSUPP;
break;
@@ -1043,7 +1067,6 @@ static bool smu_v13_0_0_is_od_feature_supported(struct smu_context *smu,
static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu,
int od_feature_bit,
- bool lower_boundary,
int32_t *min,
int32_t *max)
{
@@ -1055,29 +1078,28 @@ static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu,
int32_t od_min_setting, od_max_setting;
switch (od_feature_bit) {
- case PP_OD_FEATURE_GFXCLK_BIT:
- if (lower_boundary) {
- od_min_setting = overdrive_lowerlimits->GfxclkFmin;
- od_max_setting = overdrive_upperlimits->GfxclkFmin;
- } else {
- od_min_setting = overdrive_lowerlimits->GfxclkFmax;
- od_max_setting = overdrive_upperlimits->GfxclkFmax;
- }
+ case PP_OD_FEATURE_GFXCLK_FMIN:
+ od_min_setting = overdrive_lowerlimits->GfxclkFmin;
+ od_max_setting = overdrive_upperlimits->GfxclkFmin;
break;
- case PP_OD_FEATURE_UCLK_BIT:
- if (lower_boundary) {
- od_min_setting = overdrive_lowerlimits->UclkFmin;
- od_max_setting = overdrive_upperlimits->UclkFmin;
- } else {
- od_min_setting = overdrive_lowerlimits->UclkFmax;
- od_max_setting = overdrive_upperlimits->UclkFmax;
- }
+ case PP_OD_FEATURE_GFXCLK_FMAX:
+ od_min_setting = overdrive_lowerlimits->GfxclkFmax;
+ od_max_setting = overdrive_upperlimits->GfxclkFmax;
break;
- case PP_OD_FEATURE_GFX_VF_CURVE_BIT:
+ case PP_OD_FEATURE_UCLK_FMIN:
+ od_min_setting = overdrive_lowerlimits->UclkFmin;
+ od_max_setting = overdrive_upperlimits->UclkFmin;
+ break;
+ case PP_OD_FEATURE_UCLK_FMAX:
+ od_min_setting = overdrive_lowerlimits->UclkFmax;
+ od_max_setting = overdrive_upperlimits->UclkFmax;
+ break;
+ case PP_OD_FEATURE_GFX_VF_CURVE:
od_min_setting = overdrive_lowerlimits->VoltageOffsetPerZoneBoundary;
od_max_setting = overdrive_upperlimits->VoltageOffsetPerZoneBoundary;
break;
default:
+ od_min_setting = od_max_setting = INT_MAX;
break;
}
@@ -1140,7 +1162,6 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
(OverDriveTableExternal_t *)smu->smu_table.overdrive_table;
struct smu_13_0_dpm_table *single_dpm_table;
struct smu_13_0_pcie_table *pcie_table;
- const int link_width[] = {0, 1, 2, 4, 8, 12, 16};
uint32_t gen_speed, lane_width;
int i, curr_freq, size = 0;
int32_t min_value, max_value;
@@ -1256,7 +1277,7 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
(pcie_table->pcie_lane[i] == 6) ? "x16" : "",
pcie_table->clk_freq[i],
(gen_speed == DECODE_GEN_SPEED(pcie_table->pcie_gen[i])) &&
- (lane_width == DECODE_LANE_WIDTH(link_width[pcie_table->pcie_lane[i]])) ?
+ (lane_width == DECODE_LANE_WIDTH(pcie_table->pcie_lane[i])) ?
"*" : "");
break;
@@ -1304,13 +1325,11 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT)) {
smu_v13_0_0_get_od_setting_limits(smu,
- PP_OD_FEATURE_GFXCLK_BIT,
- true,
+ PP_OD_FEATURE_GFXCLK_FMIN,
&min_value,
NULL);
smu_v13_0_0_get_od_setting_limits(smu,
- PP_OD_FEATURE_GFXCLK_BIT,
- false,
+ PP_OD_FEATURE_GFXCLK_FMAX,
NULL,
&max_value);
size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n",
@@ -1319,13 +1338,11 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT)) {
smu_v13_0_0_get_od_setting_limits(smu,
- PP_OD_FEATURE_UCLK_BIT,
- true,
+ PP_OD_FEATURE_UCLK_FMIN,
&min_value,
NULL);
smu_v13_0_0_get_od_setting_limits(smu,
- PP_OD_FEATURE_UCLK_BIT,
- false,
+ PP_OD_FEATURE_UCLK_FMAX,
NULL,
&max_value);
size += sysfs_emit_at(buf, size, "MCLK: %7uMhz %10uMhz\n",
@@ -1334,8 +1351,7 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) {
smu_v13_0_0_get_od_setting_limits(smu,
- PP_OD_FEATURE_GFX_VF_CURVE_BIT,
- true,
+ PP_OD_FEATURE_GFX_VF_CURVE,
&min_value,
&max_value);
size += sysfs_emit_at(buf, size, "VDDC_CURVE: %7dmv %10dmv\n",
@@ -1359,7 +1375,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
OverDriveTableExternal_t *od_table =
(OverDriveTableExternal_t *)table_context->overdrive_table;
struct amdgpu_device *adev = smu->adev;
- uint32_t offset_of_featurectrlmask;
+ uint32_t offset_of_voltageoffset;
int32_t minimum, maximum;
uint32_t feature_ctrlmask;
int i, ret = 0;
@@ -1380,8 +1396,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
switch (input[i]) {
case 0:
smu_v13_0_0_get_od_setting_limits(smu,
- PP_OD_FEATURE_GFXCLK_BIT,
- true,
+ PP_OD_FEATURE_GFXCLK_FMIN,
&minimum,
&maximum);
if (input[i + 1] < minimum ||
@@ -1397,8 +1412,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
case 1:
smu_v13_0_0_get_od_setting_limits(smu,
- PP_OD_FEATURE_GFXCLK_BIT,
- false,
+ PP_OD_FEATURE_GFXCLK_FMAX,
&minimum,
&maximum);
if (input[i + 1] < minimum ||
@@ -1443,8 +1457,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
switch (input[i]) {
case 0:
smu_v13_0_0_get_od_setting_limits(smu,
- PP_OD_FEATURE_UCLK_BIT,
- true,
+ PP_OD_FEATURE_UCLK_FMIN,
&minimum,
&maximum);
if (input[i + 1] < minimum ||
@@ -1460,8 +1473,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
case 1:
smu_v13_0_0_get_od_setting_limits(smu,
- PP_OD_FEATURE_UCLK_BIT,
- false,
+ PP_OD_FEATURE_UCLK_FMAX,
&minimum,
&maximum);
if (input[i + 1] < minimum ||
@@ -1502,8 +1514,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
return -EINVAL;
smu_v13_0_0_get_od_setting_limits(smu,
- PP_OD_FEATURE_GFX_VF_CURVE_BIT,
- true,
+ PP_OD_FEATURE_GFX_VF_CURVE,
&minimum,
&maximum);
if (input[1] < minimum ||
@@ -1533,10 +1544,10 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
* It does not contain actual informations about user's custom
* settings. Thus we do not cache it.
*/
- offset_of_featurectrlmask = offsetof(OverDriveTable_t, FeatureCtrlMask);
- if (memcmp((u8 *)od_table + offset_of_featurectrlmask,
- table_context->user_overdrive_table + offset_of_featurectrlmask,
- sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask)) {
+ offset_of_voltageoffset = offsetof(OverDriveTable_t, VoltageOffsetPerZoneBoundary);
+ if (memcmp((u8 *)od_table + offset_of_voltageoffset,
+ table_context->user_overdrive_table + offset_of_voltageoffset,
+ sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset)) {
smu_v13_0_0_dump_od_table(smu, od_table);
ret = smu_v13_0_0_upload_overdrive_table(smu, od_table);
@@ -1546,9 +1557,9 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
}
od_table->OverDriveTable.FeatureCtrlMask = 0;
- memcpy(table_context->user_overdrive_table + offset_of_featurectrlmask,
- (u8 *)od_table + offset_of_featurectrlmask,
- sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask);
+ memcpy(table_context->user_overdrive_table + offset_of_voltageoffset,
+ (u8 *)od_table + offset_of_voltageoffset,
+ sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset);
if (!memcmp(table_context->user_overdrive_table,
table_context->boot_overdrive_table,
@@ -1645,37 +1656,6 @@ static int smu_v13_0_0_force_clk_levels(struct smu_context *smu,
return ret;
}
-static int smu_v13_0_0_update_pcie_parameters(struct smu_context *smu,
- uint32_t pcie_gen_cap,
- uint32_t pcie_width_cap)
-{
- struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
- struct smu_13_0_pcie_table *pcie_table =
- &dpm_context->dpm_tables.pcie_table;
- uint32_t smu_pcie_arg;
- int ret, i;
-
- for (i = 0; i < pcie_table->num_of_link_levels; i++) {
- if (pcie_table->pcie_gen[i] > pcie_gen_cap)
- pcie_table->pcie_gen[i] = pcie_gen_cap;
- if (pcie_table->pcie_lane[i] > pcie_width_cap)
- pcie_table->pcie_lane[i] = pcie_width_cap;
-
- smu_pcie_arg = i << 16;
- smu_pcie_arg |= pcie_table->pcie_gen[i] << 8;
- smu_pcie_arg |= pcie_table->pcie_lane[i];
-
- ret = smu_cmn_send_smc_msg_with_param(smu,
- SMU_MSG_OverridePcieParameters,
- smu_pcie_arg,
- NULL);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
static const struct smu_temperature_range smu13_thermal_policy[] = {
{-273150, 99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000},
{ 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000},
@@ -1765,7 +1745,7 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->average_vclk1_frequency = metrics->AverageVclk1Frequency;
gpu_metrics->average_dclk1_frequency = metrics->AverageDclk1Frequency;
- gpu_metrics->current_gfxclk = metrics->CurrClock[PPCLK_GFXCLK];
+ gpu_metrics->current_gfxclk = gpu_metrics->average_gfxclk_frequency;
gpu_metrics->current_socclk = metrics->CurrClock[PPCLK_SOCCLK];
gpu_metrics->current_uclk = metrics->CurrClock[PPCLK_UCLK];
gpu_metrics->current_vclk0 = metrics->CurrClock[PPCLK_VCLK_0];
@@ -1782,7 +1762,10 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->current_fan_speed = metrics->AvgFanRpm;
gpu_metrics->pcie_link_width = metrics->PcieWidth;
- gpu_metrics->pcie_link_speed = metrics->PcieRate;
+ if ((metrics->PcieRate - 1) > LINK_SPEED_MAX)
+ gpu_metrics->pcie_link_speed = pcie_gen_to_speed(1);
+ else
+ gpu_metrics->pcie_link_speed = pcie_gen_to_speed(metrics->PcieRate);
gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
@@ -2228,7 +2211,8 @@ static int smu_v13_0_0_baco_enter(struct smu_context *smu)
if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev))
return smu_v13_0_baco_set_armd3_sequence(smu,
- smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO);
+ (smu_baco->maco_support && amdgpu_runtime_pm != 1) ?
+ BACO_SEQ_BAMACO : BACO_SEQ_BACO);
else
return smu_v13_0_baco_enter(smu);
}
@@ -2320,7 +2304,6 @@ static int smu_v13_0_0_i2c_xfer(struct i2c_adapter *i2c_adap,
}
mutex_lock(&adev->pm.mutex);
r = smu_cmn_update_table(smu, SMU_TABLE_I2C_COMMANDS, 0, req, true);
- mutex_unlock(&adev->pm.mutex);
if (r)
goto fail;
@@ -2337,6 +2320,7 @@ static int smu_v13_0_0_i2c_xfer(struct i2c_adapter *i2c_adap,
}
r = num_msgs;
fail:
+ mutex_unlock(&adev->pm.mutex);
kfree(req);
return r;
}
@@ -2654,7 +2638,7 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
.feature_is_enabled = smu_cmn_feature_is_enabled,
.print_clk_levels = smu_v13_0_0_print_clk_levels,
.force_clk_levels = smu_v13_0_0_force_clk_levels,
- .update_pcie_parameters = smu_v13_0_0_update_pcie_parameters,
+ .update_pcie_parameters = smu_v13_0_update_pcie_parameters,
.get_thermal_temperature_range = smu_v13_0_0_get_thermal_temperature_range,
.register_irq_handler = smu_v13_0_register_irq_handler,
.enable_thermal_alert = smu_v13_0_enable_thermal_alert,