From: sguttula <[email protected]>

Unified metric values reported by SMU 15.0.0 are accumulated in units of
KBytes. Convert the accumulated values to averages by dividing by 1024
before reporting them to userspace.

Signed-off-by: sguttula <[email protected]>
Signed-off-by: Ramalingeswara Reddy, Kanala <[email protected]>
---
 .../drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c  | 76 ++++++++++++-------
 .../drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h  |  3 +-
 2 files changed, 52 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c
index a280506f43fa..a6a7df683b7e 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c
@@ -355,7 +355,7 @@ static int smu_v15_0_0_get_metrics_table(struct smu_context 
*smu,
        addr = ((uint64_t)args.out_args[1] << 32) | args.out_args[0];
        table_size = args.out_args[2];
 
-       cpu_addr = ioremap_wc(addr, metrics->table_size);
+       cpu_addr = ioremap_wc(addr, table_size);
 
        args.msg = SMU_MSG_GetMetricsTableLogSample;
        args.num_args = 0;
@@ -371,6 +371,10 @@ static int smu_v15_0_0_get_metrics_table(struct 
smu_context *smu,
 
 #define get_diff(a, b) \
        (a > b ? ((0xFFFFFFFF - a) + b + 1) : (b - a))
+#define get_diff_count(a, b) \
+       (a > b ? ((MAX_UINT32  - a) + b + 1) : (b - a))
+#define get_diff_val(a, b) \
+       (a > b ? ((MAX_UINT64  - a) + b + 1) : (b - a))
 
 static int smu_v15_0_0_get_smu_metrics_data(struct smu_context *smu,
                                            MetricsMember_t member,
@@ -380,7 +384,8 @@ static int smu_v15_0_0_get_smu_metrics_data(struct 
smu_context *smu,
        SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; //TBD
 
        SMU_15_0_0_MetricsTable_t prev_metrics;
-       int ret, counter, val;
+       uint64_t counter, val;
+       int ret;
 
        memcpy(&prev_metrics, smu_table->metrics_table,
                        sizeof(SMU_15_0_0_MetricsTable_t));
@@ -391,67 +396,86 @@ static int smu_v15_0_0_get_smu_metrics_data(struct 
smu_context *smu,
 
        switch (member) {
        case METRICS_AVERAGE_GFXCLK:
-               counter = get_diff(prev_metrics.IOD.AccumulationCounter,
+               counter = get_diff_count(prev_metrics.IOD.AccumulationCounter,
                 ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.AccumulationCounter);
-               val = get_diff(prev_metrics.IOD.GfxclkFreqEffAcc,
+               val = get_diff_val(prev_metrics.IOD.GfxclkFreqEffAcc,
                 ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.GfxclkFreqEffAcc);
-               *value = counter ? (val/counter)*1024 : 0;
+               *value = counter ? (val/counter)/1024 : 0;
                break;
        case METRICS_AVERAGE_SOCCLK:
-               counter = get_diff(prev_metrics.IOD.AccumulationCounter,
+               counter = get_diff_count(prev_metrics.IOD.AccumulationCounter,
                 ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.AccumulationCounter);
-               val = get_diff(prev_metrics.IOD.SocclkFreqEffAcc,
+               val = get_diff_val(prev_metrics.IOD.SocclkFreqEffAcc,
                 ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.SocclkFreqEffAcc);
-               *value = counter ? (val/counter)*1024 : 0;
+               *value = counter ? (val/counter)/1024 : 0;
                break;
        case METRICS_AVERAGE_VCLK:
-               *value = 0;//metrics->VclkFrequency;
+               counter = get_diff_count(prev_metrics.IOD.AccumulationCounter,
+                ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.AccumulationCounter);
+               val = get_diff_val(prev_metrics.IOD.VclkFreqEffAcc,
+                ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.VclkFreqEffAcc);
+               *value = counter ? (val/counter)/1024 : 0;
                break;
        case METRICS_AVERAGE_DCLK:
                *value = 0;
                break;
        case METRICS_AVERAGE_UCLK:
-               counter = get_diff(prev_metrics.IOD.AccumulationCounter,
+               counter = get_diff_count(prev_metrics.IOD.AccumulationCounter,
                 ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.AccumulationCounter);
-               val = get_diff(prev_metrics.IOD.MemclkFreqEffAcc,
+               val = get_diff_val(prev_metrics.IOD.MemclkFreqEffAcc,
                 ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.MemclkFreqEffAcc);
-               *value = counter ? (val/counter)*1024 : 0;
+               *value = counter ? (val/counter)/1024 : 0;
                break;
        case METRICS_AVERAGE_FCLK:
-               *value = metrics->FclkFrequency;
+               counter = get_diff_count(prev_metrics.IOD.AccumulationCounter,
+                ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.AccumulationCounter);
+               val = get_diff_val(prev_metrics.IOD.FclkFreqEffAcc,
+                ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.FclkFreqEffAcc);
+               *value = counter ? (val/counter)/1024 : 0;
                break;
        case METRICS_AVERAGE_VPECLK:
                *value = metrics->VpeclkFrequency;
                break;
        case METRICS_AVERAGE_NPUCLK:
-               *value = metrics->NpuclkFrequency;
+               counter = get_diff_count(prev_metrics.IOD.AccumulationCounter,
+                ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.AccumulationCounter);
+               val = get_diff_val(prev_metrics.IOD.NpuhclkFreqEffAcc,
+                ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.NpuhclkFreqEffAcc);
+               *value = counter ? (val/counter)/1024 : 0;
                break;
        case METRICS_AVERAGE_GFXACTIVITY:
-               counter = get_diff(prev_metrics.IOD.AccumulationCounter,
+               counter = get_diff_count(prev_metrics.IOD.AccumulationCounter,
                 ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.AccumulationCounter);
-               val = get_diff(prev_metrics.IOD.GfxBusyAcc,
+               val = get_diff_val(prev_metrics.IOD.GfxBusyAcc,
                 ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.GfxBusyAcc);
-               *value = counter ? (val/counter)*1024 : 0;
+               *value = counter ? (val/counter)/1024 : 0;
                break;
        case METRICS_AVERAGE_VCNACTIVITY:
-               *value = metrics->VcnActivity / 100;
+               counter = get_diff_count(prev_metrics.IOD.AccumulationCounter,
+                ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.AccumulationCounter);
+               val = get_diff_val(prev_metrics.IOD.VcnBusyAcc,
+                ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.VcnBusyAcc);
+               *value = counter ? (val/counter)/1024 : 0;
                break;
        case METRICS_AVERAGE_SOCKETPOWER:
-               counter = get_diff(prev_metrics.IOD.AccumulationCounter,
+               counter = get_diff_count(prev_metrics.IOD.AccumulationCounter,
                 ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.AccumulationCounter);
-               val = get_diff(prev_metrics.IOD.ApuPowerAcc,
+               val = get_diff_val(prev_metrics.IOD.ApuPowerAcc,
                 ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.ApuPowerAcc);
-               *value = counter ? (val/counter)*1024 : 0;
+               *value = counter ? (val/counter)/1024 : 0;
        case METRICS_CURR_SOCKETPOWER:
-               counter = get_diff(prev_metrics.IOD.AccumulationCounter,
+               counter = get_diff_count(prev_metrics.IOD.AccumulationCounter,
                 ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.AccumulationCounter);
-               val = get_diff(prev_metrics.IOD.SystemPowerAcc,
+               val = get_diff_val(prev_metrics.IOD.SystemPowerAcc,
                 ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.SystemPowerAcc);
-               *value = counter ? (val/counter)*1024 : 0;
+               *value = counter ? (val/counter)/1024 : 0;
                break;
        case METRICS_TEMPERATURE_EDGE:
-               *value = metrics->GfxTemperature / 100 *
-               SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
+               counter = get_diff_count(prev_metrics.IOD.AccumulationCounter,
+                ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.AccumulationCounter);
+               val = get_diff_val(prev_metrics.IOD.GFX_TempAcc,
+                ((SMU_15_0_0_MetricsTable_t 
*)smu_table->metrics_table)->IOD.GFX_TempAcc);
+               *value = counter ? (val/counter)/1024 : 0;
                break;
        case METRICS_TEMPERATURE_HOTSPOT:
                *value = metrics->SocTemperature / 100 *
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h 
b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h
index b3dc6ccdddaf..592bb0f8ee96 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h
@@ -23,6 +23,8 @@
 #ifndef __SMU_V15_0_0_PPT_H__
 #define __SMU_V15_0_0_PPT_H__
 
+#define MAX_UINT32 0x00000000FFFFFFFF
+#define MAX_UINT64 0xFFFFFFFFFFFFFFFF
 #pragma pack(push, 1)
 
 typedef struct {
@@ -213,7 +215,6 @@ typedef struct {
 } MetricsTable_CCX_t;
 
 typedef struct {
-       uint32_t table_size;
        MetricsTable_IOD_t IOD;
        MetricsTable_CCX_t CCX[4];
 } SMU_15_0_0_MetricsTable_t;
-- 
2.53.0

Reply via email to