summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Wang <kevin1.wang@amd.com>2019-08-02 12:01:00 +0800
committerKevin Wang <kevin1.wang@amd.com>2019-09-27 19:16:26 +0800
commite03c5b1fd5ce384c8ccc88d5103e35d5d7f0c44f (patch)
tree4a411697c8e552d879ae0295bc1160adfecf697b
parentab273f23f87da75fd6e42847b54b57cb8660704e (diff)
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: Kevin Wang <kevin1.wang@amd.com> Reviewed-by: Evan Quan <evan.quan@amd.com>
-rw-r--r--drivers/gpu/drm/amd/powerplay/navi10_ppt.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index b26156907add..ee3a8134ff9b 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -502,6 +502,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),
@@ -516,9 +518,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,
+ (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;
@@ -605,13 +633,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 = {0};
int ret = 0, clk_id = 0;
+ SmuMetrics_t metrics;
- if (!value)
- return -EINVAL;
-
- ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, (void *)&metrics, false);
+ ret = navi10_get_metrics_table(smu, &metrics);
if (ret)
return ret;
@@ -899,8 +924,7 @@ 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, (void *)&metrics,
- false);
+ ret = navi10_get_metrics_table(smu, &metrics);
if (ret)
return ret;
@@ -918,10 +942,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,
- (void *)&metrics, false);
+ ret = navi10_get_metrics_table(smu, &metrics);
if (ret)
return ret;
@@ -949,8 +970,7 @@ static int navi10_get_fan_speed(struct smu_context *smu, uint16_t *value)
if (!value)
return -EINVAL;
- ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS,
- (void *)&metrics, false);
+ ret = navi10_get_metrics_table(smu, &metrics);
if (ret)
return ret;