void amdgpu_amdkfd_device_init(struct amdgpu_device *rdev) { if (rdev->kfd) { struct kgd2kfd_shared_resources gpu_resources = { .compute_vmid_bitmap = 0xFF00, .first_compute_pipe = 1, .compute_pipe_count = 4 - 1, }; amdgpu_doorbell_get_kfd_info(rdev, &gpu_resources.doorbell_physical_address, &gpu_resources.doorbell_aperture_size, &gpu_resources.doorbell_start_offset); kgd2kfd->device_init(rdev->kfd, &gpu_resources); } } void amdgpu_amdkfd_device_fini(struct amdgpu_device *rdev) { if (rdev->kfd) { kgd2kfd->device_exit(rdev->kfd); rdev->kfd = NULL; } } void amdgpu_amdkfd_interrupt(struct amdgpu_device *rdev, const void *ih_ring_entry) { if (rdev->kfd) kgd2kfd->interrupt(rdev->kfd, ih_ring_entry); } void amdgpu_amdkfd_suspend(struct amdgpu_device *rdev) { if (rdev->kfd) kgd2kfd->suspend(rdev->kfd); } int amdgpu_amdkfd_resume(struct amdgpu_device *rdev) { int r = 0; if (rdev->kfd) r = kgd2kfd->resume(rdev->kfd); return r; }
void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) { int i, n; int last_valid_bit; if (adev->kfd.dev) { struct kgd2kfd_shared_resources gpu_resources = { .compute_vmid_bitmap = compute_vmid_bitmap, .num_pipe_per_mec = adev->gfx.mec.num_pipe_per_mec, .num_queue_per_pipe = adev->gfx.mec.num_queue_per_pipe, .gpuvm_size = min(adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT, AMDGPU_GMC_HOLE_START), .drm_render_minor = adev->ddev->render->index }; /* this is going to have a few of the MSBs set that we need to * clear */ bitmap_complement(gpu_resources.queue_bitmap, adev->gfx.mec.queue_bitmap, KGD_MAX_QUEUES); /* remove the KIQ bit as well */ if (adev->gfx.kiq.ring.sched.ready) clear_bit(amdgpu_gfx_queue_to_bit(adev, adev->gfx.kiq.ring.me - 1, adev->gfx.kiq.ring.pipe, adev->gfx.kiq.ring.queue), gpu_resources.queue_bitmap); /* According to linux/bitmap.h we shouldn't use bitmap_clear if * nbits is not compile time constant */ last_valid_bit = 1 /* only first MEC can have compute queues */ * adev->gfx.mec.num_pipe_per_mec * adev->gfx.mec.num_queue_per_pipe; for (i = last_valid_bit; i < KGD_MAX_QUEUES; ++i) clear_bit(i, gpu_resources.queue_bitmap); amdgpu_doorbell_get_kfd_info(adev, &gpu_resources.doorbell_physical_address, &gpu_resources.doorbell_aperture_size, &gpu_resources.doorbell_start_offset); if (adev->asic_type < CHIP_VEGA10) { kgd2kfd->device_init(adev->kfd.dev, &gpu_resources); return; } n = (adev->asic_type < CHIP_VEGA20) ? 2 : 8; for (i = 0; i < n; i += 2) { /* On SOC15 the BIF is involved in routing * doorbells using the low 12 bits of the * address. Communicate the assignments to * KFD. KFD uses two doorbell pages per * process in case of 64-bit doorbells so we * can use each doorbell assignment twice. */ gpu_resources.sdma_doorbell[0][i] = adev->doorbell_index.sdma_engine0 + (i >> 1); gpu_resources.sdma_doorbell[0][i+1] = adev->doorbell_index.sdma_engine0 + 0x200 + (i >> 1); gpu_resources.sdma_doorbell[1][i] = adev->doorbell_index.sdma_engine1 + (i >> 1); gpu_resources.sdma_doorbell[1][i+1] = adev->doorbell_index.sdma_engine1 + 0x200 + (i >> 1); } /* Doorbells 0x0e0-0ff and 0x2e0-2ff are reserved for * SDMA, IH and VCN. So don't use them for the CP. */ gpu_resources.reserved_doorbell_mask = 0x1e0; gpu_resources.reserved_doorbell_val = 0x0e0; kgd2kfd->device_init(adev->kfd.dev, &gpu_resources); } } void amdgpu_amdkfd_device_fini(struct amdgpu_device *adev) { if (adev->kfd.dev) { kgd2kfd->device_exit(adev->kfd.dev); adev->kfd.dev = NULL; } } void amdgpu_amdkfd_interrupt(struct amdgpu_device *adev, const void *ih_ring_entry) { if (adev->kfd.dev) kgd2kfd->interrupt(adev->kfd.dev, ih_ring_entry); } void amdgpu_amdkfd_suspend(struct amdgpu_device *adev) { if (adev->kfd.dev) kgd2kfd->suspend(adev->kfd.dev); } int amdgpu_amdkfd_resume(struct amdgpu_device *adev) { int r = 0; if (adev->kfd.dev) r = kgd2kfd->resume(adev->kfd.dev); return r; }