From 6e58941cff74aac49659abc8b27740c0457c2397 Mon Sep 17 00:00:00 2001 From: Eric Huang Date: Fri, 12 Mar 2021 12:43:32 -0500 Subject: [PATCH] drm/amd/pm: add a new sysfs entry for default power limit 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 Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/kgd_pp_interface.h | 3 +- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 53 ++++++++++++++++++++-- drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h | 2 + drivers/gpu/drm/amd/pm/inc/smu_v11_0.h | 1 + drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c | 12 +++-- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 3 ++ drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 2 +- .../drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 8 +++- drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 2 +- 11 files changed, 75 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 79e309a..dd69581 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -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); diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 2733af2..240bfb0 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -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; diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h index 5ac683f..25d5f03 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h @@ -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 */ diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h index 907e096..ad4db2e 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h @@ -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; }; diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c index e0d2882..ee6340c 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c @@ -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 diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 1202b9e..e722adc 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -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; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index f82dd8a..bbc0309 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -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]); 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 24195b5..3d0de2c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -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)) { diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index 94a4ea3..3621884 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -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]); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c index d9f60dc..c5b3873 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -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; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index 740025e..3c0d623 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -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; -- 2.7.4