Line data Source code
1 : /*
2 : * Copyright 2011 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 : * Authors: Alex Deucher
23 : */
24 :
25 : #include "amdgpu.h"
26 : #include "amdgpu_atombios.h"
27 : #include "amdgpu_i2c.h"
28 : #include "amdgpu_dpm.h"
29 : #include "atom.h"
30 : #include "amd_pcie.h"
31 : #include "amdgpu_display.h"
32 : #include "hwmgr.h"
33 : #include <linux/power_supply.h>
34 : #include "amdgpu_smu.h"
35 :
36 : #define amdgpu_dpm_enable_bapm(adev, e) \
37 : ((adev)->powerplay.pp_funcs->enable_bapm((adev)->powerplay.pp_handle, (e)))
38 :
39 0 : int amdgpu_dpm_get_sclk(struct amdgpu_device *adev, bool low)
40 : {
41 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
42 0 : int ret = 0;
43 :
44 0 : if (!pp_funcs->get_sclk)
45 : return 0;
46 :
47 0 : mutex_lock(&adev->pm.mutex);
48 0 : ret = pp_funcs->get_sclk((adev)->powerplay.pp_handle,
49 : low);
50 0 : mutex_unlock(&adev->pm.mutex);
51 :
52 0 : return ret;
53 : }
54 :
55 0 : int amdgpu_dpm_get_mclk(struct amdgpu_device *adev, bool low)
56 : {
57 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
58 0 : int ret = 0;
59 :
60 0 : if (!pp_funcs->get_mclk)
61 : return 0;
62 :
63 0 : mutex_lock(&adev->pm.mutex);
64 0 : ret = pp_funcs->get_mclk((adev)->powerplay.pp_handle,
65 : low);
66 0 : mutex_unlock(&adev->pm.mutex);
67 :
68 0 : return ret;
69 : }
70 :
71 0 : int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block_type, bool gate)
72 : {
73 0 : int ret = 0;
74 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
75 0 : enum ip_power_state pwr_state = gate ? POWER_STATE_OFF : POWER_STATE_ON;
76 :
77 0 : if (atomic_read(&adev->pm.pwr_state[block_type]) == pwr_state) {
78 : dev_dbg(adev->dev, "IP block%d already in the target %s state!",
79 : block_type, gate ? "gate" : "ungate");
80 : return 0;
81 : }
82 :
83 0 : mutex_lock(&adev->pm.mutex);
84 :
85 : switch (block_type) {
86 : case AMD_IP_BLOCK_TYPE_UVD:
87 : case AMD_IP_BLOCK_TYPE_VCE:
88 : case AMD_IP_BLOCK_TYPE_GFX:
89 : case AMD_IP_BLOCK_TYPE_VCN:
90 : case AMD_IP_BLOCK_TYPE_SDMA:
91 : case AMD_IP_BLOCK_TYPE_JPEG:
92 : case AMD_IP_BLOCK_TYPE_GMC:
93 : case AMD_IP_BLOCK_TYPE_ACP:
94 0 : if (pp_funcs && pp_funcs->set_powergating_by_smu)
95 0 : ret = (pp_funcs->set_powergating_by_smu(
96 : (adev)->powerplay.pp_handle, block_type, gate));
97 : break;
98 : default:
99 : break;
100 : }
101 :
102 0 : if (!ret)
103 0 : atomic_set(&adev->pm.pwr_state[block_type], pwr_state);
104 :
105 0 : mutex_unlock(&adev->pm.mutex);
106 :
107 0 : return ret;
108 : }
109 :
110 0 : int amdgpu_dpm_set_gfx_power_up_by_imu(struct amdgpu_device *adev)
111 : {
112 0 : struct smu_context *smu = adev->powerplay.pp_handle;
113 0 : int ret = -EOPNOTSUPP;
114 :
115 0 : mutex_lock(&adev->pm.mutex);
116 0 : ret = smu_set_gfx_power_up_by_imu(smu);
117 0 : mutex_unlock(&adev->pm.mutex);
118 :
119 0 : msleep(10);
120 :
121 0 : return ret;
122 : }
123 :
124 0 : int amdgpu_dpm_baco_enter(struct amdgpu_device *adev)
125 : {
126 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
127 0 : void *pp_handle = adev->powerplay.pp_handle;
128 0 : int ret = 0;
129 :
130 0 : if (!pp_funcs || !pp_funcs->set_asic_baco_state)
131 : return -ENOENT;
132 :
133 0 : mutex_lock(&adev->pm.mutex);
134 :
135 : /* enter BACO state */
136 0 : ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
137 :
138 0 : mutex_unlock(&adev->pm.mutex);
139 :
140 0 : return ret;
141 : }
142 :
143 0 : int amdgpu_dpm_baco_exit(struct amdgpu_device *adev)
144 : {
145 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
146 0 : void *pp_handle = adev->powerplay.pp_handle;
147 0 : int ret = 0;
148 :
149 0 : if (!pp_funcs || !pp_funcs->set_asic_baco_state)
150 : return -ENOENT;
151 :
152 0 : mutex_lock(&adev->pm.mutex);
153 :
154 : /* exit BACO state */
155 0 : ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
156 :
157 0 : mutex_unlock(&adev->pm.mutex);
158 :
159 0 : return ret;
160 : }
161 :
162 0 : int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
163 : enum pp_mp1_state mp1_state)
164 : {
165 0 : int ret = 0;
166 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
167 :
168 0 : if (pp_funcs && pp_funcs->set_mp1_state) {
169 0 : mutex_lock(&adev->pm.mutex);
170 :
171 0 : ret = pp_funcs->set_mp1_state(
172 : adev->powerplay.pp_handle,
173 : mp1_state);
174 :
175 0 : mutex_unlock(&adev->pm.mutex);
176 : }
177 :
178 0 : return ret;
179 : }
180 :
181 0 : bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev)
182 : {
183 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
184 0 : void *pp_handle = adev->powerplay.pp_handle;
185 : bool baco_cap;
186 0 : int ret = 0;
187 :
188 0 : if (!pp_funcs || !pp_funcs->get_asic_baco_capability)
189 : return false;
190 : /* Don't use baco for reset in S3.
191 : * This is a workaround for some platforms
192 : * where entering BACO during suspend
193 : * seems to cause reboots or hangs.
194 : * This might be related to the fact that BACO controls
195 : * power to the whole GPU including devices like audio and USB.
196 : * Powering down/up everything may adversely affect these other
197 : * devices. Needs more investigation.
198 : */
199 0 : if (adev->in_s3)
200 : return false;
201 :
202 0 : mutex_lock(&adev->pm.mutex);
203 :
204 0 : ret = pp_funcs->get_asic_baco_capability(pp_handle,
205 : &baco_cap);
206 :
207 0 : mutex_unlock(&adev->pm.mutex);
208 :
209 0 : return ret ? false : baco_cap;
210 : }
211 :
212 0 : int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev)
213 : {
214 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
215 0 : void *pp_handle = adev->powerplay.pp_handle;
216 0 : int ret = 0;
217 :
218 0 : if (!pp_funcs || !pp_funcs->asic_reset_mode_2)
219 : return -ENOENT;
220 :
221 0 : mutex_lock(&adev->pm.mutex);
222 :
223 0 : ret = pp_funcs->asic_reset_mode_2(pp_handle);
224 :
225 0 : mutex_unlock(&adev->pm.mutex);
226 :
227 0 : return ret;
228 : }
229 :
230 0 : int amdgpu_dpm_baco_reset(struct amdgpu_device *adev)
231 : {
232 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
233 0 : void *pp_handle = adev->powerplay.pp_handle;
234 0 : int ret = 0;
235 :
236 0 : if (!pp_funcs || !pp_funcs->set_asic_baco_state)
237 : return -ENOENT;
238 :
239 0 : mutex_lock(&adev->pm.mutex);
240 :
241 : /* enter BACO state */
242 0 : ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
243 0 : if (ret)
244 : goto out;
245 :
246 : /* exit BACO state */
247 0 : ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
248 :
249 : out:
250 0 : mutex_unlock(&adev->pm.mutex);
251 0 : return ret;
252 : }
253 :
254 0 : bool amdgpu_dpm_is_mode1_reset_supported(struct amdgpu_device *adev)
255 : {
256 0 : struct smu_context *smu = adev->powerplay.pp_handle;
257 0 : bool support_mode1_reset = false;
258 :
259 0 : if (is_support_sw_smu(adev)) {
260 0 : mutex_lock(&adev->pm.mutex);
261 0 : support_mode1_reset = smu_mode1_reset_is_support(smu);
262 0 : mutex_unlock(&adev->pm.mutex);
263 : }
264 :
265 0 : return support_mode1_reset;
266 : }
267 :
268 0 : int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev)
269 : {
270 0 : struct smu_context *smu = adev->powerplay.pp_handle;
271 0 : int ret = -EOPNOTSUPP;
272 :
273 0 : if (is_support_sw_smu(adev)) {
274 0 : mutex_lock(&adev->pm.mutex);
275 0 : ret = smu_mode1_reset(smu);
276 0 : mutex_unlock(&adev->pm.mutex);
277 : }
278 :
279 0 : return ret;
280 : }
281 :
282 0 : int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
283 : enum PP_SMC_POWER_PROFILE type,
284 : bool en)
285 : {
286 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
287 0 : int ret = 0;
288 :
289 0 : if (amdgpu_sriov_vf(adev))
290 : return 0;
291 :
292 0 : if (pp_funcs && pp_funcs->switch_power_profile) {
293 0 : mutex_lock(&adev->pm.mutex);
294 0 : ret = pp_funcs->switch_power_profile(
295 : adev->powerplay.pp_handle, type, en);
296 0 : mutex_unlock(&adev->pm.mutex);
297 : }
298 :
299 : return ret;
300 : }
301 :
302 0 : int amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device *adev,
303 : uint32_t pstate)
304 : {
305 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
306 0 : int ret = 0;
307 :
308 0 : if (pp_funcs && pp_funcs->set_xgmi_pstate) {
309 0 : mutex_lock(&adev->pm.mutex);
310 0 : ret = pp_funcs->set_xgmi_pstate(adev->powerplay.pp_handle,
311 : pstate);
312 0 : mutex_unlock(&adev->pm.mutex);
313 : }
314 :
315 0 : return ret;
316 : }
317 :
318 0 : int amdgpu_dpm_set_df_cstate(struct amdgpu_device *adev,
319 : uint32_t cstate)
320 : {
321 0 : int ret = 0;
322 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
323 0 : void *pp_handle = adev->powerplay.pp_handle;
324 :
325 0 : if (pp_funcs && pp_funcs->set_df_cstate) {
326 0 : mutex_lock(&adev->pm.mutex);
327 0 : ret = pp_funcs->set_df_cstate(pp_handle, cstate);
328 0 : mutex_unlock(&adev->pm.mutex);
329 : }
330 :
331 0 : return ret;
332 : }
333 :
334 0 : int amdgpu_dpm_allow_xgmi_power_down(struct amdgpu_device *adev, bool en)
335 : {
336 0 : struct smu_context *smu = adev->powerplay.pp_handle;
337 0 : int ret = 0;
338 :
339 0 : if (is_support_sw_smu(adev)) {
340 0 : mutex_lock(&adev->pm.mutex);
341 0 : ret = smu_allow_xgmi_power_down(smu, en);
342 0 : mutex_unlock(&adev->pm.mutex);
343 : }
344 :
345 0 : return ret;
346 : }
347 :
348 0 : int amdgpu_dpm_enable_mgpu_fan_boost(struct amdgpu_device *adev)
349 : {
350 0 : void *pp_handle = adev->powerplay.pp_handle;
351 0 : const struct amd_pm_funcs *pp_funcs =
352 : adev->powerplay.pp_funcs;
353 0 : int ret = 0;
354 :
355 0 : if (pp_funcs && pp_funcs->enable_mgpu_fan_boost) {
356 0 : mutex_lock(&adev->pm.mutex);
357 0 : ret = pp_funcs->enable_mgpu_fan_boost(pp_handle);
358 0 : mutex_unlock(&adev->pm.mutex);
359 : }
360 :
361 0 : return ret;
362 : }
363 :
364 0 : int amdgpu_dpm_set_clockgating_by_smu(struct amdgpu_device *adev,
365 : uint32_t msg_id)
366 : {
367 0 : void *pp_handle = adev->powerplay.pp_handle;
368 0 : const struct amd_pm_funcs *pp_funcs =
369 : adev->powerplay.pp_funcs;
370 0 : int ret = 0;
371 :
372 0 : if (pp_funcs && pp_funcs->set_clockgating_by_smu) {
373 0 : mutex_lock(&adev->pm.mutex);
374 0 : ret = pp_funcs->set_clockgating_by_smu(pp_handle,
375 : msg_id);
376 0 : mutex_unlock(&adev->pm.mutex);
377 : }
378 :
379 0 : return ret;
380 : }
381 :
382 0 : int amdgpu_dpm_smu_i2c_bus_access(struct amdgpu_device *adev,
383 : bool acquire)
384 : {
385 0 : void *pp_handle = adev->powerplay.pp_handle;
386 0 : const struct amd_pm_funcs *pp_funcs =
387 : adev->powerplay.pp_funcs;
388 0 : int ret = -EOPNOTSUPP;
389 :
390 0 : if (pp_funcs && pp_funcs->smu_i2c_bus_access) {
391 0 : mutex_lock(&adev->pm.mutex);
392 0 : ret = pp_funcs->smu_i2c_bus_access(pp_handle,
393 : acquire);
394 0 : mutex_unlock(&adev->pm.mutex);
395 : }
396 :
397 0 : return ret;
398 : }
399 :
400 0 : void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev)
401 : {
402 0 : if (adev->pm.dpm_enabled) {
403 0 : mutex_lock(&adev->pm.mutex);
404 0 : if (power_supply_is_system_supplied() > 0)
405 0 : adev->pm.ac_power = true;
406 : else
407 0 : adev->pm.ac_power = false;
408 :
409 0 : if (adev->powerplay.pp_funcs &&
410 0 : adev->powerplay.pp_funcs->enable_bapm)
411 0 : amdgpu_dpm_enable_bapm(adev, adev->pm.ac_power);
412 :
413 0 : if (is_support_sw_smu(adev))
414 0 : smu_set_ac_dc(adev->powerplay.pp_handle);
415 :
416 0 : mutex_unlock(&adev->pm.mutex);
417 : }
418 0 : }
419 :
420 0 : int amdgpu_dpm_read_sensor(struct amdgpu_device *adev, enum amd_pp_sensors sensor,
421 : void *data, uint32_t *size)
422 : {
423 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
424 0 : int ret = -EINVAL;
425 :
426 0 : if (!data || !size)
427 : return -EINVAL;
428 :
429 0 : if (pp_funcs && pp_funcs->read_sensor) {
430 0 : mutex_lock(&adev->pm.mutex);
431 0 : ret = pp_funcs->read_sensor(adev->powerplay.pp_handle,
432 : sensor,
433 : data,
434 : size);
435 0 : mutex_unlock(&adev->pm.mutex);
436 : }
437 :
438 : return ret;
439 : }
440 :
441 0 : void amdgpu_dpm_compute_clocks(struct amdgpu_device *adev)
442 : {
443 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
444 : int i;
445 :
446 0 : if (!adev->pm.dpm_enabled)
447 : return;
448 :
449 0 : if (!pp_funcs->pm_compute_clocks)
450 : return;
451 :
452 0 : if (adev->mode_info.num_crtc)
453 0 : amdgpu_display_bandwidth_update(adev);
454 :
455 0 : for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
456 0 : struct amdgpu_ring *ring = adev->rings[i];
457 0 : if (ring && ring->sched.ready)
458 0 : amdgpu_fence_wait_empty(ring);
459 : }
460 :
461 0 : mutex_lock(&adev->pm.mutex);
462 0 : pp_funcs->pm_compute_clocks(adev->powerplay.pp_handle);
463 0 : mutex_unlock(&adev->pm.mutex);
464 : }
465 :
466 0 : void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
467 : {
468 0 : int ret = 0;
469 :
470 0 : if (adev->family == AMDGPU_FAMILY_SI) {
471 0 : mutex_lock(&adev->pm.mutex);
472 0 : if (enable) {
473 0 : adev->pm.dpm.uvd_active = true;
474 0 : adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
475 : } else {
476 0 : adev->pm.dpm.uvd_active = false;
477 : }
478 0 : mutex_unlock(&adev->pm.mutex);
479 :
480 0 : amdgpu_dpm_compute_clocks(adev);
481 0 : return;
482 : }
483 :
484 0 : ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable);
485 0 : if (ret)
486 0 : DRM_ERROR("Dpm %s uvd failed, ret = %d. \n",
487 : enable ? "enable" : "disable", ret);
488 : }
489 :
490 0 : void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
491 : {
492 0 : int ret = 0;
493 :
494 0 : if (adev->family == AMDGPU_FAMILY_SI) {
495 0 : mutex_lock(&adev->pm.mutex);
496 0 : if (enable) {
497 0 : adev->pm.dpm.vce_active = true;
498 : /* XXX select vce level based on ring/task */
499 0 : adev->pm.dpm.vce_level = AMD_VCE_LEVEL_AC_ALL;
500 : } else {
501 0 : adev->pm.dpm.vce_active = false;
502 : }
503 0 : mutex_unlock(&adev->pm.mutex);
504 :
505 0 : amdgpu_dpm_compute_clocks(adev);
506 0 : return;
507 : }
508 :
509 0 : ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable);
510 0 : if (ret)
511 0 : DRM_ERROR("Dpm %s vce failed, ret = %d. \n",
512 : enable ? "enable" : "disable", ret);
513 : }
514 :
515 0 : void amdgpu_dpm_enable_jpeg(struct amdgpu_device *adev, bool enable)
516 : {
517 0 : int ret = 0;
518 :
519 0 : ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_JPEG, !enable);
520 0 : if (ret)
521 0 : DRM_ERROR("Dpm %s jpeg failed, ret = %d. \n",
522 : enable ? "enable" : "disable", ret);
523 0 : }
524 :
525 0 : int amdgpu_pm_load_smu_firmware(struct amdgpu_device *adev, uint32_t *smu_version)
526 : {
527 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
528 0 : int r = 0;
529 :
530 0 : if (!pp_funcs || !pp_funcs->load_firmware)
531 : return 0;
532 :
533 0 : mutex_lock(&adev->pm.mutex);
534 0 : r = pp_funcs->load_firmware(adev->powerplay.pp_handle);
535 0 : if (r) {
536 0 : pr_err("smu firmware loading failed\n");
537 0 : goto out;
538 : }
539 :
540 0 : if (smu_version)
541 0 : *smu_version = adev->pm.fw_version;
542 :
543 : out:
544 0 : mutex_unlock(&adev->pm.mutex);
545 0 : return r;
546 : }
547 :
548 0 : int amdgpu_dpm_handle_passthrough_sbr(struct amdgpu_device *adev, bool enable)
549 : {
550 0 : int ret = 0;
551 :
552 0 : if (is_support_sw_smu(adev)) {
553 0 : mutex_lock(&adev->pm.mutex);
554 0 : ret = smu_handle_passthrough_sbr(adev->powerplay.pp_handle,
555 : enable);
556 0 : mutex_unlock(&adev->pm.mutex);
557 : }
558 :
559 0 : return ret;
560 : }
561 :
562 0 : int amdgpu_dpm_send_hbm_bad_pages_num(struct amdgpu_device *adev, uint32_t size)
563 : {
564 0 : struct smu_context *smu = adev->powerplay.pp_handle;
565 0 : int ret = 0;
566 :
567 0 : if (!is_support_sw_smu(adev))
568 : return -EOPNOTSUPP;
569 :
570 0 : mutex_lock(&adev->pm.mutex);
571 0 : ret = smu_send_hbm_bad_pages_num(smu, size);
572 0 : mutex_unlock(&adev->pm.mutex);
573 :
574 0 : return ret;
575 : }
576 :
577 0 : int amdgpu_dpm_send_hbm_bad_channel_flag(struct amdgpu_device *adev, uint32_t size)
578 : {
579 0 : struct smu_context *smu = adev->powerplay.pp_handle;
580 0 : int ret = 0;
581 :
582 0 : if (!is_support_sw_smu(adev))
583 : return -EOPNOTSUPP;
584 :
585 0 : mutex_lock(&adev->pm.mutex);
586 0 : ret = smu_send_hbm_bad_channel_flag(smu, size);
587 0 : mutex_unlock(&adev->pm.mutex);
588 :
589 0 : return ret;
590 : }
591 :
592 0 : int amdgpu_dpm_get_dpm_freq_range(struct amdgpu_device *adev,
593 : enum pp_clock_type type,
594 : uint32_t *min,
595 : uint32_t *max)
596 : {
597 0 : int ret = 0;
598 :
599 0 : if (type != PP_SCLK)
600 : return -EINVAL;
601 :
602 0 : if (!is_support_sw_smu(adev))
603 : return -EOPNOTSUPP;
604 :
605 0 : mutex_lock(&adev->pm.mutex);
606 0 : ret = smu_get_dpm_freq_range(adev->powerplay.pp_handle,
607 : SMU_SCLK,
608 : min,
609 : max);
610 0 : mutex_unlock(&adev->pm.mutex);
611 :
612 0 : return ret;
613 : }
614 :
615 0 : int amdgpu_dpm_set_soft_freq_range(struct amdgpu_device *adev,
616 : enum pp_clock_type type,
617 : uint32_t min,
618 : uint32_t max)
619 : {
620 0 : struct smu_context *smu = adev->powerplay.pp_handle;
621 0 : int ret = 0;
622 :
623 0 : if (type != PP_SCLK)
624 : return -EINVAL;
625 :
626 0 : if (!is_support_sw_smu(adev))
627 : return -EOPNOTSUPP;
628 :
629 0 : mutex_lock(&adev->pm.mutex);
630 0 : ret = smu_set_soft_freq_range(smu,
631 : SMU_SCLK,
632 : min,
633 : max);
634 0 : mutex_unlock(&adev->pm.mutex);
635 :
636 0 : return ret;
637 : }
638 :
639 0 : int amdgpu_dpm_write_watermarks_table(struct amdgpu_device *adev)
640 : {
641 0 : struct smu_context *smu = adev->powerplay.pp_handle;
642 0 : int ret = 0;
643 :
644 0 : if (!is_support_sw_smu(adev))
645 : return 0;
646 :
647 0 : mutex_lock(&adev->pm.mutex);
648 0 : ret = smu_write_watermarks_table(smu);
649 0 : mutex_unlock(&adev->pm.mutex);
650 :
651 0 : return ret;
652 : }
653 :
654 0 : int amdgpu_dpm_wait_for_event(struct amdgpu_device *adev,
655 : enum smu_event_type event,
656 : uint64_t event_arg)
657 : {
658 0 : struct smu_context *smu = adev->powerplay.pp_handle;
659 0 : int ret = 0;
660 :
661 0 : if (!is_support_sw_smu(adev))
662 : return -EOPNOTSUPP;
663 :
664 0 : mutex_lock(&adev->pm.mutex);
665 0 : ret = smu_wait_for_event(smu, event, event_arg);
666 0 : mutex_unlock(&adev->pm.mutex);
667 :
668 0 : return ret;
669 : }
670 :
671 0 : int amdgpu_dpm_set_residency_gfxoff(struct amdgpu_device *adev, bool value)
672 : {
673 0 : struct smu_context *smu = adev->powerplay.pp_handle;
674 0 : int ret = 0;
675 :
676 0 : if (!is_support_sw_smu(adev))
677 : return -EOPNOTSUPP;
678 :
679 0 : mutex_lock(&adev->pm.mutex);
680 0 : ret = smu_set_residency_gfxoff(smu, value);
681 0 : mutex_unlock(&adev->pm.mutex);
682 :
683 0 : return ret;
684 : }
685 :
686 0 : int amdgpu_dpm_get_residency_gfxoff(struct amdgpu_device *adev, u32 *value)
687 : {
688 0 : struct smu_context *smu = adev->powerplay.pp_handle;
689 0 : int ret = 0;
690 :
691 0 : if (!is_support_sw_smu(adev))
692 : return -EOPNOTSUPP;
693 :
694 0 : mutex_lock(&adev->pm.mutex);
695 0 : ret = smu_get_residency_gfxoff(smu, value);
696 0 : mutex_unlock(&adev->pm.mutex);
697 :
698 0 : return ret;
699 : }
700 :
701 0 : int amdgpu_dpm_get_entrycount_gfxoff(struct amdgpu_device *adev, u64 *value)
702 : {
703 0 : struct smu_context *smu = adev->powerplay.pp_handle;
704 0 : int ret = 0;
705 :
706 0 : if (!is_support_sw_smu(adev))
707 : return -EOPNOTSUPP;
708 :
709 0 : mutex_lock(&adev->pm.mutex);
710 0 : ret = smu_get_entrycount_gfxoff(smu, value);
711 0 : mutex_unlock(&adev->pm.mutex);
712 :
713 0 : return ret;
714 : }
715 :
716 0 : int amdgpu_dpm_get_status_gfxoff(struct amdgpu_device *adev, uint32_t *value)
717 : {
718 0 : struct smu_context *smu = adev->powerplay.pp_handle;
719 0 : int ret = 0;
720 :
721 0 : if (!is_support_sw_smu(adev))
722 : return -EOPNOTSUPP;
723 :
724 0 : mutex_lock(&adev->pm.mutex);
725 0 : ret = smu_get_status_gfxoff(smu, value);
726 0 : mutex_unlock(&adev->pm.mutex);
727 :
728 0 : return ret;
729 : }
730 :
731 0 : uint64_t amdgpu_dpm_get_thermal_throttling_counter(struct amdgpu_device *adev)
732 : {
733 0 : struct smu_context *smu = adev->powerplay.pp_handle;
734 :
735 0 : if (!is_support_sw_smu(adev))
736 : return 0;
737 :
738 0 : return atomic64_read(&smu->throttle_int_counter);
739 : }
740 :
741 : /* amdgpu_dpm_gfx_state_change - Handle gfx power state change set
742 : * @adev: amdgpu_device pointer
743 : * @state: gfx power state(1 -sGpuChangeState_D0Entry and 2 -sGpuChangeState_D3Entry)
744 : *
745 : */
746 0 : void amdgpu_dpm_gfx_state_change(struct amdgpu_device *adev,
747 : enum gfx_change_state state)
748 : {
749 0 : mutex_lock(&adev->pm.mutex);
750 0 : if (adev->powerplay.pp_funcs &&
751 0 : adev->powerplay.pp_funcs->gfx_state_change_set)
752 0 : ((adev)->powerplay.pp_funcs->gfx_state_change_set(
753 : (adev)->powerplay.pp_handle, state));
754 0 : mutex_unlock(&adev->pm.mutex);
755 0 : }
756 :
757 0 : int amdgpu_dpm_get_ecc_info(struct amdgpu_device *adev,
758 : void *umc_ecc)
759 : {
760 0 : struct smu_context *smu = adev->powerplay.pp_handle;
761 0 : int ret = 0;
762 :
763 0 : if (!is_support_sw_smu(adev))
764 : return -EOPNOTSUPP;
765 :
766 0 : mutex_lock(&adev->pm.mutex);
767 0 : ret = smu_get_ecc_info(smu, umc_ecc);
768 0 : mutex_unlock(&adev->pm.mutex);
769 :
770 0 : return ret;
771 : }
772 :
773 0 : struct amd_vce_state *amdgpu_dpm_get_vce_clock_state(struct amdgpu_device *adev,
774 : uint32_t idx)
775 : {
776 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
777 0 : struct amd_vce_state *vstate = NULL;
778 :
779 0 : if (!pp_funcs->get_vce_clock_state)
780 : return NULL;
781 :
782 0 : mutex_lock(&adev->pm.mutex);
783 0 : vstate = pp_funcs->get_vce_clock_state(adev->powerplay.pp_handle,
784 : idx);
785 0 : mutex_unlock(&adev->pm.mutex);
786 :
787 0 : return vstate;
788 : }
789 :
790 0 : void amdgpu_dpm_get_current_power_state(struct amdgpu_device *adev,
791 : enum amd_pm_state_type *state)
792 : {
793 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
794 :
795 0 : mutex_lock(&adev->pm.mutex);
796 :
797 0 : if (!pp_funcs->get_current_power_state) {
798 0 : *state = adev->pm.dpm.user_state;
799 0 : goto out;
800 : }
801 :
802 0 : *state = pp_funcs->get_current_power_state(adev->powerplay.pp_handle);
803 0 : if (*state < POWER_STATE_TYPE_DEFAULT ||
804 : *state > POWER_STATE_TYPE_INTERNAL_3DPERF)
805 0 : *state = adev->pm.dpm.user_state;
806 :
807 : out:
808 0 : mutex_unlock(&adev->pm.mutex);
809 0 : }
810 :
811 0 : void amdgpu_dpm_set_power_state(struct amdgpu_device *adev,
812 : enum amd_pm_state_type state)
813 : {
814 0 : mutex_lock(&adev->pm.mutex);
815 0 : adev->pm.dpm.user_state = state;
816 0 : mutex_unlock(&adev->pm.mutex);
817 :
818 0 : if (is_support_sw_smu(adev))
819 : return;
820 :
821 0 : if (amdgpu_dpm_dispatch_task(adev,
822 : AMD_PP_TASK_ENABLE_USER_STATE,
823 : &state) == -EOPNOTSUPP)
824 0 : amdgpu_dpm_compute_clocks(adev);
825 : }
826 :
827 0 : enum amd_dpm_forced_level amdgpu_dpm_get_performance_level(struct amdgpu_device *adev)
828 : {
829 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
830 : enum amd_dpm_forced_level level;
831 :
832 0 : if (!pp_funcs)
833 : return AMD_DPM_FORCED_LEVEL_AUTO;
834 :
835 0 : mutex_lock(&adev->pm.mutex);
836 0 : if (pp_funcs->get_performance_level)
837 0 : level = pp_funcs->get_performance_level(adev->powerplay.pp_handle);
838 : else
839 0 : level = adev->pm.dpm.forced_level;
840 0 : mutex_unlock(&adev->pm.mutex);
841 :
842 0 : return level;
843 : }
844 :
845 0 : int amdgpu_dpm_force_performance_level(struct amdgpu_device *adev,
846 : enum amd_dpm_forced_level level)
847 : {
848 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
849 : enum amd_dpm_forced_level current_level;
850 0 : uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
851 : AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
852 : AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
853 : AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
854 :
855 0 : if (!pp_funcs || !pp_funcs->force_performance_level)
856 : return 0;
857 :
858 0 : if (adev->pm.dpm.thermal_active)
859 : return -EINVAL;
860 :
861 0 : current_level = amdgpu_dpm_get_performance_level(adev);
862 0 : if (current_level == level)
863 : return 0;
864 :
865 0 : if (adev->asic_type == CHIP_RAVEN) {
866 0 : if (!(adev->apu_flags & AMD_APU_IS_RAVEN2)) {
867 0 : if (current_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
868 0 : level == AMD_DPM_FORCED_LEVEL_MANUAL)
869 0 : amdgpu_gfx_off_ctrl(adev, false);
870 0 : else if (current_level == AMD_DPM_FORCED_LEVEL_MANUAL &&
871 0 : level != AMD_DPM_FORCED_LEVEL_MANUAL)
872 0 : amdgpu_gfx_off_ctrl(adev, true);
873 : }
874 : }
875 :
876 0 : if (!(current_level & profile_mode_mask) &&
877 : (level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT))
878 : return -EINVAL;
879 :
880 0 : if (!(current_level & profile_mode_mask) &&
881 0 : (level & profile_mode_mask)) {
882 : /* enter UMD Pstate */
883 0 : amdgpu_device_ip_set_powergating_state(adev,
884 : AMD_IP_BLOCK_TYPE_GFX,
885 : AMD_PG_STATE_UNGATE);
886 0 : amdgpu_device_ip_set_clockgating_state(adev,
887 : AMD_IP_BLOCK_TYPE_GFX,
888 : AMD_CG_STATE_UNGATE);
889 0 : } else if ((current_level & profile_mode_mask) &&
890 0 : !(level & profile_mode_mask)) {
891 : /* exit UMD Pstate */
892 0 : amdgpu_device_ip_set_clockgating_state(adev,
893 : AMD_IP_BLOCK_TYPE_GFX,
894 : AMD_CG_STATE_GATE);
895 0 : amdgpu_device_ip_set_powergating_state(adev,
896 : AMD_IP_BLOCK_TYPE_GFX,
897 : AMD_PG_STATE_GATE);
898 : }
899 :
900 0 : mutex_lock(&adev->pm.mutex);
901 :
902 0 : if (pp_funcs->force_performance_level(adev->powerplay.pp_handle,
903 : level)) {
904 0 : mutex_unlock(&adev->pm.mutex);
905 0 : return -EINVAL;
906 : }
907 :
908 0 : adev->pm.dpm.forced_level = level;
909 :
910 0 : mutex_unlock(&adev->pm.mutex);
911 :
912 0 : return 0;
913 : }
914 :
915 0 : int amdgpu_dpm_get_pp_num_states(struct amdgpu_device *adev,
916 : struct pp_states_info *states)
917 : {
918 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
919 0 : int ret = 0;
920 :
921 0 : if (!pp_funcs->get_pp_num_states)
922 : return -EOPNOTSUPP;
923 :
924 0 : mutex_lock(&adev->pm.mutex);
925 0 : ret = pp_funcs->get_pp_num_states(adev->powerplay.pp_handle,
926 : states);
927 0 : mutex_unlock(&adev->pm.mutex);
928 :
929 0 : return ret;
930 : }
931 :
932 0 : int amdgpu_dpm_dispatch_task(struct amdgpu_device *adev,
933 : enum amd_pp_task task_id,
934 : enum amd_pm_state_type *user_state)
935 : {
936 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
937 0 : int ret = 0;
938 :
939 0 : if (!pp_funcs->dispatch_tasks)
940 : return -EOPNOTSUPP;
941 :
942 0 : mutex_lock(&adev->pm.mutex);
943 0 : ret = pp_funcs->dispatch_tasks(adev->powerplay.pp_handle,
944 : task_id,
945 : user_state);
946 0 : mutex_unlock(&adev->pm.mutex);
947 :
948 0 : return ret;
949 : }
950 :
951 0 : int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char **table)
952 : {
953 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
954 0 : int ret = 0;
955 :
956 0 : if (!pp_funcs->get_pp_table)
957 : return 0;
958 :
959 0 : mutex_lock(&adev->pm.mutex);
960 0 : ret = pp_funcs->get_pp_table(adev->powerplay.pp_handle,
961 : table);
962 0 : mutex_unlock(&adev->pm.mutex);
963 :
964 0 : return ret;
965 : }
966 :
967 0 : int amdgpu_dpm_set_fine_grain_clk_vol(struct amdgpu_device *adev,
968 : uint32_t type,
969 : long *input,
970 : uint32_t size)
971 : {
972 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
973 0 : int ret = 0;
974 :
975 0 : if (!pp_funcs->set_fine_grain_clk_vol)
976 : return 0;
977 :
978 0 : mutex_lock(&adev->pm.mutex);
979 0 : ret = pp_funcs->set_fine_grain_clk_vol(adev->powerplay.pp_handle,
980 : type,
981 : input,
982 : size);
983 0 : mutex_unlock(&adev->pm.mutex);
984 :
985 0 : return ret;
986 : }
987 :
988 0 : int amdgpu_dpm_odn_edit_dpm_table(struct amdgpu_device *adev,
989 : uint32_t type,
990 : long *input,
991 : uint32_t size)
992 : {
993 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
994 0 : int ret = 0;
995 :
996 0 : if (!pp_funcs->odn_edit_dpm_table)
997 : return 0;
998 :
999 0 : mutex_lock(&adev->pm.mutex);
1000 0 : ret = pp_funcs->odn_edit_dpm_table(adev->powerplay.pp_handle,
1001 : type,
1002 : input,
1003 : size);
1004 0 : mutex_unlock(&adev->pm.mutex);
1005 :
1006 0 : return ret;
1007 : }
1008 :
1009 0 : int amdgpu_dpm_print_clock_levels(struct amdgpu_device *adev,
1010 : enum pp_clock_type type,
1011 : char *buf)
1012 : {
1013 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1014 0 : int ret = 0;
1015 :
1016 0 : if (!pp_funcs->print_clock_levels)
1017 : return 0;
1018 :
1019 0 : mutex_lock(&adev->pm.mutex);
1020 0 : ret = pp_funcs->print_clock_levels(adev->powerplay.pp_handle,
1021 : type,
1022 : buf);
1023 0 : mutex_unlock(&adev->pm.mutex);
1024 :
1025 0 : return ret;
1026 : }
1027 :
1028 0 : int amdgpu_dpm_emit_clock_levels(struct amdgpu_device *adev,
1029 : enum pp_clock_type type,
1030 : char *buf,
1031 : int *offset)
1032 : {
1033 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1034 0 : int ret = 0;
1035 :
1036 0 : if (!pp_funcs->emit_clock_levels)
1037 : return -ENOENT;
1038 :
1039 0 : mutex_lock(&adev->pm.mutex);
1040 0 : ret = pp_funcs->emit_clock_levels(adev->powerplay.pp_handle,
1041 : type,
1042 : buf,
1043 : offset);
1044 0 : mutex_unlock(&adev->pm.mutex);
1045 :
1046 0 : return ret;
1047 : }
1048 :
1049 0 : int amdgpu_dpm_set_ppfeature_status(struct amdgpu_device *adev,
1050 : uint64_t ppfeature_masks)
1051 : {
1052 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1053 0 : int ret = 0;
1054 :
1055 0 : if (!pp_funcs->set_ppfeature_status)
1056 : return 0;
1057 :
1058 0 : mutex_lock(&adev->pm.mutex);
1059 0 : ret = pp_funcs->set_ppfeature_status(adev->powerplay.pp_handle,
1060 : ppfeature_masks);
1061 0 : mutex_unlock(&adev->pm.mutex);
1062 :
1063 0 : return ret;
1064 : }
1065 :
1066 0 : int amdgpu_dpm_get_ppfeature_status(struct amdgpu_device *adev, char *buf)
1067 : {
1068 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1069 0 : int ret = 0;
1070 :
1071 0 : if (!pp_funcs->get_ppfeature_status)
1072 : return 0;
1073 :
1074 0 : mutex_lock(&adev->pm.mutex);
1075 0 : ret = pp_funcs->get_ppfeature_status(adev->powerplay.pp_handle,
1076 : buf);
1077 0 : mutex_unlock(&adev->pm.mutex);
1078 :
1079 0 : return ret;
1080 : }
1081 :
1082 0 : int amdgpu_dpm_force_clock_level(struct amdgpu_device *adev,
1083 : enum pp_clock_type type,
1084 : uint32_t mask)
1085 : {
1086 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1087 0 : int ret = 0;
1088 :
1089 0 : if (!pp_funcs->force_clock_level)
1090 : return 0;
1091 :
1092 0 : mutex_lock(&adev->pm.mutex);
1093 0 : ret = pp_funcs->force_clock_level(adev->powerplay.pp_handle,
1094 : type,
1095 : mask);
1096 0 : mutex_unlock(&adev->pm.mutex);
1097 :
1098 0 : return ret;
1099 : }
1100 :
1101 0 : int amdgpu_dpm_get_sclk_od(struct amdgpu_device *adev)
1102 : {
1103 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1104 0 : int ret = 0;
1105 :
1106 0 : if (!pp_funcs->get_sclk_od)
1107 : return 0;
1108 :
1109 0 : mutex_lock(&adev->pm.mutex);
1110 0 : ret = pp_funcs->get_sclk_od(adev->powerplay.pp_handle);
1111 0 : mutex_unlock(&adev->pm.mutex);
1112 :
1113 0 : return ret;
1114 : }
1115 :
1116 0 : int amdgpu_dpm_set_sclk_od(struct amdgpu_device *adev, uint32_t value)
1117 : {
1118 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1119 :
1120 0 : if (is_support_sw_smu(adev))
1121 : return 0;
1122 :
1123 0 : mutex_lock(&adev->pm.mutex);
1124 0 : if (pp_funcs->set_sclk_od)
1125 0 : pp_funcs->set_sclk_od(adev->powerplay.pp_handle, value);
1126 0 : mutex_unlock(&adev->pm.mutex);
1127 :
1128 0 : if (amdgpu_dpm_dispatch_task(adev,
1129 : AMD_PP_TASK_READJUST_POWER_STATE,
1130 : NULL) == -EOPNOTSUPP) {
1131 0 : adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
1132 0 : amdgpu_dpm_compute_clocks(adev);
1133 : }
1134 :
1135 : return 0;
1136 : }
1137 :
1138 0 : int amdgpu_dpm_get_mclk_od(struct amdgpu_device *adev)
1139 : {
1140 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1141 0 : int ret = 0;
1142 :
1143 0 : if (!pp_funcs->get_mclk_od)
1144 : return 0;
1145 :
1146 0 : mutex_lock(&adev->pm.mutex);
1147 0 : ret = pp_funcs->get_mclk_od(adev->powerplay.pp_handle);
1148 0 : mutex_unlock(&adev->pm.mutex);
1149 :
1150 0 : return ret;
1151 : }
1152 :
1153 0 : int amdgpu_dpm_set_mclk_od(struct amdgpu_device *adev, uint32_t value)
1154 : {
1155 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1156 :
1157 0 : if (is_support_sw_smu(adev))
1158 : return 0;
1159 :
1160 0 : mutex_lock(&adev->pm.mutex);
1161 0 : if (pp_funcs->set_mclk_od)
1162 0 : pp_funcs->set_mclk_od(adev->powerplay.pp_handle, value);
1163 0 : mutex_unlock(&adev->pm.mutex);
1164 :
1165 0 : if (amdgpu_dpm_dispatch_task(adev,
1166 : AMD_PP_TASK_READJUST_POWER_STATE,
1167 : NULL) == -EOPNOTSUPP) {
1168 0 : adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
1169 0 : amdgpu_dpm_compute_clocks(adev);
1170 : }
1171 :
1172 : return 0;
1173 : }
1174 :
1175 0 : int amdgpu_dpm_get_power_profile_mode(struct amdgpu_device *adev,
1176 : char *buf)
1177 : {
1178 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1179 0 : int ret = 0;
1180 :
1181 0 : if (!pp_funcs->get_power_profile_mode)
1182 : return -EOPNOTSUPP;
1183 :
1184 0 : mutex_lock(&adev->pm.mutex);
1185 0 : ret = pp_funcs->get_power_profile_mode(adev->powerplay.pp_handle,
1186 : buf);
1187 0 : mutex_unlock(&adev->pm.mutex);
1188 :
1189 0 : return ret;
1190 : }
1191 :
1192 0 : int amdgpu_dpm_set_power_profile_mode(struct amdgpu_device *adev,
1193 : long *input, uint32_t size)
1194 : {
1195 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1196 0 : int ret = 0;
1197 :
1198 0 : if (!pp_funcs->set_power_profile_mode)
1199 : return 0;
1200 :
1201 0 : mutex_lock(&adev->pm.mutex);
1202 0 : ret = pp_funcs->set_power_profile_mode(adev->powerplay.pp_handle,
1203 : input,
1204 : size);
1205 0 : mutex_unlock(&adev->pm.mutex);
1206 :
1207 0 : return ret;
1208 : }
1209 :
1210 0 : int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void **table)
1211 : {
1212 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1213 0 : int ret = 0;
1214 :
1215 0 : if (!pp_funcs->get_gpu_metrics)
1216 : return 0;
1217 :
1218 0 : mutex_lock(&adev->pm.mutex);
1219 0 : ret = pp_funcs->get_gpu_metrics(adev->powerplay.pp_handle,
1220 : table);
1221 0 : mutex_unlock(&adev->pm.mutex);
1222 :
1223 0 : return ret;
1224 : }
1225 :
1226 0 : int amdgpu_dpm_get_fan_control_mode(struct amdgpu_device *adev,
1227 : uint32_t *fan_mode)
1228 : {
1229 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1230 0 : int ret = 0;
1231 :
1232 0 : if (!pp_funcs->get_fan_control_mode)
1233 : return -EOPNOTSUPP;
1234 :
1235 0 : mutex_lock(&adev->pm.mutex);
1236 0 : ret = pp_funcs->get_fan_control_mode(adev->powerplay.pp_handle,
1237 : fan_mode);
1238 0 : mutex_unlock(&adev->pm.mutex);
1239 :
1240 0 : return ret;
1241 : }
1242 :
1243 0 : int amdgpu_dpm_set_fan_speed_pwm(struct amdgpu_device *adev,
1244 : uint32_t speed)
1245 : {
1246 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1247 0 : int ret = 0;
1248 :
1249 0 : if (!pp_funcs->set_fan_speed_pwm)
1250 : return -EOPNOTSUPP;
1251 :
1252 0 : mutex_lock(&adev->pm.mutex);
1253 0 : ret = pp_funcs->set_fan_speed_pwm(adev->powerplay.pp_handle,
1254 : speed);
1255 0 : mutex_unlock(&adev->pm.mutex);
1256 :
1257 0 : return ret;
1258 : }
1259 :
1260 0 : int amdgpu_dpm_get_fan_speed_pwm(struct amdgpu_device *adev,
1261 : uint32_t *speed)
1262 : {
1263 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1264 0 : int ret = 0;
1265 :
1266 0 : if (!pp_funcs->get_fan_speed_pwm)
1267 : return -EOPNOTSUPP;
1268 :
1269 0 : mutex_lock(&adev->pm.mutex);
1270 0 : ret = pp_funcs->get_fan_speed_pwm(adev->powerplay.pp_handle,
1271 : speed);
1272 0 : mutex_unlock(&adev->pm.mutex);
1273 :
1274 0 : return ret;
1275 : }
1276 :
1277 0 : int amdgpu_dpm_get_fan_speed_rpm(struct amdgpu_device *adev,
1278 : uint32_t *speed)
1279 : {
1280 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1281 0 : int ret = 0;
1282 :
1283 0 : if (!pp_funcs->get_fan_speed_rpm)
1284 : return -EOPNOTSUPP;
1285 :
1286 0 : mutex_lock(&adev->pm.mutex);
1287 0 : ret = pp_funcs->get_fan_speed_rpm(adev->powerplay.pp_handle,
1288 : speed);
1289 0 : mutex_unlock(&adev->pm.mutex);
1290 :
1291 0 : return ret;
1292 : }
1293 :
1294 0 : int amdgpu_dpm_set_fan_speed_rpm(struct amdgpu_device *adev,
1295 : uint32_t speed)
1296 : {
1297 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1298 0 : int ret = 0;
1299 :
1300 0 : if (!pp_funcs->set_fan_speed_rpm)
1301 : return -EOPNOTSUPP;
1302 :
1303 0 : mutex_lock(&adev->pm.mutex);
1304 0 : ret = pp_funcs->set_fan_speed_rpm(adev->powerplay.pp_handle,
1305 : speed);
1306 0 : mutex_unlock(&adev->pm.mutex);
1307 :
1308 0 : return ret;
1309 : }
1310 :
1311 0 : int amdgpu_dpm_set_fan_control_mode(struct amdgpu_device *adev,
1312 : uint32_t mode)
1313 : {
1314 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1315 0 : int ret = 0;
1316 :
1317 0 : if (!pp_funcs->set_fan_control_mode)
1318 : return -EOPNOTSUPP;
1319 :
1320 0 : mutex_lock(&adev->pm.mutex);
1321 0 : ret = pp_funcs->set_fan_control_mode(adev->powerplay.pp_handle,
1322 : mode);
1323 0 : mutex_unlock(&adev->pm.mutex);
1324 :
1325 0 : return ret;
1326 : }
1327 :
1328 0 : int amdgpu_dpm_get_power_limit(struct amdgpu_device *adev,
1329 : uint32_t *limit,
1330 : enum pp_power_limit_level pp_limit_level,
1331 : enum pp_power_type power_type)
1332 : {
1333 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1334 0 : int ret = 0;
1335 :
1336 0 : if (!pp_funcs->get_power_limit)
1337 : return -ENODATA;
1338 :
1339 0 : mutex_lock(&adev->pm.mutex);
1340 0 : ret = pp_funcs->get_power_limit(adev->powerplay.pp_handle,
1341 : limit,
1342 : pp_limit_level,
1343 : power_type);
1344 0 : mutex_unlock(&adev->pm.mutex);
1345 :
1346 0 : return ret;
1347 : }
1348 :
1349 0 : int amdgpu_dpm_set_power_limit(struct amdgpu_device *adev,
1350 : uint32_t limit)
1351 : {
1352 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1353 0 : int ret = 0;
1354 :
1355 0 : if (!pp_funcs->set_power_limit)
1356 : return -EINVAL;
1357 :
1358 0 : mutex_lock(&adev->pm.mutex);
1359 0 : ret = pp_funcs->set_power_limit(adev->powerplay.pp_handle,
1360 : limit);
1361 0 : mutex_unlock(&adev->pm.mutex);
1362 :
1363 0 : return ret;
1364 : }
1365 :
1366 0 : int amdgpu_dpm_is_cclk_dpm_supported(struct amdgpu_device *adev)
1367 : {
1368 0 : bool cclk_dpm_supported = false;
1369 :
1370 0 : if (!is_support_sw_smu(adev))
1371 : return false;
1372 :
1373 0 : mutex_lock(&adev->pm.mutex);
1374 0 : cclk_dpm_supported = is_support_cclk_dpm(adev);
1375 0 : mutex_unlock(&adev->pm.mutex);
1376 :
1377 0 : return (int)cclk_dpm_supported;
1378 : }
1379 :
1380 0 : int amdgpu_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev,
1381 : struct seq_file *m)
1382 : {
1383 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1384 :
1385 0 : if (!pp_funcs->debugfs_print_current_performance_level)
1386 : return -EOPNOTSUPP;
1387 :
1388 0 : mutex_lock(&adev->pm.mutex);
1389 0 : pp_funcs->debugfs_print_current_performance_level(adev->powerplay.pp_handle,
1390 : m);
1391 0 : mutex_unlock(&adev->pm.mutex);
1392 :
1393 0 : return 0;
1394 : }
1395 :
1396 0 : int amdgpu_dpm_get_smu_prv_buf_details(struct amdgpu_device *adev,
1397 : void **addr,
1398 : size_t *size)
1399 : {
1400 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1401 0 : int ret = 0;
1402 :
1403 0 : if (!pp_funcs->get_smu_prv_buf_details)
1404 : return -ENOSYS;
1405 :
1406 0 : mutex_lock(&adev->pm.mutex);
1407 0 : ret = pp_funcs->get_smu_prv_buf_details(adev->powerplay.pp_handle,
1408 : addr,
1409 : size);
1410 0 : mutex_unlock(&adev->pm.mutex);
1411 :
1412 0 : return ret;
1413 : }
1414 :
1415 0 : int amdgpu_dpm_is_overdrive_supported(struct amdgpu_device *adev)
1416 : {
1417 0 : struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
1418 0 : struct smu_context *smu = adev->powerplay.pp_handle;
1419 :
1420 0 : if ((is_support_sw_smu(adev) && smu->od_enabled) ||
1421 0 : (is_support_sw_smu(adev) && smu->is_apu) ||
1422 0 : (!is_support_sw_smu(adev) && hwmgr->od_enabled))
1423 : return true;
1424 :
1425 : return false;
1426 : }
1427 :
1428 0 : int amdgpu_dpm_set_pp_table(struct amdgpu_device *adev,
1429 : const char *buf,
1430 : size_t size)
1431 : {
1432 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1433 0 : int ret = 0;
1434 :
1435 0 : if (!pp_funcs->set_pp_table)
1436 : return -EOPNOTSUPP;
1437 :
1438 0 : mutex_lock(&adev->pm.mutex);
1439 0 : ret = pp_funcs->set_pp_table(adev->powerplay.pp_handle,
1440 : buf,
1441 : size);
1442 0 : mutex_unlock(&adev->pm.mutex);
1443 :
1444 0 : return ret;
1445 : }
1446 :
1447 0 : int amdgpu_dpm_get_num_cpu_cores(struct amdgpu_device *adev)
1448 : {
1449 0 : struct smu_context *smu = adev->powerplay.pp_handle;
1450 :
1451 0 : if (!is_support_sw_smu(adev))
1452 : return INT_MAX;
1453 :
1454 0 : return smu->cpu_core_num;
1455 : }
1456 :
1457 0 : void amdgpu_dpm_stb_debug_fs_init(struct amdgpu_device *adev)
1458 : {
1459 0 : if (!is_support_sw_smu(adev))
1460 : return;
1461 :
1462 0 : amdgpu_smu_stb_debug_fs_init(adev);
1463 : }
1464 :
1465 0 : int amdgpu_dpm_display_configuration_change(struct amdgpu_device *adev,
1466 : const struct amd_pp_display_configuration *input)
1467 : {
1468 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1469 0 : int ret = 0;
1470 :
1471 0 : if (!pp_funcs->display_configuration_change)
1472 : return 0;
1473 :
1474 0 : mutex_lock(&adev->pm.mutex);
1475 0 : ret = pp_funcs->display_configuration_change(adev->powerplay.pp_handle,
1476 : input);
1477 0 : mutex_unlock(&adev->pm.mutex);
1478 :
1479 0 : return ret;
1480 : }
1481 :
1482 0 : int amdgpu_dpm_get_clock_by_type(struct amdgpu_device *adev,
1483 : enum amd_pp_clock_type type,
1484 : struct amd_pp_clocks *clocks)
1485 : {
1486 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1487 0 : int ret = 0;
1488 :
1489 0 : if (!pp_funcs->get_clock_by_type)
1490 : return 0;
1491 :
1492 0 : mutex_lock(&adev->pm.mutex);
1493 0 : ret = pp_funcs->get_clock_by_type(adev->powerplay.pp_handle,
1494 : type,
1495 : clocks);
1496 0 : mutex_unlock(&adev->pm.mutex);
1497 :
1498 0 : return ret;
1499 : }
1500 :
1501 0 : int amdgpu_dpm_get_display_mode_validation_clks(struct amdgpu_device *adev,
1502 : struct amd_pp_simple_clock_info *clocks)
1503 : {
1504 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1505 0 : int ret = 0;
1506 :
1507 0 : if (!pp_funcs->get_display_mode_validation_clocks)
1508 : return 0;
1509 :
1510 0 : mutex_lock(&adev->pm.mutex);
1511 0 : ret = pp_funcs->get_display_mode_validation_clocks(adev->powerplay.pp_handle,
1512 : clocks);
1513 0 : mutex_unlock(&adev->pm.mutex);
1514 :
1515 0 : return ret;
1516 : }
1517 :
1518 0 : int amdgpu_dpm_get_clock_by_type_with_latency(struct amdgpu_device *adev,
1519 : enum amd_pp_clock_type type,
1520 : struct pp_clock_levels_with_latency *clocks)
1521 : {
1522 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1523 0 : int ret = 0;
1524 :
1525 0 : if (!pp_funcs->get_clock_by_type_with_latency)
1526 : return 0;
1527 :
1528 0 : mutex_lock(&adev->pm.mutex);
1529 0 : ret = pp_funcs->get_clock_by_type_with_latency(adev->powerplay.pp_handle,
1530 : type,
1531 : clocks);
1532 0 : mutex_unlock(&adev->pm.mutex);
1533 :
1534 0 : return ret;
1535 : }
1536 :
1537 0 : int amdgpu_dpm_get_clock_by_type_with_voltage(struct amdgpu_device *adev,
1538 : enum amd_pp_clock_type type,
1539 : struct pp_clock_levels_with_voltage *clocks)
1540 : {
1541 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1542 0 : int ret = 0;
1543 :
1544 0 : if (!pp_funcs->get_clock_by_type_with_voltage)
1545 : return 0;
1546 :
1547 0 : mutex_lock(&adev->pm.mutex);
1548 0 : ret = pp_funcs->get_clock_by_type_with_voltage(adev->powerplay.pp_handle,
1549 : type,
1550 : clocks);
1551 0 : mutex_unlock(&adev->pm.mutex);
1552 :
1553 0 : return ret;
1554 : }
1555 :
1556 0 : int amdgpu_dpm_set_watermarks_for_clocks_ranges(struct amdgpu_device *adev,
1557 : void *clock_ranges)
1558 : {
1559 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1560 0 : int ret = 0;
1561 :
1562 0 : if (!pp_funcs->set_watermarks_for_clocks_ranges)
1563 : return -EOPNOTSUPP;
1564 :
1565 0 : mutex_lock(&adev->pm.mutex);
1566 0 : ret = pp_funcs->set_watermarks_for_clocks_ranges(adev->powerplay.pp_handle,
1567 : clock_ranges);
1568 0 : mutex_unlock(&adev->pm.mutex);
1569 :
1570 0 : return ret;
1571 : }
1572 :
1573 0 : int amdgpu_dpm_display_clock_voltage_request(struct amdgpu_device *adev,
1574 : struct pp_display_clock_request *clock)
1575 : {
1576 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1577 0 : int ret = 0;
1578 :
1579 0 : if (!pp_funcs->display_clock_voltage_request)
1580 : return -EOPNOTSUPP;
1581 :
1582 0 : mutex_lock(&adev->pm.mutex);
1583 0 : ret = pp_funcs->display_clock_voltage_request(adev->powerplay.pp_handle,
1584 : clock);
1585 0 : mutex_unlock(&adev->pm.mutex);
1586 :
1587 0 : return ret;
1588 : }
1589 :
1590 0 : int amdgpu_dpm_get_current_clocks(struct amdgpu_device *adev,
1591 : struct amd_pp_clock_info *clocks)
1592 : {
1593 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1594 0 : int ret = 0;
1595 :
1596 0 : if (!pp_funcs->get_current_clocks)
1597 : return -EOPNOTSUPP;
1598 :
1599 0 : mutex_lock(&adev->pm.mutex);
1600 0 : ret = pp_funcs->get_current_clocks(adev->powerplay.pp_handle,
1601 : clocks);
1602 0 : mutex_unlock(&adev->pm.mutex);
1603 :
1604 0 : return ret;
1605 : }
1606 :
1607 0 : void amdgpu_dpm_notify_smu_enable_pwe(struct amdgpu_device *adev)
1608 : {
1609 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1610 :
1611 0 : if (!pp_funcs->notify_smu_enable_pwe)
1612 : return;
1613 :
1614 0 : mutex_lock(&adev->pm.mutex);
1615 0 : pp_funcs->notify_smu_enable_pwe(adev->powerplay.pp_handle);
1616 0 : mutex_unlock(&adev->pm.mutex);
1617 : }
1618 :
1619 0 : int amdgpu_dpm_set_active_display_count(struct amdgpu_device *adev,
1620 : uint32_t count)
1621 : {
1622 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1623 0 : int ret = 0;
1624 :
1625 0 : if (!pp_funcs->set_active_display_count)
1626 : return -EOPNOTSUPP;
1627 :
1628 0 : mutex_lock(&adev->pm.mutex);
1629 0 : ret = pp_funcs->set_active_display_count(adev->powerplay.pp_handle,
1630 : count);
1631 0 : mutex_unlock(&adev->pm.mutex);
1632 :
1633 0 : return ret;
1634 : }
1635 :
1636 0 : int amdgpu_dpm_set_min_deep_sleep_dcefclk(struct amdgpu_device *adev,
1637 : uint32_t clock)
1638 : {
1639 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1640 0 : int ret = 0;
1641 :
1642 0 : if (!pp_funcs->set_min_deep_sleep_dcefclk)
1643 : return -EOPNOTSUPP;
1644 :
1645 0 : mutex_lock(&adev->pm.mutex);
1646 0 : ret = pp_funcs->set_min_deep_sleep_dcefclk(adev->powerplay.pp_handle,
1647 : clock);
1648 0 : mutex_unlock(&adev->pm.mutex);
1649 :
1650 0 : return ret;
1651 : }
1652 :
1653 0 : void amdgpu_dpm_set_hard_min_dcefclk_by_freq(struct amdgpu_device *adev,
1654 : uint32_t clock)
1655 : {
1656 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1657 :
1658 0 : if (!pp_funcs->set_hard_min_dcefclk_by_freq)
1659 : return;
1660 :
1661 0 : mutex_lock(&adev->pm.mutex);
1662 0 : pp_funcs->set_hard_min_dcefclk_by_freq(adev->powerplay.pp_handle,
1663 : clock);
1664 0 : mutex_unlock(&adev->pm.mutex);
1665 : }
1666 :
1667 0 : void amdgpu_dpm_set_hard_min_fclk_by_freq(struct amdgpu_device *adev,
1668 : uint32_t clock)
1669 : {
1670 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1671 :
1672 0 : if (!pp_funcs->set_hard_min_fclk_by_freq)
1673 : return;
1674 :
1675 0 : mutex_lock(&adev->pm.mutex);
1676 0 : pp_funcs->set_hard_min_fclk_by_freq(adev->powerplay.pp_handle,
1677 : clock);
1678 0 : mutex_unlock(&adev->pm.mutex);
1679 : }
1680 :
1681 0 : int amdgpu_dpm_display_disable_memory_clock_switch(struct amdgpu_device *adev,
1682 : bool disable_memory_clock_switch)
1683 : {
1684 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1685 0 : int ret = 0;
1686 :
1687 0 : if (!pp_funcs->display_disable_memory_clock_switch)
1688 : return 0;
1689 :
1690 0 : mutex_lock(&adev->pm.mutex);
1691 0 : ret = pp_funcs->display_disable_memory_clock_switch(adev->powerplay.pp_handle,
1692 : disable_memory_clock_switch);
1693 0 : mutex_unlock(&adev->pm.mutex);
1694 :
1695 0 : return ret;
1696 : }
1697 :
1698 0 : int amdgpu_dpm_get_max_sustainable_clocks_by_dc(struct amdgpu_device *adev,
1699 : struct pp_smu_nv_clock_table *max_clocks)
1700 : {
1701 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1702 0 : int ret = 0;
1703 :
1704 0 : if (!pp_funcs->get_max_sustainable_clocks_by_dc)
1705 : return -EOPNOTSUPP;
1706 :
1707 0 : mutex_lock(&adev->pm.mutex);
1708 0 : ret = pp_funcs->get_max_sustainable_clocks_by_dc(adev->powerplay.pp_handle,
1709 : max_clocks);
1710 0 : mutex_unlock(&adev->pm.mutex);
1711 :
1712 0 : return ret;
1713 : }
1714 :
1715 0 : enum pp_smu_status amdgpu_dpm_get_uclk_dpm_states(struct amdgpu_device *adev,
1716 : unsigned int *clock_values_in_khz,
1717 : unsigned int *num_states)
1718 : {
1719 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1720 0 : int ret = 0;
1721 :
1722 0 : if (!pp_funcs->get_uclk_dpm_states)
1723 : return -EOPNOTSUPP;
1724 :
1725 0 : mutex_lock(&adev->pm.mutex);
1726 0 : ret = pp_funcs->get_uclk_dpm_states(adev->powerplay.pp_handle,
1727 : clock_values_in_khz,
1728 : num_states);
1729 0 : mutex_unlock(&adev->pm.mutex);
1730 :
1731 0 : return ret;
1732 : }
1733 :
1734 0 : int amdgpu_dpm_get_dpm_clock_table(struct amdgpu_device *adev,
1735 : struct dpm_clocks *clock_table)
1736 : {
1737 0 : const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1738 0 : int ret = 0;
1739 :
1740 0 : if (!pp_funcs->get_dpm_clock_table)
1741 : return -EOPNOTSUPP;
1742 :
1743 0 : mutex_lock(&adev->pm.mutex);
1744 0 : ret = pp_funcs->get_dpm_clock_table(adev->powerplay.pp_handle,
1745 : clock_table);
1746 0 : mutex_unlock(&adev->pm.mutex);
1747 :
1748 0 : return ret;
1749 : }
|