Merge remote-tracking branch 'ftrace/for-next'
[deliverable/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 }
This page took 0.056482 seconds and 5 git commands to generate.