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

Signed-off-by: Kevin Wang <kevin1.w...@amd.com>
---
 drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 +++++++++++++++-------
 1 file changed, 38 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c 
b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index f3adb713784a..cf2e264095a7 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -515,6 +515,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),
@@ -529,9 +531,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;
@@ -611,15 +639,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;
 
@@ -907,8 +930,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;
 
@@ -927,10 +951,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;
 
@@ -969,10 +990,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;
 
@@ -1325,7 +1345,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;
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to