diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 558 | 
1 files changed, 275 insertions, 283 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index e1b8d8daeafc..146f96661b6b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -158,7 +158,7 @@ psp_cmd_submit_buf(struct psp_context *psp,  	memcpy(psp->cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp));  	index = atomic_inc_return(&psp->fence_value); -	ret = psp_cmd_submit(psp, psp->cmd_buf_mc_addr, fence_mc_addr, index); +	ret = psp_ring_cmd_submit(psp, psp->cmd_buf_mc_addr, fence_mc_addr, index);  	if (ret) {  		atomic_dec(&psp->fence_value);  		mutex_unlock(&psp->mutex); @@ -191,9 +191,9 @@ psp_cmd_submit_buf(struct psp_context *psp,  		if (ucode)  			DRM_WARN("failed to load ucode id (%d) ",  				  ucode->ucode_id); -		DRM_DEBUG_DRIVER("psp command (0x%X) failed and response status is (0x%X)\n", +		DRM_WARN("psp command (0x%X) failed and response status is (0x%X)\n",  			 psp->cmd_buf_mem->cmd_id, -			 psp->cmd_buf_mem->resp.status & GFX_CMD_STATUS_MASK); +			 psp->cmd_buf_mem->resp.status);  		if (!timeout) {  			mutex_unlock(&psp->mutex);  			return -EINVAL; @@ -318,35 +318,17 @@ static int psp_tmr_load(struct psp_context *psp)  	return ret;  } -static void psp_prep_asd_cmd_buf(struct psp_gfx_cmd_resp *cmd, -				 uint64_t asd_mc, uint64_t asd_mc_shared, -				 uint32_t size, uint32_t shared_size) +static void psp_prep_asd_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, +				uint64_t asd_mc, uint32_t size)  {  	cmd->cmd_id = GFX_CMD_ID_LOAD_ASD;  	cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(asd_mc);  	cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(asd_mc);  	cmd->cmd.cmd_load_ta.app_len = size; -	cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(asd_mc_shared); -	cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(asd_mc_shared); -	cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size; -} - -static int psp_asd_init(struct psp_context *psp) -{ -	int ret; - -	/* -	 * Allocate 16k memory aligned to 4k from Frame Buffer (local -	 * physical) for shared ASD <-> Driver -	 */ -	ret = amdgpu_bo_create_kernel(psp->adev, PSP_ASD_SHARED_MEM_SIZE, -				      PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, -				      &psp->asd_shared_bo, -				      &psp->asd_shared_mc_addr, -				      &psp->asd_shared_buf); - -	return ret; +	cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = 0; +	cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = 0; +	cmd->cmd.cmd_load_ta.cmd_buf_len = 0;  }  static int psp_asd_load(struct psp_context *psp) @@ -368,11 +350,49 @@ static int psp_asd_load(struct psp_context *psp)  	memset(psp->fw_pri_buf, 0, PSP_1_MEG);  	memcpy(psp->fw_pri_buf, psp->asd_start_addr, psp->asd_ucode_size); -	psp_prep_asd_cmd_buf(cmd, psp->fw_pri_mc_addr, psp->asd_shared_mc_addr, -			     psp->asd_ucode_size, PSP_ASD_SHARED_MEM_SIZE); +	psp_prep_asd_load_cmd_buf(cmd, psp->fw_pri_mc_addr, +				  psp->asd_ucode_size); + +	ret = psp_cmd_submit_buf(psp, NULL, cmd, +				 psp->fence_buf_mc_addr); +	if (!ret) { +		psp->asd_context.asd_initialized = true; +		psp->asd_context.session_id = cmd->resp.session_id; +	} + +	kfree(cmd); + +	return ret; +} + +static void psp_prep_ta_unload_cmd_buf(struct psp_gfx_cmd_resp *cmd, +				       uint32_t session_id) +{ +	cmd->cmd_id = GFX_CMD_ID_UNLOAD_TA; +	cmd->cmd.cmd_unload_ta.session_id = session_id; +} + +static int psp_asd_unload(struct psp_context *psp) +{ +	int ret; +	struct psp_gfx_cmd_resp *cmd; + +	if (amdgpu_sriov_vf(psp->adev)) +		return 0; + +	if (!psp->asd_context.asd_initialized) +		return 0; + +	cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); +	if (!cmd) +		return -ENOMEM; + +	psp_prep_ta_unload_cmd_buf(cmd, psp->asd_context.session_id);  	ret = psp_cmd_submit_buf(psp, NULL, cmd,  				 psp->fence_buf_mc_addr); +	if (!ret) +		psp->asd_context.asd_initialized = false;  	kfree(cmd); @@ -407,18 +427,20 @@ int psp_reg_program(struct psp_context *psp, enum psp_reg_prog_id reg,  	return ret;  } -static void psp_prep_xgmi_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, -					  uint64_t xgmi_ta_mc, uint64_t xgmi_mc_shared, -					  uint32_t xgmi_ta_size, uint32_t shared_size) +static void psp_prep_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, +				     uint64_t ta_bin_mc, +				     uint32_t ta_bin_size, +				     uint64_t ta_shared_mc, +				     uint32_t ta_shared_size)  { -        cmd->cmd_id = GFX_CMD_ID_LOAD_TA; -        cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(xgmi_ta_mc); -        cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(xgmi_ta_mc); -        cmd->cmd.cmd_load_ta.app_len = xgmi_ta_size; +	cmd->cmd_id 				= GFX_CMD_ID_LOAD_TA; +	cmd->cmd.cmd_load_ta.app_phy_addr_lo 	= lower_32_bits(ta_bin_mc); +	cmd->cmd.cmd_load_ta.app_phy_addr_hi 	= upper_32_bits(ta_bin_mc); +	cmd->cmd.cmd_load_ta.app_len 		= ta_bin_size; -        cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(xgmi_mc_shared); -        cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(xgmi_mc_shared); -        cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size; +	cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(ta_shared_mc); +	cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(ta_shared_mc); +	cmd->cmd.cmd_load_ta.cmd_buf_len 	 = ta_shared_size;  }  static int psp_xgmi_init_shared_buf(struct psp_context *psp) @@ -438,6 +460,36 @@ static int psp_xgmi_init_shared_buf(struct psp_context *psp)  	return ret;  } +static void psp_prep_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd, +				       uint32_t ta_cmd_id, +				       uint32_t session_id) +{ +	cmd->cmd_id 				= GFX_CMD_ID_INVOKE_CMD; +	cmd->cmd.cmd_invoke_cmd.session_id 	= session_id; +	cmd->cmd.cmd_invoke_cmd.ta_cmd_id 	= ta_cmd_id; +} + +int psp_ta_invoke(struct psp_context *psp, +		  uint32_t ta_cmd_id, +		  uint32_t session_id) +{ +	int ret; +	struct psp_gfx_cmd_resp *cmd; + +	cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); +	if (!cmd) +		return -ENOMEM; + +	psp_prep_ta_invoke_cmd_buf(cmd, ta_cmd_id, session_id); + +	ret = psp_cmd_submit_buf(psp, NULL, cmd, +				 psp->fence_buf_mc_addr); + +	kfree(cmd); + +	return ret; +} +  static int psp_xgmi_load(struct psp_context *psp)  {  	int ret; @@ -446,8 +498,6 @@ static int psp_xgmi_load(struct psp_context *psp)  	/*  	 * TODO: bypass the loading in sriov for now  	 */ -	if (amdgpu_sriov_vf(psp->adev)) -		return 0;  	cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);  	if (!cmd) @@ -456,9 +506,11 @@ static int psp_xgmi_load(struct psp_context *psp)  	memset(psp->fw_pri_buf, 0, PSP_1_MEG);  	memcpy(psp->fw_pri_buf, psp->ta_xgmi_start_addr, psp->ta_xgmi_ucode_size); -	psp_prep_xgmi_ta_load_cmd_buf(cmd, psp->fw_pri_mc_addr, -				      psp->xgmi_context.xgmi_shared_mc_addr, -				      psp->ta_xgmi_ucode_size, PSP_XGMI_SHARED_MEM_SIZE); +	psp_prep_ta_load_cmd_buf(cmd, +				 psp->fw_pri_mc_addr, +				 psp->ta_xgmi_ucode_size, +				 psp->xgmi_context.xgmi_shared_mc_addr, +				 PSP_XGMI_SHARED_MEM_SIZE);  	ret = psp_cmd_submit_buf(psp, NULL, cmd,  				 psp->fence_buf_mc_addr); @@ -473,29 +525,25 @@ static int psp_xgmi_load(struct psp_context *psp)  	return ret;  } -static void psp_prep_xgmi_ta_unload_cmd_buf(struct psp_gfx_cmd_resp *cmd, -					    uint32_t xgmi_session_id) -{ -	cmd->cmd_id = GFX_CMD_ID_UNLOAD_TA; -	cmd->cmd.cmd_unload_ta.session_id = xgmi_session_id; -} -  static int psp_xgmi_unload(struct psp_context *psp)  {  	int ret;  	struct psp_gfx_cmd_resp *cmd; +	struct amdgpu_device *adev = psp->adev; + +	/* XGMI TA unload currently is not supported on Arcturus */ +	if (adev->asic_type == CHIP_ARCTURUS) +		return 0;  	/*  	 * TODO: bypass the unloading in sriov for now  	 */ -	if (amdgpu_sriov_vf(psp->adev)) -		return 0;  	cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);  	if (!cmd)  		return -ENOMEM; -	psp_prep_xgmi_ta_unload_cmd_buf(cmd, psp->xgmi_context.session_id); +	psp_prep_ta_unload_cmd_buf(cmd, psp->xgmi_context.session_id);  	ret = psp_cmd_submit_buf(psp, NULL, cmd,  				 psp->fence_buf_mc_addr); @@ -505,40 +553,9 @@ static int psp_xgmi_unload(struct psp_context *psp)  	return ret;  } -static void psp_prep_xgmi_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd, -					    uint32_t ta_cmd_id, -					    uint32_t xgmi_session_id) -{ -	cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD; -	cmd->cmd.cmd_invoke_cmd.session_id = xgmi_session_id; -	cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id; -	/* Note: cmd_invoke_cmd.buf is not used for now */ -} -  int psp_xgmi_invoke(struct psp_context *psp, uint32_t ta_cmd_id)  { -	int ret; -	struct psp_gfx_cmd_resp *cmd; - -	/* -	 * TODO: bypass the loading in sriov for now -	*/ -	if (amdgpu_sriov_vf(psp->adev)) -		return 0; - -	cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); -	if (!cmd) -		return -ENOMEM; - -	psp_prep_xgmi_ta_invoke_cmd_buf(cmd, ta_cmd_id, -					psp->xgmi_context.session_id); - -	ret = psp_cmd_submit_buf(psp, NULL, cmd, -				 psp->fence_buf_mc_addr); - -	kfree(cmd); - -        return ret; +	return psp_ta_invoke(psp, ta_cmd_id, psp->xgmi_context.session_id);  }  static int psp_xgmi_terminate(struct psp_context *psp) @@ -594,20 +611,6 @@ static int psp_xgmi_initialize(struct psp_context *psp)  }  // ras begin -static void psp_prep_ras_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, -		uint64_t ras_ta_mc, uint64_t ras_mc_shared, -		uint32_t ras_ta_size, uint32_t shared_size) -{ -	cmd->cmd_id = GFX_CMD_ID_LOAD_TA; -	cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(ras_ta_mc); -	cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(ras_ta_mc); -	cmd->cmd.cmd_load_ta.app_len = ras_ta_size; - -	cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(ras_mc_shared); -	cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(ras_mc_shared); -	cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size; -} -  static int psp_ras_init_shared_buf(struct psp_context *psp)  {  	int ret; @@ -643,15 +646,17 @@ static int psp_ras_load(struct psp_context *psp)  	memset(psp->fw_pri_buf, 0, PSP_1_MEG);  	memcpy(psp->fw_pri_buf, psp->ta_ras_start_addr, psp->ta_ras_ucode_size); -	psp_prep_ras_ta_load_cmd_buf(cmd, psp->fw_pri_mc_addr, -			psp->ras.ras_shared_mc_addr, -			psp->ta_ras_ucode_size, PSP_RAS_SHARED_MEM_SIZE); +	psp_prep_ta_load_cmd_buf(cmd, +				 psp->fw_pri_mc_addr, +				 psp->ta_ras_ucode_size, +				 psp->ras.ras_shared_mc_addr, +				 PSP_RAS_SHARED_MEM_SIZE);  	ret = psp_cmd_submit_buf(psp, NULL, cmd,  			psp->fence_buf_mc_addr);  	if (!ret) { -		psp->ras.ras_initialized = 1; +		psp->ras.ras_initialized = true;  		psp->ras.session_id = cmd->resp.session_id;  	} @@ -660,13 +665,6 @@ static int psp_ras_load(struct psp_context *psp)  	return ret;  } -static void psp_prep_ras_ta_unload_cmd_buf(struct psp_gfx_cmd_resp *cmd, -						uint32_t ras_session_id) -{ -	cmd->cmd_id = GFX_CMD_ID_UNLOAD_TA; -	cmd->cmd.cmd_unload_ta.session_id = ras_session_id; -} -  static int psp_ras_unload(struct psp_context *psp)  {  	int ret; @@ -682,7 +680,7 @@ static int psp_ras_unload(struct psp_context *psp)  	if (!cmd)  		return -ENOMEM; -	psp_prep_ras_ta_unload_cmd_buf(cmd, psp->ras.session_id); +	psp_prep_ta_unload_cmd_buf(cmd, psp->ras.session_id);  	ret = psp_cmd_submit_buf(psp, NULL, cmd,  			psp->fence_buf_mc_addr); @@ -692,40 +690,15 @@ static int psp_ras_unload(struct psp_context *psp)  	return ret;  } -static void psp_prep_ras_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd, -		uint32_t ta_cmd_id, -		uint32_t ras_session_id) -{ -	cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD; -	cmd->cmd.cmd_invoke_cmd.session_id = ras_session_id; -	cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id; -	/* Note: cmd_invoke_cmd.buf is not used for now */ -} -  int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id)  { -	int ret; -	struct psp_gfx_cmd_resp *cmd; -  	/*  	 * TODO: bypass the loading in sriov for now  	 */  	if (amdgpu_sriov_vf(psp->adev))  		return 0; -	cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); -	if (!cmd) -		return -ENOMEM; - -	psp_prep_ras_ta_invoke_cmd_buf(cmd, ta_cmd_id, -			psp->ras.session_id); - -	ret = psp_cmd_submit_buf(psp, NULL, cmd, -			psp->fence_buf_mc_addr); - -	kfree(cmd); - -	return ret; +	return psp_ta_invoke(psp, ta_cmd_id, psp->ras.session_id);  }  int psp_ras_enable_features(struct psp_context *psp, @@ -771,7 +744,7 @@ static int psp_ras_terminate(struct psp_context *psp)  	if (ret)  		return ret; -	psp->ras.ras_initialized = 0; +	psp->ras.ras_initialized = false;  	/* free ras shared memory */  	amdgpu_bo_free_kernel(&psp->ras.ras_shared_bo, @@ -812,24 +785,6 @@ static int psp_ras_initialize(struct psp_context *psp)  // ras end  // HDCP start -static void psp_prep_hdcp_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, -					  uint64_t hdcp_ta_mc, -					  uint64_t hdcp_mc_shared, -					  uint32_t hdcp_ta_size, -					  uint32_t shared_size) -{ -	cmd->cmd_id = GFX_CMD_ID_LOAD_TA; -	cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(hdcp_ta_mc); -	cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(hdcp_ta_mc); -	cmd->cmd.cmd_load_ta.app_len = hdcp_ta_size; - -	cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = -		lower_32_bits(hdcp_mc_shared); -	cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = -		upper_32_bits(hdcp_mc_shared); -	cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size; -} -  static int psp_hdcp_init_shared_buf(struct psp_context *psp)  {  	int ret; @@ -866,15 +821,16 @@ static int psp_hdcp_load(struct psp_context *psp)  	memcpy(psp->fw_pri_buf, psp->ta_hdcp_start_addr,  	       psp->ta_hdcp_ucode_size); -	psp_prep_hdcp_ta_load_cmd_buf(cmd, psp->fw_pri_mc_addr, -				      psp->hdcp_context.hdcp_shared_mc_addr, -				      psp->ta_hdcp_ucode_size, -				      PSP_HDCP_SHARED_MEM_SIZE); +	psp_prep_ta_load_cmd_buf(cmd, +				 psp->fw_pri_mc_addr, +				 psp->ta_hdcp_ucode_size, +				 psp->hdcp_context.hdcp_shared_mc_addr, +				 PSP_HDCP_SHARED_MEM_SIZE);  	ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);  	if (!ret) { -		psp->hdcp_context.hdcp_initialized = 1; +		psp->hdcp_context.hdcp_initialized = true;  		psp->hdcp_context.session_id = cmd->resp.session_id;  	} @@ -910,12 +866,6 @@ static int psp_hdcp_initialize(struct psp_context *psp)  	return 0;  } -static void psp_prep_hdcp_ta_unload_cmd_buf(struct psp_gfx_cmd_resp *cmd, -					    uint32_t hdcp_session_id) -{ -	cmd->cmd_id = GFX_CMD_ID_UNLOAD_TA; -	cmd->cmd.cmd_unload_ta.session_id = hdcp_session_id; -}  static int psp_hdcp_unload(struct psp_context *psp)  { @@ -932,7 +882,7 @@ static int psp_hdcp_unload(struct psp_context *psp)  	if (!cmd)  		return -ENOMEM; -	psp_prep_hdcp_ta_unload_cmd_buf(cmd, psp->hdcp_context.session_id); +	psp_prep_ta_unload_cmd_buf(cmd, psp->hdcp_context.session_id);  	ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); @@ -941,39 +891,15 @@ static int psp_hdcp_unload(struct psp_context *psp)  	return ret;  } -static void psp_prep_hdcp_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd, -					    uint32_t ta_cmd_id, -					    uint32_t hdcp_session_id) -{ -	cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD; -	cmd->cmd.cmd_invoke_cmd.session_id = hdcp_session_id; -	cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id; -	/* Note: cmd_invoke_cmd.buf is not used for now */ -} -  int psp_hdcp_invoke(struct psp_context *psp, uint32_t ta_cmd_id)  { -	int ret; -	struct psp_gfx_cmd_resp *cmd; -  	/*  	 * TODO: bypass the loading in sriov for now  	 */  	if (amdgpu_sriov_vf(psp->adev))  		return 0; -	cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); -	if (!cmd) -		return -ENOMEM; - -	psp_prep_hdcp_ta_invoke_cmd_buf(cmd, ta_cmd_id, -					psp->hdcp_context.session_id); - -	ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); - -	kfree(cmd); - -	return ret; +	return psp_ta_invoke(psp, ta_cmd_id, psp->hdcp_context.session_id);  }  static int psp_hdcp_terminate(struct psp_context *psp) @@ -993,7 +919,7 @@ static int psp_hdcp_terminate(struct psp_context *psp)  	if (ret)  		return ret; -	psp->hdcp_context.hdcp_initialized = 0; +	psp->hdcp_context.hdcp_initialized = false;  	/* free hdcp shared memory */  	amdgpu_bo_free_kernel(&psp->hdcp_context.hdcp_shared_bo, @@ -1005,22 +931,6 @@ static int psp_hdcp_terminate(struct psp_context *psp)  // HDCP end  // DTM start -static void psp_prep_dtm_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, -					 uint64_t dtm_ta_mc, -					 uint64_t dtm_mc_shared, -					 uint32_t dtm_ta_size, -					 uint32_t shared_size) -{ -	cmd->cmd_id = GFX_CMD_ID_LOAD_TA; -	cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(dtm_ta_mc); -	cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(dtm_ta_mc); -	cmd->cmd.cmd_load_ta.app_len = dtm_ta_size; - -	cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(dtm_mc_shared); -	cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(dtm_mc_shared); -	cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size; -} -  static int psp_dtm_init_shared_buf(struct psp_context *psp)  {  	int ret; @@ -1056,15 +966,16 @@ static int psp_dtm_load(struct psp_context *psp)  	memset(psp->fw_pri_buf, 0, PSP_1_MEG);  	memcpy(psp->fw_pri_buf, psp->ta_dtm_start_addr, psp->ta_dtm_ucode_size); -	psp_prep_dtm_ta_load_cmd_buf(cmd, psp->fw_pri_mc_addr, -				     psp->dtm_context.dtm_shared_mc_addr, -				     psp->ta_dtm_ucode_size, -				     PSP_DTM_SHARED_MEM_SIZE); +	psp_prep_ta_load_cmd_buf(cmd, +				 psp->fw_pri_mc_addr, +				 psp->ta_dtm_ucode_size, +				 psp->dtm_context.dtm_shared_mc_addr, +				 PSP_DTM_SHARED_MEM_SIZE);  	ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);  	if (!ret) { -		psp->dtm_context.dtm_initialized = 1; +		psp->dtm_context.dtm_initialized = true;  		psp->dtm_context.session_id = cmd->resp.session_id;  	} @@ -1102,23 +1013,13 @@ static int psp_dtm_initialize(struct psp_context *psp)  	return 0;  } -static void psp_prep_dtm_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd, -					   uint32_t ta_cmd_id, -					   uint32_t dtm_session_id) -{ -	cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD; -	cmd->cmd.cmd_invoke_cmd.session_id = dtm_session_id; -	cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id; -	/* Note: cmd_invoke_cmd.buf is not used for now */ -} - -int psp_dtm_invoke(struct psp_context *psp, uint32_t ta_cmd_id) +static int psp_dtm_unload(struct psp_context *psp)  {  	int ret;  	struct psp_gfx_cmd_resp *cmd;  	/* -	 * TODO: bypass the loading in sriov for now +	 * TODO: bypass the unloading in sriov for now  	 */  	if (amdgpu_sriov_vf(psp->adev))  		return 0; @@ -1127,8 +1028,7 @@ int psp_dtm_invoke(struct psp_context *psp, uint32_t ta_cmd_id)  	if (!cmd)  		return -ENOMEM; -	psp_prep_dtm_ta_invoke_cmd_buf(cmd, ta_cmd_id, -				       psp->dtm_context.session_id); +	psp_prep_ta_unload_cmd_buf(cmd, psp->dtm_context.session_id);  	ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); @@ -1137,6 +1037,17 @@ int psp_dtm_invoke(struct psp_context *psp, uint32_t ta_cmd_id)  	return ret;  } +int psp_dtm_invoke(struct psp_context *psp, uint32_t ta_cmd_id) +{ +	/* +	 * 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->dtm_context.session_id); +} +  static int psp_dtm_terminate(struct psp_context *psp)  {  	int ret; @@ -1150,11 +1061,11 @@ static int psp_dtm_terminate(struct psp_context *psp)  	if (!psp->dtm_context.dtm_initialized)  		return 0; -	ret = psp_hdcp_unload(psp); +	ret = psp_dtm_unload(psp);  	if (ret)  		return ret; -	psp->dtm_context.dtm_initialized = 0; +	psp->dtm_context.dtm_initialized = false;  	/* free hdcp shared memory */  	amdgpu_bo_free_kernel(&psp->dtm_context.dtm_shared_bo, @@ -1211,45 +1122,6 @@ static int psp_hw_start(struct psp_context *psp)  		return ret;  	} -	ret = psp_asd_init(psp); -	if (ret) { -		DRM_ERROR("PSP asd init failed!\n"); -		return ret; -	} - -	ret = psp_asd_load(psp); -	if (ret) { -		DRM_ERROR("PSP load asd failed!\n"); -		return ret; -	} - -	if (adev->gmc.xgmi.num_physical_nodes > 1) { -		ret = psp_xgmi_initialize(psp); -		/* Warning the XGMI seesion initialize failure -		 * Instead of stop driver initialization -		 */ -		if (ret) -			dev_err(psp->adev->dev, -				"XGMI: Failed to initialize XGMI session\n"); -	} - -	if (psp->adev->psp.ta_fw) { -		ret = psp_ras_initialize(psp); -		if (ret) -			dev_err(psp->adev->dev, -					"RAS: Failed to initialize RAS\n"); - -		ret = psp_hdcp_initialize(psp); -		if (ret) -			dev_err(psp->adev->dev, -				"HDCP: Failed to initialize HDCP\n"); - -		ret = psp_dtm_initialize(psp); -		if (ret) -			dev_err(psp->adev->dev, -				"DTM: Failed to initialize DTM\n"); -	} -  	return 0;  } @@ -1329,6 +1201,9 @@ static int psp_get_fw_type(struct amdgpu_firmware_info *ucode,  	case AMDGPU_UCODE_ID_VCN:  		*type = GFX_FW_TYPE_VCN;  		break; +	case AMDGPU_UCODE_ID_VCN1: +		*type = GFX_FW_TYPE_VCN1; +		break;  	case AMDGPU_UCODE_ID_DMCU_ERAM:  		*type = GFX_FW_TYPE_DMCU_ERAM;  		break; @@ -1341,6 +1216,9 @@ static int psp_get_fw_type(struct amdgpu_firmware_info *ucode,  	case AMDGPU_UCODE_ID_VCN1_RAM:  		*type = GFX_FW_TYPE_VCN1_RAM;  		break; +	case AMDGPU_UCODE_ID_DMCUB: +		*type = GFX_FW_TYPE_DMUB; +		break;  	case AMDGPU_UCODE_ID_MAXIMUM:  	default:  		return -EINVAL; @@ -1470,7 +1348,8 @@ out:                      || 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_RLC_RESTORE_LIST_SRM_MEM +	            || ucode->ucode_id == AMDGPU_UCODE_ID_SMC))  			/*skip ucode loading in SRIOV VF */  			continue; @@ -1519,16 +1398,13 @@ static int psp_load_fw(struct amdgpu_device *adev)  	if (!psp->cmd)  		return -ENOMEM; -	/* this fw pri bo is not used under SRIOV */ -	if (!amdgpu_sriov_vf(psp->adev)) { -		ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG, -					      AMDGPU_GEM_DOMAIN_GTT, -					      &psp->fw_pri_bo, -					      &psp->fw_pri_mc_addr, -					      &psp->fw_pri_buf); -		if (ret) -			goto failed; -	} +	ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG, +					AMDGPU_GEM_DOMAIN_GTT, +					&psp->fw_pri_bo, +					&psp->fw_pri_mc_addr, +					&psp->fw_pri_buf); +	if (ret) +		goto failed;  	ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE,  					AMDGPU_GEM_DOMAIN_VRAM, @@ -1562,6 +1438,39 @@ skip_memalloc:  	if (ret)  		goto failed; +	ret = psp_asd_load(psp); +	if (ret) { +		DRM_ERROR("PSP load asd failed!\n"); +		return ret; +	} + +	if (adev->gmc.xgmi.num_physical_nodes > 1) { +		ret = psp_xgmi_initialize(psp); +		/* Warning the XGMI seesion initialize failure +		 * Instead of stop driver initialization +		 */ +		if (ret) +			dev_err(psp->adev->dev, +				"XGMI: Failed to initialize XGMI session\n"); +	} + +	if (psp->adev->psp.ta_fw) { +		ret = psp_ras_initialize(psp); +		if (ret) +			dev_err(psp->adev->dev, +					"RAS: Failed to initialize RAS\n"); + +		ret = psp_hdcp_initialize(psp); +		if (ret) +			dev_err(psp->adev->dev, +				"HDCP: Failed to initialize HDCP\n"); + +		ret = psp_dtm_initialize(psp); +		if (ret) +			dev_err(psp->adev->dev, +				"DTM: Failed to initialize DTM\n"); +	} +  	return 0;  failed: @@ -1619,6 +1528,8 @@ static int psp_hw_fini(void *handle)  		psp_hdcp_terminate(psp);  	} +	psp_asd_unload(psp); +  	psp_ring_destroy(psp, PSP_RING_TYPE__KM);  	pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; @@ -1627,8 +1538,6 @@ static int psp_hw_fini(void *handle)  			      &psp->fw_pri_mc_addr, &psp->fw_pri_buf);  	amdgpu_bo_free_kernel(&psp->fence_buf_bo,  			      &psp->fence_buf_mc_addr, &psp->fence_buf); -	amdgpu_bo_free_kernel(&psp->asd_shared_bo, &psp->asd_shared_mc_addr, -			      &psp->asd_shared_buf);  	amdgpu_bo_free_kernel(&psp->cmd_buf_bo, &psp->cmd_buf_mc_addr,  			      (void **)&psp->cmd_buf_mem); @@ -1704,6 +1613,39 @@ static int psp_resume(void *handle)  	if (ret)  		goto failed; +	ret = psp_asd_load(psp); +	if (ret) { +		DRM_ERROR("PSP load asd failed!\n"); +		goto failed; +	} + +	if (adev->gmc.xgmi.num_physical_nodes > 1) { +		ret = psp_xgmi_initialize(psp); +		/* Warning the XGMI seesion initialize failure +		 * Instead of stop driver initialization +		 */ +		if (ret) +			dev_err(psp->adev->dev, +				"XGMI: Failed to initialize XGMI session\n"); +	} + +	if (psp->adev->psp.ta_fw) { +		ret = psp_ras_initialize(psp); +		if (ret) +			dev_err(psp->adev->dev, +					"RAS: Failed to initialize RAS\n"); + +		ret = psp_hdcp_initialize(psp); +		if (ret) +			dev_err(psp->adev->dev, +				"HDCP: Failed to initialize HDCP\n"); + +		ret = psp_dtm_initialize(psp); +		if (ret) +			dev_err(psp->adev->dev, +				"DTM: Failed to initialize DTM\n"); +	} +  	mutex_unlock(&adev->firmware.mutex);  	return 0; @@ -1758,6 +1700,56 @@ int psp_update_vcn_sram(struct amdgpu_device *adev, int inst_idx,  	return psp_execute_np_fw_load(&adev->psp, &ucode);  } +int psp_ring_cmd_submit(struct psp_context *psp, +			uint64_t cmd_buf_mc_addr, +			uint64_t fence_mc_addr, +			int index) +{ +	unsigned int psp_write_ptr_reg = 0; +	struct psp_gfx_rb_frame *write_frame; +	struct psp_ring *ring = &psp->km_ring; +	struct psp_gfx_rb_frame *ring_buffer_start = ring->ring_mem; +	struct psp_gfx_rb_frame *ring_buffer_end = ring_buffer_start + +		ring->ring_size / sizeof(struct psp_gfx_rb_frame) - 1; +	struct amdgpu_device *adev = psp->adev; +	uint32_t ring_size_dw = ring->ring_size / 4; +	uint32_t rb_frame_size_dw = sizeof(struct psp_gfx_rb_frame) / 4; + +	/* KM (GPCOM) prepare write pointer */ +	psp_write_ptr_reg = psp_ring_get_wptr(psp); + +	/* Update KM RB frame pointer to new frame */ +	/* write_frame ptr increments by size of rb_frame in bytes */ +	/* psp_write_ptr_reg increments by size of rb_frame in DWORDs */ +	if ((psp_write_ptr_reg % ring_size_dw) == 0) +		write_frame = ring_buffer_start; +	else +		write_frame = ring_buffer_start + (psp_write_ptr_reg / rb_frame_size_dw); +	/* Check invalid write_frame ptr address */ +	if ((write_frame < ring_buffer_start) || (ring_buffer_end < write_frame)) { +		DRM_ERROR("ring_buffer_start = %p; ring_buffer_end = %p; write_frame = %p\n", +			  ring_buffer_start, ring_buffer_end, write_frame); +		DRM_ERROR("write_frame is pointing to address out of bounds\n"); +		return -EINVAL; +	} + +	/* Initialize KM RB frame */ +	memset(write_frame, 0, sizeof(struct psp_gfx_rb_frame)); + +	/* Update KM RB frame */ +	write_frame->cmd_buf_addr_hi = upper_32_bits(cmd_buf_mc_addr); +	write_frame->cmd_buf_addr_lo = lower_32_bits(cmd_buf_mc_addr); +	write_frame->fence_addr_hi = upper_32_bits(fence_mc_addr); +	write_frame->fence_addr_lo = lower_32_bits(fence_mc_addr); +	write_frame->fence_value = index; +	amdgpu_asic_flush_hdp(adev, NULL); + +	/* Update the write Pointer in DWORDs */ +	psp_write_ptr_reg = (psp_write_ptr_reg + rb_frame_size_dw) % ring_size_dw; +	psp_ring_set_wptr(psp, psp_write_ptr_reg); +	return 0; +} +  static bool psp_check_fw_loading_status(struct amdgpu_device *adev,  					enum AMDGPU_UCODE_ID ucode_type)  { | 
