Skip to content

Commit 74e1006

Browse files
Kenneth Fengalexdeucher
authored andcommitted
drm/amd/pm: correct the workload setting
Correct the workload setting in order not to mix the setting with the end user. Update the workload mask accordingly. v2: changes as below: 1. the end user can not erase the workload from driver except default workload. 2. always shows the real highest priority workoad to the end user. 3. the real workload mask is combined with driver workload mask and end user workload mask. v3: apply this to the other ASICs as well. v4: simplify the code v5: refine the code based on the review comments. Signed-off-by: Kenneth Feng <kenneth.feng@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> (cherry picked from commit 8cc438b) Cc: stable@vger.kernel.org # 6.11.x
1 parent 1356bfc commit 74e1006

12 files changed

Lines changed: 84 additions & 36 deletions

File tree

drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,26 +1259,33 @@ static int smu_sw_init(void *handle)
12591259
smu->watermarks_bitmap = 0;
12601260
smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
12611261
smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
1262+
smu->user_dpm_profile.user_workload_mask = 0;
12621263

12631264
atomic_set(&smu->smu_power.power_gate.vcn_gated, 1);
12641265
atomic_set(&smu->smu_power.power_gate.jpeg_gated, 1);
12651266
atomic_set(&smu->smu_power.power_gate.vpe_gated, 1);
12661267
atomic_set(&smu->smu_power.power_gate.umsch_mm_gated, 1);
12671268

1268-
smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;
1269-
smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;
1270-
smu->workload_prority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2;
1271-
smu->workload_prority[PP_SMC_POWER_PROFILE_VIDEO] = 3;
1272-
smu->workload_prority[PP_SMC_POWER_PROFILE_VR] = 4;
1273-
smu->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 5;
1274-
smu->workload_prority[PP_SMC_POWER_PROFILE_CUSTOM] = 6;
1269+
smu->workload_priority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;
1270+
smu->workload_priority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;
1271+
smu->workload_priority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2;
1272+
smu->workload_priority[PP_SMC_POWER_PROFILE_VIDEO] = 3;
1273+
smu->workload_priority[PP_SMC_POWER_PROFILE_VR] = 4;
1274+
smu->workload_priority[PP_SMC_POWER_PROFILE_COMPUTE] = 5;
1275+
smu->workload_priority[PP_SMC_POWER_PROFILE_CUSTOM] = 6;
12751276

12761277
if (smu->is_apu ||
1277-
!smu_is_workload_profile_available(smu, PP_SMC_POWER_PROFILE_FULLSCREEN3D))
1278-
smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];
1279-
else
1280-
smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D];
1278+
!smu_is_workload_profile_available(smu, PP_SMC_POWER_PROFILE_FULLSCREEN3D)) {
1279+
smu->driver_workload_mask =
1280+
1 << smu->workload_priority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];
1281+
} else {
1282+
smu->driver_workload_mask =
1283+
1 << smu->workload_priority[PP_SMC_POWER_PROFILE_FULLSCREEN3D];
1284+
smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
1285+
}
12811286

1287+
smu->workload_mask = smu->driver_workload_mask |
1288+
smu->user_dpm_profile.user_workload_mask;
12821289
smu->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
12831290
smu->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
12841291
smu->workload_setting[2] = PP_SMC_POWER_PROFILE_POWERSAVING;
@@ -2348,17 +2355,20 @@ static int smu_switch_power_profile(void *handle,
23482355
return -EINVAL;
23492356

23502357
if (!en) {
2351-
smu->workload_mask &= ~(1 << smu->workload_prority[type]);
2358+
smu->driver_workload_mask &= ~(1 << smu->workload_priority[type]);
23522359
index = fls(smu->workload_mask);
23532360
index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
23542361
workload[0] = smu->workload_setting[index];
23552362
} else {
2356-
smu->workload_mask |= (1 << smu->workload_prority[type]);
2363+
smu->driver_workload_mask |= (1 << smu->workload_priority[type]);
23572364
index = fls(smu->workload_mask);
23582365
index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
23592366
workload[0] = smu->workload_setting[index];
23602367
}
23612368

2369+
smu->workload_mask = smu->driver_workload_mask |
2370+
smu->user_dpm_profile.user_workload_mask;
2371+
23622372
if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
23632373
smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)
23642374
smu_bump_power_profile_mode(smu, workload, 0);
@@ -3049,12 +3059,23 @@ static int smu_set_power_profile_mode(void *handle,
30493059
uint32_t param_size)
30503060
{
30513061
struct smu_context *smu = handle;
3062+
int ret;
30523063

30533064
if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled ||
30543065
!smu->ppt_funcs->set_power_profile_mode)
30553066
return -EOPNOTSUPP;
30563067

