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 "smu7_hwmgr.h"
25 #include "smu7_clockpowergating.h"
26 #include "smu7_common.h"
28 static int smu7_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
30 return smum_send_msg_to_smc(hwmgr->smumgr, enable ?
31 PPSMC_MSG_UVDDPM_Enable :
32 PPSMC_MSG_UVDDPM_Disable);
35 static int smu7_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
37 return smum_send_msg_to_smc(hwmgr->smumgr, enable ?
38 PPSMC_MSG_VCEDPM_Enable :
39 PPSMC_MSG_VCEDPM_Disable);
42 static int smu7_enable_disable_samu_dpm(struct pp_hwmgr *hwmgr, bool enable)
44 return smum_send_msg_to_smc(hwmgr->smumgr, enable ?
45 PPSMC_MSG_SAMUDPM_Enable :
46 PPSMC_MSG_SAMUDPM_Disable);
49 static int smu7_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
52 smum_update_smc_table(hwmgr, SMU_UVD_TABLE);
53 return smu7_enable_disable_uvd_dpm(hwmgr, !bgate);
56 static int smu7_update_vce_dpm(struct pp_hwmgr *hwmgr, bool bgate)
59 smum_update_smc_table(hwmgr, SMU_VCE_TABLE);
60 return smu7_enable_disable_vce_dpm(hwmgr, !bgate);
63 static int smu7_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate)
66 smum_update_smc_table(hwmgr, SMU_SAMU_TABLE);
67 return smu7_enable_disable_samu_dpm(hwmgr, !bgate);
70 int smu7_powerdown_uvd(struct pp_hwmgr *hwmgr)
72 if (phm_cf_want_uvd_power_gating(hwmgr))
73 return smum_send_msg_to_smc(hwmgr->smumgr,
74 PPSMC_MSG_UVDPowerOFF);
78 int smu7_powerup_uvd(struct pp_hwmgr *hwmgr)
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);
86 return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
87 PPSMC_MSG_UVDPowerON, 0);
94 int smu7_powerdown_vce(struct pp_hwmgr *hwmgr)
96 if (phm_cf_want_vce_power_gating(hwmgr))
97 return smum_send_msg_to_smc(hwmgr->smumgr,
98 PPSMC_MSG_VCEPowerOFF);
102 int smu7_powerup_vce(struct pp_hwmgr *hwmgr)
104 if (phm_cf_want_vce_power_gating(hwmgr))
105 return smum_send_msg_to_smc(hwmgr->smumgr,
106 PPSMC_MSG_VCEPowerON);
110 int smu7_powerdown_samu(struct pp_hwmgr *hwmgr)
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);
119 int smu7_powerup_samu(struct pp_hwmgr *hwmgr)
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);
128 int smu7_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
130 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
132 data->uvd_power_gated = false;
133 data->vce_power_gated = false;
134 data->samu_power_gated = false;
136 smu7_powerup_uvd(hwmgr);
137 smu7_powerup_vce(hwmgr);
138 smu7_powerup_samu(hwmgr);
143 int smu7_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
145 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
147 data->uvd_power_gated = bgate;
150 cgs_set_clockgating_state(hwmgr->device,
151 AMD_IP_BLOCK_TYPE_UVD,
153 smu7_update_uvd_dpm(hwmgr, true);
154 smu7_powerdown_uvd(hwmgr);
156 smu7_powerup_uvd(hwmgr);
157 smu7_update_uvd_dpm(hwmgr, false);
158 cgs_set_clockgating_state(hwmgr->device,
159 AMD_IP_BLOCK_TYPE_UVD,
160 AMD_CG_STATE_UNGATE);
166 int smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
168 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
170 if (data->vce_power_gated == bgate)
173 data->vce_power_gated = bgate;
176 cgs_set_clockgating_state(hwmgr->device,
177 AMD_IP_BLOCK_TYPE_VCE,
179 smu7_update_vce_dpm(hwmgr, true);
180 smu7_powerdown_vce(hwmgr);
182 smu7_powerup_vce(hwmgr);
183 smu7_update_vce_dpm(hwmgr, false);
184 cgs_set_clockgating_state(hwmgr->device,
185 AMD_IP_BLOCK_TYPE_VCE,
186 AMD_CG_STATE_UNGATE);
191 int smu7_powergate_samu(struct pp_hwmgr *hwmgr, bool bgate)
193 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
195 if (data->samu_power_gated == bgate)
198 data->samu_power_gated = bgate;
201 smu7_update_samu_dpm(hwmgr, true);
202 smu7_powerdown_samu(hwmgr);
204 smu7_powerup_samu(hwmgr);
205 smu7_update_samu_dpm(hwmgr, false);
211 int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
212 const uint32_t *msg_id)
217 if (!(hwmgr->feature_mask & PP_ENABLE_GFX_CG_THRU_SMU))
220 switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
222 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
223 case PP_BLOCK_GFX_CG:
224 if (PP_STATE_SUPPORT_CG & *msg_id) {
225 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
226 PPSMC_MSG_EnableClockGatingFeature :
227 PPSMC_MSG_DisableClockGatingFeature;
228 value = CG_GFX_CGCG_MASK;
230 if (smum_send_msg_to_smc_with_parameter(
231 hwmgr->smumgr, msg, value))
234 if (PP_STATE_SUPPORT_LS & *msg_id) {
235 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
236 ? PPSMC_MSG_EnableClockGatingFeature
237 : PPSMC_MSG_DisableClockGatingFeature;
238 value = CG_GFX_CGLS_MASK;
240 if (smum_send_msg_to_smc_with_parameter(
241 hwmgr->smumgr, msg, value))
246 case PP_BLOCK_GFX_3D:
247 if (PP_STATE_SUPPORT_CG & *msg_id) {
248 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
249 PPSMC_MSG_EnableClockGatingFeature :
250 PPSMC_MSG_DisableClockGatingFeature;
251 value = CG_GFX_3DCG_MASK;
253 if (smum_send_msg_to_smc_with_parameter(
254 hwmgr->smumgr, msg, value))
258 if (PP_STATE_SUPPORT_LS & *msg_id) {
259 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
260 PPSMC_MSG_EnableClockGatingFeature :
261 PPSMC_MSG_DisableClockGatingFeature;
262 value = CG_GFX_3DLS_MASK;
264 if (smum_send_msg_to_smc_with_parameter(
265 hwmgr->smumgr, msg, value))
270 case PP_BLOCK_GFX_RLC:
271 if (PP_STATE_SUPPORT_LS & *msg_id) {
272 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
273 PPSMC_MSG_EnableClockGatingFeature :
274 PPSMC_MSG_DisableClockGatingFeature;
275 value = CG_GFX_RLC_LS_MASK;
277 if (smum_send_msg_to_smc_with_parameter(
278 hwmgr->smumgr, msg, value))
283 case PP_BLOCK_GFX_CP:
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_GFX_CP_LS_MASK;
290 if (smum_send_msg_to_smc_with_parameter(
291 hwmgr->smumgr, msg, value))
296 case PP_BLOCK_GFX_MG:
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_CPF_MGCG_MASK | CG_RLC_MGCG_MASK |
302 CG_GFX_OTHERS_MGCG_MASK);
304 if (smum_send_msg_to_smc_with_parameter(
305 hwmgr->smumgr, msg, value))
316 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
317 case PP_BLOCK_SYS_BIF:
318 if (PP_STATE_SUPPORT_CG & *msg_id) {
319 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
320 PPSMC_MSG_EnableClockGatingFeature :
321 PPSMC_MSG_DisableClockGatingFeature;
322 value = CG_SYS_BIF_MGCG_MASK;
324 if (smum_send_msg_to_smc_with_parameter(
325 hwmgr->smumgr, msg, value))
328 if (PP_STATE_SUPPORT_LS & *msg_id) {
329 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
330 PPSMC_MSG_EnableClockGatingFeature :
331 PPSMC_MSG_DisableClockGatingFeature;
332 value = CG_SYS_BIF_MGLS_MASK;
334 if (smum_send_msg_to_smc_with_parameter(
335 hwmgr->smumgr, msg, value))
340 case PP_BLOCK_SYS_MC:
341 if (PP_STATE_SUPPORT_CG & *msg_id) {
342 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
343 PPSMC_MSG_EnableClockGatingFeature :
344 PPSMC_MSG_DisableClockGatingFeature;
345 value = CG_SYS_MC_MGCG_MASK;
347 if (smum_send_msg_to_smc_with_parameter(
348 hwmgr->smumgr, msg, value))
352 if (PP_STATE_SUPPORT_LS & *msg_id) {
353 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
354 PPSMC_MSG_EnableClockGatingFeature :
355 PPSMC_MSG_DisableClockGatingFeature;
356 value = CG_SYS_MC_MGLS_MASK;
358 if (smum_send_msg_to_smc_with_parameter(
359 hwmgr->smumgr, msg, value))
364 case PP_BLOCK_SYS_DRM:
365 if (PP_STATE_SUPPORT_CG & *msg_id) {
366 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
367 PPSMC_MSG_EnableClockGatingFeature :
368 PPSMC_MSG_DisableClockGatingFeature;
369 value = CG_SYS_DRM_MGCG_MASK;
371 if (smum_send_msg_to_smc_with_parameter(
372 hwmgr->smumgr, msg, value))
375 if (PP_STATE_SUPPORT_LS & *msg_id) {
376 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
377 PPSMC_MSG_EnableClockGatingFeature :
378 PPSMC_MSG_DisableClockGatingFeature;
379 value = CG_SYS_DRM_MGLS_MASK;
381 if (smum_send_msg_to_smc_with_parameter(
382 hwmgr->smumgr, msg, value))
387 case PP_BLOCK_SYS_HDP:
388 if (PP_STATE_SUPPORT_CG & *msg_id) {
389 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
390 PPSMC_MSG_EnableClockGatingFeature :
391 PPSMC_MSG_DisableClockGatingFeature;
392 value = CG_SYS_HDP_MGCG_MASK;
394 if (smum_send_msg_to_smc_with_parameter(
395 hwmgr->smumgr, msg, value))
399 if (PP_STATE_SUPPORT_LS & *msg_id) {
400 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
401 PPSMC_MSG_EnableClockGatingFeature :
402 PPSMC_MSG_DisableClockGatingFeature;
403 value = CG_SYS_HDP_MGLS_MASK;
405 if (smum_send_msg_to_smc_with_parameter(
406 hwmgr->smumgr, msg, value))
411 case PP_BLOCK_SYS_SDMA:
412 if (PP_STATE_SUPPORT_CG & *msg_id) {
413 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
414 PPSMC_MSG_EnableClockGatingFeature :
415 PPSMC_MSG_DisableClockGatingFeature;
416 value = CG_SYS_SDMA_MGCG_MASK;
418 if (smum_send_msg_to_smc_with_parameter(
419 hwmgr->smumgr, msg, value))
423 if (PP_STATE_SUPPORT_LS & *msg_id) {
424 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
425 PPSMC_MSG_EnableClockGatingFeature :
426 PPSMC_MSG_DisableClockGatingFeature;
427 value = CG_SYS_SDMA_MGLS_MASK;
429 if (smum_send_msg_to_smc_with_parameter(
430 hwmgr->smumgr, msg, value))
435 case PP_BLOCK_SYS_ROM:
436 if (PP_STATE_SUPPORT_CG & *msg_id) {
437 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
438 PPSMC_MSG_EnableClockGatingFeature :
439 PPSMC_MSG_DisableClockGatingFeature;
440 value = CG_SYS_ROM_MASK;
442 if (smum_send_msg_to_smc_with_parameter(
443 hwmgr->smumgr, msg, value))
462 /* This function is for Polaris11 only for now,
463 * Powerplay will only control the static per CU Power Gating.
464 * Dynamic per CU Power Gating will be done in gfx.
466 int smu7_enable_per_cu_power_gating(struct pp_hwmgr *hwmgr, bool enable)
468 struct cgs_system_info sys_info = {0};
472 sys_info.size = sizeof(struct cgs_system_info);
473 sys_info.info_id = CGS_SYSTEM_INFO_GFX_CU_INFO;
475 result = cgs_query_system_info(hwmgr->device, &sys_info);
480 active_cus = sys_info.value;
483 return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
484 PPSMC_MSG_GFX_CU_PG_ENABLE, active_cus);
486 return smum_send_msg_to_smc(hwmgr->smumgr,
487 PPSMC_MSG_GFX_CU_PG_DISABLE);