Commit 22ca75ea authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/amdgpu/swsmu/renoir: simplify sensor handling (v2)



Just query the metrics table directly rather than going through
an extra level of functions.

v2: use proper enum

Reviewed-by: default avatarEvan Quan <evan.quan@amd.com>
Reviewed-by: default avatarHuang Rui <ray.huang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 2139d12b
Loading
Loading
Loading
Loading
+93 −112
Original line number Diff line number Diff line
@@ -492,28 +492,6 @@ static int renoir_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
	return ret;
}

static int renoir_get_current_clk_freq_by_table(struct smu_context *smu,
				       enum smu_clk_type clk_type,
				       uint32_t *value)
{
	int ret = 0, clk_id = 0;
	SmuMetrics_t metrics;

	ret = smu_cmn_get_metrics_table(smu, &metrics, false);
	if (ret)
		return ret;

	clk_id = smu_cmn_to_asic_specific_index(smu,
						CMN2ASIC_MAPPING_CLK,
						clk_type);
	if (clk_id < 0)
		return clk_id;

	*value = metrics.ClockFrequency[clk_id];

	return ret;
}

static int renoir_force_dpm_limit_value(struct smu_context *smu, bool highest)
{
	int ret = 0, i = 0;
@@ -574,88 +552,6 @@ static int renoir_unforce_dpm_levels(struct smu_context *smu) {
	return ret;
}

static int renoir_get_gpu_temperature(struct smu_context *smu, uint32_t *value)
{
	int ret = 0;
	SmuMetrics_t metrics;

	if (!value)
		return -EINVAL;

	ret = smu_cmn_get_metrics_table(smu, &metrics, false);
	if (ret)
		return ret;

	*value = (metrics.GfxTemperature / 100) *
		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;

	return 0;
}

static int renoir_get_current_activity_percent(struct smu_context *smu,
					       enum amd_pp_sensors sensor,
					       uint32_t *value)
{
	int ret = 0;
	SmuMetrics_t metrics;

	if (!value)
		return -EINVAL;

	ret = smu_cmn_get_metrics_table(smu, &metrics, false);
	if (ret)
		return ret;

	switch (sensor) {
	case AMDGPU_PP_SENSOR_GPU_LOAD:
		*value = metrics.AverageGfxActivity / 100;
		break;
	default:
		dev_err(smu->adev->dev, "Invalid sensor for retrieving clock activity\n");
		return -EINVAL;
	}

	return 0;
}

static int renoir_get_vddc(struct smu_context *smu, uint32_t *value,
			   unsigned int index)
{
	int ret = 0;
	SmuMetrics_t metrics;

	if (index >= 2)
		return -EINVAL;

	if (!value)
		return -EINVAL;

	ret = smu_cmn_get_metrics_table(smu, &metrics, false);
	if (ret)
		return ret;

	*value = metrics.Voltage[index];

	return 0;
}

static int renoir_get_power(struct smu_context *smu, uint32_t *value)
{
	int ret = 0;
	SmuMetrics_t metrics;

	if (!value)
		return -EINVAL;

	ret = smu_cmn_get_metrics_table(smu, &metrics, false);
	if (ret)
		return ret;

	*value = metrics.CurrentSocketPower << 8;

	return 0;
}

/*
 * This interface get dpm clock table for dc
 */
@@ -1011,6 +907,71 @@ static int renoir_get_power_profile_mode(struct smu_context *smu,
	return size;
}

static int renoir_get_smu_metrics_data(struct smu_context *smu,
				       MetricsMember_t member,
				       uint32_t *value)
{
	struct smu_table_context *smu_table = &smu->smu_table;

	SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
	int ret = 0;

	mutex_lock(&smu->metrics_lock);

	ret = smu_cmn_get_metrics_table_locked(smu,
					       NULL,
					       false);
	if (ret) {
		mutex_unlock(&smu->metrics_lock);
		return ret;
	}

	switch (member) {
	case METRICS_AVERAGE_GFXCLK:
		*value = metrics->ClockFrequency[CLOCK_GFXCLK];
		break;
	case METRICS_AVERAGE_SOCCLK:
		*value = metrics->ClockFrequency[CLOCK_SOCCLK];
		break;
	case METRICS_AVERAGE_UCLK:
		*value = metrics->ClockFrequency[CLOCK_FCLK];
		break;
	case METRICS_AVERAGE_GFXACTIVITY:
		*value = metrics->AverageGfxActivity / 100;
		break;
	case METRICS_AVERAGE_VCNACTIVITY:
		*value = metrics->AverageUvdActivity / 100;
		break;
	case METRICS_AVERAGE_SOCKETPOWER:
		*value = metrics->CurrentSocketPower << 8;
		break;
	case METRICS_TEMPERATURE_EDGE:
		*value = (metrics->GfxTemperature / 100) *
			SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
		break;
	case METRICS_TEMPERATURE_HOTSPOT:
		*value = (metrics->SocTemperature / 100) *
			SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
		break;
	case METRICS_THROTTLER_STATUS:
		*value = metrics->ThrottlerStatus;
		break;
	case METRICS_VOLTAGE_VDDGFX:
		*value = metrics->Voltage[0];
		break;
	case METRICS_VOLTAGE_VDDSOC:
		*value = metrics->Voltage[1];
		break;
	default:
		*value = UINT_MAX;
		break;
	}

	mutex_unlock(&smu->metrics_lock);

	return ret;
}

static int renoir_read_sensor(struct smu_context *smu,
				 enum amd_pp_sensors sensor,
				 void *data, uint32_t *size)
@@ -1023,33 +984,53 @@ static int renoir_read_sensor(struct smu_context *smu,
	mutex_lock(&smu->sensor_lock);
	switch (sensor) {
	case AMDGPU_PP_SENSOR_GPU_LOAD:
		ret = renoir_get_current_activity_percent(smu, sensor, (uint32_t *)data);
		ret = renoir_get_smu_metrics_data(smu,
						  METRICS_AVERAGE_GFXACTIVITY,
						  (uint32_t *)data);
		*size = 4;
		break;
	case AMDGPU_PP_SENSOR_EDGE_TEMP:
		ret = renoir_get_smu_metrics_data(smu,
						  METRICS_TEMPERATURE_EDGE,
						  (uint32_t *)data);
		*size = 4;
		break;
	case AMDGPU_PP_SENSOR_GPU_TEMP:
		ret = renoir_get_gpu_temperature(smu, (uint32_t *)data);
	case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
		ret = renoir_get_smu_metrics_data(smu,
						  METRICS_TEMPERATURE_HOTSPOT,
						  (uint32_t *)data);
		*size = 4;
		break;
	case AMDGPU_PP_SENSOR_GFX_MCLK:
		ret = renoir_get_current_clk_freq_by_table(smu, SMU_UCLK, (uint32_t *)data);
		ret = renoir_get_smu_metrics_data(smu,
						  METRICS_AVERAGE_UCLK,
						  (uint32_t *)data);
		*(uint32_t *)data *= 100;
		*size = 4;
		break;
	case AMDGPU_PP_SENSOR_GFX_SCLK:
		ret = renoir_get_current_clk_freq_by_table(smu, SMU_GFXCLK, (uint32_t *)data);
		ret = renoir_get_smu_metrics_data(smu,
						  METRICS_AVERAGE_GFXCLK,
						  (uint32_t *)data);
		*(uint32_t *)data *= 100;
		*size = 4;
		break;
	case AMDGPU_PP_SENSOR_VDDGFX:
		ret = renoir_get_vddc(smu, (uint32_t *)data, 0);
		ret = renoir_get_smu_metrics_data(smu,
						  METRICS_VOLTAGE_VDDGFX,
						  (uint32_t *)data);
		*size = 4;
		break;
	case AMDGPU_PP_SENSOR_VDDNB:
		ret = renoir_get_vddc(smu, (uint32_t *)data, 1);
		ret = renoir_get_smu_metrics_data(smu,
						  METRICS_VOLTAGE_VDDSOC,
						  (uint32_t *)data);
		*size = 4;
		break;
	case AMDGPU_PP_SENSOR_GPU_POWER:
		ret = renoir_get_power(smu, (uint32_t *)data);
		ret = renoir_get_smu_metrics_data(smu,
						  METRICS_AVERAGE_SOCKETPOWER,
						  (uint32_t *)data);
		*size = 4;
		break;
	default: