diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2020-07-16 10:09:23 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2020-07-16 10:09:23 +0000 |
commit | e09bdd7f30376adb78687eec1ff8d7a910940b2a (patch) | |
tree | ef40a7bf4b0ce529e492b84aeb71b8463ebda403 /sys | |
parent | d710647d67a95b18ecf92e1684874167be21f3f7 (diff) |
drm/amdgpu: add TMR destory function for psp
From Huang Rui
2c41c968c6f6480860c67210815cadc6507f5014 in linux 5.7.y/5.7.9
c564b8601ae917086751d90f464d5f19d731ece7 in mainline linux
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/drm/amd/amdgpu/amdgpu_psp.c | 57 |
1 files changed, 53 insertions, 4 deletions
diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_psp.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_psp.c index d7b825312d1..df5c9f31948 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_psp.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_psp.c @@ -370,6 +370,52 @@ static int psp_tmr_load(struct psp_context *psp) return ret; } +static void psp_prep_tmr_unload_cmd_buf(struct psp_context *psp, + struct psp_gfx_cmd_resp *cmd) +{ + if (amdgpu_sriov_vf(psp->adev)) + cmd->cmd_id = GFX_CMD_ID_DESTROY_VMR; + else + cmd->cmd_id = GFX_CMD_ID_DESTROY_TMR; +} + +static int psp_tmr_unload(struct psp_context *psp) +{ + int ret; + struct psp_gfx_cmd_resp *cmd; + + cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + psp_prep_tmr_unload_cmd_buf(psp, cmd); + DRM_INFO("free PSP TMR buffer\n"); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, + psp->fence_buf_mc_addr); + + kfree(cmd); + + return ret; +} + +static int psp_tmr_terminate(struct psp_context *psp) +{ + int ret; + void *tmr_buf; + void **pptr; + + ret = psp_tmr_unload(psp); + if (ret) + return ret; + + /* free TMR memory buffer */ + pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; + amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, pptr); + + return 0; +} + static void psp_prep_asd_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, uint64_t asd_mc, uint32_t size) { @@ -1575,8 +1621,6 @@ static int psp_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct psp_context *psp = &adev->psp; - void *tmr_buf; - void **pptr; if (psp->adev->psp.ta_fw) { psp_ras_terminate(psp); @@ -1586,10 +1630,9 @@ static int psp_hw_fini(void *handle) psp_asd_unload(psp); + psp_tmr_terminate(psp); psp_ring_destroy(psp, PSP_RING_TYPE__KM); - pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; - amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, pptr); amdgpu_bo_free_kernel(&psp->fw_pri_bo, &psp->fw_pri_mc_addr, &psp->fw_pri_buf); amdgpu_bo_free_kernel(&psp->fence_buf_bo, @@ -1636,6 +1679,12 @@ static int psp_suspend(void *handle) } } + ret = psp_tmr_terminate(psp); + if (ret) { + DRM_ERROR("Falied to terminate tmr\n"); + return ret; + } + ret = psp_ring_stop(psp, PSP_RING_TYPE__KM); if (ret) { DRM_ERROR("PSP ring stop failed\n"); |