vega10_smumgr.c 16.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
/*
 * Copyright 2016 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#include "smumgr.h"
#include "vega10_inc.h"
#include "pp_soc15.h"
#include "vega10_smumgr.h"
#include "vega10_ppsmc.h"
#include "smu9_driver_if.h"

#include "ppatomctrl.h"
#include "pp_debug.h"
#include "smu_ucode_xfer_vi.h"
#include "smu7_smumgr.h"

#define AVFS_EN_MSB		1568
#define AVFS_EN_LSB		1568

#define VOLTAGE_SCALE	4

/* Microcode file is stored in this buffer */
#define BUFFER_SIZE                 80000
#define MAX_STRING_SIZE             15
#define BUFFER_SIZETWO              131072 /* 128 *1024 */

/* MP Apertures */
#define MP0_Public                  0x03800000
#define MP0_SRAM                    0x03900000
#define MP1_Public                  0x03b00000
#define MP1_SRAM                    0x03c00004

#define smnMP1_FIRMWARE_FLAGS                                                                           0x3010028
#define smnMP0_FW_INTF                                                                                  0x3010104
#define smnMP1_PUB_CTRL                                                                                 0x3010b14

56
static bool vega10_is_smc_ram_running(struct pp_hwmgr *hwmgr)
57 58 59 60 61 62
{
	uint32_t mp1_fw_flags, reg;

	reg = soc15_get_register_offset(NBIF_HWID, 0,
			mmPCIE_INDEX2_BASE_IDX, mmPCIE_INDEX2);

63
	cgs_write_register(hwmgr->device, reg,
64 65 66 67 68
			(MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff)));

	reg = soc15_get_register_offset(NBIF_HWID, 0,
			mmPCIE_DATA2_BASE_IDX, mmPCIE_DATA2);

69
	mp1_fw_flags = cgs_read_register(hwmgr->device, reg);
70 71 72 73 74 75 76

	if (mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK)
		return true;

	return false;
}

77 78 79 80 81 82
/*
 * Check if SMC has responded to previous message.
 *
 * @param    smumgr  the address of the powerplay hardware manager.
 * @return   TRUE    SMC has responded, FALSE otherwise.
 */
83
static uint32_t vega10_wait_for_response(struct pp_hwmgr *hwmgr)
84 85
{
	uint32_t reg;
86
	uint32_t ret;
87 88 89 90

	reg = soc15_get_register_offset(MP1_HWID, 0,
			mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);

91
	ret = phm_wait_for_register_unequal(hwmgr, reg,
92 93
			0, MP1_C2PMSG_90__CONTENT_MASK);

94 95 96
	if (ret)
		pr_err("No response from smu\n");

97
	return cgs_read_register(hwmgr->device, reg);
98 99
}

100 101 102 103 104 105
/*
 * Send a message to the SMC, and do not wait for its response.
 * @param    smumgr  the address of the powerplay hardware manager.
 * @param    msg the message to send.
 * @return   Always return 0.
 */
106
int vega10_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr,
107 108 109 110 111 112
		uint16_t msg)
{
	uint32_t reg;

	reg = soc15_get_register_offset(MP1_HWID, 0,
			mmMP1_SMN_C2PMSG_66_BASE_IDX, mmMP1_SMN_C2PMSG_66);
113
	cgs_write_register(hwmgr->device, reg, msg);
114 115 116 117

	return 0;
}

118 119
/*
 * Send a message to the SMC, and wait for its response.
120
 * @param    hwmgr  the address of the powerplay hardware manager.
121 122 123
 * @param    msg the message to send.
 * @return   Always return 0.
 */
124
int vega10_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
125 126
{
	uint32_t reg;
127
	uint32_t ret;
128

129
	vega10_wait_for_response(hwmgr);
130 131 132

	reg = soc15_get_register_offset(MP1_HWID, 0,
			mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);
133
	cgs_write_register(hwmgr->device, reg, 0);
134

135
	vega10_send_msg_to_smc_without_waiting(hwmgr, msg);
136

137 138 139
	ret = vega10_wait_for_response(hwmgr);
	if (ret != 1)
		pr_err("Failed to send message: 0x%x, ret value: 0x%x\n", msg, ret);
140 141 142 143

	return 0;
}

