2 * Copyright 2018 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.
25 #include "vega20_inc.h"
26 #include "soc15_common.h"
27 #include "vega20_smumgr.h"
28 #include "vega20_ppsmc.h"
29 #include "smu11_driver_if.h"
30 #include "ppatomctrl.h"
32 #include "smu_ucode_xfer_vi.h"
33 #include "smu7_smumgr.h"
34 #include "vega20_hwmgr.h"
37 #define MP0_Public 0x03800000
38 #define MP0_SRAM 0x03900000
39 #define MP1_Public 0x03b00000
40 #define MP1_SRAM 0x03c00004
43 #define smnMP1_FIRMWARE_FLAGS 0x3010024
44 #define smnMP0_FW_INTF 0x30101c0
45 #define smnMP1_PUB_CTRL 0x3010b14
47 bool vega20_is_smc_ram_running(struct pp_hwmgr
*hwmgr
)
49 struct amdgpu_device
*adev
= hwmgr
->adev
;
50 uint32_t mp1_fw_flags
;
52 mp1_fw_flags
= RREG32_PCIE(MP1_Public
|
53 (smnMP1_FIRMWARE_FLAGS
& 0xffffffff));
55 if ((mp1_fw_flags
& MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK
) >>
56 MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT
)
63 * Check if SMC has responded to previous message.
65 * @param smumgr the address of the powerplay hardware manager.
66 * @return TRUE SMC has responded, FALSE otherwise.
68 static uint32_t vega20_wait_for_response(struct pp_hwmgr
*hwmgr
)
70 struct amdgpu_device
*adev
= hwmgr
->adev
;
73 reg
= SOC15_REG_OFFSET(MP1
, 0, mmMP1_SMN_C2PMSG_90
);
75 phm_wait_for_register_unequal(hwmgr
, reg
,
76 0, MP1_C2PMSG_90__CONTENT_MASK
);
78 return RREG32_SOC15(MP1
, 0, mmMP1_SMN_C2PMSG_90
);
82 * Send a message to the SMC, and do not wait for its response.
83 * @param smumgr the address of the powerplay hardware manager.
84 * @param msg the message to send.
85 * @return Always return 0.
87 static int vega20_send_msg_to_smc_without_waiting(struct pp_hwmgr
*hwmgr
,
90 struct amdgpu_device
*adev
= hwmgr
->adev
;
92 WREG32_SOC15(MP1
, 0, mmMP1_SMN_C2PMSG_66
, msg
);
98 * Send a message to the SMC, and wait for its response.
99 * @param hwmgr the address of the powerplay hardware manager.
100 * @param msg the message to send.
101 * @return Always return 0.
103 static int vega20_send_msg_to_smc(struct pp_hwmgr
*hwmgr
, uint16_t msg
)
105 struct amdgpu_device
*adev
= hwmgr
->adev
;
108 vega20_wait_for_response(hwmgr
);
110 WREG32_SOC15(MP1
, 0, mmMP1_SMN_C2PMSG_90
, 0);
112 vega20_send_msg_to_smc_without_waiting(hwmgr
, msg
);
114 ret
= vega20_wait_for_response(hwmgr
);
115 if (ret
!= PPSMC_Result_OK
)
116 pr_err("Failed to send message 0x%x, response 0x%x\n", msg
, ret
);
118 return (ret
== PPSMC_Result_OK
) ? 0 : -EIO
;
122 * Send a message to the SMC with parameter
123 * @param hwmgr: the address of the powerplay hardware manager.
124 * @param msg: the message to send.
125 * @param parameter: the parameter to send
126 * @return Always return 0.
128 static int vega20_send_msg_to_smc_with_parameter(struct pp_hwmgr
*hwmgr
,
129 uint16_t msg
, uint32_t parameter
)
131 struct amdgpu_device
*adev
= hwmgr
->adev
;
134 vega20_wait_for_response(hwmgr
);
136 WREG32_SOC15(MP1
, 0, mmMP1_SMN_C2PMSG_90
, 0);
138 WREG32_SOC15(MP1
, 0, mmMP1_SMN_C2PMSG_82
, parameter
);
140 vega20_send_msg_to_smc_without_waiting(hwmgr
, msg
);
142 ret
= vega20_wait_for_response(hwmgr
);
143 if (ret
!= PPSMC_Result_OK
)
144 pr_err("Failed to send message 0x%x, response 0x%x\n", msg
, ret
);
146 return (ret
== PPSMC_Result_OK
) ? 0 : -EIO
;
149 static uint32_t vega20_get_argument(struct pp_hwmgr
*hwmgr
)
151 struct amdgpu_device
*adev
= hwmgr
->adev
;
153 return RREG32_SOC15(MP1
, 0, mmMP1_SMN_C2PMSG_82
);
157 * Copy table from SMC into driver FB
158 * @param hwmgr the address of the HW manager
159 * @param table_id the driver's table ID to copy from
161 static int vega20_copy_table_from_smc(struct pp_hwmgr
*hwmgr
,
162 uint8_t *table
, int16_t table_id
)
164 struct vega20_smumgr
*priv
=
165 (struct vega20_smumgr
*)(hwmgr
->smu_backend
);
166 struct amdgpu_device
*adev
= hwmgr
->adev
;
169 PP_ASSERT_WITH_CODE(table_id
< TABLE_COUNT
,
170 "Invalid SMU Table ID!", return -EINVAL
);
171 PP_ASSERT_WITH_CODE(priv
->smu_tables
.entry
[table_id
].version
!= 0,
172 "Invalid SMU Table version!", return -EINVAL
);
173 PP_ASSERT_WITH_CODE(priv
->smu_tables
.entry
[table_id
].size
!= 0,
174 "Invalid SMU Table Length!", return -EINVAL
);
176 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
177 PPSMC_MSG_SetDriverDramAddrHigh
,
178 upper_32_bits(priv
->smu_tables
.entry
[table_id
].mc_addr
))) == 0,
179 "[CopyTableFromSMC] Attempt to Set Dram Addr High Failed!",
181 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
182 PPSMC_MSG_SetDriverDramAddrLow
,
183 lower_32_bits(priv
->smu_tables
.entry
[table_id
].mc_addr
))) == 0,
184 "[CopyTableFromSMC] Attempt to Set Dram Addr Low Failed!",
186 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
187 PPSMC_MSG_TransferTableSmu2Dram
, table_id
)) == 0,
188 "[CopyTableFromSMC] Attempt to Transfer Table From SMU Failed!",
191 /* flush hdp cache */
192 amdgpu_asic_flush_hdp(adev
, NULL
);
194 memcpy(table
, priv
->smu_tables
.entry
[table_id
].table
,
195 priv
->smu_tables
.entry
[table_id
].size
);
201 * Copy table from Driver FB into SMC
202 * @param hwmgr the address of the HW manager
203 * @param table_id the table to copy from
205 static int vega20_copy_table_to_smc(struct pp_hwmgr
*hwmgr
,
206 uint8_t *table
, int16_t table_id
)
208 struct vega20_smumgr
*priv
=
209 (struct vega20_smumgr
*)(hwmgr
->smu_backend
);
210 struct amdgpu_device
*adev
= hwmgr
->adev
;
213 PP_ASSERT_WITH_CODE(table_id
< TABLE_COUNT
,
214 "Invalid SMU Table ID!", return -EINVAL
);
215 PP_ASSERT_WITH_CODE(priv
->smu_tables
.entry
[table_id
].version
!= 0,
216 "Invalid SMU Table version!", return -EINVAL
);
217 PP_ASSERT_WITH_CODE(priv
->smu_tables
.entry
[table_id
].size
!= 0,
218 "Invalid SMU Table Length!", return -EINVAL
);
220 memcpy(priv
->smu_tables
.entry
[table_id
].table
, table
,
221 priv
->smu_tables
.entry
[table_id
].size
);
223 amdgpu_asic_flush_hdp(adev
, NULL
);
225 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
226 PPSMC_MSG_SetDriverDramAddrHigh
,
227 upper_32_bits(priv
->smu_tables
.entry
[table_id
].mc_addr
))) == 0,
228 "[CopyTableToSMC] Attempt to Set Dram Addr High Failed!",
230 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
231 PPSMC_MSG_SetDriverDramAddrLow
,
232 lower_32_bits(priv
->smu_tables
.entry
[table_id
].mc_addr
))) == 0,
233 "[CopyTableToSMC] Attempt to Set Dram Addr Low Failed!",
235 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
236 PPSMC_MSG_TransferTableDram2Smu
, table_id
)) == 0,
237 "[CopyTableToSMC] Attempt to Transfer Table To SMU Failed!",
243 int vega20_set_activity_monitor_coeff(struct pp_hwmgr
*hwmgr
,
244 uint8_t *table
, uint16_t workload_type
)
246 struct vega20_smumgr
*priv
=
247 (struct vega20_smumgr
*)(hwmgr
->smu_backend
);
248 struct amdgpu_device
*adev
= hwmgr
->adev
;
251 memcpy(priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].table
, table
,
252 priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].size
);
254 amdgpu_asic_flush_hdp(adev
, NULL
);
256 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
257 PPSMC_MSG_SetDriverDramAddrHigh
,
258 upper_32_bits(priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].mc_addr
))) == 0,
259 "[SetActivityMonitor] Attempt to Set Dram Addr High Failed!",
261 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
262 PPSMC_MSG_SetDriverDramAddrLow
,
263 lower_32_bits(priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].mc_addr
))) == 0,
264 "[SetActivityMonitor] Attempt to Set Dram Addr Low Failed!",
266 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
267 PPSMC_MSG_TransferTableDram2Smu
, TABLE_ACTIVITY_MONITOR_COEFF
| (workload_type
<< 16))) == 0,
268 "[SetActivityMonitor] Attempt to Transfer Table To SMU Failed!",
274 int vega20_get_activity_monitor_coeff(struct pp_hwmgr
*hwmgr
,
275 uint8_t *table
, uint16_t workload_type
)
277 struct vega20_smumgr
*priv
=
278 (struct vega20_smumgr
*)(hwmgr
->smu_backend
);
279 struct amdgpu_device
*adev
= hwmgr
->adev
;
282 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
283 PPSMC_MSG_SetDriverDramAddrHigh
,
284 upper_32_bits(priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].mc_addr
))) == 0,
285 "[GetActivityMonitor] Attempt to Set Dram Addr High Failed!",
287 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
288 PPSMC_MSG_SetDriverDramAddrLow
,
289 lower_32_bits(priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].mc_addr
))) == 0,
290 "[GetActivityMonitor] Attempt to Set Dram Addr Low Failed!",
292 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
293 PPSMC_MSG_TransferTableSmu2Dram
,
294 TABLE_ACTIVITY_MONITOR_COEFF
| (workload_type
<< 16))) == 0,
295 "[GetActivityMonitor] Attempt to Transfer Table From SMU Failed!",
298 /* flush hdp cache */
299 amdgpu_asic_flush_hdp(adev
, NULL
);
301 memcpy(table
, priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].table
,
302 priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].size
);
307 int vega20_enable_smc_features(struct pp_hwmgr
*hwmgr
,
308 bool enable
, uint64_t feature_mask
)
310 uint32_t smu_features_low
, smu_features_high
;
313 smu_features_low
= (uint32_t)((feature_mask
& SMU_FEATURES_LOW_MASK
) >> SMU_FEATURES_LOW_SHIFT
);
314 smu_features_high
= (uint32_t)((feature_mask
& SMU_FEATURES_HIGH_MASK
) >> SMU_FEATURES_HIGH_SHIFT
);
317 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
318 PPSMC_MSG_EnableSmuFeaturesLow
, smu_features_low
)) == 0,
319 "[EnableDisableSMCFeatures] Attemp to enable SMU features Low failed!",
321 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
322 PPSMC_MSG_EnableSmuFeaturesHigh
, smu_features_high
)) == 0,
323 "[EnableDisableSMCFeatures] Attemp to enable SMU features High failed!",
326 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
327 PPSMC_MSG_DisableSmuFeaturesLow
, smu_features_low
)) == 0,
328 "[EnableDisableSMCFeatures] Attemp to disable SMU features Low failed!",
330 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
331 PPSMC_MSG_DisableSmuFeaturesHigh
, smu_features_high
)) == 0,
332 "[EnableDisableSMCFeatures] Attemp to disable SMU features High failed!",
339 int vega20_get_enabled_smc_features(struct pp_hwmgr
*hwmgr
,
340 uint64_t *features_enabled
)
342 uint32_t smc_features_low
, smc_features_high
;
345 if (features_enabled
== NULL
)
348 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc(hwmgr
,
349 PPSMC_MSG_GetEnabledSmuFeaturesLow
)) == 0,
350 "[GetEnabledSMCFeatures] Attemp to get SMU features Low failed!",
352 smc_features_low
= vega20_get_argument(hwmgr
);
353 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc(hwmgr
,
354 PPSMC_MSG_GetEnabledSmuFeaturesHigh
)) == 0,
355 "[GetEnabledSMCFeatures] Attemp to get SMU features High failed!",
357 smc_features_high
= vega20_get_argument(hwmgr
);
359 *features_enabled
= ((((uint64_t)smc_features_low
<< SMU_FEATURES_LOW_SHIFT
) & SMU_FEATURES_LOW_MASK
) |
360 (((uint64_t)smc_features_high
<< SMU_FEATURES_HIGH_SHIFT
) & SMU_FEATURES_HIGH_MASK
));
365 static int vega20_set_tools_address(struct pp_hwmgr
*hwmgr
)
367 struct vega20_smumgr
*priv
=
368 (struct vega20_smumgr
*)(hwmgr
->smu_backend
);
371 if (priv
->smu_tables
.entry
[TABLE_PMSTATUSLOG
].mc_addr
) {
372 ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
373 PPSMC_MSG_SetToolsDramAddrHigh
,
374 upper_32_bits(priv
->smu_tables
.entry
[TABLE_PMSTATUSLOG
].mc_addr
));
376 ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
377 PPSMC_MSG_SetToolsDramAddrLow
,
378 lower_32_bits(priv
->smu_tables
.entry
[TABLE_PMSTATUSLOG
].mc_addr
));
384 int vega20_set_pptable_driver_address(struct pp_hwmgr
*hwmgr
)
386 struct vega20_smumgr
*priv
=
387 (struct vega20_smumgr
*)(hwmgr
->smu_backend
);
390 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
391 PPSMC_MSG_SetDriverDramAddrHigh
,
392 upper_32_bits(priv
->smu_tables
.entry
[TABLE_PPTABLE
].mc_addr
))) == 0,
393 "[SetPPtabeDriverAddress] Attempt to Set Dram Addr High Failed!",
395 PP_ASSERT_WITH_CODE((ret
= vega20_send_msg_to_smc_with_parameter(hwmgr
,
396 PPSMC_MSG_SetDriverDramAddrLow
,
397 lower_32_bits(priv
->smu_tables
.entry
[TABLE_PPTABLE
].mc_addr
))) == 0,
398 "[SetPPtabeDriverAddress] Attempt to Set Dram Addr Low Failed!",
404 static int vega20_smu_init(struct pp_hwmgr
*hwmgr
)
406 struct vega20_smumgr
*priv
;
407 unsigned long tools_size
= 0x19000;
410 struct cgs_firmware_info info
= {0};
412 ret
= cgs_get_firmware_info(hwmgr
->device
,
413 smu7_convert_fw_type_to_cgs(UCODE_ID_SMU
),
415 if (ret
|| !info
.kptr
)
418 priv
= kzalloc(sizeof(struct vega20_smumgr
), GFP_KERNEL
);
422 hwmgr
->smu_backend
= priv
;
424 /* allocate space for pptable */
425 ret
= amdgpu_bo_create_kernel((struct amdgpu_device
*)hwmgr
->adev
,
428 AMDGPU_GEM_DOMAIN_VRAM
,
429 &priv
->smu_tables
.entry
[TABLE_PPTABLE
].handle
,
430 &priv
->smu_tables
.entry
[TABLE_PPTABLE
].mc_addr
,
431 &priv
->smu_tables
.entry
[TABLE_PPTABLE
].table
);
435 priv
->smu_tables
.entry
[TABLE_PPTABLE
].version
= 0x01;
436 priv
->smu_tables
.entry
[TABLE_PPTABLE
].size
= sizeof(PPTable_t
);
438 /* allocate space for watermarks table */
439 ret
= amdgpu_bo_create_kernel((struct amdgpu_device
*)hwmgr
->adev
,
440 sizeof(Watermarks_t
),
442 AMDGPU_GEM_DOMAIN_VRAM
,
443 &priv
->smu_tables
.entry
[TABLE_WATERMARKS
].handle
,
444 &priv
->smu_tables
.entry
[TABLE_WATERMARKS
].mc_addr
,
445 &priv
->smu_tables
.entry
[TABLE_WATERMARKS
].table
);
449 priv
->smu_tables
.entry
[TABLE_WATERMARKS
].version
= 0x01;
450 priv
->smu_tables
.entry
[TABLE_WATERMARKS
].size
= sizeof(Watermarks_t
);
452 /* allocate space for pmstatuslog table */
453 ret
= amdgpu_bo_create_kernel((struct amdgpu_device
*)hwmgr
->adev
,
456 AMDGPU_GEM_DOMAIN_VRAM
,
457 &priv
->smu_tables
.entry
[TABLE_PMSTATUSLOG
].handle
,
458 &priv
->smu_tables
.entry
[TABLE_PMSTATUSLOG
].mc_addr
,
459 &priv
->smu_tables
.entry
[TABLE_PMSTATUSLOG
].table
);
463 priv
->smu_tables
.entry
[TABLE_PMSTATUSLOG
].version
= 0x01;
464 priv
->smu_tables
.entry
[TABLE_PMSTATUSLOG
].size
= tools_size
;
466 /* allocate space for OverDrive table */
467 ret
= amdgpu_bo_create_kernel((struct amdgpu_device
*)hwmgr
->adev
,
468 sizeof(OverDriveTable_t
),
470 AMDGPU_GEM_DOMAIN_VRAM
,
471 &priv
->smu_tables
.entry
[TABLE_OVERDRIVE
].handle
,
472 &priv
->smu_tables
.entry
[TABLE_OVERDRIVE
].mc_addr
,
473 &priv
->smu_tables
.entry
[TABLE_OVERDRIVE
].table
);
477 priv
->smu_tables
.entry
[TABLE_OVERDRIVE
].version
= 0x01;
478 priv
->smu_tables
.entry
[TABLE_OVERDRIVE
].size
= sizeof(OverDriveTable_t
);
480 /* allocate space for SmuMetrics table */
481 ret
= amdgpu_bo_create_kernel((struct amdgpu_device
*)hwmgr
->adev
,
482 sizeof(SmuMetrics_t
),
484 AMDGPU_GEM_DOMAIN_VRAM
,
485 &priv
->smu_tables
.entry
[TABLE_SMU_METRICS
].handle
,
486 &priv
->smu_tables
.entry
[TABLE_SMU_METRICS
].mc_addr
,
487 &priv
->smu_tables
.entry
[TABLE_SMU_METRICS
].table
);
491 priv
->smu_tables
.entry
[TABLE_SMU_METRICS
].version
= 0x01;
492 priv
->smu_tables
.entry
[TABLE_SMU_METRICS
].size
= sizeof(SmuMetrics_t
);
494 /* allocate space for ActivityMonitor table */
495 ret
= amdgpu_bo_create_kernel((struct amdgpu_device
*)hwmgr
->adev
,
496 sizeof(DpmActivityMonitorCoeffInt_t
),
498 AMDGPU_GEM_DOMAIN_VRAM
,
499 &priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].handle
,
500 &priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].mc_addr
,
501 &priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].table
);
505 priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].version
= 0x01;
506 priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].size
= sizeof(DpmActivityMonitorCoeffInt_t
);
511 amdgpu_bo_free_kernel(&priv
->smu_tables
.entry
[TABLE_SMU_METRICS
].handle
,
512 &priv
->smu_tables
.entry
[TABLE_SMU_METRICS
].mc_addr
,
513 &priv
->smu_tables
.entry
[TABLE_SMU_METRICS
].table
);
515 amdgpu_bo_free_kernel(&priv
->smu_tables
.entry
[TABLE_OVERDRIVE
].handle
,
516 &priv
->smu_tables
.entry
[TABLE_OVERDRIVE
].mc_addr
,
517 &priv
->smu_tables
.entry
[TABLE_OVERDRIVE
].table
);
519 amdgpu_bo_free_kernel(&priv
->smu_tables
.entry
[TABLE_PMSTATUSLOG
].handle
,
520 &priv
->smu_tables
.entry
[TABLE_PMSTATUSLOG
].mc_addr
,
521 &priv
->smu_tables
.entry
[TABLE_PMSTATUSLOG
].table
);
523 amdgpu_bo_free_kernel(&priv
->smu_tables
.entry
[TABLE_WATERMARKS
].handle
,
524 &priv
->smu_tables
.entry
[TABLE_WATERMARKS
].mc_addr
,
525 &priv
->smu_tables
.entry
[TABLE_WATERMARKS
].table
);
527 amdgpu_bo_free_kernel(&priv
->smu_tables
.entry
[TABLE_PPTABLE
].handle
,
528 &priv
->smu_tables
.entry
[TABLE_PPTABLE
].mc_addr
,
529 &priv
->smu_tables
.entry
[TABLE_PPTABLE
].table
);
531 kfree(hwmgr
->smu_backend
);
536 static int vega20_smu_fini(struct pp_hwmgr
*hwmgr
)
538 struct vega20_smumgr
*priv
=
539 (struct vega20_smumgr
*)(hwmgr
->smu_backend
);
542 amdgpu_bo_free_kernel(&priv
->smu_tables
.entry
[TABLE_PPTABLE
].handle
,
543 &priv
->smu_tables
.entry
[TABLE_PPTABLE
].mc_addr
,
544 &priv
->smu_tables
.entry
[TABLE_PPTABLE
].table
);
545 amdgpu_bo_free_kernel(&priv
->smu_tables
.entry
[TABLE_WATERMARKS
].handle
,
546 &priv
->smu_tables
.entry
[TABLE_WATERMARKS
].mc_addr
,
547 &priv
->smu_tables
.entry
[TABLE_WATERMARKS
].table
);
548 amdgpu_bo_free_kernel(&priv
->smu_tables
.entry
[TABLE_PMSTATUSLOG
].handle
,
549 &priv
->smu_tables
.entry
[TABLE_PMSTATUSLOG
].mc_addr
,
550 &priv
->smu_tables
.entry
[TABLE_PMSTATUSLOG
].table
);
551 amdgpu_bo_free_kernel(&priv
->smu_tables
.entry
[TABLE_OVERDRIVE
].handle
,
552 &priv
->smu_tables
.entry
[TABLE_OVERDRIVE
].mc_addr
,
553 &priv
->smu_tables
.entry
[TABLE_OVERDRIVE
].table
);
554 amdgpu_bo_free_kernel(&priv
->smu_tables
.entry
[TABLE_SMU_METRICS
].handle
,
555 &priv
->smu_tables
.entry
[TABLE_SMU_METRICS
].mc_addr
,
556 &priv
->smu_tables
.entry
[TABLE_SMU_METRICS
].table
);
557 amdgpu_bo_free_kernel(&priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].handle
,
558 &priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].mc_addr
,
559 &priv
->smu_tables
.entry
[TABLE_ACTIVITY_MONITOR_COEFF
].table
);
560 kfree(hwmgr
->smu_backend
);
561 hwmgr
->smu_backend
= NULL
;
566 static int vega20_start_smu(struct pp_hwmgr
*hwmgr
)
570 ret
= vega20_is_smc_ram_running(hwmgr
);
571 PP_ASSERT_WITH_CODE(ret
,
572 "[Vega20StartSmu] SMC is not running!",
575 ret
= vega20_set_tools_address(hwmgr
);
576 PP_ASSERT_WITH_CODE(!ret
,
577 "[Vega20StartSmu] Failed to set tools address!",
583 static bool vega20_is_dpm_running(struct pp_hwmgr
*hwmgr
)
585 uint64_t features_enabled
= 0;
587 vega20_get_enabled_smc_features(hwmgr
, &features_enabled
);
589 if (features_enabled
& SMC_DPM_FEATURES
)
595 static int vega20_smc_table_manager(struct pp_hwmgr
*hwmgr
, uint8_t *table
,
596 uint16_t table_id
, bool rw
)
601 ret
= vega20_copy_table_from_smc(hwmgr
, table
, table_id
);
603 ret
= vega20_copy_table_to_smc(hwmgr
, table
, table_id
);
608 const struct pp_smumgr_func vega20_smu_funcs
= {
609 .name
= "vega20_smu",
610 .smu_init
= &vega20_smu_init
,
611 .smu_fini
= &vega20_smu_fini
,
612 .start_smu
= &vega20_start_smu
,
613 .request_smu_load_specific_fw
= NULL
,
614 .send_msg_to_smc
= &vega20_send_msg_to_smc
,
615 .send_msg_to_smc_with_parameter
= &vega20_send_msg_to_smc_with_parameter
,
616 .download_pptable_settings
= NULL
,
617 .upload_pptable_settings
= NULL
,
618 .is_dpm_running
= vega20_is_dpm_running
,
619 .get_argument
= vega20_get_argument
,
620 .smc_table_manager
= vega20_smc_table_manager
,