2 * Copyright 2015 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
23 #include <linux/types.h>
24 #include <linux/kernel.h>
25 #include <linux/gfp.h>
26 #include <linux/slab.h>
27 #include "amd_shared.h"
28 #include "amd_powerplay.h"
29 #include "pp_instance.h"
30 #include "power_state.h"
31 #include "eventmanager.h"
33 #define PP_CHECK(handle) \
35 if ((handle) == NULL || (handle)->pp_valid != PP_VALID) \
39 static int pp_early_init(void *handle
)
44 static int pp_sw_init(void *handle
)
46 struct pp_instance
*pp_handle
;
47 struct pp_hwmgr
*hwmgr
;
53 pp_handle
= (struct pp_instance
*)handle
;
54 hwmgr
= pp_handle
->hwmgr
;
56 if (hwmgr
== NULL
|| hwmgr
->pptable_func
== NULL
||
57 hwmgr
->hwmgr_func
== NULL
||
58 hwmgr
->pptable_func
->pptable_init
== NULL
||
59 hwmgr
->hwmgr_func
->backend_init
== NULL
)
62 ret
= hwmgr
->pptable_func
->pptable_init(hwmgr
);
65 ret
= hwmgr
->hwmgr_func
->backend_init(hwmgr
);
68 printk("amdgpu: powerplay initialization failed\n");
70 printk("amdgpu: powerplay initialized\n");
75 static int pp_sw_fini(void *handle
)
77 struct pp_instance
*pp_handle
;
78 struct pp_hwmgr
*hwmgr
;
84 pp_handle
= (struct pp_instance
*)handle
;
85 hwmgr
= pp_handle
->hwmgr
;
87 if (hwmgr
!= NULL
|| hwmgr
->hwmgr_func
!= NULL
||
88 hwmgr
->hwmgr_func
->backend_fini
!= NULL
)
89 ret
= hwmgr
->hwmgr_func
->backend_fini(hwmgr
);
94 static int pp_hw_init(void *handle
)
96 struct pp_instance
*pp_handle
;
97 struct pp_smumgr
*smumgr
;
98 struct pp_eventmgr
*eventmgr
;
104 pp_handle
= (struct pp_instance
*)handle
;
105 smumgr
= pp_handle
->smu_mgr
;
107 if (smumgr
== NULL
|| smumgr
->smumgr_funcs
== NULL
||
108 smumgr
->smumgr_funcs
->smu_init
== NULL
||
109 smumgr
->smumgr_funcs
->start_smu
== NULL
)
112 ret
= smumgr
->smumgr_funcs
->smu_init(smumgr
);
114 printk(KERN_ERR
"[ powerplay ] smc initialization failed\n");
118 ret
= smumgr
->smumgr_funcs
->start_smu(smumgr
);
120 printk(KERN_ERR
"[ powerplay ] smc start failed\n");
121 smumgr
->smumgr_funcs
->smu_fini(smumgr
);
125 hw_init_power_state_table(pp_handle
->hwmgr
);
126 eventmgr
= pp_handle
->eventmgr
;
128 if (eventmgr
== NULL
|| eventmgr
->pp_eventmgr_init
== NULL
)
131 ret
= eventmgr
->pp_eventmgr_init(eventmgr
);
135 static int pp_hw_fini(void *handle
)
137 struct pp_instance
*pp_handle
;
138 struct pp_smumgr
*smumgr
;
139 struct pp_eventmgr
*eventmgr
;
144 pp_handle
= (struct pp_instance
*)handle
;
145 eventmgr
= pp_handle
->eventmgr
;
147 if (eventmgr
!= NULL
|| eventmgr
->pp_eventmgr_fini
!= NULL
)
148 eventmgr
->pp_eventmgr_fini(eventmgr
);
150 smumgr
= pp_handle
->smu_mgr
;
152 if (smumgr
!= NULL
|| smumgr
->smumgr_funcs
!= NULL
||
153 smumgr
->smumgr_funcs
->smu_fini
!= NULL
)
154 smumgr
->smumgr_funcs
->smu_fini(smumgr
);
159 static bool pp_is_idle(void *handle
)
164 static int pp_wait_for_idle(void *handle
)
169 static int pp_sw_reset(void *handle
)
174 static void pp_print_status(void *handle
)
179 static int pp_set_clockgating_state(void *handle
,
180 enum amd_clockgating_state state
)
185 static int pp_set_powergating_state(void *handle
,
186 enum amd_powergating_state state
)
191 static int pp_suspend(void *handle
)
193 struct pp_instance
*pp_handle
;
194 struct pp_eventmgr
*eventmgr
;
195 struct pem_event_data event_data
= { {0} };
200 pp_handle
= (struct pp_instance
*)handle
;
201 eventmgr
= pp_handle
->eventmgr
;
202 pem_handle_event(eventmgr
, AMD_PP_EVENT_SUSPEND
, &event_data
);
206 static int pp_resume(void *handle
)
208 struct pp_instance
*pp_handle
;
209 struct pp_eventmgr
*eventmgr
;
210 struct pem_event_data event_data
= { {0} };
211 struct pp_smumgr
*smumgr
;
217 pp_handle
= (struct pp_instance
*)handle
;
218 smumgr
= pp_handle
->smu_mgr
;
220 if (smumgr
== NULL
|| smumgr
->smumgr_funcs
== NULL
||
221 smumgr
->smumgr_funcs
->start_smu
== NULL
)
224 ret
= smumgr
->smumgr_funcs
->start_smu(smumgr
);
226 printk(KERN_ERR
"[ powerplay ] smc start failed\n");
227 smumgr
->smumgr_funcs
->smu_fini(smumgr
);
231 eventmgr
= pp_handle
->eventmgr
;
232 pem_handle_event(eventmgr
, AMD_PP_EVENT_RESUME
, &event_data
);
237 const struct amd_ip_funcs pp_ip_funcs
= {
238 .early_init
= pp_early_init
,
240 .sw_init
= pp_sw_init
,
241 .sw_fini
= pp_sw_fini
,
242 .hw_init
= pp_hw_init
,
243 .hw_fini
= pp_hw_fini
,
244 .suspend
= pp_suspend
,
246 .is_idle
= pp_is_idle
,
247 .wait_for_idle
= pp_wait_for_idle
,
248 .soft_reset
= pp_sw_reset
,
249 .print_status
= pp_print_status
,
250 .set_clockgating_state
= pp_set_clockgating_state
,
251 .set_powergating_state
= pp_set_powergating_state
,
254 static int pp_dpm_load_fw(void *handle
)
259 static int pp_dpm_fw_loading_complete(void *handle
)
264 static int pp_dpm_force_performance_level(void *handle
,
265 enum amd_dpm_forced_level level
)
267 struct pp_instance
*pp_handle
;
268 struct pp_hwmgr
*hwmgr
;
273 pp_handle
= (struct pp_instance
*)handle
;
275 hwmgr
= pp_handle
->hwmgr
;
277 if (hwmgr
== NULL
|| hwmgr
->hwmgr_func
== NULL
||
278 hwmgr
->hwmgr_func
->force_dpm_level
== NULL
)
281 hwmgr
->hwmgr_func
->force_dpm_level(hwmgr
, level
);
286 static enum amd_dpm_forced_level
pp_dpm_get_performance_level(
289 struct pp_hwmgr
*hwmgr
;
294 hwmgr
= ((struct pp_instance
*)handle
)->hwmgr
;
299 return (((struct pp_instance
*)handle
)->hwmgr
->dpm_level
);
302 static int pp_dpm_get_sclk(void *handle
, bool low
)
304 struct pp_hwmgr
*hwmgr
;
309 hwmgr
= ((struct pp_instance
*)handle
)->hwmgr
;
311 if (hwmgr
== NULL
|| hwmgr
->hwmgr_func
== NULL
||
312 hwmgr
->hwmgr_func
->get_sclk
== NULL
)
315 return hwmgr
->hwmgr_func
->get_sclk(hwmgr
, low
);
318 static int pp_dpm_get_mclk(void *handle
, bool low
)
320 struct pp_hwmgr
*hwmgr
;
325 hwmgr
= ((struct pp_instance
*)handle
)->hwmgr
;
327 if (hwmgr
== NULL
|| hwmgr
->hwmgr_func
== NULL
||
328 hwmgr
->hwmgr_func
->get_mclk
== NULL
)
331 return hwmgr
->hwmgr_func
->get_mclk(hwmgr
, low
);
334 static int pp_dpm_powergate_vce(void *handle
, bool gate
)
336 struct pp_hwmgr
*hwmgr
;
341 hwmgr
= ((struct pp_instance
*)handle
)->hwmgr
;
343 if (hwmgr
== NULL
|| hwmgr
->hwmgr_func
== NULL
||
344 hwmgr
->hwmgr_func
->powergate_vce
== NULL
)
347 return hwmgr
->hwmgr_func
->powergate_vce(hwmgr
, gate
);
350 static int pp_dpm_powergate_uvd(void *handle
, bool gate
)
352 struct pp_hwmgr
*hwmgr
;
357 hwmgr
= ((struct pp_instance
*)handle
)->hwmgr
;
359 if (hwmgr
== NULL
|| hwmgr
->hwmgr_func
== NULL
||
360 hwmgr
->hwmgr_func
->powergate_uvd
== NULL
)
363 return hwmgr
->hwmgr_func
->powergate_uvd(hwmgr
, gate
);
366 static enum PP_StateUILabel
power_state_convert(enum amd_pm_state_type state
)
369 case POWER_STATE_TYPE_BATTERY
:
370 return PP_StateUILabel_Battery
;
371 case POWER_STATE_TYPE_BALANCED
:
372 return PP_StateUILabel_Balanced
;
373 case POWER_STATE_TYPE_PERFORMANCE
:
374 return PP_StateUILabel_Performance
;
376 return PP_StateUILabel_None
;
380 int pp_dpm_dispatch_tasks(void *handle
, enum amd_pp_event event_id
, void *input
, void *output
)
383 struct pp_instance
*pp_handle
;
384 struct pem_event_data data
= { {0} };
386 pp_handle
= (struct pp_instance
*)handle
;
388 if (pp_handle
== NULL
)
392 case AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE
:
393 ret
= pem_handle_event(pp_handle
->eventmgr
, event_id
, &data
);
395 case AMD_PP_EVENT_ENABLE_USER_STATE
:
397 enum amd_pm_state_type ps
;
401 ps
= *(unsigned long *)input
;
403 data
.requested_ui_label
= power_state_convert(ps
);
404 ret
= pem_handle_event(pp_handle
->eventmgr
, event_id
, &data
);
407 case AMD_PP_EVENT_COMPLETE_INIT
:
408 ret
= pem_handle_event(pp_handle
->eventmgr
, event_id
, &data
);
416 enum amd_pm_state_type
pp_dpm_get_current_power_state(void *handle
)
418 struct pp_hwmgr
*hwmgr
;
419 struct pp_power_state
*state
;
424 hwmgr
= ((struct pp_instance
*)handle
)->hwmgr
;
426 if (hwmgr
== NULL
|| hwmgr
->current_ps
== NULL
)
429 state
= hwmgr
->current_ps
;
431 switch (state
->classification
.ui_label
) {
432 case PP_StateUILabel_Battery
:
433 return POWER_STATE_TYPE_BATTERY
;
434 case PP_StateUILabel_Balanced
:
435 return POWER_STATE_TYPE_BALANCED
;
436 case PP_StateUILabel_Performance
:
437 return POWER_STATE_TYPE_PERFORMANCE
;
439 return POWER_STATE_TYPE_DEFAULT
;
444 pp_debugfs_print_current_performance_level(void *handle
,
447 struct pp_hwmgr
*hwmgr
;
452 hwmgr
= ((struct pp_instance
*)handle
)->hwmgr
;
454 if (hwmgr
== NULL
|| hwmgr
->hwmgr_func
== NULL
||
455 hwmgr
->hwmgr_func
->print_current_perforce_level
== NULL
)
458 hwmgr
->hwmgr_func
->print_current_perforce_level(hwmgr
, m
);
461 static int pp_dpm_set_fan_control_mode(void *handle
, uint32_t mode
)
463 struct pp_hwmgr
*hwmgr
;
468 hwmgr
= ((struct pp_instance
*)handle
)->hwmgr
;
470 if (hwmgr
== NULL
|| hwmgr
->hwmgr_func
== NULL
||
471 hwmgr
->hwmgr_func
->set_fan_control_mode
== NULL
)
474 return hwmgr
->hwmgr_func
->set_fan_control_mode(hwmgr
, mode
);
477 static int pp_dpm_get_fan_control_mode(void *handle
)
479 struct pp_hwmgr
*hwmgr
;
484 hwmgr
= ((struct pp_instance
*)handle
)->hwmgr
;
486 if (hwmgr
== NULL
|| hwmgr
->hwmgr_func
== NULL
||
487 hwmgr
->hwmgr_func
->get_fan_control_mode
== NULL
)
490 return hwmgr
->hwmgr_func
->get_fan_control_mode(hwmgr
);
493 static int pp_dpm_set_fan_speed_percent(void *handle
, uint32_t percent
)
495 struct pp_hwmgr
*hwmgr
;
500 hwmgr
= ((struct pp_instance
*)handle
)->hwmgr
;
502 if (hwmgr
== NULL
|| hwmgr
->hwmgr_func
== NULL
||
503 hwmgr
->hwmgr_func
->set_fan_speed_percent
== NULL
)
506 return hwmgr
->hwmgr_func
->set_fan_speed_percent(hwmgr
, percent
);
509 static int pp_dpm_get_fan_speed_percent(void *handle
, uint32_t *speed
)
511 struct pp_hwmgr
*hwmgr
;
516 hwmgr
= ((struct pp_instance
*)handle
)->hwmgr
;
518 if (hwmgr
== NULL
|| hwmgr
->hwmgr_func
== NULL
||
519 hwmgr
->hwmgr_func
->get_fan_speed_percent
== NULL
)
522 return hwmgr
->hwmgr_func
->get_fan_speed_percent(hwmgr
, speed
);
525 static int pp_dpm_get_temperature(void *handle
)
527 struct pp_hwmgr
*hwmgr
;
532 hwmgr
= ((struct pp_instance
*)handle
)->hwmgr
;
534 if (hwmgr
== NULL
|| hwmgr
->hwmgr_func
== NULL
||
535 hwmgr
->hwmgr_func
->get_temperature
== NULL
)
538 return hwmgr
->hwmgr_func
->get_temperature(hwmgr
);
541 const struct amd_powerplay_funcs pp_dpm_funcs
= {
542 .get_temperature
= pp_dpm_get_temperature
,
543 .load_firmware
= pp_dpm_load_fw
,
544 .wait_for_fw_loading_complete
= pp_dpm_fw_loading_complete
,
545 .force_performance_level
= pp_dpm_force_performance_level
,
546 .get_performance_level
= pp_dpm_get_performance_level
,
547 .get_current_power_state
= pp_dpm_get_current_power_state
,
548 .get_sclk
= pp_dpm_get_sclk
,
549 .get_mclk
= pp_dpm_get_mclk
,
550 .powergate_vce
= pp_dpm_powergate_vce
,
551 .powergate_uvd
= pp_dpm_powergate_uvd
,
552 .dispatch_tasks
= pp_dpm_dispatch_tasks
,
553 .print_current_performance_level
= pp_debugfs_print_current_performance_level
,
554 .set_fan_control_mode
= pp_dpm_set_fan_control_mode
,
555 .get_fan_control_mode
= pp_dpm_get_fan_control_mode
,
556 .set_fan_speed_percent
= pp_dpm_set_fan_speed_percent
,
557 .get_fan_speed_percent
= pp_dpm_get_fan_speed_percent
,
560 static int amd_pp_instance_init(struct amd_pp_init
*pp_init
,
561 struct amd_powerplay
*amd_pp
)
564 struct pp_instance
*handle
;
566 handle
= kzalloc(sizeof(struct pp_instance
), GFP_KERNEL
);
570 handle
->pp_valid
= PP_VALID
;
572 ret
= smum_init(pp_init
, handle
);
576 ret
= hwmgr_init(pp_init
, handle
);
580 ret
= eventmgr_init(handle
);
584 amd_pp
->pp_handle
= handle
;
588 hwmgr_fini(handle
->hwmgr
);
590 smum_fini(handle
->smu_mgr
);
596 static int amd_pp_instance_fini(void *handle
)
598 struct pp_instance
*instance
= (struct pp_instance
*)handle
;
600 if (instance
== NULL
)
603 eventmgr_fini(instance
->eventmgr
);
605 hwmgr_fini(instance
->hwmgr
);
607 smum_fini(instance
->smu_mgr
);
613 int amd_powerplay_init(struct amd_pp_init
*pp_init
,
614 struct amd_powerplay
*amd_pp
)
618 if (pp_init
== NULL
|| amd_pp
== NULL
)
621 ret
= amd_pp_instance_init(pp_init
, amd_pp
);
626 amd_pp
->ip_funcs
= &pp_ip_funcs
;
627 amd_pp
->pp_funcs
= &pp_dpm_funcs
;
632 int amd_powerplay_fini(void *handle
)
634 amd_pp_instance_fini(handle
);
639 /* export this function to DAL */
641 int amd_powerplay_display_configuration_change(void *handle
, const void *input
)
643 struct pp_hwmgr
*hwmgr
;
644 const struct amd_pp_display_configuration
*display_config
= input
;
646 PP_CHECK((struct pp_instance
*)handle
);
648 hwmgr
= ((struct pp_instance
*)handle
)->hwmgr
;
650 phm_store_dal_configuration_data(hwmgr
, display_config
);
655 int amd_powerplay_get_display_power_level(void *handle
,
656 struct amd_pp_dal_clock_info
*output
)
658 struct pp_hwmgr
*hwmgr
;
660 PP_CHECK((struct pp_instance
*)handle
);
665 hwmgr
= ((struct pp_instance
*)handle
)->hwmgr
;
667 return phm_get_dal_power_level(hwmgr
, output
);