A new sysfs interface mem_busy_percent is added for telling
how busy the VRAM is(in percentage).

Change-Id: I302f7594000a1ad609d71563d8ab3872f37bfb8d
Signed-off-by: Evan Quan <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c        | 40 +++++++++++++++++++
 .../gpu/drm/amd/include/kgd_pp_interface.h    |  1 +
 .../drm/amd/powerplay/hwmgr/vega20_hwmgr.c    | 16 +++++++-
 3 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index b80873348624..eab58771132c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -1354,6 +1354,32 @@ static ssize_t amdgpu_get_busy_percent(struct device 
*dev,
        return snprintf(buf, PAGE_SIZE, "%d\n", value);
 }
 
+/**
+ * DOC: mem_busy_percent
+ *
+ * The amdgpu driver provides a sysfs API for reading how busy the VRAM
+ * is as a percentage.  The file mem_busy_percent is used for this.
+ * The SMU firmware computes a percentage of load based on the
+ * aggregate activity level in the IP cores.
+ */
+static ssize_t amdgpu_get_memory_busy_percent(struct device *dev,
+               struct device_attribute *attr,
+               char *buf)
+{
+       struct drm_device *ddev = dev_get_drvdata(dev);
+       struct amdgpu_device *adev = ddev->dev_private;
+       int r, value, size = sizeof(value);
+
+       /* read the IP busy sensor */
+       r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MEM_LOAD,
+                                  (void *)&value, &size);
+
+       if (r)
+               return r;
+
+       return snprintf(buf, PAGE_SIZE, "%d\n", value);
+}
+
 /**
  * DOC: pcie_bw
  *
@@ -1423,6 +1449,8 @@ static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR,
                amdgpu_set_pp_od_clk_voltage);
 static DEVICE_ATTR(gpu_busy_percent, S_IRUGO,
                amdgpu_get_busy_percent, NULL);
+static DEVICE_ATTR(mem_busy_percent, S_IRUGO,
+               amdgpu_get_memory_busy_percent, NULL);
 static DEVICE_ATTR(pcie_bw, S_IRUGO, amdgpu_get_pcie_bw, NULL);
 static DEVICE_ATTR(ppfeatures, S_IRUGO | S_IWUSR,
                amdgpu_get_ppfeature_status,
@@ -2805,6 +2833,16 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
                                "gpu_busy_level\n");
                return ret;
        }
+       /* APU does not have its own dedicated memory */
+       if (!(adev->flags & AMD_IS_APU)) {
+               ret = device_create_file(adev->dev,
+                               &dev_attr_mem_busy_percent);
+               if (ret) {
+                       DRM_ERROR("failed to create device file "
+                                       "mem_busy_percent\n");
+                       return ret;
+               }
+       }
        /* PCIe Perf counters won't work on APU nodes */
        if (!(adev->flags & AMD_IS_APU)) {
                ret = device_create_file(adev->dev, &dev_attr_pcie_bw);
@@ -2870,6 +2908,8 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
                device_remove_file(adev->dev,
                                &dev_attr_pp_od_clk_voltage);
        device_remove_file(adev->dev, &dev_attr_gpu_busy_percent);
+       if (!(adev->flags & AMD_IS_APU))
+               device_remove_file(adev->dev, &dev_attr_mem_busy_percent);
        if (!(adev->flags & AMD_IS_APU))
                device_remove_file(adev->dev, &dev_attr_pcie_bw);
        if ((adev->asic_type >= CHIP_VEGA10) &&
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h 
b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 30788d510576..9f661bf96ed0 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -109,6 +109,7 @@ enum amd_pp_sensors {
        AMDGPU_PP_SENSOR_UVD_DCLK,
        AMDGPU_PP_SENSOR_VCE_ECCLK,
        AMDGPU_PP_SENSOR_GPU_LOAD,
+       AMDGPU_PP_SENSOR_MEM_LOAD,
        AMDGPU_PP_SENSOR_GFX_MCLK,
        AMDGPU_PP_SENSOR_GPU_TEMP,
        AMDGPU_PP_SENSOR_EDGE_TEMP = AMDGPU_PP_SENSOR_GPU_TEMP,
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c 
b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
index abd3df9a0211..7534eb628803 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
@@ -2094,6 +2094,7 @@ static int vega20_get_current_clk_freq(struct pp_hwmgr 
*hwmgr,
 }
 
 static int vega20_get_current_activity_percent(struct pp_hwmgr *hwmgr,
+               int idx,
                uint32_t *activity_percent)
 {
        int ret = 0;
@@ -2103,7 +2104,17 @@ static int vega20_get_current_activity_percent(struct 
pp_hwmgr *hwmgr,
        if (ret)
                return ret;
 
-       *activity_percent = metrics_table.AverageGfxActivity;
+       switch (idx) {
+       case AMDGPU_PP_SENSOR_GPU_LOAD:
+               *activity_percent = metrics_table.AverageGfxActivity;
+               break;
+       case AMDGPU_PP_SENSOR_MEM_LOAD:
+               *activity_percent = metrics_table.AverageUclkActivity;
+               break;
+       default:
+               pr_err("Invalid index for retrieving clock activity\n");
+               return -EINVAL;
+       }
 
        return ret;
 }
@@ -2134,7 +2145,8 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int 
idx,
                        *size = 4;
                break;
        case AMDGPU_PP_SENSOR_GPU_LOAD:
-               ret = vega20_get_current_activity_percent(hwmgr, (uint32_t 
*)value);
+       case AMDGPU_PP_SENSOR_MEM_LOAD:
+               ret = vega20_get_current_activity_percent(hwmgr, idx, (uint32_t 
*)value);
                if (!ret)
                        *size = 4;
                break;
-- 
2.21.0

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to