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, enable ?
31 PPSMC_MSG_UVDDPM_Enable :
32 PPSMC_MSG_UVDDPM_Disable,
36 static int smu7_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
38 return smum_send_msg_to_smc(hwmgr, enable ?
39 PPSMC_MSG_VCEDPM_Enable :
40 PPSMC_MSG_VCEDPM_Disable,
44 static int smu7_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
47 smum_update_smc_table(hwmgr, SMU_UVD_TABLE);
48 return smu7_enable_disable_uvd_dpm(hwmgr, !bgate);
51 static int smu7_update_vce_dpm(struct pp_hwmgr *hwmgr, bool bgate)
54 smum_update_smc_table(hwmgr, SMU_VCE_TABLE);
55 return smu7_enable_disable_vce_dpm(hwmgr, !bgate);
58 int smu7_powerdown_uvd(struct pp_hwmgr *hwmgr)
60 if (phm_cf_want_uvd_power_gating(hwmgr))
61 return smum_send_msg_to_smc(hwmgr,
62 PPSMC_MSG_UVDPowerOFF,
67 static int smu7_powerup_uvd(struct pp_hwmgr *hwmgr)
69 if (phm_cf_want_uvd_power_gating(hwmgr)) {
70 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
71 PHM_PlatformCaps_UVDDynamicPowerGating)) {
72 return smum_send_msg_to_smc_with_parameter(hwmgr,
73 PPSMC_MSG_UVDPowerON, 1, NULL);
75 return smum_send_msg_to_smc_with_parameter(hwmgr,
76 PPSMC_MSG_UVDPowerON, 0, NULL);
83 static int smu7_powerdown_vce(struct pp_hwmgr *hwmgr)
85 if (phm_cf_want_vce_power_gating(hwmgr))
86 return smum_send_msg_to_smc(hwmgr,
87 PPSMC_MSG_VCEPowerOFF,
92 static int smu7_powerup_vce(struct pp_hwmgr *hwmgr)
94 if (phm_cf_want_vce_power_gating(hwmgr))
95 return smum_send_msg_to_smc(hwmgr,
101 int smu7_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
103 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
105 data->uvd_power_gated = false;
106 data->vce_power_gated = false;
108 smu7_powerup_uvd(hwmgr);
109 smu7_powerup_vce(hwmgr);
114 void smu7_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
116 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
118 data->uvd_power_gated = bgate;
121 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
122 AMD_IP_BLOCK_TYPE_UVD,
124 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
125 AMD_IP_BLOCK_TYPE_UVD,
127 smu7_update_uvd_dpm(hwmgr, true);
128 smu7_powerdown_uvd(hwmgr);
130 smu7_powerup_uvd(hwmgr);
131 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
132 AMD_IP_BLOCK_TYPE_UVD,
133 AMD_CG_STATE_UNGATE);
134 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
135 AMD_IP_BLOCK_TYPE_UVD,
136 AMD_PG_STATE_UNGATE);
137 smu7_update_uvd_dpm(hwmgr, false);
142 void smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
144 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
146 data->vce_power_gated = bgate;
149 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
150 AMD_IP_BLOCK_TYPE_VCE,
152 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
153 AMD_IP_BLOCK_TYPE_VCE,
155 smu7_update_vce_dpm(hwmgr, true);
156 smu7_powerdown_vce(hwmgr);
158 smu7_powerup_vce(hwmgr);
159 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
160 AMD_IP_BLOCK_TYPE_VCE,
161 AMD_CG_STATE_UNGATE);
162 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
163 AMD_IP_BLOCK_TYPE_VCE,
164 AMD_PG_STATE_UNGATE);
165 smu7_update_vce_dpm(hwmgr, false);
169 int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
170 const uint32_t *msg_id)
175 if (!(hwmgr->feature_mask & PP_ENABLE_GFX_CG_THRU_SMU))
178 switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
180 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
181 case PP_BLOCK_GFX_CG:
182 if (PP_STATE_SUPPORT_CG & *msg_id) {
183 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
184 PPSMC_MSG_EnableClockGatingFeature :
185 PPSMC_MSG_DisableClockGatingFeature;
186 value = CG_GFX_CGCG_MASK;
188 if (smum_send_msg_to_smc_with_parameter(
189 hwmgr, msg, value, NULL))
192 if (PP_STATE_SUPPORT_LS & *msg_id) {
193 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
194 ? PPSMC_MSG_EnableClockGatingFeature
195 : PPSMC_MSG_DisableClockGatingFeature;
196 value = CG_GFX_CGLS_MASK;
198 if (smum_send_msg_to_smc_with_parameter(
199 hwmgr, msg, value, NULL))
204 case PP_BLOCK_GFX_3D:
205 if (PP_STATE_SUPPORT_CG & *msg_id) {
206 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
207 PPSMC_MSG_EnableClockGatingFeature :
208 PPSMC_MSG_DisableClockGatingFeature;
209 value = CG_GFX_3DCG_MASK;
211 if (smum_send_msg_to_smc_with_parameter(
212 hwmgr, msg, value, NULL))
216 if (PP_STATE_SUPPORT_LS & *msg_id) {
217 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
218 PPSMC_MSG_EnableClockGatingFeature :
219 PPSMC_MSG_DisableClockGatingFeature;
220 value = CG_GFX_3DLS_MASK;
222 if (smum_send_msg_to_smc_with_parameter(
223 hwmgr, msg, value, NULL))
228 case PP_BLOCK_GFX_RLC:
229 if (PP_STATE_SUPPORT_LS & *msg_id) {
230 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
231 PPSMC_MSG_EnableClockGatingFeature :
232 PPSMC_MSG_DisableClockGatingFeature;
233 value = CG_GFX_RLC_LS_MASK;
235 if (smum_send_msg_to_smc_with_parameter(
236 hwmgr, msg, value, NULL))
241 case PP_BLOCK_GFX_CP:
242 if (PP_STATE_SUPPORT_LS & *msg_id) {
243 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
244 PPSMC_MSG_EnableClockGatingFeature :
245 PPSMC_MSG_DisableClockGatingFeature;
246 value = CG_GFX_CP_LS_MASK;
248 if (smum_send_msg_to_smc_with_parameter(
249 hwmgr, msg, value, NULL))
254 case PP_BLOCK_GFX_MG:
255 if (PP_STATE_SUPPORT_CG & *msg_id) {
256 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
257 PPSMC_MSG_EnableClockGatingFeature :
258 PPSMC_MSG_DisableClockGatingFeature;
259 value = (CG_CPF_MGCG_MASK | CG_RLC_MGCG_MASK |
260 CG_GFX_OTHERS_MGCG_MASK);
262 if (smum_send_msg_to_smc_with_parameter(
263 hwmgr, msg, value, NULL))
274 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
275 case PP_BLOCK_SYS_BIF:
276 if (PP_STATE_SUPPORT_CG & *msg_id) {
277 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
278 PPSMC_MSG_EnableClockGatingFeature :
279 PPSMC_MSG_DisableClockGatingFeature;
280 value = CG_SYS_BIF_MGCG_MASK;
282 if (smum_send_msg_to_smc_with_parameter(
283 hwmgr, msg, value, NULL))
286 if (PP_STATE_SUPPORT_LS & *msg_id) {
287 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
288 PPSMC_MSG_EnableClockGatingFeature :
289 PPSMC_MSG_DisableClockGatingFeature;
290 value = CG_SYS_BIF_MGLS_MASK;
292 if (smum_send_msg_to_smc_with_parameter(
293 hwmgr, msg, value, NULL))
298 case PP_BLOCK_SYS_MC:
299 if (PP_STATE_SUPPORT_CG & *msg_id) {
300 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
301 PPSMC_MSG_EnableClockGatingFeature :
302 PPSMC_MSG_DisableClockGatingFeature;
303 value = CG_SYS_MC_MGCG_MASK;
305 if (smum_send_msg_to_smc_with_parameter(
306 hwmgr, msg, value, NULL))
310 if (PP_STATE_SUPPORT_LS & *msg_id) {
311 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
312 PPSMC_MSG_EnableClockGatingFeature :
313 PPSMC_MSG_DisableClockGatingFeature;
314 value = CG_SYS_MC_MGLS_MASK;
316 if (smum_send_msg_to_smc_with_parameter(
317 hwmgr, msg, value, NULL))
322 case PP_BLOCK_SYS_DRM:
323 if (PP_STATE_SUPPORT_CG & *msg_id) {
324 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
325 PPSMC_MSG_EnableClockGatingFeature :
326 PPSMC_MSG_DisableClockGatingFeature;
327 value = CG_SYS_DRM_MGCG_MASK;
329 if (smum_send_msg_to_smc_with_parameter(
330 hwmgr, msg, value, NULL))
333 if (PP_STATE_SUPPORT_LS & *msg_id) {
334 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
335 PPSMC_MSG_EnableClockGatingFeature :
336 PPSMC_MSG_DisableClockGatingFeature;
337 value = CG_SYS_DRM_MGLS_MASK;
339 if (smum_send_msg_to_smc_with_parameter(
340 hwmgr, msg, value, NULL))
345 case PP_BLOCK_SYS_HDP:
346 if (PP_STATE_SUPPORT_CG & *msg_id) {
347 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
348 PPSMC_MSG_EnableClockGatingFeature :
349 PPSMC_MSG_DisableClockGatingFeature;
350 value = CG_SYS_HDP_MGCG_MASK;
352 if (smum_send_msg_to_smc_with_parameter(
353 hwmgr, msg, value, NULL))
357 if (PP_STATE_SUPPORT_LS & *msg_id) {
358 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
359 PPSMC_MSG_EnableClockGatingFeature :
360 PPSMC_MSG_DisableClockGatingFeature;
361 value = CG_SYS_HDP_MGLS_MASK;
363 if (smum_send_msg_to_smc_with_parameter(
364 hwmgr, msg, value, NULL))
369 case PP_BLOCK_SYS_SDMA:
370 if (PP_STATE_SUPPORT_CG & *msg_id) {
371 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
372 PPSMC_MSG_EnableClockGatingFeature :
373 PPSMC_MSG_DisableClockGatingFeature;
374 value = CG_SYS_SDMA_MGCG_MASK;
376 if (smum_send_msg_to_smc_with_parameter(
377 hwmgr, msg, value, NULL))
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_SDMA_MGLS_MASK;
387 if (smum_send_msg_to_smc_with_parameter(
388 hwmgr, msg, value, NULL))
393 case PP_BLOCK_SYS_ROM:
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_ROM_MASK;
400 if (smum_send_msg_to_smc_with_parameter(
401 hwmgr, msg, value, NULL))
420 /* This function is for Polaris11 only for now,
421 * Powerplay will only control the static per CU Power Gating.
422 * Dynamic per CU Power Gating will be done in gfx.
424 int smu7_powergate_gfx(struct pp_hwmgr *hwmgr, bool enable)
426 struct amdgpu_device *adev = hwmgr->adev;
429 return smum_send_msg_to_smc_with_parameter(hwmgr,
430 PPSMC_MSG_GFX_CU_PG_ENABLE,
431 adev->gfx.cu_info.number,
434 return smum_send_msg_to_smc(hwmgr,
435 PPSMC_MSG_GFX_CU_PG_DISABLE,