drm/amd/pm: correct the power limits reporting on OOB supported
authorEvan Quan <evan.quan@amd.com>
Wed, 19 May 2021 04:22:04 +0000 (12:22 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 11 Jun 2021 20:03:09 +0000 (16:03 -0400)
As OOB(out-of-band) interface may be used to update the power limits.
Thus to make sure the power limits reporting of our driver always
reflects the correct values, the internal cache must be aligned
carefully.

V2: add support for out-of-band of other ASICs
    align cached current power limit with OOB imposed

Signed-off-by: Evan Quan <evan.quan@amd.com>
Reviewed-By: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu_internal.h

index 0c06c2f6ea43b0cff2413702b28514bef7e3ede7..6559912ba2293eb1aa29016d10fe30d4e4bc5525 100644 (file)
@@ -765,7 +765,10 @@ struct pptable_funcs {
        /**
         * @get_power_limit: Get the device's power limits.
         */
-       int (*get_power_limit)(struct smu_context *smu);
+       int (*get_power_limit)(struct smu_context *smu,
+                              uint32_t *current_power_limit,
+                              uint32_t *default_power_limit,
+                              uint32_t *max_power_limit);
 
        /**
         * @get_ppt_limit: Get the device's ppt limits.
index a6029a88929bb878de5713bd5071345fce7f0a5f..cb375f1beebdef0257c0934399189fb917ca4bc4 100644 (file)
@@ -688,7 +688,10 @@ static int smu_late_init(void *handle)
                return ret;
        }
 
-       ret = smu_get_asic_power_limits(smu);
+       ret = smu_get_asic_power_limits(smu,
+                                       &smu->current_power_limit,
+                                       &smu->default_power_limit,
+                                       &smu->max_power_limit);
        if (ret) {
                dev_err(adev->dev, "Failed to get asic power limits!\n");
                return ret;
@@ -2238,6 +2241,15 @@ int smu_get_power_limit(void *handle,
        } else {
                switch (limit_level) {
                case SMU_PPT_LIMIT_CURRENT:
+                       if ((smu->adev->asic_type == CHIP_ALDEBARAN) ||
+                            (smu->adev->asic_type == CHIP_SIENNA_CICHLID) ||
+                            (smu->adev->asic_type == CHIP_NAVY_FLOUNDER) ||
+                            (smu->adev->asic_type == CHIP_DIMGREY_CAVEFISH) ||
+                            (smu->adev->asic_type == CHIP_BEIGE_GOBY))
+                               ret = smu_get_asic_power_limits(smu,
+                                                               &smu->current_power_limit,
+                                                               NULL,
+                                                               NULL);
                        *limit = smu->current_power_limit;
                        break;
                case SMU_PPT_LIMIT_DEFAULT:
index 51ab5cb3f9372c1424c6170833534d6f78f4d2ca..094df6f87cfc4105cd5318373cc66807d40a9f34 100644 (file)
@@ -1194,7 +1194,10 @@ static int arcturus_get_fan_parameters(struct smu_context *smu)
        return 0;
 }
 
-static int arcturus_get_power_limit(struct smu_context *smu)
+static int arcturus_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;
@@ -1210,17 +1213,24 @@ static int arcturus_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) {
-               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;
 
-               dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
+       if (max_power_limit) {
+               if (smu->od_enabled) {
+                       od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
 
-               power_limit *= (100 + od_percent);
-               power_limit /= 100;
+                       dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
+
+                       power_limit *= (100 + od_percent);
+                       power_limit /= 100;
+               }
+
+               *max_power_limit = power_limit;
        }
-       smu->max_power_limit = power_limit;
 
        return 0;
 }
index 5a967db225122dd81aa463e94b231ba957b97bd1..0e67517682e3197ce2d331f1f0773a481c11ca4f 100644 (file)
@@ -2136,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;
@@ -2153,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;
 
-               dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, 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]);
 
-               power_limit *= (100 + od_percent);
-               power_limit /= 100;
+                       dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
+
+                       power_limit *= (100 + od_percent);
+                       power_limit /= 100;
+               }
+
+               *max_power_limit = power_limit;
        }
-       smu->max_power_limit = power_limit;
 
        return 0;
 }
index 848efc20c01efb5373d25b5f1d339ddb79c2c515..c751f717a0daff49620bcd850906bb362df1f665 100644 (file)
@@ -1791,7 +1791,10 @@ static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context
        return ret;
 }
 
-static int sienna_cichlid_get_power_limit(struct smu_context *smu)
+static int sienna_cichlid_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_7_powerplay_table *powerplay_table =
                (struct smu_11_0_7_powerplay_table *)smu->smu_table.power_play_table;
@@ -1804,17 +1807,23 @@ static int sienna_cichlid_get_power_limit(struct smu_context *smu)
                power_limit =
                        table_member[PPT_THROTTLER_PPT0];
        }
-       smu->current_power_limit = smu->default_power_limit = power_limit;
 
-       if (smu->od_enabled) {
-               od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
+       if (current_power_limit)
+               *current_power_limit = power_limit;
+       if (default_power_limit)
+               *default_power_limit = power_limit;
 
-               dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
+       if (max_power_limit) {
+               if (smu->od_enabled) {
+                       od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
 
-               power_limit *= (100 + od_percent);
-               power_limit /= 100;
+                       dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
+
+                       power_limit *= (100 + od_percent);
+                       power_limit /= 100;
+               }
+               *max_power_limit = power_limit;
        }
-       smu->max_power_limit = power_limit;
 
        return 0;
 }
index 3a7d2f59c42a00bd62d39a575162115cf39af855..18681dc458da2b9fe96335e098dcb7b6681a4154 100644 (file)
@@ -2071,7 +2071,10 @@ static int vangogh_mode2_reset(struct smu_context *smu)
        return vangogh_mode_reset(smu, SMU_RESET_MODE_2);
 }
 
-static int vangogh_get_power_limit(struct smu_context *smu)
+static int vangogh_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_5_power_context *power_context =
                                                                smu->smu_power.power_context;
@@ -2087,8 +2090,12 @@ static int vangogh_get_power_limit(struct smu_context *smu)
                return ret;
        }
        /* convert from milliwatt to watt */
-       smu->current_power_limit = smu->default_power_limit = ppt_limit / 1000;
-       smu->max_power_limit = 29;
+       if (current_power_limit)
+               *current_power_limit = ppt_limit / 1000;
+       if (default_power_limit)
+               *default_power_limit = ppt_limit / 1000;
+       if (max_power_limit)
+               *max_power_limit = 29;
 
        ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetFastPPTLimit, &ppt_limit);
        if (ret) {
index 0a539094aa29523d637eec4083e06f3d4354dec3..64a4126ef076820c773507f3a9972308a9d5e8ee 100644 (file)
@@ -1146,7 +1146,10 @@ static int aldebaran_read_sensor(struct smu_context *smu,
        return ret;
 }
 
-static int aldebaran_get_power_limit(struct smu_context *smu)
+static int aldebaran_get_power_limit(struct smu_context *smu,
+                                    uint32_t *current_power_limit,
+                                    uint32_t *default_power_limit,
+                                    uint32_t *max_power_limit)
 {
        PPTable_t *pptable = smu->smu_table.driver_pptable;
        uint32_t power_limit = 0;
@@ -1166,9 +1169,15 @@ static int aldebaran_get_power_limit(struct smu_context *smu)
                power_limit = pptable->PptLimit;
        }
 
-       smu->current_power_limit = smu->default_power_limit = power_limit;
-       if (pptable)
-               smu->max_power_limit = pptable->PptLimit;
+       if (current_power_limit)
+               *current_power_limit = power_limit;
+       if (default_power_limit)
+               *default_power_limit = power_limit;
+
+       if (max_power_limit) {
+               if (pptable)
+                       *max_power_limit = pptable->PptLimit;
+       }
 
        return 0;
 }
index b6d2f2edcd6135f7675ec1bc8a93c585df1ed5ce..59f9cfff3d61515d118e4dc2f8fb66d594721ec0 100644 (file)
@@ -82,7 +82,7 @@
 #define smu_i2c_fini(smu, control)                                     smu_ppt_funcs(i2c_fini, 0, smu, control)
 #define smu_get_unique_id(smu)                                         smu_ppt_funcs(get_unique_id, 0, smu)
 #define smu_log_thermal_throttling(smu)                                        smu_ppt_funcs(log_thermal_throttling_event, 0, smu)
-#define smu_get_asic_power_limits(smu)                                 smu_ppt_funcs(get_power_limit, 0, smu)
+#define smu_get_asic_power_limits(smu, current, default, max)          smu_ppt_funcs(get_power_limit, 0, smu, current, default, max)
 #define smu_get_pp_feature_mask(smu, buf)                              smu_ppt_funcs(get_pp_feature_mask, 0, smu, buf)
 #define smu_set_pp_feature_mask(smu, new_mask)                         smu_ppt_funcs(set_pp_feature_mask, 0, smu, new_mask)
 #define smu_gfx_ulv_control(smu, enablement)                           smu_ppt_funcs(gfx_ulv_control, 0, smu, enablement)