drm/amd/pm: Add support to fetch pm metrics sample
authorLijo Lazar <lijo.lazar@amd.com>
Fri, 29 Sep 2023 05:21:02 +0000 (10:51 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 29 Nov 2023 21:23:46 +0000 (16:23 -0500)
Add API support to fetch a snapshot of power management metrics from PMFW.

Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: Yang Wang <kevinyang.wang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/include/kgd_pp_interface.h
drivers/gpu/drm/amd/pm/amdgpu_dpm.c
drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h

index f9c438d16c5656e8c9a2cab67014864c1907cee6..6a1d31e8fdd1f7451ae641cf1c2b5c7ac3806d0a 100644 (file)
@@ -431,6 +431,7 @@ struct amd_pm_funcs {
        int (*set_df_cstate)(void *handle, enum pp_df_cstate state);
        int (*set_xgmi_pstate)(void *handle, uint32_t pstate);
        ssize_t (*get_gpu_metrics)(void *handle, void **table);
+       ssize_t (*get_pm_metrics)(void *handle, void *pmmetrics, size_t size);
        int (*set_watermarks_for_clock_ranges)(void *handle,
                                               struct pp_smu_wm_range_sets *ranges);
        int (*display_disable_memory_clock_switch)(void *handle,
index 1ae3b81548fa3e4567d2586b6a23cd302f0e7dbb..4717884a2bc4c6bbe6b7748ff437a43cd9f3eeaf 100644 (file)
@@ -1299,6 +1299,23 @@ int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void **table)
        return ret;
 }
 
+ssize_t amdgpu_dpm_get_pm_metrics(struct amdgpu_device *adev, void *pm_metrics,
+                                 size_t size)
+{
+       const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+       int ret = 0;
+
+       if (!pp_funcs->get_pm_metrics)
+               return -EOPNOTSUPP;
+
+       mutex_lock(&adev->pm.mutex);
+       ret = pp_funcs->get_pm_metrics(adev->powerplay.pp_handle, pm_metrics,
+                                      size);
+       mutex_unlock(&adev->pm.mutex);
+
+       return ret;
+}
+
 int amdgpu_dpm_get_fan_control_mode(struct amdgpu_device *adev,
                                    uint32_t *fan_mode)
 {
index feccd2a7120dcdf82e8f0492050f1f9b87f172e6..9b3fef5474b118171b33649267cad5b2f021e932 100644 (file)
@@ -511,6 +511,18 @@ int amdgpu_dpm_get_power_profile_mode(struct amdgpu_device *adev,
 int amdgpu_dpm_set_power_profile_mode(struct amdgpu_device *adev,
                                      long *input, uint32_t size);
 int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void **table);
+
+/**
+ * @get_pm_metrics: Get one snapshot of power management metrics from PMFW. The
+ * sample is copied to pm_metrics buffer. It's expected to be allocated by the
+ * caller and size of the allocated buffer is passed. Max size expected for a
+ * metrics sample is 4096 bytes.
+ *
+ * Return: Actual size of the metrics sample
+ */
+ssize_t amdgpu_dpm_get_pm_metrics(struct amdgpu_device *adev, void *pm_metrics,
+                                 size_t size);
+
 int amdgpu_dpm_get_fan_control_mode(struct amdgpu_device *adev,
                                    uint32_t *fan_mode);
 int amdgpu_dpm_set_fan_speed_pwm(struct amdgpu_device *adev,
index 37c2605f9b35110d3ff0a07b67f6298d7ede7a4d..930e7e3532ad36cd6d83c7fe654f32a5924b0623 100644 (file)
@@ -3189,6 +3189,20 @@ static ssize_t smu_sys_get_gpu_metrics(void *handle, void **table)
        return smu->ppt_funcs->get_gpu_metrics(smu, table);
 }
 
+static ssize_t smu_sys_get_pm_metrics(void *handle, void *pm_metrics,
+                                     size_t size)
+{
+       struct smu_context *smu = handle;
+
+       if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
+               return -EOPNOTSUPP;
+
+       if (!smu->ppt_funcs->get_pm_metrics)
+               return -EOPNOTSUPP;
+
+       return smu->ppt_funcs->get_pm_metrics(smu, pm_metrics, size);
+}
+
 static int smu_enable_mgpu_fan_boost(void *handle)
 {
        struct smu_context *smu = handle;
@@ -3330,6 +3344,7 @@ static const struct amd_pm_funcs swsmu_pm_funcs = {
        .set_df_cstate                    = smu_set_df_cstate,
        .set_xgmi_pstate                  = smu_set_xgmi_pstate,
        .get_gpu_metrics                  = smu_sys_get_gpu_metrics,
+       .get_pm_metrics                   = smu_sys_get_pm_metrics,
        .set_watermarks_for_clock_ranges     = smu_set_watermarks_for_clock_ranges,
        .display_disable_memory_clock_switch = smu_display_disable_memory_clock_switch,
        .get_max_sustainable_clocks_by_dc    = smu_get_max_sustainable_clocks_by_dc,
index 8def291b18bcdaa3db86ec4ef2545f154f70c098..32600ba74bf121d2898817ed0007d5b25f777b86 100644 (file)
@@ -253,6 +253,7 @@ struct smu_table {
        uint64_t mc_address;
        void *cpu_addr;
        struct amdgpu_bo *bo;
+       uint32_t version;
 };
 
 enum smu_perf_level_designation {
@@ -1252,6 +1253,15 @@ struct pptable_funcs {
         */
        ssize_t (*get_gpu_metrics)(struct smu_context *smu, void **table);
 
+       /**
+        * @get_pm_metrics: Get one snapshot of power management metrics from
+        * PMFW.
+        *
+        * Return: Size of the metrics sample
+        */
+       ssize_t (*get_pm_metrics)(struct smu_context *smu, void *pm_metrics,
+                                 size_t size);
+
        /**
         * @enable_mgpu_fan_boost: Enable multi-GPU fan boost.
         */
index 9dd47d91093eb6e3248c8d6de8edc5ed493be137..ea8ea99b74368a6e9b485954b6e9334a9cedc4d6 100644 (file)
        __SMU_DUMMY_MAP(PowerUpUmsch),  \
        __SMU_DUMMY_MAP(PowerDownUmsch),        \
        __SMU_DUMMY_MAP(SetSoftMaxVpe), \
-       __SMU_DUMMY_MAP(SetSoftMinVpe),
+       __SMU_DUMMY_MAP(SetSoftMinVpe), \
+       __SMU_DUMMY_MAP(GetMetricsVersion),
 
 #undef __SMU_DUMMY_MAP
 #define __SMU_DUMMY_MAP(type)  SMU_MSG_##type