aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1459-drm-amd-powerplay-adjust-power-state-when-set-od_clk.patch
blob: 2f2e8afdbada14e76a22f8da7192613cd63e38ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
From d10759d37624110fd5a266ad230fe25f9960ad34 Mon Sep 17 00:00:00 2001
From: Likun Gao <Likun.Gao@amd.com>
Date: Wed, 23 Jan 2019 11:10:59 +0800
Subject: [PATCH 1459/2940] drm/amd/powerplay: adjust power state when set
 od_clk

Expose the function of adjust_power_state_dynamic to make it common to
other functions.
Add the operate of adjust powet state when set od percentage or
overdrive commit dpm table.

Signed-off-by: Likun Gao <Likun.Gao@amd.com>
Reviewed-by: Huang Rui <ray.huang@amd.com>
Reviewed-by: Kevin Wang <kevin1.wang@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 80 +++++++++++++++-------
 1 file changed, 56 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
index ff44ef89204a..2833bd8a8078 100644
--- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
@@ -1764,44 +1764,35 @@ static enum amd_dpm_forced_level vega20_get_performance_level(struct smu_context
 	return smu_dpm_ctx->dpm_level;
 }
 
-static int
-vega20_force_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level)
+static int vega20_adjust_power_state_dynamic(struct smu_context *smu,
+					     enum amd_dpm_forced_level level)
 {
 	int ret = 0;
 	int index = 0;
-	int i = 0;
 	uint32_t sclk_mask, mclk_mask, soc_mask;
 	long workload;
 	struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
-	if (!smu_dpm_ctx->dpm_context)
-		return -EINVAL;
 
-	for (i = 0; i < smu->adev->num_ip_blocks; i++) {
-		if (smu->adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC)
-			break;
-	}
-	mutex_lock(&smu->mutex);
-	smu->adev->ip_blocks[i].version->funcs->enable_umd_pstate(smu, &level);
 	ret = vega20_display_config_changed(smu);
 	if (ret) {
 		pr_err("Failed to change display config!");
-		goto failed;
+		return ret;
 	}
 	ret = vega20_apply_clocks_adjust_rules(smu);
 	if (ret) {
 		pr_err("Failed to apply clocks adjust rules!");
-		goto failed;
+		return ret;
 	}
 	ret = vega20_notify_smc_dispaly_config(smu);
 	if (ret) {
 		pr_err("Failed to notify smc display config!");
-		goto failed;
+		return ret;
 	}
+
 	switch (level) {
 	case AMD_DPM_FORCED_LEVEL_HIGH:
 		ret = vega20_force_dpm_highest(smu);
 		break;
-
 	case AMD_DPM_FORCED_LEVEL_LOW:
 		ret = vega20_force_dpm_lowest(smu);
 		break;
@@ -1819,7 +1810,7 @@ vega20_force_performance_level(struct smu_context *smu, enum amd_dpm_forced_leve
 						    &mclk_mask,
 						    &soc_mask);
 		if (ret)
-			goto failed;
+			return ret;
 		vega20_force_clk_levels(smu, PP_SCLK, 1 << sclk_mask);
 		vega20_force_clk_levels(smu, PP_MCLK, 1 << mclk_mask);
 		break;
@@ -1842,8 +1833,31 @@ vega20_force_performance_level(struct smu_context *smu, enum amd_dpm_forced_leve
 			smu->funcs->set_power_profile_mode(smu, &workload, 0);
 	}
 
-failed:
+	return ret;
+}
+
+static int
+vega20_force_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level)
+{
+	int ret = 0;
+	int i;
+	struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
+
+	if (!smu_dpm_ctx->dpm_context)
+		return -EINVAL;
+
+	for (i = 0; i < smu->adev->num_ip_blocks; i++) {
+		if (smu->adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC)
+			break;
+	}
+
+	mutex_lock(&smu->mutex);
+
+	smu->adev->ip_blocks[i].version->funcs->enable_umd_pstate(smu, &level);
+	ret = vega20_adjust_power_state_dynamic(smu, level);
+
 	mutex_unlock(&smu->mutex);
+
 	return ret;
 }
 
@@ -1934,9 +1948,12 @@ static int vega20_set_od_percentage(struct smu_context *smu,
 	struct vega20_single_dpm_table *single_dpm_table;
 	struct vega20_single_dpm_table *golden_dpm_table;
 	uint32_t od_clk, index;
-	int ret, feature_enabled;
+	int ret = 0;
+	int feature_enabled;
 	PPCLK_e clk_id;
 
+	mutex_lock(&(smu->mutex));
+
 	dpm_table = smu_dpm->dpm_context;
 	golden_table = smu_dpm->golden_dpm_context;
 
@@ -1956,10 +1973,13 @@ static int vega20_set_od_percentage(struct smu_context *smu,
 		index = OD8_SETTING_UCLK_FMAX;
 		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
 		break;
 	}
 
+	if (ret)
+		goto set_od_failed;
+
 	od_clk = golden_dpm_table->dpm_levels[golden_dpm_table->count - 1].value * value;
 	od_clk /= 100;
 	od_clk += golden_dpm_table->dpm_levels[golden_dpm_table->count - 1].value;
@@ -1967,7 +1987,7 @@ static int vega20_set_od_percentage(struct smu_context *smu,
 	ret = smu_update_od8_settings(smu, index, od_clk);
 	if (ret) {
 		pr_err("[Setoverdrive] failed to set od clk!\n");
-		return ret;
+		goto set_od_failed;
 	}
 
 	if (feature_enabled) {
@@ -1975,14 +1995,19 @@ static int vega20_set_od_percentage(struct smu_context *smu,
 						  clk_id);
 		if (ret) {
 			pr_err("[Setoverdrive] failed to refresh dpm table!\n");
-			return ret;
+			goto set_od_failed;
 		}
 	} else {
 		single_dpm_table->count = 1;
 		single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
 	}
 
-	return 0;
+	ret = vega20_adjust_power_state_dynamic(smu, smu_dpm->dpm_level);
+
+set_od_failed:
+	mutex_unlock(&(smu->mutex));
+
+	return ret;
 }
 
 static int vega20_odn_edit_dpm_table(struct smu_context *smu,
@@ -1999,7 +2024,8 @@ static int vega20_odn_edit_dpm_table(struct smu_context *smu,
 		(struct vega20_od8_settings *)table_context->od8_settings;
 	struct pp_clock_levels_with_latency clocks;
 	int32_t input_index, input_clk, input_vol, i;
-	int od8_id, ret;
+	int od8_id;
+	int ret = 0;
 
 	dpm_table = smu_dpm->dpm_context;
 
@@ -2204,7 +2230,13 @@ static int vega20_odn_edit_dpm_table(struct smu_context *smu,
 		return -EINVAL;
 	}
 
-	return 0;
+	if (type == PP_OD_COMMIT_DPM_TABLE) {
+		mutex_lock(&(smu->mutex));
+		ret = vega20_adjust_power_state_dynamic(smu, smu_dpm->dpm_level);
+		mutex_unlock(&(smu->mutex));
+	}
+
+	return ret;
 }
 
 static const struct pptable_funcs vega20_ppt_funcs = {
-- 
2.17.1