3057-
return smu_bump_power_profile_mode(smu, param, param_size);
3068+
if (smu->user_dpm_profile.user_workload_mask &
3069+
(1 << smu->workload_priority[param[param_size]]))
3070+
return 0;
3071+
3072+
smu->user_dpm_profile.user_workload_mask =
3073+
(1 << smu->workload_priority[param[param_size]]);
3074+
smu->workload_mask = smu->user_dpm_profile.user_workload_mask |
3075+
smu->driver_workload_mask;
3076+
ret = smu_bump_power_profile_mode(smu, param, param_size);
3077+
3078+
return ret;
30583079
}
30593080

30603081
static int smu_get_fan_control_mode(void *handle, u32 *fan_mode)

drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ struct smu_user_dpm_profile {
240240
/* user clock state information */
241241
uint32_t clk_mask[SMU_CLK_COUNT];
242242
uint32_t clk_dependency;
243+
uint32_t user_workload_mask;
243244
};
244245

245246
#define SMU_TABLE_INIT(tables, table_id, s, a, d) \
@@ -557,7 +558,8 @@ struct smu_context {
557558
bool disable_uclk_switch;
558559

559560
uint32_t workload_mask;
560-
uint32_t workload_prority[WORKLOAD_POLICY_MAX];
561+
uint32_t driver_workload_mask;
562+
uint32_t workload_priority[WORKLOAD_POLICY_MAX];
561563
uint32_t workload_setting[WORKLOAD_POLICY_MAX];
562564
uint32_t power_profile_mode;
563565
uint32_t default_power_profile_mode;

drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,7 +1455,6 @@ static int arcturus_set_power_profile_mode(struct smu_context *smu,
14551455
return -EINVAL;
14561456
}
14571457

1458-
14591458
if ((profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) &&
14601459
(smu->smc_fw_version >= 0x360d00)) {
14611460
if (size != 10)
@@ -1523,14 +1522,14 @@ static int arcturus_set_power_profile_mode(struct smu_context *smu,
15231522

15241523
ret = smu_cmn_send_smc_msg_with_param(smu,
15251524
SMU_MSG_SetWorkloadMask,
1526-
1 << workload_type,
1525+
smu->workload_mask,
15271526
NULL);
15281527
if (ret) {
15291528
dev_err(smu->adev->dev, "Fail to set workload type %d\n", workload_type);
15301529
return ret;
15311530
}
15321531

1533-
smu->power_profile_mode = profile_mode;
1532+
smu_cmn_assign_power_profile(smu);
15341533

15351534
return 0;
15361535
}

drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2081,10 +2081,13 @@ static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, u
20812081
smu->power_profile_mode);
20822082
if (workload_type < 0)
20832083
return -EINVAL;
2084+
20842085
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
2085-
1 << workload_type, NULL);
2086+
smu->workload_mask, NULL);
20862087
if (ret)
20872088
dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__);
2089+
else
2090+
smu_cmn_assign_power_profile(smu);
20882091

20892092
return ret;
20902093
}

drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1786,10 +1786,13 @@ static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu, long *
17861786
smu->power_profile_mode);
17871787
if (workload_type < 0)
17881788
return -EINVAL;
1789+
17891790
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
1790-
1 << workload_type, NULL);
1791+
smu->workload_mask, NULL);
17911792
if (ret)
17921793
dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__);
1794+
else
1795+
smu_cmn_assign_power_profile(smu);
17931796

17941797
return ret;
17951798
}

drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,15 +1079,15 @@ static int vangogh_set_power_profile_mode(struct smu_context *smu, long *input,
10791079
}
10801080

10811081
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,
1082-
1 << workload_type,
1082+
smu->workload_mask,
10831083
NULL);
10841084
if (ret) {
10851085
dev_err_once(smu->adev->dev, "Fail to set workload type %d\n",
10861086
workload_type);
10871087
return ret;
10881088
}
10891089

1090-
smu->power_profile_mode = profile_mode;
1090+
smu_cmn_assign_power_profile(smu);
10911091

10921092
return 0;
10931093
}

drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -890,14 +890,14 @@ static int renoir_set_power_profile_mode(struct smu_context *smu, long *input, u
890890
}
891891

892892
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,
893-
1 << workload_type,
893+
smu->workload_mask,
894894
NULL);
895895
if (ret) {
896896
dev_err_once(smu->adev->dev, "Fail to set workload type %d\n", workload_type);
897897
return ret;
898898
}
899899

900-
smu->power_profile_mode = profile_mode;
900+
smu_cmn_assign_power_profile(smu);
901901

902902
return 0;
903903
}

drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,7 +2485,7 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
24852485
DpmActivityMonitorCoeffInt_t *activity_monitor =
24862486
&(activity_monitor_external.DpmActivityMonitorCoeffInt);
24872487
int workload_type, ret = 0;
2488-
u32 workload_mask, selected_workload_mask;
2488+
u32 workload_mask;
24892489

24902490
smu->power_profile_mode = input[size];
24912491

@@ -2552,7 +2552,7 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
25522552
if (workload_type < 0)
25532553
return -EINVAL;
25542554

2555-
selected_workload_mask = workload_mask = 1 << workload_type;
2555+
workload_mask = 1 << workload_type;
25562556

25572557
/* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */
25582558
if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) &&
@@ -2567,12 +2567,22 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
25672567
workload_mask |= 1 << workload_type;
25682568
}
25692569

2570+
smu->workload_mask |= workload_mask;
25702571
ret = smu_cmn_send_smc_msg_with_param(smu,
25712572
SMU_MSG_SetWorkloadMask,
2572-
workload_mask,
2573+
smu->workload_mask,
25732574
NULL);
2574-
if (!ret)
2575-
smu->workload_mask = selected_workload_mask;
2575+
if (!ret) {
2576+
smu_cmn_assign_power_profile(smu);
2577+
if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING) {
2578+
workload_type = smu_cmn_to_asic_specific_index(smu,
2579+
CMN2ASIC_MAPPING_WORKLOAD,
2580+
PP_SMC_POWER_PROFILE_FULLSCREEN3D);
2581+
smu->power_profile_mode = smu->workload_mask & (1 << workload_type)
2582+
? PP_SMC_POWER_PROFILE_FULLSCREEN3D
2583+
: PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
2584+
}
2585+
}
25762586

25772587
return ret;
25782588
}

drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2499,13 +2499,14 @@ static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *inp
24992499
smu->power_profile_mode);
25002500
if (workload_type < 0)
25012501
return -EINVAL;
2502+
25022503
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
2503-
1 << workload_type, NULL);
2504+
smu->workload_mask, NULL);
25042505

25052506
if (ret)
25062507
dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__);
25072508
else
2508-
smu->workload_mask = (1 << workload_type);
2509+
smu_cmn_assign_power_profile(smu);
25092510

25102511
return ret;
25112512
}

drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,12 +1807,11 @@ static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu,
18071807
if (workload_type < 0)
18081808
return -EINVAL;
18091809

1810-
ret = smu_cmn_send_smc_msg_with_param(smu,
1811-
SMU_MSG_SetWorkloadMask,
1812-
1 << workload_type,
1813-
NULL);
1810+
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
1811+
smu->workload_mask, NULL);
1812+
18141813
if (!ret)
1815-
smu->workload_mask = 1 << workload_type;
1814+
smu_cmn_assign_power_profile(smu);
18161815

18171816
return ret;
18181817
}

0 commit comments

Comments
 (0)