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.
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"
35 static inline int pp_check(struct pp_instance *handle)
37 if (handle == NULL || handle->pp_valid != PP_VALID)
40 if (handle->smu_mgr == NULL || handle->smu_mgr->smumgr_funcs == NULL)
43 if (handle->pm_en == 0)
44 return PP_DPM_DISABLED;
46 if (handle->hwmgr == NULL || handle->hwmgr->hwmgr_func == NULL
47 || handle->eventmgr == NULL)
48 return PP_DPM_DISABLED;
53 static int pp_early_init(void *handle)
56 struct pp_instance *pp_handle = (struct pp_instance *)handle;
58 ret = smum_early_init(pp_handle);
62 if ((pp_handle->pm_en == 0)
63 || cgs_is_virtualization_enabled(pp_handle->device))
64 return PP_DPM_DISABLED;
66 ret = hwmgr_early_init(pp_handle);
69 return PP_DPM_DISABLED;
72 ret = eventmgr_early_init(pp_handle);
74 kfree(pp_handle->hwmgr);
75 pp_handle->hwmgr = NULL;
77 return PP_DPM_DISABLED;
83 static int pp_sw_init(void *handle)
85 struct pp_smumgr *smumgr;
87 struct pp_instance *pp_handle = (struct pp_instance *)handle;
89 ret = pp_check(pp_handle);
91 if (ret == 0 || ret == PP_DPM_DISABLED) {
92 smumgr = pp_handle->smu_mgr;
94 if (smumgr->smumgr_funcs->smu_init == NULL)
97 ret = smumgr->smumgr_funcs->smu_init(smumgr);
99 pr_info("amdgpu: powerplay sw initialized\n");
104 static int pp_sw_fini(void *handle)
106 struct pp_smumgr *smumgr;
108 struct pp_instance *pp_handle = (struct pp_instance *)handle;
110 ret = pp_check(pp_handle);
111 if (ret == 0 || ret == PP_DPM_DISABLED) {
112 smumgr = pp_handle->smu_mgr;
114 if (smumgr->smumgr_funcs->smu_fini == NULL)
117 ret = smumgr->smumgr_funcs->smu_fini(smumgr);
122 static int pp_hw_init(void *handle)
124 struct pp_smumgr *smumgr;
125 struct pp_eventmgr *eventmgr;
127 struct pp_instance *pp_handle = (struct pp_instance *)handle;
129 ret = pp_check(pp_handle);
131 if (ret == 0 || ret == PP_DPM_DISABLED) {
132 smumgr = pp_handle->smu_mgr;
134 if (smumgr->smumgr_funcs->start_smu == NULL)
137 if(smumgr->smumgr_funcs->start_smu(smumgr)) {
138 pr_err("smc start failed\n");
139 smumgr->smumgr_funcs->smu_fini(smumgr);
142 if (ret == PP_DPM_DISABLED)
143 return PP_DPM_DISABLED;
146 ret = hwmgr_hw_init(pp_handle);
150 eventmgr = pp_handle->eventmgr;
151 if (eventmgr->pp_eventmgr_init == NULL ||
152 eventmgr->pp_eventmgr_init(eventmgr))
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;
165 static int pp_hw_fini(void *handle)
167 struct pp_eventmgr *eventmgr;
168 struct pp_instance *pp_handle = (struct pp_instance *)handle;
171 ret = pp_check(pp_handle);
174 eventmgr = pp_handle->eventmgr;
176 if (eventmgr->pp_eventmgr_fini != NULL)
177 eventmgr->pp_eventmgr_fini(eventmgr);
179 hwmgr_hw_fini(pp_handle);
184 static bool pp_is_idle(void *handle)
189 static int pp_wait_for_idle(void *handle)
194 static int pp_sw_reset(void *handle)
200 int amd_set_clockgating_by_smu(void *handle, uint32_t msg_id)
202 struct pp_hwmgr *hwmgr;
203 struct pp_instance *pp_handle = (struct pp_instance *)handle;
206 ret = pp_check(pp_handle);
211 hwmgr = pp_handle->hwmgr;
213 if (hwmgr->hwmgr_func->update_clock_gatings == NULL) {
214 pr_info("%s was not implemented.\n", __func__);
218 return hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
221 static int pp_set_powergating_state(void *handle,
222 enum amd_powergating_state state)
224 struct pp_hwmgr *hwmgr;
225 struct pp_instance *pp_handle = (struct pp_instance *)handle;
228 ret = pp_check(pp_handle);
233 hwmgr = pp_handle->hwmgr;
235 if (hwmgr->hwmgr_func->enable_per_cu_power_gating == NULL) {
236 pr_info("%s was not implemented.\n", __func__);
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 ? true : false);
245 static int pp_suspend(void *handle)
247 struct pp_eventmgr *eventmgr;
248 struct pem_event_data event_data = { {0} };
249 struct pp_instance *pp_handle = (struct pp_instance *)handle;
252 ret = pp_check(pp_handle);
257 eventmgr = pp_handle->eventmgr;
258 pem_handle_event(eventmgr, AMD_PP_EVENT_SUSPEND, &event_data);
263 static int pp_resume(void *handle)
265 struct pp_eventmgr *eventmgr;
266 struct pem_event_data event_data = { {0} };
267 struct pp_smumgr *smumgr;
269 struct pp_instance *pp_handle = (struct pp_instance *)handle;
271 ret1 = pp_check(pp_handle);
273 if (ret1 != 0 && ret1 != PP_DPM_DISABLED)
276 smumgr = pp_handle->smu_mgr;
278 if (smumgr->smumgr_funcs->start_smu == NULL)
281 ret = smumgr->smumgr_funcs->start_smu(smumgr);
283 pr_err("smc start failed\n");
284 smumgr->smumgr_funcs->smu_fini(smumgr);
288 if (ret1 == PP_DPM_DISABLED)
291 eventmgr = pp_handle->eventmgr;
293 pem_handle_event(eventmgr, AMD_PP_EVENT_RESUME, &event_data);
298 const struct amd_ip_funcs pp_ip_funcs = {
300 .early_init = pp_early_init,
302 .sw_init = pp_sw_init,
303 .sw_fini = pp_sw_fini,
304 .hw_init = pp_hw_init,
305 .hw_fini = pp_hw_fini,
306 .suspend = pp_suspend,
308 .is_idle = pp_is_idle,
309 .wait_for_idle = pp_wait_for_idle,
310 .soft_reset = pp_sw_reset,
311 .set_clockgating_state = NULL,
312 .set_powergating_state = pp_set_powergating_state,
315 static int pp_dpm_load_fw(void *handle)
320 static int pp_dpm_fw_loading_complete(void *handle)
325 static int pp_dpm_force_performance_level(void *handle,
326 enum amd_dpm_forced_level level)
328 struct pp_hwmgr *hwmgr;
329 struct pp_instance *pp_handle = (struct pp_instance *)handle;
332 ret = pp_check(pp_handle);
337 hwmgr = pp_handle->hwmgr;
339 if (hwmgr->hwmgr_func->force_dpm_level == NULL) {
340 pr_info("%s was not implemented.\n", __func__);
344 hwmgr->hwmgr_func->force_dpm_level(hwmgr, level);
349 static enum amd_dpm_forced_level pp_dpm_get_performance_level(
352 struct pp_hwmgr *hwmgr;
353 struct pp_instance *pp_handle = (struct pp_instance *)handle;
356 ret = pp_check(pp_handle);
361 hwmgr = pp_handle->hwmgr;
363 return hwmgr->dpm_level;
366 static int pp_dpm_get_sclk(void *handle, bool low)
368 struct pp_hwmgr *hwmgr;
369 struct pp_instance *pp_handle = (struct pp_instance *)handle;
372 ret = pp_check(pp_handle);
377 hwmgr = pp_handle->hwmgr;
379 if (hwmgr->hwmgr_func->get_sclk == NULL) {
380 pr_info("%s was not implemented.\n", __func__);
384 return hwmgr->hwmgr_func->get_sclk(hwmgr, low);
387 static int pp_dpm_get_mclk(void *handle, bool low)
389 struct pp_hwmgr *hwmgr;
390 struct pp_instance *pp_handle = (struct pp_instance *)handle;
393 ret = pp_check(pp_handle);
398 hwmgr = pp_handle->hwmgr;
400 if (hwmgr->hwmgr_func->get_mclk == NULL) {
401 pr_info("%s was not implemented.\n", __func__);
405 return hwmgr->hwmgr_func->get_mclk(hwmgr, low);
408 static int pp_dpm_powergate_vce(void *handle, bool gate)
410 struct pp_hwmgr *hwmgr;
411 struct pp_instance *pp_handle = (struct pp_instance *)handle;
414 ret = pp_check(pp_handle);
419 hwmgr = pp_handle->hwmgr;
421 if (hwmgr->hwmgr_func->powergate_vce == NULL) {
422 pr_info("%s was not implemented.\n", __func__);
426 return hwmgr->hwmgr_func->powergate_vce(hwmgr, gate);
429 static int pp_dpm_powergate_uvd(void *handle, bool gate)
431 struct pp_hwmgr *hwmgr;
432 struct pp_instance *pp_handle = (struct pp_instance *)handle;
435 ret = pp_check(pp_handle);
440 hwmgr = pp_handle->hwmgr;
442 if (hwmgr->hwmgr_func->powergate_uvd == NULL) {
443 pr_info("%s was not implemented.\n", __func__);
447 return hwmgr->hwmgr_func->powergate_uvd(hwmgr, gate);
450 static enum PP_StateUILabel power_state_convert(enum amd_pm_state_type state)
453 case POWER_STATE_TYPE_BATTERY:
454 return PP_StateUILabel_Battery;
455 case POWER_STATE_TYPE_BALANCED:
456 return PP_StateUILabel_Balanced;
457 case POWER_STATE_TYPE_PERFORMANCE:
458 return PP_StateUILabel_Performance;
460 return PP_StateUILabel_None;
464 static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_event event_id,
465 void *input, void *output)
468 struct pem_event_data data = { {0} };
469 struct pp_instance *pp_handle = (struct pp_instance *)handle;
471 ret = pp_check(pp_handle);
477 case AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE:
478 ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
480 case AMD_PP_EVENT_ENABLE_USER_STATE:
482 enum amd_pm_state_type ps;
486 ps = *(unsigned long *)input;
488 data.requested_ui_label = power_state_convert(ps);
489 ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
492 case AMD_PP_EVENT_COMPLETE_INIT:
493 ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
495 case AMD_PP_EVENT_READJUST_POWER_STATE:
496 ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
504 static enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle)
506 struct pp_hwmgr *hwmgr;
507 struct pp_power_state *state;
508 struct pp_instance *pp_handle = (struct pp_instance *)handle;
511 ret = pp_check(pp_handle);
516 hwmgr = pp_handle->hwmgr;
518 if (hwmgr->current_ps == NULL)
521 state = hwmgr->current_ps;
523 switch (state->classification.ui_label) {
524 case PP_StateUILabel_Battery:
525 return POWER_STATE_TYPE_BATTERY;
526 case PP_StateUILabel_Balanced:
527 return POWER_STATE_TYPE_BALANCED;
528 case PP_StateUILabel_Performance:
529 return POWER_STATE_TYPE_PERFORMANCE;
531 if (state->classification.flags & PP_StateClassificationFlag_Boot)
532 return POWER_STATE_TYPE_INTERNAL_BOOT;
534 return POWER_STATE_TYPE_DEFAULT;
538 static int pp_dpm_set_fan_control_mode(void *handle, uint32_t mode)
540 struct pp_hwmgr *hwmgr;
541 struct pp_instance *pp_handle = (struct pp_instance *)handle;
544 ret = pp_check(pp_handle);
549 hwmgr = pp_handle->hwmgr;
551 if (hwmgr->hwmgr_func->set_fan_control_mode == NULL) {
552 pr_info("%s was not implemented.\n", __func__);
556 return hwmgr->hwmgr_func->set_fan_control_mode(hwmgr, mode);
559 static int pp_dpm_get_fan_control_mode(void *handle)
561 struct pp_hwmgr *hwmgr;
562 struct pp_instance *pp_handle = (struct pp_instance *)handle;
565 ret = pp_check(pp_handle);
570 hwmgr = pp_handle->hwmgr;
572 if (hwmgr->hwmgr_func->get_fan_control_mode == NULL) {
573 pr_info("%s was not implemented.\n", __func__);
577 return hwmgr->hwmgr_func->get_fan_control_mode(hwmgr);
580 static int pp_dpm_set_fan_speed_percent(void *handle, uint32_t percent)
582 struct pp_hwmgr *hwmgr;
583 struct pp_instance *pp_handle = (struct pp_instance *)handle;
586 ret = pp_check(pp_handle);
591 hwmgr = pp_handle->hwmgr;
593 if (hwmgr->hwmgr_func->set_fan_speed_percent == NULL) {
594 pr_info("%s was not implemented.\n", __func__);
598 return hwmgr->hwmgr_func->set_fan_speed_percent(hwmgr, percent);
601 static int pp_dpm_get_fan_speed_percent(void *handle, uint32_t *speed)
603 struct pp_hwmgr *hwmgr;
604 struct pp_instance *pp_handle = (struct pp_instance *)handle;
607 ret = pp_check(pp_handle);
612 hwmgr = pp_handle->hwmgr;
614 if (hwmgr->hwmgr_func->get_fan_speed_percent == NULL) {
615 pr_info("%s was not implemented.\n", __func__);
619 return hwmgr->hwmgr_func->get_fan_speed_percent(hwmgr, speed);
622 static int pp_dpm_get_fan_speed_rpm(void *handle, uint32_t *rpm)
624 struct pp_hwmgr *hwmgr;
625 struct pp_instance *pp_handle = (struct pp_instance *)handle;
628 ret = pp_check(pp_handle);
633 hwmgr = pp_handle->hwmgr;
635 if (hwmgr->hwmgr_func->get_fan_speed_rpm == NULL)
638 return hwmgr->hwmgr_func->get_fan_speed_rpm(hwmgr, rpm);
641 static int pp_dpm_get_temperature(void *handle)
643 struct pp_hwmgr *hwmgr;
644 struct pp_instance *pp_handle = (struct pp_instance *)handle;
647 ret = pp_check(pp_handle);
652 hwmgr = pp_handle->hwmgr;
654 if (hwmgr->hwmgr_func->get_temperature == NULL) {
655 pr_info("%s was not implemented.\n", __func__);
659 return hwmgr->hwmgr_func->get_temperature(hwmgr);
662 static int pp_dpm_get_pp_num_states(void *handle,
663 struct pp_states_info *data)
665 struct pp_hwmgr *hwmgr;
667 struct pp_instance *pp_handle = (struct pp_instance *)handle;
670 ret = pp_check(pp_handle);
675 hwmgr = pp_handle->hwmgr;
677 if (hwmgr->ps == NULL)
680 data->nums = hwmgr->num_ps;
682 for (i = 0; i < hwmgr->num_ps; i++) {
683 struct pp_power_state *state = (struct pp_power_state *)
684 ((unsigned long)hwmgr->ps + i * hwmgr->ps_size);
685 switch (state->classification.ui_label) {
686 case PP_StateUILabel_Battery:
687 data->states[i] = POWER_STATE_TYPE_BATTERY;
689 case PP_StateUILabel_Balanced:
690 data->states[i] = POWER_STATE_TYPE_BALANCED;
692 case PP_StateUILabel_Performance:
693 data->states[i] = POWER_STATE_TYPE_PERFORMANCE;
696 if (state->classification.flags & PP_StateClassificationFlag_Boot)
697 data->states[i] = POWER_STATE_TYPE_INTERNAL_BOOT;
699 data->states[i] = POWER_STATE_TYPE_DEFAULT;
706 static int pp_dpm_get_pp_table(void *handle, char **table)
708 struct pp_hwmgr *hwmgr;
709 struct pp_instance *pp_handle = (struct pp_instance *)handle;
712 ret = pp_check(pp_handle);
717 hwmgr = pp_handle->hwmgr;
719 if (!hwmgr->soft_pp_table)
722 *table = (char *)hwmgr->soft_pp_table;
724 return hwmgr->soft_pp_table_size;
727 static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size)
729 struct pp_hwmgr *hwmgr;
730 struct pp_instance *pp_handle = (struct pp_instance *)handle;
733 ret = pp_check(pp_handle);
738 hwmgr = pp_handle->hwmgr;
740 if (!hwmgr->hardcode_pp_table) {
741 hwmgr->hardcode_pp_table = kmemdup(hwmgr->soft_pp_table,
742 hwmgr->soft_pp_table_size,
745 if (!hwmgr->hardcode_pp_table)
749 memcpy(hwmgr->hardcode_pp_table, buf, size);
751 hwmgr->soft_pp_table = hwmgr->hardcode_pp_table;
753 return amd_powerplay_reset(handle);
756 static int pp_dpm_force_clock_level(void *handle,
757 enum pp_clock_type type, uint32_t mask)
759 struct pp_hwmgr *hwmgr;
760 struct pp_instance *pp_handle = (struct pp_instance *)handle;
763 ret = pp_check(pp_handle);
768 hwmgr = pp_handle->hwmgr;
770 if (hwmgr->hwmgr_func->force_clock_level == NULL) {
771 pr_info("%s was not implemented.\n", __func__);
775 return hwmgr->hwmgr_func->force_clock_level(hwmgr, type, mask);
778 static int pp_dpm_print_clock_levels(void *handle,
779 enum pp_clock_type type, char *buf)
781 struct pp_hwmgr *hwmgr;
782 struct pp_instance *pp_handle = (struct pp_instance *)handle;
785 ret = pp_check(pp_handle);
790 hwmgr = pp_handle->hwmgr;
792 if (hwmgr->hwmgr_func->print_clock_levels == NULL) {
793 pr_info("%s was not implemented.\n", __func__);
796 return hwmgr->hwmgr_func->print_clock_levels(hwmgr, type, buf);
799 static int pp_dpm_get_sclk_od(void *handle)
801 struct pp_hwmgr *hwmgr;
802 struct pp_instance *pp_handle = (struct pp_instance *)handle;
805 ret = pp_check(pp_handle);
810 hwmgr = pp_handle->hwmgr;
812 if (hwmgr->hwmgr_func->get_sclk_od == NULL) {
813 pr_info("%s was not implemented.\n", __func__);
817 return hwmgr->hwmgr_func->get_sclk_od(hwmgr);
820 static int pp_dpm_set_sclk_od(void *handle, uint32_t value)
822 struct pp_hwmgr *hwmgr;
823 struct pp_instance *pp_handle = (struct pp_instance *)handle;
826 ret = pp_check(pp_handle);
831 hwmgr = pp_handle->hwmgr;
833 if (hwmgr->hwmgr_func->set_sclk_od == NULL) {
834 pr_info("%s was not implemented.\n", __func__);
838 return hwmgr->hwmgr_func->set_sclk_od(hwmgr, value);
841 static int pp_dpm_get_mclk_od(void *handle)
843 struct pp_hwmgr *hwmgr;
844 struct pp_instance *pp_handle = (struct pp_instance *)handle;
847 ret = pp_check(pp_handle);
852 hwmgr = pp_handle->hwmgr;
854 if (hwmgr->hwmgr_func->get_mclk_od == NULL) {
855 pr_info("%s was not implemented.\n", __func__);
859 return hwmgr->hwmgr_func->get_mclk_od(hwmgr);
862 static int pp_dpm_set_mclk_od(void *handle, uint32_t value)
864 struct pp_hwmgr *hwmgr;
865 struct pp_instance *pp_handle = (struct pp_instance *)handle;
868 ret = pp_check(pp_handle);
873 hwmgr = pp_handle->hwmgr;
875 if (hwmgr->hwmgr_func->set_mclk_od == NULL) {
876 pr_info("%s was not implemented.\n", __func__);
880 return hwmgr->hwmgr_func->set_mclk_od(hwmgr, value);
883 static int pp_dpm_read_sensor(void *handle, int idx, int32_t *value)
885 struct pp_hwmgr *hwmgr;
886 struct pp_instance *pp_handle = (struct pp_instance *)handle;
889 ret = pp_check(pp_handle);
894 hwmgr = pp_handle->hwmgr;
896 if (hwmgr->hwmgr_func->read_sensor == NULL) {
897 pr_info("%s was not implemented.\n", __func__);
901 return hwmgr->hwmgr_func->read_sensor(hwmgr, idx, value);
904 static struct amd_vce_state*
905 pp_dpm_get_vce_clock_state(void *handle, unsigned idx)
907 struct pp_hwmgr *hwmgr;
908 struct pp_instance *pp_handle = (struct pp_instance *)handle;
911 ret = pp_check(pp_handle);
916 hwmgr = pp_handle->hwmgr;
918 if (hwmgr && idx < hwmgr->num_vce_state_tables)
919 return &hwmgr->vce_states[idx];
924 const struct amd_powerplay_funcs pp_dpm_funcs = {
925 .get_temperature = pp_dpm_get_temperature,
926 .load_firmware = pp_dpm_load_fw,
927 .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete,
928 .force_performance_level = pp_dpm_force_performance_level,
929 .get_performance_level = pp_dpm_get_performance_level,
930 .get_current_power_state = pp_dpm_get_current_power_state,
931 .get_sclk = pp_dpm_get_sclk,
932 .get_mclk = pp_dpm_get_mclk,
933 .powergate_vce = pp_dpm_powergate_vce,
934 .powergate_uvd = pp_dpm_powergate_uvd,
935 .dispatch_tasks = pp_dpm_dispatch_tasks,
936 .set_fan_control_mode = pp_dpm_set_fan_control_mode,
937 .get_fan_control_mode = pp_dpm_get_fan_control_mode,
938 .set_fan_speed_percent = pp_dpm_set_fan_speed_percent,
939 .get_fan_speed_percent = pp_dpm_get_fan_speed_percent,
940 .get_fan_speed_rpm = pp_dpm_get_fan_speed_rpm,
941 .get_pp_num_states = pp_dpm_get_pp_num_states,
942 .get_pp_table = pp_dpm_get_pp_table,
943 .set_pp_table = pp_dpm_set_pp_table,
944 .force_clock_level = pp_dpm_force_clock_level,
945 .print_clock_levels = pp_dpm_print_clock_levels,
946 .get_sclk_od = pp_dpm_get_sclk_od,
947 .set_sclk_od = pp_dpm_set_sclk_od,
948 .get_mclk_od = pp_dpm_get_mclk_od,
949 .set_mclk_od = pp_dpm_set_mclk_od,
950 .read_sensor = pp_dpm_read_sensor,
951 .get_vce_clock_state = pp_dpm_get_vce_clock_state,
954 int amd_powerplay_create(struct amd_pp_init *pp_init,
957 struct pp_instance *instance;
959 if (pp_init == NULL || handle == NULL)
962 instance = kzalloc(sizeof(struct pp_instance), GFP_KERNEL);
963 if (instance == NULL)
966 instance->pp_valid = PP_VALID;
967 instance->chip_family = pp_init->chip_family;
968 instance->chip_id = pp_init->chip_id;
969 instance->pm_en = pp_init->pm_en;
970 instance->feature_mask = pp_init->feature_mask;
971 instance->device = pp_init->device;
977 int amd_powerplay_destroy(void *handle)
979 struct pp_instance *instance = (struct pp_instance *)handle;
981 if (instance->pm_en) {
982 kfree(instance->eventmgr);
983 kfree(instance->hwmgr);
984 instance->hwmgr = NULL;
985 instance->eventmgr = NULL;
988 kfree(instance->smu_mgr);
989 instance->smu_mgr = NULL;
995 int amd_powerplay_reset(void *handle)
997 struct pp_instance *instance = (struct pp_instance *)handle;
998 struct pp_eventmgr *eventmgr;
999 struct pem_event_data event_data = { {0} };
1002 if (cgs_is_virtualization_enabled(instance->smu_mgr->device))
1003 return PP_DPM_DISABLED;
1005 ret = pp_check(instance);
1009 ret = pp_hw_fini(handle);
1013 ret = hwmgr_hw_init(instance);
1015 return PP_DPM_DISABLED;
1017 eventmgr = instance->eventmgr;
1019 if (eventmgr->pp_eventmgr_init == NULL)
1020 return PP_DPM_DISABLED;
1022 ret = eventmgr->pp_eventmgr_init(eventmgr);
1026 return pem_handle_event(eventmgr, AMD_PP_EVENT_COMPLETE_INIT, &event_data);
1029 /* export this function to DAL */
1031 int amd_powerplay_display_configuration_change(void *handle,
1032 const struct amd_pp_display_configuration *display_config)
1034 struct pp_hwmgr *hwmgr;
1035 struct pp_instance *pp_handle = (struct pp_instance *)handle;
1038 ret = pp_check(pp_handle);
1043 hwmgr = pp_handle->hwmgr;
1045 phm_store_dal_configuration_data(hwmgr, display_config);
1050 int amd_powerplay_get_display_power_level(void *handle,
1051 struct amd_pp_simple_clock_info *output)
1053 struct pp_hwmgr *hwmgr;
1054 struct pp_instance *pp_handle = (struct pp_instance *)handle;
1057 ret = pp_check(pp_handle);
1062 hwmgr = pp_handle->hwmgr;
1067 return phm_get_dal_power_level(hwmgr, output);
1070 int amd_powerplay_get_current_clocks(void *handle,
1071 struct amd_pp_clock_info *clocks)
1073 struct amd_pp_simple_clock_info simple_clocks;
1074 struct pp_clock_info hw_clocks;
1075 struct pp_hwmgr *hwmgr;
1076 struct pp_instance *pp_handle = (struct pp_instance *)handle;
1079 ret = pp_check(pp_handle);
1084 hwmgr = pp_handle->hwmgr;
1086 phm_get_dal_power_level(hwmgr, &simple_clocks);
1088 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PowerContainment)) {
1089 if (0 != phm_get_clock_info(hwmgr, &hwmgr->current_ps->hardware, &hw_clocks, PHM_PerformanceLevelDesignation_PowerContainment))
1090 PP_ASSERT_WITH_CODE(0, "Error in PHM_GetPowerContainmentClockInfo", return -1);
1092 if (0 != phm_get_clock_info(hwmgr, &hwmgr->current_ps->hardware, &hw_clocks, PHM_PerformanceLevelDesignation_Activity))
1093 PP_ASSERT_WITH_CODE(0, "Error in PHM_GetClockInfo", return -1);
1096 clocks->min_engine_clock = hw_clocks.min_eng_clk;
1097 clocks->max_engine_clock = hw_clocks.max_eng_clk;
1098 clocks->min_memory_clock = hw_clocks.min_mem_clk;
1099 clocks->max_memory_clock = hw_clocks.max_mem_clk;
1100 clocks->min_bus_bandwidth = hw_clocks.min_bus_bandwidth;
1101 clocks->max_bus_bandwidth = hw_clocks.max_bus_bandwidth;
1103 clocks->max_engine_clock_in_sr = hw_clocks.max_eng_clk;
1104 clocks->min_engine_clock_in_sr = hw_clocks.min_eng_clk;
1106 clocks->max_clocks_state = simple_clocks.level;
1108 if (0 == phm_get_current_shallow_sleep_clocks(hwmgr, &hwmgr->current_ps->hardware, &hw_clocks)) {
1109 clocks->max_engine_clock_in_sr = hw_clocks.max_eng_clk;
1110 clocks->min_engine_clock_in_sr = hw_clocks.min_eng_clk;
1117 int amd_powerplay_get_clock_by_type(void *handle, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks)
1120 struct pp_hwmgr *hwmgr;
1121 struct pp_instance *pp_handle = (struct pp_instance *)handle;
1124 ret = pp_check(pp_handle);
1129 hwmgr = pp_handle->hwmgr;
1134 result = phm_get_clock_by_type(hwmgr, type, clocks);
1139 int amd_powerplay_get_display_mode_validation_clocks(void *handle,
1140 struct amd_pp_simple_clock_info *clocks)
1142 struct pp_hwmgr *hwmgr;
1143 struct pp_instance *pp_handle = (struct pp_instance *)handle;
1146 ret = pp_check(pp_handle);
1151 hwmgr = pp_handle->hwmgr;
1157 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DynamicPatchPowerState))
1158 ret = phm_get_max_high_clocks(hwmgr, clocks);