drm/amd/pm: add a new sysfs entry for default power limit
authorEric Huang <jinhuieric.huang@amd.com>
Fri, 12 Mar 2021 17:43:32 +0000 (12:43 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 24 Mar 2021 03:30:55 +0000 (23:30 -0400)
Driver doesn't keep the default bootup power limit and expose it
to user. As requested we add it in driver.

Signed-off-by: Eric Huang <jinhuieric.huang@amd.com>
Reviewed-by: Evan Quan <evan.quan@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/include/kgd_pp_interface.h
drivers/gpu/drm/amd/pm/amdgpu_pm.c
drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
drivers/gpu/drm/amd/pm/inc/smu_v11_0.h
drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
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

index 79e309a..dd69581 100644 (file)
@@ -288,7 +288,8 @@ struct amd_pm_funcs {
                                uint32_t block_type, bool gate);
        int (*set_clockgating_by_smu)(void *handle, uint32_t msg_id);
        int (*set_power_limit)(void *handle, uint32_t n);
-       int (*get_power_limit)(void *handle, uint32_t *limit, bool default_limit);
+       int (*get_power_limit)(void *handle, uint32_t *limit, uint32_t *max_limit,
+                       bool default_limit);
        int (*get_power_profile_mode)(void *handle, char *buf);
        int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
        int (*set_fine_grain_clk_vol)(void *handle, uint32_t type, long *input, uint32_t size);
index 2733af2..240bfb0 100644 (file)
@@ -2613,6 +2613,7 @@ static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev,
        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
        int limit_type = to_sensor_dev_attr(attr)->index;
        uint32_t limit = limit_type << 24;
+       uint32_t max_limit = 0;
        ssize_t size;
        int r;
 
@@ -2629,8 +2630,9 @@ static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev,
                smu_get_power_limit(&adev->smu, &limit, SMU_PPT_LIMIT_MAX);
                size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
        } else if (pp_funcs && pp_funcs->get_power_limit) {
-               pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, true);
-               size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
+               pp_funcs->get_power_limit(adev->powerplay.pp_handle,
+                               &limit, &max_limit, true);
+               size = snprintf(buf, PAGE_SIZE, "%u\n", max_limit * 1000000);
        } else {
                size = snprintf(buf, PAGE_SIZE, "\n");
        }
@@ -2665,7 +2667,8 @@ static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev,
                smu_get_power_limit(&adev->smu, &limit, SMU_PPT_LIMIT_CURRENT);
                size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
        } else if (pp_funcs && pp_funcs->get_power_limit) {
-               pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, false);
+               pp_funcs->get_power_limit(adev->powerplay.pp_handle,
+                               &limit, NULL, false);
                size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
        } else {
                size = snprintf(buf, PAGE_SIZE, "\n");
@@ -2677,6 +2680,42 @@ static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev,
        return size;
 }
 
+static ssize_t amdgpu_hwmon_show_power_cap_default(struct device *dev,
+                                        struct device_attribute *attr,
+                                        char *buf)
+{
+       struct amdgpu_device *adev = dev_get_drvdata(dev);
+       const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+       int limit_type = to_sensor_dev_attr(attr)->index;
+       uint32_t limit = limit_type << 24;
+       ssize_t size;
+       int r;
+
+       if (amdgpu_in_reset(adev))
+               return -EPERM;
+
+       r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
+       if (r < 0) {
+               pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
+               return r;
+       }
+
+       if (is_support_sw_smu(adev)) {
+               smu_get_power_limit(&adev->smu, &limit, SMU_PPT_LIMIT_DEFAULT);
+               size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
+       } else if (pp_funcs && pp_funcs->get_power_limit) {
+               pp_funcs->get_power_limit(adev->powerplay.pp_handle,
+                               &limit, NULL, true);
+               size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
+       } else {
+               size = snprintf(buf, PAGE_SIZE, "\n");
+       }
+
+       pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
+       pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
+
+       return size;
+}
 static ssize_t amdgpu_hwmon_show_power_label(struct device *dev,
                                         struct device_attribute *attr,
                                         char *buf)