144
/*
145
 * Send a message to the SMC with parameter
146
 * @param    hwmgr:  the address of the powerplay hardware manager.
147 148
 * @param    msg: the message to send.
 * @param    parameter: the parameter to send
149
 * @return   Always return 0.
150
 */
151
int vega10_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
152 153 154
		uint16_t msg, uint32_t parameter)
{
	uint32_t reg;
155
	uint32_t ret;
156

157
	vega10_wait_for_response(hwmgr);
158 159 160

	reg = soc15_get_register_offset(MP1_HWID, 0,
			mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);
161
	cgs_write_register(hwmgr->device, reg, 0);
162 163 164

	reg = soc15_get_register_offset(MP1_HWID, 0,
			mmMP1_SMN_C2PMSG_82_BASE_IDX, mmMP1_SMN_C2PMSG_82);
165
	cgs_write_register(hwmgr->device, reg, parameter);
166

167
	vega10_send_msg_to_smc_without_waiting(hwmgr, msg);
168

169 170
	ret = vega10_wait_for_response(hwmgr);
	if (ret != 1)
171
		pr_err("Failed message: 0x%x, input parameter: 0x%x, error code: 0x%x\n", msg, parameter, ret);
172 173 174 175 176

	return 0;
}


177 178
/*
 * Send a message to the SMC with parameter, do not wait for response
179
 * @param    hwmgr:  the address of the powerplay hardware manager.
180 181 182 183
 * @param    msg: the message to send.
 * @param    parameter: the parameter to send
 * @return   The response that came from the SMC.
 */
184
int vega10_send_msg_to_smc_with_parameter_without_waiting(
185
		struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter)
186 187 188 189 190
{
	uint32_t reg;

	reg = soc15_get_register_offset(MP1_HWID, 0,
			mmMP1_SMN_C2PMSG_82_BASE_IDX, mmMP1_SMN_C2PMSG_82);
191
	cgs_write_register(hwmgr->device, reg, parameter);
192

193
	return vega10_send_msg_to_smc_without_waiting(hwmgr, msg);
194 195
}

196 197
/*
 * Retrieve an argument from SMC.
198
 * @param    hwmgr  the address of the powerplay hardware manager.
199 200 201
 * @param    arg     pointer to store the argument from SMC.
 * @return   Always return 0.
 */
202
int vega10_read_arg_from_smc(struct pp_hwmgr *hwmgr, uint32_t *arg)
203 204 205 206 207 208
{
	uint32_t reg;

	reg = soc15_get_register_offset(MP1_HWID, 0,
			mmMP1_SMN_C2PMSG_82_BASE_IDX, mmMP1_SMN_C2PMSG_82);

209
	*arg = cgs_read_register(hwmgr->device, reg);
210 211 212 213

	return 0;
}

214 215
/*
 * Copy table from SMC into driver FB
216
 * @param   hwmgr    the address of the HW manager
217 218
 * @param   table_id    the driver's table ID to copy from
 */
219
int vega10_copy_table_from_smc(struct pp_hwmgr *hwmgr,
220 221 222
		uint8_t *table, int16_t table_id)
{
	struct vega10_smumgr *priv =
223
			(struct vega10_smumgr *)(hwmgr->smu_backend);
224 225

	PP_ASSERT_WITH_CODE(table_id < MAX_SMU_TABLE,
226
			"Invalid SMU Table ID!", return -EINVAL);
227
	PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].version != 0,
228
			"Invalid SMU Table version!", return -EINVAL);
229
	PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
230
			"Invalid SMU Table Length!", return -EINVAL);
