2 * Copyright 2016 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
24 #include "polaris10_clockpowergating.h"
26 int polaris10_phm_powerdown_uvd(struct pp_hwmgr
*hwmgr
)
28 if (phm_cf_want_uvd_power_gating(hwmgr
))
29 return smum_send_msg_to_smc(hwmgr
->smumgr
,
30 PPSMC_MSG_UVDPowerOFF
);
34 int polaris10_phm_powerup_uvd(struct pp_hwmgr
*hwmgr
)
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);
42 return smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
,
43 PPSMC_MSG_UVDPowerON
, 0);
50 int polaris10_phm_powerdown_vce(struct pp_hwmgr
*hwmgr
)
52 if (phm_cf_want_vce_power_gating(hwmgr
))
53 return smum_send_msg_to_smc(hwmgr
->smumgr
,
54 PPSMC_MSG_VCEPowerOFF
);
58 int polaris10_phm_powerup_vce(struct pp_hwmgr
*hwmgr
)
60 if (phm_cf_want_vce_power_gating(hwmgr
))
61 return smum_send_msg_to_smc(hwmgr
->smumgr
,
62 PPSMC_MSG_VCEPowerON
);
66 int polaris10_phm_powerdown_samu(struct pp_hwmgr
*hwmgr
)
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
);
75 int polaris10_phm_powerup_samu(struct pp_hwmgr
*hwmgr
)
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
);
84 int polaris10_phm_disable_clock_power_gating(struct pp_hwmgr
*hwmgr
)
86 struct polaris10_hwmgr
*data
= (struct polaris10_hwmgr
*)(hwmgr
->backend
);
88 data
->uvd_power_gated
= false;
89 data
->vce_power_gated
= false;
90 data
->samu_power_gated
= false;
92 polaris10_phm_powerup_uvd(hwmgr
);
93 polaris10_phm_powerup_vce(hwmgr
);
94 polaris10_phm_powerup_samu(hwmgr
);
99 int polaris10_phm_powergate_uvd(struct pp_hwmgr
*hwmgr
, bool bgate
)
101 struct polaris10_hwmgr
*data
= (struct polaris10_hwmgr
*)(hwmgr
->backend
);
103 if (data
->uvd_power_gated
== bgate
)
106 data
->uvd_power_gated
= bgate
;
109 cgs_set_clockgating_state(hwmgr
->device
,
110 AMD_IP_BLOCK_TYPE_UVD
,
112 polaris10_update_uvd_dpm(hwmgr
, true);
113 polaris10_phm_powerdown_uvd(hwmgr
);
115 polaris10_phm_powerup_uvd(hwmgr
);
116 polaris10_update_uvd_dpm(hwmgr
, false);
117 cgs_set_clockgating_state(hwmgr
->device
,
118 AMD_IP_BLOCK_TYPE_UVD
,
119 AMD_CG_STATE_UNGATE
);
125 int polaris10_phm_powergate_vce(struct pp_hwmgr
*hwmgr
, bool bgate
)
127 struct polaris10_hwmgr
*data
= (struct polaris10_hwmgr
*)(hwmgr
->backend
);
129 if (data
->vce_power_gated
== bgate
)
132 data
->vce_power_gated
= bgate
;
135 cgs_set_clockgating_state(hwmgr
->device
,
136 AMD_IP_BLOCK_TYPE_VCE
,
138 polaris10_update_vce_dpm(hwmgr
, true);
139 polaris10_phm_powerdown_vce(hwmgr
);
141 polaris10_phm_powerup_vce(hwmgr
);
142 polaris10_update_vce_dpm(hwmgr
, false);
143 cgs_set_clockgating_state(hwmgr
->device
,
144 AMD_IP_BLOCK_TYPE_VCE
,
145 AMD_CG_STATE_UNGATE
);
150 int polaris10_phm_powergate_samu(struct pp_hwmgr
*hwmgr
, bool bgate
)
152 struct polaris10_hwmgr
*data
= (struct polaris10_hwmgr
*)(hwmgr
->backend
);
154 if (data
->samu_power_gated
== bgate
)
157 data
->samu_power_gated
= bgate
;
160 polaris10_update_samu_dpm(hwmgr
, true);
161 polaris10_phm_powerdown_samu(hwmgr
);
163 polaris10_phm_powerup_samu(hwmgr
);
164 polaris10_update_samu_dpm(hwmgr
, false);
170 int polaris10_phm_update_clock_gatings(struct pp_hwmgr
*hwmgr
,
171 const uint32_t *msg_id
)
176 switch ((*msg_id
& PP_GROUP_MASK
) >> PP_GROUP_SHIFT
) {
178 switch ((*msg_id
& PP_BLOCK_MASK
) >> PP_BLOCK_SHIFT
) {
179 case PP_BLOCK_GFX_CG
:
180 if (PP_STATE_SUPPORT_CG
& *msg_id
) {
181 msg
= ((*msg_id
& PP_STATE_MASK
) & PP_STATE_CG
) ?
182 PPSMC_MSG_EnableClockGatingFeature
:
183 PPSMC_MSG_DisableClockGatingFeature
;
184 value
= CG_GFX_CGCG_MASK
;
186 if (smum_send_msg_to_smc_with_parameter(
187 hwmgr
->smumgr
, msg
, value
))
190 if (PP_STATE_SUPPORT_LS
& *msg_id
) {
191 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_LS
192 ? PPSMC_MSG_EnableClockGatingFeature
193 : PPSMC_MSG_DisableClockGatingFeature
;
194 value
= CG_GFX_CGLS_MASK
;
196 if (smum_send_msg_to_smc_with_parameter(
197 hwmgr
->smumgr
, msg
, value
))
202 case PP_BLOCK_GFX_3D
:
203 if (PP_STATE_SUPPORT_CG
& *msg_id
) {
204 msg
= ((*msg_id
& PP_STATE_MASK
) & PP_STATE_CG
) ?
205 PPSMC_MSG_EnableClockGatingFeature
:
206 PPSMC_MSG_DisableClockGatingFeature
;
207 value
= CG_GFX_3DCG_MASK
;
209 if (smum_send_msg_to_smc_with_parameter(
210 hwmgr
->smumgr
, msg
, value
))
214 if (PP_STATE_SUPPORT_LS
& *msg_id
) {
215 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_LS
?
216 PPSMC_MSG_EnableClockGatingFeature
:
217 PPSMC_MSG_DisableClockGatingFeature
;
218 value
= CG_GFX_3DLS_MASK
;
220 if (smum_send_msg_to_smc_with_parameter(
221 hwmgr
->smumgr
, msg
, value
))
226 case PP_BLOCK_GFX_RLC
:
227 if (PP_STATE_SUPPORT_LS
& *msg_id
) {
228 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_LS
?
229 PPSMC_MSG_EnableClockGatingFeature
:
230 PPSMC_MSG_DisableClockGatingFeature
;
231 value
= CG_GFX_RLC_LS_MASK
;
233 if (smum_send_msg_to_smc_with_parameter(
234 hwmgr
->smumgr
, msg
, value
))
239 case PP_BLOCK_GFX_CP
:
240 if (PP_STATE_SUPPORT_LS
& *msg_id
) {
241 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_LS
?
242 PPSMC_MSG_EnableClockGatingFeature
:
243 PPSMC_MSG_DisableClockGatingFeature
;
244 value
= CG_GFX_CP_LS_MASK
;
246 if (smum_send_msg_to_smc_with_parameter(
247 hwmgr
->smumgr
, msg
, value
))
252 case PP_BLOCK_GFX_MG
:
253 if (PP_STATE_SUPPORT_CG
& *msg_id
) {
254 msg
= ((*msg_id
& PP_STATE_MASK
) & PP_STATE_CG
) ?
255 PPSMC_MSG_EnableClockGatingFeature
:
256 PPSMC_MSG_DisableClockGatingFeature
;
257 value
= (CG_CPF_MGCG_MASK
| CG_RLC_MGCG_MASK
|
258 CG_GFX_OTHERS_MGCG_MASK
);
260 if (smum_send_msg_to_smc_with_parameter(
261 hwmgr
->smumgr
, msg
, value
))
272 switch ((*msg_id
& PP_BLOCK_MASK
) >> PP_BLOCK_SHIFT
) {
273 case PP_BLOCK_SYS_BIF
:
274 if (PP_STATE_SUPPORT_CG
& *msg_id
) {
275 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_CG
?
276 PPSMC_MSG_EnableClockGatingFeature
:
277 PPSMC_MSG_DisableClockGatingFeature
;
278 value
= CG_SYS_BIF_MGCG_MASK
;
280 if (smum_send_msg_to_smc_with_parameter(
281 hwmgr
->smumgr
, msg
, value
))
284 if (PP_STATE_SUPPORT_LS
& *msg_id
) {
285 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_LS
?
286 PPSMC_MSG_EnableClockGatingFeature
:
287 PPSMC_MSG_DisableClockGatingFeature
;
288 value
= CG_SYS_BIF_MGLS_MASK
;
290 if (smum_send_msg_to_smc_with_parameter(
291 hwmgr
->smumgr
, msg
, value
))
296 case PP_BLOCK_SYS_MC
:
297 if (PP_STATE_SUPPORT_CG
& *msg_id
) {
298 msg
= ((*msg_id
& PP_STATE_MASK
) & PP_STATE_CG
) ?
299 PPSMC_MSG_EnableClockGatingFeature
:
300 PPSMC_MSG_DisableClockGatingFeature
;
301 value
= CG_SYS_MC_MGCG_MASK
;
303 if (smum_send_msg_to_smc_with_parameter(
304 hwmgr
->smumgr
, msg
, value
))
308 if (PP_STATE_SUPPORT_LS
& *msg_id
) {
309 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_LS
?
310 PPSMC_MSG_EnableClockGatingFeature
:
311 PPSMC_MSG_DisableClockGatingFeature
;
312 value
= CG_SYS_MC_MGLS_MASK
;
314 if (smum_send_msg_to_smc_with_parameter(
315 hwmgr
->smumgr
, msg
, value
))
320 case PP_BLOCK_SYS_DRM
:
321 if (PP_STATE_SUPPORT_CG
& *msg_id
) {
322 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_CG
?
323 PPSMC_MSG_EnableClockGatingFeature
:
324 PPSMC_MSG_DisableClockGatingFeature
;
325 value
= CG_SYS_DRM_MGCG_MASK
;
327 if (smum_send_msg_to_smc_with_parameter(
328 hwmgr
->smumgr
, msg
, value
))
331 if (PP_STATE_SUPPORT_LS
& *msg_id
) {
332 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_LS
?
333 PPSMC_MSG_EnableClockGatingFeature
:
334 PPSMC_MSG_DisableClockGatingFeature
;
335 value
= CG_SYS_DRM_MGLS_MASK
;
337 if (smum_send_msg_to_smc_with_parameter(
338 hwmgr
->smumgr
, msg
, value
))
343 case PP_BLOCK_SYS_HDP
:
344 if (PP_STATE_SUPPORT_CG
& *msg_id
) {
345 msg
= ((*msg_id
& PP_STATE_MASK
) & PP_STATE_CG
) ?
346 PPSMC_MSG_EnableClockGatingFeature
:
347 PPSMC_MSG_DisableClockGatingFeature
;
348 value
= CG_SYS_HDP_MGCG_MASK
;
350 if (smum_send_msg_to_smc_with_parameter(
351 hwmgr
->smumgr
, msg
, value
))
355 if (PP_STATE_SUPPORT_LS
& *msg_id
) {
356 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_LS
?
357 PPSMC_MSG_EnableClockGatingFeature
:
358 PPSMC_MSG_DisableClockGatingFeature
;
359 value
= CG_SYS_HDP_MGLS_MASK
;
361 if (smum_send_msg_to_smc_with_parameter(
362 hwmgr
->smumgr
, msg
, value
))
367 case PP_BLOCK_SYS_SDMA
:
368 if (PP_STATE_SUPPORT_CG
& *msg_id
) {
369 msg
= ((*msg_id
& PP_STATE_MASK
) & PP_STATE_CG
) ?
370 PPSMC_MSG_EnableClockGatingFeature
:
371 PPSMC_MSG_DisableClockGatingFeature
;
372 value
= CG_SYS_SDMA_MGCG_MASK
;
374 if (smum_send_msg_to_smc_with_parameter(
375 hwmgr
->smumgr
, msg
, value
))
379 if (PP_STATE_SUPPORT_LS
& *msg_id
) {
380 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_LS
?
381 PPSMC_MSG_EnableClockGatingFeature
:
382 PPSMC_MSG_DisableClockGatingFeature
;
383 value
= CG_SYS_SDMA_MGLS_MASK
;
385 if (smum_send_msg_to_smc_with_parameter(
386 hwmgr
->smumgr
, msg
, value
))
391 case PP_BLOCK_SYS_ROM
:
392 if (PP_STATE_SUPPORT_CG
& *msg_id
) {
393 msg
= ((*msg_id
& PP_STATE_MASK
) & PP_STATE_CG
) ?
394 PPSMC_MSG_EnableClockGatingFeature
:
395 PPSMC_MSG_DisableClockGatingFeature
;
396 value
= CG_SYS_ROM_MASK
;
398 if (smum_send_msg_to_smc_with_parameter(
399 hwmgr
->smumgr
, msg
, value
))
418 /* This function is for Polaris11 only for now,
419 * Powerplay will only control the static per CU Power Gating.
420 * Dynamic per CU Power Gating will be done in gfx.
422 int polaris10_phm_enable_per_cu_power_gating(struct pp_hwmgr
*hwmgr
, bool enable
)
424 struct cgs_system_info sys_info
= {0};
428 sys_info
.size
= sizeof(struct cgs_system_info
);
429 sys_info
.info_id
= CGS_SYSTEM_INFO_GFX_CU_INFO
;
431 result
= cgs_query_system_info(hwmgr
->device
, &sys_info
);
436 active_cus
= sys_info
.value
;
439 return smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
,
440 PPSMC_MSG_GFX_CU_PG_ENABLE
, active_cus
);
442 return smum_send_msg_to_smc(hwmgr
->smumgr
,
443 PPSMC_MSG_GFX_CU_PG_DISABLE
);