drm/amd/pm: Fetch static metrics table
authorAsad Kamal <asad.kamal@amd.com>
Mon, 10 Feb 2025 16:03:18 +0000 (00:03 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 25 Feb 2025 16:43:59 +0000 (11:43 -0500)
Fetch clock frequency table from static metrics table for
smu_v13_0_12

v2: Move PPTable definition, remove unnecessary checks for getting
static metrics table(Lijo)

Signed-off-by: Asad Kamal <asad.kamal@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h

index 609a04c7512911e4fdf490f5fd41fe5cd7b77de2..4dc3b37d52b9365f770167d0c3303667ef83c7f8 100644 (file)
 
 #define SMU_13_VCLK_SHIFT              16
 
+#define SMUQ10_TO_UINT(x) ((x) >> 10)
+#define SMUQ10_FRAC(x) ((x) & 0x3ff)
+#define SMUQ10_ROUND(x) ((SMUQ10_TO_UINT(x)) + ((SMUQ10_FRAC(x)) >= 0x200))
+
 extern const int pmfw_decoded_link_speed[5];
 extern const int pmfw_decoded_link_width[7];
 
@@ -307,6 +311,8 @@ int smu_v13_0_get_boot_freq_by_index(struct smu_context *smu,
 
 void smu_v13_0_interrupt_work(struct smu_context *smu);
 bool smu_v13_0_12_is_dpm_running(struct smu_context *smu);
+int smu_v13_0_12_get_max_metrics_size(void);
+int smu_v13_0_12_setup_driver_pptable(struct smu_context *smu);
 extern const struct cmn2asic_mapping smu_v13_0_12_feature_mask_map[];
 extern const struct cmn2asic_msg_mapping smu_v13_0_12_message_map[];
 #endif
index 5ad5dd879e81db5fdfc0bc240bbb318e3bffe298..1555fb9544875385aa34e215b1f1b8f46c1600e2 100644 (file)
@@ -145,6 +145,76 @@ static int smu_v13_0_12_get_enabled_mask(struct smu_context *smu,
        return ret;
 }
 
+int smu_v13_0_12_get_max_metrics_size(void)
+{
+       return sizeof(StaticMetricsTable_t);
+}
+
+static int smu_v13_0_12_get_static_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;
+       int ret;
+
+       ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetStaticMetricsTable, NULL);
+       if (ret) {
+               dev_info(smu->adev->dev,
+                        "Failed to export static metrics table!\n");
+               return ret;
+       }
+
+       amdgpu_asic_invalidate_hdp(smu->adev, NULL);
+       memcpy(smu_table->metrics_table, table->cpu_addr, table_size);
+
+       return 0;
+}
+
+int smu_v13_0_12_setup_driver_pptable(struct smu_context *smu)
+{
+       struct smu_table_context *smu_table = &smu->smu_table;
+       StaticMetricsTable_t *static_metrics = (StaticMetricsTable_t *)smu_table->metrics_table;
+       struct PPTable_t *pptable =
+               (struct PPTable_t *)smu_table->driver_pptable;
+       int ret, i;
+
+       if (!pptable->Init) {
+               ret = smu_v13_0_12_get_static_metrics_table(smu);
+               if (ret)
+                       return ret;
+
+               pptable->MaxSocketPowerLimit =
+                       SMUQ10_ROUND(static_metrics->MaxSocketPowerLimit);
+               pptable->MaxGfxclkFrequency =
+                       SMUQ10_ROUND(static_metrics->MaxGfxclkFrequency);
+               pptable->MinGfxclkFrequency =
+                       SMUQ10_ROUND(static_metrics->MinGfxclkFrequency);
+
+               for (i = 0; i < 4; ++i) {
+                       pptable->FclkFrequencyTable[i] =
+                               SMUQ10_ROUND(static_metrics->FclkFrequencyTable[i]);
+                       pptable->UclkFrequencyTable[i] =
+                               SMUQ10_ROUND(static_metrics->UclkFrequencyTable[i]);
+                       pptable->SocclkFrequencyTable[i] =
+                               SMUQ10_ROUND(static_metrics->SocclkFrequencyTable[i]);
+                       pptable->VclkFrequencyTable[i] =
+                               SMUQ10_ROUND(static_metrics->VclkFrequencyTable[i]);
+                       pptable->DclkFrequencyTable[i] =
+                               SMUQ10_ROUND(static_metrics->DclkFrequencyTable[i]);
+                       pptable->LclkFrequencyTable[i] =
+                               SMUQ10_ROUND(static_metrics->LclkFrequencyTable[i]);
+               }
+
+               /* use AID0 serial number by default */
+               pptable->PublicSerialNumber_AID =
+                       static_metrics->PublicSerialNumber_AID[0];
+
+               pptable->Init = true;
+       }
+
+       return 0;
+}
+
 bool smu_v13_0_12_is_dpm_running(struct smu_context *smu)
 {
        int ret;
index c43fce62df1c3bc5e27cf9796cbf4908b01d521b..c3e0da680cf8eb765404d2c6ec33214b5cfdd73b 100644 (file)
@@ -116,6 +116,7 @@ enum smu_v13_0_6_caps {
        SMU_CAP(RMA_MSG),
        SMU_CAP(ACA_SYND),
        SMU_CAP(SDMA_RESET),
+       SMU_CAP(STATIC_METRICS),
        SMU_CAP(ALL),
 };
 
@@ -252,25 +253,6 @@ static const uint8_t smu_v13_0_6_throttler_map[] = {
        [THROTTLER_PROCHOT_BIT]         = (SMU_THROTTLER_PROCHOT_GFX_BIT),
 };
 
-struct PPTable_t {
-       uint32_t MaxSocketPowerLimit;
-       uint32_t MaxGfxclkFrequency;
-       uint32_t MinGfxclkFrequency;
-       uint32_t FclkFrequencyTable[4];
-       uint32_t UclkFrequencyTable[4];
-       uint32_t SocclkFrequencyTable[4];
-       uint32_t VclkFrequencyTable[4];
-       uint32_t DclkFrequencyTable[4];
-       uint32_t LclkFrequencyTable[4];
-       uint32_t MaxLclkDpmRange;
-       uint32_t MinLclkDpmRange;
-       uint64_t PublicSerialNumber_AID;
-       bool Init;
-};
-
-#define SMUQ10_TO_UINT(x) ((x) >> 10)
-#define SMUQ10_FRAC(x) ((x) & 0x3ff)
-#define SMUQ10_ROUND(x) ((SMUQ10_TO_UINT(x)) + ((SMUQ10_FRAC(x)) >= 0x200))
 #define GET_GPU_METRIC_FIELD(field, version) ((version == METRICS_VERSION_V0) ?\
                (metrics_v0->field) : (metrics_v2->field))
 #define GET_METRIC_FIELD(field, version) ((version == METRICS_VERSION_V1) ?\
