]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/pm: update the power cap setting
authorKenneth Feng <kenneth.feng@amd.com>
Fri, 19 Jan 2024 08:12:00 +0000 (16:12 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 25 Jan 2024 20:42:53 +0000 (15:42 -0500)
update the power cap setting for smu_v13.0.0/smu_v13.0.7

Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2356
Signed-off-by: Kenneth Feng <kenneth.feng@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c

index a9b25faa63e468d0069ea08acfd7b90b1b36f056..4fdf34fffa9a57f53ad55418e957e36282ac98b9 100644 (file)
@@ -2357,6 +2357,7 @@ static int smu_v13_0_0_get_power_limit(struct smu_context *smu,
        PPTable_t *pptable = table_context->driver_pptable;
        SkuTable_t *skutable = &pptable->SkuTable;
        uint32_t power_limit, od_percent_upper, od_percent_lower;
+       uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
 
        if (smu_v13_0_get_current_power_limit(smu, &power_limit))
                power_limit = smu->adev->pm.ac_power ?
@@ -2380,7 +2381,7 @@ static int smu_v13_0_0_get_power_limit(struct smu_context *smu,
                                        od_percent_upper, od_percent_lower, power_limit);
 
        if (max_power_limit) {
-               *max_power_limit = power_limit * (100 + od_percent_upper);
+               *max_power_limit = msg_limit * (100 + od_percent_upper);
                *max_power_limit /= 100;
        }
 
@@ -2959,6 +2960,55 @@ static bool smu_v13_0_0_wbrf_support_check(struct smu_context *smu)
        }
 }
 
+static int smu_v13_0_0_set_power_limit(struct smu_context *smu,
+                                      enum smu_ppt_limit_type limit_type,
+                                      uint32_t limit)
+{
+       PPTable_t *pptable = smu->smu_table.driver_pptable;
+       SkuTable_t *skutable = &pptable->SkuTable;
+       uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
+       struct smu_table_context *table_context = &smu->smu_table;
+       OverDriveTableExternal_t *od_table =
+               (OverDriveTableExternal_t *)table_context->overdrive_table;
+       int ret = 0;
+
+       if (limit_type != SMU_DEFAULT_PPT_LIMIT)
+               return -EINVAL;
+
+       if (limit <= msg_limit) {
+               if (smu->current_power_limit > msg_limit) {
+                       od_table->OverDriveTable.Ppt = 0;
+                       od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT;
+
+                       ret = smu_v13_0_0_upload_overdrive_table(smu, od_table);
+                       if (ret) {
+                               dev_err(smu->adev->dev, "Failed to upload overdrive table!\n");
+                               return ret;
+                       }
+               }
+               return smu_v13_0_set_power_limit(smu, limit_type, limit);
+       } else if (smu->od_enabled) {
+               ret = smu_v13_0_set_power_limit(smu, limit_type, msg_limit);
+               if (ret)
+                       return ret;
+
+               od_table->OverDriveTable.Ppt = (limit * 100) / msg_limit - 100;
+               od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT;
+
+               ret = smu_v13_0_0_upload_overdrive_table(smu, od_table);
+               if (ret) {
+                 dev_err(smu->adev->dev, "Failed to upload overdrive table!\n");
+                 return ret;
+               }
+
+               smu->current_power_limit = limit;
+       } else {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
        .get_allowed_feature_mask = smu_v13_0_0_get_allowed_feature_mask,
        .set_default_dpm_table = smu_v13_0_0_set_default_dpm_table,
@@ -3013,7 +3063,7 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
        .set_fan_control_mode = smu_v13_0_set_fan_control_mode,
        .enable_mgpu_fan_boost = smu_v13_0_0_enable_mgpu_fan_boost,
        .get_power_limit = smu_v13_0_0_get_power_limit,
-       .set_power_limit = smu_v13_0_set_power_limit,
+       .set_power_limit = smu_v13_0_0_set_power_limit,
        .set_power_source = smu_v13_0_set_power_source,
        .get_power_profile_mode = smu_v13_0_0_get_power_profile_mode,
        .set_power_profile_mode = smu_v13_0_0_set_power_profile_mode,
index 59606a19e3d2b4494885b72f36f6524ec25b5139..7c3e162e2d818fa4083c62373990b2c7e9a69e26 100644 (file)
@@ -2321,6 +2321,7 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu,
        PPTable_t *pptable = table_context->driver_pptable;
        SkuTable_t *skutable = &pptable->SkuTable;
        uint32_t power_limit, od_percent_upper, od_percent_lower;
+       uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
 
        if (smu_v13_0_get_current_power_limit(smu, &power_limit))
                power_limit = smu->adev->pm.ac_power ?
@@ -2344,7 +2345,7 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu,
                                        od_percent_upper, od_percent_lower, power_limit);
 
        if (max_power_limit) {
-               *max_power_limit = power_limit * (100 + od_percent_upper);
+               *max_power_limit = msg_limit * (100 + od_percent_upper);
                *max_power_limit /= 100;
        }
 
@@ -2545,6 +2546,55 @@ static bool smu_v13_0_7_wbrf_support_check(struct smu_context *smu)
        return smu->smc_fw_version > 0x00524600;
 }
 
