aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c')
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c430
1 files changed, 430 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c
new file mode 100644
index 000000000000..8f142a74ad08
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c
@@ -0,0 +1,430 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#include "polaris10_clockpowergating.h"
25
26int polaris10_phm_powerdown_uvd(struct pp_hwmgr *hwmgr)
27{
28 if (phm_cf_want_uvd_power_gating(hwmgr))
29 return smum_send_msg_to_smc(hwmgr->smumgr,
30 PPSMC_MSG_UVDPowerOFF);
31 return 0;
32}
33
34int polaris10_phm_powerup_uvd(struct pp_hwmgr *hwmgr)
35{
36 if (phm_cf_want_uvd_power_gating(hwmgr)) {
37 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
38 PHM_PlatformCaps_UVDDynamicPowerGating)) {
39 return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
40 PPSMC_MSG_UVDPowerON, 1);
41 } else {
42 return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
43 PPSMC_MSG_UVDPowerON, 0);
44 }
45 }
46
47 return 0;
48}
49
50int polaris10_phm_powerdown_vce(struct pp_hwmgr *hwmgr)
51{
52 if (phm_cf_want_vce_power_gating(hwmgr))
53 return smum_send_msg_to_smc(hwmgr->smumgr,
54 PPSMC_MSG_VCEPowerOFF);
55 return 0;
56}
57
58int polaris10_phm_powerup_vce(struct pp_hwmgr *hwmgr)
59{
60 if (phm_cf_want_vce_power_gating(hwmgr))
61 return smum_send_msg_to_smc(hwmgr->smumgr,
62 PPSMC_MSG_VCEPowerON);
63 return 0;
64}
65
66int polaris10_phm_powerdown_samu(struct pp_hwmgr *hwmgr)
67{
68 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
69 PHM_PlatformCaps_SamuPowerGating))
70 return smum_send_msg_to_smc(hwmgr->smumgr,
71 PPSMC_MSG_SAMPowerOFF);
72 return 0;
73}
74
75int polaris10_phm_powerup_samu(struct pp_hwmgr *hwmgr)
76{
77 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
78 PHM_PlatformCaps_SamuPowerGating))
79 return smum_send_msg_to_smc(hwmgr->smumgr,
80 PPSMC_MSG_SAMPowerON);
81 return 0;
82}
83
84int polaris10_phm_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
85{
86 struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
87
88 data->uvd_power_gated = false;
89 data->vce_power_gated = false;
90 data->samu_power_gated = false;
91
92 polaris10_phm_powerup_uvd(hwmgr);
93 polaris10_phm_powerup_vce(hwmgr);
94 polaris10_phm_powerup_samu(hwmgr);
95
96 return 0;
97}
98
99int polaris10_phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
100{
101 struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
102
103 if (data->uvd_power_gated == bgate)
104 return 0;
105
106 data->uvd_power_gated = bgate;
107
108 if (bgate) {
109 polaris10_update_uvd_dpm(hwmgr, true);
110 polaris10_phm_powerdown_uvd(hwmgr);
111 } else {
112 polaris10_phm_powerup_uvd(hwmgr);
113 polaris10_update_uvd_dpm(hwmgr, false);
114 }
115
116 return 0;
117}
118
119int polaris10_phm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
120{
121 struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
122
123 if (data->vce_power_gated == bgate)
124 return 0;
125
126 data->vce_power_gated = bgate;
127
128 if (bgate)
129 polaris10_phm_powerdown_vce(hwmgr);
130 else
131 polaris10_phm_powerup_vce(hwmgr);
132
133 return 0;
134}
135
136int polaris10_phm_powergate_samu(struct pp_hwmgr *hwmgr, bool bgate)
137{
138 struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
139
140 if (data->samu_power_gated == bgate)
141 return 0;
142
143 data->samu_power_gated = bgate;
144
145 if (bgate) {
146 polaris10_update_samu_dpm(hwmgr, true);
147 polaris10_phm_powerdown_samu(hwmgr);
148 } else {
149 polaris10_phm_powerup_samu(hwmgr);
150 polaris10_update_samu_dpm(hwmgr, false);
151 }
152
153 return 0;
154}
155
156int polaris10_phm_update_clock_gatings(struct pp_hwmgr *hwmgr,
157 const uint32_t *msg_id)
158{
159 PPSMC_Msg msg;
160 uint32_t value;
161
162 switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
163 case PP_GROUP_GFX:
164 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
165 case PP_BLOCK_GFX_CG:
166 if (PP_STATE_SUPPORT_CG & *msg_id) {
167 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
168 PPSMC_MSG_EnableClockGatingFeature :
169 PPSMC_MSG_DisableClockGatingFeature;
170 value = CG_GFX_CGCG_MASK;
171
172 if (smum_send_msg_to_smc_with_parameter(
173 hwmgr->smumgr, msg, value))
174 return -1;
175 }
176 if (PP_STATE_SUPPORT_LS & *msg_id) {
177 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
178 ? PPSMC_MSG_EnableClockGatingFeature
179 : PPSMC_MSG_DisableClockGatingFeature;
180 value = CG_GFX_CGLS_MASK;
181
182 if (smum_send_msg_to_smc_with_parameter(
183 hwmgr->smumgr, msg, value))
184 return -1;
185 }
186 break;
187
188 case PP_BLOCK_GFX_3D:
189 if (PP_STATE_SUPPORT_CG & *msg_id) {
190 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
191 PPSMC_MSG_EnableClockGatingFeature :
192 PPSMC_MSG_DisableClockGatingFeature;
193 value = CG_GFX_3DCG_MASK;
194
195 if (smum_send_msg_to_smc_with_parameter(
196 hwmgr->smumgr, msg, value))
197 return -1;
198 }
199
200 if (PP_STATE_SUPPORT_LS & *msg_id) {
201 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
202 PPSMC_MSG_EnableClockGatingFeature :
203 PPSMC_MSG_DisableClockGatingFeature;
204 value = CG_GFX_3DLS_MASK;
205
206 if (smum_send_msg_to_smc_with_parameter(
207 hwmgr->smumgr, msg, value))
208 return -1;
209 }
210 break;
211
212 case PP_BLOCK_GFX_RLC:
213 if (PP_STATE_SUPPORT_LS & *msg_id) {
214 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
215 PPSMC_MSG_EnableClockGatingFeature :
216 PPSMC_MSG_DisableClockGatingFeature;
217 value = CG_GFX_RLC_LS_MASK;
218
219 if (smum_send_msg_to_smc_with_parameter(
220 hwmgr->smumgr, msg, value))
221 return -1;
222 }
223 break;
224
225 case PP_BLOCK_GFX_CP:
226 if (PP_STATE_SUPPORT_LS & *msg_id) {
227 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
228 PPSMC_MSG_EnableClockGatingFeature :
229 PPSMC_MSG_DisableClockGatingFeature;
230 value = CG_GFX_CP_LS_MASK;
231
232 if (smum_send_msg_to_smc_with_parameter(
233 hwmgr->smumgr, msg, value))
234 return -1;
235 }
236 break;
237
238 case PP_BLOCK_GFX_MG:
239 if (PP_STATE_SUPPORT_CG & *msg_id) {
240 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
241 PPSMC_MSG_EnableClockGatingFeature :
242 PPSMC_MSG_DisableClockGatingFeature;
243 value = (CG_CPF_MGCG_MASK | CG_RLC_MGCG_MASK |
244 CG_GFX_OTHERS_MGCG_MASK);
245
246 if (smum_send_msg_to_smc_with_parameter(
247 hwmgr->smumgr, msg, value))
248 return -1;
249 }
250 break;
251
252 default:
253 return -1;
254 }
255 break;
256
257 case PP_GROUP_SYS:
258 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
259 case PP_BLOCK_SYS_BIF:
260 if (PP_STATE_SUPPORT_CG & *msg_id) {
261 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
262 PPSMC_MSG_EnableClockGatingFeature :
263 PPSMC_MSG_DisableClockGatingFeature;
264 value = CG_SYS_BIF_MGCG_MASK;
265
266 if (smum_send_msg_to_smc_with_parameter(
267 hwmgr->smumgr, msg, value))
268 return -1;
269 }
270 if (PP_STATE_SUPPORT_LS & *msg_id) {
271 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
272 PPSMC_MSG_EnableClockGatingFeature :
273 PPSMC_MSG_DisableClockGatingFeature;
274 value = CG_SYS_BIF_MGLS_MASK;
275
276 if (smum_send_msg_to_smc_with_parameter(
277 hwmgr->smumgr, msg, value))
278 return -1;
279 }
280 break;
281
282 case PP_BLOCK_SYS_MC:
283 if (PP_STATE_SUPPORT_CG & *msg_id) {
284 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
285 PPSMC_MSG_EnableClockGatingFeature :
286 PPSMC_MSG_DisableClockGatingFeature;
287 value = CG_SYS_MC_MGCG_MASK;
288
289 if (smum_send_msg_to_smc_with_parameter(
290 hwmgr->smumgr, msg, value))
291 return -1;
292 }
293
294 if (PP_STATE_SUPPORT_LS & *msg_id) {
295 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
296 PPSMC_MSG_EnableClockGatingFeature :
297 PPSMC_MSG_DisableClockGatingFeature;
298 value = CG_SYS_MC_MGLS_MASK;
299
300 if (smum_send_msg_to_smc_with_parameter(
301 hwmgr->smumgr, msg, value))
302 return -1;
303 }
304 break;
305
306 case PP_BLOCK_SYS_DRM:
307 if (PP_STATE_SUPPORT_CG & *msg_id) {
308 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
309 PPSMC_MSG_EnableClockGatingFeature :
310 PPSMC_MSG_DisableClockGatingFeature;
311 value = CG_SYS_DRM_MGCG_MASK;
312
313 if (smum_send_msg_to_smc_with_parameter(
314 hwmgr->smumgr, msg, value))
315 return -1;
316 }
317 if (PP_STATE_SUPPORT_LS & *msg_id) {
318 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
319 PPSMC_MSG_EnableClockGatingFeature :
320 PPSMC_MSG_DisableClockGatingFeature;
321 value = CG_SYS_DRM_MGLS_MASK;
322
323 if (smum_send_msg_to_smc_with_parameter(
324 hwmgr->smumgr, msg, value))
325 return -1;
326 }
327 break;
328
329 case PP_BLOCK_SYS_HDP:
330 if (PP_STATE_SUPPORT_CG & *msg_id) {
331 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
332 PPSMC_MSG_EnableClockGatingFeature :
333 PPSMC_MSG_DisableClockGatingFeature;
334 value = CG_SYS_HDP_MGCG_MASK;
335
336 if (smum_send_msg_to_smc_with_parameter(
337 hwmgr->smumgr, msg, value))
338 return -1;
339 }
340
341 if (PP_STATE_SUPPORT_LS & *msg_id) {
342 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
343 PPSMC_MSG_EnableClockGatingFeature :
344 PPSMC_MSG_DisableClockGatingFeature;
345 value = CG_SYS_HDP_MGLS_MASK;
346
347 if (smum_send_msg_to_smc_with_parameter(
348 hwmgr->smumgr, msg, value))
349 return -1;
350 }
351 break;
352
353 case PP_BLOCK_SYS_SDMA:
354 if (PP_STATE_SUPPORT_CG & *msg_id) {
355 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
356 PPSMC_MSG_EnableClockGatingFeature :
357 PPSMC_MSG_DisableClockGatingFeature;
358 value = CG_SYS_SDMA_MGCG_MASK;
359
360 if (smum_send_msg_to_smc_with_parameter(
361 hwmgr->smumgr, msg, value))
362 return -1;
363 }
364
365 if (PP_STATE_SUPPORT_LS & *msg_id) {
366 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
367 PPSMC_MSG_EnableClockGatingFeature :
368 PPSMC_MSG_DisableClockGatingFeature;
369 value = CG_SYS_SDMA_MGLS_MASK;
370
371 if (smum_send_msg_to_smc_with_parameter(
372 hwmgr->smumgr, msg, value))
373 return -1;
374 }
375 break;
376
377 case PP_BLOCK_SYS_ROM:
378 if (PP_STATE_SUPPORT_CG & *msg_id) {
379 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
380 PPSMC_MSG_EnableClockGatingFeature :
381 PPSMC_MSG_DisableClockGatingFeature;
382 value = CG_SYS_ROM_MASK;
383
384 if (smum_send_msg_to_smc_with_parameter(
385 hwmgr->smumgr, msg, value))
386 return -1;
387 }
388 break;
389
390 default:
391 return -1;
392
393 }
394 break;
395
396 default:
397 return -1;
398
399 }
400
401 return 0;
402}
403
404/* This function is for Polaris11 only for now,
405 * Powerplay will only control the static per CU Power Gating.
406 * Dynamic per CU Power Gating will be done in gfx.
407 */
408int polaris10_phm_enable_per_cu_power_gating(struct pp_hwmgr *hwmgr, bool enable)
409{
410 struct cgs_system_info sys_info = {0};
411 uint32_t active_cus;
412 int result;
413
414 sys_info.size = sizeof(struct cgs_system_info);
415 sys_info.info_id = CGS_SYSTEM_INFO_GFX_CU_INFO;
416
417 result = cgs_query_system_info(hwmgr->device, &sys_info);
418
419 if (result)
420 return -EINVAL;
421 else
422 active_cus = sys_info.value;
423
424 if (enable)
425 return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
426 PPSMC_MSG_GFX_CU_PG_ENABLE, active_cus);
427 else
428 return smum_send_msg_to_smc(hwmgr->smumgr,
429 PPSMC_MSG_GFX_CU_PG_DISABLE);
430}