Implement caching separately for SystemMetrics table from PMFW. The same
table could be used for multiple interfaces. Hence, cache it internally
to avoid multiple queries to the firmware. For SystemMetrics table, 5ms
cache interval is sufficient.

Signed-off-by: Lijo Lazar <lijo.la...@amd.com>
---
 drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h |  1 +
 .../drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c | 43 +++++++++++++------
 .../drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c  |  4 ++
 .../drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h  |  1 +
 4 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h 
b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
index 5dd49eca598d..5976eda80035 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
@@ -333,6 +333,7 @@ enum smu_table_id {
        SMU_TABLE_WIFIBAND,
        SMU_TABLE_GPUBOARD_TEMP_METRICS,
        SMU_TABLE_BASEBOARD_TEMP_METRICS,
+       SMU_TABLE_PMFW_SYSTEM_METRICS,
        SMU_TABLE_COUNT,
 };
 
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c
index 32fd0be05cff..0bec12b348ce 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c
@@ -149,6 +149,12 @@ int smu_v13_0_12_tables_init(struct smu_context *smu)
        struct smu_table_cache *cache;
        int ret;
 
+       ret = smu_table_cache_init(smu, SMU_TABLE_PMFW_SYSTEM_METRICS,
+                                  smu_v13_0_12_get_system_metrics_size(), 5);
+
+       if (ret)
+               return ret;
+
        ret = smu_table_cache_init(smu, SMU_TABLE_BASEBOARD_TEMP_METRICS,
                                   sizeof(*baseboard_temp_metrics), 50);
        if (ret)
@@ -162,6 +168,7 @@ int smu_v13_0_12_tables_init(struct smu_context *smu)
        ret = smu_table_cache_init(smu, SMU_TABLE_GPUBOARD_TEMP_METRICS,
                                   sizeof(*gpuboard_temp_metrics), 50);
        if (ret) {
+               smu_table_cache_fini(smu, SMU_TABLE_PMFW_SYSTEM_METRICS);
                smu_table_cache_fini(smu, SMU_TABLE_BASEBOARD_TEMP_METRICS);
                return ret;
        }
