diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 447 | 
1 files changed, 366 insertions, 81 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index deaa26808841..7301fdcfb8bc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -37,11 +37,11 @@  #include "amdgpu_ras.h" -static void psp_set_funcs(struct amdgpu_device *adev); -  static int psp_sysfs_init(struct amdgpu_device *adev);  static void psp_sysfs_fini(struct amdgpu_device *adev); +static int psp_load_smu_fw(struct psp_context *psp); +  /*   * Due to DF Cstate management centralized to PMFW, the firmware   * loading sequence will be updated as below: @@ -80,8 +80,6 @@ static int psp_early_init(void *handle)  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	struct psp_context *psp = &adev->psp; -	psp_set_funcs(adev); -  	switch (adev->asic_type) {  	case CHIP_VEGA10:  	case CHIP_VEGA12: @@ -201,6 +199,7 @@ psp_cmd_submit_buf(struct psp_context *psp,  	int index;  	int timeout = 2000;  	bool ras_intr = false; +	bool skip_unsupport = false;  	mutex_lock(&psp->mutex); @@ -232,6 +231,9 @@ psp_cmd_submit_buf(struct psp_context *psp,  		amdgpu_asic_invalidate_hdp(psp->adev, NULL);  	} +	/* We allow TEE_ERROR_NOT_SUPPORTED for VMR command in SRIOV */ +	skip_unsupport = (psp->cmd_buf_mem->resp.status == 0xffff000a) && amdgpu_sriov_vf(psp->adev); +  	/* In some cases, psp response status is not 0 even there is no  	 * problem while the command is submitted. Some version of PSP FW  	 * doesn't write 0 to that field. @@ -239,7 +241,7 @@ psp_cmd_submit_buf(struct psp_context *psp,  	 * during psp initialization to avoid breaking hw_init and it doesn't  	 * return -EINVAL.  	 */ -	if ((psp->cmd_buf_mem->resp.status || !timeout) && !ras_intr) { +	if (!skip_unsupport && (psp->cmd_buf_mem->resp.status || !timeout) && !ras_intr) {  		if (ucode)  			DRM_WARN("failed to load ucode id (%d) ",  				  ucode->ucode_id); @@ -268,7 +270,7 @@ static void psp_prep_tmr_cmd_buf(struct psp_context *psp,  				 struct psp_gfx_cmd_resp *cmd,  				 uint64_t tmr_mc, uint32_t size)  { -	if (psp_support_vmr_ring(psp)) +	if (amdgpu_sriov_vf(psp->adev))  		cmd->cmd_id = GFX_CMD_ID_SETUP_VMR;  	else  		cmd->cmd_id = GFX_CMD_ID_SETUP_TMR; @@ -662,6 +664,121 @@ int psp_xgmi_initialize(struct psp_context *psp)  	return ret;  } +int psp_xgmi_get_hive_id(struct psp_context *psp, uint64_t *hive_id) +{ +	struct ta_xgmi_shared_memory *xgmi_cmd; +	int ret; + +	xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf; +	memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); + +	xgmi_cmd->cmd_id = TA_COMMAND_XGMI__GET_HIVE_ID; + +	/* Invoke xgmi ta to get hive id */ +	ret = psp_xgmi_invoke(psp, xgmi_cmd->cmd_id); +	if (ret) +		return ret; + +	*hive_id = xgmi_cmd->xgmi_out_message.get_hive_id.hive_id; + +	return 0; +} + +int psp_xgmi_get_node_id(struct psp_context *psp, uint64_t *node_id) +{ +	struct ta_xgmi_shared_memory *xgmi_cmd; +	int ret; + +	xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf; +	memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); + +	xgmi_cmd->cmd_id = TA_COMMAND_XGMI__GET_NODE_ID; + +	/* Invoke xgmi ta to get the node id */ +	ret = psp_xgmi_invoke(psp, xgmi_cmd->cmd_id); +	if (ret) +		return ret; + +	*node_id = xgmi_cmd->xgmi_out_message.get_node_id.node_id; + +	return 0; +} + +int psp_xgmi_get_topology_info(struct psp_context *psp, +			       int number_devices, +			       struct psp_xgmi_topology_info *topology) +{ +	struct ta_xgmi_shared_memory *xgmi_cmd; +	struct ta_xgmi_cmd_get_topology_info_input *topology_info_input; +	struct ta_xgmi_cmd_get_topology_info_output *topology_info_output; +	int i; +	int ret; + +	if (!topology || topology->num_nodes > TA_XGMI__MAX_CONNECTED_NODES) +		return -EINVAL; + +	xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf; +	memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); + +	/* Fill in the shared memory with topology information as input */ +	topology_info_input = &xgmi_cmd->xgmi_in_message.get_topology_info; +	xgmi_cmd->cmd_id = TA_COMMAND_XGMI__GET_GET_TOPOLOGY_INFO; +	topology_info_input->num_nodes = number_devices; + +	for (i = 0; i < topology_info_input->num_nodes; i++) { +		topology_info_input->nodes[i].node_id = topology->nodes[i].node_id; +		topology_info_input->nodes[i].num_hops = topology->nodes[i].num_hops; +		topology_info_input->nodes[i].is_sharing_enabled = topology->nodes[i].is_sharing_enabled; +		topology_info_input->nodes[i].sdma_engine = topology->nodes[i].sdma_engine; +	} + +	/* Invoke xgmi ta to get the topology information */ +	ret = psp_xgmi_invoke(psp, TA_COMMAND_XGMI__GET_GET_TOPOLOGY_INFO); +	if (ret) +		return ret; + +	/* Read the output topology information from the shared memory */ +	topology_info_output = &xgmi_cmd->xgmi_out_message.get_topology_info; +	topology->num_nodes = xgmi_cmd->xgmi_out_message.get_topology_info.num_nodes; +	for (i = 0; i < topology->num_nodes; i++) { +		topology->nodes[i].node_id = topology_info_output->nodes[i].node_id; +		topology->nodes[i].num_hops = topology_info_output->nodes[i].num_hops; +		topology->nodes[i].is_sharing_enabled = topology_info_output->nodes[i].is_sharing_enabled; +		topology->nodes[i].sdma_engine = topology_info_output->nodes[i].sdma_engine; +	} + +	return 0; +} + +int psp_xgmi_set_topology_info(struct psp_context *psp, +			       int number_devices, +			       struct psp_xgmi_topology_info *topology) +{ +	struct ta_xgmi_shared_memory *xgmi_cmd; +	struct ta_xgmi_cmd_get_topology_info_input *topology_info_input; +	int i; + +	if (!topology || topology->num_nodes > TA_XGMI__MAX_CONNECTED_NODES) +		return -EINVAL; + +	xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf; +	memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); + +	topology_info_input = &xgmi_cmd->xgmi_in_message.get_topology_info; +	xgmi_cmd->cmd_id = TA_COMMAND_XGMI__SET_TOPOLOGY_INFO; +	topology_info_input->num_nodes = number_devices; + +	for (i = 0; i < topology_info_input->num_nodes; i++) { +		topology_info_input->nodes[i].node_id = topology->nodes[i].node_id; +		topology_info_input->nodes[i].num_hops = topology->nodes[i].num_hops; +		topology_info_input->nodes[i].is_sharing_enabled = 1; +		topology_info_input->nodes[i].sdma_engine = topology->nodes[i].sdma_engine; +	} + +	/* Invoke xgmi ta to set topology information */ +	return psp_xgmi_invoke(psp, TA_COMMAND_XGMI__SET_TOPOLOGY_INFO); +} +  // ras begin  static int psp_ras_init_shared_buf(struct psp_context *psp)  { @@ -744,13 +861,40 @@ static int psp_ras_unload(struct psp_context *psp)  int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id)  { +	struct ta_ras_shared_memory *ras_cmd; +	int ret; + +	ras_cmd = (struct ta_ras_shared_memory *)psp->ras.ras_shared_buf; +  	/*  	 * TODO: bypass the loading in sriov for now  	 */  	if (amdgpu_sriov_vf(psp->adev))  		return 0; -	return psp_ta_invoke(psp, ta_cmd_id, psp->ras.session_id); +	ret = psp_ta_invoke(psp, ta_cmd_id, psp->ras.session_id); + +	if (amdgpu_ras_intr_triggered()) +		return ret; + +	if (ras_cmd->if_version > RAS_TA_HOST_IF_VER) +	{ +		DRM_WARN("RAS: Unsupported Interface"); +		return -EINVAL; +	} + +	if (!ret) { +		if (ras_cmd->ras_out_message.flags.err_inject_switch_disable_flag) { +			dev_warn(psp->adev->dev, "ECC switch disabled\n"); + +			ras_cmd->ras_status = TA_RAS_STATUS__ERROR_RAS_NOT_AVAILABLE; +		} +		else if (ras_cmd->ras_out_message.flags.reg_access_failure_flag) +			dev_warn(psp->adev->dev, +				 "RAS internal register access blocked\n"); +	} + +	return ret;  }  int psp_ras_enable_features(struct psp_context *psp, @@ -834,6 +978,33 @@ static int psp_ras_initialize(struct psp_context *psp)  	return 0;  } + +int psp_ras_trigger_error(struct psp_context *psp, +			  struct ta_ras_trigger_error_input *info) +{ +	struct ta_ras_shared_memory *ras_cmd; +	int ret; + +	if (!psp->ras.ras_initialized) +		return -EINVAL; + +	ras_cmd = (struct ta_ras_shared_memory *)psp->ras.ras_shared_buf; +	memset(ras_cmd, 0, sizeof(struct ta_ras_shared_memory)); + +	ras_cmd->cmd_id = TA_RAS_COMMAND__TRIGGER_ERROR; +	ras_cmd->ras_in_message.trigger_error = *info; + +	ret = psp_ras_invoke(psp, ras_cmd->cmd_id); +	if (ret) +		return -EINVAL; + +	/* If err_event_athub occurs error inject was successful, however +	   return status from TA is no long reliable */ +	if (amdgpu_ras_intr_triggered()) +		return 0; + +	return ras_cmd->ras_status; +}  // ras end  // HDCP start @@ -884,6 +1055,7 @@ static int psp_hdcp_load(struct psp_context *psp)  	if (!ret) {  		psp->hdcp_context.hdcp_initialized = true;  		psp->hdcp_context.session_id = cmd->resp.session_id; +		mutex_init(&psp->hdcp_context.mutex);  	}  	kfree(cmd); @@ -1029,6 +1201,7 @@ static int psp_dtm_load(struct psp_context *psp)  	if (!ret) {  		psp->dtm_context.dtm_initialized = true;  		psp->dtm_context.session_id = cmd->resp.session_id; +		mutex_init(&psp->dtm_context.mutex);  	}  	kfree(cmd); @@ -1169,16 +1342,20 @@ static int psp_hw_start(struct psp_context *psp)  	}  	/* -	 * For those ASICs with DF Cstate management centralized +	 * For ASICs with DF Cstate management centralized  	 * to PMFW, TMR setup should be performed after PMFW  	 * loaded and before other non-psp firmware loaded.  	 */ -	if (!psp->pmfw_centralized_cstate_management) { -		ret = psp_tmr_load(psp); -		if (ret) { -			DRM_ERROR("PSP load tmr failed!\n"); +	if (psp->pmfw_centralized_cstate_management) { +		ret = psp_load_smu_fw(psp); +		if (ret)  			return ret; -		} +	} + +	ret = psp_tmr_load(psp); +	if (ret) { +		DRM_ERROR("PSP load tmr failed!\n"); +		return ret;  	}  	return 0; @@ -1355,7 +1532,7 @@ static int psp_prep_load_ip_fw_cmd_buf(struct amdgpu_firmware_info *ucode,  }  static int psp_execute_np_fw_load(struct psp_context *psp, -			       struct amdgpu_firmware_info *ucode) +			          struct amdgpu_firmware_info *ucode)  {  	int ret = 0; @@ -1369,64 +1546,96 @@ static int psp_execute_np_fw_load(struct psp_context *psp,  	return ret;  } +static int psp_load_smu_fw(struct psp_context *psp) +{ +	int ret; +	struct amdgpu_device* adev = psp->adev; +	struct amdgpu_firmware_info *ucode = +			&adev->firmware.ucode[AMDGPU_UCODE_ID_SMC]; +	struct amdgpu_ras *ras = psp->ras.ras; + +	if (!ucode->fw || amdgpu_sriov_vf(psp->adev)) +		return 0; + + +	if (adev->in_gpu_reset && ras && ras->supported) { +		ret = amdgpu_dpm_set_mp1_state(adev, PP_MP1_STATE_UNLOAD); +		if (ret) { +			DRM_WARN("Failed to set MP1 state prepare for reload\n"); +		} +	} + +	ret = psp_execute_np_fw_load(psp, ucode); + +	if (ret) +		DRM_ERROR("PSP load smu failed!\n"); + +	return ret; +} + +static bool fw_load_skip_check(struct psp_context *psp, +			       struct amdgpu_firmware_info *ucode) +{ +	if (!ucode->fw) +		return true; + +	if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC && +	    (psp_smu_reload_quirk(psp) || +	     psp->autoload_supported || +	     psp->pmfw_centralized_cstate_management)) +		return true; + +	if (amdgpu_sriov_vf(psp->adev) && +	   (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA0 +	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1 +	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2 +	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3 +	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA4 +	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA5 +	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA6 +	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA7 +	    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G +	    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL +	    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM +	    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM +	    || ucode->ucode_id == AMDGPU_UCODE_ID_SMC)) +		/*skip ucode loading in SRIOV VF */ +		return true; + +	if (psp->autoload_supported && +	    (ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC1_JT || +	     ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC2_JT)) +		/* skip mec JT when autoload is enabled */ +		return true; + +	return false; +} +  static int psp_np_fw_load(struct psp_context *psp)  {  	int i, ret;  	struct amdgpu_firmware_info *ucode;  	struct amdgpu_device* adev = psp->adev; -	if (psp->autoload_supported || -	    psp->pmfw_centralized_cstate_management) { -		ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC]; -		if (!ucode->fw || amdgpu_sriov_vf(adev)) -			goto out; - -		ret = psp_execute_np_fw_load(psp, ucode); +	if (psp->autoload_supported && +	    !psp->pmfw_centralized_cstate_management) { +		ret = psp_load_smu_fw(psp);  		if (ret)  			return ret;  	} -	if (psp->pmfw_centralized_cstate_management) { -		ret = psp_tmr_load(psp); -		if (ret) { -			DRM_ERROR("PSP load tmr failed!\n"); -			return ret; -		} -	} - -out:  	for (i = 0; i < adev->firmware.max_ucodes; i++) {  		ucode = &adev->firmware.ucode[i]; -		if (!ucode->fw) -			continue;  		if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC && -		    (psp_smu_reload_quirk(psp) || -		     psp->autoload_supported || -		     psp->pmfw_centralized_cstate_management)) -			continue; - -		if (amdgpu_sriov_vf(adev) && -		   (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA0 -		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1 -		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2 -		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3 -		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA4 -		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA5 -		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA6 -		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA7 -                    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G -	            || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL -	            || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM -	            || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM -	            || ucode->ucode_id == AMDGPU_UCODE_ID_SMC)) -			/*skip ucode loading in SRIOV VF */ +		    !fw_load_skip_check(psp, ucode)) { +			ret = psp_load_smu_fw(psp); +			if (ret) +				return ret;  			continue; +		} -		if (psp->autoload_supported && -		    (ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC1_JT || -		     ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC2_JT)) -			/* skip mec JT when autoload is enabled */ +		if (fw_load_skip_check(psp, ucode))  			continue;  		psp_print_fw_hdr(psp, ucode); @@ -1438,17 +1647,12 @@ out:  		/* Start rlc autoload after psp recieved all the gfx firmware */  		if (psp->autoload_supported && ucode->ucode_id == (amdgpu_sriov_vf(adev) ?  		    AMDGPU_UCODE_ID_CP_MEC2 : AMDGPU_UCODE_ID_RLC_G)) { -			ret = psp_rlc_autoload(psp); +			ret = psp_rlc_autoload_start(psp);  			if (ret) {  				DRM_ERROR("Failed to start rlc autoload\n");  				return ret;  			}  		} -#if 0 -		/* check if firmware loaded sucessfully */ -		if (!amdgpu_psp_check_fw_loading_status(adev, i)) -			return -EINVAL; -#endif  	}  	return 0; @@ -1806,19 +2010,110 @@ int psp_ring_cmd_submit(struct psp_context *psp,  	return 0;  } -static bool psp_check_fw_loading_status(struct amdgpu_device *adev, -					enum AMDGPU_UCODE_ID ucode_type) +int psp_init_asd_microcode(struct psp_context *psp, +			   const char *chip_name)  { -	struct amdgpu_firmware_info *ucode = NULL; +	struct amdgpu_device *adev = psp->adev; +	char fw_name[30]; +	const struct psp_firmware_header_v1_0 *asd_hdr; +	int err = 0; -	if (!adev->firmware.fw_size) -		return false; +	if (!chip_name) { +		dev_err(adev->dev, "invalid chip name for asd microcode\n"); +		return -EINVAL; +	} -	ucode = &adev->firmware.ucode[ucode_type]; -	if (!ucode->fw || !ucode->ucode_size) -		return false; +	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_asd.bin", chip_name); +	err = request_firmware(&adev->psp.asd_fw, fw_name, adev->dev); +	if (err) +		goto out; + +	err = amdgpu_ucode_validate(adev->psp.asd_fw); +	if (err) +		goto out; + +	asd_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data; +	adev->psp.asd_fw_version = le32_to_cpu(asd_hdr->header.ucode_version); +	adev->psp.asd_feature_version = le32_to_cpu(asd_hdr->ucode_feature_version); +	adev->psp.asd_ucode_size = le32_to_cpu(asd_hdr->header.ucode_size_bytes); +	adev->psp.asd_start_addr = (uint8_t *)asd_hdr + +				le32_to_cpu(asd_hdr->header.ucode_array_offset_bytes); +	return 0; +out: +	dev_err(adev->dev, "fail to initialize asd microcode\n"); +	release_firmware(adev->psp.asd_fw); +	adev->psp.asd_fw = NULL; +	return err; +} + +int psp_init_sos_microcode(struct psp_context *psp, +			   const char *chip_name) +{ +	struct amdgpu_device *adev = psp->adev; +	char fw_name[30]; +	const struct psp_firmware_header_v1_0 *sos_hdr; +	const struct psp_firmware_header_v1_1 *sos_hdr_v1_1; +	const struct psp_firmware_header_v1_2 *sos_hdr_v1_2; +	int err = 0; + +	if (!chip_name) { +		dev_err(adev->dev, "invalid chip name for sos microcode\n"); +		return -EINVAL; +	} + +	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sos.bin", chip_name); +	err = request_firmware(&adev->psp.sos_fw, fw_name, adev->dev); +	if (err) +		goto out; + +	err = amdgpu_ucode_validate(adev->psp.sos_fw); +	if (err) +		goto out; + +	sos_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.sos_fw->data; +	amdgpu_ucode_print_psp_hdr(&sos_hdr->header); + +	switch (sos_hdr->header.header_version_major) { +	case 1: +		adev->psp.sos_fw_version = le32_to_cpu(sos_hdr->header.ucode_version); +		adev->psp.sos_feature_version = le32_to_cpu(sos_hdr->ucode_feature_version); +		adev->psp.sos_bin_size = le32_to_cpu(sos_hdr->sos_size_bytes); +		adev->psp.sys_bin_size = le32_to_cpu(sos_hdr->sos_offset_bytes); +		adev->psp.sys_start_addr = (uint8_t *)sos_hdr + +				le32_to_cpu(sos_hdr->header.ucode_array_offset_bytes); +		adev->psp.sos_start_addr = (uint8_t *)adev->psp.sys_start_addr + +				le32_to_cpu(sos_hdr->sos_offset_bytes); +		if (sos_hdr->header.header_version_minor == 1) { +			sos_hdr_v1_1 = (const struct psp_firmware_header_v1_1 *)adev->psp.sos_fw->data; +			adev->psp.toc_bin_size = le32_to_cpu(sos_hdr_v1_1->toc_size_bytes); +			adev->psp.toc_start_addr = (uint8_t *)adev->psp.sys_start_addr + +					le32_to_cpu(sos_hdr_v1_1->toc_offset_bytes); +			adev->psp.kdb_bin_size = le32_to_cpu(sos_hdr_v1_1->kdb_size_bytes); +			adev->psp.kdb_start_addr = (uint8_t *)adev->psp.sys_start_addr + +					le32_to_cpu(sos_hdr_v1_1->kdb_offset_bytes); +		} +		if (sos_hdr->header.header_version_minor == 2) { +			sos_hdr_v1_2 = (const struct psp_firmware_header_v1_2 *)adev->psp.sos_fw->data; +			adev->psp.kdb_bin_size = le32_to_cpu(sos_hdr_v1_2->kdb_size_bytes); +			adev->psp.kdb_start_addr = (uint8_t *)adev->psp.sys_start_addr + +						    le32_to_cpu(sos_hdr_v1_2->kdb_offset_bytes); +		} +		break; +	default: +		dev_err(adev->dev, +			"unsupported psp sos firmware\n"); +		err = -EINVAL; +		goto out; +	} + +	return 0; +out: +	dev_err(adev->dev, +		"failed to init sos firmware\n"); +	release_firmware(adev->psp.sos_fw); +	adev->psp.sos_fw = NULL; -	return psp_compare_sram_data(&adev->psp, ucode, ucode_type); +	return err;  }  static int psp_set_clockgating_state(void *handle, @@ -1957,16 +2252,6 @@ static void psp_sysfs_fini(struct amdgpu_device *adev)  	device_remove_file(adev->dev, &dev_attr_usbc_pd_fw);  } -static const struct amdgpu_psp_funcs psp_funcs = { -	.check_fw_loading_status = psp_check_fw_loading_status, -}; - -static void psp_set_funcs(struct amdgpu_device *adev) -{ -	if (NULL == adev->firmware.funcs) -		adev->firmware.funcs = &psp_funcs; -} -  const struct amdgpu_ip_block_version psp_v3_1_ip_block =  {  	.type = AMD_IP_BLOCK_TYPE_PSP,  |