Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b94afb61 authored by Kevin Wang's avatar Kevin Wang Committed by Alex Deucher
Browse files

drm/amd/powerplay: honor hw limit on fetching metrics data for navi10



too frequently to update mertrics table will cause smu internal error.

Signed-off-by: default avatarKevin Wang <kevin1.wang@amd.com>
Reviewed-by: default avatarEvan Quan <evan.quan@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent bd200d19
Loading
Loading
Loading
Loading
+38 −18
Original line number Diff line number Diff line
@@ -516,6 +516,8 @@ static int navi10_store_powerplay_table(struct smu_context *smu)

static int navi10_tables_init(struct smu_context *smu, struct smu_table *tables)
{
	struct smu_table_context *smu_table = &smu->smu_table;

	SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t),
		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
	SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
@@ -530,9 +532,35 @@ static int navi10_tables_init(struct smu_context *smu, struct smu_table *tables)
		       sizeof(DpmActivityMonitorCoeffInt_t), PAGE_SIZE,
		       AMDGPU_GEM_DOMAIN_VRAM);

	smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
	if (!smu_table->metrics_table)
		return -ENOMEM;
	smu_table->metrics_time = 0;

	return 0;
}

static int navi10_get_metrics_table(struct smu_context *smu,
				    SmuMetrics_t *metrics_table)
{
	struct smu_table_context *smu_table= &smu->smu_table;
	int ret = 0;

	if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + HZ / 1000)) {
		ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0,
				(void *)smu_table->metrics_table, false);
		if (ret) {
			pr_info("Failed to export SMU metrics table!\n");
			return ret;
		}
		smu_table->metrics_time = jiffies;
	}

	memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t));

	return ret;
}

static int navi10_allocate_dpm_context(struct smu_context *smu)
{
	struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
@@ -612,15 +640,10 @@ static int navi10_get_current_clk_freq_by_table(struct smu_context *smu,
				       enum smu_clk_type clk_type,
				       uint32_t *value)
{
	static SmuMetrics_t metrics;
	int ret = 0, clk_id = 0;
	SmuMetrics_t metrics;

	if (!value)
		return -EINVAL;

	memset(&metrics, 0, sizeof(metrics));

	ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void *)&metrics, false);
	ret = navi10_get_metrics_table(smu, &metrics);
	if (ret)
		return ret;

@@ -908,8 +931,9 @@ static int navi10_get_gpu_power(struct smu_context *smu, uint32_t *value)
	if (!value)
		return -EINVAL;

	ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void *)&metrics,
			       false);
	ret = navi10_get_metrics_table(smu, &metrics);
	if (ret)
		return ret;
	if (ret)
		return ret;

@@ -928,10 +952,7 @@ static int navi10_get_current_activity_percent(struct smu_context *smu,
	if (!value)
		return -EINVAL;

	msleep(1);

	ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0,
			       (void *)&metrics, false);
	ret = navi10_get_metrics_table(smu, &metrics);
	if (ret)
		return ret;

@@ -970,10 +991,9 @@ static int navi10_get_fan_speed_rpm(struct smu_context *smu,
	if (!speed)
		return -EINVAL;

	memset(&metrics, 0, sizeof(metrics));

	ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0,
			       (void *)&metrics, false);
	ret = navi10_get_metrics_table(smu, &metrics);
	if (ret)
		return ret;
	if (ret)
		return ret;

@@ -1326,7 +1346,7 @@ static int navi10_thermal_get_temperature(struct smu_context *smu,
	if (!value)
		return -EINVAL;

	ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void *)&metrics, false);
	ret = navi10_get_metrics_table(smu, &metrics);
	if (ret)
		return ret;