@@ -368,6 +350,9 @@ static void smu_v13_0_12_init_caps(struct smu_context *smu)
 
        if (fw_ver >= 0x00561700)
                smu_v13_0_6_cap_set(smu, SMU_CAP(SDMA_RESET));
+
+       if (fw_ver >= 0x00561E00)
+               smu_v13_0_6_cap_set(smu, SMU_CAP(STATIC_METRICS));
 }
 
 static void smu_v13_0_6_init_caps(struct smu_context *smu)
@@ -523,13 +508,14 @@ static int smu_v13_0_6_tables_init(struct smu_context *smu)
        struct smu_table_context *smu_table = &smu->smu_table;
        struct smu_table *tables = smu_table->tables;
        struct amdgpu_device *adev = smu->adev;
+       int gpu_metrcs_size = METRICS_TABLE_SIZE;
 
        if (!(adev->flags & AMD_IS_APU))
                SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU13_TOOL_SIZE,
                               PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
 
        SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS,
-                      METRICS_TABLE_SIZE,
+                      max(gpu_metrcs_size, smu_v13_0_12_get_max_metrics_size()),
                       PAGE_SIZE,
                       AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT);
 
@@ -776,6 +762,9 @@ static int smu_v13_0_6_setup_driver_pptable(struct smu_context *smu)
        int ret, i, retry = 100;
        uint32_t table_version;
 
+       if (smu_v13_0_6_cap_supported(smu, SMU_CAP(STATIC_METRICS)))
+               return smu_v13_0_12_setup_driver_pptable(smu);
+
        /* Store one-time values in driver PPTable */
        if (!pptable->Init) {
                while (--retry) {
index 717fe669882eb50398c63de9637cf2892d66def1..83745909e5644d1a2509ea4121cf9ec74a7a9ee1 100644 (file)
@@ -35,6 +35,22 @@ typedef enum {
 /*3*/   NUM_METRICS                         = 3
 } METRICS_LIST_e;
 
+struct PPTable_t {
+       uint32_t MaxSocketPowerLimit;
+       uint32_t MaxGfxclkFrequency;
+       uint32_t MinGfxclkFrequency;
+       uint32_t FclkFrequencyTable[4];
+       uint32_t UclkFrequencyTable[4];
+       uint32_t SocclkFrequencyTable[4];
+       uint32_t VclkFrequencyTable[4];
+       uint32_t DclkFrequencyTable[4];
+       uint32_t LclkFrequencyTable[4];
+       uint32_t MaxLclkDpmRange;
+       uint32_t MinLclkDpmRange;
+       uint64_t PublicSerialNumber_AID;
+       bool Init;
+};
+
 extern void smu_v13_0_6_set_ppt_funcs(struct smu_context *smu);
 
 #endif