Comment inline.

Regards
Evan

-----Original Message-----
From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf Of Rex 
Zhu
Sent: Friday, March 02, 2018 8:44 PM
To: amd-gfx@lists.freedesktop.org
Cc: Zhu, Rex <rex....@amd.com>
Subject: [PATCH 1/4] drm/amd/pp: Implement get/set_power_profile_mode on smu7

It show what parameters can be configured to tune the behavior of natural dpm 
for perf/watt on smu7.

user can select the mode per workload, but even the default per workload 
settings are not bulletproof.

user can configure custom settings per different use case for better perf or 
better perf/watt.

cat pp_power_profile_mode
NUM        MODE_NAME     SCLK_UP_HYST   SCLK_DOWN_HYST SCLK_ACTIVE_LEVEL     
MCLK_UP_HYST   MCLK_DOWN_HYST MCLK_ACTIVE_LEVEL
  0   3D_FULL_SCREEN:        0              100               30                
0              100               10
  1     POWER_SAVING:       10                0               30                
-                -                -
  2            VIDEO:        -                -                -               
10               16               31
  3               VR:        0               11               50                
0              100               10
  4          COMPUTE:        0                5               30                
-                -                -
  5           CUSTOM:        0                0                0                
0                0                0
  *          CURRENT:        0              100               30                
0              100               10

Under manual dpm level,

user can echo "0/1/2/3/4">pp_power_profile_mode to select 
3D_FULL_SCREEN/POWER_SAVING/VIDEO/VR/COMPUTE
mode.

echo "5 * * * * * * * *">pp_power_profile_mode to set custom settings.
"5 * * * * * * * *" mean "CUSTOM enable_sclk SCLK_UP_HYST SCLK_DOWN_HYST 
SCLK_ACTIVE_LEVEL enable_mclk MCLK_UP_HYST MCLK_DOWN_HYST MCLK_ACTIVE_LEVEL"

if the parameter enable_sclk/enable_mclk is true, driver will update the 
following parameters to dpm table.
if false, ignore the following parameters.

Reviewed-by: Alex Deucher <alexander.deuc...@amd.com>
Signed-off-by: Rex Zhu <rex....@amd.com>
---
 drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 143 +++++++++++++++++++++++
 1 file changed, 143 insertions(+)

diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c 
b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
index 731475b..c1e32f4 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
@@ -81,6 +81,13 @@
 #define PCIE_BUS_CLK                10000
 #define TCLK                        (PCIE_BUS_CLK / 10)
 
+static const struct profile_mode_setting smu7_profiling[5] =
+                                       {{1, 0, 100, 30, 1, 0, 100, 10},
+                                        {1, 10, 0, 30, 0, 0, 0, 0},
+                                        {0, 0, 0, 0, 1, 10, 16, 31},
+                                        {1, 0, 11, 50, 1, 0, 100, 10},
+                                        {1, 0, 5, 30, 0, 0, 0, 0},
+                                       };
 
 /** Values for the CG_THERMAL_CTRL::DPM_EVENT_SRC field. */  enum 