@@ -2919,11 +2958,13 @@ static SENSOR_DEVICE_ATTR(power1_average, S_IRUGO, amdgpu_hwmon_show_power_avg,
 static SENSOR_DEVICE_ATTR(power1_cap_max, S_IRUGO, amdgpu_hwmon_show_power_cap_max, NULL, 0);
 static SENSOR_DEVICE_ATTR(power1_cap_min, S_IRUGO, amdgpu_hwmon_show_power_cap_min, NULL, 0);
 static SENSOR_DEVICE_ATTR(power1_cap, S_IRUGO | S_IWUSR, amdgpu_hwmon_show_power_cap, amdgpu_hwmon_set_power_cap, 0);
+static SENSOR_DEVICE_ATTR(power1_cap_default, S_IRUGO, amdgpu_hwmon_show_power_cap_default, NULL, 0);
 static SENSOR_DEVICE_ATTR(power1_label, S_IRUGO, amdgpu_hwmon_show_power_label, NULL, 0);
 static SENSOR_DEVICE_ATTR(power2_average, S_IRUGO, amdgpu_hwmon_show_power_avg, NULL, 1);
 static SENSOR_DEVICE_ATTR(power2_cap_max, S_IRUGO, amdgpu_hwmon_show_power_cap_max, NULL, 1);
 static SENSOR_DEVICE_ATTR(power2_cap_min, S_IRUGO, amdgpu_hwmon_show_power_cap_min, NULL, 1);
 static SENSOR_DEVICE_ATTR(power2_cap, S_IRUGO | S_IWUSR, amdgpu_hwmon_show_power_cap, amdgpu_hwmon_set_power_cap, 1);
+static SENSOR_DEVICE_ATTR(power2_cap_default, S_IRUGO, amdgpu_hwmon_show_power_cap_default, NULL, 1);
 static SENSOR_DEVICE_ATTR(power2_label, S_IRUGO, amdgpu_hwmon_show_power_label, NULL, 1);
 static SENSOR_DEVICE_ATTR(freq1_input, S_IRUGO, amdgpu_hwmon_show_sclk, NULL, 0);
 static SENSOR_DEVICE_ATTR(freq1_label, S_IRUGO, amdgpu_hwmon_show_sclk_label, NULL, 0);
@@ -2963,11 +3004,13 @@ static struct attribute *hwmon_attributes[] = {
        &sensor_dev_attr_power1_cap_max.dev_attr.attr,
        &sensor_dev_attr_power1_cap_min.dev_attr.attr,
        &sensor_dev_attr_power1_cap.dev_attr.attr,
+       &sensor_dev_attr_power1_cap_default.dev_attr.attr,
        &sensor_dev_attr_power1_label.dev_attr.attr,
        &sensor_dev_attr_power2_average.dev_attr.attr,
        &sensor_dev_attr_power2_cap_max.dev_attr.attr,
        &sensor_dev_attr_power2_cap_min.dev_attr.attr,
        &sensor_dev_attr_power2_cap.dev_attr.attr,
+       &sensor_dev_attr_power2_cap_default.dev_attr.attr,
        &sensor_dev_attr_power2_label.dev_attr.attr,
        &sensor_dev_attr_freq1_input.dev_attr.attr,
        &sensor_dev_attr_freq1_label.dev_attr.attr,
@@ -3066,7 +3109,8 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
              (adev->asic_type != CHIP_VANGOGH))) &&    /* not implemented yet */
            (attr == &sensor_dev_attr_power1_cap_max.dev_attr.attr ||
             attr == &sensor_dev_attr_power1_cap_min.dev_attr.attr||
-            attr == &sensor_dev_attr_power1_cap.dev_attr.attr))
+            attr == &sensor_dev_attr_power1_cap.dev_attr.attr ||
+            attr == &sensor_dev_attr_power1_cap_default.dev_attr.attr))
                return 0;
 
        if (((adev->family == AMDGPU_FAMILY_SI) ||
@@ -3132,6 +3176,7 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
                 attr == &sensor_dev_attr_power2_cap_max.dev_attr.attr ||
             attr == &sensor_dev_attr_power2_cap_min.dev_attr.attr ||
                 attr == &sensor_dev_attr_power2_cap.dev_attr.attr ||
+                attr == &sensor_dev_attr_power2_cap_default.dev_attr.attr ||
                 attr == &sensor_dev_attr_power2_label.dev_attr.attr ||
                 attr == &sensor_dev_attr_power1_label.dev_attr.attr))
                return 0;
index 5ac683f..25d5f03 100644 (file)
@@ -171,6 +171,7 @@ enum smu_ppt_limit_level
 {
        SMU_PPT_LIMIT_MIN = -1,
        SMU_PPT_LIMIT_CURRENT,
+       SMU_PPT_LIMIT_DEFAULT,
        SMU_PPT_LIMIT_MAX,
 };
 
@@ -446,6 +447,7 @@ struct smu_context
 
        bool od_enabled;
        uint32_t current_power_limit;
