brintos

brintos / linux-shallow public Read only

0
0
Text · 20.1 KiB · 4d33c95 Raw
684 lines · c
1/*2 * Copyright 2023 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 */23#include <drm/drm_drv.h>24#include <linux/vmalloc.h>25#include "amdgpu.h"26#include "amdgpu_psp.h"27#include "amdgpu_ucode.h"28#include "soc15_common.h"29#include "psp_v14_0.h"30 31#include "mp/mp_14_0_2_offset.h"32#include "mp/mp_14_0_2_sh_mask.h"33 34MODULE_FIRMWARE("amdgpu/psp_14_0_2_sos.bin");35MODULE_FIRMWARE("amdgpu/psp_14_0_2_ta.bin");36MODULE_FIRMWARE("amdgpu/psp_14_0_3_sos.bin");37MODULE_FIRMWARE("amdgpu/psp_14_0_3_ta.bin");38 39/* For large FW files the time to complete can be very long */40#define USBC_PD_POLLING_LIMIT_S 24041 42/* Read USB-PD from LFB */43#define GFX_CMD_USB_PD_USE_LFB 0x48044 45/* VBIOS gfl defines */46#define MBOX_READY_MASK 0x8000000047#define MBOX_STATUS_MASK 0x0000FFFF48#define MBOX_COMMAND_MASK 0x00FF000049#define MBOX_READY_FLAG 0x8000000050#define C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_LO 0x251#define C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_HI 0x352#define C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE 0x453 54/* memory training timeout define */55#define MEM_TRAIN_SEND_MSG_TIMEOUT_US	300000056 57static int psp_v14_0_init_microcode(struct psp_context *psp)58{59	struct amdgpu_device *adev = psp->adev;60	char ucode_prefix[30];61	int err = 0;62 63	amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));64 65	switch (amdgpu_ip_version(adev, MP0_HWIP, 0)) {66	case IP_VERSION(14, 0, 2):67	case IP_VERSION(14, 0, 3):68		err = psp_init_sos_microcode(psp, ucode_prefix);69		if (err)70			return err;71		err = psp_init_ta_microcode(psp, ucode_prefix);72		if (err)73			return err;74		break;75	default:76		BUG();77	}78 79	return 0;80}81 82static bool psp_v14_0_is_sos_alive(struct psp_context *psp)83{84	struct amdgpu_device *adev = psp->adev;85	uint32_t sol_reg;86 87	sol_reg = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_81);88 89	return sol_reg != 0x0;90}91 92static int psp_v14_0_wait_for_bootloader(struct psp_context *psp)93{94	struct amdgpu_device *adev = psp->adev;95 96	int ret;97	int retry_loop;98 99	for (retry_loop = 0; retry_loop < 10; retry_loop++) {100		/* Wait for bootloader to signify that is101		    ready having bit 31 of C2PMSG_35 set to 1 */102		ret = psp_wait_for(psp,103				   SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_35),104				   0x80000000,105				   0x80000000,106				   false);107 108		if (ret == 0)109			return 0;110	}111 112	return ret;113}114 115static int psp_v14_0_bootloader_load_component(struct psp_context  	*psp,116					       struct psp_bin_desc 	*bin_desc,117					       enum psp_bootloader_cmd  bl_cmd)118{119	int ret;120	uint32_t psp_gfxdrv_command_reg = 0;121	struct amdgpu_device *adev = psp->adev;122 123	/* Check tOS sign of life register to confirm sys driver and sOS124	 * are already been loaded.125	 */126	if (psp_v14_0_is_sos_alive(psp))127		return 0;128 129	ret = psp_v14_0_wait_for_bootloader(psp);130	if (ret)131		return ret;132 133	memset(psp->fw_pri_buf, 0, PSP_1_MEG);134 135	/* Copy PSP KDB binary to memory */136	memcpy(psp->fw_pri_buf, bin_desc->start_addr, bin_desc->size_bytes);137 138	/* Provide the PSP KDB to bootloader */139	WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_36,140	       (uint32_t)(psp->fw_pri_mc_addr >> 20));141	psp_gfxdrv_command_reg = bl_cmd;142	WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_35,143	       psp_gfxdrv_command_reg);144 145	ret = psp_v14_0_wait_for_bootloader(psp);146 147	return ret;148}149 150static int psp_v14_0_bootloader_load_kdb(struct psp_context *psp)151{152	return psp_v14_0_bootloader_load_component(psp, &psp->kdb, PSP_BL__LOAD_KEY_DATABASE);153}154 155static int psp_v14_0_bootloader_load_spl(struct psp_context *psp)156{157	return psp_v14_0_bootloader_load_component(psp, &psp->spl, PSP_BL__LOAD_TOS_SPL_TABLE);158}159 160static int psp_v14_0_bootloader_load_sysdrv(struct psp_context *psp)161{162	return psp_v14_0_bootloader_load_component(psp, &psp->sys, PSP_BL__LOAD_SYSDRV);163}164 165static int psp_v14_0_bootloader_load_soc_drv(struct psp_context *psp)166{167	return psp_v14_0_bootloader_load_component(psp, &psp->soc_drv, PSP_BL__LOAD_SOCDRV);168}169 170static int psp_v14_0_bootloader_load_intf_drv(struct psp_context *psp)171{172	return psp_v14_0_bootloader_load_component(psp, &psp->intf_drv, PSP_BL__LOAD_INTFDRV);173}174 175static int psp_v14_0_bootloader_load_dbg_drv(struct psp_context *psp)176{177	/* dbg_drv was renamed to had_drv in psp v14 */178	return psp_v14_0_bootloader_load_component(psp, &psp->dbg_drv, PSP_BL__LOAD_HADDRV);179}180 181static int psp_v14_0_bootloader_load_ras_drv(struct psp_context *psp)182{183	return psp_v14_0_bootloader_load_component(psp, &psp->ras_drv, PSP_BL__LOAD_RASDRV);184}185 186static int psp_v14_0_bootloader_load_ipkeymgr_drv(struct psp_context *psp)187{188	return psp_v14_0_bootloader_load_component(psp, &psp->ipkeymgr_drv, PSP_BL__LOAD_IPKEYMGRDRV);189}190 191static int psp_v14_0_bootloader_load_sos(struct psp_context *psp)192{193	int ret;194	unsigned int psp_gfxdrv_command_reg = 0;195	struct amdgpu_device *adev = psp->adev;196 197	/* Check sOS sign of life register to confirm sys driver and sOS198	 * are already been loaded.199	 */200	if (psp_v14_0_is_sos_alive(psp))201		return 0;202 203	ret = psp_v14_0_wait_for_bootloader(psp);204	if (ret)205		return ret;206 207	memset(psp->fw_pri_buf, 0, PSP_1_MEG);208 209	/* Copy Secure OS binary to PSP memory */210	memcpy(psp->fw_pri_buf, psp->sos.start_addr, psp->sos.size_bytes);211 212	/* Provide the PSP secure OS to bootloader */213	WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_36,214	       (uint32_t)(psp->fw_pri_mc_addr >> 20));215	psp_gfxdrv_command_reg = PSP_BL__LOAD_SOSDRV;216	WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_35,217	       psp_gfxdrv_command_reg);218 219	/* there might be handshake issue with hardware which needs delay */220	mdelay(20);221	ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_81),222			   RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_81),223			   0, true);224 225	return ret;226}227 228static int psp_v14_0_ring_stop(struct psp_context *psp,229			       enum psp_ring_type ring_type)230{231	int ret = 0;232	struct amdgpu_device *adev = psp->adev;233 234	if (amdgpu_sriov_vf(adev)) {235		/* Write the ring destroy command*/236		WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_101,237			     GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING);238		/* there might be handshake issue with hardware which needs delay */239		mdelay(20);240		/* Wait for response flag (bit 31) */241		ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_101),242				   0x80000000, 0x80000000, false);243	} else {244		/* Write the ring destroy command*/245		WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_64,246			     GFX_CTRL_CMD_ID_DESTROY_RINGS);247		/* there might be handshake issue with hardware which needs delay */248		mdelay(20);249		/* Wait for response flag (bit 31) */250		ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_64),251				   0x80000000, 0x80000000, false);252	}253 254	return ret;255}256 257static int psp_v14_0_ring_create(struct psp_context *psp,258				 enum psp_ring_type ring_type)259{260	int ret = 0;261	unsigned int psp_ring_reg = 0;262	struct psp_ring *ring = &psp->km_ring;263	struct amdgpu_device *adev = psp->adev;264 265	if (amdgpu_sriov_vf(adev)) {266		ret = psp_v14_0_ring_stop(psp, ring_type);267		if (ret) {268			DRM_ERROR("psp_v14_0_ring_stop_sriov failed!\n");269			return ret;270		}271 272		/* Write low address of the ring to C2PMSG_102 */273		psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);274		WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_102, psp_ring_reg);275		/* Write high address of the ring to C2PMSG_103 */276		psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr);277		WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_103, psp_ring_reg);278 279		/* Write the ring initialization command to C2PMSG_101 */280		WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_101,281			     GFX_CTRL_CMD_ID_INIT_GPCOM_RING);282 283		/* there might be handshake issue with hardware which needs delay */284		mdelay(20);285 286		/* Wait for response flag (bit 31) in C2PMSG_101 */287		ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_101),288				   0x80000000, 0x8000FFFF, false);289 290	} else {291		/* Wait for sOS ready for ring creation */292		ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_64),293				   0x80000000, 0x80000000, false);294		if (ret) {295			DRM_ERROR("Failed to wait for trust OS ready for ring creation\n");296			return ret;297		}298 299		/* Write low address of the ring to C2PMSG_69 */300		psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);301		WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_69, psp_ring_reg);302		/* Write high address of the ring to C2PMSG_70 */303		psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr);304		WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_70, psp_ring_reg);305		/* Write size of ring to C2PMSG_71 */306		psp_ring_reg = ring->ring_size;307		WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_71, psp_ring_reg);308		/* Write the ring initialization command to C2PMSG_64 */309		psp_ring_reg = ring_type;310		psp_ring_reg = psp_ring_reg << 16;311		WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_64, psp_ring_reg);312 313		/* there might be handshake issue with hardware which needs delay */314		mdelay(20);315 316		/* Wait for response flag (bit 31) in C2PMSG_64 */317		ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_64),318				   0x80000000, 0x8000FFFF, false);319	}320 321	return ret;322}323 324static int psp_v14_0_ring_destroy(struct psp_context *psp,325				  enum psp_ring_type ring_type)326{327	int ret = 0;328	struct psp_ring *ring = &psp->km_ring;329	struct amdgpu_device *adev = psp->adev;330 331	ret = psp_v14_0_ring_stop(psp, ring_type);332	if (ret)333		DRM_ERROR("Fail to stop psp ring\n");334 335	amdgpu_bo_free_kernel(&adev->firmware.rbuf,336			      &ring->ring_mem_mc_addr,337			      (void **)&ring->ring_mem);338 339	return ret;340}341 342static uint32_t psp_v14_0_ring_get_wptr(struct psp_context *psp)343{344	uint32_t data;345	struct amdgpu_device *adev = psp->adev;346 347	if (amdgpu_sriov_vf(adev))348		data = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_102);349	else350		data = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_67);351 352	return data;353}354 355static void psp_v14_0_ring_set_wptr(struct psp_context *psp, uint32_t value)356{357	struct amdgpu_device *adev = psp->adev;358 359	if (amdgpu_sriov_vf(adev)) {360		WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_102, value);361		WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_101,362			     GFX_CTRL_CMD_ID_CONSUME_CMD);363	} else364		WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_67, value);365}366 367static int psp_v14_0_memory_training_send_msg(struct psp_context *psp, int msg)368{369	int ret;370	int i;371	uint32_t data_32;372	int max_wait;373	struct amdgpu_device *adev = psp->adev;374 375	data_32 = (psp->mem_train_ctx.c2p_train_data_offset >> 20);376	WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_36, data_32);377	WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_35, msg);378 379	max_wait = MEM_TRAIN_SEND_MSG_TIMEOUT_US / adev->usec_timeout;380	for (i = 0; i < max_wait; i++) {381		ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_35),382				   0x80000000, 0x80000000, false);383		if (ret == 0)384			break;385	}386	if (i < max_wait)387		ret = 0;388	else389		ret = -ETIME;390 391	dev_dbg(adev->dev, "training %s %s, cost %d @ %d ms\n",392		  (msg == PSP_BL__DRAM_SHORT_TRAIN) ? "short" : "long",393		  (ret == 0) ? "succeed" : "failed",394		  i, adev->usec_timeout/1000);395	return ret;396}397 398 399static int psp_v14_0_memory_training(struct psp_context *psp, uint32_t ops)400{401	struct psp_memory_training_context *ctx = &psp->mem_train_ctx;402	uint32_t *pcache = (uint32_t *)ctx->sys_cache;403	struct amdgpu_device *adev = psp->adev;404	uint32_t p2c_header[4];405	uint32_t sz;406	void *buf;407	int ret, idx;408 409	if (ctx->init == PSP_MEM_TRAIN_NOT_SUPPORT) {410		dev_dbg(adev->dev, "Memory training is not supported.\n");411		return 0;412	} else if (ctx->init != PSP_MEM_TRAIN_INIT_SUCCESS) {413		dev_err(adev->dev, "Memory training initialization failure.\n");414		return -EINVAL;415	}416 417	if (psp_v14_0_is_sos_alive(psp)) {418		dev_dbg(adev->dev, "SOS is alive, skip memory training.\n");419		return 0;420	}421 422	amdgpu_device_vram_access(adev, ctx->p2c_train_data_offset, p2c_header, sizeof(p2c_header), false);423	dev_dbg(adev->dev, "sys_cache[%08x,%08x,%08x,%08x] p2c_header[%08x,%08x,%08x,%08x]\n",424		  pcache[0], pcache[1], pcache[2], pcache[3],425		  p2c_header[0], p2c_header[1], p2c_header[2], p2c_header[3]);426 427	if (ops & PSP_MEM_TRAIN_SEND_SHORT_MSG) {428		dev_dbg(adev->dev, "Short training depends on restore.\n");429		ops |= PSP_MEM_TRAIN_RESTORE;430	}431 432	if ((ops & PSP_MEM_TRAIN_RESTORE) &&433	    pcache[0] != MEM_TRAIN_SYSTEM_SIGNATURE) {434		dev_dbg(adev->dev, "sys_cache[0] is invalid, restore depends on save.\n");435		ops |= PSP_MEM_TRAIN_SAVE;436	}437 438	if (p2c_header[0] == MEM_TRAIN_SYSTEM_SIGNATURE &&439	    !(pcache[0] == MEM_TRAIN_SYSTEM_SIGNATURE &&440	      pcache[3] == p2c_header[3])) {441		dev_dbg(adev->dev, "sys_cache is invalid or out-of-date, need save training data to sys_cache.\n");442		ops |= PSP_MEM_TRAIN_SAVE;443	}444 445	if ((ops & PSP_MEM_TRAIN_SAVE) &&446	    p2c_header[0] != MEM_TRAIN_SYSTEM_SIGNATURE) {447		dev_dbg(adev->dev, "p2c_header[0] is invalid, save depends on long training.\n");448		ops |= PSP_MEM_TRAIN_SEND_LONG_MSG;449	}450 451	if (ops & PSP_MEM_TRAIN_SEND_LONG_MSG) {452		ops &= ~PSP_MEM_TRAIN_SEND_SHORT_MSG;453		ops |= PSP_MEM_TRAIN_SAVE;454	}455 456	dev_dbg(adev->dev, "Memory training ops:%x.\n", ops);457 458	if (ops & PSP_MEM_TRAIN_SEND_LONG_MSG) {459		/*460		 * Long training will encroach a certain amount on the bottom of VRAM;461		 * save the content from the bottom of VRAM to system memory462		 * before training, and restore it after training to avoid463		 * VRAM corruption.464		 */465		sz = BIST_MEM_TRAINING_ENCROACHED_SIZE;466 467		if (adev->gmc.visible_vram_size < sz || !adev->mman.aper_base_kaddr) {468			dev_err(adev->dev, "visible_vram_size %llx or aper_base_kaddr %p is not initialized.\n",469				  adev->gmc.visible_vram_size,470				  adev->mman.aper_base_kaddr);471			return -EINVAL;472		}473 474		buf = vmalloc(sz);475		if (!buf) {476			dev_err(adev->dev, "failed to allocate system memory.\n");477			return -ENOMEM;478		}479 480		if (drm_dev_enter(adev_to_drm(adev), &idx)) {481			memcpy_fromio(buf, adev->mman.aper_base_kaddr, sz);482			ret = psp_v14_0_memory_training_send_msg(psp, PSP_BL__DRAM_LONG_TRAIN);483			if (ret) {484				DRM_ERROR("Send long training msg failed.\n");485				vfree(buf);486				drm_dev_exit(idx);487				return ret;488			}489 490			memcpy_toio(adev->mman.aper_base_kaddr, buf, sz);491			adev->hdp.funcs->flush_hdp(adev, NULL);492			vfree(buf);493			drm_dev_exit(idx);494		} else {495			vfree(buf);496			return -ENODEV;497		}498	}499 500	if (ops & PSP_MEM_TRAIN_SAVE) {501		amdgpu_device_vram_access(psp->adev, ctx->p2c_train_data_offset, ctx->sys_cache, ctx->train_data_size, false);502	}503 504	if (ops & PSP_MEM_TRAIN_RESTORE) {505		amdgpu_device_vram_access(psp->adev, ctx->c2p_train_data_offset, ctx->sys_cache, ctx->train_data_size, true);506	}507 508	if (ops & PSP_MEM_TRAIN_SEND_SHORT_MSG) {509		ret = psp_v14_0_memory_training_send_msg(psp, (amdgpu_force_long_training > 0) ?510							 PSP_BL__DRAM_LONG_TRAIN : PSP_BL__DRAM_SHORT_TRAIN);511		if (ret) {512			dev_err(adev->dev, "send training msg failed.\n");513			return ret;514		}515	}516	ctx->training_cnt++;517	return 0;518}519 520static int psp_v14_0_load_usbc_pd_fw(struct psp_context *psp, uint64_t fw_pri_mc_addr)521{522	struct amdgpu_device *adev = psp->adev;523	uint32_t reg_status;524	int ret, i = 0;525 526	/*527	 * LFB address which is aligned to 1MB address and has to be528	 * right-shifted by 20 so that LFB address can be passed on a 32-bit C2P529	 * register530	 */531	WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_36, (fw_pri_mc_addr >> 20));532 533	ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_35),534			     0x80000000, 0x80000000, false);535	if (ret)536		return ret;537 538	/* Fireup interrupt so PSP can pick up the address */539	WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_35, (GFX_CMD_USB_PD_USE_LFB << 16));540 541	/* FW load takes very long time */542	do {543		msleep(1000);544		reg_status = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_35);545 546		if (reg_status & 0x80000000)547			goto done;548 549	} while (++i < USBC_PD_POLLING_LIMIT_S);550 551	return -ETIME;552done:553 554	if ((reg_status & 0xFFFF) != 0) {555		DRM_ERROR("Address load failed - MP0_SMN_C2PMSG_35.Bits [15:0] = %04x\n",556				reg_status & 0xFFFF);557		return -EIO;558	}559 560	return 0;561}562 563static int psp_v14_0_read_usbc_pd_fw(struct psp_context *psp, uint32_t *fw_ver)564{565	struct amdgpu_device *adev = psp->adev;566	int ret;567 568	WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_35, C2PMSG_CMD_GFX_USB_PD_FW_VER);569 570	ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_35),571				     0x80000000, 0x80000000, false);572	if (!ret)573		*fw_ver = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_36);574 575	return ret;576}577 578static int psp_v14_0_exec_spi_cmd(struct psp_context *psp, int cmd)579{580	uint32_t reg_status = 0, reg_val = 0;581	struct amdgpu_device *adev = psp->adev;582	int ret;583 584	/* clear MBX ready (MBOX_READY_MASK bit is 0) and set update command */585	reg_val |= (cmd << 16);586	WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_115,  reg_val);587 588	/* Ring the doorbell */589	WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_73, 1);590 591	if (cmd == C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE)592		ret = psp_wait_for_spirom_update(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_115),593						 MBOX_READY_FLAG, MBOX_READY_MASK, PSP_SPIROM_UPDATE_TIMEOUT);594	else595		ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_115),596				   MBOX_READY_FLAG, MBOX_READY_MASK, false);597 598	ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_115),599				MBOX_READY_FLAG, MBOX_READY_MASK, false);600	if (ret) {601		dev_err(adev->dev, "SPI cmd %x timed out, ret = %d", cmd, ret);602		return ret;603	}604 605	reg_status = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_115);606	if ((reg_status & 0xFFFF) != 0) {607		dev_err(adev->dev, "SPI cmd %x failed, fail status = %04x\n",608				cmd, reg_status & 0xFFFF);609		return -EIO;610	}611 612	return 0;613}614 615static int psp_v14_0_update_spirom(struct psp_context *psp,616				   uint64_t fw_pri_mc_addr)617{618	struct amdgpu_device *adev = psp->adev;619	int ret;620 621	/* Confirm PSP is ready to start */622	ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_115),623			   MBOX_READY_FLAG, MBOX_READY_MASK, false);624	if (ret) {625		dev_err(adev->dev, "PSP Not ready to start processing, ret = %d", ret);626		return ret;627	}628 629	WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_116, lower_32_bits(fw_pri_mc_addr));630 631	ret = psp_v14_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_LO);632	if (ret)633		return ret;634 635	WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_116, upper_32_bits(fw_pri_mc_addr));636 637	ret = psp_v14_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_HI);638	if (ret)639		return ret;640 641	psp->vbflash_done = true;642 643	ret = psp_v14_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE);644	if (ret)645		return ret;646 647	return 0;648}649 650static int psp_v14_0_vbflash_status(struct psp_context *psp)651{652	struct amdgpu_device *adev = psp->adev;653 654	return RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_115);655}656 657static const struct psp_funcs psp_v14_0_funcs = {658	.init_microcode = psp_v14_0_init_microcode,659	.bootloader_load_kdb = psp_v14_0_bootloader_load_kdb,660	.bootloader_load_spl = psp_v14_0_bootloader_load_spl,661	.bootloader_load_sysdrv = psp_v14_0_bootloader_load_sysdrv,662	.bootloader_load_soc_drv = psp_v14_0_bootloader_load_soc_drv,663	.bootloader_load_intf_drv = psp_v14_0_bootloader_load_intf_drv,664	.bootloader_load_dbg_drv = psp_v14_0_bootloader_load_dbg_drv,665	.bootloader_load_ras_drv = psp_v14_0_bootloader_load_ras_drv,666	.bootloader_load_ipkeymgr_drv = psp_v14_0_bootloader_load_ipkeymgr_drv,667	.bootloader_load_sos = psp_v14_0_bootloader_load_sos,668	.ring_create = psp_v14_0_ring_create,669	.ring_stop = psp_v14_0_ring_stop,670	.ring_destroy = psp_v14_0_ring_destroy,671	.ring_get_wptr = psp_v14_0_ring_get_wptr,672	.ring_set_wptr = psp_v14_0_ring_set_wptr,673	.mem_training = psp_v14_0_memory_training,674	.load_usbc_pd_fw = psp_v14_0_load_usbc_pd_fw,675	.read_usbc_pd_fw = psp_v14_0_read_usbc_pd_fw,676	.update_spirom = psp_v14_0_update_spirom,677	.vbflash_stat = psp_v14_0_vbflash_status678};679 680void psp_v14_0_set_psp_funcs(struct psp_context *psp)681{682	psp->funcs = &psp_v14_0_funcs;683}684