提交 494c1432 编写于 作者: S Sathishkumar S 提交者: Alex Deucher

drm/amd/pm: consistent approach for smartshift

create smartshift sysfs attributes from dGPU device even
on smartshift 1.0 platform to be consistent. Do not populate
the attributes on platforms that have APU only but not dGPU
or vice versa.

V2:
 avoid checking for the number of VGA/DISPLAY devices (Lijo)
 move code to read from dGPU or APU into a function and reuse (Lijo)
Suggested-by: NAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: NSathishkumar S <sathishkumar.sundararaju@amd.com>
Acked-by: NAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: NLijo Lazar <lijo.lazar@amd.com>
Signed-off-by: NAlex Deucher <alexander.deucher@amd.com>
上级 f3106c94
...@@ -1734,22 +1734,11 @@ static ssize_t amdgpu_get_gpu_metrics(struct device *dev, ...@@ -1734,22 +1734,11 @@ static ssize_t amdgpu_get_gpu_metrics(struct device *dev,
return size; return size;
} }
/** static int amdgpu_device_read_powershift(struct amdgpu_device *adev,
* DOC: smartshift_apu_power uint32_t *ss_power, bool dgpu_share)
*
* The amdgpu driver provides a sysfs API for reporting APU power
* share if it supports smartshift. The value is expressed as
* the proportion of stapm limit where stapm limit is the total APU
* power limit. The result is in percentage. If APU power is 130% of
* STAPM, then APU is using 30% of the dGPU's headroom.
*/
static ssize_t amdgpu_get_smartshift_apu_power(struct device *dev, struct device_attribute *attr,
char *buf)
{ {
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = adev_to_drm(adev);
struct amdgpu_device *adev = drm_to_adev(ddev); uint32_t size;
uint32_t ss_power, size;
int r = 0; int r = 0;
if (amdgpu_in_reset(adev)) if (amdgpu_in_reset(adev))
...@@ -1763,61 +1752,77 @@ static ssize_t amdgpu_get_smartshift_apu_power(struct device *dev, struct device ...@@ -1763,61 +1752,77 @@ static ssize_t amdgpu_get_smartshift_apu_power(struct device *dev, struct device
return r; return r;
} }
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_APU_SHARE, if (dgpu_share)
(void *)&ss_power, &size); r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE,
if (r) (void *)ss_power, &size);
goto out; else
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_APU_SHARE,
r = sysfs_emit(buf, "%u%%\n", ss_power); (void *)ss_power, &size);
out:
pm_runtime_mark_last_busy(ddev->dev); pm_runtime_mark_last_busy(ddev->dev);
pm_runtime_put_autosuspend(ddev->dev); pm_runtime_put_autosuspend(ddev->dev);
return r; return r;
} }
/** static int amdgpu_show_powershift_percent(struct device *dev,
* DOC: smartshift_dgpu_power char *buf, bool dgpu_share)
*
* The amdgpu driver provides a sysfs API for reporting the dGPU power
* share if the device is in HG and supports smartshift. The value
* is expressed as the proportion of stapm limit where stapm limit
* is the total APU power limit. The value is in percentage. If dGPU
* power is 20% higher than STAPM power(120%), it's using 20% of the
* APU's power headroom.
*/
static ssize_t amdgpu_get_smartshift_dgpu_power(struct device *dev, struct device_attribute *attr,
char *buf)
{ {
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, size; uint32_t ss_power;
int r = 0; int r = 0, i;
if (amdgpu_in_reset(adev)) r = amdgpu_device_read_powershift(adev, &ss_power, dgpu_share);
return -EPERM; if (r == -EOPNOTSUPP) {
if (adev->in_suspend && !adev->in_runpm) /* sensor not available on dGPU, try to read from APU */
return -EPERM; adev = NULL;
mutex_lock(&mgpu_info.mutex);
r = pm_runtime_get_sync(ddev->dev); for (i = 0; i < mgpu_info.num_gpu; i++) {
if (r < 0) { if (mgpu_info.gpu_ins[i].adev->flags & AMD_IS_APU) {
pm_runtime_put_autosuspend(ddev->dev); adev = mgpu_info.gpu_ins[i].adev;
return r; break;
}
}
mutex_unlock(&mgpu_info.mutex);
if (adev)
r = amdgpu_device_read_powershift(adev, &ss_power, dgpu_share);
} }
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE, if (!r)
(void *)&ss_power, &size); r = sysfs_emit(buf, "%u%%\n", ss_power);
if (r) return r;
goto out; }
/**
* DOC: smartshift_apu_power
*
* The amdgpu driver provides a sysfs API for reporting APU power
* shift in percentage if platform supports smartshift. Value 0 means that
* there is no powershift and values between [1-100] means that the power
* is shifted to APU, the percentage of boost is with respect to APU power
* limit on the platform.
*/
r = sysfs_emit(buf, "%u%%\n", ss_power); 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);
}
out: /**
pm_runtime_mark_last_busy(ddev->dev); * DOC: smartshift_dgpu_power
pm_runtime_put_autosuspend(ddev->dev); *
return r; * The amdgpu driver provides a sysfs API for reporting dGPU power
* shift in percentage if platform supports smartshift. Value 0 means that
* there is no powershift and values between [1-100] means that the power is
* shifted to dGPU, the percentage of boost is with respect to dGPU power
* limit on the platform.
*/
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);
} }
/** /**
...@@ -1884,18 +1889,7 @@ static ssize_t amdgpu_set_smartshift_bias(struct device *dev, ...@@ -1884,18 +1889,7 @@ static ssize_t amdgpu_set_smartshift_bias(struct device *dev,
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)
{ {
uint32_t ss_power, size; if (!amdgpu_device_supports_smart_shift(adev_to_drm(adev)))
if (!amdgpu_acpi_is_power_shift_control_supported())
*states = ATTR_STATE_UNSUPPORTED;
else if ((adev->flags & AMD_IS_PX) &&
!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))
*states = ATTR_STATE_UNSUPPORTED;
else if (amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE,
(void *)&ss_power, &size))
*states = ATTR_STATE_UNSUPPORTED; *states = ATTR_STATE_UNSUPPORTED;
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册