+       uint32_t default_power_limit;
        uint32_t max_power_limit;
 
        /* soft pptable */
index 907e096..ad4db2e 100644 (file)
@@ -141,6 +141,7 @@ struct smu_11_5_power_context {
        enum smu_11_0_power_state power_state;
 
        uint32_t        current_fast_ppt_limit;
+       uint32_t        default_fast_ppt_limit;
        uint32_t        max_fast_ppt_limit;
 };
 
index e0d2882..ee6340c 100644 (file)
@@ -1034,7 +1034,8 @@ static int pp_set_power_limit(void *handle, uint32_t limit)
        return 0;
 }
 
-static int pp_get_power_limit(void *handle, uint32_t *limit, bool default_limit)
+static int pp_get_power_limit(void *handle, uint32_t *limit,
+               uint32_t *max_limit, bool default_limit)
 {
        struct pp_hwmgr *hwmgr = handle;
 
@@ -1045,9 +1046,12 @@ static int pp_get_power_limit(void *handle, uint32_t *limit, bool default_limit)
 
        if (default_limit) {
                *limit = hwmgr->default_power_limit;
-               if (hwmgr->od_enabled) {
-                       *limit *= (100 + hwmgr->platform_descriptor.TDPODLimit);
-                       *limit /= 100;
+               if (max_limit) {
+                       *max_limit = *limit;
+                       if (hwmgr->od_enabled) {
+                               *max_limit *= (100 + hwmgr->platform_descriptor.TDPODLimit);
+                               *max_limit /= 100;
+                       }
                }
        }
        else
index 1202b9e..e722adc 100644 (file)
@@ -2183,6 +2183,9 @@ int smu_get_power_limit(struct smu_context *smu,
                case SMU_PPT_LIMIT_CURRENT:
                        *limit = smu->current_power_limit;
                        break;
+               case SMU_PPT_LIMIT_DEFAULT:
+                       *limit = smu->default_power_limit;
+                       break;
                case SMU_PPT_LIMIT_MAX:
                        *limit = smu->max_power_limit;
                        break;
index f82dd8a..bbc0309 100644 (file)
@@ -1129,7 +1129,7 @@ static int arcturus_get_power_limit(struct smu_context *smu)
                power_limit =
                        pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
        }
-       smu->current_power_limit = power_limit;
+       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]);
index 24195b5..3d0de2c 100644 (file)
@@ -2111,7 +2111,7 @@ static int navi10_get_power_limit(struct smu_context *smu)
                power_limit =
                        pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
        }
-       smu->current_power_limit = power_limit;
+       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)) {
index 94a4ea3..3621884 100644 (file)
@@ -1736,7 +1736,7 @@ static int sienna_cichlid_get_power_limit(struct smu_context *smu)
                power_limit =
                        pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
        }
-       smu->current_power_limit = power_limit;
+       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]);
index d9f60dc..c5b3873 100644 (file)
@@ -1756,7 +1756,7 @@ static int vangogh_get_power_limit(struct smu_context *smu)
                return ret;
        }
        /* convert from milliwatt to watt */
-       smu->current_power_limit = ppt_limit / 1000;
+       smu->current_power_limit = smu->default_power_limit = ppt_limit / 1000;
        smu->max_power_limit = 29;
 
        ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetFastPPTLimit, &ppt_limit);
@@ -1765,7 +1765,8 @@ static int vangogh_get_power_limit(struct smu_context *smu)
                return ret;
        }
        /* convert from milliwatt to watt */
-       power_context->current_fast_ppt_limit = ppt_limit / 1000;
+       power_context->current_fast_ppt_limit =
+                       power_context->default_fast_ppt_limit = ppt_limit / 1000;
        power_context->max_fast_ppt_limit = 30;
 
        return ret;
@@ -1790,6 +1791,9 @@ static int vangogh_get_ppt_limit(struct smu_context *smu,
                case SMU_PPT_LIMIT_CURRENT:
                        *ppt_limit = power_context->current_fast_ppt_limit;
                        break;
+               case SMU_PPT_LIMIT_DEFAULT:
+                       *ppt_limit = power_context->default_fast_ppt_limit;
+                       break;
                default:
                        break;
                }
index 740025e..3c0d623 100644 (file)
@@ -1088,7 +1088,7 @@ static int aldebaran_get_power_limit(struct smu_context *smu)
                power_limit = pptable->PptLimit;
        }
 
-       smu->current_power_limit = power_limit;
+       smu->current_power_limit = smu->default_power_limit = power_limit;
        if (pptable)
                smu->max_power_limit = pptable->PptLimit;