231
	vega10_send_msg_to_smc_with_parameter(hwmgr,
232
			PPSMC_MSG_SetDriverDramAddrHigh,
233
			smu_upper_32_bits(priv->smu_tables.entry[table_id].mc_addr));
234
	vega10_send_msg_to_smc_with_parameter(hwmgr,
235
			PPSMC_MSG_SetDriverDramAddrLow,
236
			smu_lower_32_bits(priv->smu_tables.entry[table_id].mc_addr));
237
	vega10_send_msg_to_smc_with_parameter(hwmgr,
238
			PPSMC_MSG_TransferTableSmu2Dram,
239
			priv->smu_tables.entry[table_id].table_id);
240 241 242 243 244 245 246

	memcpy(table, priv->smu_tables.entry[table_id].table,
			priv->smu_tables.entry[table_id].size);

	return 0;
}

247 248
/*
 * Copy table from Driver FB into SMC
249
 * @param   hwmgr    the address of the HW manager
250 251
 * @param   table_id    the table to copy from
 */
252
int vega10_copy_table_to_smc(struct pp_hwmgr *hwmgr,
253 254 255
		uint8_t *table, int16_t table_id)
{
	struct vega10_smumgr *priv =
256
			(struct vega10_smumgr *)(hwmgr->smu_backend);
257 258

	PP_ASSERT_WITH_CODE(table_id < MAX_SMU_TABLE,
259
			"Invalid SMU Table ID!", return -EINVAL);
260
	PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].version != 0,
261
			"Invalid SMU Table version!", return -EINVAL);
262
	PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
263
			"Invalid SMU Table Length!", return -EINVAL);
264 265 266 267

	memcpy(priv->smu_tables.entry[table_id].table, table,
			priv->smu_tables.entry[table_id].size);

268
	vega10_send_msg_to_smc_with_parameter(hwmgr,
269
			PPSMC_MSG_SetDriverDramAddrHigh,
270
			smu_upper_32_bits(priv->smu_tables.entry[table_id].mc_addr));
271
	vega10_send_msg_to_smc_with_parameter(hwmgr,
272
			PPSMC_MSG_SetDriverDramAddrLow,
273
			smu_lower_32_bits(priv->smu_tables.entry[table_id].mc_addr));
274
	vega10_send_msg_to_smc_with_parameter(hwmgr,
275
			PPSMC_MSG_TransferTableDram2Smu,
276
			priv->smu_tables.entry[table_id].table_id);
277 278 279 280

	return 0;
}

281
int vega10_save_vft_table(struct pp_hwmgr *hwmgr, uint8_t *avfs_table)
282 283 284
{
	PP_ASSERT_WITH_CODE(avfs_table,
			"No access to SMC AVFS Table",
285
			return -EINVAL);
286

287
	return vega10_copy_table_from_smc(hwmgr, avfs_table, AVFSTABLE);
288 289
}

290
int vega10_restore_vft_table(struct pp_hwmgr *hwmgr, uint8_t *avfs_table)
291 292 293
{
	PP_ASSERT_WITH_CODE(avfs_table,
			"No access to SMC AVFS Table",
294
			return -EINVAL);
295

296
	return vega10_copy_table_to_smc(hwmgr, avfs_table, AVFSTABLE);
297 298
}

299
int vega10_enable_smc_features(struct pp_hwmgr *hwmgr,
300 301 302 303 304
		bool enable, uint32_t feature_mask)
{
	int msg = enable ? PPSMC_MSG_EnableSmuFeatures :
			PPSMC_MSG_DisableSmuFeatures;

305
	return vega10_send_msg_to_smc_with_parameter(hwmgr,
306 307 308
			msg, feature_mask);
}

309
int vega10_get_smc_features(struct pp_hwmgr *hwmgr,
310 311
		uint32_t *features_enabled)
{
312 313 314
	if (features_enabled == NULL)
		return -EINVAL;

315 316 317
	vega10_send_msg_to_smc(hwmgr, PPSMC_MSG_GetEnabledSmuFeatures);
	vega10_read_arg_from_smc(hwmgr, features_enabled);
	return 0;
318 319
}

