1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "smu7_hwmgr.h"
25#include "smu7_clockpowergating.h"
26#include "smu7_common.h"
27
28static int smu7_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
29{
30 return smum_send_msg_to_smc(hwmgr, enable ?
31 PPSMC_MSG_UVDDPM_Enable :
32 PPSMC_MSG_UVDDPM_Disable);
33}
34
35static int smu7_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
36{
37 return smum_send_msg_to_smc(hwmgr, enable ?
38 PPSMC_MSG_VCEDPM_Enable :
39 PPSMC_MSG_VCEDPM_Disable);
40}
41
42static int smu7_enable_disable_samu_dpm(struct pp_hwmgr *hwmgr, bool enable)
43{
44 return smum_send_msg_to_smc(hwmgr, enable ?
45 PPSMC_MSG_SAMUDPM_Enable :
46 PPSMC_MSG_SAMUDPM_Disable);
47}
48
49static 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
56static 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
63static 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
70int 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,
74 PPSMC_MSG_UVDPowerOFF);
75 return 0;
76}
77
78static 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,
84 PPSMC_MSG_UVDPowerON, 1);
85 } else {
86 return smum_send_msg_to_smc_with_parameter(hwmgr,
87 PPSMC_MSG_UVDPowerON, 0);
88 }
89 }
90
91 return 0;
92}
93
94static 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,
98 PPSMC_MSG_VCEPowerOFF);
99 return 0;
100}
101
102static 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,
106 PPSMC_MSG_VCEPowerON);
107 return 0;
108}
109
110static 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,
115 PPSMC_MSG_SAMPowerOFF);
116 return 0;
117}
118
119static 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,
124 PPSMC_MSG_SAMPowerON);
125 return 0;
126}
127
128int 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
143void 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_PG_STATE_UNGATE);
166 smu7_update_uvd_dpm(hwmgr, false);
167 }
168
169}
170
171void smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
172{
173 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
174
175 data->vce_power_gated = bgate;
176
177 if (bgate) {
178 cgs_set_powergating_state(hwmgr->device,
179 AMD_IP_BLOCK_TYPE_VCE,
180 AMD_PG_STATE_GATE);
181 cgs_set_clockgating_state(hwmgr->device,
182 AMD_IP_BLOCK_TYPE_VCE,
183 AMD_CG_STATE_GATE);
184 smu7_update_vce_dpm(hwmgr, true);
185 smu7_powerdown_vce(hwmgr);
186 } else {
187 smu7_powerup_vce(hwmgr);
188 cgs_set_clockgating_state(hwmgr->device,
189 AMD_IP_BLOCK_TYPE_VCE,
190 AMD_CG_STATE_UNGATE);
191 cgs_set_powergating_state(hwmgr->device,
192 AMD_IP_BLOCK_TYPE_VCE,
193 AMD_PG_STATE_UNGATE);
194 smu7_update_vce_dpm(hwmgr, false);
195 }
196}
197
198int smu7_powergate_samu(struct pp_hwmgr *hwmgr, bool bgate)
199{
200 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
201
202 if (data->samu_power_gated == bgate)
203 return 0;
204
205 data->samu_power_gated = bgate;
206
207 if (bgate) {
208 smu7_update_samu_dpm(hwmgr, true);
209 smu7_powerdown_samu(hwmgr);
210 } else {
211 smu7_powerup_samu(hwmgr);
212 smu7_update_samu_dpm(hwmgr, false);
213 }
214
215 return 0;
216}
217
218int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
219 const uint32_t *msg_id)
220{
221 PPSMC_Msg msg;
222 uint32_t value;
223
224 if (!(hwmgr->feature_mask & PP_ENABLE_GFX_CG_THRU_SMU))
225 return 0;
226
227 switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
228 case PP_GROUP_GFX:
229 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
230 case PP_BLOCK_GFX_CG:
231 if (PP_STATE_SUPPORT_CG & *msg_id) {
232 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
233 PPSMC_MSG_EnableClockGatingFeature :
234 PPSMC_MSG_DisableClockGatingFeature;
235 value = CG_GFX_CGCG_MASK;
236
237 if (smum_send_msg_to_smc_with_parameter(
238 hwmgr, msg, value))
239 return -EINVAL;
240 }
241 if (PP_STATE_SUPPORT_LS & *msg_id) {
242 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
243 ? PPSMC_MSG_EnableClockGatingFeature
244 : PPSMC_MSG_DisableClockGatingFeature;
245 value = CG_GFX_CGLS_MASK;
246
247 if (smum_send_msg_to_smc_with_parameter(
248 hwmgr, msg, value))
249 return -EINVAL;
250 }
251 break;
252
253 case PP_BLOCK_GFX_3D:
254 if (PP_STATE_SUPPORT_CG & *msg_id) {
255 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
256 PPSMC_MSG_EnableClockGatingFeature :
257 PPSMC_MSG_DisableClockGatingFeature;
258 value = CG_GFX_3DCG_MASK;
259
260 if (smum_send_msg_to_smc_with_parameter(
261 hwmgr, msg, value))
262 return -EINVAL;
263 }
264
265 if (PP_STATE_SUPPORT_LS & *msg_id) {
266 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
267 PPSMC_MSG_EnableClockGatingFeature :
268 PPSMC_MSG_DisableClockGatingFeature;
269 value = CG_GFX_3DLS_MASK;
270
271 if (smum_send_msg_to_smc_with_parameter(
272 hwmgr, msg, value))
273 return -EINVAL;
274 }
275 break;
276
277 case PP_BLOCK_GFX_RLC:
278 if (PP_STATE_SUPPORT_LS & *msg_id) {
279 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
280 PPSMC_MSG_EnableClockGatingFeature :
281 PPSMC_MSG_DisableClockGatingFeature;
282 value = CG_GFX_RLC_LS_MASK;
283
284 if (smum_send_msg_to_smc_with_parameter(
285 hwmgr, msg, value))
286 return -EINVAL;
287 }
288 break;
289
290 case PP_BLOCK_GFX_CP:
291 if (PP_STATE_SUPPORT_LS & *msg_id) {
292 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
293 PPSMC_MSG_EnableClockGatingFeature :
294 PPSMC_MSG_DisableClockGatingFeature;
295 value = CG_GFX_CP_LS_MASK;
296
297 if (smum_send_msg_to_smc_with_parameter(
298 hwmgr, msg, value))
299 return -EINVAL;
300 }
301 break;
302
303 case PP_BLOCK_GFX_MG:
304 if (PP_STATE_SUPPORT_CG & *msg_id) {
305 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
306 PPSMC_MSG_EnableClockGatingFeature :
307 PPSMC_MSG_DisableClockGatingFeature;
308 value = (CG_CPF_MGCG_MASK | CG_RLC_MGCG_MASK |
309 CG_GFX_OTHERS_MGCG_MASK);
310
311 if (smum_send_msg_to_smc_with_parameter(
312 hwmgr, msg, value))
313 return -EINVAL;
314 }
315 break;
316
317 default:
318 return -EINVAL;
319 }
320 break;
321
322 case PP_GROUP_SYS:
323 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
324 case PP_BLOCK_SYS_BIF:
325 if (PP_STATE_SUPPORT_CG & *msg_id) {
326 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
327 PPSMC_MSG_EnableClockGatingFeature :
328 PPSMC_MSG_DisableClockGatingFeature;
329 value = CG_SYS_BIF_MGCG_MASK;
330
331 if (smum_send_msg_to_smc_with_parameter(
332 hwmgr, msg, value))
333 return -EINVAL;
334 }
335 if (PP_STATE_SUPPORT_LS & *msg_id) {
336 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
337 PPSMC_MSG_EnableClockGatingFeature :
338 PPSMC_MSG_DisableClockGatingFeature;
339 value = CG_SYS_BIF_MGLS_MASK;
340
341 if (smum_send_msg_to_smc_with_parameter(
342 hwmgr, msg, value))
343 return -EINVAL;
344 }
345 break;
346
347 case PP_BLOCK_SYS_MC:
348 if (PP_STATE_SUPPORT_CG & *msg_id) {
349 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
350 PPSMC_MSG_EnableClockGatingFeature :
351 PPSMC_MSG_DisableClockGatingFeature;
352 value = CG_SYS_MC_MGCG_MASK;
353
354 if (smum_send_msg_to_smc_with_parameter(
355 hwmgr, msg, value))
356 return -EINVAL;
357 }
358
359 if (PP_STATE_SUPPORT_LS & *msg_id) {
360 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
361 PPSMC_MSG_EnableClockGatingFeature :
362 PPSMC_MSG_DisableClockGatingFeature;
363 value = CG_SYS_MC_MGLS_MASK;
364
365 if (smum_send_msg_to_smc_with_parameter(
366 hwmgr, msg, value))
367 return -EINVAL;
368 }
369 break;
370
371 case PP_BLOCK_SYS_DRM:
372 if (PP_STATE_SUPPORT_CG & *msg_id) {
373 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
374 PPSMC_MSG_EnableClockGatingFeature :
375 PPSMC_MSG_DisableClockGatingFeature;
376 value = CG_SYS_DRM_MGCG_MASK;
377
378 if (smum_send_msg_to_smc_with_parameter(
379 hwmgr, msg, value))
380 return -EINVAL;
381 }
382 if (PP_STATE_SUPPORT_LS & *msg_id) {
383 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
384 PPSMC_MSG_EnableClockGatingFeature :
385 PPSMC_MSG_DisableClockGatingFeature;
386 value = CG_SYS_DRM_MGLS_MASK;
387
388 if (smum_send_msg_to_smc_with_parameter(
389 hwmgr, msg, value))
390 return -EINVAL;
391 }
392 break;
393
394 case PP_BLOCK_SYS_HDP:
395 if (PP_STATE_SUPPORT_CG & *msg_id) {
396 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
397 PPSMC_MSG_EnableClockGatingFeature :
398 PPSMC_MSG_DisableClockGatingFeature;
399 value = CG_SYS_HDP_MGCG_MASK;
400
401 if (smum_send_msg_to_smc_with_parameter(
402 hwmgr, msg, value))
403 return -EINVAL;
404 }
405
406 if (PP_STATE_SUPPORT_LS & *msg_id) {
407 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
408 PPSMC_MSG_EnableClockGatingFeature :
409 PPSMC_MSG_DisableClockGatingFeature;
410 value = CG_SYS_HDP_MGLS_MASK;
411
412 if (smum_send_msg_to_smc_with_parameter(
413 hwmgr, msg, value))
414 return -EINVAL;
415 }
416 break;
417
418 case PP_BLOCK_SYS_SDMA:
419 if (PP_STATE_SUPPORT_CG & *msg_id) {
420 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
421 PPSMC_MSG_EnableClockGatingFeature :
422 PPSMC_MSG_DisableClockGatingFeature;
423 value = CG_SYS_SDMA_MGCG_MASK;
424
425 if (smum_send_msg_to_smc_with_parameter(
426 hwmgr, msg, value))
427 return -EINVAL;
428 }
429
430 if (PP_STATE_SUPPORT_LS & *msg_id) {
431 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
432 PPSMC_MSG_EnableClockGatingFeature :
433 PPSMC_MSG_DisableClockGatingFeature;
434 value = CG_SYS_SDMA_MGLS_MASK;
435
436 if (smum_send_msg_to_smc_with_parameter(
437 hwmgr, msg, value))
438 return -EINVAL;
439 }
440 break;
441
442 case PP_BLOCK_SYS_ROM:
443 if (PP_STATE_SUPPORT_CG & *msg_id) {
444 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
445 PPSMC_MSG_EnableClockGatingFeature :
446 PPSMC_MSG_DisableClockGatingFeature;
447 value = CG_SYS_ROM_MASK;
448
449 if (smum_send_msg_to_smc_with_parameter(
450 hwmgr, msg, value))
451 return -EINVAL;
452 }
453 break;
454
455 default:
456 return -EINVAL;
457
458 }
459 break;
460
461 default:
462 return -EINVAL;
463
464 }
465
466 return 0;
467}
468
469
470
471
472
473int smu7_enable_per_cu_power_gating(struct pp_hwmgr *hwmgr, bool enable)
474{
475 struct amdgpu_device *adev = hwmgr->adev;
476
477 if (enable)
478 return smum_send_msg_to_smc_with_parameter(hwmgr,
479 PPSMC_MSG_GFX_CU_PG_ENABLE,
480 adev->gfx.cu_info.number);
481 else
482 return smum_send_msg_to_smc(hwmgr,
483 PPSMC_MSG_GFX_CU_PG_DISABLE);
484}
485