Commit a7673a1c authored by Sathishkumar S's avatar Sathishkumar S Committed by Alex Deucher
Browse files

drm/amd/pm: sysfs attrs to read ss powershare (v6)



add sysfs attrs to read smartshift APU and DGPU power share.
document the sysfs device attributes.

V2: change variable/macro name for stapm power limit (Lijo)
V3: files to be exposed as sysfs device attributes (Alex)
V4: check ret value of sysfs create and remove only if created.
V5: add ss attrs in amdgpu_device_attrs and use attr_update (Lijo)
V6: all checks for ss support to be in if else if statements. (Lijo)

Signed-off-by: default avatarSathishkumar S <sathishkumar.sundararaju@amd.com>
Reviewed-by: default avatarLijo Lazar <lijo.lazar@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 34667f60
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -300,4 +300,19 @@ pcie_replay_count
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
   :doc: pcie_replay_count

+GPU SmartShift Information
============================

GPU SmartShift information via sysfs

smartshift_apu_power
--------------------

.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
   :doc: smartshift_apu_power

smartshift_dgpu_power
---------------------

.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
   :doc: smartshift_dgpu_power
+2 −0
Original line number Diff line number Diff line
@@ -124,6 +124,8 @@ enum amd_pp_sensors {
	AMDGPU_PP_SENSOR_VCE_POWER,
	AMDGPU_PP_SENSOR_UVD_POWER,
	AMDGPU_PP_SENSOR_GPU_POWER,
	AMDGPU_PP_SENSOR_SS_APU_SHARE,
	AMDGPU_PP_SENSOR_SS_DGPU_SHARE,
	AMDGPU_PP_SENSOR_STABLE_PSTATE_SCLK,
	AMDGPU_PP_SENSOR_STABLE_PSTATE_MCLK,
	AMDGPU_PP_SENSOR_ENABLED_SMC_FEATURES_MASK,
+110 −0
Original line number Diff line number Diff line
@@ -1817,6 +1817,112 @@ static ssize_t amdgpu_get_gpu_metrics(struct device *dev,
	return size;
}

/**
 * DOC: smartshift_apu_power
 *
 * 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 amdgpu_device *adev = drm_to_adev(ddev);
	uint32_t ss_power, 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;
	}

	r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_APU_SHARE,
				   (void *)&ss_power, &size);
	if (r)
		goto out;

	r = sysfs_emit(buf, "%u%%\n", ss_power);

out:
	pm_runtime_mark_last_busy(ddev->dev);
	pm_runtime_put_autosuspend(ddev->dev);
	return r;
}

/**
 * DOC: smartshift_dgpu_power
 *
 * 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 amdgpu_device *adev = drm_to_adev(ddev);
	uint32_t ss_power, 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;
	}

	r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE,
				   (void *)&ss_power, &size);

	if (r)
		goto out;

	r = sysfs_emit(buf, "%u%%\n", ss_power);

out:
	pm_runtime_mark_last_busy(ddev->dev);
	pm_runtime_put_autosuspend(ddev->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)
{
	uint32_t ss_power, size;

	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;

	return 0;
}

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),
@@ -1843,6 +1949,10 @@ static struct amdgpu_device_attr amdgpu_device_attrs[] = {
	AMDGPU_DEVICE_ATTR_RO(unique_id,				ATTR_FLAG_BASIC),
	AMDGPU_DEVICE_ATTR_RW(thermal_throttling_logging,		ATTR_FLAG_BASIC),
	AMDGPU_DEVICE_ATTR_RO(gpu_metrics,				ATTR_FLAG_BASIC),
	AMDGPU_DEVICE_ATTR_RO(smartshift_apu_power,			ATTR_FLAG_BASIC,
			      .attr_update = ss_power_attr_update),
	AMDGPU_DEVICE_ATTR_RO(smartshift_dgpu_power,			ATTR_FLAG_BASIC,
			      .attr_update = ss_power_attr_update),
};

static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr,
+2 −0
Original line number Diff line number Diff line
@@ -1218,6 +1218,8 @@ typedef enum {
	METRICS_CURR_FANSPEED,
	METRICS_VOLTAGE_VDDSOC,
	METRICS_VOLTAGE_VDDGFX,
	METRICS_SS_APU_SHARE,
	METRICS_SS_DGPU_SHARE,
} MetricsMember_t;

enum smu_cmn2asic_mapping_type {