• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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 #include "pp_debug.h"
24 #include <linux/types.h>
25 #include <linux/kernel.h>
26 #include <linux/gfp.h>
27 #include <linux/slab.h>
28 #include "amd_shared.h"
29 #include "amd_powerplay.h"
30 #include "pp_instance.h"
31 #include "power_state.h"
32 #include "eventmanager.h"
33 
34 
pp_check(struct pp_instance * handle)35 static inline int pp_check(struct pp_instance *handle)
36 {
37 	if (handle == NULL || handle->pp_valid != PP_VALID)
38 		return -EINVAL;
39 
40 	if (handle->smu_mgr == NULL || handle->smu_mgr->smumgr_funcs == NULL)
41 		return -EINVAL;
42 
43 	if (handle->pm_en == 0)
44 		return PP_DPM_DISABLED;
45 
46 	if (handle->hwmgr == NULL || handle->hwmgr->hwmgr_func == NULL
47 		|| handle->eventmgr == NULL)
48 		return PP_DPM_DISABLED;
49 
50 	return 0;
51 }
52 
pp_early_init(void * handle)53 static int pp_early_init(void *handle)
54 {
55 	int ret;
56 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
57 
58 	ret = smum_early_init(pp_handle);
59 	if (ret)
60 		return ret;
61 
62 	if ((pp_handle->pm_en == 0)
63 		|| cgs_is_virtualization_enabled(pp_handle->device))
64 		return PP_DPM_DISABLED;
65 
66 	ret = hwmgr_early_init(pp_handle);
67 	if (ret) {
68 		pp_handle->pm_en = 0;
69 		return PP_DPM_DISABLED;
70 	}
71 
72 	ret = eventmgr_early_init(pp_handle);
73 	if (ret) {
74 		kfree(pp_handle->hwmgr);
75 		pp_handle->hwmgr = NULL;
76 		pp_handle->pm_en = 0;
77 		return PP_DPM_DISABLED;
78 	}
79 
80 	return 0;
81 }
82 
pp_sw_init(void * handle)83 static int pp_sw_init(void *handle)
84 {
85 	struct pp_smumgr *smumgr;
86 	int ret = 0;
87 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
88 
89 	ret = pp_check(pp_handle);
90 
91 	if (ret == 0 || ret == PP_DPM_DISABLED) {
92 		smumgr = pp_handle->smu_mgr;
93 
94 		if (smumgr->smumgr_funcs->smu_init == NULL)
95 			return -EINVAL;
96 
97 		ret = smumgr->smumgr_funcs->smu_init(smumgr);
98 
99 		pr_info("amdgpu: powerplay sw initialized\n");
100 	}
101 	return ret;
102 }
103 
pp_sw_fini(void * handle)104 static int pp_sw_fini(void *handle)
105 {
106 	struct pp_smumgr *smumgr;
107 	int ret = 0;
108 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
109 
110 	ret = pp_check(pp_handle);
111 	if (ret == 0 || ret == PP_DPM_DISABLED) {
112 		smumgr = pp_handle->smu_mgr;
113 
114 		if (smumgr->smumgr_funcs->smu_fini == NULL)
115 			return -EINVAL;
116 
117 		ret = smumgr->smumgr_funcs->smu_fini(smumgr);
118 	}
119 	return ret;
120 }
121 
pp_hw_init(void * handle)122 static int pp_hw_init(void *handle)
123 {
124 	struct pp_smumgr *smumgr;
125 	struct pp_eventmgr *eventmgr;
126 	int ret = 0;
127 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
128 
129 	ret = pp_check(pp_handle);
130 
131 	if (ret == 0 || ret == PP_DPM_DISABLED) {
132 		smumgr = pp_handle->smu_mgr;
133 
134 		if (smumgr->smumgr_funcs->start_smu == NULL)
135 			return -EINVAL;
136 
137 		if(smumgr->smumgr_funcs->start_smu(smumgr)) {
138 			pr_err("smc start failed\n");
139 			smumgr->smumgr_funcs->smu_fini(smumgr);
140 			return -EINVAL;;
141 		}
142 		if (ret == PP_DPM_DISABLED)
143 			return PP_DPM_DISABLED;
144 	}
145 
146 	ret = hwmgr_hw_init(pp_handle);
147 	if (ret)
148 		goto err;
149 
150 	eventmgr = pp_handle->eventmgr;
151 	if (eventmgr->pp_eventmgr_init == NULL ||
152 		eventmgr->pp_eventmgr_init(eventmgr))
153 		goto err;
154 
155 	return 0;
156 err:
157 	pp_handle->pm_en = 0;
158 	kfree(pp_handle->eventmgr);
159 	kfree(pp_handle->hwmgr);
160 	pp_handle->hwmgr = NULL;
161 	pp_handle->eventmgr = NULL;
162 	return PP_DPM_DISABLED;
163 }
164 
pp_hw_fini(void * handle)165 static int pp_hw_fini(void *handle)
166 {
167 	struct pp_eventmgr *eventmgr;
168 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
169 	int ret = 0;
170 
171 	ret = pp_check(pp_handle);
172 
173 	if (ret == 0) {
174 		eventmgr = pp_handle->eventmgr;
175 
176 		if (eventmgr->pp_eventmgr_fini != NULL)
177 			eventmgr->pp_eventmgr_fini(eventmgr);
178 
179 		hwmgr_hw_fini(pp_handle);
180 	}
181 	return 0;
182 }
183 
pp_is_idle(void * handle)184 static bool pp_is_idle(void *handle)
185 {
186 	return false;
187 }
188 
pp_wait_for_idle(void * handle)189 static int pp_wait_for_idle(void *handle)
190 {
191 	return 0;
192 }
193 
pp_sw_reset(void * handle)194 static int pp_sw_reset(void *handle)
195 {
196 	return 0;
197 }
198 
199 
amd_set_clockgating_by_smu(void * handle,uint32_t msg_id)200 int amd_set_clockgating_by_smu(void *handle, uint32_t msg_id)
201 {
202 	struct pp_hwmgr  *hwmgr;
203 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
204 	int ret = 0;
205 
206 	ret = pp_check(pp_handle);
207 
208 	if (ret != 0)
209 		return ret;
210 
211 	hwmgr = pp_handle->hwmgr;
212 
213 	if (hwmgr->hwmgr_func->update_clock_gatings == NULL) {
214 		pr_info("%s was not implemented.\n", __func__);
215 		return 0;
216 	}
217 
218 	return hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
219 }
220 
pp_set_powergating_state(void * handle,enum amd_powergating_state state)221 static int pp_set_powergating_state(void *handle,
222 				    enum amd_powergating_state state)
223 {
224 	struct pp_hwmgr  *hwmgr;
225 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
226 	int ret = 0;
227 
228 	ret = pp_check(pp_handle);
229 
230 	if (ret != 0)
231 		return ret;
232 
233 	hwmgr = pp_handle->hwmgr;
234 
235 	if (hwmgr->hwmgr_func->enable_per_cu_power_gating == NULL) {
236 		pr_info("%s was not implemented.\n", __func__);
237 		return 0;
238 	}
239 
240 	/* Enable/disable GFX per cu powergating through SMU */
241 	return hwmgr->hwmgr_func->enable_per_cu_power_gating(hwmgr,
242 			state == AMD_PG_STATE_GATE);
243 }
244 
pp_suspend(void * handle)245 static int pp_suspend(void *handle)
246 {
247 	struct pp_eventmgr *eventmgr;
248 	struct pem_event_data event_data = { {0} };
249 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
250 	int ret = 0;
251 
252 	ret = pp_check(pp_handle);
253 
254 	if (ret == PP_DPM_DISABLED)
255 		return 0;
256 	else if (ret != 0)
257 		return ret;
258 
259 	eventmgr = pp_handle->eventmgr;
260 	pem_handle_event(eventmgr, AMD_PP_EVENT_SUSPEND, &event_data);
261 
262 	return 0;
263 }
264 
pp_resume(void * handle)265 static int pp_resume(void *handle)
266 {
267 	struct pp_eventmgr *eventmgr;
268 	struct pem_event_data event_data = { {0} };
269 	struct pp_smumgr *smumgr;
270 	int ret, ret1;
271 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
272 
273 	ret1 = pp_check(pp_handle);
274 
275 	if (ret1 != 0 && ret1 != PP_DPM_DISABLED)
276 		return ret1;
277 
278 	smumgr = pp_handle->smu_mgr;
279 
280 	if (smumgr->smumgr_funcs->start_smu == NULL)
281 		return -EINVAL;
282 
283 	ret = smumgr->smumgr_funcs->start_smu(smumgr);
284 	if (ret) {
285 		pr_err("smc start failed\n");
286 		smumgr->smumgr_funcs->smu_fini(smumgr);
287 		return ret;
288 	}
289 
290 	if (ret1 == PP_DPM_DISABLED)
291 		return 0;
292 
293 	eventmgr = pp_handle->eventmgr;
294 
295 	pem_handle_event(eventmgr, AMD_PP_EVENT_RESUME, &event_data);
296 
297 	return 0;
298 }
299 
300 const struct amd_ip_funcs pp_ip_funcs = {
301 	.name = "powerplay",
302 	.early_init = pp_early_init,
303 	.late_init = NULL,
304 	.sw_init = pp_sw_init,
305 	.sw_fini = pp_sw_fini,
306 	.hw_init = pp_hw_init,
307 	.hw_fini = pp_hw_fini,
308 	.suspend = pp_suspend,
309 	.resume = pp_resume,
310 	.is_idle = pp_is_idle,
311 	.wait_for_idle = pp_wait_for_idle,
312 	.soft_reset = pp_sw_reset,
313 	.set_clockgating_state = NULL,
314 	.set_powergating_state = pp_set_powergating_state,
315 };
316 
pp_dpm_load_fw(void * handle)317 static int pp_dpm_load_fw(void *handle)
318 {
319 	return 0;
320 }
321 
pp_dpm_fw_loading_complete(void * handle)322 static int pp_dpm_fw_loading_complete(void *handle)
323 {
324 	return 0;
325 }
326 
pp_dpm_force_performance_level(void * handle,enum amd_dpm_forced_level level)327 static int pp_dpm_force_performance_level(void *handle,
328 					enum amd_dpm_forced_level level)
329 {
330 	struct pp_hwmgr  *hwmgr;
331 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
332 	int ret = 0;
333 
334 	ret = pp_check(pp_handle);
335 
336 	if (ret != 0)
337 		return ret;
338 
339 	hwmgr = pp_handle->hwmgr;
340 
341 	if (hwmgr->hwmgr_func->force_dpm_level == NULL) {
342 		pr_info("%s was not implemented.\n", __func__);
343 		return 0;
344 	}
345 
346 	mutex_lock(&pp_handle->pp_lock);
347 	hwmgr->hwmgr_func->force_dpm_level(hwmgr, level);
348 	mutex_unlock(&pp_handle->pp_lock);
349 	return 0;
350 }
351 
pp_dpm_get_performance_level(void * handle)352 static enum amd_dpm_forced_level pp_dpm_get_performance_level(
353 								void *handle)
354 {
355 	struct pp_hwmgr  *hwmgr;
356 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
357 	int ret = 0;
358 	enum amd_dpm_forced_level level;
359 
360 	ret = pp_check(pp_handle);
361 
362 	if (ret != 0)
363 		return ret;
364 
365 	hwmgr = pp_handle->hwmgr;
366 	mutex_lock(&pp_handle->pp_lock);
367 	level = hwmgr->dpm_level;
368 	mutex_unlock(&pp_handle->pp_lock);
369 	return level;
370 }
371 
pp_dpm_get_sclk(void * handle,bool low)372 static int pp_dpm_get_sclk(void *handle, bool low)
373 {
374 	struct pp_hwmgr  *hwmgr;
375 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
376 	int ret = 0;
377 
378 	ret = pp_check(pp_handle);
379 
380 	if (ret != 0)
381 		return ret;
382 
383 	hwmgr = pp_handle->hwmgr;
384 
385 	if (hwmgr->hwmgr_func->get_sclk == NULL) {
386 		pr_info("%s was not implemented.\n", __func__);
387 		return 0;
388 	}
389 	mutex_lock(&pp_handle->pp_lock);
390 	ret = hwmgr->hwmgr_func->get_sclk(hwmgr, low);
391 	mutex_unlock(&pp_handle->pp_lock);
392 	return ret;
393 }
394 
pp_dpm_get_mclk(void * handle,bool low)395 static int pp_dpm_get_mclk(void *handle, bool low)
396 {
397 	struct pp_hwmgr  *hwmgr;
398 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
399 	int ret = 0;
400 
401 	ret = pp_check(pp_handle);
402 
403 	if (ret != 0)
404 		return ret;
405 
406 	hwmgr = pp_handle->hwmgr;
407 
408 	if (hwmgr->hwmgr_func->get_mclk == NULL) {
409 		pr_info("%s was not implemented.\n", __func__);
410 		return 0;
411 	}
412 	mutex_lock(&pp_handle->pp_lock);
413 	ret = hwmgr->hwmgr_func->get_mclk(hwmgr, low);
414 	mutex_unlock(&pp_handle->pp_lock);
415 	return ret;
416 }
417 
pp_dpm_powergate_vce(void * handle,bool gate)418 static int pp_dpm_powergate_vce(void *handle, bool gate)
419 {
420 	struct pp_hwmgr  *hwmgr;
421 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
422 	int ret = 0;
423 
424 	ret = pp_check(pp_handle);
425 
426 	if (ret != 0)
427 		return ret;
428 
429 	hwmgr = pp_handle->hwmgr;
430 
431 	if (hwmgr->hwmgr_func->powergate_vce == NULL) {
432 		pr_info("%s was not implemented.\n", __func__);
433 		return 0;
434 	}
435 	mutex_lock(&pp_handle->pp_lock);
436 	ret = hwmgr->hwmgr_func->powergate_vce(hwmgr, gate);
437 	mutex_unlock(&pp_handle->pp_lock);
438 	return ret;
439 }
440 
pp_dpm_powergate_uvd(void * handle,bool gate)441 static int pp_dpm_powergate_uvd(void *handle, bool gate)
442 {
443 	struct pp_hwmgr  *hwmgr;
444 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
445 	int ret = 0;
446 
447 	ret = pp_check(pp_handle);
448 
449 	if (ret != 0)
450 		return ret;
451 
452 	hwmgr = pp_handle->hwmgr;
453 
454 	if (hwmgr->hwmgr_func->powergate_uvd == NULL) {
455 		pr_info("%s was not implemented.\n", __func__);
456 		return 0;
457 	}
458 	mutex_lock(&pp_handle->pp_lock);
459 	ret = hwmgr->hwmgr_func->powergate_uvd(hwmgr, gate);
460 	mutex_unlock(&pp_handle->pp_lock);
461 	return ret;
462 }
463 
power_state_convert(enum amd_pm_state_type state)464 static enum PP_StateUILabel power_state_convert(enum amd_pm_state_type  state)
465 {
466 	switch (state) {
467 	case POWER_STATE_TYPE_BATTERY:
468 		return PP_StateUILabel_Battery;
469 	case POWER_STATE_TYPE_BALANCED:
470 		return PP_StateUILabel_Balanced;
471 	case POWER_STATE_TYPE_PERFORMANCE:
472 		return PP_StateUILabel_Performance;
473 	default:
474 		return PP_StateUILabel_None;
475 	}
476 }
477 
pp_dpm_dispatch_tasks(void * handle,enum amd_pp_event event_id,void * input,void * output)478 static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_event event_id,
479 		void *input, void *output)
480 {
481 	int ret = 0;
482 	struct pem_event_data data = { {0} };
483 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
484 
485 	ret = pp_check(pp_handle);
486 
487 	if (ret != 0)
488 		return ret;
489 	mutex_lock(&pp_handle->pp_lock);
490 	switch (event_id) {
491 	case AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE:
492 		ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
493 		break;
494 	case AMD_PP_EVENT_ENABLE_USER_STATE:
495 	{
496 		enum amd_pm_state_type  ps;
497 
498 		if (input == NULL) {
499 			ret = -EINVAL;
500 			break;
501 		}
502 		ps = *(unsigned long *)input;
503 
504 		data.requested_ui_label = power_state_convert(ps);
505 		ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
506 		break;
507 	}
508 	case AMD_PP_EVENT_COMPLETE_INIT:
509 		ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
510 		break;
511 	case AMD_PP_EVENT_READJUST_POWER_STATE:
512 		ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
513 		break;
514 	default:
515 		break;
516 	}
517 	mutex_unlock(&pp_handle->pp_lock);
518 	return ret;
519 }
520 
pp_dpm_get_current_power_state(void * handle)521 static enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle)
522 {
523 	struct pp_hwmgr *hwmgr;
524 	struct pp_power_state *state;
525 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
526 	int ret = 0;
527 	enum amd_pm_state_type pm_type;
528 
529 	ret = pp_check(pp_handle);
530 
531 	if (ret != 0)
532 		return ret;
533 
534 	hwmgr = pp_handle->hwmgr;
535 
536 	if (hwmgr->current_ps == NULL)
537 		return -EINVAL;
538 
539 	mutex_lock(&pp_handle->pp_lock);
540 
541 	state = hwmgr->current_ps;
542 
543 	switch (state->classification.ui_label) {
544 	case PP_StateUILabel_Battery:
545 		pm_type = POWER_STATE_TYPE_BATTERY;
546 		break;
547 	case PP_StateUILabel_Balanced:
548 		pm_type = POWER_STATE_TYPE_BALANCED;
549 		break;
550 	case PP_StateUILabel_Performance:
551 		pm_type = POWER_STATE_TYPE_PERFORMANCE;
552 		break;
553 	default:
554 		if (state->classification.flags & PP_StateClassificationFlag_Boot)
555 			pm_type = POWER_STATE_TYPE_INTERNAL_BOOT;
556 		else
557 			pm_type = POWER_STATE_TYPE_DEFAULT;
558 		break;
559 	}
560 	mutex_unlock(&pp_handle->pp_lock);
561 
562 	return pm_type;
563 }
564 
pp_dpm_set_fan_control_mode(void * handle,uint32_t mode)565 static int pp_dpm_set_fan_control_mode(void *handle, uint32_t mode)
566 {
567 	struct pp_hwmgr  *hwmgr;
568 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
569 	int ret = 0;
570 
571 	ret = pp_check(pp_handle);
572 
573 	if (ret != 0)
574 		return ret;
575 
576 	hwmgr = pp_handle->hwmgr;
577 
578 	if (hwmgr->hwmgr_func->set_fan_control_mode == NULL) {
579 		pr_info("%s was not implemented.\n", __func__);
580 		return 0;
581 	}
582 	mutex_lock(&pp_handle->pp_lock);
583 	ret = hwmgr->hwmgr_func->set_fan_control_mode(hwmgr, mode);
584 	mutex_unlock(&pp_handle->pp_lock);
585 	return ret;
586 }
587 
pp_dpm_get_fan_control_mode(void * handle)588 static int pp_dpm_get_fan_control_mode(void *handle)
589 {
590 	struct pp_hwmgr  *hwmgr;
591 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
592 	int ret = 0;
593 
594 	ret = pp_check(pp_handle);
595 
596 	if (ret != 0)
597 		return ret;
598 
599 	hwmgr = pp_handle->hwmgr;
600 
601 	if (hwmgr->hwmgr_func->get_fan_control_mode == NULL) {
602 		pr_info("%s was not implemented.\n", __func__);
603 		return 0;
604 	}
605 	mutex_lock(&pp_handle->pp_lock);
606 	ret = hwmgr->hwmgr_func->get_fan_control_mode(hwmgr);
607 	mutex_unlock(&pp_handle->pp_lock);
608 	return ret;
609 }
610 
pp_dpm_set_fan_speed_percent(void * handle,uint32_t percent)611 static int pp_dpm_set_fan_speed_percent(void *handle, uint32_t percent)
612 {
613 	struct pp_hwmgr  *hwmgr;
614 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
615 	int ret = 0;
616 
617 	ret = pp_check(pp_handle);
618 
619 	if (ret != 0)
620 		return ret;
621 
622 	hwmgr = pp_handle->hwmgr;
623 
624 	if (hwmgr->hwmgr_func->set_fan_speed_percent == NULL) {
625 		pr_info("%s was not implemented.\n", __func__);
626 		return 0;
627 	}
628 	mutex_lock(&pp_handle->pp_lock);
629 	ret = hwmgr->hwmgr_func->set_fan_speed_percent(hwmgr, percent);
630 	mutex_unlock(&pp_handle->pp_lock);
631 	return ret;
632 }
633 
pp_dpm_get_fan_speed_percent(void * handle,uint32_t * speed)634 static int pp_dpm_get_fan_speed_percent(void *handle, uint32_t *speed)
635 {
636 	struct pp_hwmgr  *hwmgr;
637 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
638 	int ret = 0;
639 
640 	ret = pp_check(pp_handle);
641 
642 	if (ret != 0)
643 		return ret;
644 
645 	hwmgr = pp_handle->hwmgr;
646 
647 	if (hwmgr->hwmgr_func->get_fan_speed_percent == NULL) {
648 		pr_info("%s was not implemented.\n", __func__);
649 		return 0;
650 	}
651 
652 	mutex_lock(&pp_handle->pp_lock);
653 	ret = hwmgr->hwmgr_func->get_fan_speed_percent(hwmgr, speed);
654 	mutex_unlock(&pp_handle->pp_lock);
655 	return ret;
656 }
657 
pp_dpm_get_fan_speed_rpm(void * handle,uint32_t * rpm)658 static int pp_dpm_get_fan_speed_rpm(void *handle, uint32_t *rpm)
659 {
660 	struct pp_hwmgr *hwmgr;
661 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
662 	int ret = 0;
663 
664 	ret = pp_check(pp_handle);
665 
666 	if (ret != 0)
667 		return ret;
668 
669 	hwmgr = pp_handle->hwmgr;
670 
671 	if (hwmgr->hwmgr_func->get_fan_speed_rpm == NULL)
672 		return -EINVAL;
673 
674 	mutex_lock(&pp_handle->pp_lock);
675 	ret = hwmgr->hwmgr_func->get_fan_speed_rpm(hwmgr, rpm);
676 	mutex_unlock(&pp_handle->pp_lock);
677 	return ret;
678 }
679 
pp_dpm_get_temperature(void * handle)680 static int pp_dpm_get_temperature(void *handle)
681 {
682 	struct pp_hwmgr  *hwmgr;
683 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
684 	int ret = 0;
685 
686 	ret = pp_check(pp_handle);
687 
688 	if (ret != 0)
689 		return ret;
690 
691 	hwmgr = pp_handle->hwmgr;
692 
693 	if (hwmgr->hwmgr_func->get_temperature == NULL) {
694 		pr_info("%s was not implemented.\n", __func__);
695 		return 0;
696 	}
697 	mutex_lock(&pp_handle->pp_lock);
698 	ret = hwmgr->hwmgr_func->get_temperature(hwmgr);
699 	mutex_unlock(&pp_handle->pp_lock);
700 	return ret;
701 }
702 
pp_dpm_get_pp_num_states(void * handle,struct pp_states_info * data)703 static int pp_dpm_get_pp_num_states(void *handle,
704 		struct pp_states_info *data)
705 {
706 	struct pp_hwmgr *hwmgr;
707 	int i;
708 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
709 	int ret = 0;
710 
711 	ret = pp_check(pp_handle);
712 
713 	if (ret != 0)
714 		return ret;
715 
716 	hwmgr = pp_handle->hwmgr;
717 
718 	if (hwmgr->ps == NULL)
719 		return -EINVAL;
720 
721 	mutex_lock(&pp_handle->pp_lock);
722 
723 	data->nums = hwmgr->num_ps;
724 
725 	for (i = 0; i < hwmgr->num_ps; i++) {
726 		struct pp_power_state *state = (struct pp_power_state *)
727 				((unsigned long)hwmgr->ps + i * hwmgr->ps_size);
728 		switch (state->classification.ui_label) {
729 		case PP_StateUILabel_Battery:
730 			data->states[i] = POWER_STATE_TYPE_BATTERY;
731 			break;
732 		case PP_StateUILabel_Balanced:
733 			data->states[i] = POWER_STATE_TYPE_BALANCED;
734 			break;
735 		case PP_StateUILabel_Performance:
736 			data->states[i] = POWER_STATE_TYPE_PERFORMANCE;
737 			break;
738 		default:
739 			if (state->classification.flags & PP_StateClassificationFlag_Boot)
740 				data->states[i] = POWER_STATE_TYPE_INTERNAL_BOOT;
741 			else
742 				data->states[i] = POWER_STATE_TYPE_DEFAULT;
743 		}
744 	}
745 	mutex_unlock(&pp_handle->pp_lock);
746 	return 0;
747 }
748 
pp_dpm_get_pp_table(void * handle,char ** table)749 static int pp_dpm_get_pp_table(void *handle, char **table)
750 {
751 	struct pp_hwmgr *hwmgr;
752 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
753 	int ret = 0;
754 	int size = 0;
755 
756 	ret = pp_check(pp_handle);
757 
758 	if (ret != 0)
759 		return ret;
760 
761 	hwmgr = pp_handle->hwmgr;
762 
763 	if (!hwmgr->soft_pp_table)
764 		return -EINVAL;
765 
766 	mutex_lock(&pp_handle->pp_lock);
767 	*table = (char *)hwmgr->soft_pp_table;
768 	size = hwmgr->soft_pp_table_size;
769 	mutex_unlock(&pp_handle->pp_lock);
770 	return size;
771 }
772 
pp_dpm_set_pp_table(void * handle,const char * buf,size_t size)773 static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size)
774 {
775 	struct pp_hwmgr *hwmgr;
776 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
777 	int ret = 0;
778 
779 	ret = pp_check(pp_handle);
780 
781 	if (ret != 0)
782 		return ret;
783 
784 	hwmgr = pp_handle->hwmgr;
785 	mutex_lock(&pp_handle->pp_lock);
786 	if (!hwmgr->hardcode_pp_table) {
787 		hwmgr->hardcode_pp_table = kmemdup(hwmgr->soft_pp_table,
788 						   hwmgr->soft_pp_table_size,
789 						   GFP_KERNEL);
790 		if (!hwmgr->hardcode_pp_table) {
791 			mutex_unlock(&pp_handle->pp_lock);
792 			return -ENOMEM;
793 		}
794 	}
795 
796 	memcpy(hwmgr->hardcode_pp_table, buf, size);
797 
798 	hwmgr->soft_pp_table = hwmgr->hardcode_pp_table;
799 	mutex_unlock(&pp_handle->pp_lock);
800 
801 	ret = amd_powerplay_reset(handle);
802 	if (ret)
803 		return ret;
804 
805 	if (hwmgr->hwmgr_func->avfs_control) {
806 		ret = hwmgr->hwmgr_func->avfs_control(hwmgr, false);
807 		if (ret)
808 			return ret;
809 	}
810 
811 	return 0;
812 }
813 
pp_dpm_force_clock_level(void * handle,enum pp_clock_type type,uint32_t mask)814 static int pp_dpm_force_clock_level(void *handle,
815 		enum pp_clock_type type, uint32_t mask)
816 {
817 	struct pp_hwmgr *hwmgr;
818 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
819 	int ret = 0;
820 
821 	ret = pp_check(pp_handle);
822 
823 	if (ret != 0)
824 		return ret;
825 
826 	hwmgr = pp_handle->hwmgr;
827 
828 	if (hwmgr->hwmgr_func->force_clock_level == NULL) {
829 		pr_info("%s was not implemented.\n", __func__);
830 		return 0;
831 	}
832 	mutex_lock(&pp_handle->pp_lock);
833 	hwmgr->hwmgr_func->force_clock_level(hwmgr, type, mask);
834 	mutex_unlock(&pp_handle->pp_lock);
835 	return ret;
836 }
837 
pp_dpm_print_clock_levels(void * handle,enum pp_clock_type type,char * buf)838 static int pp_dpm_print_clock_levels(void *handle,
839 		enum pp_clock_type type, char *buf)
840 {
841 	struct pp_hwmgr *hwmgr;
842 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
843 	int ret = 0;
844 
845 	ret = pp_check(pp_handle);
846 
847 	if (ret != 0)
848 		return ret;
849 
850 	hwmgr = pp_handle->hwmgr;
851 
852 	if (hwmgr->hwmgr_func->print_clock_levels == NULL) {
853 		pr_info("%s was not implemented.\n", __func__);
854 		return 0;
855 	}
856 	mutex_lock(&pp_handle->pp_lock);
857 	ret = hwmgr->hwmgr_func->print_clock_levels(hwmgr, type, buf);
858 	mutex_unlock(&pp_handle->pp_lock);
859 	return ret;
860 }
861 
pp_dpm_get_sclk_od(void * handle)862 static int pp_dpm_get_sclk_od(void *handle)
863 {
864 	struct pp_hwmgr *hwmgr;
865 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
866 	int ret = 0;
867 
868 	ret = pp_check(pp_handle);
869 
870 	if (ret != 0)
871 		return ret;
872 
873 	hwmgr = pp_handle->hwmgr;
874 
875 	if (hwmgr->hwmgr_func->get_sclk_od == NULL) {
876 		pr_info("%s was not implemented.\n", __func__);
877 		return 0;
878 	}
879 	mutex_lock(&pp_handle->pp_lock);
880 	ret = hwmgr->hwmgr_func->get_sclk_od(hwmgr);
881 	mutex_unlock(&pp_handle->pp_lock);
882 	return ret;
883 }
884 
pp_dpm_set_sclk_od(void * handle,uint32_t value)885 static int pp_dpm_set_sclk_od(void *handle, uint32_t value)
886 {
887 	struct pp_hwmgr *hwmgr;
888 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
889 	int ret = 0;
890 
891 	ret = pp_check(pp_handle);
892 
893 	if (ret != 0)
894 		return ret;
895 
896 	hwmgr = pp_handle->hwmgr;
897 
898 	if (hwmgr->hwmgr_func->set_sclk_od == NULL) {
899 		pr_info("%s was not implemented.\n", __func__);
900 		return 0;
901 	}
902 
903 	mutex_lock(&pp_handle->pp_lock);
904 	ret = hwmgr->hwmgr_func->set_sclk_od(hwmgr, value);
905 	mutex_unlock(&pp_handle->pp_lock);
906 	return ret;
907 }
908 
pp_dpm_get_mclk_od(void * handle)909 static int pp_dpm_get_mclk_od(void *handle)
910 {
911 	struct pp_hwmgr *hwmgr;
912 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
913 	int ret = 0;
914 
915 	ret = pp_check(pp_handle);
916 
917 	if (ret != 0)
918 		return ret;
919 
920 	hwmgr = pp_handle->hwmgr;
921 
922 	if (hwmgr->hwmgr_func->get_mclk_od == NULL) {
923 		pr_info("%s was not implemented.\n", __func__);
924 		return 0;
925 	}
926 	mutex_lock(&pp_handle->pp_lock);
927 	ret = hwmgr->hwmgr_func->get_mclk_od(hwmgr);
928 	mutex_unlock(&pp_handle->pp_lock);
929 	return ret;
930 }
931 
pp_dpm_set_mclk_od(void * handle,uint32_t value)932 static int pp_dpm_set_mclk_od(void *handle, uint32_t value)
933 {
934 	struct pp_hwmgr *hwmgr;
935 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
936 	int ret = 0;
937 
938 	ret = pp_check(pp_handle);
939 
940 	if (ret != 0)
941 		return ret;
942 
943 	hwmgr = pp_handle->hwmgr;
944 
945 	if (hwmgr->hwmgr_func->set_mclk_od == NULL) {
946 		pr_info("%s was not implemented.\n", __func__);
947 		return 0;
948 	}
949 	mutex_lock(&pp_handle->pp_lock);
950 	ret = hwmgr->hwmgr_func->set_mclk_od(hwmgr, value);
951 	mutex_unlock(&pp_handle->pp_lock);
952 	return ret;
953 }
954 
pp_dpm_read_sensor(void * handle,int idx,void * value,int * size)955 static int pp_dpm_read_sensor(void *handle, int idx,
956 			      void *value, int *size)
957 {
958 	struct pp_hwmgr *hwmgr;
959 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
960 	int ret = 0;
961 
962 	ret = pp_check(pp_handle);
963 
964 	if (ret != 0)
965 		return ret;
966 
967 	hwmgr = pp_handle->hwmgr;
968 
969 	if (hwmgr->hwmgr_func->read_sensor == NULL) {
970 		pr_info("%s was not implemented.\n", __func__);
971 		return 0;
972 	}
973 
974 	mutex_lock(&pp_handle->pp_lock);
975 	ret = hwmgr->hwmgr_func->read_sensor(hwmgr, idx, value, size);
976 	mutex_unlock(&pp_handle->pp_lock);
977 
978 	return ret;
979 }
980 
981 static struct amd_vce_state*
pp_dpm_get_vce_clock_state(void * handle,unsigned idx)982 pp_dpm_get_vce_clock_state(void *handle, unsigned idx)
983 {
984 	struct pp_hwmgr *hwmgr;
985 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
986 	int ret = 0;
987 
988 	ret = pp_check(pp_handle);
989 
990 	if (ret != 0)
991 		return NULL;
992 
993 	hwmgr = pp_handle->hwmgr;
994 
995 	if (hwmgr && idx < hwmgr->num_vce_state_tables)
996 		return &hwmgr->vce_states[idx];
997 	return NULL;
998 }
999 
pp_dpm_reset_power_profile_state(void * handle,struct amd_pp_profile * request)1000 static int pp_dpm_reset_power_profile_state(void *handle,
1001 		struct amd_pp_profile *request)
1002 {
1003 	struct pp_hwmgr *hwmgr;
1004 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
1005 
1006 	if (!request || pp_check(pp_handle))
1007 		return -EINVAL;
1008 
1009 	hwmgr = pp_handle->hwmgr;
1010 
1011 	if (hwmgr->hwmgr_func->set_power_profile_state == NULL) {
1012 		pr_info("%s was not implemented.\n", __func__);
1013 		return 0;
1014 	}
1015 
1016 	if (request->type == AMD_PP_GFX_PROFILE) {
1017 		hwmgr->gfx_power_profile = hwmgr->default_gfx_power_profile;
1018 		return hwmgr->hwmgr_func->set_power_profile_state(hwmgr,
1019 				&hwmgr->gfx_power_profile);
1020 	} else if (request->type == AMD_PP_COMPUTE_PROFILE) {
1021 		hwmgr->compute_power_profile =
1022 				hwmgr->default_compute_power_profile;
1023 		return hwmgr->hwmgr_func->set_power_profile_state(hwmgr,
1024 				&hwmgr->compute_power_profile);
1025 	} else
1026 		return -EINVAL;
1027 }
1028 
pp_dpm_get_power_profile_state(void * handle,struct amd_pp_profile * query)1029 static int pp_dpm_get_power_profile_state(void *handle,
1030 		struct amd_pp_profile *query)
1031 {
1032 	struct pp_hwmgr *hwmgr;
1033 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
1034 
1035 	if (!query || pp_check(pp_handle))
1036 		return -EINVAL;
1037 
1038 	hwmgr = pp_handle->hwmgr;
1039 
1040 	if (query->type == AMD_PP_GFX_PROFILE)
1041 		memcpy(query, &hwmgr->gfx_power_profile,
1042 				sizeof(struct amd_pp_profile));
1043 	else if (query->type == AMD_PP_COMPUTE_PROFILE)
1044 		memcpy(query, &hwmgr->compute_power_profile,
1045 				sizeof(struct amd_pp_profile));
1046 	else
1047 		return -EINVAL;
1048 
1049 	return 0;
1050 }
1051 
pp_dpm_set_power_profile_state(void * handle,struct amd_pp_profile * request)1052 static int pp_dpm_set_power_profile_state(void *handle,
1053 		struct amd_pp_profile *request)
1054 {
1055 	struct pp_hwmgr *hwmgr;
1056 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
1057 	int ret = -1;
1058 
1059 	if (!request || pp_check(pp_handle))
1060 		return -EINVAL;
1061 
1062 	hwmgr = pp_handle->hwmgr;
1063 
1064 	if (hwmgr->hwmgr_func->set_power_profile_state == NULL) {
1065 		pr_info("%s was not implemented.\n", __func__);
1066 		return 0;
1067 	}
1068 
1069 	if (request->min_sclk ||
1070 		request->min_mclk ||
1071 		request->activity_threshold ||
1072 		request->up_hyst ||
1073 		request->down_hyst) {
1074 		if (request->type == AMD_PP_GFX_PROFILE)
1075 			memcpy(&hwmgr->gfx_power_profile, request,
1076 					sizeof(struct amd_pp_profile));
1077 		else if (request->type == AMD_PP_COMPUTE_PROFILE)
1078 			memcpy(&hwmgr->compute_power_profile, request,
1079 					sizeof(struct amd_pp_profile));
1080 		else
1081 			return -EINVAL;
1082 
1083 		if (request->type == hwmgr->current_power_profile)
1084 			ret = hwmgr->hwmgr_func->set_power_profile_state(
1085 					hwmgr,
1086 					request);
1087 	} else {
1088 		/* set power profile if it exists */
1089 		switch (request->type) {
1090 		case AMD_PP_GFX_PROFILE:
1091 			ret = hwmgr->hwmgr_func->set_power_profile_state(
1092 					hwmgr,
1093 					&hwmgr->gfx_power_profile);
1094 			break;
1095 		case AMD_PP_COMPUTE_PROFILE:
1096 			ret = hwmgr->hwmgr_func->set_power_profile_state(
1097 					hwmgr,
1098 					&hwmgr->compute_power_profile);
1099 			break;
1100 		default:
1101 			return -EINVAL;
1102 		}
1103 	}
1104 
1105 	if (!ret)
1106 		hwmgr->current_power_profile = request->type;
1107 
1108 	return 0;
1109 }
1110 
pp_dpm_switch_power_profile(void * handle,enum amd_pp_profile_type type)1111 static int pp_dpm_switch_power_profile(void *handle,
1112 		enum amd_pp_profile_type type)
1113 {
1114 	struct pp_hwmgr *hwmgr;
1115 	struct amd_pp_profile request = {0};
1116 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
1117 
1118 	if (pp_check(pp_handle))
1119 		return -EINVAL;
1120 
1121 	hwmgr = pp_handle->hwmgr;
1122 
1123 	if (hwmgr->current_power_profile != type) {
1124 		request.type = type;
1125 		pp_dpm_set_power_profile_state(handle, &request);
1126 	}
1127 
1128 	return 0;
1129 }
1130 
1131 const struct amd_powerplay_funcs pp_dpm_funcs = {
1132 	.get_temperature = pp_dpm_get_temperature,
1133 	.load_firmware = pp_dpm_load_fw,
1134 	.wait_for_fw_loading_complete = pp_dpm_fw_loading_complete,
1135 	.force_performance_level = pp_dpm_force_performance_level,
1136 	.get_performance_level = pp_dpm_get_performance_level,
1137 	.get_current_power_state = pp_dpm_get_current_power_state,
1138 	.get_sclk = pp_dpm_get_sclk,
1139 	.get_mclk = pp_dpm_get_mclk,
1140 	.powergate_vce = pp_dpm_powergate_vce,
1141 	.powergate_uvd = pp_dpm_powergate_uvd,
1142 	.dispatch_tasks = pp_dpm_dispatch_tasks,
1143 	.set_fan_control_mode = pp_dpm_set_fan_control_mode,
1144 	.get_fan_control_mode = pp_dpm_get_fan_control_mode,
1145 	.set_fan_speed_percent = pp_dpm_set_fan_speed_percent,
1146 	.get_fan_speed_percent = pp_dpm_get_fan_speed_percent,
1147 	.get_fan_speed_rpm = pp_dpm_get_fan_speed_rpm,
1148 	.get_pp_num_states = pp_dpm_get_pp_num_states,
1149 	.get_pp_table = pp_dpm_get_pp_table,
1150 	.set_pp_table = pp_dpm_set_pp_table,
1151 	.force_clock_level = pp_dpm_force_clock_level,
1152 	.print_clock_levels = pp_dpm_print_clock_levels,
1153 	.get_sclk_od = pp_dpm_get_sclk_od,
1154 	.set_sclk_od = pp_dpm_set_sclk_od,
1155 	.get_mclk_od = pp_dpm_get_mclk_od,
1156 	.set_mclk_od = pp_dpm_set_mclk_od,
1157 	.read_sensor = pp_dpm_read_sensor,
1158 	.get_vce_clock_state = pp_dpm_get_vce_clock_state,
1159 	.reset_power_profile_state = pp_dpm_reset_power_profile_state,
1160 	.get_power_profile_state = pp_dpm_get_power_profile_state,
1161 	.set_power_profile_state = pp_dpm_set_power_profile_state,
1162 	.switch_power_profile = pp_dpm_switch_power_profile,
1163 };
1164 
amd_powerplay_create(struct amd_pp_init * pp_init,void ** handle)1165 int amd_powerplay_create(struct amd_pp_init *pp_init,
1166 				void **handle)
1167 {
1168 	struct pp_instance *instance;
1169 
1170 	if (pp_init == NULL || handle == NULL)
1171 		return -EINVAL;
1172 
1173 	instance = kzalloc(sizeof(struct pp_instance), GFP_KERNEL);
1174 	if (instance == NULL)
1175 		return -ENOMEM;
1176 
1177 	instance->pp_valid = PP_VALID;
1178 	instance->chip_family = pp_init->chip_family;
1179 	instance->chip_id = pp_init->chip_id;
1180 	instance->pm_en = pp_init->pm_en;
1181 	instance->feature_mask = pp_init->feature_mask;
1182 	instance->device = pp_init->device;
1183 	mutex_init(&instance->pp_lock);
1184 	*handle = instance;
1185 	return 0;
1186 }
1187 
amd_powerplay_destroy(void * handle)1188 int amd_powerplay_destroy(void *handle)
1189 {
1190 	struct pp_instance *instance = (struct pp_instance *)handle;
1191 
1192 	if (instance->pm_en) {
1193 		kfree(instance->eventmgr);
1194 		kfree(instance->hwmgr);
1195 		instance->hwmgr = NULL;
1196 		instance->eventmgr = NULL;
1197 	}
1198 
1199 	kfree(instance->smu_mgr);
1200 	instance->smu_mgr = NULL;
1201 	kfree(instance);
1202 	instance = NULL;
1203 	return 0;
1204 }
1205 
amd_powerplay_reset(void * handle)1206 int amd_powerplay_reset(void *handle)
1207 {
1208 	struct pp_instance *instance = (struct pp_instance *)handle;
1209 	struct pp_eventmgr *eventmgr;
1210 	struct pem_event_data event_data = { {0} };
1211 	int ret;
1212 
1213 	if (cgs_is_virtualization_enabled(instance->smu_mgr->device))
1214 		return PP_DPM_DISABLED;
1215 
1216 	ret = pp_check(instance);
1217 	if (ret != 0)
1218 		return ret;
1219 
1220 	ret = pp_hw_fini(handle);
1221 	if (ret)
1222 		return ret;
1223 
1224 	ret = hwmgr_hw_init(instance);
1225 	if (ret)
1226 		return PP_DPM_DISABLED;
1227 
1228 	eventmgr = instance->eventmgr;
1229 
1230 	if (eventmgr->pp_eventmgr_init == NULL)
1231 		return PP_DPM_DISABLED;
1232 
1233 	ret = eventmgr->pp_eventmgr_init(eventmgr);
1234 	if (ret)
1235 		return ret;
1236 
1237 	return pem_handle_event(eventmgr, AMD_PP_EVENT_COMPLETE_INIT, &event_data);
1238 }
1239 
1240 /* export this function to DAL */
1241 
amd_powerplay_display_configuration_change(void * handle,const struct amd_pp_display_configuration * display_config)1242 int amd_powerplay_display_configuration_change(void *handle,
1243 	const struct amd_pp_display_configuration *display_config)
1244 {
1245 	struct pp_hwmgr  *hwmgr;
1246 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
1247 	int ret = 0;
1248 
1249 	ret = pp_check(pp_handle);
1250 
1251 	if (ret != 0)
1252 		return ret;
1253 
1254 	hwmgr = pp_handle->hwmgr;
1255 	mutex_lock(&pp_handle->pp_lock);
1256 	phm_store_dal_configuration_data(hwmgr, display_config);
1257 	mutex_unlock(&pp_handle->pp_lock);
1258 	return 0;
1259 }
1260 
amd_powerplay_get_display_power_level(void * handle,struct amd_pp_simple_clock_info * output)1261 int amd_powerplay_get_display_power_level(void *handle,
1262 		struct amd_pp_simple_clock_info *output)
1263 {
1264 	struct pp_hwmgr  *hwmgr;
1265 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
1266 	int ret = 0;
1267 
1268 	ret = pp_check(pp_handle);
1269 
1270 	if (ret != 0)
1271 		return ret;
1272 
1273 	hwmgr = pp_handle->hwmgr;
1274 
1275 	if (output == NULL)
1276 		return -EINVAL;
1277 
1278 	mutex_lock(&pp_handle->pp_lock);
1279 	ret = phm_get_dal_power_level(hwmgr, output);
1280 	mutex_unlock(&pp_handle->pp_lock);
1281 	return ret;
1282 }
1283 
amd_powerplay_get_current_clocks(void * handle,struct amd_pp_clock_info * clocks)1284 int amd_powerplay_get_current_clocks(void *handle,
1285 		struct amd_pp_clock_info *clocks)
1286 {
1287 	struct amd_pp_simple_clock_info simple_clocks;
1288 	struct pp_clock_info hw_clocks;
1289 	struct pp_hwmgr  *hwmgr;
1290 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
1291 	int ret = 0;
1292 
1293 	ret = pp_check(pp_handle);
1294 
1295 	if (ret != 0)
1296 		return ret;
1297 
1298 	hwmgr = pp_handle->hwmgr;
1299 
1300 	mutex_lock(&pp_handle->pp_lock);
1301 
1302 	phm_get_dal_power_level(hwmgr, &simple_clocks);
1303 
1304 	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
1305 					PHM_PlatformCaps_PowerContainment))
1306 		ret = phm_get_clock_info(hwmgr, &hwmgr->current_ps->hardware,
1307 					&hw_clocks, PHM_PerformanceLevelDesignation_PowerContainment);
1308 	else
1309 		ret = phm_get_clock_info(hwmgr, &hwmgr->current_ps->hardware,
1310 					&hw_clocks, PHM_PerformanceLevelDesignation_Activity);
1311 
1312 	if (ret != 0) {
1313 		pr_info("Error in phm_get_clock_info \n");
1314 		mutex_unlock(&pp_handle->pp_lock);
1315 		return -EINVAL;
1316 	}
1317 
1318 	clocks->min_engine_clock = hw_clocks.min_eng_clk;
1319 	clocks->max_engine_clock = hw_clocks.max_eng_clk;
1320 	clocks->min_memory_clock = hw_clocks.min_mem_clk;
1321 	clocks->max_memory_clock = hw_clocks.max_mem_clk;
1322 	clocks->min_bus_bandwidth = hw_clocks.min_bus_bandwidth;
1323 	clocks->max_bus_bandwidth = hw_clocks.max_bus_bandwidth;
1324 
1325 	clocks->max_engine_clock_in_sr = hw_clocks.max_eng_clk;
1326 	clocks->min_engine_clock_in_sr = hw_clocks.min_eng_clk;
1327 
1328 	clocks->max_clocks_state = simple_clocks.level;
1329 
1330 	if (0 == phm_get_current_shallow_sleep_clocks(hwmgr, &hwmgr->current_ps->hardware, &hw_clocks)) {
1331 		clocks->max_engine_clock_in_sr = hw_clocks.max_eng_clk;
1332 		clocks->min_engine_clock_in_sr = hw_clocks.min_eng_clk;
1333 	}
1334 	mutex_unlock(&pp_handle->pp_lock);
1335 	return 0;
1336 }
1337 
amd_powerplay_get_clock_by_type(void * handle,enum amd_pp_clock_type type,struct amd_pp_clocks * clocks)1338 int amd_powerplay_get_clock_by_type(void *handle, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks)
1339 {
1340 	struct pp_hwmgr  *hwmgr;
1341 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
1342 	int ret = 0;
1343 
1344 	ret = pp_check(pp_handle);
1345 
1346 	if (ret != 0)
1347 		return ret;
1348 
1349 	hwmgr = pp_handle->hwmgr;
1350 
1351 	if (clocks == NULL)
1352 		return -EINVAL;
1353 
1354 	mutex_lock(&pp_handle->pp_lock);
1355 	ret = phm_get_clock_by_type(hwmgr, type, clocks);
1356 	mutex_unlock(&pp_handle->pp_lock);
1357 	return ret;
1358 }
1359 
amd_powerplay_get_clock_by_type_with_latency(void * handle,enum amd_pp_clock_type type,struct pp_clock_levels_with_latency * clocks)1360 int amd_powerplay_get_clock_by_type_with_latency(void *handle,
1361 		enum amd_pp_clock_type type,
1362 		struct pp_clock_levels_with_latency *clocks)
1363 {
1364 	struct pp_hwmgr *hwmgr;
1365 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
1366 	int ret = 0;
1367 
1368 	ret = pp_check(pp_handle);
1369 	if (ret != 0)
1370 		return ret;
1371 
1372 	if (!clocks)
1373 		return -EINVAL;
1374 
1375 	mutex_lock(&pp_handle->pp_lock);
1376 	hwmgr = ((struct pp_instance *)handle)->hwmgr;
1377 	ret = phm_get_clock_by_type_with_latency(hwmgr, type, clocks);
1378 	mutex_unlock(&pp_handle->pp_lock);
1379 	return ret;
1380 }
1381 
amd_powerplay_get_clock_by_type_with_voltage(void * handle,enum amd_pp_clock_type type,struct pp_clock_levels_with_voltage * clocks)1382 int amd_powerplay_get_clock_by_type_with_voltage(void *handle,
1383 		enum amd_pp_clock_type type,
1384 		struct pp_clock_levels_with_voltage *clocks)
1385 {
1386 	struct pp_hwmgr *hwmgr;
1387 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
1388 	int ret = 0;
1389 
1390 	ret = pp_check(pp_handle);
1391 	if (ret != 0)
1392 		return ret;
1393 
1394 	if (!clocks)
1395 		return -EINVAL;
1396 
1397 	hwmgr = ((struct pp_instance *)handle)->hwmgr;
1398 
1399 	mutex_lock(&pp_handle->pp_lock);
1400 
1401 	ret = phm_get_clock_by_type_with_voltage(hwmgr, type, clocks);
1402 
1403 	mutex_unlock(&pp_handle->pp_lock);
1404 	return ret;
1405 }
1406 
amd_powerplay_set_watermarks_for_clocks_ranges(void * handle,struct pp_wm_sets_with_clock_ranges_soc15 * wm_with_clock_ranges)1407 int amd_powerplay_set_watermarks_for_clocks_ranges(void *handle,
1408 		struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges)
1409 {
1410 	struct pp_hwmgr *hwmgr;
1411 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
1412 	int ret = 0;
1413 
1414 	ret = pp_check(pp_handle);
1415 	if (ret != 0)
1416 		return ret;
1417 
1418 	if (!wm_with_clock_ranges)
1419 		return -EINVAL;
1420 
1421 	hwmgr = ((struct pp_instance *)handle)->hwmgr;
1422 
1423 	mutex_lock(&pp_handle->pp_lock);
1424 	ret = phm_set_watermarks_for_clocks_ranges(hwmgr,
1425 			wm_with_clock_ranges);
1426 	mutex_unlock(&pp_handle->pp_lock);
1427 
1428 	return ret;
1429 }
1430 
amd_powerplay_display_clock_voltage_request(void * handle,struct pp_display_clock_request * clock)1431 int amd_powerplay_display_clock_voltage_request(void *handle,
1432 		struct pp_display_clock_request *clock)
1433 {
1434 	struct pp_hwmgr *hwmgr;
1435 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
1436 	int ret = 0;
1437 
1438 	ret = pp_check(pp_handle);
1439 	if (ret != 0)
1440 		return ret;
1441 
1442 	if (!clock)
1443 		return -EINVAL;
1444 
1445 	hwmgr = ((struct pp_instance *)handle)->hwmgr;
1446 
1447 	mutex_lock(&pp_handle->pp_lock);
1448 	ret = phm_display_clock_voltage_request(hwmgr, clock);
1449 	mutex_unlock(&pp_handle->pp_lock);
1450 
1451 	return ret;
1452 }
1453 
amd_powerplay_get_display_mode_validation_clocks(void * handle,struct amd_pp_simple_clock_info * clocks)1454 int amd_powerplay_get_display_mode_validation_clocks(void *handle,
1455 		struct amd_pp_simple_clock_info *clocks)
1456 {
1457 	struct pp_hwmgr  *hwmgr;
1458 	struct pp_instance *pp_handle = (struct pp_instance *)handle;
1459 	int ret = 0;
1460 
1461 	ret = pp_check(pp_handle);
1462 
1463 	if (ret != 0)
1464 		return ret;
1465 
1466 	hwmgr = pp_handle->hwmgr;
1467 
1468 	if (clocks == NULL)
1469 		return -EINVAL;
1470 
1471 	mutex_lock(&pp_handle->pp_lock);
1472 
1473 	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DynamicPatchPowerState))
1474 		ret = phm_get_max_high_clocks(hwmgr, clocks);
1475 
1476 	mutex_unlock(&pp_handle->pp_lock);
1477 	return ret;
1478 }
1479 
1480