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

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
Loading
Loading
Loading
Loading
+88 −233
Original line number Diff line number Diff line
@@ -1467,6 +1467,32 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
	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
 *
@@ -1481,26 +1507,10 @@ static ssize_t amdgpu_get_gpu_busy_percent(struct device *dev,
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = drm_to_adev(ddev);
	int r, value, size = sizeof(value);

	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);
	unsigned int value;
	int r;

	r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GPU_LOAD, &value);
	if (r)
		return r;

@@ -1521,26 +1531,10 @@ static ssize_t amdgpu_get_mem_busy_percent(struct device *dev,
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = drm_to_adev(ddev);
	int r, value, size = sizeof(value);

	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);
	unsigned int value;
	int r;

	r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MEM_LOAD, &value);
	if (r)
		return r;

@@ -1814,45 +1808,15 @@ static ssize_t amdgpu_get_gpu_metrics(struct device *dev,
	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,
					char *buf, bool dgpu_share)
					char *buf, enum amd_pp_sensors sensor)
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = drm_to_adev(ddev);
	uint32_t ss_power;
	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) {
		/* sensor not available on dGPU, try to read from APU */
		adev = NULL;
@@ -1865,14 +1829,15 @@ static int amdgpu_show_powershift_percent(struct device *dev,
		}
		mutex_unlock(&mgpu_info.mutex);
		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)
		r = sysfs_emit(buf, "%u%%\n", ss_power);

	if (r)
		return r;

	return sysfs_emit(buf, "%u%%\n", ss_power);
}

/**
 * DOC: smartshift_apu_power
 *
@@ -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,
					       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
static ssize_t amdgpu_get_smartshift_dgpu_power(struct device *dev, struct device_attribute *attr,
						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,
	return r;
}


static int ss_power_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr,
				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
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 ss_power, size;
	uint32_t ss_power;

	if (!amdgpu_device_supports_smart_shift(adev_to_drm(adev)))
		*states = ATTR_STATE_UNSUPPORTED;
	else if (amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_APU_SHARE,
		 (void *)&ss_power, &size))
	else if (amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_SS_APU_SHARE,
		 (void *)&ss_power))
		*states = ATTR_STATE_UNSUPPORTED;
	else if (amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE,
		 (void *)&ss_power, &size))
	else if (amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE,
		 (void *)&ss_power))
		*states = ATTR_STATE_UNSUPPORTED;

	return 0;
@@ -2271,46 +2235,32 @@ static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
{
	struct amdgpu_device *adev = dev_get_drvdata(dev);
	int channel = to_sensor_dev_attr(attr)->index;
	int r, temp = 0, size = sizeof(temp);

	if (amdgpu_in_reset(adev))
		return -EPERM;
	if (adev->in_suspend && !adev->in_runpm)
		return -EPERM;
	int r, temp = 0;

	if (channel >= PP_TEMP_MAX)
		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) {
	case PP_TEMP_JUNCTION:
		/* get current junction temperature */
		r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_HOTSPOT_TEMP,
					   (void *)&temp, &size);
		r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_HOTSPOT_TEMP,
					   (void *)&temp);
		break;
	case PP_TEMP_EDGE:
		/* get current edge temperature */
		r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_EDGE_TEMP,
					   (void *)&temp, &size);
		r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_EDGE_TEMP,
					   (void *)&temp);
		break;
	case PP_TEMP_MEM:
		/* get current memory temperature */
		r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MEM_TEMP,
					   (void *)&temp, &size);
		r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MEM_TEMP,
					   (void *)&temp);
		break;
	default:
		r = -EINVAL;
		break;
	}

	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);

	if (r)
		return r;

@@ -2594,25 +2544,10 @@ static ssize_t amdgpu_hwmon_get_fan1_min(struct device *dev,
{
	struct amdgpu_device *adev = dev_get_drvdata(dev);
	u32 min_rpm = 0;
	u32 size = sizeof(min_rpm);
	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;
	}

	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);
	r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MIN_FAN_RPM,
				   (void *)&min_rpm);

	if (r)
		return r;
@@ -2626,25 +2561,10 @@ static ssize_t amdgpu_hwmon_get_fan1_max(struct device *dev,
{
	struct amdgpu_device *adev = dev_get_drvdata(dev);
	u32 max_rpm = 0;
	u32 size = sizeof(max_rpm);
	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;
	}

	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);
	r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MAX_FAN_RPM,
				   (void *)&max_rpm);

	if (r)
		return r;
@@ -2806,26 +2726,11 @@ static ssize_t amdgpu_hwmon_show_vddgfx(struct device *dev,
{
	struct amdgpu_device *adev = dev_get_drvdata(dev);
	u32 vddgfx;
	int r, size = sizeof(vddgfx);

	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;
	}
	int r;

	/* get the voltage */
	r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDGFX,
				   (void *)&vddgfx, &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, AMDGPU_PP_SENSOR_VDDGFX,
				   (void *)&vddgfx);
	if (r)
		return r;

@@ -2845,30 +2750,15 @@ static ssize_t amdgpu_hwmon_show_vddnb(struct device *dev,
{
	struct amdgpu_device *adev = dev_get_drvdata(dev);
	u32 vddnb;
	int r, size = sizeof(vddnb);

	if (amdgpu_in_reset(adev))
		return -EPERM;
	if (adev->in_suspend && !adev->in_runpm)
		return -EPERM;
	int r;

	/* only APUs have vddnb */
	if  (!(adev->flags & AMD_IS_APU))
		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 */
	r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB,
				   (void *)&vddnb, &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, AMDGPU_PP_SENSOR_VDDNB,
				   (void *)&vddnb);
	if (r)
		return r;

@@ -2882,40 +2772,35 @@ static ssize_t amdgpu_hwmon_show_vddnb_label(struct device *dev,
	return sysfs_emit(buf, "vddnb\n");
}

static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev,
					   struct device_attribute *attr,
					   char *buf)
static unsigned int amdgpu_hwmon_get_power(struct device *dev,
					   enum amd_pp_sensors sensor)
{
	struct amdgpu_device *adev = dev_get_drvdata(dev);
	unsigned int uw;
	u32 query = 0;
	int r, size = sizeof(u32);
	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);
	int r;

	r = amdgpu_hwmon_get_sensor_generic(adev, sensor, (void *)&query);
	if (r)
		return r;

	/* convert to microwatts */
	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,
@@ -3050,26 +2935,11 @@ static ssize_t amdgpu_hwmon_show_sclk(struct device *dev,
{
	struct amdgpu_device *adev = dev_get_drvdata(dev);
	uint32_t sclk;
	int r, size = sizeof(sclk);

	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;
	}
	int r;

	/* get the sclk */
	r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_SCLK,
				   (void *)&sclk, &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, AMDGPU_PP_SENSOR_GFX_SCLK,
				   (void *)&sclk);
	if (r)
		return r;

@@ -3089,26 +2959,11 @@ static ssize_t amdgpu_hwmon_show_mclk(struct device *dev,
{
	struct amdgpu_device *adev = dev_get_drvdata(dev);
	uint32_t mclk;
	int r, size = sizeof(mclk);

	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;
	}
	int r;

	/* get the sclk */
	r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_MCLK,
				   (void *)&mclk, &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, AMDGPU_PP_SENSOR_GFX_MCLK,
				   (void *)&mclk);
	if (r)
		return r;