From 48b270bb22dbe27f122ed9b310f23a20d2f39228 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 24 May 2020 02:46:53 -0400 Subject: drm/amdgpu/pm: return an error during GPU reset or suspend (v2) Return an error for sysfs and debugfs power interfaces during gpu reset and suspend. Prevents access to the hw while it may be in an unusable state. v2: squash in fix to drop suspend check Acked-by: Nirmoy Das Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 171 +++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index d7646cbce346..775e389c9a13 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -163,6 +163,9 @@ static ssize_t amdgpu_get_power_dpm_state(struct device *dev, enum amd_pm_state_type pm; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -196,6 +199,9 @@ static ssize_t amdgpu_set_power_dpm_state(struct device *dev, enum amd_pm_state_type state; int ret; + if (adev->in_gpu_reset) + return -EPERM; + if (strncmp("battery", buf, strlen("battery")) == 0) state = POWER_STATE_TYPE_BATTERY; else if (strncmp("balanced", buf, strlen("balanced")) == 0) @@ -297,6 +303,9 @@ static ssize_t amdgpu_get_power_dpm_force_performance_level(struct device *dev, enum amd_dpm_forced_level level = 0xff; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -334,6 +343,9 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev, enum amd_dpm_forced_level current_level = 0xff; int ret = 0; + if (adev->in_gpu_reset) + return -EPERM; + if (strncmp("low", buf, strlen("low")) == 0) { level = AMD_DPM_FORCED_LEVEL_LOW; } else if (strncmp("high", buf, strlen("high")) == 0) { @@ -433,6 +445,9 @@ static ssize_t amdgpu_get_pp_num_states(struct device *dev, struct pp_states_info data; int i, buf_len, ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -472,6 +487,9 @@ static ssize_t amdgpu_get_pp_cur_state(struct device *dev, enum amd_pm_state_type pm = 0; int i = 0, ret = 0; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -508,6 +526,9 @@ static ssize_t amdgpu_get_pp_force_state(struct device *dev, struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; + if (adev->in_gpu_reset) + return -EPERM; + if (adev->pp_force_state_enabled) return amdgpu_get_pp_cur_state(dev, attr, buf); else @@ -525,6 +546,9 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev, unsigned long idx; int ret; + if (adev->in_gpu_reset) + return -EPERM; + if (strlen(buf) == 1) adev->pp_force_state_enabled = false; else if (is_support_sw_smu(adev)) @@ -580,6 +604,9 @@ static ssize_t amdgpu_get_pp_table(struct device *dev, char *table = NULL; int size, ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -619,6 +646,9 @@ static ssize_t amdgpu_set_pp_table(struct device *dev, struct amdgpu_device *adev = ddev->dev_private; int ret = 0; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -721,6 +751,9 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev, const char delimiter[3] = {' ', '\n', '\0'}; uint32_t type; + if (adev->in_gpu_reset) + return -EPERM; + if (count > 127) return -EINVAL; @@ -810,6 +843,9 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev, ssize_t size; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -859,6 +895,9 @@ static ssize_t amdgpu_set_pp_features(struct device *dev, uint64_t featuremask; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = kstrtou64(buf, 0, &featuremask); if (ret) return -EINVAL; @@ -899,6 +938,9 @@ static ssize_t amdgpu_get_pp_features(struct device *dev, ssize_t size; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -955,6 +997,9 @@ static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev, ssize_t size; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1018,6 +1063,9 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, int ret; uint32_t mask = 0; + if (adev->in_gpu_reset) + return -EPERM; + ret = amdgpu_read_mask(buf, count, &mask); if (ret) return ret; @@ -1049,6 +1097,9 @@ static ssize_t amdgpu_get_pp_dpm_mclk(struct device *dev, ssize_t size; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1076,6 +1127,9 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, uint32_t mask = 0; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = amdgpu_read_mask(buf, count, &mask); if (ret) return ret; @@ -1107,6 +1161,9 @@ static ssize_t amdgpu_get_pp_dpm_socclk(struct device *dev, ssize_t size; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1134,6 +1191,9 @@ static ssize_t amdgpu_set_pp_dpm_socclk(struct device *dev, int ret; uint32_t mask = 0; + if (adev->in_gpu_reset) + return -EPERM; + ret = amdgpu_read_mask(buf, count, &mask); if (ret) return ret; @@ -1167,6 +1227,9 @@ static ssize_t amdgpu_get_pp_dpm_fclk(struct device *dev, ssize_t size; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1194,6 +1257,9 @@ static ssize_t amdgpu_set_pp_dpm_fclk(struct device *dev, int ret; uint32_t mask = 0; + if (adev->in_gpu_reset) + return -EPERM; + ret = amdgpu_read_mask(buf, count, &mask); if (ret) return ret; @@ -1227,6 +1293,9 @@ static ssize_t amdgpu_get_pp_dpm_dcefclk(struct device *dev, ssize_t size; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1254,6 +1323,9 @@ static ssize_t amdgpu_set_pp_dpm_dcefclk(struct device *dev, int ret; uint32_t mask = 0; + if (adev->in_gpu_reset) + return -EPERM; + ret = amdgpu_read_mask(buf, count, &mask); if (ret) return ret; @@ -1287,6 +1359,9 @@ static ssize_t amdgpu_get_pp_dpm_pcie(struct device *dev, ssize_t size; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1314,6 +1389,9 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, int ret; uint32_t mask = 0; + if (adev->in_gpu_reset) + return -EPERM; + ret = amdgpu_read_mask(buf, count, &mask); if (ret) return ret; @@ -1347,6 +1425,9 @@ static ssize_t amdgpu_get_pp_sclk_od(struct device *dev, uint32_t value = 0; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1372,6 +1453,9 @@ static ssize_t amdgpu_set_pp_sclk_od(struct device *dev, int ret; long int value; + if (adev->in_gpu_reset) + return -EPERM; + ret = kstrtol(buf, 0, &value); if (ret) @@ -1410,6 +1494,9 @@ static ssize_t amdgpu_get_pp_mclk_od(struct device *dev, uint32_t value = 0; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1435,6 +1522,9 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev, int ret; long int value; + if (adev->in_gpu_reset) + return -EPERM; + ret = kstrtol(buf, 0, &value); if (ret) @@ -1493,6 +1583,9 @@ static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev, ssize_t size; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1528,6 +1621,9 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev, long int profile_mode = 0; const char delimiter[3] = {' ', '\n', '\0'}; + if (adev->in_gpu_reset) + return -EPERM; + tmp[0] = *(buf); tmp[1] = '\0'; ret = kstrtol(tmp, 0, &profile_mode); @@ -1587,6 +1683,9 @@ static ssize_t amdgpu_get_gpu_busy_percent(struct device *dev, struct amdgpu_device *adev = ddev->dev_private; int r, value, size = sizeof(value); + if (adev->in_gpu_reset) + return -EPERM; + r = pm_runtime_get_sync(ddev->dev); if (r < 0) return r; @@ -1620,6 +1719,9 @@ static ssize_t amdgpu_get_mem_busy_percent(struct device *dev, struct amdgpu_device *adev = ddev->dev_private; int r, value, size = sizeof(value); + if (adev->in_gpu_reset) + return -EPERM; + r = pm_runtime_get_sync(ddev->dev); if (r < 0) return r; @@ -1658,6 +1760,9 @@ static ssize_t amdgpu_get_pcie_bw(struct device *dev, uint64_t count0 = 0, count1 = 0; int ret; + if (adev->in_gpu_reset) + return -EPERM; + if (adev->flags & AMD_IS_APU) return -ENODATA; @@ -1694,6 +1799,9 @@ static ssize_t amdgpu_get_unique_id(struct device *dev, struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; + if (adev->in_gpu_reset) + return -EPERM; + if (adev->unique_id) return snprintf(buf, PAGE_SIZE, "%016llx\n", adev->unique_id); @@ -1888,6 +1996,9 @@ static ssize_t amdgpu_hwmon_show_temp(struct device *dev, int channel = to_sensor_dev_attr(attr)->index; int r, temp = 0, size = sizeof(temp); + if (adev->in_gpu_reset) + return -EPERM; + if (channel >= PP_TEMP_MAX) return -EINVAL; @@ -2019,6 +2130,9 @@ static ssize_t amdgpu_hwmon_get_pwm1_enable(struct device *dev, u32 pwm_mode = 0; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(adev->ddev->dev); if (ret < 0) return ret; @@ -2050,6 +2164,9 @@ static ssize_t amdgpu_hwmon_set_pwm1_enable(struct device *dev, int err, ret; int value; + if (adev->in_gpu_reset) + return -EPERM; + err = kstrtoint(buf, 10, &value); if (err) return err; @@ -2099,6 +2216,9 @@ static ssize_t amdgpu_hwmon_set_pwm1(struct device *dev, u32 value; u32 pwm_mode; + if (adev->in_gpu_reset) + return -EPERM; + err = pm_runtime_get_sync(adev->ddev->dev); if (err < 0) return err; @@ -2148,6 +2268,9 @@ static ssize_t amdgpu_hwmon_get_pwm1(struct device *dev, int err; u32 speed = 0; + if (adev->in_gpu_reset) + return -EPERM; + err = pm_runtime_get_sync(adev->ddev->dev); if (err < 0) return err; @@ -2178,6 +2301,9 @@ static ssize_t amdgpu_hwmon_get_fan1_input(struct device *dev, int err; u32 speed = 0; + if (adev->in_gpu_reset) + return -EPERM; + err = pm_runtime_get_sync(adev->ddev->dev); if (err < 0) return err; @@ -2207,6 +2333,9 @@ static ssize_t amdgpu_hwmon_get_fan1_min(struct device *dev, u32 size = sizeof(min_rpm); int r; + if (adev->in_gpu_reset) + return -EPERM; + r = pm_runtime_get_sync(adev->ddev->dev); if (r < 0) return r; @@ -2232,6 +2361,9 @@ static ssize_t amdgpu_hwmon_get_fan1_max(struct device *dev, u32 size = sizeof(max_rpm); int r; + if (adev->in_gpu_reset) + return -EPERM; + r = pm_runtime_get_sync(adev->ddev->dev); if (r < 0) return r; @@ -2256,6 +2388,9 @@ static ssize_t amdgpu_hwmon_get_fan1_target(struct device *dev, int err; u32 rpm = 0; + if (adev->in_gpu_reset) + return -EPERM; + err = pm_runtime_get_sync(adev->ddev->dev); if (err < 0) return err; @@ -2285,6 +2420,9 @@ static ssize_t amdgpu_hwmon_set_fan1_target(struct device *dev, u32 value; u32 pwm_mode; + if (adev->in_gpu_reset) + return -EPERM; + err = pm_runtime_get_sync(adev->ddev->dev); if (err < 0) return err; @@ -2331,6 +2469,9 @@ static ssize_t amdgpu_hwmon_get_fan1_enable(struct device *dev, u32 pwm_mode = 0; int ret; + if (adev->in_gpu_reset) + return -EPERM; + ret = pm_runtime_get_sync(adev->ddev->dev); if (ret < 0) return ret; @@ -2363,6 +2504,9 @@ static ssize_t amdgpu_hwmon_set_fan1_enable(struct device *dev, int value; u32 pwm_mode; + if (adev->in_gpu_reset) + return -EPERM; + err = kstrtoint(buf, 10, &value); if (err) return err; @@ -2403,6 +2547,9 @@ static ssize_t amdgpu_hwmon_show_vddgfx(struct device *dev, u32 vddgfx; int r, size = sizeof(vddgfx); + if (adev->in_gpu_reset) + return -EPERM; + r = pm_runtime_get_sync(adev->ddev->dev); if (r < 0) return r; @@ -2435,6 +2582,9 @@ static ssize_t amdgpu_hwmon_show_vddnb(struct device *dev, u32 vddnb; int r, size = sizeof(vddnb); + if (adev->in_gpu_reset) + return -EPERM; + /* only APUs have vddnb */ if (!(adev->flags & AMD_IS_APU)) return -EINVAL; @@ -2472,6 +2622,9 @@ static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev, int r, size = sizeof(u32); unsigned uw; + if (adev->in_gpu_reset) + return -EPERM; + r = pm_runtime_get_sync(adev->ddev->dev); if (r < 0) return r; @@ -2508,6 +2661,9 @@ static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev, ssize_t size; int r; + if (adev->in_gpu_reset) + return -EPERM; + r = pm_runtime_get_sync(adev->ddev->dev); if (r < 0) return r; @@ -2537,6 +2693,9 @@ static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev, ssize_t size; int r; + if (adev->in_gpu_reset) + return -EPERM; + r = pm_runtime_get_sync(adev->ddev->dev); if (r < 0) return r; @@ -2567,6 +2726,9 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device *dev, int err; u32 value; + if (adev->in_gpu_reset) + return -EPERM; + if (amdgpu_sriov_vf(adev)) return -EINVAL; @@ -2605,6 +2767,9 @@ static ssize_t amdgpu_hwmon_show_sclk(struct device *dev, uint32_t sclk; int r, size = sizeof(sclk); + if (adev->in_gpu_reset) + return -EPERM; + r = pm_runtime_get_sync(adev->ddev->dev); if (r < 0) return r; @@ -2637,6 +2802,9 @@ static ssize_t amdgpu_hwmon_show_mclk(struct device *dev, uint32_t mclk; int r, size = sizeof(mclk); + if (adev->in_gpu_reset) + return -EPERM; + r = pm_runtime_get_sync(adev->ddev->dev); if (r < 0) return r; @@ -3497,6 +3665,9 @@ static int amdgpu_debugfs_pm_info(struct seq_file *m, void *data) u32 flags = 0; int r; + if (adev->in_gpu_reset) + return -EPERM; + r = pm_runtime_get_sync(dev->dev); if (r < 0) return r; -- cgit v1.2.3 From b265bdbd9f2811c2a674ea9d1161de821923897c Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Fri, 22 May 2020 18:57:11 +0800 Subject: drm/amdgpu: added a sysfs interface for thermal throttling related V4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User can check and set the enablement of throttling logging and the interval between each logging. V2: simplify the sysfs interface(no string parsing) V3: add proper lock protection on updating throttling_logging_rs.interval V4: documentation cosmetic per Luben's suggestion Signed-off-by: Evan Quan Reviewed-by: Christian König Reviewed-by: Luben Tuikov Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 11 +++++ drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 68 ++++++++++++++++++++++++++++++ drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 10 ++--- 4 files changed, 86 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index cd913986863e..922d5bca14c0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -993,6 +993,9 @@ struct amdgpu_device { char serial[16]; struct amdgpu_autodump autodump; + + atomic_t throttling_logging_enabled; + struct ratelimit_state throttling_logging_rs; }; static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_bo_device *bdev) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 2f0e8da7bacf..e5b639a1575e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3035,6 +3035,17 @@ int amdgpu_device_init(struct amdgpu_device *adev, adev->gfx.gfx_off_req_count = 1; adev->pm.ac_power = power_supply_is_system_supplied() > 0; + atomic_set(&adev->throttling_logging_enabled, 1); + /* + * If throttling continues, logging will be performed every minute + * to avoid log flooding. "-1" is subtracted since the thermal + * throttling interrupt comes every second. Thus, the total logging + * interval is 59 seconds(retelimited printk interval) + 1(waiting + * for throttling interrupt) = 60 seconds. + */ + ratelimit_state_init(&adev->throttling_logging_rs, (60 - 1) * HZ, 1); + ratelimit_set_flags(&adev->throttling_logging_rs, RATELIMIT_MSG_ON_RELEASE); + /* Registers mapping */ /* TODO: block userspace mapping of io register */ if (adev->asic_type >= CHIP_BONAIRE) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 775e389c9a13..b0dff9ecfb88 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1808,6 +1808,73 @@ static ssize_t amdgpu_get_unique_id(struct device *dev, return 0; } +/** + * DOC: thermal_throttling_logging + * + * Thermal throttling pulls down the clock frequency and thus the performance. + * It's an useful mechanism to protect the chip from overheating. Since it + * impacts performance, the user controls whether it is enabled and if so, + * the log frequency. + * + * Reading back the file shows you the status(enabled or disabled) and + * the interval(in seconds) between each thermal logging. + * + * Writing an integer to the file, sets a new logging interval, in seconds. + * The value should be between 1 and 3600. If the value is less than 1, + * thermal logging is disabled. Values greater than 3600 are ignored. + */ +static ssize_t amdgpu_get_thermal_throttling_logging(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + + return snprintf(buf, PAGE_SIZE, "%s: thermal throttling logging %s, with interval %d seconds\n", + adev->ddev->unique, + atomic_read(&adev->throttling_logging_enabled) ? "enabled" : "disabled", + adev->throttling_logging_rs.interval / HZ + 1); +} + +static ssize_t amdgpu_set_thermal_throttling_logging(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + long throttling_logging_interval; + unsigned long flags; + int ret = 0; + + ret = kstrtol(buf, 0, &throttling_logging_interval); + if (ret) + return ret; + + if (throttling_logging_interval > 3600) + return -EINVAL; + + if (throttling_logging_interval > 0) { + raw_spin_lock_irqsave(&adev->throttling_logging_rs.lock, flags); + /* + * Reset the ratelimit timer internals. + * This can effectively restart the timer. + */ + adev->throttling_logging_rs.interval = + (throttling_logging_interval - 1) * HZ; + adev->throttling_logging_rs.begin = 0; + adev->throttling_logging_rs.printed = 0; + adev->throttling_logging_rs.missed = 0; + raw_spin_unlock_irqrestore(&adev->throttling_logging_rs.lock, flags); + + atomic_set(&adev->throttling_logging_enabled, 1); + } else { + atomic_set(&adev->throttling_logging_enabled, 0); + } + + return count; +} + static struct amdgpu_device_attr amdgpu_device_attrs[] = { AMDGPU_DEVICE_ATTR_RW(power_dpm_state, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), AMDGPU_DEVICE_ATTR_RW(power_dpm_force_performance_level, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), @@ -1830,6 +1897,7 @@ static struct amdgpu_device_attr amdgpu_device_attrs[] = { AMDGPU_DEVICE_ATTR_RO(pcie_bw, ATTR_FLAG_BASIC), AMDGPU_DEVICE_ATTR_RW(pp_features, ATTR_FLAG_BASIC), AMDGPU_DEVICE_ATTR_RO(unique_id, ATTR_FLAG_BASIC), + AMDGPU_DEVICE_ATTR_RW(thermal_throttling_logging, ATTR_FLAG_BASIC), }; static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c index 92cb7924524d..123a2af4be2e 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c @@ -1533,11 +1533,6 @@ static int smu_v11_0_irq_process(struct amdgpu_device *adev, */ uint32_t ctxid = entry->src_data[0]; uint32_t data; - /* - * if the throttling continues, the logging will be performed every - * minute to avoid log flooding. - */ - static DEFINE_RATELIMIT_STATE(ratelimit_state, 60 * HZ, 1); if (client_id == SOC15_IH_CLIENTID_THM) { switch (src_id) { @@ -1582,7 +1577,10 @@ static int smu_v11_0_irq_process(struct amdgpu_device *adev, smu_v11_0_ack_ac_dc_interrupt(&adev->smu); break; case 0x7: - if (__ratelimit(&ratelimit_state)) + if (!atomic_read(&adev->throttling_logging_enabled)) + return 0; + + if (__ratelimit(&adev->throttling_logging_rs)) smu_log_thermal_throttling(smu); break; -- cgit v1.2.3 From 81a16241114ba4e0b188e517e5e8522951dfeb7b Mon Sep 17 00:00:00 2001 From: Kent Russell Date: Mon, 27 Apr 2020 09:28:04 -0400 Subject: drm/amdgpu: Add unique_id and serial_number for Arcturus v3 Add support for unique_id and serial_number, as these are now the same value, and will be for future ASICs as well. v2: Explicitly create unique_id only for VG10/20/ARC v3: Change set_unique_id to get_unique_id for clarity Signed-off-by: Kent Russell Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 4 +++- drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 2 ++ drivers/gpu/drm/amd/powerplay/arcturus_ppt.c | 32 ++++++++++++++++++++++++++ drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 1 + drivers/gpu/drm/amd/powerplay/smu_internal.h | 2 ++ 5 files changed, 40 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index b0dff9ecfb88..b2cdc8a1268f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1940,7 +1940,9 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ if (adev->flags & AMD_IS_APU) *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(unique_id)) { - if (!adev->unique_id) + if (asic_type != CHIP_VEGA10 && + asic_type != CHIP_VEGA20 && + asic_type != CHIP_ARCTURUS) *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_features)) { if (adev->flags & AMD_IS_APU || asic_type < CHIP_VEGA10) diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index 1f8ced4c4e2d..1c5374349b52 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -793,6 +793,8 @@ static int smu_late_init(void *handle) if (!smu->pm_enabled) return 0; + smu_get_unique_id(smu); + smu_handle_task(&adev->smu, smu->smu_dpm.dpm_level, AMD_PP_TASK_COMPLETE_INIT, diff --git a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c index d66ac7457574..df7b408319f7 100644 --- a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c @@ -2262,6 +2262,37 @@ static void arcturus_i2c_eeprom_control_fini(struct i2c_adapter *control) i2c_del_adapter(control); } +static void arcturus_get_unique_id(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + uint32_t top32, bottom32, smu_version, size; + char sn[16]; + uint64_t id; + + if (smu_get_smc_version(smu, NULL, &smu_version)) { + pr_warn("Failed to get smu version, cannot get unique_id or serial_number\n"); + return; + } + + /* PPSMC_MSG_ReadSerial* is supported by 54.23.0 and onwards */ + if (smu_version < 0x361700) { + pr_warn("ReadSerial is only supported by PMFW 54.23.0 and onwards\n"); + return; + } + + /* Get the SN to turn into a Unique ID */ + smu_send_smc_msg(smu, SMU_MSG_ReadSerialNumTop32, &top32); + smu_send_smc_msg(smu, SMU_MSG_ReadSerialNumBottom32, &bottom32); + + id = ((uint64_t)bottom32 << 32) | top32; + adev->unique_id = id; + /* For Arcturus-and-later, unique_id == serial_number, so convert it to a + * 16-digit HEX string for convenience and backwards-compatibility + */ + size = sprintf(sn, "%llx", id); + memcpy(adev->serial, &sn, size); +} + static bool arcturus_is_baco_supported(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; @@ -2416,6 +2447,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = { .dpm_set_uvd_enable = arcturus_dpm_set_uvd_enable, .i2c_eeprom_init = arcturus_i2c_eeprom_control_init, .i2c_eeprom_fini = arcturus_i2c_eeprom_control_fini, + .get_unique_id = arcturus_get_unique_id, .init_microcode = smu_v11_0_init_microcode, .load_microcode = smu_v11_0_load_microcode, .init_smc_tables = smu_v11_0_init_smc_tables, diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h index 5bb1ac821aeb..13fc5773ba45 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -495,6 +495,7 @@ struct pptable_funcs { int (*update_pcie_parameters)(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap); int (*i2c_eeprom_init)(struct i2c_adapter *control); void (*i2c_eeprom_fini)(struct i2c_adapter *control); + void (*get_unique_id)(struct smu_context *smu); int (*get_dpm_clock_table)(struct smu_context *smu, struct dpm_clocks *clock_table); int (*init_microcode)(struct smu_context *smu); int (*load_microcode)(struct smu_context *smu); diff --git a/drivers/gpu/drm/amd/powerplay/smu_internal.h b/drivers/gpu/drm/amd/powerplay/smu_internal.h index 6c59eeef2590..c9440c978402 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_internal.h +++ b/drivers/gpu/drm/amd/powerplay/smu_internal.h @@ -218,6 +218,8 @@ static inline int smu_send_smc_msg(struct smu_context *smu, enum smu_message_typ ((smu)->ppt_funcs->i2c_eeprom_init ? (smu)->ppt_funcs->i2c_eeprom_init((control)) : 0) #define smu_i2c_eeprom_fini(smu, control) \ ((smu)->ppt_funcs->i2c_eeprom_fini ? (smu)->ppt_funcs->i2c_eeprom_fini((control)) : 0) +#define smu_get_unique_id(smu) \ + ((smu)->ppt_funcs->get_unique_id ? (smu)->ppt_funcs->get_unique_id((smu)) : 0) #define smu_log_thermal_throttling(smu) \ ((smu)->ppt_funcs->log_thermal_throttling_event ? (smu)->ppt_funcs->log_thermal_throttling_event((smu)) : 0) -- cgit v1.2.3 From 4cb738ab7853c66ca563246cc8b74ac7e88e02d2 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 8 Jun 2020 17:04:04 +0800 Subject: drm/amd/powerplay: drop unused code around power limit Drop unused APIs, variables and argument. Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 4 +-- drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 20 +++++-------- drivers/gpu/drm/amd/powerplay/arcturus_ppt.c | 35 ---------------------- drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 6 +--- drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 34 --------------------- drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c | 34 --------------------- drivers/gpu/drm/amd/powerplay/smu_internal.h | 2 -- 7 files changed, 10 insertions(+), 125 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index b2cdc8a1268f..395ddbe2461c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -2739,7 +2739,7 @@ static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev, return r; if (is_support_sw_smu(adev)) { - smu_get_power_limit(&adev->smu, &limit, true, true); + smu_get_power_limit(&adev->smu, &limit, true); size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000); } else if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_power_limit) { adev->powerplay.pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, true); @@ -2771,7 +2771,7 @@ static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev, return r; if (is_support_sw_smu(adev)) { - smu_get_power_limit(&adev->smu, &limit, false, true); + smu_get_power_limit(&adev->smu, &limit, false); size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000); } else if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_power_limit) { adev->powerplay.pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, false); diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index 7cde80c9614f..725ac90c0f36 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -2210,24 +2210,18 @@ int smu_set_fan_speed_rpm(struct smu_context *smu, uint32_t speed) int smu_get_power_limit(struct smu_context *smu, uint32_t *limit, - bool def, - bool lock_needed) + bool max_setting) { - int ret = 0; - - if (lock_needed) { - if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) - return -EOPNOTSUPP; + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) + return -EOPNOTSUPP; - mutex_lock(&smu->mutex); - } + mutex_lock(&smu->mutex); - *limit = (def ? smu->max_power_limit : smu->current_power_limit); + *limit = (max_setting ? smu->max_power_limit : smu->current_power_limit); - if (lock_needed) - mutex_unlock(&smu->mutex); + mutex_unlock(&smu->mutex); - return ret; + return 0; } int smu_set_power_limit(struct smu_context *smu, uint32_t limit) diff --git a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c index 66b8f143cc46..c104844b28f1 100644 --- a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c @@ -2411,13 +2411,6 @@ static bool arcturus_is_baco_supported(struct smu_context *smu) return (val & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK) ? true : false; } -static uint32_t arcturus_get_pptable_power_limit(struct smu_context *smu) -{ - PPTable_t *pptable = smu->smu_table.driver_pptable; - - return pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0]; -} - static int arcturus_set_df_cstate(struct smu_context *smu, enum pp_df_cstate state) { @@ -2544,33 +2537,6 @@ static int arcturus_set_thermal_range(struct smu_context *smu, return 0; } -static uint32_t atcturus_get_max_power_limit(struct smu_context *smu) { - uint32_t od_limit, max_power_limit; - struct smu_11_0_powerplay_table *powerplay_table = NULL; - struct smu_table_context *table_context = &smu->smu_table; - powerplay_table = table_context->power_play_table; - - max_power_limit = arcturus_get_pptable_power_limit(smu); - - if (!max_power_limit) { - // If we couldn't get the table limit, fall back on first-read value - if (!smu->default_power_limit) - smu->default_power_limit = smu->power_limit; - max_power_limit = smu->default_power_limit; - } - - if (smu->od_enabled) { - od_limit = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); - - dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_limit, smu->default_power_limit); - - max_power_limit *= (100 + od_limit); - max_power_limit /= 100; - } - - return max_power_limit; -} - static const struct pptable_funcs arcturus_ppt_funcs = { /* translate smu index into arcturus specific index */ .get_smu_msg_index = arcturus_get_smu_msg_index, @@ -2662,7 +2628,6 @@ static const struct pptable_funcs arcturus_ppt_funcs = { .allow_xgmi_power_down = arcturus_allow_xgmi_power_down, .log_thermal_throttling_event = arcturus_log_thermal_throttling_event, .set_thermal_range = arcturus_set_thermal_range, - .get_max_power_limit = atcturus_get_max_power_limit, }; void arcturus_set_ppt_funcs(struct smu_context *smu) diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h index db63ed057840..8eaa6338ad44 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -380,8 +380,6 @@ struct smu_context uint32_t pstate_mclk; bool od_enabled; - uint32_t power_limit; - uint32_t default_power_limit; uint32_t current_power_limit; uint32_t max_power_limit; @@ -573,7 +571,6 @@ struct pptable_funcs { int (*set_power_source)(struct smu_context *smu, enum smu_power_src_type power_src); void (*log_thermal_throttling_event)(struct smu_context *smu); int (*set_thermal_range)(struct smu_context *smu, struct smu_temperature_range range); - uint32_t (*get_max_power_limit)(struct smu_context *smu); }; typedef enum { @@ -616,8 +613,7 @@ int smu_set_fan_speed_rpm(struct smu_context *smu, uint32_t speed); int smu_get_power_limit(struct smu_context *smu, uint32_t *limit, - bool def, - bool lock_needed); + bool max_setting); int smu_set_power_limit(struct smu_context *smu, uint32_t limit); int smu_print_clk_levels(struct smu_context *smu, enum smu_clk_type clk_type, char *buf); diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c index 2e0836976001..186cdf6696f8 100644 --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c @@ -1916,12 +1916,6 @@ static int navi10_display_disable_memory_clock_switch(struct smu_context *smu, return ret; } -static uint32_t navi10_get_pptable_power_limit(struct smu_context *smu) -{ - PPTable_t *pptable = smu->smu_table.driver_pptable; - return pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0]; -} - static int navi10_get_power_limit(struct smu_context *smu) { struct smu_11_0_powerplay_table *powerplay_table = @@ -2380,33 +2374,6 @@ static int navi10_set_thermal_range(struct smu_context *smu, return 0; } -static uint32_t navi10_get_max_power_limit(struct smu_context *smu) { - uint32_t od_limit, max_power_limit; - struct smu_11_0_powerplay_table *powerplay_table = NULL; - struct smu_table_context *table_context = &smu->smu_table; - powerplay_table = table_context->power_play_table; - - max_power_limit = navi10_get_pptable_power_limit(smu); - - if (!max_power_limit) { - // If we couldn't get the table limit, fall back on first-read value - if (!smu->default_power_limit) - smu->default_power_limit = smu->power_limit; - max_power_limit = smu->default_power_limit; - } - - if (smu->od_enabled) { - od_limit = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); - - dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_limit, smu->default_power_limit); - - max_power_limit *= (100 + od_limit); - max_power_limit /= 100; - } - - return max_power_limit; -} - static const struct pptable_funcs navi10_ppt_funcs = { .tables_init = navi10_tables_init, .alloc_dpm_context = navi10_allocate_dpm_context, @@ -2497,7 +2464,6 @@ static const struct pptable_funcs navi10_ppt_funcs = { .disable_umc_cdr_12gbps_workaround = navi10_disable_umc_cdr_12gbps_workaround, .set_power_source = smu_v11_0_set_power_source, .set_thermal_range = navi10_set_thermal_range, - .get_max_power_limit = navi10_get_max_power_limit, }; void navi10_set_ppt_funcs(struct smu_context *smu) diff --git a/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c index 44719c110655..81cc04de9b06 100644 --- a/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c @@ -1737,12 +1737,6 @@ static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context return ret; } -static uint32_t sienna_cichlid_get_pptable_power_limit(struct smu_context *smu) -{ - PPTable_t *pptable = smu->smu_table.driver_pptable; - return pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0]; -} - static int sienna_cichlid_get_power_limit(struct smu_context *smu) { struct smu_11_0_7_powerplay_table *powerplay_table = @@ -1886,33 +1880,6 @@ static int sienna_cichlid_set_thermal_range(struct smu_context *smu, return 0; } -static uint32_t sienna_cichlid_get_max_power_limit(struct smu_context *smu) { - uint32_t od_limit, max_power_limit; - struct smu_11_0_7_powerplay_table *powerplay_table = NULL; - struct smu_table_context *table_context = &smu->smu_table; - powerplay_table = table_context->power_play_table; - - max_power_limit = sienna_cichlid_get_pptable_power_limit(smu); - - if (!max_power_limit) { - // If we couldn't get the table limit, fall back on first-read value - if (!smu->default_power_limit) - smu->default_power_limit = smu->power_limit; - max_power_limit = smu->default_power_limit; - } - - if (smu->od_enabled) { - od_limit = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]); - - dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_limit, smu->default_power_limit); - - max_power_limit *= (100 + od_limit); - max_power_limit /= 100; - } - - return max_power_limit; -} - static void sienna_cichlid_dump_pptable(struct smu_context *smu) { struct smu_table_context *table_context = &smu->smu_table; @@ -2664,7 +2631,6 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = { .set_soft_freq_limited_range = sienna_cichlid_set_soft_freq_limited_range, .override_pcie_parameters = smu_v11_0_override_pcie_parameters, .set_thermal_range = sienna_cichlid_set_thermal_range, - .get_max_power_limit = sienna_cichlid_get_max_power_limit, }; void sienna_cichlid_set_ppt_funcs(struct smu_context *smu) diff --git a/drivers/gpu/drm/amd/powerplay/smu_internal.h b/drivers/gpu/drm/amd/powerplay/smu_internal.h index 346aea9198e9..094db34ddbd1 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_internal.h +++ b/drivers/gpu/drm/amd/powerplay/smu_internal.h @@ -194,8 +194,6 @@ static inline int smu_send_smc_msg(struct smu_context *smu, enum smu_message_typ #define smu_set_thermal_range(smu, range) \ ((smu)->ppt_funcs->set_thermal_range ? (smu)->ppt_funcs->set_thermal_range((smu), (range)) : 0) -#define smu_get_max_power_limit(smu) \ - ((smu)->ppt_funcs->get_max_power_limit ? (smu)->ppt_funcs->get_max_power_limit((smu)) : 0) #define smu_disable_umc_cdr_12gbps_workaround(smu) \ ((smu)->ppt_funcs->disable_umc_cdr_12gbps_workaround ? (smu)->ppt_funcs->disable_umc_cdr_12gbps_workaround((smu)) : 0) -- cgit v1.2.3 From bd09331a74cf05f85c85e8fd144e3b35907dfc6d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 15 Jun 2020 14:29:55 -0400 Subject: drm/amdgpu/pm: update comment to clarify Overdrive interfaces Vega10 and previous asics use one interface, vega20 and newer use another. Reviewed-by: Evan Quan Acked-by: Nirmoy Das Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 395ddbe2461c..5a8e177e4f56 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -696,7 +696,7 @@ static ssize_t amdgpu_set_pp_table(struct device *dev, * default power levels, write "r" (reset) to the file to reset them. * * - * < For Vega20 > + * < For Vega20 and newer ASICs > * * Reading the file will display: * -- cgit v1.2.3 From f503fe69ebca2f7a5e1eda1b279609b033b953cd Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 15 Jun 2020 16:36:49 -0400 Subject: drm/amdgpu: fix documentation around busy_percentage Add rename the gpu busy percentage for consistency and add the mem busy percentage documentation. Reviewed-by: Evan Quan Reviewed-by: Nirmoy Das Signed-off-by: Alex Deucher --- Documentation/gpu/amdgpu.rst | 9 ++++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/Documentation/gpu/amdgpu.rst b/Documentation/gpu/amdgpu.rst index 4cc74325bf91..17112352f605 100644 --- a/Documentation/gpu/amdgpu.rst +++ b/Documentation/gpu/amdgpu.rst @@ -197,11 +197,14 @@ pp_power_profile_mode .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c :doc: pp_power_profile_mode -busy_percent -~~~~~~~~~~~~ +*_busy_percent +~~~~~~~~~~~~~~ .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c - :doc: busy_percent + :doc: gpu_busy_percent + +.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c + :doc: mem_busy_percent GPU Product Information ======================= diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 5a8e177e4f56..42bbdf49458e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1668,7 +1668,7 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev, } /** - * DOC: busy_percent + * DOC: gpu_busy_percent * * The amdgpu driver provides a sysfs API for reading how busy the GPU * is as a percentage. The file gpu_busy_percent is used for this. -- cgit v1.2.3 From 66429300e1bd9cdfbe96cfc475e4964db2a36921 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 17 Jun 2020 14:43:08 -0400 Subject: drm/amdgpu/pm: fix ref count leak when pm_runtime_get_sync fails The call to pm_runtime_get_sync increments the counter even in case of failure, leading to incorrect ref count. In case of failure, decrement the ref count before returning. Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 220 ++++++++++++++++++++++++--------- 1 file changed, 165 insertions(+), 55 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 42bbdf49458e..14cc6c546f65 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -167,8 +167,10 @@ static ssize_t amdgpu_get_power_dpm_state(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) { if (adev->smu.ppt_funcs->get_current_power_state) @@ -212,8 +214,10 @@ static ssize_t amdgpu_set_power_dpm_state(struct device *dev, return -EINVAL; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) { mutex_lock(&adev->pm.mutex); @@ -307,8 +311,10 @@ static ssize_t amdgpu_get_power_dpm_force_performance_level(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) level = smu_get_performance_level(&adev->smu); @@ -369,8 +375,10 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev, } ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) current_level = smu_get_performance_level(&adev->smu); @@ -449,8 +457,10 @@ static ssize_t amdgpu_get_pp_num_states(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) { ret = smu_get_power_num_states(&adev->smu, &data); @@ -491,8 +501,10 @@ static ssize_t amdgpu_get_pp_cur_state(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) { pm = smu_get_current_power_state(smu); @@ -567,8 +579,10 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev, state = data.states[idx]; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } /* only set user selected power states */ if (state != POWER_STATE_TYPE_INTERNAL_BOOT && @@ -608,8 +622,10 @@ static ssize_t amdgpu_get_pp_table(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) { size = smu_sys_get_pp_table(&adev->smu, (void **)&table); @@ -650,8 +666,10 @@ static ssize_t amdgpu_set_pp_table(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) { ret = smu_sys_set_pp_table(&adev->smu, (void *)buf, count); @@ -790,8 +808,10 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev, } ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) { ret = smu_od_edit_dpm_table(&adev->smu, type, @@ -847,8 +867,10 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) { size = smu_print_clk_levels(&adev->smu, SMU_OD_SCLK, buf); @@ -905,8 +927,10 @@ static ssize_t amdgpu_set_pp_features(struct device *dev, pr_debug("featuremask = 0x%llx\n", featuremask); ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) { ret = smu_sys_set_pp_feature_mask(&adev->smu, featuremask); @@ -942,8 +966,10 @@ static ssize_t amdgpu_get_pp_features(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) size = smu_sys_get_pp_feature_mask(&adev->smu, buf); @@ -1001,8 +1027,10 @@ static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) size = smu_print_clk_levels(&adev->smu, SMU_SCLK, buf); @@ -1071,8 +1099,10 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, return ret; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) ret = smu_force_clk_levels(&adev->smu, SMU_SCLK, mask, true); @@ -1101,8 +1131,10 @@ static ssize_t amdgpu_get_pp_dpm_mclk(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) size = smu_print_clk_levels(&adev->smu, SMU_MCLK, buf); @@ -1135,8 +1167,10 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, return ret; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) ret = smu_force_clk_levels(&adev->smu, SMU_MCLK, mask, true); @@ -1165,8 +1199,10 @@ static ssize_t amdgpu_get_pp_dpm_socclk(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) size = smu_print_clk_levels(&adev->smu, SMU_SOCCLK, buf); @@ -1199,8 +1235,10 @@ static ssize_t amdgpu_set_pp_dpm_socclk(struct device *dev, return ret; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) ret = smu_force_clk_levels(&adev->smu, SMU_SOCCLK, mask, true); @@ -1231,8 +1269,10 @@ static ssize_t amdgpu_get_pp_dpm_fclk(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) size = smu_print_clk_levels(&adev->smu, SMU_FCLK, buf); @@ -1265,8 +1305,10 @@ static ssize_t amdgpu_set_pp_dpm_fclk(struct device *dev, return ret; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) ret = smu_force_clk_levels(&adev->smu, SMU_FCLK, mask, true); @@ -1297,8 +1339,10 @@ static ssize_t amdgpu_get_pp_dpm_dcefclk(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) size = smu_print_clk_levels(&adev->smu, SMU_DCEFCLK, buf); @@ -1331,8 +1375,10 @@ static ssize_t amdgpu_set_pp_dpm_dcefclk(struct device *dev, return ret; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) ret = smu_force_clk_levels(&adev->smu, SMU_DCEFCLK, mask, true); @@ -1363,8 +1409,10 @@ static ssize_t amdgpu_get_pp_dpm_pcie(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) size = smu_print_clk_levels(&adev->smu, SMU_PCIE, buf); @@ -1397,8 +1445,10 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, return ret; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) ret = smu_force_clk_levels(&adev->smu, SMU_PCIE, mask, true); @@ -1429,8 +1479,10 @@ static ssize_t amdgpu_get_pp_sclk_od(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) value = smu_get_od_percentage(&(adev->smu), SMU_OD_SCLK); @@ -1462,8 +1514,10 @@ static ssize_t amdgpu_set_pp_sclk_od(struct device *dev, return -EINVAL; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) { value = smu_set_od_percentage(&(adev->smu), SMU_OD_SCLK, (uint32_t)value); @@ -1498,8 +1552,10 @@ static ssize_t amdgpu_get_pp_mclk_od(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) value = smu_get_od_percentage(&(adev->smu), SMU_OD_MCLK); @@ -1531,8 +1587,10 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev, return -EINVAL; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) { value = smu_set_od_percentage(&(adev->smu), SMU_OD_MCLK, (uint32_t)value); @@ -1587,8 +1645,10 @@ static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) size = smu_get_power_profile_mode(&adev->smu, buf); @@ -1650,8 +1710,10 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev, parameter[parameter_size] = profile_mode; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } if (is_support_sw_smu(adev)) ret = smu_set_power_profile_mode(&adev->smu, parameter, parameter_size, true); @@ -1687,8 +1749,10 @@ static ssize_t amdgpu_get_gpu_busy_percent(struct device *dev, return -EPERM; r = pm_runtime_get_sync(ddev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(ddev->dev); return r; + } /* read the IP busy sensor */ r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_LOAD, @@ -1723,8 +1787,10 @@ static ssize_t amdgpu_get_mem_busy_percent(struct device *dev, return -EPERM; r = pm_runtime_get_sync(ddev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(ddev->dev); return r; + } /* read the IP busy sensor */ r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MEM_LOAD, @@ -1770,8 +1836,10 @@ static ssize_t amdgpu_get_pcie_bw(struct device *dev, return -ENODATA; ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); return ret; + } amdgpu_asic_get_pcie_usage(adev, &count0, &count1); @@ -2073,8 +2141,10 @@ static ssize_t amdgpu_hwmon_show_temp(struct device *dev, return -EINVAL; r = pm_runtime_get_sync(adev->ddev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return r; + } switch (channel) { case PP_TEMP_JUNCTION: @@ -2204,8 +2274,10 @@ static ssize_t amdgpu_hwmon_get_pwm1_enable(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(adev->ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return ret; + } if (is_support_sw_smu(adev)) { pwm_mode = smu_get_fan_control_mode(&adev->smu); @@ -2242,8 +2314,10 @@ static ssize_t amdgpu_hwmon_set_pwm1_enable(struct device *dev, return err; ret = pm_runtime_get_sync(adev->ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return ret; + } if (is_support_sw_smu(adev)) { smu_set_fan_control_mode(&adev->smu, value); @@ -2290,8 +2364,10 @@ static ssize_t amdgpu_hwmon_set_pwm1(struct device *dev, return -EPERM; err = pm_runtime_get_sync(adev->ddev->dev); - if (err < 0) + if (err < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return err; + } if (is_support_sw_smu(adev)) pwm_mode = smu_get_fan_control_mode(&adev->smu); @@ -2342,8 +2418,10 @@ static ssize_t amdgpu_hwmon_get_pwm1(struct device *dev, return -EPERM; err = pm_runtime_get_sync(adev->ddev->dev); - if (err < 0) + if (err < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return err; + } if (is_support_sw_smu(adev)) err = smu_get_fan_speed_percent(&adev->smu, &speed); @@ -2375,8 +2453,10 @@ static ssize_t amdgpu_hwmon_get_fan1_input(struct device *dev, return -EPERM; err = pm_runtime_get_sync(adev->ddev->dev); - if (err < 0) + if (err < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return err; + } if (is_support_sw_smu(adev)) err = smu_get_fan_speed_rpm(&adev->smu, &speed); @@ -2407,8 +2487,10 @@ static ssize_t amdgpu_hwmon_get_fan1_min(struct device *dev, return -EPERM; r = pm_runtime_get_sync(adev->ddev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return r; + } r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MIN_FAN_RPM, (void *)&min_rpm, &size); @@ -2435,8 +2517,10 @@ static ssize_t amdgpu_hwmon_get_fan1_max(struct device *dev, return -EPERM; r = pm_runtime_get_sync(adev->ddev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return r; + } r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MAX_FAN_RPM, (void *)&max_rpm, &size); @@ -2462,8 +2546,10 @@ static ssize_t amdgpu_hwmon_get_fan1_target(struct device *dev, return -EPERM; err = pm_runtime_get_sync(adev->ddev->dev); - if (err < 0) + if (err < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return err; + } if (is_support_sw_smu(adev)) err = smu_get_fan_speed_rpm(&adev->smu, &rpm); @@ -2494,8 +2580,10 @@ static ssize_t amdgpu_hwmon_set_fan1_target(struct device *dev, return -EPERM; err = pm_runtime_get_sync(adev->ddev->dev); - if (err < 0) + if (err < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return err; + } if (is_support_sw_smu(adev)) pwm_mode = smu_get_fan_control_mode(&adev->smu); @@ -2543,8 +2631,10 @@ static ssize_t amdgpu_hwmon_get_fan1_enable(struct device *dev, return -EPERM; ret = pm_runtime_get_sync(adev->ddev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return ret; + } if (is_support_sw_smu(adev)) { pwm_mode = smu_get_fan_control_mode(&adev->smu); @@ -2589,8 +2679,10 @@ static ssize_t amdgpu_hwmon_set_fan1_enable(struct device *dev, return -EINVAL; err = pm_runtime_get_sync(adev->ddev->dev); - if (err < 0) + if (err < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return err; + } if (is_support_sw_smu(adev)) { smu_set_fan_control_mode(&adev->smu, pwm_mode); @@ -2621,8 +2713,10 @@ static ssize_t amdgpu_hwmon_show_vddgfx(struct device *dev, return -EPERM; r = pm_runtime_get_sync(adev->ddev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return r; + } /* get the voltage */ r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDGFX, @@ -2660,8 +2754,10 @@ static ssize_t amdgpu_hwmon_show_vddnb(struct device *dev, return -EINVAL; r = pm_runtime_get_sync(adev->ddev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return r; + } /* get the voltage */ r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB, @@ -2696,8 +2792,10 @@ static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev, return -EPERM; r = pm_runtime_get_sync(adev->ddev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return r; + } /* get the voltage */ r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_POWER, @@ -2735,8 +2833,10 @@ static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev, return -EPERM; r = pm_runtime_get_sync(adev->ddev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return r; + } if (is_support_sw_smu(adev)) { smu_get_power_limit(&adev->smu, &limit, true); @@ -2767,8 +2867,10 @@ static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev, return -EPERM; r = pm_runtime_get_sync(adev->ddev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return r; + } if (is_support_sw_smu(adev)) { smu_get_power_limit(&adev->smu, &limit, false); @@ -2810,8 +2912,10 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device *dev, err = pm_runtime_get_sync(adev->ddev->dev); - if (err < 0) + if (err < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return err; + } if (is_support_sw_smu(adev)) err = smu_set_power_limit(&adev->smu, value); @@ -2841,8 +2945,10 @@ static ssize_t amdgpu_hwmon_show_sclk(struct device *dev, return -EPERM; r = pm_runtime_get_sync(adev->ddev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return r; + } /* get the sclk */ r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_SCLK, @@ -2876,8 +2982,10 @@ static ssize_t amdgpu_hwmon_show_mclk(struct device *dev, return -EPERM; r = pm_runtime_get_sync(adev->ddev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(adev->ddev->dev); return r; + } /* get the sclk */ r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_MCLK, @@ -3739,8 +3847,10 @@ static int amdgpu_debugfs_pm_info(struct seq_file *m, void *data) return -EPERM; r = pm_runtime_get_sync(dev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(dev->dev); return r; + } amdgpu_device_ip_get_clockgating_state(adev, &flags); seq_printf(m, "Clock Gating Flags Mask: 0x%x\n", flags); -- cgit v1.2.3 From 7c8e0835ebb1682a042aeaec7cef6dc45aebb0cb Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 18 Jun 2020 11:26:22 +0100 Subject: drm/amdgpu: remove redundant initialization of variable ret The variable ret is being initialized with a value that is never read and it is being updated later with a new value. The initialization is redundant and can be removed. Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 14cc6c546f65..13870ac8f610 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1669,7 +1669,7 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev, const char *buf, size_t count) { - int ret = 0xff; + int ret; struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; uint32_t parameter_size = 0; -- cgit v1.2.3 From a2e6ad1900124c874b06cde130512721aba695c0 Mon Sep 17 00:00:00 2001 From: Wenhui Sheng Date: Fri, 12 Jun 2020 17:18:39 +0800 Subject: drm/amdgpu: remove perf level dpm in one-VF On Navi12 platform, node power_dpm_force_performance_level doesn't work correctly in one-VF mode with at least three smu messages not supported: SMU_MSG_SetSoftMaxByFreq SMU_MSG_SetSoftMinByFreq SMU_MSG_TransferTableDram2Smu Reviewed-by: Kevin Wang Signed-off-by: Wenhui Sheng Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 13870ac8f610..347b06d3c140 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1945,7 +1945,7 @@ static ssize_t amdgpu_set_thermal_throttling_logging(struct device *dev, static struct amdgpu_device_attr amdgpu_device_attrs[] = { AMDGPU_DEVICE_ATTR_RW(power_dpm_state, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), - AMDGPU_DEVICE_ATTR_RW(power_dpm_force_performance_level, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), + AMDGPU_DEVICE_ATTR_RW(power_dpm_force_performance_level, ATTR_FLAG_BASIC), AMDGPU_DEVICE_ATTR_RO(pp_num_states, ATTR_FLAG_BASIC), AMDGPU_DEVICE_ATTR_RO(pp_cur_state, ATTR_FLAG_BASIC), AMDGPU_DEVICE_ATTR_RW(pp_force_state, ATTR_FLAG_BASIC), -- cgit v1.2.3 From a71a4f501586c9a1c710c3d5c1db4ff6650e5fc4 Mon Sep 17 00:00:00 2001 From: Alex Jivin Date: Wed, 24 Jun 2020 13:37:20 -0400 Subject: drm/amdgpu: SI support for UVD and VCE power managment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port functionality from the Radeon driver to support UVD and VCE power management. Signed-off-by: Alex Jivin Reviewed-by: Alex Deucher Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 67 +++++++++++++++++++++++++--------- drivers/gpu/drm/amd/amdgpu/si_dpm.c | 19 ++++++++++ 2 files changed, 68 insertions(+), 18 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 347b06d3c140..26c8e39a78bd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -3558,21 +3558,36 @@ void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) { int ret = 0; - ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable); - if (ret) - DRM_ERROR("Dpm %s uvd failed, ret = %d. \n", - enable ? "enable" : "disable", ret); - - /* enable/disable Low Memory PState for UVD (4k videos) */ - if (adev->asic_type == CHIP_STONEY && - adev->uvd.decode_image_width >= WIDTH_4K) { - struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; + if (adev->family == AMDGPU_FAMILY_SI) { + if (enable) { + mutex_lock(&adev->pm.mutex); + adev->pm.dpm.uvd_active = true; + adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD; + mutex_unlock(&adev->pm.mutex); + } else { + mutex_lock(&adev->pm.mutex); + adev->pm.dpm.uvd_active = false; + mutex_unlock(&adev->pm.mutex); + } - if (hwmgr && hwmgr->hwmgr_func && - hwmgr->hwmgr_func->update_nbdpm_pstate) - hwmgr->hwmgr_func->update_nbdpm_pstate(hwmgr, - !enable, - true); + amdgpu_pm_compute_clocks(adev); + } else { + ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable); + if (ret) + DRM_ERROR("Dpm %s uvd failed, ret = %d. \n", + enable ? "enable" : "disable", ret); + + /* enable/disable Low Memory PState for UVD (4k videos) */ + if (adev->asic_type == CHIP_STONEY && + adev->uvd.decode_image_width >= WIDTH_4K) { + struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; + + if (hwmgr && hwmgr->hwmgr_func && + hwmgr->hwmgr_func->update_nbdpm_pstate) + hwmgr->hwmgr_func->update_nbdpm_pstate(hwmgr, + !enable, + true); + } } } @@ -3580,10 +3595,26 @@ void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable) { int ret = 0; - ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable); - if (ret) - DRM_ERROR("Dpm %s vce failed, ret = %d. \n", - enable ? "enable" : "disable", ret); + if (adev->family == AMDGPU_FAMILY_SI) { + if (enable) { + mutex_lock(&adev->pm.mutex); + adev->pm.dpm.vce_active = true; + /* XXX select vce level based on ring/task */ + adev->pm.dpm.vce_level = AMD_VCE_LEVEL_AC_ALL; + mutex_unlock(&adev->pm.mutex); + } else { + mutex_lock(&adev->pm.mutex); + adev->pm.dpm.vce_active = false; + mutex_unlock(&adev->pm.mutex); + } + + amdgpu_pm_compute_clocks(adev); + } else { + ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable); + if (ret) + DRM_ERROR("Dpm %s vce failed, ret = %d. \n", + enable ? "enable" : "disable", ret); + } } void amdgpu_pm_print_power_states(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index c00ba4b23c9a..ea914b256ebd 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c @@ -6953,6 +6953,24 @@ static int si_power_control_set_level(struct amdgpu_device *adev) return 0; } +static void si_set_vce_clock(struct amdgpu_device *adev, + struct amdgpu_ps *new_rps, + struct amdgpu_ps *old_rps) +{ + if ((old_rps->evclk != new_rps->evclk) || + (old_rps->ecclk != new_rps->ecclk)) { + /* Turn the clocks on when encoding, off otherwise */ + if (new_rps->evclk || new_rps->ecclk) { + /* Place holder for future VCE1.0 porting to amdgpu + vce_v1_0_enable_mgcg(adev, false, false);*/ + } else { + /* Place holder for future VCE1.0 porting to amdgpu + vce_v1_0_enable_mgcg(adev, true, false); + amdgpu_asic_set_vce_clocks(adev, new_rps->evclk, new_rps->ecclk);*/ + } + } +} + static int si_dpm_set_power_state(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -7029,6 +7047,7 @@ static int si_dpm_set_power_state(void *handle) return ret; } ni_set_uvd_clock_after_set_eng_clock(adev, new_ps, old_ps); + si_set_vce_clock(adev, new_ps, old_ps); if (eg_pi->pcie_performance_request) si_notify_link_speed_change_after_state_change(adev, new_ps, old_ps); ret = si_set_power_state_conditionally_enable_ulv(adev, new_ps); -- cgit v1.2.3 From 2a80f883988862dc2c52f79291ed38388246cf36 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 1 Jul 2020 12:00:08 -0400 Subject: drm/amdgpu: use %u rather than %d for sclk/mclk Large clock values may overflow and show up as negative. Reported by prOMiNd on IRC. Acked-by: Nirmoy Das Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 26c8e39a78bd..838d6d51904c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -2960,7 +2960,7 @@ static ssize_t amdgpu_hwmon_show_sclk(struct device *dev, if (r) return r; - return snprintf(buf, PAGE_SIZE, "%d\n", sclk * 10 * 1000); + return snprintf(buf, PAGE_SIZE, "%u\n", sclk * 10 * 1000); } static ssize_t amdgpu_hwmon_show_sclk_label(struct device *dev, @@ -2997,7 +2997,7 @@ static ssize_t amdgpu_hwmon_show_mclk(struct device *dev, if (r) return r; - return snprintf(buf, PAGE_SIZE, "%d\n", mclk * 10 * 1000); + return snprintf(buf, PAGE_SIZE, "%u\n", mclk * 10 * 1000); } static ssize_t amdgpu_hwmon_show_mclk_label(struct device *dev, -- cgit v1.2.3 From fa4a882008a71bf18a30c7f548572ecf19882fbd Mon Sep 17 00:00:00 2001 From: Alex Jivin Date: Mon, 6 Jul 2020 11:07:19 -0400 Subject: drm/amdgpu: Move the mutex lock/unlock out Move the mutext lock/unlock outside of the if(), as the mutex is always taken: either in the if() branch or in the else branch. Signed-off-by: Alex Jivin Suggested-By: Luben Tukov Reviewed-by: Luben Tuikov Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 838d6d51904c..d2401379bd33 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -3559,16 +3559,14 @@ void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) int ret = 0; if (adev->family == AMDGPU_FAMILY_SI) { + mutex_lock(&adev->pm.mutex); if (enable) { - mutex_lock(&adev->pm.mutex); adev->pm.dpm.uvd_active = true; adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD; - mutex_unlock(&adev->pm.mutex); } else { - mutex_lock(&adev->pm.mutex); adev->pm.dpm.uvd_active = false; - mutex_unlock(&adev->pm.mutex); } + mutex_unlock(&adev->pm.mutex); amdgpu_pm_compute_clocks(adev); } else { @@ -3596,17 +3594,15 @@ void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable) int ret = 0; if (adev->family == AMDGPU_FAMILY_SI) { + mutex_lock(&adev->pm.mutex); if (enable) { - mutex_lock(&adev->pm.mutex); adev->pm.dpm.vce_active = true; /* XXX select vce level based on ring/task */ adev->pm.dpm.vce_level = AMD_VCE_LEVEL_AC_ALL; - mutex_unlock(&adev->pm.mutex); } else { - mutex_lock(&adev->pm.mutex); adev->pm.dpm.vce_active = false; - mutex_unlock(&adev->pm.mutex); } + mutex_unlock(&adev->pm.mutex); amdgpu_pm_compute_clocks(adev); } else { -- cgit v1.2.3 From 42f75c849f1786ae53209cec33376c4dbafe600c Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Thu, 2 Jul 2020 12:42:06 +0800 Subject: drm/amd/powerplay: drop unused APIs and parameters Leftover of previous performance level setting cleanups. Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 12 ++++++------ drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 9 +++------ drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 12 +----------- drivers/gpu/drm/amd/powerplay/renoir_ppt.c | 2 -- drivers/gpu/drm/amd/powerplay/smu_internal.h | 5 ----- 5 files changed, 10 insertions(+), 30 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index d2401379bd33..20f39aa04fb9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1105,7 +1105,7 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, } if (is_support_sw_smu(adev)) - ret = smu_force_clk_levels(&adev->smu, SMU_SCLK, mask, true); + ret = smu_force_clk_levels(&adev->smu, SMU_SCLK, mask); else if (adev->powerplay.pp_funcs->force_clock_level) ret = amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask); @@ -1173,7 +1173,7 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, } if (is_support_sw_smu(adev)) - ret = smu_force_clk_levels(&adev->smu, SMU_MCLK, mask, true); + ret = smu_force_clk_levels(&adev->smu, SMU_MCLK, mask); else if (adev->powerplay.pp_funcs->force_clock_level) ret = amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask); @@ -1241,7 +1241,7 @@ static ssize_t amdgpu_set_pp_dpm_socclk(struct device *dev, } if (is_support_sw_smu(adev)) - ret = smu_force_clk_levels(&adev->smu, SMU_SOCCLK, mask, true); + ret = smu_force_clk_levels(&adev->smu, SMU_SOCCLK, mask); else if (adev->powerplay.pp_funcs->force_clock_level) ret = amdgpu_dpm_force_clock_level(adev, PP_SOCCLK, mask); else @@ -1311,7 +1311,7 @@ static ssize_t amdgpu_set_pp_dpm_fclk(struct device *dev, } if (is_support_sw_smu(adev)) - ret = smu_force_clk_levels(&adev->smu, SMU_FCLK, mask, true); + ret = smu_force_clk_levels(&adev->smu, SMU_FCLK, mask); else if (adev->powerplay.pp_funcs->force_clock_level) ret = amdgpu_dpm_force_clock_level(adev, PP_FCLK, mask); else @@ -1381,7 +1381,7 @@ static ssize_t amdgpu_set_pp_dpm_dcefclk(struct device *dev, } if (is_support_sw_smu(adev)) - ret = smu_force_clk_levels(&adev->smu, SMU_DCEFCLK, mask, true); + ret = smu_force_clk_levels(&adev->smu, SMU_DCEFCLK, mask); else if (adev->powerplay.pp_funcs->force_clock_level) ret = amdgpu_dpm_force_clock_level(adev, PP_DCEFCLK, mask); else @@ -1451,7 +1451,7 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, } if (is_support_sw_smu(adev)) - ret = smu_force_clk_levels(&adev->smu, SMU_PCIE, mask, true); + ret = smu_force_clk_levels(&adev->smu, SMU_PCIE, mask); else if (adev->powerplay.pp_funcs->force_clock_level) ret = amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask); else diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index ff35dce24a3a..b0d863f4f55a 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -1764,8 +1764,7 @@ int smu_set_display_count(struct smu_context *smu, uint32_t count) int smu_force_clk_levels(struct smu_context *smu, enum smu_clk_type clk_type, - uint32_t mask, - bool lock_needed) + uint32_t mask) { struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); int ret = 0; @@ -1778,14 +1777,12 @@ int smu_force_clk_levels(struct smu_context *smu, return -EINVAL; } - if (lock_needed) - mutex_lock(&smu->mutex); + mutex_lock(&smu->mutex); if (smu->ppt_funcs && smu->ppt_funcs->force_clk_levels) ret = smu->ppt_funcs->force_clk_levels(smu, clk_type, mask); - if (lock_needed) - mutex_unlock(&smu->mutex); + mutex_unlock(&smu->mutex); return ret; } diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h index 6a0b4382c86f..c560c3d23581 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -476,13 +476,6 @@ struct pptable_funcs { int (*display_config_changed)(struct smu_context *smu); int (*apply_clocks_adjust_rules)(struct smu_context *smu); int (*notify_smc_display_config)(struct smu_context *smu); - int (*force_dpm_limit_value)(struct smu_context *smu, bool highest); - int (*unforce_dpm_levels)(struct smu_context *smu); - int (*get_profiling_clk_mask)(struct smu_context *smu, - enum amd_dpm_forced_level level, - uint32_t *sclk_mask, - uint32_t *mclk_mask, - uint32_t *soc_mask); int (*set_cpu_power_state)(struct smu_context *smu); bool (*is_dpm_running)(struct smu_context *smu); int (*tables_init)(struct smu_context *smu, struct smu_table *tables); @@ -498,8 +491,6 @@ struct pptable_funcs { int (*display_disable_memory_clock_switch)(struct smu_context *smu, bool disable_memory_clock_switch); void (*dump_pptable)(struct smu_context *smu); int (*get_power_limit)(struct smu_context *smu); - int (*get_dpm_clk_limited)(struct smu_context *smu, enum smu_clk_type clk_type, - uint32_t dpm_level, uint32_t *freq); int (*set_df_cstate)(struct smu_context *smu, enum pp_df_cstate state); int (*allow_xgmi_power_down)(struct smu_context *smu, bool en); int (*update_pcie_parameters)(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap); @@ -749,8 +740,7 @@ size_t smu_sys_get_pp_feature_mask(struct smu_context *smu, char *buf); int smu_sys_set_pp_feature_mask(struct smu_context *smu, uint64_t new_mask); int smu_force_clk_levels(struct smu_context *smu, enum smu_clk_type clk_type, - uint32_t mask, - bool lock_needed); + uint32_t mask); int smu_set_mp1_state(struct smu_context *smu, enum pp_mp1_state mp1_state); int smu_set_df_cstate(struct smu_context *smu, diff --git a/drivers/gpu/drm/amd/powerplay/renoir_ppt.c b/drivers/gpu/drm/amd/powerplay/renoir_ppt.c index fc2bd4e558cb..79cadc2df0d5 100644 --- a/drivers/gpu/drm/amd/powerplay/renoir_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/renoir_ppt.c @@ -1069,13 +1069,11 @@ static const struct pptable_funcs renoir_ppt_funcs = { .get_smu_table_index = renoir_get_smu_table_index, .tables_init = renoir_tables_init, .set_power_state = NULL, - .get_dpm_clk_limited = renoir_get_dpm_clk_limited, .print_clk_levels = renoir_print_clk_levels, .get_current_power_state = renoir_get_current_power_state, .dpm_set_vcn_enable = renoir_dpm_set_vcn_enable, .dpm_set_jpeg_enable = renoir_dpm_set_jpeg_enable, .get_workload_type = renoir_get_workload_type, - .get_profiling_clk_mask = renoir_get_profiling_clk_mask, .force_clk_levels = renoir_force_clk_levels, .set_power_profile_mode = renoir_set_power_profile_mode, .set_performance_level = renoir_set_performance_level, diff --git a/drivers/gpu/drm/amd/powerplay/smu_internal.h b/drivers/gpu/drm/amd/powerplay/smu_internal.h index 91d3965bbe80..727498a6e76d 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_internal.h +++ b/drivers/gpu/drm/amd/powerplay/smu_internal.h @@ -68,8 +68,6 @@ #define smu_display_config_changed(smu) smu_ppt_funcs(display_config_changed, 0 , smu) #define smu_apply_clocks_adjust_rules(smu) smu_ppt_funcs(apply_clocks_adjust_rules, 0, smu) #define smu_notify_smc_display_config(smu) smu_ppt_funcs(notify_smc_display_config, 0, smu) -#define smu_force_dpm_limit_value(smu, highest) smu_ppt_funcs(force_dpm_limit_value, 0, smu, highest) -#define smu_unforce_dpm_levels(smu) smu_ppt_funcs(unforce_dpm_levels, 0, smu) #define smu_set_cpu_power_state(smu) smu_ppt_funcs(set_cpu_power_state, 0, smu) #define smu_msg_get_index(smu, msg) smu_ppt_funcs(get_smu_msg_index, -EINVAL, smu, msg) #define smu_clk_get_index(smu, clk) smu_ppt_funcs(get_smu_clk_index, -EINVAL, smu, clk) @@ -92,7 +90,6 @@ #define smu_get_dpm_ultimate_freq(smu, param, min, max) smu_ppt_funcs(get_dpm_ultimate_freq, 0, smu, param, min, max) #define smu_asic_set_performance_level(smu, level) smu_ppt_funcs(set_performance_level, -EINVAL, smu, level) #define smu_dump_pptable(smu) smu_ppt_funcs(dump_pptable, 0, smu) -#define smu_get_dpm_clk_limited(smu, clk_type, dpm_level, freq) smu_ppt_funcs(get_dpm_clk_limited, -EINVAL, smu, clk_type, dpm_level, freq) #define smu_override_pcie_parameters(smu) smu_ppt_funcs(override_pcie_parameters, 0, smu) #define smu_update_pcie_parameters(smu, pcie_gen_cap, pcie_width_cap) smu_ppt_funcs(update_pcie_parameters, 0, smu, pcie_gen_cap, pcie_width_cap) #define smu_set_thermal_range(smu, range) smu_ppt_funcs(set_thermal_range, 0, smu, range) @@ -103,7 +100,5 @@ #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_profiling_clk_mask(smu, level, sclk_mask, mclk_mask, soc_mask) \ - smu_ppt_funcs(get_profiling_clk_mask, 0, smu, level, sclk_mask, mclk_mask, soc_mask) #endif -- cgit v1.2.3 From 9cb268215dbb186f4eaed589bda1a7a50ccabdc8 Mon Sep 17 00:00:00 2001 From: Paweł Gronowski Date: Sun, 19 Jul 2020 17:54:53 +0200 Subject: drm/amdgpu: Fix NULL dereference in dpm sysfs handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NULL dereference occurs when string that is not ended with space or newline is written to some dpm sysfs interface (for example pp_dpm_sclk). This happens because strsep replaces the tmp with NULL if the delimiter is not present in string, which is then dereferenced by tmp[0]. Reproduction example: sudo sh -c 'echo -n 1 > /sys/class/drm/card0/device/pp_dpm_sclk' Signed-off-by: Paweł Gronowski Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 20f39aa04fb9..5f20cadee343 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -796,8 +796,7 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev, tmp_str++; while (isspace(*++tmp_str)); - while (tmp_str[0]) { - sub_str = strsep(&tmp_str, delimiter); + while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) { ret = kstrtol(sub_str, 0, ¶meter[parameter_size]); if (ret) return -EINVAL; @@ -1067,8 +1066,7 @@ static ssize_t amdgpu_read_mask(const char *buf, size_t count, uint32_t *mask) memcpy(buf_cpy, buf, bytes); buf_cpy[bytes] = '\0'; tmp = buf_cpy; - while (tmp[0]) { - sub_str = strsep(&tmp, delimiter); + while ((sub_str = strsep(&tmp, delimiter)) != NULL) { if (strlen(sub_str)) { ret = kstrtol(sub_str, 0, &level); if (ret) @@ -1697,8 +1695,7 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev, i++; memcpy(buf_cpy, buf, count-i); tmp_str = buf_cpy; - while (tmp_str[0]) { - sub_str = strsep(&tmp_str, delimiter); + while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) { ret = kstrtol(sub_str, 0, ¶meter[parameter_size]); if (ret) return -EINVAL; -- cgit v1.2.3 From a676a97623d399f7a2174b347d688412864d385a Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Mon, 27 Jul 2020 16:19:45 +0800 Subject: drm/amdgpu: skip crit temperature values on APU (v2) It doesn't expose PPTable descriptor on APU platform. So max/min temperature values cannot be got from APU platform. v2: Stoney needs to skip crit temperature as well. Signed-off-by: Huang Rui Reviewed-by: Kevin Wang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 5f20cadee343..e4dbf14320b6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -3212,6 +3212,12 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, attr == &sensor_dev_attr_fan1_enable.dev_attr.attr)) return 0; + /* Skip crit temp on APU */ + if ((adev->flags & AMD_IS_APU) && (adev->family >= AMDGPU_FAMILY_CZ) && + (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr || + attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr)) + return 0; + /* Skip limit attributes if DPM is not enabled */ if (!adev->pm.dpm_enabled && (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr || -- cgit v1.2.3