xref: /openbmc/linux/drivers/gpu/drm/amd/pm/powerplay/smumgr/smumgr.c (revision cdd38c5f1ce4398ec58fec95904b75824daab7b5)
1e098bc96SEvan Quan /*
2e098bc96SEvan Quan  * Copyright 2015 Advanced Micro Devices, Inc.
3e098bc96SEvan Quan  *
4e098bc96SEvan Quan  * Permission is hereby granted, free of charge, to any person obtaining a
5e098bc96SEvan Quan  * copy of this software and associated documentation files (the "Software"),
6e098bc96SEvan Quan  * to deal in the Software without restriction, including without limitation
7e098bc96SEvan Quan  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8e098bc96SEvan Quan  * and/or sell copies of the Software, and to permit persons to whom the
9e098bc96SEvan Quan  * Software is furnished to do so, subject to the following conditions:
10e098bc96SEvan Quan  *
11e098bc96SEvan Quan  * The above copyright notice and this permission notice shall be included in
12e098bc96SEvan Quan  * all copies or substantial portions of the Software.
13e098bc96SEvan Quan  *
14e098bc96SEvan Quan  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15e098bc96SEvan Quan  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16e098bc96SEvan Quan  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17e098bc96SEvan Quan  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18e098bc96SEvan Quan  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19e098bc96SEvan Quan  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20e098bc96SEvan Quan  * OTHER DEALINGS IN THE SOFTWARE.
21e098bc96SEvan Quan  *
22e098bc96SEvan Quan  */
23e098bc96SEvan Quan 
24e098bc96SEvan Quan #include <linux/delay.h>
25e098bc96SEvan Quan #include <linux/kernel.h>
26e098bc96SEvan Quan #include <linux/module.h>
27e098bc96SEvan Quan #include <linux/slab.h>
28e098bc96SEvan Quan #include <linux/types.h>
29e098bc96SEvan Quan #include <drm/amdgpu_drm.h>
30e098bc96SEvan Quan #include "smumgr.h"
31e098bc96SEvan Quan 
32e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/bonaire_smc.bin");
33e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/bonaire_k_smc.bin");
34e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/hawaii_smc.bin");
35e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/hawaii_k_smc.bin");
36e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/topaz_smc.bin");
37e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/topaz_k_smc.bin");
38e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/tonga_smc.bin");
39e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/tonga_k_smc.bin");
40e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/fiji_smc.bin");
41e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/polaris10_smc.bin");
42e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin");
43e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/polaris10_k_smc.bin");
44e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/polaris10_k2_smc.bin");
45e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/polaris11_smc.bin");
46e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin");
47e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/polaris11_k_smc.bin");
48e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/polaris11_k2_smc.bin");
49e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/polaris12_smc.bin");
50e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/polaris12_k_smc.bin");
51e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/vegam_smc.bin");
52e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/vega10_smc.bin");
53e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/vega10_acg_smc.bin");
54e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/vega12_smc.bin");
55e098bc96SEvan Quan MODULE_FIRMWARE("amdgpu/vega20_smc.bin");
56e098bc96SEvan Quan 
smum_thermal_avfs_enable(struct pp_hwmgr * hwmgr)57e098bc96SEvan Quan int smum_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
58e098bc96SEvan Quan {
59e098bc96SEvan Quan 	if (NULL != hwmgr->smumgr_funcs->thermal_avfs_enable)
60e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->thermal_avfs_enable(hwmgr);
61e098bc96SEvan Quan 
62e098bc96SEvan Quan 	return 0;
63e098bc96SEvan Quan }
64e098bc96SEvan Quan 
smum_thermal_setup_fan_table(struct pp_hwmgr * hwmgr)65e098bc96SEvan Quan int smum_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
66e098bc96SEvan Quan {
67e098bc96SEvan Quan 	if (NULL != hwmgr->smumgr_funcs->thermal_setup_fan_table)
68e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->thermal_setup_fan_table(hwmgr);
69e098bc96SEvan Quan 
70e098bc96SEvan Quan 	return 0;
71e098bc96SEvan Quan }
72e098bc96SEvan Quan 
smum_update_sclk_threshold(struct pp_hwmgr * hwmgr)73e098bc96SEvan Quan int smum_update_sclk_threshold(struct pp_hwmgr *hwmgr)
74e098bc96SEvan Quan {
75e098bc96SEvan Quan 
76e098bc96SEvan Quan 	if (NULL != hwmgr->smumgr_funcs->update_sclk_threshold)
77e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->update_sclk_threshold(hwmgr);
78e098bc96SEvan Quan 
79e098bc96SEvan Quan 	return 0;
80e098bc96SEvan Quan }
81e098bc96SEvan Quan 
smum_update_smc_table(struct pp_hwmgr * hwmgr,uint32_t type)82e098bc96SEvan Quan int smum_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type)
83e098bc96SEvan Quan {
84e098bc96SEvan Quan 
85e098bc96SEvan Quan 	if (NULL != hwmgr->smumgr_funcs->update_smc_table)
86e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->update_smc_table(hwmgr, type);
87e098bc96SEvan Quan 
88e098bc96SEvan Quan 	return 0;
89e098bc96SEvan Quan }
90e098bc96SEvan Quan 
smum_get_offsetof(struct pp_hwmgr * hwmgr,uint32_t type,uint32_t member)91e098bc96SEvan Quan uint32_t smum_get_offsetof(struct pp_hwmgr *hwmgr, uint32_t type, uint32_t member)
92e098bc96SEvan Quan {
93e098bc96SEvan Quan 	if (NULL != hwmgr->smumgr_funcs->get_offsetof)
94e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->get_offsetof(type, member);
95e098bc96SEvan Quan 
96e098bc96SEvan Quan 	return 0;
97e098bc96SEvan Quan }
98e098bc96SEvan Quan 
smum_process_firmware_header(struct pp_hwmgr * hwmgr)99e098bc96SEvan Quan int smum_process_firmware_header(struct pp_hwmgr *hwmgr)
100e098bc96SEvan Quan {
101e098bc96SEvan Quan 	if (NULL != hwmgr->smumgr_funcs->process_firmware_header)
102e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->process_firmware_header(hwmgr);
103e098bc96SEvan Quan 	return 0;
104e098bc96SEvan Quan }
105e098bc96SEvan Quan 
smum_get_mac_definition(struct pp_hwmgr * hwmgr,uint32_t value)106e098bc96SEvan Quan uint32_t smum_get_mac_definition(struct pp_hwmgr *hwmgr, uint32_t value)
107e098bc96SEvan Quan {
108e098bc96SEvan Quan 	if (NULL != hwmgr->smumgr_funcs->get_mac_definition)
109e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->get_mac_definition(value);
110e098bc96SEvan Quan 
111e098bc96SEvan Quan 	return 0;
112e098bc96SEvan Quan }
113e098bc96SEvan Quan 
smum_download_powerplay_table(struct pp_hwmgr * hwmgr,void ** table)114e098bc96SEvan Quan int smum_download_powerplay_table(struct pp_hwmgr *hwmgr, void **table)
115e098bc96SEvan Quan {
116e098bc96SEvan Quan 	if (NULL != hwmgr->smumgr_funcs->download_pptable_settings)
117e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->download_pptable_settings(hwmgr,
118e098bc96SEvan Quan 									table);
119e098bc96SEvan Quan 	return 0;
120e098bc96SEvan Quan }
121e098bc96SEvan Quan 
smum_upload_powerplay_table(struct pp_hwmgr * hwmgr)122e098bc96SEvan Quan int smum_upload_powerplay_table(struct pp_hwmgr *hwmgr)
123e098bc96SEvan Quan {
124e098bc96SEvan Quan 	if (NULL != hwmgr->smumgr_funcs->upload_pptable_settings)
125e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->upload_pptable_settings(hwmgr);
126e098bc96SEvan Quan 
127e098bc96SEvan Quan 	return 0;
128e098bc96SEvan Quan }
129e098bc96SEvan Quan 
smum_send_msg_to_smc(struct pp_hwmgr * hwmgr,uint16_t msg,uint32_t * resp)130e098bc96SEvan Quan int smum_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t *resp)
131e098bc96SEvan Quan {
132e098bc96SEvan Quan 	int ret = 0;
133e098bc96SEvan Quan 
134e098bc96SEvan Quan 	if (hwmgr == NULL ||
135e098bc96SEvan Quan 	    hwmgr->smumgr_funcs->send_msg_to_smc == NULL ||
136e098bc96SEvan Quan 	    (resp && !hwmgr->smumgr_funcs->get_argument))
137e098bc96SEvan Quan 		return -EINVAL;
138e098bc96SEvan Quan 
139e098bc96SEvan Quan 	mutex_lock(&hwmgr->msg_lock);
140e098bc96SEvan Quan 
141e098bc96SEvan Quan 	ret = hwmgr->smumgr_funcs->send_msg_to_smc(hwmgr, msg);
142e098bc96SEvan Quan 	if (ret) {
143e098bc96SEvan Quan 		mutex_unlock(&hwmgr->msg_lock);
144e098bc96SEvan Quan 		return ret;
145e098bc96SEvan Quan 	}
146e098bc96SEvan Quan 
147e098bc96SEvan Quan 	if (resp)
148e098bc96SEvan Quan 		*resp = hwmgr->smumgr_funcs->get_argument(hwmgr);
149e098bc96SEvan Quan 
150e098bc96SEvan Quan 	mutex_unlock(&hwmgr->msg_lock);
151e098bc96SEvan Quan 
152e098bc96SEvan Quan 	return ret;
153e098bc96SEvan Quan }
154e098bc96SEvan Quan 
smum_send_msg_to_smc_with_parameter(struct pp_hwmgr * hwmgr,uint16_t msg,uint32_t parameter,uint32_t * resp)155e098bc96SEvan Quan int smum_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
156e098bc96SEvan Quan 					uint16_t msg,
157e098bc96SEvan Quan 					uint32_t parameter,
158e098bc96SEvan Quan 					uint32_t *resp)
159e098bc96SEvan Quan {
160e098bc96SEvan Quan 	int ret = 0;
161e098bc96SEvan Quan 
162e098bc96SEvan Quan 	if (hwmgr == NULL ||
163e098bc96SEvan Quan 	    hwmgr->smumgr_funcs->send_msg_to_smc_with_parameter == NULL ||
164e098bc96SEvan Quan 	    (resp && !hwmgr->smumgr_funcs->get_argument))
165e098bc96SEvan Quan 		return -EINVAL;
166e098bc96SEvan Quan 
167e098bc96SEvan Quan 	mutex_lock(&hwmgr->msg_lock);
168e098bc96SEvan Quan 
169e098bc96SEvan Quan 	ret = hwmgr->smumgr_funcs->send_msg_to_smc_with_parameter(
170e098bc96SEvan Quan 						hwmgr, msg, parameter);
171e098bc96SEvan Quan 	if (ret) {
172e098bc96SEvan Quan 		mutex_unlock(&hwmgr->msg_lock);
173e098bc96SEvan Quan 		return ret;
174e098bc96SEvan Quan 	}
175e098bc96SEvan Quan 
176e098bc96SEvan Quan 	if (resp)
177e098bc96SEvan Quan 		*resp = hwmgr->smumgr_funcs->get_argument(hwmgr);
178e098bc96SEvan Quan 
179e098bc96SEvan Quan 	mutex_unlock(&hwmgr->msg_lock);
180e098bc96SEvan Quan 
181e098bc96SEvan Quan 	return ret;
182e098bc96SEvan Quan }
183e098bc96SEvan Quan 
smum_init_smc_table(struct pp_hwmgr * hwmgr)184e098bc96SEvan Quan int smum_init_smc_table(struct pp_hwmgr *hwmgr)
185e098bc96SEvan Quan {
186e098bc96SEvan Quan 	if (NULL != hwmgr->smumgr_funcs->init_smc_table)
187e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->init_smc_table(hwmgr);
188e098bc96SEvan Quan 
189e098bc96SEvan Quan 	return 0;
190e098bc96SEvan Quan }
191e098bc96SEvan Quan 
smum_populate_all_graphic_levels(struct pp_hwmgr * hwmgr)192e098bc96SEvan Quan int smum_populate_all_graphic_levels(struct pp_hwmgr *hwmgr)
193e098bc96SEvan Quan {
194e098bc96SEvan Quan 	if (NULL != hwmgr->smumgr_funcs->populate_all_graphic_levels)
195e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->populate_all_graphic_levels(hwmgr);
196e098bc96SEvan Quan 
197e098bc96SEvan Quan 	return 0;
198e098bc96SEvan Quan }
199e098bc96SEvan Quan 
smum_populate_all_memory_levels(struct pp_hwmgr * hwmgr)200e098bc96SEvan Quan int smum_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
201e098bc96SEvan Quan {
202e098bc96SEvan Quan 	if (NULL != hwmgr->smumgr_funcs->populate_all_memory_levels)
203e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->populate_all_memory_levels(hwmgr);
204e098bc96SEvan Quan 
205e098bc96SEvan Quan 	return 0;
206e098bc96SEvan Quan }
207e098bc96SEvan Quan 
208e098bc96SEvan Quan /*this interface is needed by island ci/vi */
smum_initialize_mc_reg_table(struct pp_hwmgr * hwmgr)209e098bc96SEvan Quan int smum_initialize_mc_reg_table(struct pp_hwmgr *hwmgr)
210e098bc96SEvan Quan {
211e098bc96SEvan Quan 	if (NULL != hwmgr->smumgr_funcs->initialize_mc_reg_table)
212e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->initialize_mc_reg_table(hwmgr);
213e098bc96SEvan Quan 
214e098bc96SEvan Quan 	return 0;
215e098bc96SEvan Quan }
216e098bc96SEvan Quan 
smum_is_dpm_running(struct pp_hwmgr * hwmgr)217e098bc96SEvan Quan bool smum_is_dpm_running(struct pp_hwmgr *hwmgr)
218e098bc96SEvan Quan {
219e098bc96SEvan Quan 	if (NULL != hwmgr->smumgr_funcs->is_dpm_running)
220e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->is_dpm_running(hwmgr);
221e098bc96SEvan Quan 
222e098bc96SEvan Quan 	return true;
223e098bc96SEvan Quan }
224e098bc96SEvan Quan 
smum_is_hw_avfs_present(struct pp_hwmgr * hwmgr)225e098bc96SEvan Quan bool smum_is_hw_avfs_present(struct pp_hwmgr *hwmgr)
226e098bc96SEvan Quan {
227e098bc96SEvan Quan 	if (hwmgr->smumgr_funcs->is_hw_avfs_present)
228e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->is_hw_avfs_present(hwmgr);
229e098bc96SEvan Quan 
230e098bc96SEvan Quan 	return false;
231e098bc96SEvan Quan }
232e098bc96SEvan Quan 
smum_update_dpm_settings(struct pp_hwmgr * hwmgr,void * profile_setting)233e098bc96SEvan Quan int smum_update_dpm_settings(struct pp_hwmgr *hwmgr, void *profile_setting)
234e098bc96SEvan Quan {
235e098bc96SEvan Quan 	if (hwmgr->smumgr_funcs->update_dpm_settings)
236e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->update_dpm_settings(hwmgr, profile_setting);
237e098bc96SEvan Quan 
238e098bc96SEvan Quan 	return -EINVAL;
239e098bc96SEvan Quan }
240e098bc96SEvan Quan 
smum_smc_table_manager(struct pp_hwmgr * hwmgr,uint8_t * table,uint16_t table_id,bool rw)241e098bc96SEvan Quan int smum_smc_table_manager(struct pp_hwmgr *hwmgr, uint8_t *table, uint16_t table_id, bool rw)
242e098bc96SEvan Quan {
243e098bc96SEvan Quan 	if (hwmgr->smumgr_funcs->smc_table_manager)
244e098bc96SEvan Quan 		return hwmgr->smumgr_funcs->smc_table_manager(hwmgr, table, table_id, rw);
245e098bc96SEvan Quan 
246e098bc96SEvan Quan 	return -EINVAL;
247e098bc96SEvan Quan }
248*277b080fSEvan Quan 
smum_stop_smc(struct pp_hwmgr * hwmgr)249*277b080fSEvan Quan int smum_stop_smc(struct pp_hwmgr *hwmgr)
250*277b080fSEvan Quan {
251*277b080fSEvan Quan 	if (hwmgr->smumgr_funcs->stop_smc)
252*277b080fSEvan Quan 		return hwmgr->smumgr_funcs->stop_smc(hwmgr);
253*277b080fSEvan Quan 
254*277b080fSEvan Quan 	return 0;
255*277b080fSEvan Quan }
256