diff options
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c')
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c | 430 |
1 files changed, 430 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c new file mode 100644 index 000000000000..8f142a74ad08 --- /dev/null +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c | |||
@@ -0,0 +1,430 @@ | |||
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 | polaris10_update_uvd_dpm(hwmgr, true); | ||
110 | polaris10_phm_powerdown_uvd(hwmgr); | ||
111 | } else { | ||
112 | polaris10_phm_powerup_uvd(hwmgr); | ||
113 | polaris10_update_uvd_dpm(hwmgr, false); | ||
114 | } | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | int polaris10_phm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate) | ||
120 | { | ||
121 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
122 | |||
123 | if (data->vce_power_gated == bgate) | ||
124 | return 0; | ||
125 | |||
126 | data->vce_power_gated = bgate; | ||
127 | |||
128 | if (bgate) | ||
129 | polaris10_phm_powerdown_vce(hwmgr); | ||
130 | else | ||
131 | polaris10_phm_powerup_vce(hwmgr); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | int polaris10_phm_powergate_samu(struct pp_hwmgr *hwmgr, bool bgate) | ||
137 | { | ||
138 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
139 | |||
140 | if (data->samu_power_gated == bgate) | ||
141 | return 0; | ||
142 | |||
143 | data->samu_power_gated = bgate; | ||
144 | |||
145 | if (bgate) { | ||
146 | polaris10_update_samu_dpm(hwmgr, true); | ||
147 | polaris10_phm_powerdown_samu(hwmgr); | ||
148 | } else { | ||
149 | polaris10_phm_powerup_samu(hwmgr); | ||
150 | polaris10_update_samu_dpm(hwmgr, false); | ||
151 | } | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | int polaris10_phm_update_clock_gatings(struct pp_hwmgr *hwmgr, | ||
157 | const uint32_t *msg_id) | ||
158 | { | ||
159 | PPSMC_Msg msg; | ||
160 | uint32_t value; | ||
161 | |||
162 | switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) { | ||
163 | case PP_GROUP_GFX: | ||
164 | switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) { | ||
165 | case PP_BLOCK_GFX_CG: | ||
166 | if (PP_STATE_SUPPORT_CG & *msg_id) { | ||
167 | msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ? | ||
168 | PPSMC_MSG_EnableClockGatingFeature : | ||
169 | PPSMC_MSG_DisableClockGatingFeature; | ||
170 | value = CG_GFX_CGCG_MASK; | ||
171 | |||
172 | if (smum_send_msg_to_smc_with_parameter( | ||
173 | hwmgr->smumgr, msg, value)) | ||
174 | return -1; | ||
175 | } | ||
176 | if (PP_STATE_SUPPORT_LS & *msg_id) { | ||
177 | msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS | ||
178 | ? PPSMC_MSG_EnableClockGatingFeature | ||
179 | : PPSMC_MSG_DisableClockGatingFeature; | ||
180 | value = CG_GFX_CGLS_MASK; | ||
181 | |||
182 | if (smum_send_msg_to_smc_with_parameter( | ||
183 | hwmgr->smumgr, msg, value)) | ||
184 | return -1; | ||
185 | } | ||
186 | break; | ||
187 | |||
188 | case PP_BLOCK_GFX_3D: | ||
189 | if (PP_STATE_SUPPORT_CG & *msg_id) { | ||
190 | msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ? | ||
191 | PPSMC_MSG_EnableClockGatingFeature : | ||
192 | PPSMC_MSG_DisableClockGatingFeature; | ||
193 | value = CG_GFX_3DCG_MASK; | ||
194 | |||
195 | if (smum_send_msg_to_smc_with_parameter( | ||
196 | hwmgr->smumgr, msg, value)) | ||
197 | return -1; | ||
198 | } | ||
199 | |||
200 | if (PP_STATE_SUPPORT_LS & *msg_id) { | ||
201 | msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ? | ||
202 | PPSMC_MSG_EnableClockGatingFeature : | ||
203 | PPSMC_MSG_DisableClockGatingFeature; | ||
204 | value = CG_GFX_3DLS_MASK; | ||
205 | |||
206 | if (smum_send_msg_to_smc_with_parameter( | ||
207 | hwmgr->smumgr, msg, value)) | ||
208 | return -1; | ||
209 | } | ||
210 | break; | ||
211 | |||
212 | case PP_BLOCK_GFX_RLC: | ||
213 | if (PP_STATE_SUPPORT_LS & *msg_id) { | ||
214 | msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ? | ||
215 | PPSMC_MSG_EnableClockGatingFeature : | ||
216 | PPSMC_MSG_DisableClockGatingFeature; | ||
217 | value = CG_GFX_RLC_LS_MASK; | ||
218 | |||
219 | if (smum_send_msg_to_smc_with_parameter( | ||
220 | hwmgr->smumgr, msg, value)) | ||
221 | return -1; | ||
222 | } | ||
223 | break; | ||
224 | |||
225 | case PP_BLOCK_GFX_CP: | ||
226 | if (PP_STATE_SUPPORT_LS & *msg_id) { | ||
227 | msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ? | ||
228 | PPSMC_MSG_EnableClockGatingFeature : | ||
229 | PPSMC_MSG_DisableClockGatingFeature; | ||
230 | value = CG_GFX_CP_LS_MASK; | ||
231 | |||
232 | if (smum_send_msg_to_smc_with_parameter( | ||
233 | hwmgr->smumgr, msg, value)) | ||
234 | return -1; | ||
235 | } | ||
236 | break; | ||
237 | |||
238 | case PP_BLOCK_GFX_MG: | ||
239 | if (PP_STATE_SUPPORT_CG & *msg_id) { | ||
240 | msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ? | ||
241 | PPSMC_MSG_EnableClockGatingFeature : | ||
242 | PPSMC_MSG_DisableClockGatingFeature; | ||
243 | value = (CG_CPF_MGCG_MASK | CG_RLC_MGCG_MASK | | ||
244 | CG_GFX_OTHERS_MGCG_MASK); | ||
245 | |||
246 | if (smum_send_msg_to_smc_with_parameter( | ||
247 | hwmgr->smumgr, msg, value)) | ||
248 | return -1; | ||
249 | } | ||
250 | break; | ||
251 | |||
252 | default: | ||
253 | return -1; | ||
254 | } | ||
255 | break; | ||
256 | |||
257 | case PP_GROUP_SYS: | ||
258 | switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) { | ||
259 | case PP_BLOCK_SYS_BIF: | ||
260 | if (PP_STATE_SUPPORT_CG & *msg_id) { | ||
261 | msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ? | ||
262 | PPSMC_MSG_EnableClockGatingFeature : | ||
263 | PPSMC_MSG_DisableClockGatingFeature; | ||
264 | value = CG_SYS_BIF_MGCG_MASK; | ||
265 | |||
266 | if (smum_send_msg_to_smc_with_parameter( | ||
267 | hwmgr->smumgr, msg, value)) | ||
268 | return -1; | ||
269 | } | ||
270 | if (PP_STATE_SUPPORT_LS & *msg_id) { | ||
271 | msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ? | ||
272 | PPSMC_MSG_EnableClockGatingFeature : | ||
273 | PPSMC_MSG_DisableClockGatingFeature; | ||
274 | value = CG_SYS_BIF_MGLS_MASK; | ||
275 | |||
276 | if (smum_send_msg_to_smc_with_parameter( | ||
277 | hwmgr->smumgr, msg, value)) | ||
278 | return -1; | ||
279 | } | ||
280 | break; | ||
281 | |||
282 | case PP_BLOCK_SYS_MC: | ||
283 | if (PP_STATE_SUPPORT_CG & *msg_id) { | ||
284 | msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ? | ||
285 | PPSMC_MSG_EnableClockGatingFeature : | ||
286 | PPSMC_MSG_DisableClockGatingFeature; | ||
287 | value = CG_SYS_MC_MGCG_MASK; | ||
288 | |||
289 | if (smum_send_msg_to_smc_with_parameter( | ||
290 | hwmgr->smumgr, msg, value)) | ||
291 | return -1; | ||
292 | } | ||
293 | |||
294 | if (PP_STATE_SUPPORT_LS & *msg_id) { | ||
295 | msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ? | ||
296 | PPSMC_MSG_EnableClockGatingFeature : | ||
297 | PPSMC_MSG_DisableClockGatingFeature; | ||
298 | value = CG_SYS_MC_MGLS_MASK; | ||
299 | |||
300 | if (smum_send_msg_to_smc_with_parameter( | ||
301 | hwmgr->smumgr, msg, value)) | ||
302 | return -1; | ||
303 | } | ||
304 | break; | ||
305 | |||
306 | case PP_BLOCK_SYS_DRM: | ||
307 | if (PP_STATE_SUPPORT_CG & *msg_id) { | ||
308 | msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ? | ||
309 | PPSMC_MSG_EnableClockGatingFeature : | ||
310 | PPSMC_MSG_DisableClockGatingFeature; | ||
311 | value = CG_SYS_DRM_MGCG_MASK; | ||
312 | |||
313 | if (smum_send_msg_to_smc_with_parameter( | ||
314 | hwmgr->smumgr, msg, value)) | ||
315 | return -1; | ||
316 | } | ||
317 | if (PP_STATE_SUPPORT_LS & *msg_id) { | ||
318 | msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ? | ||
319 | PPSMC_MSG_EnableClockGatingFeature : | ||
320 | PPSMC_MSG_DisableClockGatingFeature; | ||
321 | value = CG_SYS_DRM_MGLS_MASK; | ||
322 | |||
323 | if (smum_send_msg_to_smc_with_parameter( | ||
324 | hwmgr->smumgr, msg, value)) | ||
325 | return -1; | ||
326 | } | ||
327 | break; | ||
328 | |||
329 | case PP_BLOCK_SYS_HDP: | ||
330 | if (PP_STATE_SUPPORT_CG & *msg_id) { | ||
331 | msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ? | ||
332 | PPSMC_MSG_EnableClockGatingFeature : | ||
333 | PPSMC_MSG_DisableClockGatingFeature; | ||
334 | value = CG_SYS_HDP_MGCG_MASK; | ||
335 | |||
336 | if (smum_send_msg_to_smc_with_parameter( | ||
337 | hwmgr->smumgr, msg, value)) | ||
338 | return -1; | ||
339 | } | ||
340 | |||
341 | if (PP_STATE_SUPPORT_LS & *msg_id) { | ||
342 | msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ? | ||
343 | PPSMC_MSG_EnableClockGatingFeature : | ||
344 | PPSMC_MSG_DisableClockGatingFeature; | ||
345 | value = CG_SYS_HDP_MGLS_MASK; | ||
346 | |||
347 | if (smum_send_msg_to_smc_with_parameter( | ||
348 | hwmgr->smumgr, msg, value)) | ||
349 | return -1; | ||
350 | } | ||
351 | break; | ||
352 | |||
353 | case PP_BLOCK_SYS_SDMA: | ||
354 | if (PP_STATE_SUPPORT_CG & *msg_id) { | ||
355 | msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ? | ||
356 | PPSMC_MSG_EnableClockGatingFeature : | ||
357 | PPSMC_MSG_DisableClockGatingFeature; | ||
358 | value = CG_SYS_SDMA_MGCG_MASK; | ||
359 | |||
360 | if (smum_send_msg_to_smc_with_parameter( | ||
361 | hwmgr->smumgr, msg, value)) | ||
362 | return -1; | ||
363 | } | ||
364 | |||
365 | if (PP_STATE_SUPPORT_LS & *msg_id) { | ||
366 | msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ? | ||
367 | PPSMC_MSG_EnableClockGatingFeature : | ||
368 | PPSMC_MSG_DisableClockGatingFeature; | ||
369 | value = CG_SYS_SDMA_MGLS_MASK; | ||
370 | |||
371 | if (smum_send_msg_to_smc_with_parameter( | ||
372 | hwmgr->smumgr, msg, value)) | ||
373 | return -1; | ||
374 | } | ||
375 | break; | ||
376 | |||
377 | case PP_BLOCK_SYS_ROM: | ||
378 | if (PP_STATE_SUPPORT_CG & *msg_id) { | ||
379 | msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ? | ||
380 | PPSMC_MSG_EnableClockGatingFeature : | ||
381 | PPSMC_MSG_DisableClockGatingFeature; | ||
382 | value = CG_SYS_ROM_MASK; | ||
383 | |||
384 | if (smum_send_msg_to_smc_with_parameter( | ||
385 | hwmgr->smumgr, msg, value)) | ||
386 | return -1; | ||
387 | } | ||
388 | break; | ||
389 | |||
390 | default: | ||
391 | return -1; | ||
392 | |||
393 | } | ||
394 | break; | ||
395 | |||
396 | default: | ||
397 | return -1; | ||
398 | |||
399 | } | ||
400 | |||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | /* This function is for Polaris11 only for now, | ||
405 | * Powerplay will only control the static per CU Power Gating. | ||
406 | * Dynamic per CU Power Gating will be done in gfx. | ||
407 | */ | ||
408 | int polaris10_phm_enable_per_cu_power_gating(struct pp_hwmgr *hwmgr, bool enable) | ||
409 | { | ||
410 | struct cgs_system_info sys_info = {0}; | ||
411 | uint32_t active_cus; | ||
412 | int result; | ||
413 | |||
414 | sys_info.size = sizeof(struct cgs_system_info); | ||
415 | sys_info.info_id = CGS_SYSTEM_INFO_GFX_CU_INFO; | ||
416 | |||
417 | result = cgs_query_system_info(hwmgr->device, &sys_info); | ||
418 | |||
419 | if (result) | ||
420 | return -EINVAL; | ||
421 | else | ||
422 | active_cus = sys_info.value; | ||
423 | |||
424 | if (enable) | ||
425 | return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | ||
426 | PPSMC_MSG_GFX_CU_PG_ENABLE, active_cus); | ||
427 | else | ||
428 | return smum_send_msg_to_smc(hwmgr->smumgr, | ||
429 | PPSMC_MSG_GFX_CU_PG_DISABLE); | ||
430 | } | ||