DPM_EVENT_SRC { @@ -2475,6 +2482,9 @@ static int smu7_hwmgr_backend_init(struct 
pp_hwmgr *hwmgr)
        smu7_patch_voltage_workaround(hwmgr);
        smu7_init_dpm_defaults(hwmgr);
 
+       hwmgr->power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
+       hwmgr->default_power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
+
        /* Get leakage voltage based on leakage ID. */
        if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
                        PHM_PlatformCaps_EVV)) {
@@ -4923,6 +4933,137 @@ static int smu7_odn_edit_dpm_table(struct pp_hwmgr 
*hwmgr,
        return 0;
 }
 
+static int smu7_get_power_profile_mode(struct pp_hwmgr *hwmgr, char 
+*buf) {
+       struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
+       uint32_t i, size = 0;
+       uint32_t len;
+
+       static const char *profile_name[6] = {"3D_FULL_SCREEN",
+                                       "POWER_SAVING",
+                                       "VIDEO",
+                                       "VR",
+                                       "COMPUTE",
+                                       "CUSTOM"};
+
+       static const char *title[8] = {"NUM",
+                       "MODE_NAME",
+                       "SCLK_UP_HYST",
+                       "SCLK_DOWN_HYST",
+                       "SCLK_ACTIVE_LEVEL",
+                       "MCLK_UP_HYST",
+                       "MCLK_DOWN_HYST",
+                       "MCLK_ACTIVE_LEVEL"};
+
+       if (!buf)
+               return -EINVAL;
+
+       size += sprintf(buf + size, "%s %16s %16s %16s %16s %16s %16s %16s\n",
+                       title[0], title[1], title[2], title[3],
+                       title[4], title[5], title[6], title[7]);
+
+       len = sizeof(smu7_profiling) / sizeof(struct profile_mode_setting);
+
+       for (i = 0; i < len; i++) {
+               if (smu7_profiling[i].bupdate_sclk)
+                       size += sprintf(buf + size, "%3d %16s: %8d %16d %16d ",
+                       i, profile_name[i], smu7_profiling[i].sclk_up_hyst,
+                       smu7_profiling[i].sclk_down_hyst,
+                       smu7_profiling[i].sclk_activity);
+               else
+                       size += sprintf(buf + size, "%3d %16s: %8s %16s %16s ",
+                       i, profile_name[i], "-", "-", "-");
+
+               if (smu7_profiling[i].bupdate_mclk)
+                       size += sprintf(buf + size, "%16d %16d %16d\n",
+                       smu7_profiling[i].mclk_up_hyst,
+                       smu7_profiling[i].mclk_down_hyst,
+                       smu7_profiling[i].mclk_activity);
+               else
+                       size += sprintf(buf + size, "%16s %16s %16s\n",
+                       "-", "-", "-");
+       }
+
+       size += sprintf(buf + size, "%3d %16s: %8d %16d %16d %16d %16d %16d\n",
+                       i, profile_name[i],
+                       data->custom_profile_setting.sclk_up_hyst,
+                       data->custom_profile_setting.sclk_down_hyst,
+                       data->custom_profile_setting.sclk_activity,
+                       data->custom_profile_setting.mclk_up_hyst,
+                       data->custom_profile_setting.mclk_down_hyst,
+                       data->custom_profile_setting.mclk_activity);
+
+       size += sprintf(buf + size, "%3s %16s: %8d %16d %16d %16d %16d %16d\n",
+                       "*", "CURRENT",
+                       data->current_profile_setting.sclk_up_hyst,
+                       data->current_profile_setting.sclk_down_hyst,
+                       data->current_profile_setting.sclk_activity,
+                       data->current_profile_setting.mclk_up_hyst,
+                       data->current_profile_setting.mclk_down_hyst,
+                       data->current_profile_setting.mclk_activity);
+
+       return size;
+}
+
+static int smu7_set_power_profile_mode(struct pp_hwmgr *hwmgr, long 
+*input, uint32_t size) {
+       struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
+       struct profile_mode_setting tmp;
+       enum PP_SMC_POWER_PROFILE mode;
+
+       if (input == NULL)
+               return -EINVAL;
+
+       mode = input[size];
+       switch (mode) {
+       case PP_SMC_POWER_PROFILE_CUSTOM:
+               if (size < 8)
+                       return -EINVAL;
+
+               data->custom_profile_setting.bupdate_sclk = input[0];
+               data->custom_profile_setting.sclk_up_hyst = input[1];
+               data->custom_profile_setting.sclk_down_hyst = input[2];
+               data->custom_profile_setting.sclk_activity = input[3];
+               data->custom_profile_setting.bupdate_mclk = input[4];
+               data->custom_profile_setting.mclk_up_hyst = input[5];
+               data->custom_profile_setting.mclk_down_hyst = input[6];
+               data->custom_profile_setting.mclk_activity = input[7];
+               if (!smum_update_dpm_settings(hwmgr, 
&data->custom_profile_setting)) {
+                       memcpy(&data->current_profile_setting, 
&data->custom_profile_setting, sizeof(struct profile_mode_setting));
+                       hwmgr->power_profile_mode = mode;
+               }
+               break;
+       case PP_SMC_POWER_PROFILE_FULLSCREEN3D:
+       case PP_SMC_POWER_PROFILE_POWERSAVING:
+       case PP_SMC_POWER_PROFILE_VIDEO:
+       case PP_SMC_POWER_PROFILE_VR:
+       case PP_SMC_POWER_PROFILE_COMPUTE:
+               if (mode == hwmgr->power_profile_mode)
+                       return 0;
+
+               memcpy(&tmp, &smu7_profiling[hwmgr->power_profile_mode], 
sizeof(struct profile_mode_setting));
[evan]  It seems the "hwmgr->power_profile_mode" should be "mode". That's the 
mode user wants to set.

+               if (!smum_update_dpm_settings(hwmgr, &tmp)) {
+                       if (tmp.bupdate_sclk) {
+                               data->current_profile_setting.bupdate_sclk = 
tmp.bupdate_sclk;
+                               data->current_profile_setting.sclk_up_hyst = 
tmp.sclk_up_hyst;
+                               data->current_profile_setting.sclk_down_hyst = 
tmp.sclk_down_hyst;
+                               data->current_profile_setting.sclk_activity = 
tmp.sclk_activity;
+                       }
+                       if (tmp.bupdate_mclk) {
+                               data->current_profile_setting.bupdate_mclk = 
tmp.bupdate_mclk;
+                               data->current_profile_setting.mclk_up_hyst = 
tmp.mclk_up_hyst;
+                               data->current_profile_setting.mclk_down_hyst = 
tmp.mclk_down_hyst;
+                               data->current_profile_setting.mclk_activity = 
tmp.mclk_activity;
+                       }
+                       hwmgr->power_profile_mode = mode;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
 
 static const struct pp_hwmgr_func smu7_hwmgr_funcs = {
        .backend_init = &smu7_hwmgr_backend_init, @@ -4979,6 +5120,8 @@ static 
int smu7_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
        .get_thermal_temperature_range = smu7_get_thermal_temperature_range,
        .odn_edit_dpm_table = smu7_odn_edit_dpm_table,
        .set_power_limit = smu7_set_power_limit,
+       .get_power_profile_mode = smu7_get_power_profile_mode,
+       .set_power_profile_mode = smu7_set_power_profile_mode,
 };
 
 uint8_t smu7_get_sleep_divider_id_from_clock(uint32_t clock,
--
1.9.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to