@@ -176,6 +183,7 @@ void smu_v13_0_12_tables_fini(struct smu_context *smu)
 {
        smu_table_cache_fini(smu, SMU_TABLE_BASEBOARD_TEMP_METRICS);
        smu_table_cache_fini(smu, SMU_TABLE_GPUBOARD_TEMP_METRICS);
+       smu_table_cache_fini(smu, SMU_TABLE_PMFW_SYSTEM_METRICS);
 }
 
 static int smu_v13_0_12_get_enabled_mask(struct smu_context *smu,
@@ -222,8 +230,12 @@ static int smu_v13_0_12_fru_get_product_info(struct 
smu_context *smu,
 
 int smu_v13_0_12_get_max_metrics_size(void)
 {
-       return max3(sizeof(StaticMetricsTable_t), sizeof(MetricsTable_t),
-                  sizeof(SystemMetricsTable_t));
+       return max(sizeof(StaticMetricsTable_t), sizeof(MetricsTable_t));
+}
+
+size_t smu_v13_0_12_get_system_metrics_size(void)
+{
+       return sizeof(SystemMetricsTable_t);
 }
 
 static void smu_v13_0_12_init_xgmi_data(struct smu_context *smu,
@@ -414,14 +426,18 @@ int smu_v13_0_12_get_smu_metrics_data(struct smu_context 
*smu,
        return 0;
 }
 
-static int smu_v13_0_12_get_system_metrics_table(struct smu_context *smu,
-                                                void *metrics_table)
+static int smu_v13_0_12_get_system_metrics_table(struct smu_context *smu)
 {
        struct smu_table_context *smu_table = &smu->smu_table;
-       uint32_t table_size = smu_table->tables[SMU_TABLE_SMU_METRICS].size;
        struct smu_table *table = &smu_table->driver_table;
+       struct smu_table *tables = smu_table->tables;
+       struct smu_table *sys_table;
        int ret;
 
+       sys_table = &tables[SMU_TABLE_PMFW_SYSTEM_METRICS];
+       if (smu_table_cache_is_valid(sys_table))
+               return 0;
+
        ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetSystemMetricsTable, NULL);
        if (ret) {
                dev_info(smu->adev->dev,
@@ -430,10 +446,9 @@ static int smu_v13_0_12_get_system_metrics_table(struct 
smu_context *smu,
        }
 
        amdgpu_asic_invalidate_hdp(smu->adev, NULL);
-       memcpy(smu_table->metrics_table, table->cpu_addr, table_size);
-
-       if (metrics_table)
-               memcpy(metrics_table, smu_table->metrics_table, 
sizeof(SystemMetricsTable_t));
+       smu_table_cache_update_time(sys_table, jiffies);
+       memcpy(sys_table->cache.buffer, table->cpu_addr,
+              smu_v13_0_12_get_system_metrics_size());
 
        return 0;
 }
@@ -571,10 +586,10 @@ static ssize_t smu_v13_0_12_get_temp_metrics(struct 
smu_context *smu,
        struct amdgpu_baseboard_temp_metrics_v1_0 *baseboard_temp_metrics;
        struct amdgpu_gpuboard_temp_metrics_v1_0 *gpuboard_temp_metrics;
        struct smu_table_context *smu_table = &smu->smu_table;
-       SystemMetricsTable_t *metrics =
-               (SystemMetricsTable_t *)smu_table->metrics_table;
-
+       struct smu_table *tables = smu_table->tables;
+       SystemMetricsTable_t *metrics;
        struct smu_table *data_table;
+       struct smu_table *sys_table;
        int ret, sensor_type;
        u32 idx, sensors;
        ssize_t size;
@@ -596,10 +611,12 @@ static ssize_t smu_v13_0_12_get_temp_metrics(struct 
smu_context *smu,
                size = sizeof(*baseboard_temp_metrics);
        }
 
-       ret = smu_v13_0_12_get_system_metrics_table(smu, NULL);
+       ret = smu_v13_0_12_get_system_metrics_table(smu);
        if (ret)
                return ret;
 
+       sys_table = &tables[SMU_TABLE_PMFW_SYSTEM_METRICS];
+       metrics = (SystemMetricsTable_t *)sys_table->cache.buffer;
        smu_table_cache_update_time(data_table, jiffies);
 
        if (type == SMU_TEMP_METRIC_GPUBOARD) {
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
index e37b7b5358ea..ebee659f8a1c 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
@@ -559,6 +559,10 @@ static int smu_v13_0_6_tables_init(struct smu_context *smu)
                       PAGE_SIZE,
                       AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT);
 
+       SMU_TABLE_INIT(tables, SMU_TABLE_PMFW_SYSTEM_METRICS,
+                      smu_v13_0_12_get_system_metrics_size(), PAGE_SIZE,
+                      AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT);
+
        metrics_table = kzalloc(METRICS_TABLE_SIZE, GFP_KERNEL);
        if (!metrics_table)
                return -ENOMEM;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h
index bcb8246c0804..aae9a546a67e 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h
@@ -82,6 +82,7 @@ int smu_v13_0_6_get_metrics_table(struct smu_context *smu, 
void *metrics_table,
 
 bool smu_v13_0_12_is_dpm_running(struct smu_context *smu);
 int smu_v13_0_12_get_max_metrics_size(void);
+size_t smu_v13_0_12_get_system_metrics_size(void);
 int smu_v13_0_12_setup_driver_pptable(struct smu_context *smu);
 int smu_v13_0_12_get_smu_metrics_data(struct smu_context *smu,
                                      MetricsMember_t member, uint32_t *value);
-- 
2.49.0

Reply via email to