+static int smu_v13_0_7_set_power_limit(struct smu_context *smu,
+                                      enum smu_ppt_limit_type limit_type,
+                                      uint32_t limit)
+{
+       PPTable_t *pptable = smu->smu_table.driver_pptable;
+       SkuTable_t *skutable = &pptable->SkuTable;
+       uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
+       struct smu_table_context *table_context = &smu->smu_table;
+       OverDriveTableExternal_t *od_table =
+               (OverDriveTableExternal_t *)table_context->overdrive_table;
+       int ret = 0;
+
+       if (limit_type != SMU_DEFAULT_PPT_LIMIT)
+               return -EINVAL;
+
+       if (limit <= msg_limit) {
+               if (smu->current_power_limit > msg_limit) {
+                       od_table->OverDriveTable.Ppt = 0;
+                       od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT;
+
+                       ret = smu_v13_0_7_upload_overdrive_table(smu, od_table);
+                       if (ret) {
+                               dev_err(smu->adev->dev, "Failed to upload overdrive table!\n");
+                               return ret;
+                       }
+               }
+               return smu_v13_0_set_power_limit(smu, limit_type, limit);
+       } else if (smu->od_enabled) {
+               ret = smu_v13_0_set_power_limit(smu, limit_type, msg_limit);
+               if (ret)
+                       return ret;
+
+               od_table->OverDriveTable.Ppt = (limit * 100) / msg_limit - 100;
+               od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT;
+
+               ret = smu_v13_0_7_upload_overdrive_table(smu, od_table);
+               if (ret) {
+                 dev_err(smu->adev->dev, "Failed to upload overdrive table!\n");
+                 return ret;
+               }
+
+               smu->current_power_limit = limit;
+       } else {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
        .get_allowed_feature_mask = smu_v13_0_7_get_allowed_feature_mask,
        .set_default_dpm_table = smu_v13_0_7_set_default_dpm_table,
@@ -2596,7 +2646,7 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
        .set_fan_control_mode = smu_v13_0_set_fan_control_mode,
        .enable_mgpu_fan_boost = smu_v13_0_7_enable_mgpu_fan_boost,
        .get_power_limit = smu_v13_0_7_get_power_limit,
-       .set_power_limit = smu_v13_0_set_power_limit,
+       .set_power_limit = smu_v13_0_7_set_power_limit,
        .set_power_source = smu_v13_0_set_power_source,
        .get_power_profile_mode = smu_v13_0_7_get_power_profile_mode,
        .set_power_profile_mode = smu_v13_0_7_set_power_profile_mode,