MAINTAINERS: mmc: Move the mmc tree to kernel.org
[cascardo/linux.git] / drivers / gpu / drm / amd / powerplay / hwmgr / polaris10_clockpowergating.c
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 "polaris10_clockpowergating.h"
25
26 int polaris10_phm_powerdown_uvd(struct pp_hwmgr *hwmgr)
27 {
28         if (phm_cf_want_uvd_power_gating(hwmgr))
29                 return smum_send_msg_to_smc(hwmgr->smumgr,
30                                 PPSMC_MSG_UVDPowerOFF);
31         return 0;
32 }
33
34 int polaris10_phm_powerup_uvd(struct pp_hwmgr *hwmgr)
35 {
36         if (phm_cf_want_uvd_power_gating(hwmgr)) {
37                 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
38                                   PHM_PlatformCaps_UVDDynamicPowerGating)) {
39                         return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
40                                         PPSMC_MSG_UVDPowerON, 1);
41                 } else {
42                         return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
43                                         PPSMC_MSG_UVDPowerON, 0);
44                 }
45         }
46
47         return 0;
48 }
49
50 int polaris10_phm_powerdown_vce(struct pp_hwmgr *hwmgr)
51 {
52         if (phm_cf_want_vce_power_gating(hwmgr))
53                 return smum_send_msg_to_smc(hwmgr->smumgr,
54                                 PPSMC_MSG_VCEPowerOFF);
55         return 0;
56 }
57
58 int polaris10_phm_powerup_vce(struct pp_hwmgr *hwmgr)
59 {
60         if (phm_cf_want_vce_power_gating(hwmgr))
61                 return smum_send_msg_to_smc(hwmgr->smumgr,
62                                 PPSMC_MSG_VCEPowerON);
63         return 0;
64 }
65
66 int polaris10_phm_powerdown_samu(struct pp_hwmgr *hwmgr)
67 {
68         if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
69                         PHM_PlatformCaps_SamuPowerGating))
70                 return smum_send_msg_to_smc(hwmgr->smumgr,
71                                 PPSMC_MSG_SAMPowerOFF);
72         return 0;
73 }
74
75 int polaris10_phm_powerup_samu(struct pp_hwmgr *hwmgr)
76 {
77         if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
78                         PHM_PlatformCaps_SamuPowerGating))
79                 return smum_send_msg_to_smc(hwmgr->smumgr,
80                                 PPSMC_MSG_SAMPowerON);
81         return 0;
82 }
83
84 int polaris10_phm_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
85 {
86         struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
87
88         data->uvd_power_gated = false;
89         data->vce_power_gated = false;
90         data->samu_power_gated = false;
91
92         polaris10_phm_powerup_uvd(hwmgr);
93         polaris10_phm_powerup_vce(hwmgr);
94         polaris10_phm_powerup_samu(hwmgr);
95
96         return 0;
97 }
98
99 int polaris10_phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
100 {
101         struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
102
103         if (data->uvd_power_gated == bgate)
104                 return 0;
105
106         data->uvd_power_gated = bgate;
107
108         if (bgate) {
109                 cgs_set_clockgating_state(hwmgr->device,
110                                 AMD_IP_BLOCK_TYPE_UVD,
111                                 AMD_CG_STATE_GATE);
112                 polaris10_update_uvd_dpm(hwmgr, true);
113                 polaris10_phm_powerdown_uvd(hwmgr);
114         } else {
115                 polaris10_phm_powerup_uvd(hwmgr);
116                 polaris10_update_uvd_dpm(hwmgr, false);
117                 cgs_set_clockgating_state(hwmgr->device,
118                                 AMD_IP_BLOCK_TYPE_UVD,
119                                 AMD_CG_STATE_UNGATE);
120         }
121
122         return 0;
123 }
124
125 int polaris10_phm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
126 {
127         struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
128
129         if (data->vce_power_gated == bgate)
130                 return 0;
131
132         data->vce_power_gated = bgate;
133
134         if (bgate) {
135                 cgs_set_clockgating_state(hwmgr->device,
136                                 AMD_IP_BLOCK_TYPE_VCE,
137                                 AMD_CG_STATE_GATE);
138                 polaris10_update_vce_dpm(hwmgr, true);
139                 polaris10_phm_powerdown_vce(hwmgr);
140         } else {
141                 polaris10_phm_powerup_vce(hwmgr);
142                 polaris10_update_vce_dpm(hwmgr, false);
143                 cgs_set_clockgating_state(hwmgr->device,
144                                 AMD_IP_BLOCK_TYPE_VCE,
145                                 AMD_CG_STATE_UNGATE);
146         }
147         return 0;
148 }
149
150 int polaris10_phm_powergate_samu(struct pp_hwmgr *hwmgr, bool bgate)
151 {
152         struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
153
154         if (data->samu_power_gated == bgate)
155                 return 0;
156
157         data->samu_power_gated = bgate;
158
159         if (bgate) {
160                 polaris10_update_samu_dpm(hwmgr, true);
161                 polaris10_phm_powerdown_samu(hwmgr);
162         } else {
163                 polaris10_phm_powerup_samu(hwmgr);
164                 polaris10_update_samu_dpm(hwmgr, false);
165         }
166
167         return 0;
168 }
169
170 int polaris10_phm_update_clock_gatings(struct pp_hwmgr *hwmgr,
171                                         const uint32_t *msg_id)
172 {
173         PPSMC_Msg msg;
174         uint32_t value;
175
176         switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
177         case PP_GROUP_GFX:
178                 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
179                 case PP_BLOCK_GFX_CG:
180                         if (PP_STATE_SUPPORT_CG & *msg_id) {
181                                 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
182                                                 PPSMC_MSG_EnableClockGatingFeature :
183                                                 PPSMC_MSG_DisableClockGatingFeature;
184                                 value = CG_GFX_CGCG_MASK;
185
186                                 if (smum_send_msg_to_smc_with_parameter(
187                                                 hwmgr->smumgr, msg, value))
188                                         return -1;
189                         }
190                         if (PP_STATE_SUPPORT_LS & *msg_id) {
191                                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
192                                         ? PPSMC_MSG_EnableClockGatingFeature
193                                         : PPSMC_MSG_DisableClockGatingFeature;
194                                 value = CG_GFX_CGLS_MASK;
195
196                                 if (smum_send_msg_to_smc_with_parameter(
197                                                 hwmgr->smumgr, msg, value))
198                                         return -1;
199                         }
200                         break;
201
202                 case PP_BLOCK_GFX_3D:
203                         if (PP_STATE_SUPPORT_CG & *msg_id) {
204                                 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
205                                                 PPSMC_MSG_EnableClockGatingFeature :
206                                                 PPSMC_MSG_DisableClockGatingFeature;
207                                 value = CG_GFX_3DCG_MASK;
208
209                                 if (smum_send_msg_to_smc_with_parameter(
210                                                 hwmgr->smumgr, msg, value))
211                                         return -1;
212                         }
213
214                         if  (PP_STATE_SUPPORT_LS & *msg_id) {
215                                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
216                                                 PPSMC_MSG_EnableClockGatingFeature :
217                                                 PPSMC_MSG_DisableClockGatingFeature;
218                                 value = CG_GFX_3DLS_MASK;
219
220                                 if (smum_send_msg_to_smc_with_parameter(
221                                                 hwmgr->smumgr, msg, value))
222                                         return -1;
223                         }
224                         break;
225
226                 case PP_BLOCK_GFX_RLC:
227                         if (PP_STATE_SUPPORT_LS & *msg_id) {
228                                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
229                                                 PPSMC_MSG_EnableClockGatingFeature :
230                                                 PPSMC_MSG_DisableClockGatingFeature;
231                                 value = CG_GFX_RLC_LS_MASK;
232
233                                 if (smum_send_msg_to_smc_with_parameter(
234                                                 hwmgr->smumgr, msg, value))
235                                         return -1;
236                         }
237                         break;
238
239                 case PP_BLOCK_GFX_CP:
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_CP_LS_MASK;
245
246                                 if (smum_send_msg_to_smc_with_parameter(
247                                                 hwmgr->smumgr, msg, value))
248                                         return -1;
249                         }
250                         break;
251
252                 case PP_BLOCK_GFX_MG:
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_CPF_MGCG_MASK | CG_RLC_MGCG_MASK |
258                                                 CG_GFX_OTHERS_MGCG_MASK);
259
260                                 if (smum_send_msg_to_smc_with_parameter(
261                                                 hwmgr->smumgr, msg, value))
262                                         return -1;
263                         }
264                         break;
265
266                 default:
267                         return -1;
268                 }
269                 break;
270
271         case PP_GROUP_SYS:
272                 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
273                 case PP_BLOCK_SYS_BIF:
274                         if (PP_STATE_SUPPORT_CG & *msg_id) {
275                                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
276                                                 PPSMC_MSG_EnableClockGatingFeature :
277                                                 PPSMC_MSG_DisableClockGatingFeature;
278                                 value = CG_SYS_BIF_MGCG_MASK;
279
280                                 if (smum_send_msg_to_smc_with_parameter(
281                                                 hwmgr->smumgr, msg, value))
282                                         return -1;
283                         }
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_SYS_BIF_MGLS_MASK;
289
290                                 if (smum_send_msg_to_smc_with_parameter(
291                                                 hwmgr->smumgr, msg, value))
292                                         return -1;
293                         }
294                         break;
295
296                 case PP_BLOCK_SYS_MC:
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_SYS_MC_MGCG_MASK;
302
303                                 if (smum_send_msg_to_smc_with_parameter(
304                                                 hwmgr->smumgr, msg, value))
305                                         return -1;
306                         }
307
308                         if (PP_STATE_SUPPORT_LS & *msg_id) {
309                                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
310                                                 PPSMC_MSG_EnableClockGatingFeature :
311                                                 PPSMC_MSG_DisableClockGatingFeature;
312                                 value = CG_SYS_MC_MGLS_MASK;
313
314                                 if (smum_send_msg_to_smc_with_parameter(
315                                                 hwmgr->smumgr, msg, value))
316                                         return -1;
317                         }
318                         break;
319
320                 case PP_BLOCK_SYS_DRM:
321                         if (PP_STATE_SUPPORT_CG & *msg_id) {
322                                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
323                                                 PPSMC_MSG_EnableClockGatingFeature :
324                                                 PPSMC_MSG_DisableClockGatingFeature;
325                                 value = CG_SYS_DRM_MGCG_MASK;
326
327                                 if (smum_send_msg_to_smc_with_parameter(
328                                                 hwmgr->smumgr, msg, value))
329                                         return -1;
330                         }
331                         if (PP_STATE_SUPPORT_LS & *msg_id) {
332                                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
333                                                 PPSMC_MSG_EnableClockGatingFeature :
334                                                 PPSMC_MSG_DisableClockGatingFeature;
335                                 value = CG_SYS_DRM_MGLS_MASK;
336
337                                 if (smum_send_msg_to_smc_with_parameter(
338                                                 hwmgr->smumgr, msg, value))
339                                         return -1;
340                         }
341                         break;
342
343                 case PP_BLOCK_SYS_HDP:
344                         if (PP_STATE_SUPPORT_CG & *msg_id) {
345                                 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
346                                                 PPSMC_MSG_EnableClockGatingFeature :
347                                                 PPSMC_MSG_DisableClockGatingFeature;
348                                 value = CG_SYS_HDP_MGCG_MASK;
349
350                                 if (smum_send_msg_to_smc_with_parameter(
351                                                 hwmgr->smumgr, msg, value))
352                                         return -1;
353                         }
354
355                         if (PP_STATE_SUPPORT_LS & *msg_id) {
356                                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
357                                                 PPSMC_MSG_EnableClockGatingFeature :
358                                                 PPSMC_MSG_DisableClockGatingFeature;
359                                 value = CG_SYS_HDP_MGLS_MASK;
360
361                                 if (smum_send_msg_to_smc_with_parameter(
362                                                 hwmgr->smumgr, msg, value))
363                                         return -1;
364                         }
365                         break;
366
367                 case PP_BLOCK_SYS_SDMA:
368                         if (PP_STATE_SUPPORT_CG & *msg_id) {
369                                 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
370                                                 PPSMC_MSG_EnableClockGatingFeature :
371                                                 PPSMC_MSG_DisableClockGatingFeature;
372                                 value = CG_SYS_SDMA_MGCG_MASK;
373
374                                 if (smum_send_msg_to_smc_with_parameter(
375                                                 hwmgr->smumgr, msg, value))
376                                         return -1;
377                         }
378
379                         if (PP_STATE_SUPPORT_LS & *msg_id) {
380                                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
381                                                 PPSMC_MSG_EnableClockGatingFeature :
382                                                 PPSMC_MSG_DisableClockGatingFeature;
383                                 value = CG_SYS_SDMA_MGLS_MASK;
384
385                                 if (smum_send_msg_to_smc_with_parameter(
386                                                 hwmgr->smumgr, msg, value))
387                                         return -1;
388                         }
389                         break;
390
391                 case PP_BLOCK_SYS_ROM:
392                         if (PP_STATE_SUPPORT_CG & *msg_id) {
393                                 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
394                                                 PPSMC_MSG_EnableClockGatingFeature :
395                                                 PPSMC_MSG_DisableClockGatingFeature;
396                                 value = CG_SYS_ROM_MASK;
397
398                                 if (smum_send_msg_to_smc_with_parameter(
399                                                 hwmgr->smumgr, msg, value))
400                                         return -1;
401                         }
402                         break;
403
404                 default:
405                         return -1;
406
407                 }
408                 break;
409
410         default:
411                 return -1;
412
413         }
414
415         return 0;
416 }
417
418 /* This function is for Polaris11 only for now,
419  * Powerplay will only control the static per CU Power Gating.
420  * Dynamic per CU Power Gating will be done in gfx.
421  */
422 int polaris10_phm_enable_per_cu_power_gating(struct pp_hwmgr *hwmgr, bool enable)
423 {
424         struct cgs_system_info sys_info = {0};
425         uint32_t active_cus;
426         int result;
427
428         sys_info.size = sizeof(struct cgs_system_info);
429         sys_info.info_id = CGS_SYSTEM_INFO_GFX_CU_INFO;
430
431         result = cgs_query_system_info(hwmgr->device, &sys_info);
432
433         if (result)
434                 return -EINVAL;
435         else
436                 active_cus = sys_info.value;
437
438         if (enable)
439                 return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
440                                 PPSMC_MSG_GFX_CU_PG_ENABLE, active_cus);
441         else
442                 return smum_send_msg_to_smc(hwmgr->smumgr,
443                                 PPSMC_MSG_GFX_CU_PG_DISABLE);
444 }