static int psp_resume(void *handle) { int ret; struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct psp_context *psp = &adev->psp; if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) return 0; DRM_INFO("PSP is resuming...\n"); mutex_lock(&adev->firmware.mutex); ret = psp_hw_start(psp); if (ret) goto failed; ret = psp_np_fw_load(psp); if (ret) goto failed; mutex_unlock(&adev->firmware.mutex); return 0; failed: DRM_ERROR("PSP resume failed\n"); mutex_unlock(&adev->firmware.mutex); return ret; }
static int psp_load_fw(struct amdgpu_device *adev) { int ret; struct psp_context *psp = &adev->psp; if (amdgpu_sriov_vf(adev) && adev->in_gpu_reset != 0) goto skip_memalloc; psp->cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); if (!psp->cmd) return -ENOMEM; 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, &psp->fence_buf_bo, &psp->fence_buf_mc_addr, &psp->fence_buf); if (ret) goto failed_mem2; ret = amdgpu_bo_create_kernel(adev, PSP_CMD_BUFFER_SIZE, PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, &psp->cmd_buf_bo, &psp->cmd_buf_mc_addr, (void **)&psp->cmd_buf_mem); if (ret) goto failed_mem1; memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE); ret = psp_ring_init(psp, PSP_RING_TYPE__KM); if (ret) goto failed_mem; ret = psp_tmr_init(psp); if (ret) goto failed_mem; ret = psp_asd_init(psp); if (ret) goto failed_mem; skip_memalloc: ret = psp_hw_start(psp); if (ret) goto failed_mem; ret = psp_np_fw_load(psp); if (ret) goto failed_mem; return 0; failed_mem: amdgpu_bo_free_kernel(&psp->cmd_buf_bo, &psp->cmd_buf_mc_addr, (void **)&psp->cmd_buf_mem); failed_mem1: amdgpu_bo_free_kernel(&psp->fence_buf_bo, &psp->fence_buf_mc_addr, &psp->fence_buf); failed_mem2: amdgpu_bo_free_kernel(&psp->fw_pri_bo, &psp->fw_pri_mc_addr, &psp->fw_pri_buf); failed: kfree(psp->cmd); psp->cmd = NULL; return ret; }
static int psp_load_fw(struct amdgpu_device *adev) { int ret; struct psp_context *psp = &adev->psp; if (amdgpu_sriov_vf(adev) && adev->in_gpu_reset) { psp_ring_stop(psp, PSP_RING_TYPE__KM); /* should not destroy ring, only stop */ goto skip_memalloc; } psp->cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); if (!psp->cmd) return -ENOMEM; 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, &psp->fence_buf_bo, &psp->fence_buf_mc_addr, &psp->fence_buf); if (ret) goto failed; ret = amdgpu_bo_create_kernel(adev, PSP_CMD_BUFFER_SIZE, PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, &psp->cmd_buf_bo, &psp->cmd_buf_mc_addr, (void **)&psp->cmd_buf_mem); if (ret) goto failed; memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE); ret = psp_ring_init(psp, PSP_RING_TYPE__KM); if (ret) { DRM_ERROR("PSP ring init failed!\n"); goto failed; } ret = psp_tmr_init(psp); if (ret) { DRM_ERROR("PSP tmr init failed!\n"); goto failed; } ret = psp_asd_init(psp); if (ret) { DRM_ERROR("PSP asd init failed!\n"); goto failed; } skip_memalloc: ret = psp_hw_start(psp); if (ret) goto failed; ret = psp_np_fw_load(psp); if (ret) goto failed; return 0; failed: /* * all cleanup jobs (xgmi terminate, ras terminate, * ring destroy, cmd/fence/fw buffers destory, * psp->cmd destory) are delayed to psp_hw_fini */ return ret; }