xref: /dragonfly/sys/dev/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c (revision b843c749addef9340ee7d4e250b09fdd492602a1)
1 /*
2  * Copyright 2016 Advanced Micro Devices, Inc.
3  *
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:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
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.
21  *
22  */
23 
24 #include "smu7_hwmgr.h"
25 #include "smu7_clockpowergating.h"
26 #include "smu7_common.h"
27 
smu7_enable_disable_uvd_dpm(struct pp_hwmgr * hwmgr,bool enable)28 static int smu7_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
29 {
30           return smum_send_msg_to_smc(hwmgr, enable ?
31                               PPSMC_MSG_UVDDPM_Enable :
32                               PPSMC_MSG_UVDDPM_Disable);
33 }
34 
smu7_enable_disable_vce_dpm(struct pp_hwmgr * hwmgr,bool enable)35 static int smu7_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
36 {
37           return smum_send_msg_to_smc(hwmgr, enable ?
38                               PPSMC_MSG_VCEDPM_Enable :
39                               PPSMC_MSG_VCEDPM_Disable);
40 }
41 
smu7_update_uvd_dpm(struct pp_hwmgr * hwmgr,bool bgate)42 static int smu7_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
43 {
44           if (!bgate)
45                     smum_update_smc_table(hwmgr, SMU_UVD_TABLE);
46           return smu7_enable_disable_uvd_dpm(hwmgr, !bgate);
47 }
48 
smu7_update_vce_dpm(struct pp_hwmgr * hwmgr,bool bgate)49 static int smu7_update_vce_dpm(struct pp_hwmgr *hwmgr, bool bgate)
50 {
51           if (!bgate)
52                     smum_update_smc_table(hwmgr, SMU_VCE_TABLE);
53           return smu7_enable_disable_vce_dpm(hwmgr, !bgate);
54 }
55 
smu7_powerdown_uvd(struct pp_hwmgr * hwmgr)56 int smu7_powerdown_uvd(struct pp_hwmgr *hwmgr)
57 {
58           if (phm_cf_want_uvd_power_gating(hwmgr))
59                     return smum_send_msg_to_smc(hwmgr,
60                                         PPSMC_MSG_UVDPowerOFF);
61           return 0;
62 }
63 
smu7_powerup_uvd(struct pp_hwmgr * hwmgr)64 static int smu7_powerup_uvd(struct pp_hwmgr *hwmgr)
65 {
66           if (phm_cf_want_uvd_power_gating(hwmgr)) {
67                     if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
68                                           PHM_PlatformCaps_UVDDynamicPowerGating)) {
69                               return smum_send_msg_to_smc_with_parameter(hwmgr,
70                                                   PPSMC_MSG_UVDPowerON, 1);
71                     } else {
72                               return smum_send_msg_to_smc_with_parameter(hwmgr,
73                                                   PPSMC_MSG_UVDPowerON, 0);
74                     }
75           }
76 
77           return 0;
78 }
79 
smu7_powerdown_vce(struct pp_hwmgr * hwmgr)80 static int smu7_powerdown_vce(struct pp_hwmgr *hwmgr)
81 {
82           if (phm_cf_want_vce_power_gating(hwmgr))
83                     return smum_send_msg_to_smc(hwmgr,
84                                         PPSMC_MSG_VCEPowerOFF);
85           return 0;
86 }
87 
smu7_powerup_vce(struct pp_hwmgr * hwmgr)88 static int smu7_powerup_vce(struct pp_hwmgr *hwmgr)
89 {
90           if (phm_cf_want_vce_power_gating(hwmgr))
91                     return smum_send_msg_to_smc(hwmgr,
92                                         PPSMC_MSG_VCEPowerON);
93           return 0;
94 }
95 
smu7_disable_clock_power_gating(struct pp_hwmgr * hwmgr)96 int smu7_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
97 {
98           struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
99 
100           data->uvd_power_gated = false;
101           data->vce_power_gated = false;
102 
103           smu7_powerup_uvd(hwmgr);
104           smu7_powerup_vce(hwmgr);
105 
106           return 0;
107 }
108 
smu7_powergate_uvd(struct pp_hwmgr * hwmgr,bool bgate)109 void smu7_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
110 {
111           struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
112 
113           data->uvd_power_gated = bgate;
114 
115           if (bgate) {
116                     amdgpu_device_ip_set_powergating_state(hwmgr->adev,
117                                                             AMD_IP_BLOCK_TYPE_UVD,
118                                                             AMD_PG_STATE_GATE);
119                     amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
120                                         AMD_IP_BLOCK_TYPE_UVD,
121                                         AMD_CG_STATE_GATE);
122                     smu7_update_uvd_dpm(hwmgr, true);
123                     smu7_powerdown_uvd(hwmgr);
124           } else {
125                     smu7_powerup_uvd(hwmgr);
126                     amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
127                                         AMD_IP_BLOCK_TYPE_UVD,
128                                         AMD_CG_STATE_UNGATE);
129                     amdgpu_device_ip_set_powergating_state(hwmgr->adev,
130                                                             AMD_IP_BLOCK_TYPE_UVD,
131                                                             AMD_PG_STATE_UNGATE);
132                     smu7_update_uvd_dpm(hwmgr, false);
133           }
134 
135 }
136 
smu7_powergate_vce(struct pp_hwmgr * hwmgr,bool bgate)137 void smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
138 {
139           struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
140 
141           data->vce_power_gated = bgate;
142 
143           if (bgate) {
144                     amdgpu_device_ip_set_powergating_state(hwmgr->adev,
145                                                             AMD_IP_BLOCK_TYPE_VCE,
146                                                             AMD_PG_STATE_GATE);
147                     amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
148                                         AMD_IP_BLOCK_TYPE_VCE,
149                                         AMD_CG_STATE_GATE);
150                     smu7_update_vce_dpm(hwmgr, true);
151                     smu7_powerdown_vce(hwmgr);
152           } else {
153                     smu7_powerup_vce(hwmgr);
154                     amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
155                                         AMD_IP_BLOCK_TYPE_VCE,
156                                         AMD_CG_STATE_UNGATE);
157                     amdgpu_device_ip_set_powergating_state(hwmgr->adev,
158                                                             AMD_IP_BLOCK_TYPE_VCE,
159                                                             AMD_PG_STATE_UNGATE);
160                     smu7_update_vce_dpm(hwmgr, false);
161           }
162 }
163 
smu7_update_clock_gatings(struct pp_hwmgr * hwmgr,const uint32_t * msg_id)164 int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
165                                                   const uint32_t *msg_id)
166 {
167           PPSMC_Msg msg;
168           uint32_t value;
169 
170           if (!(hwmgr->feature_mask & PP_ENABLE_GFX_CG_THRU_SMU))
171                     return 0;
172 
173           switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
174           case PP_GROUP_GFX:
175                     switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
176                     case PP_BLOCK_GFX_CG:
177                               if (PP_STATE_SUPPORT_CG & *msg_id) {
178                                         msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
179                                                             PPSMC_MSG_EnableClockGatingFeature :
180                                                             PPSMC_MSG_DisableClockGatingFeature;
181                                         value = CG_GFX_CGCG_MASK;
182 
183                                         if (smum_send_msg_to_smc_with_parameter(
184                                                             hwmgr, msg, value))
185                                                   return -EINVAL;
186                               }
187                               if (PP_STATE_SUPPORT_LS & *msg_id) {
188                                         msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
189                                                   ? PPSMC_MSG_EnableClockGatingFeature
190                                                   : PPSMC_MSG_DisableClockGatingFeature;
191                                         value = CG_GFX_CGLS_MASK;
192 
193                                         if (smum_send_msg_to_smc_with_parameter(
194                                                             hwmgr, msg, value))
195                                                   return -EINVAL;
196                               }
197                               break;
198 
199                     case PP_BLOCK_GFX_3D:
200                               if (PP_STATE_SUPPORT_CG & *msg_id) {
201                                         msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
202                                                             PPSMC_MSG_EnableClockGatingFeature :
203                                                             PPSMC_MSG_DisableClockGatingFeature;
204                                         value = CG_GFX_3DCG_MASK;
205 
206                                         if (smum_send_msg_to_smc_with_parameter(
207                                                             hwmgr, msg, value))
208                                                   return -EINVAL;
209                               }
210 
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_3DLS_MASK;
216 
217                                         if (smum_send_msg_to_smc_with_parameter(
218                                                             hwmgr, msg, value))
219                                                   return -EINVAL;
220                               }
221                               break;
222 
223                     case PP_BLOCK_GFX_RLC:
224                               if (PP_STATE_SUPPORT_LS & *msg_id) {
225                                         msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
226                                                             PPSMC_MSG_EnableClockGatingFeature :
227                                                             PPSMC_MSG_DisableClockGatingFeature;
228                                         value = CG_GFX_RLC_LS_MASK;
229 
230                                         if (smum_send_msg_to_smc_with_parameter(
231                                                             hwmgr, msg, value))
232                                                   return -EINVAL;
233                               }
234                               break;
235 
236                     case PP_BLOCK_GFX_CP:
237                               if (PP_STATE_SUPPORT_LS & *msg_id) {
238                                         msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
239                                                             PPSMC_MSG_EnableClockGatingFeature :
240                                                             PPSMC_MSG_DisableClockGatingFeature;
241                                         value = CG_GFX_CP_LS_MASK;
242 
243                                         if (smum_send_msg_to_smc_with_parameter(
244                                                             hwmgr, msg, value))
245                                                   return -EINVAL;
246                               }
247                               break;
248 
249                     case PP_BLOCK_GFX_MG:
250                               if (PP_STATE_SUPPORT_CG & *msg_id) {
251                                         msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)   ?
252                                                             PPSMC_MSG_EnableClockGatingFeature :
253                                                             PPSMC_MSG_DisableClockGatingFeature;
254                                         value = (CG_CPF_MGCG_MASK | CG_RLC_MGCG_MASK |
255                                                             CG_GFX_OTHERS_MGCG_MASK);
256 
257                                         if (smum_send_msg_to_smc_with_parameter(
258                                                             hwmgr, msg, value))
259                                                   return -EINVAL;
260                               }
261                               break;
262 
263                     default:
264                               return -EINVAL;
265                     }
266                     break;
267 
268           case PP_GROUP_SYS:
269                     switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
270                     case PP_BLOCK_SYS_BIF:
271                               if (PP_STATE_SUPPORT_CG & *msg_id) {
272                                         msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
273                                                             PPSMC_MSG_EnableClockGatingFeature :
274                                                             PPSMC_MSG_DisableClockGatingFeature;
275                                         value = CG_SYS_BIF_MGCG_MASK;
276 
277                                         if (smum_send_msg_to_smc_with_parameter(
278                                                             hwmgr, msg, value))
279                                                   return -EINVAL;
280                               }
281                               if  (PP_STATE_SUPPORT_LS & *msg_id) {
282                                         msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
283                                                             PPSMC_MSG_EnableClockGatingFeature :
284                                                             PPSMC_MSG_DisableClockGatingFeature;
285                                         value = CG_SYS_BIF_MGLS_MASK;
286 
287                                         if (smum_send_msg_to_smc_with_parameter(
288                                                             hwmgr, msg, value))
289                                                   return -EINVAL;
290                               }
291                               break;
292 
293                     case PP_BLOCK_SYS_MC:
294                               if (PP_STATE_SUPPORT_CG & *msg_id) {
295                                         msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)   ?
296                                                             PPSMC_MSG_EnableClockGatingFeature :
297                                                             PPSMC_MSG_DisableClockGatingFeature;
298                                         value = CG_SYS_MC_MGCG_MASK;
299 
300                                         if (smum_send_msg_to_smc_with_parameter(
301                                                             hwmgr, msg, value))
302                                                   return -EINVAL;
303                               }
304 
305                               if (PP_STATE_SUPPORT_LS & *msg_id) {
306                                         msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
307                                                             PPSMC_MSG_EnableClockGatingFeature :
308                                                             PPSMC_MSG_DisableClockGatingFeature;
309                                         value = CG_SYS_MC_MGLS_MASK;
310 
311                                         if (smum_send_msg_to_smc_with_parameter(
312                                                             hwmgr, msg, value))
313                                                   return -EINVAL;
314                               }
315                               break;
316 
317                     case PP_BLOCK_SYS_DRM:
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_DRM_MGCG_MASK;
323 
324                                         if (smum_send_msg_to_smc_with_parameter(
325                                                             hwmgr, msg, value))
326                                                   return -EINVAL;
327                               }
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_DRM_MGLS_MASK;
333 
334                                         if (smum_send_msg_to_smc_with_parameter(
335                                                             hwmgr, msg, value))
336                                                   return -EINVAL;
337                               }
338                               break;
339 
340                     case PP_BLOCK_SYS_HDP:
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_HDP_MGCG_MASK;
346 
347                                         if (smum_send_msg_to_smc_with_parameter(
348                                                             hwmgr, msg, value))
349                                                   return -EINVAL;
350                               }
351 
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_HDP_MGLS_MASK;
357 
358                                         if (smum_send_msg_to_smc_with_parameter(
359                                                             hwmgr, msg, value))
360                                                   return -EINVAL;
361                               }
362                               break;
363 
364                     case PP_BLOCK_SYS_SDMA:
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_SDMA_MGCG_MASK;
370 
371                                         if (smum_send_msg_to_smc_with_parameter(
372                                                             hwmgr, msg, value))
373                                                   return -EINVAL;
374                               }
375 
376                               if (PP_STATE_SUPPORT_LS & *msg_id) {
377                                         msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
378                                                             PPSMC_MSG_EnableClockGatingFeature :
379                                                             PPSMC_MSG_DisableClockGatingFeature;
380                                         value = CG_SYS_SDMA_MGLS_MASK;
381 
382                                         if (smum_send_msg_to_smc_with_parameter(
383                                                             hwmgr, msg, value))
384                                                   return -EINVAL;
385                               }
386                               break;
387 
388                     case PP_BLOCK_SYS_ROM:
389                               if (PP_STATE_SUPPORT_CG & *msg_id) {
390                                         msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
391                                                             PPSMC_MSG_EnableClockGatingFeature :
392                                                             PPSMC_MSG_DisableClockGatingFeature;
393                                         value = CG_SYS_ROM_MASK;
394 
395                                         if (smum_send_msg_to_smc_with_parameter(
396                                                             hwmgr, msg, value))
397                                                   return -EINVAL;
398                               }
399                               break;
400 
401                     default:
402                               return -EINVAL;
403 
404                     }
405                     break;
406 
407           default:
408                     return -EINVAL;
409 
410           }
411 
412           return 0;
413 }
414 
415 /* This function is for Polaris11 only for now,
416  * Powerplay will only control the static per CU Power Gating.
417  * Dynamic per CU Power Gating will be done in gfx.
418  */
smu7_powergate_gfx(struct pp_hwmgr * hwmgr,bool enable)419 int smu7_powergate_gfx(struct pp_hwmgr *hwmgr, bool enable)
420 {
421           struct amdgpu_device *adev = hwmgr->adev;
422 
423           if (enable)
424                     return smum_send_msg_to_smc_with_parameter(hwmgr,
425                                                   PPSMC_MSG_GFX_CU_PG_ENABLE,
426                                                   adev->gfx.cu_info.number);
427           else
428                     return smum_send_msg_to_smc(hwmgr,
429                                         PPSMC_MSG_GFX_CU_PG_DISABLE);
430 }
431