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 static 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 static 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 static 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 static 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 static 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_powergating_state(hwmgr->device,
151 AMD_IP_BLOCK_TYPE_UVD,
153 cgs_set_clockgating_state(hwmgr->device,
154 AMD_IP_BLOCK_TYPE_UVD,
156 smu7_update_uvd_dpm(hwmgr, true);
157 smu7_powerdown_uvd(hwmgr);
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);
172 int smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
174 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
176 if (data->vce_power_gated == bgate)
179 data->vce_power_gated = bgate;
182 cgs_set_clockgating_state(hwmgr->device,
183 AMD_IP_BLOCK_TYPE_VCE,
185 smu7_update_vce_dpm(hwmgr, true);
186 smu7_powerdown_vce(hwmgr);
188 smu7_powerup_vce(hwmgr);
189 smu7_update_vce_dpm(hwmgr, false);
190 cgs_set_clockgating_state(hwmgr->device,
191 AMD_IP_BLOCK_TYPE_VCE,
192 AMD_CG_STATE_UNGATE);
197 int smu7_powergate_samu(struct pp_hwmgr *hwmgr, bool bgate)
199 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
201 if (data->samu_power_gated == bgate)
204 data->samu_power_gated = bgate;
207 smu7_update_samu_dpm(hwmgr, true);
208 smu7_powerdown_samu(hwmgr);
210 smu7_powerup_samu(hwmgr);
211 smu7_update_samu_dpm(hwmgr, false);
217 int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
218 const uint32_t *msg_id)
223 if (!(hwmgr->feature_mask & PP_ENABLE_GFX_CG_THRU_SMU))
226 switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
228 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
229 case PP_BLOCK_GFX_CG:
230 if (PP_STATE_SUPPORT_CG & *msg_id) {
231 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
232 PPSMC_MSG_EnableClockGatingFeature :
233 PPSMC_MSG_DisableClockGatingFeature;
234 value = CG_GFX_CGCG_MASK;
236 if (smum_send_msg_to_smc_with_parameter(
237 hwmgr->smumgr, msg, value))
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_CGLS_MASK;
246 if (smum_send_msg_to_smc_with_parameter(
247 hwmgr->smumgr, msg, value))
252 case PP_BLOCK_GFX_3D:
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_GFX_3DCG_MASK;
259 if (smum_send_msg_to_smc_with_parameter(
260 hwmgr->smumgr, msg, value))
264 if (PP_STATE_SUPPORT_LS & *msg_id) {
265 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
266 PPSMC_MSG_EnableClockGatingFeature :
267 PPSMC_MSG_DisableClockGatingFeature;
268 value = CG_GFX_3DLS_MASK;
270 if (smum_send_msg_to_smc_with_parameter(
271 hwmgr->smumgr, msg, value))
276 case PP_BLOCK_GFX_RLC:
277 if (PP_STATE_SUPPORT_LS & *msg_id) {
278 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
279 PPSMC_MSG_EnableClockGatingFeature :
280 PPSMC_MSG_DisableClockGatingFeature;
281 value = CG_GFX_RLC_LS_MASK;
283 if (smum_send_msg_to_smc_with_parameter(
284 hwmgr->smumgr, msg, value))
289 case PP_BLOCK_GFX_CP:
290 if (PP_STATE_SUPPORT_LS & *msg_id) {
291 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
292 PPSMC_MSG_EnableClockGatingFeature :
293 PPSMC_MSG_DisableClockGatingFeature;
294 value = CG_GFX_CP_LS_MASK;
296 if (smum_send_msg_to_smc_with_parameter(
297 hwmgr->smumgr, msg, value))
302 case PP_BLOCK_GFX_MG:
303 if (PP_STATE_SUPPORT_CG & *msg_id) {
304 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
305 PPSMC_MSG_EnableClockGatingFeature :
306 PPSMC_MSG_DisableClockGatingFeature;
307 value = (CG_CPF_MGCG_MASK | CG_RLC_MGCG_MASK |
308 CG_GFX_OTHERS_MGCG_MASK);
310 if (smum_send_msg_to_smc_with_parameter(
311 hwmgr->smumgr, msg, value))
322 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
323 case PP_BLOCK_SYS_BIF:
324 if (PP_STATE_SUPPORT_CG & *msg_id) {
325 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
326 PPSMC_MSG_EnableClockGatingFeature :
327 PPSMC_MSG_DisableClockGatingFeature;
328 value = CG_SYS_BIF_MGCG_MASK;
330 if (smum_send_msg_to_smc_with_parameter(
331 hwmgr->smumgr, msg, value))
334 if (PP_STATE_SUPPORT_LS & *msg_id) {
335 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
336 PPSMC_MSG_EnableClockGatingFeature :
337 PPSMC_MSG_DisableClockGatingFeature;
338 value = CG_SYS_BIF_MGLS_MASK;
340 if (smum_send_msg_to_smc_with_parameter(
341 hwmgr->smumgr, msg, value))
346 case PP_BLOCK_SYS_MC:
347 if (PP_STATE_SUPPORT_CG & *msg_id) {
348 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
349 PPSMC_MSG_EnableClockGatingFeature :
350 PPSMC_MSG_DisableClockGatingFeature;
351 value = CG_SYS_MC_MGCG_MASK;
353 if (smum_send_msg_to_smc_with_parameter(
354 hwmgr->smumgr, msg, value))
358 if (PP_STATE_SUPPORT_LS & *msg_id) {
359 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
360 PPSMC_MSG_EnableClockGatingFeature :
361 PPSMC_MSG_DisableClockGatingFeature;
362 value = CG_SYS_MC_MGLS_MASK;
364 if (smum_send_msg_to_smc_with_parameter(
365 hwmgr->smumgr, msg, value))
370 case PP_BLOCK_SYS_DRM:
371 if (PP_STATE_SUPPORT_CG & *msg_id) {
372 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
373 PPSMC_MSG_EnableClockGatingFeature :
374 PPSMC_MSG_DisableClockGatingFeature;
375 value = CG_SYS_DRM_MGCG_MASK;
377 if (smum_send_msg_to_smc_with_parameter(
378 hwmgr->smumgr, msg, value))
381 if (PP_STATE_SUPPORT_LS & *msg_id) {
382 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
383 PPSMC_MSG_EnableClockGatingFeature :
384 PPSMC_MSG_DisableClockGatingFeature;
385 value = CG_SYS_DRM_MGLS_MASK;
387 if (smum_send_msg_to_smc_with_parameter(
388 hwmgr->smumgr, msg, value))
393 case PP_BLOCK_SYS_HDP:
394 if (PP_STATE_SUPPORT_CG & *msg_id) {
395 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
396 PPSMC_MSG_EnableClockGatingFeature :
397 PPSMC_MSG_DisableClockGatingFeature;
398 value = CG_SYS_HDP_MGCG_MASK;
400 if (smum_send_msg_to_smc_with_parameter(
401 hwmgr->smumgr, msg, value))
405 if (PP_STATE_SUPPORT_LS & *msg_id) {
406 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
407 PPSMC_MSG_EnableClockGatingFeature :
408 PPSMC_MSG_DisableClockGatingFeature;
409 value = CG_SYS_HDP_MGLS_MASK;
411 if (smum_send_msg_to_smc_with_parameter(
412 hwmgr->smumgr, msg, value))
417 case PP_BLOCK_SYS_SDMA:
418 if (PP_STATE_SUPPORT_CG & *msg_id) {
419 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
420 PPSMC_MSG_EnableClockGatingFeature :
421 PPSMC_MSG_DisableClockGatingFeature;
422 value = CG_SYS_SDMA_MGCG_MASK;
424 if (smum_send_msg_to_smc_with_parameter(
425 hwmgr->smumgr, msg, value))
429 if (PP_STATE_SUPPORT_LS & *msg_id) {
430 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
431 PPSMC_MSG_EnableClockGatingFeature :
432 PPSMC_MSG_DisableClockGatingFeature;
433 value = CG_SYS_SDMA_MGLS_MASK;
435 if (smum_send_msg_to_smc_with_parameter(
436 hwmgr->smumgr, msg, value))
441 case PP_BLOCK_SYS_ROM:
442 if (PP_STATE_SUPPORT_CG & *msg_id) {
443 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
444 PPSMC_MSG_EnableClockGatingFeature :
445 PPSMC_MSG_DisableClockGatingFeature;
446 value = CG_SYS_ROM_MASK;
448 if (smum_send_msg_to_smc_with_parameter(
449 hwmgr->smumgr, msg, value))
468 /* This function is for Polaris11 only for now,
469 * Powerplay will only control the static per CU Power Gating.
470 * Dynamic per CU Power Gating will be done in gfx.
472 int smu7_enable_per_cu_power_gating(struct pp_hwmgr *hwmgr, bool enable)
474 struct cgs_system_info sys_info = {0};
478 sys_info.size = sizeof(struct cgs_system_info);
479 sys_info.info_id = CGS_SYSTEM_INFO_GFX_CU_INFO;
481 result = cgs_query_system_info(hwmgr->device, &sys_info);
486 active_cus = sys_info.value;
489 return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
490 PPSMC_MSG_GFX_CU_PG_ENABLE, active_cus);
492 return smum_send_msg_to_smc(hwmgr->smumgr,
493 PPSMC_MSG_GFX_CU_PG_DISABLE);