320 321 322 323 324 325 326 327 328 329 330 331
static bool vega10_is_dpm_running(struct pp_hwmgr *hwmgr)
{
	uint32_t features_enabled = 0;

	vega10_get_smc_features(hwmgr, &features_enabled);

	if (features_enabled & SMC_DPM_FEATURES)
		return true;
	else
		return false;
}

332
int vega10_set_tools_address(struct pp_hwmgr *hwmgr)
333 334
{
	struct vega10_smumgr *priv =
335
			(struct vega10_smumgr *)(hwmgr->smu_backend);
336

337
	if (priv->smu_tables.entry[TOOLSTABLE].mc_addr) {
338
		vega10_send_msg_to_smc_with_parameter(hwmgr,
339
				PPSMC_MSG_SetToolsDramAddrHigh,
340
				smu_upper_32_bits(priv->smu_tables.entry[TOOLSTABLE].mc_addr));
341 342
		vega10_send_msg_to_smc_with_parameter(hwmgr,
				PPSMC_MSG_SetToolsDramAddrLow,
343
				smu_lower_32_bits(priv->smu_tables.entry[TOOLSTABLE].mc_addr));
344 345 346 347
	}
	return 0;
}

348
static int vega10_verify_smc_interface(struct pp_hwmgr *hwmgr)
349 350
{
	uint32_t smc_driver_if_version;
351
	struct amdgpu_device *adev = hwmgr->adev;
352 353
	uint32_t dev_id;
	uint32_t rev_id;
354

355
	PP_ASSERT_WITH_CODE(!vega10_send_msg_to_smc(hwmgr,
356 357
			PPSMC_MSG_GetDriverIfVersion),
			"Attempt to get SMC IF Version Number Failed!",
358
			return -EINVAL);
359
	vega10_read_arg_from_smc(hwmgr, &smc_driver_if_version);
360

361 362
	dev_id = adev->pdev->device;
	rev_id = adev->pdev->revision;
363 364 365 366 367 368

	if (!((dev_id == 0x687f) &&
		((rev_id == 0xc0) ||
		(rev_id == 0xc1) ||
		(rev_id == 0xc3)))) {
		if (smc_driver_if_version != SMU9_DRIVER_IF_VERSION) {
369 370
			pr_err("Your firmware(0x%x) doesn't match SMU9_DRIVER_IF_VERSION(0x%x). Please update your firmware!\n",
			       smc_driver_if_version, SMU9_DRIVER_IF_VERSION);
371 372
			return -EINVAL;
		}
373
	}
374 375 376 377

	return 0;
}

378
static int vega10_smu_init(struct pp_hwmgr *hwmgr)
379 380 381 382
{
	struct vega10_smumgr *priv;
	uint64_t mc_addr;
	void *kaddr = NULL;
383 384
	unsigned long tools_size;
	struct amdgpu_bo *handle;
385 386 387
	int ret;
	struct cgs_firmware_info info = {0};

388
	ret = cgs_get_firmware_info(hwmgr->device,
389 390 391 392 393 394 395 396 397 398
				    smu7_convert_fw_type_to_cgs(UCODE_ID_SMU),
				    &info);
	if (ret || !info.kptr)
		return -EINVAL;

	priv = kzalloc(sizeof(struct vega10_smumgr), GFP_KERNEL);

	if (!priv)
		return -ENOMEM;

399
	hwmgr->smu_backend = priv;
400 401

	/* allocate space for pptable */
402
	ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
403 404
			sizeof(PPTable_t),
			PAGE_SIZE,
405 406
			AMDGPU_GEM_DOMAIN_VRAM,
			&handle,
407
			&mc_addr,
408 409 410 411
			&kaddr);

	if (ret)
		return -EINVAL;
412 413 414 415

	priv->smu_tables.entry[PPTABLE].version = 0x01;
	priv->smu_tables.entry[PPTABLE].size = sizeof(PPTable_t);
	priv->smu_tables.entry[PPTABLE].table_id = TABLE_PPTABLE;
