static int psp_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct psp_context *psp = &adev->psp; if (adev->gmc.xgmi.num_physical_nodes > 1 && psp->xgmi_context.initialized == 1) psp_xgmi_terminate(psp); if (psp->adev->psp.ta_fw) psp_ras_terminate(psp); psp_ring_destroy(psp, PSP_RING_TYPE__KM); amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); 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, &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); kfree(psp->cmd); psp->cmd = NULL; return 0; }
static int psp_hw_fini(void *handle) { 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; amdgpu_ucode_fini_bo(adev); psp_ring_destroy(psp, PSP_RING_TYPE__KM); if (psp->tmr_buf) amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); if (psp->fw_pri_buf) amdgpu_bo_free_kernel(&psp->fw_pri_bo, &psp->fw_pri_mc_addr, &psp->fw_pri_buf); if (psp->fence_buf_bo) amdgpu_bo_free_kernel(&psp->fence_buf_bo, &psp->fence_buf_mc_addr, &psp->fence_buf); return 0; }
static int psp_hw_fini(void *handle) { 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; psp_ring_destroy(psp, PSP_RING_TYPE__KM); amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); 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, &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); kfree(psp->cmd); psp->cmd = NULL; return 0; }
int psp_v10_0_ring_destroy(struct psp_context *psp, enum psp_ring_type ring_type) { int ret = 0; struct psp_ring *ring; unsigned int psp_ring_reg = 0; struct amdgpu_device *adev = psp->adev; ring = &psp->km_ring; /* Write the ring destroy command to C2PMSG_64 */ psp_ring_reg = 3 << 16; WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, psp_ring_reg); /* There might be handshake issue with hardware which needs delay */ mdelay(20); /* Wait for response flag (bit 31) in C2PMSG_64 */ ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64), 0x80000000, 0x80000000, false); amdgpu_bo_free_kernel(&adev->firmware.rbuf, &ring->ring_mem_mc_addr, (void **)&ring->ring_mem); return ret; }
void amdgpu_gfx_compute_mqd_sw_fini(struct amdgpu_device *adev) { struct amdgpu_ring *ring = NULL; int i; for (i = 0; i < adev->gfx.num_compute_rings; i++) { ring = &adev->gfx.compute_ring[i]; kfree(adev->gfx.mec.mqd_backup[i]); amdgpu_bo_free_kernel(&ring->mqd_obj, &ring->mqd_gpu_addr, &ring->mqd_ptr); } ring = &adev->gfx.kiq.ring; kfree(adev->gfx.mec.mqd_backup[AMDGPU_MAX_COMPUTE_RINGS]); amdgpu_bo_free_kernel(&ring->mqd_obj, &ring->mqd_gpu_addr, &ring->mqd_ptr); }
/** * amdgpu_virt_free_mm_table() - free mm table memory * @amdgpu: amdgpu device. * Free MM table memory */ void amdgpu_virt_free_mm_table(struct amdgpu_device *adev) { if (!amdgpu_sriov_vf(adev) || !adev->virt.mm_table.gpu_addr) return; amdgpu_bo_free_kernel(&adev->virt.mm_table.bo, &adev->virt.mm_table.gpu_addr, (void *)&adev->virt.mm_table.cpu_addr); adev->virt.mm_table.gpu_addr = 0; }
/** * amdgpu_ring_fini - tear down the driver ring struct. * * @adev: amdgpu_device pointer * @ring: amdgpu_ring structure holding ring information * * Tear down the driver information for the selected ring (all asics). */ void amdgpu_ring_fini(struct amdgpu_ring *ring) { ring->ready = false; amdgpu_wb_free(ring->adev, ring->cond_exe_offs); amdgpu_wb_free(ring->adev, ring->fence_offs); amdgpu_wb_free(ring->adev, ring->rptr_offs); amdgpu_wb_free(ring->adev, ring->wptr_offs); amdgpu_bo_free_kernel(&ring->ring_obj, &ring->gpu_addr, (void **)&ring->ring); amdgpu_debugfs_ring_fini(ring); ring->adev->rings[ring->idx] = NULL; }
static int psp_v11_0_ring_destroy(struct psp_context *psp, enum psp_ring_type ring_type) { int ret = 0; struct psp_ring *ring = &psp->km_ring; struct amdgpu_device *adev = psp->adev; ret = psp_v11_0_ring_stop(psp, ring_type); if (ret) DRM_ERROR("Fail to stop psp ring\n"); amdgpu_bo_free_kernel(&adev->firmware.rbuf, &ring->ring_mem_mc_addr, (void **)&ring->ring_mem); return ret; }
static int smu_free_memory_pool(struct smu_context *smu) { struct smu_table_context *smu_table = &smu->smu_table; struct smu_table *memory_pool = &smu_table->memory_pool; int ret = 0; if (memory_pool->size == SMU_MEMORY_POOL_SIZE_ZERO) return ret; amdgpu_bo_free_kernel(&memory_pool->bo, &memory_pool->mc_address, &memory_pool->cpu_addr); memset(memory_pool, 0, sizeof(struct smu_table)); return ret; }
static int smu_fini_fb_allocations(struct smu_context *smu) { struct smu_table_context *smu_table = &smu->smu_table; struct smu_table *tables = smu_table->tables; uint32_t table_count = smu_table->table_count; uint32_t i = 0; if (table_count == 0 || tables == NULL) return 0; for (i = 0 ; i < table_count; i++) { if (tables[i].size == 0) continue; amdgpu_bo_free_kernel(&tables[i].bo, &tables[i].mc_address, &tables[i].cpu_addr); } return 0; }
static int psp_ras_terminate(struct psp_context *psp) { int ret; if (!psp->ras.ras_initialized) return 0; ret = psp_ras_unload(psp); if (ret) return ret; psp->ras.ras_initialized = 0; /* free ras shared memory */ amdgpu_bo_free_kernel(&psp->ras.ras_shared_bo, &psp->ras.ras_shared_mc_addr, &psp->ras.ras_shared_buf); return 0; }
/** * amdgpu_ih_ring_fini - tear down the IH state * * @adev: amdgpu_device pointer * * Tears down the IH state and frees buffer * used for the IH ring buffer. */ void amdgpu_ih_ring_fini(struct amdgpu_device *adev) { if (adev->irq.ih.use_bus_addr) { if (adev->irq.ih.ring) { /* add 8 bytes for the rptr/wptr shadows and * add them to the end of the ring allocation. */ pci_free_consistent(adev->pdev, adev->irq.ih.ring_size + 8, (void *)adev->irq.ih.ring, adev->irq.ih.rb_dma_addr); adev->irq.ih.ring = NULL; } } else { amdgpu_bo_free_kernel(&adev->irq.ih.ring_obj, &adev->irq.ih.gpu_addr, (void **)&adev->irq.ih.ring); amdgpu_device_wb_free(adev, adev->irq.ih.wptr_offs); amdgpu_device_wb_free(adev, adev->irq.ih.rptr_offs); } }
static int smu_init_fb_allocations(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; struct smu_table_context *smu_table = &smu->smu_table; struct smu_table *tables = smu_table->tables; uint32_t table_count = smu_table->table_count; uint32_t i = 0; int32_t ret = 0; if (table_count <= 0) return -EINVAL; for (i = 0 ; i < table_count; i++) { if (tables[i].size == 0) continue; ret = amdgpu_bo_create_kernel(adev, tables[i].size, tables[i].align, tables[i].domain, &tables[i].bo, &tables[i].mc_address, &tables[i].cpu_addr); if (ret) goto failed; } return 0; failed: for (; i > 0; i--) { if (tables[i].size == 0) continue; amdgpu_bo_free_kernel(&tables[i].bo, &tables[i].mc_address, &tables[i].cpu_addr); } return ret; }
static int psp_cmd_submit_buf(struct psp_context *psp, struct amdgpu_firmware_info *ucode, struct psp_gfx_cmd_resp *cmd, uint64_t fence_mc_addr, int index) { int ret; struct amdgpu_bo *cmd_buf_bo; uint64_t cmd_buf_mc_addr; struct psp_gfx_cmd_resp *cmd_buf_mem; struct amdgpu_device *adev = psp->adev; ret = amdgpu_bo_create_kernel(adev, PSP_CMD_BUFFER_SIZE, PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, &cmd_buf_bo, &cmd_buf_mc_addr, (void **)&cmd_buf_mem); if (ret) return ret; memset(cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE); memcpy(cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp)); ret = psp_cmd_submit(psp, ucode, cmd_buf_mc_addr, fence_mc_addr, index); while (*((unsigned int *)psp->fence_buf) != index) { msleep(1); } amdgpu_bo_free_kernel(&cmd_buf_bo, &cmd_buf_mc_addr, (void **)&cmd_buf_mem); return ret; }
static int gmc_v9_0_sw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; amdgpu_gem_force_release(adev); amdgpu_vm_manager_fini(adev); /* * TODO: * Currently there is a bug where some memory client outside * of the driver writes to first 8M of VRAM on S3 resume, * this overrides GART which by default gets placed in first 8M and * causes VM_FAULTS once GTT is accessed. * Keep the stolen memory reservation until the while this is not solved. * Also check code in gmc_v9_0_get_vbios_fb_size and gmc_v9_0_late_init */ amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL); amdgpu_gart_table_vram_free(adev); amdgpu_bo_fini(adev); amdgpu_gart_fini(adev); return 0; }
void amdgpu_gfx_kiq_fini(struct amdgpu_device *adev) { struct amdgpu_kiq *kiq = &adev->gfx.kiq; amdgpu_bo_free_kernel(&kiq->eop_obj, &kiq->eop_gpu_addr, NULL); }
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; }