1b843c749SSergey Zigachev /*
2b843c749SSergey Zigachev  * Copyright 2017 Advanced Micro Devices, Inc.
3b843c749SSergey Zigachev  *
4b843c749SSergey Zigachev  * Permission is hereby granted, free of charge, to any person obtaining a
5b843c749SSergey Zigachev  * copy of this software and associated documentation files (the "Software"),
6b843c749SSergey Zigachev  * to deal in the Software without restriction, including without limitation
7b843c749SSergey Zigachev  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b843c749SSergey Zigachev  * and/or sell copies of the Software, and to permit persons to whom the
9b843c749SSergey Zigachev  * Software is furnished to do so, subject to the following conditions:
10b843c749SSergey Zigachev  *
11b843c749SSergey Zigachev  * The above copyright notice and this permission notice shall be included in
12b843c749SSergey Zigachev  * all copies or substantial portions of the Software.
13b843c749SSergey Zigachev  *
14b843c749SSergey Zigachev  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15b843c749SSergey Zigachev  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16b843c749SSergey Zigachev  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17b843c749SSergey Zigachev  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18b843c749SSergey Zigachev  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19b843c749SSergey Zigachev  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20b843c749SSergey Zigachev  * OTHER DEALINGS IN THE SOFTWARE.
21b843c749SSergey Zigachev  *
22b843c749SSergey Zigachev  */
23b843c749SSergey Zigachev 
24b843c749SSergey Zigachev #include "smumgr.h"
25b843c749SSergey Zigachev #include "vega12_inc.h"
26b843c749SSergey Zigachev #include "soc15_common.h"
27b843c749SSergey Zigachev #include "smu9_smumgr.h"
28b843c749SSergey Zigachev #include "vega12_smumgr.h"
29b843c749SSergey Zigachev #include "vega12_ppsmc.h"
30b843c749SSergey Zigachev #include "vega12/smu9_driver_if.h"
31b843c749SSergey Zigachev #include "ppatomctrl.h"
32b843c749SSergey Zigachev #include "pp_debug.h"
33b843c749SSergey Zigachev 
34b843c749SSergey Zigachev 
35b843c749SSergey Zigachev /*
36b843c749SSergey Zigachev  * Copy table from SMC into driver FB
37b843c749SSergey Zigachev  * @param   hwmgr    the address of the HW manager
38b843c749SSergey Zigachev  * @param   table_id    the driver's table ID to copy from
39b843c749SSergey Zigachev  */
vega12_copy_table_from_smc(struct pp_hwmgr * hwmgr,uint8_t * table,int16_t table_id)40b843c749SSergey Zigachev int vega12_copy_table_from_smc(struct pp_hwmgr *hwmgr,
41b843c749SSergey Zigachev 		uint8_t *table, int16_t table_id)
42b843c749SSergey Zigachev {
43b843c749SSergey Zigachev 	struct vega12_smumgr *priv =
44b843c749SSergey Zigachev 			(struct vega12_smumgr *)(hwmgr->smu_backend);
45b843c749SSergey Zigachev 
46b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(table_id < TABLE_COUNT,
47b843c749SSergey Zigachev 			"Invalid SMU Table ID!", return -EINVAL);
48b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].version != 0,
49b843c749SSergey Zigachev 			"Invalid SMU Table version!", return -EINVAL);
50b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
51b843c749SSergey Zigachev 			"Invalid SMU Table Length!", return -EINVAL);
52b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
53b843c749SSergey Zigachev 			PPSMC_MSG_SetDriverDramAddrHigh,
54b843c749SSergey Zigachev 			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0,
55b843c749SSergey Zigachev 			"[CopyTableFromSMC] Attempt to Set Dram Addr High Failed!", return -EINVAL);
56b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
57b843c749SSergey Zigachev 			PPSMC_MSG_SetDriverDramAddrLow,
58b843c749SSergey Zigachev 			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0,
59b843c749SSergey Zigachev 			"[CopyTableFromSMC] Attempt to Set Dram Addr Low Failed!",
60b843c749SSergey Zigachev 			return -EINVAL);
61b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
62b843c749SSergey Zigachev 			PPSMC_MSG_TransferTableSmu2Dram,
63b843c749SSergey Zigachev 			table_id) == 0,
64b843c749SSergey Zigachev 			"[CopyTableFromSMC] Attempt to Transfer Table From SMU Failed!",
65b843c749SSergey Zigachev 			return -EINVAL);
66b843c749SSergey Zigachev 
67b843c749SSergey Zigachev 	memcpy(table, priv->smu_tables.entry[table_id].table,
68b843c749SSergey Zigachev 			priv->smu_tables.entry[table_id].size);
69b843c749SSergey Zigachev 
70b843c749SSergey Zigachev 	return 0;
71b843c749SSergey Zigachev }
72b843c749SSergey Zigachev 
73b843c749SSergey Zigachev /*
74b843c749SSergey Zigachev  * Copy table from Driver FB into SMC
75b843c749SSergey Zigachev  * @param   hwmgr    the address of the HW manager
76b843c749SSergey Zigachev  * @param   table_id    the table to copy from
77b843c749SSergey Zigachev  */
vega12_copy_table_to_smc(struct pp_hwmgr * hwmgr,uint8_t * table,int16_t table_id)78b843c749SSergey Zigachev int vega12_copy_table_to_smc(struct pp_hwmgr *hwmgr,
79b843c749SSergey Zigachev 		uint8_t *table, int16_t table_id)
80b843c749SSergey Zigachev {
81b843c749SSergey Zigachev 	struct vega12_smumgr *priv =
82b843c749SSergey Zigachev 			(struct vega12_smumgr *)(hwmgr->smu_backend);
83b843c749SSergey Zigachev 
84b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(table_id < TABLE_COUNT,
85b843c749SSergey Zigachev 			"Invalid SMU Table ID!", return -EINVAL);
86b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].version != 0,
87b843c749SSergey Zigachev 			"Invalid SMU Table version!", return -EINVAL);
88b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
89b843c749SSergey Zigachev 			"Invalid SMU Table Length!", return -EINVAL);
90b843c749SSergey Zigachev 
91b843c749SSergey Zigachev 	memcpy(priv->smu_tables.entry[table_id].table, table,
92b843c749SSergey Zigachev 			priv->smu_tables.entry[table_id].size);
93b843c749SSergey Zigachev 
94b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
95b843c749SSergey Zigachev 			PPSMC_MSG_SetDriverDramAddrHigh,
96b843c749SSergey Zigachev 			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0,
97b843c749SSergey Zigachev 			"[CopyTableToSMC] Attempt to Set Dram Addr High Failed!",
98b843c749SSergey Zigachev 			return -EINVAL;);
99b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
100b843c749SSergey Zigachev 			PPSMC_MSG_SetDriverDramAddrLow,
101b843c749SSergey Zigachev 			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0,
102b843c749SSergey Zigachev 			"[CopyTableToSMC] Attempt to Set Dram Addr Low Failed!",
103b843c749SSergey Zigachev 			return -EINVAL);
104b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
105b843c749SSergey Zigachev 			PPSMC_MSG_TransferTableDram2Smu,
106b843c749SSergey Zigachev 			table_id) == 0,
107b843c749SSergey Zigachev 			"[CopyTableToSMC] Attempt to Transfer Table To SMU Failed!",
108b843c749SSergey Zigachev 			return -EINVAL);
109b843c749SSergey Zigachev 
110b843c749SSergey Zigachev 	return 0;
111b843c749SSergey Zigachev }
112b843c749SSergey Zigachev 
vega12_enable_smc_features(struct pp_hwmgr * hwmgr,bool enable,uint64_t feature_mask)113b843c749SSergey Zigachev int vega12_enable_smc_features(struct pp_hwmgr *hwmgr,
114b843c749SSergey Zigachev 		bool enable, uint64_t feature_mask)
115b843c749SSergey Zigachev {
116b843c749SSergey Zigachev 	uint32_t smu_features_low, smu_features_high;
117b843c749SSergey Zigachev 
118b843c749SSergey Zigachev 	smu_features_low = (uint32_t)((feature_mask & SMU_FEATURES_LOW_MASK) >> SMU_FEATURES_LOW_SHIFT);
119b843c749SSergey Zigachev 	smu_features_high = (uint32_t)((feature_mask & SMU_FEATURES_HIGH_MASK) >> SMU_FEATURES_HIGH_SHIFT);
120b843c749SSergey Zigachev 
121b843c749SSergey Zigachev 	if (enable) {
122b843c749SSergey Zigachev 		PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
123b843c749SSergey Zigachev 				PPSMC_MSG_EnableSmuFeaturesLow, smu_features_low) == 0,
124b843c749SSergey Zigachev 				"[EnableDisableSMCFeatures] Attemp to enable SMU features Low failed!",
125b843c749SSergey Zigachev 				return -EINVAL);
126b843c749SSergey Zigachev 		PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
127b843c749SSergey Zigachev 				PPSMC_MSG_EnableSmuFeaturesHigh, smu_features_high) == 0,
128b843c749SSergey Zigachev 				"[EnableDisableSMCFeatures] Attemp to enable SMU features High failed!",
129b843c749SSergey Zigachev 				return -EINVAL);
130b843c749SSergey Zigachev 	} else {
131b843c749SSergey Zigachev 		PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
132b843c749SSergey Zigachev 				PPSMC_MSG_DisableSmuFeaturesLow, smu_features_low) == 0,
133b843c749SSergey Zigachev 				"[EnableDisableSMCFeatures] Attemp to disable SMU features Low failed!",
134b843c749SSergey Zigachev 				return -EINVAL);
135b843c749SSergey Zigachev 		PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
136b843c749SSergey Zigachev 				PPSMC_MSG_DisableSmuFeaturesHigh, smu_features_high) == 0,
137b843c749SSergey Zigachev 				"[EnableDisableSMCFeatures] Attemp to disable SMU features High failed!",
138b843c749SSergey Zigachev 				return -EINVAL);
139b843c749SSergey Zigachev 	}
140b843c749SSergey Zigachev 
141b843c749SSergey Zigachev 	return 0;
142b843c749SSergey Zigachev }
143b843c749SSergey Zigachev 
vega12_get_enabled_smc_features(struct pp_hwmgr * hwmgr,uint64_t * features_enabled)144b843c749SSergey Zigachev int vega12_get_enabled_smc_features(struct pp_hwmgr *hwmgr,
145b843c749SSergey Zigachev 		uint64_t *features_enabled)
146b843c749SSergey Zigachev {
147b843c749SSergey Zigachev 	uint32_t smc_features_low, smc_features_high;
148b843c749SSergey Zigachev 
149b843c749SSergey Zigachev 	if (features_enabled == NULL)
150b843c749SSergey Zigachev 		return -EINVAL;
151b843c749SSergey Zigachev 
152b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc(hwmgr,
153b843c749SSergey Zigachev 			PPSMC_MSG_GetEnabledSmuFeaturesLow) == 0,
154b843c749SSergey Zigachev 			"[GetEnabledSMCFeatures] Attemp to get SMU features Low failed!",
155b843c749SSergey Zigachev 			return -EINVAL);
156b843c749SSergey Zigachev 	smc_features_low = smu9_get_argument(hwmgr);
157b843c749SSergey Zigachev 
158b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc(hwmgr,
159b843c749SSergey Zigachev 			PPSMC_MSG_GetEnabledSmuFeaturesHigh) == 0,
160b843c749SSergey Zigachev 			"[GetEnabledSMCFeatures] Attemp to get SMU features High failed!",
161b843c749SSergey Zigachev 			return -EINVAL);
162b843c749SSergey Zigachev 	smc_features_high = smu9_get_argument(hwmgr);
163b843c749SSergey Zigachev 
164b843c749SSergey Zigachev 	*features_enabled = ((((uint64_t)smc_features_low << SMU_FEATURES_LOW_SHIFT) & SMU_FEATURES_LOW_MASK) |
165b843c749SSergey Zigachev 			(((uint64_t)smc_features_high << SMU_FEATURES_HIGH_SHIFT) & SMU_FEATURES_HIGH_MASK));
166b843c749SSergey Zigachev 
167b843c749SSergey Zigachev 	return 0;
168b843c749SSergey Zigachev }
169b843c749SSergey Zigachev 
vega12_is_dpm_running(struct pp_hwmgr * hwmgr)170b843c749SSergey Zigachev static bool vega12_is_dpm_running(struct pp_hwmgr *hwmgr)
171b843c749SSergey Zigachev {
172b843c749SSergey Zigachev 	uint64_t features_enabled = 0;
173b843c749SSergey Zigachev 
174b843c749SSergey Zigachev 	vega12_get_enabled_smc_features(hwmgr, &features_enabled);
175b843c749SSergey Zigachev 
176b843c749SSergey Zigachev 	if (features_enabled & SMC_DPM_FEATURES)
177b843c749SSergey Zigachev 		return true;
178b843c749SSergey Zigachev 	else
179b843c749SSergey Zigachev 		return false;
180b843c749SSergey Zigachev }
181b843c749SSergey Zigachev 
vega12_set_tools_address(struct pp_hwmgr * hwmgr)182b843c749SSergey Zigachev static int vega12_set_tools_address(struct pp_hwmgr *hwmgr)
183b843c749SSergey Zigachev {
184b843c749SSergey Zigachev 	struct vega12_smumgr *priv =
185b843c749SSergey Zigachev 			(struct vega12_smumgr *)(hwmgr->smu_backend);
186b843c749SSergey Zigachev 
187b843c749SSergey Zigachev 	if (priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr) {
188b843c749SSergey Zigachev 		if (!smu9_send_msg_to_smc_with_parameter(hwmgr,
189b843c749SSergey Zigachev 				PPSMC_MSG_SetToolsDramAddrHigh,
190b843c749SSergey Zigachev 				upper_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr)))
191b843c749SSergey Zigachev 			smu9_send_msg_to_smc_with_parameter(hwmgr,
192b843c749SSergey Zigachev 					PPSMC_MSG_SetToolsDramAddrLow,
193b843c749SSergey Zigachev 					lower_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr));
194b843c749SSergey Zigachev 	}
195b843c749SSergey Zigachev 	return 0;
196b843c749SSergey Zigachev }
197b843c749SSergey Zigachev 
vega12_smu_init(struct pp_hwmgr * hwmgr)198b843c749SSergey Zigachev static int vega12_smu_init(struct pp_hwmgr *hwmgr)
199b843c749SSergey Zigachev {
200b843c749SSergey Zigachev 	struct vega12_smumgr *priv;
201b843c749SSergey Zigachev 	unsigned long tools_size;
202b843c749SSergey Zigachev 	struct cgs_firmware_info info = {0};
203b843c749SSergey Zigachev 	int ret;
204b843c749SSergey Zigachev 
205b843c749SSergey Zigachev 	ret = cgs_get_firmware_info(hwmgr->device, CGS_UCODE_ID_SMU,
206b843c749SSergey Zigachev 				&info);
207b843c749SSergey Zigachev 	if (ret || !info.kptr)
208b843c749SSergey Zigachev 		return -EINVAL;
209b843c749SSergey Zigachev 
210b843c749SSergey Zigachev 	priv = kzalloc(sizeof(struct vega12_smumgr), GFP_KERNEL);
211b843c749SSergey Zigachev 	if (!priv)
212b843c749SSergey Zigachev 		return -ENOMEM;
213b843c749SSergey Zigachev 
214b843c749SSergey Zigachev 	hwmgr->smu_backend = priv;
215b843c749SSergey Zigachev 
216b843c749SSergey Zigachev 	/* allocate space for pptable */
217b843c749SSergey Zigachev 	ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
218b843c749SSergey Zigachev 			sizeof(PPTable_t),
219b843c749SSergey Zigachev 			PAGE_SIZE,
220b843c749SSergey Zigachev 			AMDGPU_GEM_DOMAIN_VRAM,
221b843c749SSergey Zigachev 			&priv->smu_tables.entry[TABLE_PPTABLE].handle,
222*78973132SSergey Zigachev 			(u64 *)&priv->smu_tables.entry[TABLE_PPTABLE].mc_addr,
223b843c749SSergey Zigachev 			&priv->smu_tables.entry[TABLE_PPTABLE].table);
224b843c749SSergey Zigachev 	if (ret)
225b843c749SSergey Zigachev 		goto free_backend;
226b843c749SSergey Zigachev 
227b843c749SSergey Zigachev 	priv->smu_tables.entry[TABLE_PPTABLE].version = 0x01;
228b843c749SSergey Zigachev 	priv->smu_tables.entry[TABLE_PPTABLE].size = sizeof(PPTable_t);
229b843c749SSergey Zigachev 
230b843c749SSergey Zigachev 	/* allocate space for watermarks table */
231b843c749SSergey Zigachev 	ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
232b843c749SSergey Zigachev 				      sizeof(Watermarks_t),
233b843c749SSergey Zigachev 				      PAGE_SIZE,
234b843c749SSergey Zigachev 				      AMDGPU_GEM_DOMAIN_VRAM,
235b843c749SSergey Zigachev 				      &priv->smu_tables.entry[TABLE_WATERMARKS].handle,
236*78973132SSergey Zigachev 				      (u64 *)&priv->smu_tables.entry[TABLE_WATERMARKS].mc_addr,
237b843c749SSergey Zigachev 				      &priv->smu_tables.entry[TABLE_WATERMARKS].table);
238b843c749SSergey Zigachev 
239b843c749SSergey Zigachev 	if (ret)
240b843c749SSergey Zigachev 		goto err0;
241b843c749SSergey Zigachev 
242b843c749SSergey Zigachev 	priv->smu_tables.entry[TABLE_WATERMARKS].version = 0x01;
243b843c749SSergey Zigachev 	priv->smu_tables.entry[TABLE_WATERMARKS].size = sizeof(Watermarks_t);
244b843c749SSergey Zigachev 
245b843c749SSergey Zigachev 	tools_size = 0x19000;
246b843c749SSergey Zigachev 	if (tools_size) {
247b843c749SSergey Zigachev 		ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
248b843c749SSergey Zigachev 					      tools_size,
249b843c749SSergey Zigachev 					      PAGE_SIZE,
250b843c749SSergey Zigachev 					      AMDGPU_GEM_DOMAIN_VRAM,
251b843c749SSergey Zigachev 					      &priv->smu_tables.entry[TABLE_PMSTATUSLOG].handle,
252*78973132SSergey Zigachev 					      (u64 *)&priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr,
253b843c749SSergey Zigachev 					      &priv->smu_tables.entry[TABLE_PMSTATUSLOG].table);
254b843c749SSergey Zigachev 		if (ret)
255b843c749SSergey Zigachev 			goto err1;
256b843c749SSergey Zigachev 
257b843c749SSergey Zigachev 		priv->smu_tables.entry[TABLE_PMSTATUSLOG].version = 0x01;
258b843c749SSergey Zigachev 		priv->smu_tables.entry[TABLE_PMSTATUSLOG].size = tools_size;
259b843c749SSergey Zigachev 	}
260b843c749SSergey Zigachev 
261b843c749SSergey Zigachev 	/* allocate space for AVFS Fuse table */
262b843c749SSergey Zigachev 	ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
263b843c749SSergey Zigachev 				      sizeof(AvfsFuseOverride_t),
264b843c749SSergey Zigachev 				      PAGE_SIZE,
265b843c749SSergey Zigachev 				      AMDGPU_GEM_DOMAIN_VRAM,
266b843c749SSergey Zigachev 				      &priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].handle,
267*78973132SSergey Zigachev 				      (u64 *)&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].mc_addr,
268b843c749SSergey Zigachev 				      &priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].table);
269b843c749SSergey Zigachev 
270b843c749SSergey Zigachev 	if (ret)
271b843c749SSergey Zigachev 		goto err2;
272b843c749SSergey Zigachev 
273b843c749SSergey Zigachev 	priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].version = 0x01;
274b843c749SSergey Zigachev 	priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].size = sizeof(AvfsFuseOverride_t);
275b843c749SSergey Zigachev 
276b843c749SSergey Zigachev 	/* allocate space for OverDrive table */
277b843c749SSergey Zigachev 	ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
278b843c749SSergey Zigachev 				      sizeof(OverDriveTable_t),
279b843c749SSergey Zigachev 				      PAGE_SIZE,
280b843c749SSergey Zigachev 				      AMDGPU_GEM_DOMAIN_VRAM,
281b843c749SSergey Zigachev 				      &priv->smu_tables.entry[TABLE_OVERDRIVE].handle,
282*78973132SSergey Zigachev 				      (u64 *)&priv->smu_tables.entry[TABLE_OVERDRIVE].mc_addr,
283b843c749SSergey Zigachev 				      &priv->smu_tables.entry[TABLE_OVERDRIVE].table);
284b843c749SSergey Zigachev 	if (ret)
285b843c749SSergey Zigachev 		goto err3;
286b843c749SSergey Zigachev 
287b843c749SSergey Zigachev 	priv->smu_tables.entry[TABLE_OVERDRIVE].version = 0x01;
288b843c749SSergey Zigachev 	priv->smu_tables.entry[TABLE_OVERDRIVE].size = sizeof(OverDriveTable_t);
289b843c749SSergey Zigachev 
290b843c749SSergey Zigachev 	return 0;
291b843c749SSergey Zigachev 
292b843c749SSergey Zigachev err3:
293b843c749SSergey Zigachev 	amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].handle,
294*78973132SSergey Zigachev 				(u64 *)&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].mc_addr,
295b843c749SSergey Zigachev 				&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].table);
296b843c749SSergey Zigachev err2:
297b843c749SSergey Zigachev 	if (priv->smu_tables.entry[TABLE_PMSTATUSLOG].table)
298b843c749SSergey Zigachev 		amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_PMSTATUSLOG].handle,
299*78973132SSergey Zigachev 				(u64 *)&priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr,
300b843c749SSergey Zigachev 				&priv->smu_tables.entry[TABLE_PMSTATUSLOG].table);
301b843c749SSergey Zigachev err1:
302b843c749SSergey Zigachev 	amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_WATERMARKS].handle,
303*78973132SSergey Zigachev 				(u64 *)&priv->smu_tables.entry[TABLE_WATERMARKS].mc_addr,
304b843c749SSergey Zigachev 				&priv->smu_tables.entry[TABLE_WATERMARKS].table);
305b843c749SSergey Zigachev err0:
306b843c749SSergey Zigachev 	amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_PPTABLE].handle,
307*78973132SSergey Zigachev 			(u64 *)&priv->smu_tables.entry[TABLE_PPTABLE].mc_addr,
308b843c749SSergey Zigachev 			&priv->smu_tables.entry[TABLE_PPTABLE].table);
309b843c749SSergey Zigachev free_backend:
310b843c749SSergey Zigachev 	kfree(hwmgr->smu_backend);
311b843c749SSergey Zigachev 
312b843c749SSergey Zigachev 	return -EINVAL;
313b843c749SSergey Zigachev }
314b843c749SSergey Zigachev 
vega12_smu_fini(struct pp_hwmgr * hwmgr)315b843c749SSergey Zigachev static int vega12_smu_fini(struct pp_hwmgr *hwmgr)
316b843c749SSergey Zigachev {
317b843c749SSergey Zigachev 	struct vega12_smumgr *priv =
318b843c749SSergey Zigachev 			(struct vega12_smumgr *)(hwmgr->smu_backend);
319b843c749SSergey Zigachev 
320b843c749SSergey Zigachev 	if (priv) {
321b843c749SSergey Zigachev 		amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_PPTABLE].handle,
322*78973132SSergey Zigachev 				      (u64 *)&priv->smu_tables.entry[TABLE_PPTABLE].mc_addr,
323b843c749SSergey Zigachev 				      &priv->smu_tables.entry[TABLE_PPTABLE].table);
324b843c749SSergey Zigachev 		amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_WATERMARKS].handle,
325*78973132SSergey Zigachev 				      (u64 *)&priv->smu_tables.entry[TABLE_WATERMARKS].mc_addr,
326b843c749SSergey Zigachev 				      &priv->smu_tables.entry[TABLE_WATERMARKS].table);
327b843c749SSergey Zigachev 		if (priv->smu_tables.entry[TABLE_PMSTATUSLOG].table)
328b843c749SSergey Zigachev 			amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_PMSTATUSLOG].handle,
329*78973132SSergey Zigachev 					      (u64 *)&priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr,
330b843c749SSergey Zigachev 					      &priv->smu_tables.entry[TABLE_PMSTATUSLOG].table);
331b843c749SSergey Zigachev 		amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].handle,
332*78973132SSergey Zigachev 				      (u64 *)&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].mc_addr,
333b843c749SSergey Zigachev 				      &priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].table);
334b843c749SSergey Zigachev 		amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_OVERDRIVE].handle,
335*78973132SSergey Zigachev 				      (u64 *)&priv->smu_tables.entry[TABLE_OVERDRIVE].mc_addr,
336b843c749SSergey Zigachev 				      &priv->smu_tables.entry[TABLE_OVERDRIVE].table);
337b843c749SSergey Zigachev 		kfree(hwmgr->smu_backend);
338b843c749SSergey Zigachev 		hwmgr->smu_backend = NULL;
339b843c749SSergey Zigachev 	}
340b843c749SSergey Zigachev 	return 0;
341b843c749SSergey Zigachev }
342b843c749SSergey Zigachev 
vega12_start_smu(struct pp_hwmgr * hwmgr)343b843c749SSergey Zigachev static int vega12_start_smu(struct pp_hwmgr *hwmgr)
344b843c749SSergey Zigachev {
345b843c749SSergey Zigachev 	PP_ASSERT_WITH_CODE(smu9_is_smc_ram_running(hwmgr),
346b843c749SSergey Zigachev 			"SMC is not running!",
347b843c749SSergey Zigachev 			return -EINVAL);
348b843c749SSergey Zigachev 
349b843c749SSergey Zigachev 	vega12_set_tools_address(hwmgr);
350b843c749SSergey Zigachev 
351b843c749SSergey Zigachev 	return 0;
352b843c749SSergey Zigachev }
353b843c749SSergey Zigachev 
354b843c749SSergey Zigachev const struct pp_smumgr_func vega12_smu_funcs = {
355b843c749SSergey Zigachev 	.smu_init = &vega12_smu_init,
356b843c749SSergey Zigachev 	.smu_fini = &vega12_smu_fini,
357b843c749SSergey Zigachev 	.start_smu = &vega12_start_smu,
358b843c749SSergey Zigachev 	.request_smu_load_specific_fw = NULL,
359b843c749SSergey Zigachev 	.send_msg_to_smc = &smu9_send_msg_to_smc,
360b843c749SSergey Zigachev 	.send_msg_to_smc_with_parameter = &smu9_send_msg_to_smc_with_parameter,
361b843c749SSergey Zigachev 	.download_pptable_settings = NULL,
362b843c749SSergey Zigachev 	.upload_pptable_settings = NULL,
363b843c749SSergey Zigachev 	.is_dpm_running = vega12_is_dpm_running,
364b843c749SSergey Zigachev 	.get_argument = smu9_get_argument,
365b843c749SSergey Zigachev };
366