diff options
author | Emily Deng <Emily.Deng@amd.com> | 2020-06-11 06:36:04 +0300 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2020-07-01 08:59:19 +0300 |
commit | 3bda8acd974e362069e291a78c59a10624debc6e (patch) | |
tree | ca482af73ace91f30795dca1b83c6c5ee1f5a820 /drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | |
parent | b6df946ef4b5ae29183b2fdb2d12c381c757b3fb (diff) | |
download | linux-3bda8acd974e362069e291a78c59a10624debc6e.tar.xz |
drm/amdgpu/sriov: Add clear vf fw support
Guest VM issue the PSP clear_vf_fw command at 2 points:
1.On VF driver loading, after VF message PSP to setup rings,
the next command is “clear_vf_fw”
2.On VF driver unload before VF message to
destroy rings
Signed-off-by: Emily Deng <Emily.Deng@amd.com>
Ack-by: Monk.liu <monk.liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index cdd65b577986..60558497f054 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -270,8 +270,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); + /* We allow TEE_ERROR_NOT_SUPPORTED for VMR command and PSP_ERR_UNKNOWN_COMMAND in SRIOV */ + skip_unsupport = (psp->cmd_buf_mem->resp.status == TEE_ERROR_NOT_SUPPORTED || + psp->cmd_buf_mem->resp.status == PSP_ERR_UNKNOWN_COMMAND) && 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 @@ -389,6 +390,26 @@ static int psp_tmr_init(struct psp_context *psp) return ret; } +static int psp_clear_vf_fw(struct psp_context *psp) +{ + int ret; + struct psp_gfx_cmd_resp *cmd; + + if (!amdgpu_sriov_vf(psp->adev) || psp->adev->asic_type != CHIP_NAVI12) + return 0; + + cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + cmd->cmd_id = GFX_CMD_ID_CLEAR_VF_FW; + + ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); + kfree(cmd); + + return ret; +} + static int psp_tmr_load(struct psp_context *psp) { int ret; @@ -1382,6 +1403,12 @@ static int psp_hw_start(struct psp_context *psp) return ret; } + ret = psp_clear_vf_fw(psp); + if (ret) { + DRM_ERROR("PSP clear vf fw!\n"); + return ret; + } + ret = psp_tmr_init(psp); if (ret) { DRM_ERROR("PSP tmr init failed!\n"); @@ -1843,6 +1870,7 @@ static int psp_hw_fini(void *handle) struct psp_context *psp = &adev->psp; void *tmr_buf; void **pptr; + int ret; if (psp->adev->psp.ta_fw) { psp_ras_terminate(psp); @@ -1851,6 +1879,11 @@ static int psp_hw_fini(void *handle) } psp_asd_unload(psp); + ret = psp_clear_vf_fw(psp); + if (ret) { + DRM_ERROR("PSP clear vf fw!\n"); + return ret; + } psp_ring_destroy(psp, PSP_RING_TYPE__KM); |