416
	priv->smu_tables.entry[PPTABLE].mc_addr = mc_addr;
417 418 419 420
	priv->smu_tables.entry[PPTABLE].table = kaddr;
	priv->smu_tables.entry[PPTABLE].handle = handle;

	/* allocate space for watermarks table */
421
	ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
422 423
			sizeof(Watermarks_t),
			PAGE_SIZE,
424 425
			AMDGPU_GEM_DOMAIN_VRAM,
			&handle,
426
			&mc_addr,
427 428 429 430
			&kaddr);

	if (ret)
		goto err0;
431 432 433 434

	priv->smu_tables.entry[WMTABLE].version = 0x01;
	priv->smu_tables.entry[WMTABLE].size = sizeof(Watermarks_t);
	priv->smu_tables.entry[WMTABLE].table_id = TABLE_WATERMARKS;
435
	priv->smu_tables.entry[WMTABLE].mc_addr = mc_addr;
436 437 438 439
	priv->smu_tables.entry[WMTABLE].table = kaddr;
	priv->smu_tables.entry[WMTABLE].handle = handle;

	/* allocate space for AVFS table */
440
	ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
441 442
			sizeof(AvfsTable_t),
			PAGE_SIZE,
443 444
			AMDGPU_GEM_DOMAIN_VRAM,
			&handle,
445
			&mc_addr,
446 447 448 449
			&kaddr);

	if (ret)
		goto err1;
450 451 452 453

	priv->smu_tables.entry[AVFSTABLE].version = 0x01;
	priv->smu_tables.entry[AVFSTABLE].size = sizeof(AvfsTable_t);
	priv->smu_tables.entry[AVFSTABLE].table_id = TABLE_AVFS;
454
	priv->smu_tables.entry[AVFSTABLE].mc_addr = mc_addr;
455 456 457
	priv->smu_tables.entry[AVFSTABLE].table = kaddr;
	priv->smu_tables.entry[AVFSTABLE].handle = handle;

458
	tools_size = 0x19000;
459
	if (tools_size) {
460
		ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
461 462
				tools_size,
				PAGE_SIZE,
463 464
				AMDGPU_GEM_DOMAIN_VRAM,
				&handle,
465
				&mc_addr,
466 467 468 469 470 471 472 473 474
				&kaddr);
		if (ret)
			goto err2;
		priv->smu_tables.entry[TOOLSTABLE].version = 0x01;
		priv->smu_tables.entry[TOOLSTABLE].size = tools_size;
		priv->smu_tables.entry[TOOLSTABLE].table_id = TABLE_PMSTATUSLOG;
		priv->smu_tables.entry[TOOLSTABLE].mc_addr = mc_addr;
		priv->smu_tables.entry[TOOLSTABLE].table = kaddr;
		priv->smu_tables.entry[TOOLSTABLE].handle = handle;
475 476
	}

477
	/* allocate space for AVFS Fuse table */
478
	ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
479 480
			sizeof(AvfsFuseOverride_t),
			PAGE_SIZE,
481 482
			AMDGPU_GEM_DOMAIN_VRAM,
			&handle,
483
			&mc_addr,
484 485 486
			&kaddr);
	if (ret)
		goto err3;
487 488 489 490

	priv->smu_tables.entry[AVFSFUSETABLE].version = 0x01;
	priv->smu_tables.entry[AVFSFUSETABLE].size = sizeof(AvfsFuseOverride_t);
	priv->smu_tables.entry[AVFSFUSETABLE].table_id = TABLE_AVFS_FUSE_OVERRIDE;
491
	priv->smu_tables.entry[AVFSFUSETABLE].mc_addr = mc_addr;
492 493 494
	priv->smu_tables.entry[AVFSFUSETABLE].table = kaddr;
	priv->smu_tables.entry[AVFSFUSETABLE].handle = handle;

495
	return 0;
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514

