Commit d78c227f authored by Mario Limonciello's avatar Mario Limonciello Committed by Alex Deucher

drm/amd: Add amdgpu_hwmon_get_sensor_generic()

Many sensor function have a lot of boilerplate checks.  Move these
into a generic amdgpu_hwmon_get_sensor_generic() instead.

No intended functional changes.
Signed-off-by: default avatarMario Limonciello <mario.limonciello@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 8d724442
...@@ -1467,6 +1467,32 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev, ...@@ -1467,6 +1467,32 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
return -EINVAL; return -EINVAL;
} }
static unsigned int amdgpu_hwmon_get_sensor_generic(struct amdgpu_device *adev,
enum amd_pp_sensors sensor,
void *query)
{
int r, size = sizeof(uint32_t);
if (amdgpu_in_reset(adev))
return -EPERM;
if (adev->in_suspend && !adev->in_runpm)
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;
}
/* get the sensor value */
r = amdgpu_dpm_read_sensor(adev, sensor, query, &size);
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
/** /**
* DOC: gpu_busy_percent * DOC: gpu_busy_percent
* *
...@@ -1481,26 +1507,10 @@ static ssize_t amdgpu_get_gpu_busy_percent(struct device *dev, ...@@ -1481,26 +1507,10 @@ static ssize_t amdgpu_get_gpu_busy_percent(struct device *dev,
{ {
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev); struct amdgpu_device *adev = drm_to_adev(ddev);
int r, value, size = sizeof(value); unsigned int value;
int r;
if (amdgpu_in_reset(adev))
return -EPERM;
if (adev->in_suspend && !adev->in_runpm)
return -EPERM;
r = pm_runtime_get_sync(ddev->dev);
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,
(void *)&value, &size);
pm_runtime_mark_last_busy(ddev->dev);
pm_runtime_put_autosuspend(ddev->dev);
r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GPU_LOAD, &value);
if (r) if (r)
return r; return r;
...@@ -1521,26 +1531,10 @@ static ssize_t amdgpu_get_mem_busy_percent(struct device *dev, ...@@ -1521,26 +1531,10 @@ static ssize_t amdgpu_get_mem_busy_percent(struct device *dev,
{ {
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev); struct amdgpu_device *adev = drm_to_adev(ddev);
int r, value, size = sizeof(value); unsigned int value;
int r;
if (amdgpu_in_reset(adev))
return -EPERM;
if (adev->in_suspend && !adev->in_runpm)
return -EPERM;
r = pm_runtime_get_sync(ddev->dev);
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,
(void *)&value, &size);
pm_runtime_mark_last_busy(ddev->dev);
pm_runtime_put_autosuspend(ddev->dev);
r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MEM_LOAD, &value);
if (r) if (r)
return r; return r;
...@@ -1814,45 +1808,15 @@ static ssize_t amdgpu_get_gpu_metrics(struct device *dev, ...@@ -1814,45 +1808,15 @@ static ssize_t amdgpu_get_gpu_metrics(struct device *dev,
return size; return size;
} }
static int amdgpu_device_read_powershift(struct amdgpu_device *adev,
uint32_t *ss_power, bool dgpu_share)
{
struct drm_device *ddev = adev_to_drm(adev);
uint32_t size;
int r = 0;
if (amdgpu_in_reset(adev))
return -EPERM;
if (adev->in_suspend && !adev->in_runpm)
return -EPERM;
r = pm_runtime_get_sync(ddev->dev);
if (r < 0) {
pm_runtime_put_autosuspend(ddev->dev);
return r;
}
if (dgpu_share)
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE,
(void *)ss_power, &size);
else
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_APU_SHARE,
(void *)ss_power, &size);
pm_runtime_mark_last_busy(ddev->dev);
pm_runtime_put_autosuspend(ddev->dev);
return r;
}
static int amdgpu_show_powershift_percent(struct device *dev, static int amdgpu_show_powershift_percent(struct device *dev,
char *buf, bool dgpu_share) char *buf, enum amd_pp_sensors sensor)
{ {
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev); struct amdgpu_device *adev = drm_to_adev(ddev);
uint32_t ss_power; uint32_t ss_power;
int r = 0, i; int r = 0, i;
r = amdgpu_device_read_powershift(adev, &ss_power, dgpu_share); r = amdgpu_hwmon_get_sensor_generic(adev, sensor, (void *)&ss_power);
if (r == -EOPNOTSUPP) { if (r == -EOPNOTSUPP) {
/* sensor not available on dGPU, try to read from APU */ /* sensor not available on dGPU, try to read from APU */
adev = NULL; adev = NULL;
...@@ -1865,14 +1829,15 @@ static int amdgpu_show_powershift_percent(struct device *dev, ...@@ -1865,14 +1829,15 @@ static int amdgpu_show_powershift_percent(struct device *dev,
} }
mutex_unlock(&mgpu_info.mutex); mutex_unlock(&mgpu_info.mutex);
if (adev) if (adev)
r = amdgpu_device_read_powershift(adev, &ss_power, dgpu_share); r = amdgpu_hwmon_get_sensor_generic(adev, sensor, (void *)&ss_power);
} }
if (!r) if (r)
r = sysfs_emit(buf, "%u%%\n", ss_power); return r;
return r; return sysfs_emit(buf, "%u%%\n", ss_power);
} }
/** /**
* DOC: smartshift_apu_power * DOC: smartshift_apu_power
* *
...@@ -1886,7 +1851,7 @@ static int amdgpu_show_powershift_percent(struct device *dev, ...@@ -1886,7 +1851,7 @@ static int amdgpu_show_powershift_percent(struct device *dev,
static ssize_t amdgpu_get_smartshift_apu_power(struct device *dev, struct device_attribute *attr, static ssize_t amdgpu_get_smartshift_apu_power(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
return amdgpu_show_powershift_percent(dev, buf, false); return amdgpu_show_powershift_percent(dev, buf, AMDGPU_PP_SENSOR_SS_APU_SHARE);
} }
/** /**
...@@ -1902,7 +1867,7 @@ static ssize_t amdgpu_get_smartshift_apu_power(struct device *dev, struct device ...@@ -1902,7 +1867,7 @@ static ssize_t amdgpu_get_smartshift_apu_power(struct device *dev, struct device
static ssize_t amdgpu_get_smartshift_dgpu_power(struct device *dev, struct device_attribute *attr, static ssize_t amdgpu_get_smartshift_dgpu_power(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
return amdgpu_show_powershift_percent(dev, buf, true); return amdgpu_show_powershift_percent(dev, buf, AMDGPU_PP_SENSOR_SS_DGPU_SHARE);
} }
/** /**
...@@ -1965,7 +1930,6 @@ static ssize_t amdgpu_set_smartshift_bias(struct device *dev, ...@@ -1965,7 +1930,6 @@ static ssize_t amdgpu_set_smartshift_bias(struct device *dev,
return r; return r;
} }
static int ss_power_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, static int ss_power_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr,
uint32_t mask, enum amdgpu_device_attr_states *states) uint32_t mask, enum amdgpu_device_attr_states *states)
{ {
...@@ -1978,15 +1942,15 @@ static int ss_power_attr_update(struct amdgpu_device *adev, struct amdgpu_device ...@@ -1978,15 +1942,15 @@ static int ss_power_attr_update(struct amdgpu_device *adev, struct amdgpu_device
static int ss_bias_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, static int ss_bias_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr,
uint32_t mask, enum amdgpu_device_attr_states *states) uint32_t mask, enum amdgpu_device_attr_states *states)
{ {
uint32_t ss_power, size; uint32_t ss_power;
if (!amdgpu_device_supports_smart_shift(adev_to_drm(adev))) if (!amdgpu_device_supports_smart_shift(adev_to_drm(adev)))
*states = ATTR_STATE_UNSUPPORTED; *states = ATTR_STATE_UNSUPPORTED;
else if (amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_APU_SHARE, else if (amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_SS_APU_SHARE,
(void *)&ss_power, &size)) (void *)&ss_power))
*states = ATTR_STATE_UNSUPPORTED; *states = ATTR_STATE_UNSUPPORTED;
else if (amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE, else if (amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE,
(void *)&ss_power, &size)) (void *)&ss_power))
*states = ATTR_STATE_UNSUPPORTED; *states = ATTR_STATE_UNSUPPORTED;
return 0; return 0;
...@@ -2271,46 +2235,32 @@ static ssize_t amdgpu_hwmon_show_temp(struct device *dev, ...@@ -2271,46 +2235,32 @@ static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
{ {
struct amdgpu_device *adev = dev_get_drvdata(dev); struct amdgpu_device *adev = dev_get_drvdata(dev);
int channel = to_sensor_dev_attr(attr)->index; int channel = to_sensor_dev_attr(attr)->index;
int r, temp = 0, size = sizeof(temp); int r, temp = 0;
if (amdgpu_in_reset(adev))
return -EPERM;
if (adev->in_suspend && !adev->in_runpm)
return -EPERM;
if (channel >= PP_TEMP_MAX) if (channel >= PP_TEMP_MAX)
return -EINVAL; return -EINVAL;
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
switch (channel) { switch (channel) {
case PP_TEMP_JUNCTION: case PP_TEMP_JUNCTION:
/* get current junction temperature */ /* get current junction temperature */
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_HOTSPOT_TEMP, r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_HOTSPOT_TEMP,
(void *)&temp, &size); (void *)&temp);
break; break;
case PP_TEMP_EDGE: case PP_TEMP_EDGE:
/* get current edge temperature */ /* get current edge temperature */
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_EDGE_TEMP, r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_EDGE_TEMP,
(void *)&temp, &size); (void *)&temp);
break; break;
case PP_TEMP_MEM: case PP_TEMP_MEM:
/* get current memory temperature */ /* get current memory temperature */
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MEM_TEMP, r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MEM_TEMP,
(void *)&temp, &size); (void *)&temp);
break; break;
default: default:
r = -EINVAL; r = -EINVAL;
break; break;
} }
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
if (r) if (r)
return r; return r;
...@@ -2594,25 +2544,10 @@ static ssize_t amdgpu_hwmon_get_fan1_min(struct device *dev, ...@@ -2594,25 +2544,10 @@ static ssize_t amdgpu_hwmon_get_fan1_min(struct device *dev,
{ {
struct amdgpu_device *adev = dev_get_drvdata(dev); struct amdgpu_device *adev = dev_get_drvdata(dev);
u32 min_rpm = 0; u32 min_rpm = 0;
u32 size = sizeof(min_rpm);
int r; int r;
if (amdgpu_in_reset(adev)) r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MIN_FAN_RPM,
return -EPERM; (void *)&min_rpm);
if (adev->in_suspend && !adev->in_runpm)
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;
}
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MIN_FAN_RPM,
(void *)&min_rpm, &size);
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
if (r) if (r)
return r; return r;
...@@ -2626,25 +2561,10 @@ static ssize_t amdgpu_hwmon_get_fan1_max(struct device *dev, ...@@ -2626,25 +2561,10 @@ static ssize_t amdgpu_hwmon_get_fan1_max(struct device *dev,
{ {
struct amdgpu_device *adev = dev_get_drvdata(dev); struct amdgpu_device *adev = dev_get_drvdata(dev);
u32 max_rpm = 0; u32 max_rpm = 0;
u32 size = sizeof(max_rpm);
int r; int r;
if (amdgpu_in_reset(adev)) r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MAX_FAN_RPM,
return -EPERM; (void *)&max_rpm);
if (adev->in_suspend && !adev->in_runpm)
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;
}
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MAX_FAN_RPM,
(void *)&max_rpm, &size);
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
if (r) if (r)
return r; return r;
...@@ -2806,26 +2726,11 @@ static ssize_t amdgpu_hwmon_show_vddgfx(struct device *dev, ...@@ -2806,26 +2726,11 @@ static ssize_t amdgpu_hwmon_show_vddgfx(struct device *dev,
{ {
struct amdgpu_device *adev = dev_get_drvdata(dev); struct amdgpu_device *adev = dev_get_drvdata(dev);
u32 vddgfx; u32 vddgfx;
int r, size = sizeof(vddgfx); int r;
if (amdgpu_in_reset(adev))
return -EPERM;
if (adev->in_suspend && !adev->in_runpm)
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;
}
/* get the voltage */ /* get the voltage */
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDGFX, r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_VDDGFX,
(void *)&vddgfx, &size); (void *)&vddgfx);
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
if (r) if (r)
return r; return r;
...@@ -2845,30 +2750,15 @@ static ssize_t amdgpu_hwmon_show_vddnb(struct device *dev, ...@@ -2845,30 +2750,15 @@ static ssize_t amdgpu_hwmon_show_vddnb(struct device *dev,
{ {
struct amdgpu_device *adev = dev_get_drvdata(dev); struct amdgpu_device *adev = dev_get_drvdata(dev);
u32 vddnb; u32 vddnb;
int r, size = sizeof(vddnb); int r;
if (amdgpu_in_reset(adev))
return -EPERM;
if (adev->in_suspend && !adev->in_runpm)
return -EPERM;
/* only APUs have vddnb */ /* only APUs have vddnb */
if (!(adev->flags & AMD_IS_APU)) if (!(adev->flags & AMD_IS_APU))
return -EINVAL; return -EINVAL;
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
/* get the voltage */ /* get the voltage */
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB, r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_VDDNB,
(void *)&vddnb, &size); (void *)&vddnb);
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
if (r) if (r)
return r; return r;
...@@ -2882,40 +2772,35 @@ static ssize_t amdgpu_hwmon_show_vddnb_label(struct device *dev, ...@@ -2882,40 +2772,35 @@ static ssize_t amdgpu_hwmon_show_vddnb_label(struct device *dev,
return sysfs_emit(buf, "vddnb\n"); return sysfs_emit(buf, "vddnb\n");
} }
static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev, static unsigned int amdgpu_hwmon_get_power(struct device *dev,
struct device_attribute *attr, enum amd_pp_sensors sensor)
char *buf)
{ {
struct amdgpu_device *adev = dev_get_drvdata(dev); struct amdgpu_device *adev = dev_get_drvdata(dev);
unsigned int uw;
u32 query = 0; u32 query = 0;
int r, size = sizeof(u32); int r;
unsigned uw;
if (amdgpu_in_reset(adev))
return -EPERM;
if (adev->in_suspend && !adev->in_runpm)
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;
}
/* get the voltage */
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_POWER,
(void *)&query, &size);
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
r = amdgpu_hwmon_get_sensor_generic(adev, sensor, (void *)&query);
if (r) if (r)
return r; return r;
/* convert to microwatts */ /* convert to microwatts */
uw = (query >> 8) * 1000000 + (query & 0xff) * 1000; uw = (query >> 8) * 1000000 + (query & 0xff) * 1000;
return sysfs_emit(buf, "%u\n", uw); return uw;
}
static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev,
struct device_attribute *attr,
char *buf)
{
unsigned int val;
val = amdgpu_hwmon_get_power(dev, AMDGPU_PP_SENSOR_GPU_POWER);
if (val < 0)
return val;
return sysfs_emit(buf, "%u\n", val);
} }
static ssize_t amdgpu_hwmon_show_power_cap_min(struct device *dev, static ssize_t amdgpu_hwmon_show_power_cap_min(struct device *dev,
...@@ -3050,26 +2935,11 @@ static ssize_t amdgpu_hwmon_show_sclk(struct device *dev, ...@@ -3050,26 +2935,11 @@ static ssize_t amdgpu_hwmon_show_sclk(struct device *dev,
{ {
struct amdgpu_device *adev = dev_get_drvdata(dev); struct amdgpu_device *adev = dev_get_drvdata(dev);
uint32_t sclk; uint32_t sclk;
int r, size = sizeof(sclk); int r;
if (amdgpu_in_reset(adev))
return -EPERM;
if (adev->in_suspend && !adev->in_runpm)
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;
}
/* get the sclk */ /* get the sclk */
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_SCLK, r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GFX_SCLK,
(void *)&sclk, &size); (void *)&sclk);
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
if (r) if (r)
return r; return r;
...@@ -3089,26 +2959,11 @@ static ssize_t amdgpu_hwmon_show_mclk(struct device *dev, ...@@ -3089,26 +2959,11 @@ static ssize_t amdgpu_hwmon_show_mclk(struct device *dev,
{ {
struct amdgpu_device *adev = dev_get_drvdata(dev); struct amdgpu_device *adev = dev_get_drvdata(dev);
uint32_t mclk; uint32_t mclk;
int r, size = sizeof(mclk); int r;
if (amdgpu_in_reset(adev))
return -EPERM;
if (adev->in_suspend && !adev->in_runpm)
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;
}
/* get the sclk */ /* get the sclk */
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_MCLK, r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GFX_MCLK,
(void *)&mclk, &size); (void *)&mclk);
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
if (r) if (r)
return r; return r;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment