2 * Copyright 2015 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.
25 #include "tonga_clockpowergating.h"
26 #include "tonga_ppsmc.h"
27 #include "tonga_hwmgr.h"
29 int tonga_phm_powerdown_uvd(struct pp_hwmgr
*hwmgr
)
31 if (phm_cf_want_uvd_power_gating(hwmgr
))
32 return smum_send_msg_to_smc(hwmgr
->smumgr
,
33 PPSMC_MSG_UVDPowerOFF
);
37 int tonga_phm_powerup_uvd(struct pp_hwmgr
*hwmgr
)
39 if (phm_cf_want_uvd_power_gating(hwmgr
)) {
40 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
41 PHM_PlatformCaps_UVDDynamicPowerGating
)) {
42 return smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
,
43 PPSMC_MSG_UVDPowerON
, 1);
45 return smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
,
46 PPSMC_MSG_UVDPowerON
, 0);
53 int tonga_phm_powerdown_vce(struct pp_hwmgr
*hwmgr
)
55 if (phm_cf_want_vce_power_gating(hwmgr
))
56 return smum_send_msg_to_smc(hwmgr
->smumgr
,
57 PPSMC_MSG_VCEPowerOFF
);
61 int tonga_phm_powerup_vce(struct pp_hwmgr
*hwmgr
)
63 if (phm_cf_want_vce_power_gating(hwmgr
))
64 return smum_send_msg_to_smc(hwmgr
->smumgr
,
65 PPSMC_MSG_VCEPowerON
);
69 int tonga_phm_set_asic_block_gating(struct pp_hwmgr
*hwmgr
, enum PHM_AsicBlock block
, enum PHM_ClockGateSetting gating
)
74 case PHM_AsicBlock_UVD_MVC
:
75 case PHM_AsicBlock_UVD
:
76 case PHM_AsicBlock_UVD_HD
:
77 case PHM_AsicBlock_UVD_SD
:
78 if (gating
== PHM_ClockGateSetting_StaticOff
)
79 ret
= tonga_phm_powerdown_uvd(hwmgr
);
81 ret
= tonga_phm_powerup_uvd(hwmgr
);
83 case PHM_AsicBlock_GFX
:
91 int tonga_phm_disable_clock_power_gating(struct pp_hwmgr
*hwmgr
)
93 struct tonga_hwmgr
*data
= (struct tonga_hwmgr
*)(hwmgr
->backend
);
95 data
->uvd_power_gated
= false;
96 data
->vce_power_gated
= false;
98 tonga_phm_powerup_uvd(hwmgr
);
99 tonga_phm_powerup_vce(hwmgr
);
104 int tonga_phm_powergate_uvd(struct pp_hwmgr
*hwmgr
, bool bgate
)
106 struct tonga_hwmgr
*data
= (struct tonga_hwmgr
*)(hwmgr
->backend
);
108 if (data
->uvd_power_gated
== bgate
)
111 data
->uvd_power_gated
= bgate
;
114 cgs_set_clockgating_state(hwmgr
->device
,
115 AMD_IP_BLOCK_TYPE_UVD
,
116 AMD_CG_STATE_UNGATE
);
117 cgs_set_powergating_state(hwmgr
->device
,
118 AMD_IP_BLOCK_TYPE_UVD
,
120 tonga_update_uvd_dpm(hwmgr
, true);
121 tonga_phm_powerdown_uvd(hwmgr
);
123 tonga_phm_powerup_uvd(hwmgr
);
124 cgs_set_powergating_state(hwmgr
->device
,
125 AMD_IP_BLOCK_TYPE_UVD
,
126 AMD_PG_STATE_UNGATE
);
127 cgs_set_clockgating_state(hwmgr
->device
,
128 AMD_IP_BLOCK_TYPE_UVD
,
131 tonga_update_uvd_dpm(hwmgr
, false);
137 int tonga_phm_powergate_vce(struct pp_hwmgr
*hwmgr
, bool bgate
)
139 struct tonga_hwmgr
*data
= (struct tonga_hwmgr
*)(hwmgr
->backend
);
140 struct phm_set_power_state_input states
;
141 const struct pp_power_state
*pcurrent
;
142 struct pp_power_state
*requested
;
144 pcurrent
= hwmgr
->current_ps
;
145 requested
= hwmgr
->request_ps
;
147 states
.pcurrent_state
= &(pcurrent
->hardware
);
148 states
.pnew_state
= &(requested
->hardware
);
150 if (phm_cf_want_vce_power_gating(hwmgr
)) {
151 if (data
->vce_power_gated
!= bgate
) {
153 cgs_set_clockgating_state(
155 AMD_IP_BLOCK_TYPE_VCE
,
156 AMD_CG_STATE_UNGATE
);
157 cgs_set_powergating_state(
159 AMD_IP_BLOCK_TYPE_VCE
,
161 tonga_enable_disable_vce_dpm(hwmgr
, false);
162 data
->vce_power_gated
= true;
164 tonga_phm_powerup_vce(hwmgr
);
165 data
->vce_power_gated
= false;
166 cgs_set_powergating_state(
168 AMD_IP_BLOCK_TYPE_VCE
,
169 AMD_PG_STATE_UNGATE
);
170 cgs_set_clockgating_state(
172 AMD_IP_BLOCK_TYPE_VCE
,
175 tonga_update_vce_dpm(hwmgr
, &states
);
176 tonga_enable_disable_vce_dpm(hwmgr
, true);
181 tonga_update_vce_dpm(hwmgr
, &states
);
182 tonga_enable_disable_vce_dpm(hwmgr
, true);
186 if (!data
->vce_power_gated
)
187 tonga_update_vce_dpm(hwmgr
, &states
);
192 int tonga_phm_update_clock_gatings(struct pp_hwmgr
*hwmgr
,
193 const uint32_t *msg_id
)
198 switch ((*msg_id
& PP_GROUP_MASK
) >> PP_GROUP_SHIFT
) {
200 switch ((*msg_id
& PP_BLOCK_MASK
) >> PP_BLOCK_SHIFT
) {
201 case PP_BLOCK_GFX_CG
:
202 if (PP_STATE_SUPPORT_CG
& *msg_id
) {
203 msg
= ((*msg_id
& PP_STATE_MASK
) & PP_STATE_CG
)
204 ? PPSMC_MSG_EnableClockGatingFeature
205 : PPSMC_MSG_DisableClockGatingFeature
;
206 value
= CG_GFX_CGCG_MASK
;
208 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
, msg
, value
))
211 if (PP_STATE_SUPPORT_LS
& *msg_id
) {
212 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_LS
213 ? PPSMC_MSG_EnableClockGatingFeature
214 : PPSMC_MSG_DisableClockGatingFeature
;
215 value
= CG_GFX_CGLS_MASK
;
217 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
, msg
, value
))
222 case PP_BLOCK_GFX_MG
:
223 /* For GFX MGCG, there are three different ones;
224 * CPF, RLC, and all others. CPF MGCG will not be used for Tonga.
225 * For GFX MGLS, Tonga will not support it.
227 if (PP_STATE_SUPPORT_CG
& *msg_id
) {
228 msg
= ((*msg_id
& PP_STATE_MASK
) & PP_STATE_CG
)
229 ? PPSMC_MSG_EnableClockGatingFeature
230 : PPSMC_MSG_DisableClockGatingFeature
;
231 value
= (CG_RLC_MGCG_MASK
| CG_GFX_OTHERS_MGCG_MASK
);
233 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
, msg
, value
))
244 switch ((*msg_id
& PP_BLOCK_MASK
) >> PP_BLOCK_SHIFT
) {
245 case PP_BLOCK_SYS_BIF
:
246 if (PP_STATE_SUPPORT_LS
& *msg_id
) {
247 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_LS
248 ? PPSMC_MSG_EnableClockGatingFeature
249 : PPSMC_MSG_DisableClockGatingFeature
;
250 value
= CG_SYS_BIF_MGLS_MASK
;
252 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
, msg
, value
))
257 case PP_BLOCK_SYS_MC
:
258 if (PP_STATE_SUPPORT_CG
& *msg_id
) {
259 msg
= ((*msg_id
& PP_STATE_MASK
) & PP_STATE_CG
)
260 ? PPSMC_MSG_EnableClockGatingFeature
261 : PPSMC_MSG_DisableClockGatingFeature
;
262 value
= CG_SYS_MC_MGCG_MASK
;
264 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
, msg
, value
))
268 if (PP_STATE_SUPPORT_LS
& *msg_id
) {
269 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_LS
270 ? PPSMC_MSG_EnableClockGatingFeature
271 : PPSMC_MSG_DisableClockGatingFeature
;
272 value
= CG_SYS_MC_MGLS_MASK
;
274 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
, msg
, value
))
280 case PP_BLOCK_SYS_HDP
:
281 if (PP_STATE_SUPPORT_CG
& *msg_id
) {
282 msg
= ((*msg_id
& PP_STATE_MASK
) & PP_STATE_CG
)
283 ? PPSMC_MSG_EnableClockGatingFeature
284 : PPSMC_MSG_DisableClockGatingFeature
;
285 value
= CG_SYS_HDP_MGCG_MASK
;
287 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
, msg
, value
))
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
;
296 value
= CG_SYS_HDP_MGLS_MASK
;
298 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
, msg
, value
))
303 case PP_BLOCK_SYS_SDMA
:
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_SYS_SDMA_MGCG_MASK
;
310 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
, msg
, value
))
314 if (PP_STATE_SUPPORT_LS
& *msg_id
) {
315 msg
= (*msg_id
& PP_STATE_MASK
) & PP_STATE_LS
316 ? PPSMC_MSG_EnableClockGatingFeature
317 : PPSMC_MSG_DisableClockGatingFeature
;
319 value
= CG_SYS_SDMA_MGLS_MASK
;
321 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
, msg
, value
))
326 case PP_BLOCK_SYS_ROM
:
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_ROM_MASK
;
333 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
, msg
, value
))