err3:
	if (priv->smu_tables.entry[TOOLSTABLE].table)
		amdgpu_bo_free_kernel(&priv->smu_tables.entry[TOOLSTABLE].handle,
				&priv->smu_tables.entry[TOOLSTABLE].mc_addr,
				&priv->smu_tables.entry[TOOLSTABLE].table);
err2:
	amdgpu_bo_free_kernel(&priv->smu_tables.entry[AVFSTABLE].handle,
				&priv->smu_tables.entry[AVFSTABLE].mc_addr,
				&priv->smu_tables.entry[AVFSTABLE].table);
err1:
	amdgpu_bo_free_kernel(&priv->smu_tables.entry[WMTABLE].handle,
				&priv->smu_tables.entry[WMTABLE].mc_addr,
				&priv->smu_tables.entry[WMTABLE].table);
err0:
	amdgpu_bo_free_kernel(&priv->smu_tables.entry[PPTABLE].handle,
			&priv->smu_tables.entry[PPTABLE].mc_addr,
			&priv->smu_tables.entry[PPTABLE].table);
	return -EINVAL;
515 516
}

517
static int vega10_smu_fini(struct pp_hwmgr *hwmgr)
518 519
{
	struct vega10_smumgr *priv =
520
			(struct vega10_smumgr *)(hwmgr->smu_backend);
521 522

	if (priv) {
523 524 525 526 527 528 529 530 531
		amdgpu_bo_free_kernel(&priv->smu_tables.entry[PPTABLE].handle,
				&priv->smu_tables.entry[PPTABLE].mc_addr,
				&priv->smu_tables.entry[PPTABLE].table);
		amdgpu_bo_free_kernel(&priv->smu_tables.entry[WMTABLE].handle,
					&priv->smu_tables.entry[WMTABLE].mc_addr,
					&priv->smu_tables.entry[WMTABLE].table);
		amdgpu_bo_free_kernel(&priv->smu_tables.entry[AVFSTABLE].handle,
					&priv->smu_tables.entry[AVFSTABLE].mc_addr,
					&priv->smu_tables.entry[AVFSTABLE].table);
532
		if (priv->smu_tables.entry[TOOLSTABLE].table)
533 534 535 536 537 538
			amdgpu_bo_free_kernel(&priv->smu_tables.entry[TOOLSTABLE].handle,
					&priv->smu_tables.entry[TOOLSTABLE].mc_addr,
					&priv->smu_tables.entry[TOOLSTABLE].table);
		amdgpu_bo_free_kernel(&priv->smu_tables.entry[AVFSFUSETABLE].handle,
					&priv->smu_tables.entry[AVFSFUSETABLE].mc_addr,
					&priv->smu_tables.entry[AVFSFUSETABLE].table);
539 540
		kfree(hwmgr->smu_backend);
		hwmgr->smu_backend = NULL;
541 542 543 544
	}
	return 0;
}

545
static int vega10_start_smu(struct pp_hwmgr *hwmgr)
546
{
547 548 549
	if (!vega10_is_smc_ram_running(hwmgr))
		return -EINVAL;

550
	PP_ASSERT_WITH_CODE(!vega10_verify_smc_interface(hwmgr),
551
			"Failed to verify SMC interface!",
552
			return -EINVAL);
553

554
	vega10_set_tools_address(hwmgr);
555

556 557 558 559 560 561 562 563 564 565 566 567
	return 0;
}

const struct pp_smumgr_func vega10_smu_funcs = {
	.smu_init = &vega10_smu_init,
	.smu_fini = &vega10_smu_fini,
	.start_smu = &vega10_start_smu,
	.request_smu_load_specific_fw = NULL,
	.send_msg_to_smc = &vega10_send_msg_to_smc,
	.send_msg_to_smc_with_parameter = &vega10_send_msg_to_smc_with_parameter,
	.download_pptable_settings = NULL,
	.upload_pptable_settings = NULL,
568
	.is_dpm_running = vega10_is_dpm_running,
569
};