]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c
Merge remote-tracking branches 'spi/topic/devprop', 'spi/topic/fsl', 'spi/topic/fsl...
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / amd / powerplay / hwmgr / smu7_clockpowergating.c
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 "smu7_hwmgr.h"
25 #include "smu7_clockpowergating.h"
26 #include "smu7_common.h"
27
28 static int smu7_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
29 {
30 return smum_send_msg_to_smc(hwmgr->smumgr, enable ?
31 PPSMC_MSG_UVDDPM_Enable :
32 PPSMC_MSG_UVDDPM_Disable);
33 }
34
35 static int smu7_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
36 {
37 return smum_send_msg_to_smc(hwmgr->smumgr, enable ?
38 PPSMC_MSG_VCEDPM_Enable :
39 PPSMC_MSG_VCEDPM_Disable);
40 }
41
42 static int smu7_enable_disable_samu_dpm(struct pp_hwmgr *hwmgr, bool enable)
43 {
44 return smum_send_msg_to_smc(hwmgr->smumgr, enable ?
45 PPSMC_MSG_SAMUDPM_Enable :
46 PPSMC_MSG_SAMUDPM_Disable);
47 }
48
49 static int smu7_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
50 {
51 if (!bgate)
52 smum_update_smc_table(hwmgr, SMU_UVD_TABLE);
53 return smu7_enable_disable_uvd_dpm(hwmgr, !bgate);
54 }
55
56 static int smu7_update_vce_dpm(struct pp_hwmgr *hwmgr, bool bgate)
57 {
58 if (!bgate)
59 smum_update_smc_table(hwmgr, SMU_VCE_TABLE);
60 return smu7_enable_disable_vce_dpm(hwmgr, !bgate);
61 }
62
63 static int smu7_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate)
64 {
65 if (!bgate)
66 smum_update_smc_table(hwmgr, SMU_SAMU_TABLE);
67 return smu7_enable_disable_samu_dpm(hwmgr, !bgate);
68 }
69
70 int smu7_powerdown_uvd(struct pp_hwmgr *hwmgr)
71 {
72 if (phm_cf_want_uvd_power_gating(hwmgr))
73 return smum_send_msg_to_smc(hwmgr->smumgr,
74 PPSMC_MSG_UVDPowerOFF);
75 return 0;
76 }
77
78 static int smu7_powerup_uvd(struct pp_hwmgr *hwmgr)
79 {
80 if (phm_cf_want_uvd_power_gating(hwmgr)) {
81 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
82 PHM_PlatformCaps_UVDDynamicPowerGating)) {
83 return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
84 PPSMC_MSG_UVDPowerON, 1);
85 } else {
86 return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
87 PPSMC_MSG_UVDPowerON, 0);
88 }
89 }
90
91 return 0;
92 }
93
94 static int smu7_powerdown_vce(struct pp_hwmgr *hwmgr)
95 {
96 if (phm_cf_want_vce_power_gating(hwmgr))
97 return smum_send_msg_to_smc(hwmgr->smumgr,
98 PPSMC_MSG_VCEPowerOFF);
99 return 0;
100 }
101
102 static int smu7_powerup_vce(struct pp_hwmgr *hwmgr)
103 {
104 if (phm_cf_want_vce_power_gating(hwmgr))
105 return smum_send_msg_to_smc(hwmgr->smumgr,
106 PPSMC_MSG_VCEPowerON);
107 return 0;
108 }
109
110 static int smu7_powerdown_samu(struct pp_hwmgr *hwmgr)
111 {
112 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
113 PHM_PlatformCaps_SamuPowerGating))
114 return smum_send_msg_to_smc(hwmgr->smumgr,
115 PPSMC_MSG_SAMPowerOFF);
116 return 0;
117 }
118
119 static int smu7_powerup_samu(struct pp_hwmgr *hwmgr)
120 {
121 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
122 PHM_PlatformCaps_SamuPowerGating))
123 return smum_send_msg_to_smc(hwmgr->smumgr,
124 PPSMC_MSG_SAMPowerON);
125 return 0;
126 }
127
128 int smu7_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
129 {
130 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
131
132 data->uvd_power_gated = false;
133 data->vce_power_gated = false;
134 data->samu_power_gated = false;
135
136 smu7_powerup_uvd(hwmgr);
137 smu7_powerup_vce(hwmgr);
138 smu7_powerup_samu(hwmgr);
139
140 return 0;
141 }
142
143 int smu7_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
144 {
145 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
146
147 data->uvd_power_gated = bgate;
148
149 if (bgate) {
150 cgs_set_powergating_state(hwmgr->device,
151 AMD_IP_BLOCK_TYPE_UVD,
152 AMD_PG_STATE_GATE);
153 cgs_set_clockgating_state(hwmgr->device,
154 AMD_IP_BLOCK_TYPE_UVD,
155 AMD_CG_STATE_GATE);
156 smu7_update_uvd_dpm(hwmgr, true);
157 smu7_powerdown_uvd(hwmgr);
158 } else {
159 smu7_powerup_uvd(hwmgr);
160 cgs_set_clockgating_state(hwmgr->device,
161 AMD_IP_BLOCK_TYPE_UVD,
162 AMD_CG_STATE_UNGATE);
163 cgs_set_powergating_state(hwmgr->device,
164 AMD_IP_BLOCK_TYPE_UVD,
165 AMD_CG_STATE_UNGATE);
166 smu7_update_uvd_dpm(hwmgr, false);
167 }
168
169 return 0;
170 }
171
172 int smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
173 {
174 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
175
176 data->vce_power_gated = bgate;
177
178 if (bgate) {
179 cgs_set_powergating_state(hwmgr->device,
180 AMD_IP_BLOCK_TYPE_VCE,
181 AMD_PG_STATE_GATE);
182 cgs_set_clockgating_state(hwmgr->device,
183 AMD_IP_BLOCK_TYPE_VCE,
184 AMD_CG_STATE_GATE);
185 smu7_update_vce_dpm(hwmgr, true);
186 smu7_powerdown_vce(hwmgr);
187 } else {
188 smu7_powerup_vce(hwmgr);
189 cgs_set_clockgating_state(hwmgr->device,
190 AMD_IP_BLOCK_TYPE_VCE,
191 AMD_CG_STATE_UNGATE);
192 cgs_set_powergating_state(hwmgr->device,
193 AMD_IP_BLOCK_TYPE_VCE,
194 AMD_PG_STATE_UNGATE);
195 smu7_update_vce_dpm(hwmgr, false);
196 }
197 return 0;
198 }
199
200 int smu7_powergate_samu(struct pp_hwmgr *hwmgr, bool bgate)
201 {
202 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
203
204 if (data->samu_power_gated == bgate)
205 return 0;
206
207 data->samu_power_gated = bgate;
208
209 if (bgate) {
210 smu7_update_samu_dpm(hwmgr, true);
211 smu7_powerdown_samu(hwmgr);
212 } else {
213 smu7_powerup_samu(hwmgr);
214 smu7_update_samu_dpm(hwmgr, false);
215 }
216
217 return 0;
218 }
219
220 int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
221 const uint32_t *msg_id)
222 {
223 PPSMC_Msg msg;
224 uint32_t value;
225
226 if (!(hwmgr->feature_mask & PP_ENABLE_GFX_CG_THRU_SMU))
227 return 0;
228
229 switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
230 case PP_GROUP_GFX:
231 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
232 case PP_BLOCK_GFX_CG:
233 if (PP_STATE_SUPPORT_CG & *msg_id) {
234 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
235 PPSMC_MSG_EnableClockGatingFeature :
236 PPSMC_MSG_DisableClockGatingFeature;
237 value = CG_GFX_CGCG_MASK;
238
239 if (smum_send_msg_to_smc_with_parameter(
240 hwmgr->smumgr, msg, value))
241 return -EINVAL;
242 }
243 if (PP_STATE_SUPPORT_LS & *msg_id) {
244 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
245 ? PPSMC_MSG_EnableClockGatingFeature
246 : PPSMC_MSG_DisableClockGatingFeature;
247 value = CG_GFX_CGLS_MASK;
248
249 if (smum_send_msg_to_smc_with_parameter(
250 hwmgr->smumgr, msg, value))
251 return -EINVAL;
252 }
253 break;
254
255 case PP_BLOCK_GFX_3D:
256 if (PP_STATE_SUPPORT_CG & *msg_id) {
257 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
258 PPSMC_MSG_EnableClockGatingFeature :
259 PPSMC_MSG_DisableClockGatingFeature;
260 value = CG_GFX_3DCG_MASK;
261
262 if (smum_send_msg_to_smc_with_parameter(
263 hwmgr->smumgr, msg, value))
264 return -EINVAL;
265 }
266
267 if (PP_STATE_SUPPORT_LS & *msg_id) {
268 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
269 PPSMC_MSG_EnableClockGatingFeature :
270 PPSMC_MSG_DisableClockGatingFeature;
271 value = CG_GFX_3DLS_MASK;
272
273 if (smum_send_msg_to_smc_with_parameter(
274 hwmgr->smumgr, msg, value))
275 return -EINVAL;
276 }
277 break;
278
279 case PP_BLOCK_GFX_RLC:
280 if (PP_STATE_SUPPORT_LS & *msg_id) {
281 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
282 PPSMC_MSG_EnableClockGatingFeature :
283 PPSMC_MSG_DisableClockGatingFeature;
284 value = CG_GFX_RLC_LS_MASK;
285
286 if (smum_send_msg_to_smc_with_parameter(
287 hwmgr->smumgr, msg, value))
288 return -EINVAL;
289 }
290 break;
291
292 case PP_BLOCK_GFX_CP:
293 if (PP_STATE_SUPPORT_LS & *msg_id) {
294 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
295 PPSMC_MSG_EnableClockGatingFeature :
296 PPSMC_MSG_DisableClockGatingFeature;
297 value = CG_GFX_CP_LS_MASK;
298
299 if (smum_send_msg_to_smc_with_parameter(
300 hwmgr->smumgr, msg, value))
301 return -EINVAL;
302 }
303 break;
304
305 case PP_BLOCK_GFX_MG:
306 if (PP_STATE_SUPPORT_CG & *msg_id) {
307 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
308 PPSMC_MSG_EnableClockGatingFeature :
309 PPSMC_MSG_DisableClockGatingFeature;
310 value = (CG_CPF_MGCG_MASK | CG_RLC_MGCG_MASK |
311 CG_GFX_OTHERS_MGCG_MASK);
312
313 if (smum_send_msg_to_smc_with_parameter(
314 hwmgr->smumgr, msg, value))
315 return -EINVAL;
316 }
317 break;
318
319 default:
320 return -EINVAL;
321 }
322 break;
323
324 case PP_GROUP_SYS:
325 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
326 case PP_BLOCK_SYS_BIF:
327 if (PP_STATE_SUPPORT_CG & *msg_id) {
328 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
329 PPSMC_MSG_EnableClockGatingFeature :
330 PPSMC_MSG_DisableClockGatingFeature;
331 value = CG_SYS_BIF_MGCG_MASK;
332
333 if (smum_send_msg_to_smc_with_parameter(
334 hwmgr->smumgr, msg, value))
335 return -EINVAL;
336 }
337 if (PP_STATE_SUPPORT_LS & *msg_id) {
338 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
339 PPSMC_MSG_EnableClockGatingFeature :
340 PPSMC_MSG_DisableClockGatingFeature;
341 value = CG_SYS_BIF_MGLS_MASK;
342
343 if (smum_send_msg_to_smc_with_parameter(
344 hwmgr->smumgr, msg, value))
345 return -EINVAL;
346 }
347 break;
348
349 case PP_BLOCK_SYS_MC:
350 if (PP_STATE_SUPPORT_CG & *msg_id) {
351 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
352 PPSMC_MSG_EnableClockGatingFeature :
353 PPSMC_MSG_DisableClockGatingFeature;
354 value = CG_SYS_MC_MGCG_MASK;
355
356 if (smum_send_msg_to_smc_with_parameter(
357 hwmgr->smumgr, msg, value))
358 return -EINVAL;
359 }
360
361 if (PP_STATE_SUPPORT_LS & *msg_id) {
362 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
363 PPSMC_MSG_EnableClockGatingFeature :
364 PPSMC_MSG_DisableClockGatingFeature;
365 value = CG_SYS_MC_MGLS_MASK;
366
367 if (smum_send_msg_to_smc_with_parameter(
368 hwmgr->smumgr, msg, value))
369 return -EINVAL;
370 }
371 break;
372
373 case PP_BLOCK_SYS_DRM:
374 if (PP_STATE_SUPPORT_CG & *msg_id) {
375 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
376 PPSMC_MSG_EnableClockGatingFeature :
377 PPSMC_MSG_DisableClockGatingFeature;
378 value = CG_SYS_DRM_MGCG_MASK;
379
380 if (smum_send_msg_to_smc_with_parameter(
381 hwmgr->smumgr, msg, value))
382 return -EINVAL;
383 }
384 if (PP_STATE_SUPPORT_LS & *msg_id) {
385 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
386 PPSMC_MSG_EnableClockGatingFeature :
387 PPSMC_MSG_DisableClockGatingFeature;
388 value = CG_SYS_DRM_MGLS_MASK;
389
390 if (smum_send_msg_to_smc_with_parameter(
391 hwmgr->smumgr, msg, value))
392 return -EINVAL;
393 }
394 break;
395
396 case PP_BLOCK_SYS_HDP:
397 if (PP_STATE_SUPPORT_CG & *msg_id) {
398 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
399 PPSMC_MSG_EnableClockGatingFeature :
400 PPSMC_MSG_DisableClockGatingFeature;
401 value = CG_SYS_HDP_MGCG_MASK;
402
403 if (smum_send_msg_to_smc_with_parameter(
404 hwmgr->smumgr, msg, value))
405 return -EINVAL;
406 }
407
408 if (PP_STATE_SUPPORT_LS & *msg_id) {
409 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
410 PPSMC_MSG_EnableClockGatingFeature :
411 PPSMC_MSG_DisableClockGatingFeature;
412 value = CG_SYS_HDP_MGLS_MASK;
413
414 if (smum_send_msg_to_smc_with_parameter(
415 hwmgr->smumgr, msg, value))
416 return -EINVAL;
417 }
418 break;
419
420 case PP_BLOCK_SYS_SDMA:
421 if (PP_STATE_SUPPORT_CG & *msg_id) {
422 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
423 PPSMC_MSG_EnableClockGatingFeature :
424 PPSMC_MSG_DisableClockGatingFeature;
425 value = CG_SYS_SDMA_MGCG_MASK;
426
427 if (smum_send_msg_to_smc_with_parameter(
428 hwmgr->smumgr, msg, value))
429 return -EINVAL;
430 }
431
432 if (PP_STATE_SUPPORT_LS & *msg_id) {
433 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
434 PPSMC_MSG_EnableClockGatingFeature :
435 PPSMC_MSG_DisableClockGatingFeature;
436 value = CG_SYS_SDMA_MGLS_MASK;
437
438 if (smum_send_msg_to_smc_with_parameter(
439 hwmgr->smumgr, msg, value))
440 return -EINVAL;
441 }
442 break;
443
444 case PP_BLOCK_SYS_ROM:
445 if (PP_STATE_SUPPORT_CG & *msg_id) {
446 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
447 PPSMC_MSG_EnableClockGatingFeature :
448 PPSMC_MSG_DisableClockGatingFeature;
449 value = CG_SYS_ROM_MASK;
450
451 if (smum_send_msg_to_smc_with_parameter(
452 hwmgr->smumgr, msg, value))
453 return -EINVAL;
454 }
455 break;
456
457 default:
458 return -EINVAL;
459
460 }
461 break;
462
463 default:
464 return -EINVAL;
465
466 }
467
468 return 0;
469 }
470
471 /* This function is for Polaris11 only for now,
472 * Powerplay will only control the static per CU Power Gating.
473 * Dynamic per CU Power Gating will be done in gfx.
474 */
475 int smu7_enable_per_cu_power_gating(struct pp_hwmgr *hwmgr, bool enable)
476 {
477 struct cgs_system_info sys_info = {0};
478 uint32_t active_cus;
479 int result;
480
481 sys_info.size = sizeof(struct cgs_system_info);
482 sys_info.info_id = CGS_SYSTEM_INFO_GFX_CU_INFO;
483
484 result = cgs_query_system_info(hwmgr->device, &sys_info);
485
486 if (result)
487 return -EINVAL;
488
489 active_cus = sys_info.value;
490
491 if (enable)
492 return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
493 PPSMC_MSG_GFX_CU_PG_ENABLE, active_cus);
494 else
495 return smum_send_msg_to_smc(hwmgr->smumgr,
496 PPSMC_MSG_GFX_CU_PG_DISABLE);
497 }