diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 93 |
1 files changed, 49 insertions, 44 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 0c791e35acf0..c31a8849e9f8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
| 29 | 29 | ||
| 30 | const struct kgd2kfd_calls *kgd2kfd; | 30 | const struct kgd2kfd_calls *kgd2kfd; |
| 31 | bool (*kgd2kfd_init_p)(unsigned int, const struct kgd2kfd_calls**); | ||
| 32 | 31 | ||
| 33 | static const unsigned int compute_vmid_bitmap = 0xFF00; | 32 | static const unsigned int compute_vmid_bitmap = 0xFF00; |
| 34 | 33 | ||
| @@ -36,45 +35,23 @@ int amdgpu_amdkfd_init(void) | |||
| 36 | { | 35 | { |
| 37 | int ret; | 36 | int ret; |
| 38 | 37 | ||
| 39 | #if defined(CONFIG_HSA_AMD_MODULE) | 38 | #ifdef CONFIG_HSA_AMD |
| 40 | int (*kgd2kfd_init_p)(unsigned int, const struct kgd2kfd_calls**); | ||
| 41 | |||
| 42 | kgd2kfd_init_p = symbol_request(kgd2kfd_init); | ||
| 43 | |||
| 44 | if (kgd2kfd_init_p == NULL) | ||
| 45 | return -ENOENT; | ||
| 46 | |||
| 47 | ret = kgd2kfd_init_p(KFD_INTERFACE_VERSION, &kgd2kfd); | ||
| 48 | if (ret) { | ||
| 49 | symbol_put(kgd2kfd_init); | ||
| 50 | kgd2kfd = NULL; | ||
| 51 | } | ||
| 52 | |||
| 53 | |||
| 54 | #elif defined(CONFIG_HSA_AMD) | ||
| 55 | |||
| 56 | ret = kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd); | 39 | ret = kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd); |
| 57 | if (ret) | 40 | if (ret) |
| 58 | kgd2kfd = NULL; | 41 | kgd2kfd = NULL; |
| 59 | 42 | amdgpu_amdkfd_gpuvm_init_mem_limits(); | |
| 60 | #else | 43 | #else |
| 61 | kgd2kfd = NULL; | 44 | kgd2kfd = NULL; |
| 62 | ret = -ENOENT; | 45 | ret = -ENOENT; |
| 63 | #endif | 46 | #endif |
| 64 | 47 | ||
| 65 | #if defined(CONFIG_HSA_AMD_MODULE) || defined(CONFIG_HSA_AMD) | ||
| 66 | amdgpu_amdkfd_gpuvm_init_mem_limits(); | ||
| 67 | #endif | ||
| 68 | |||
| 69 | return ret; | 48 | return ret; |
| 70 | } | 49 | } |
| 71 | 50 | ||
| 72 | void amdgpu_amdkfd_fini(void) | 51 | void amdgpu_amdkfd_fini(void) |
| 73 | { | 52 | { |
| 74 | if (kgd2kfd) { | 53 | if (kgd2kfd) |
| 75 | kgd2kfd->exit(); | 54 | kgd2kfd->exit(); |
| 76 | symbol_put(kgd2kfd_init); | ||
| 77 | } | ||
| 78 | } | 55 | } |
| 79 | 56 | ||
| 80 | void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev) | 57 | void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev) |
| @@ -99,6 +76,7 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev) | |||
| 99 | kfd2kgd = amdgpu_amdkfd_gfx_8_0_get_functions(); | 76 | kfd2kgd = amdgpu_amdkfd_gfx_8_0_get_functions(); |
| 100 | break; | 77 | break; |
| 101 | case CHIP_VEGA10: | 78 | case CHIP_VEGA10: |
| 79 | case CHIP_VEGA20: | ||
| 102 | case CHIP_RAVEN: | 80 | case CHIP_RAVEN: |
| 103 | kfd2kgd = amdgpu_amdkfd_gfx_9_0_get_functions(); | 81 | kfd2kgd = amdgpu_amdkfd_gfx_9_0_get_functions(); |
| 104 | break; | 82 | break; |
| @@ -146,7 +124,7 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev, | |||
| 146 | 124 | ||
| 147 | void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) | 125 | void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) |
| 148 | { | 126 | { |
| 149 | int i; | 127 | int i, n; |
| 150 | int last_valid_bit; | 128 | int last_valid_bit; |
| 151 | if (adev->kfd) { | 129 | if (adev->kfd) { |
| 152 | struct kgd2kfd_shared_resources gpu_resources = { | 130 | struct kgd2kfd_shared_resources gpu_resources = { |
| @@ -155,7 +133,7 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) | |||
| 155 | .num_queue_per_pipe = adev->gfx.mec.num_queue_per_pipe, | 133 | .num_queue_per_pipe = adev->gfx.mec.num_queue_per_pipe, |
| 156 | .gpuvm_size = min(adev->vm_manager.max_pfn | 134 | .gpuvm_size = min(adev->vm_manager.max_pfn |
| 157 | << AMDGPU_GPU_PAGE_SHIFT, | 135 | << AMDGPU_GPU_PAGE_SHIFT, |
| 158 | AMDGPU_VA_HOLE_START), | 136 | AMDGPU_GMC_HOLE_START), |
| 159 | .drm_render_minor = adev->ddev->render->index | 137 | .drm_render_minor = adev->ddev->render->index |
| 160 | }; | 138 | }; |
| 161 | 139 | ||
| @@ -185,7 +163,15 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) | |||
| 185 | &gpu_resources.doorbell_physical_address, | 163 | &gpu_resources.doorbell_physical_address, |
| 186 | &gpu_resources.doorbell_aperture_size, | 164 | &gpu_resources.doorbell_aperture_size, |
| 187 | &gpu_resources.doorbell_start_offset); | 165 | &gpu_resources.doorbell_start_offset); |
| 188 | if (adev->asic_type >= CHIP_VEGA10) { | 166 | |
| 167 | if (adev->asic_type < CHIP_VEGA10) { | ||
| 168 | kgd2kfd->device_init(adev->kfd, &gpu_resources); | ||
| 169 | return; | ||
| 170 | } | ||
| 171 | |||
| 172 | n = (adev->asic_type < CHIP_VEGA20) ? 2 : 8; | ||
| 173 | |||
| 174 | for (i = 0; i < n; i += 2) { | ||
| 189 | /* On SOC15 the BIF is involved in routing | 175 | /* On SOC15 the BIF is involved in routing |
| 190 | * doorbells using the low 12 bits of the | 176 | * doorbells using the low 12 bits of the |
| 191 | * address. Communicate the assignments to | 177 | * address. Communicate the assignments to |
| @@ -193,20 +179,31 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) | |||
| 193 | * process in case of 64-bit doorbells so we | 179 | * process in case of 64-bit doorbells so we |
| 194 | * can use each doorbell assignment twice. | 180 | * can use each doorbell assignment twice. |
| 195 | */ | 181 | */ |
| 196 | gpu_resources.sdma_doorbell[0][0] = | 182 | if (adev->asic_type == CHIP_VEGA10) { |
| 197 | AMDGPU_DOORBELL64_sDMA_ENGINE0; | 183 | gpu_resources.sdma_doorbell[0][i] = |
| 198 | gpu_resources.sdma_doorbell[0][1] = | 184 | AMDGPU_VEGA10_DOORBELL64_sDMA_ENGINE0 + (i >> 1); |
| 199 | AMDGPU_DOORBELL64_sDMA_ENGINE0 + 0x200; | 185 | gpu_resources.sdma_doorbell[0][i+1] = |
| 200 | gpu_resources.sdma_doorbell[1][0] = | 186 | AMDGPU_VEGA10_DOORBELL64_sDMA_ENGINE0 + 0x200 + (i >> 1); |
| 201 | AMDGPU_DOORBELL64_sDMA_ENGINE1; | 187 | gpu_resources.sdma_doorbell[1][i] = |
| 202 | gpu_resources.sdma_doorbell[1][1] = | 188 | AMDGPU_VEGA10_DOORBELL64_sDMA_ENGINE1 + (i >> 1); |
| 203 | AMDGPU_DOORBELL64_sDMA_ENGINE1 + 0x200; | 189 | gpu_resources.sdma_doorbell[1][i+1] = |
| 204 | /* Doorbells 0x0f0-0ff and 0x2f0-2ff are reserved for | 190 | AMDGPU_VEGA10_DOORBELL64_sDMA_ENGINE1 + 0x200 + (i >> 1); |
| 205 | * SDMA, IH and VCN. So don't use them for the CP. | 191 | } else { |
| 206 | */ | 192 | gpu_resources.sdma_doorbell[0][i] = |
| 207 | gpu_resources.reserved_doorbell_mask = 0x1f0; | 193 | AMDGPU_DOORBELL64_sDMA_ENGINE0 + (i >> 1); |
| 208 | gpu_resources.reserved_doorbell_val = 0x0f0; | 194 | gpu_resources.sdma_doorbell[0][i+1] = |
| 195 | AMDGPU_DOORBELL64_sDMA_ENGINE0 + 0x200 + (i >> 1); | ||
| 196 | gpu_resources.sdma_doorbell[1][i] = | ||
| 197 | AMDGPU_DOORBELL64_sDMA_ENGINE1 + (i >> 1); | ||
| 198 | gpu_resources.sdma_doorbell[1][i+1] = | ||
| 199 | AMDGPU_DOORBELL64_sDMA_ENGINE1 + 0x200 + (i >> 1); | ||
| 200 | } | ||
| 209 | } | 201 | } |
| 202 | /* Doorbells 0x0e0-0ff and 0x2e0-2ff are reserved for | ||
| 203 | * SDMA, IH and VCN. So don't use them for the CP. | ||
| 204 | */ | ||
| 205 | gpu_resources.reserved_doorbell_mask = 0x1e0; | ||
| 206 | gpu_resources.reserved_doorbell_val = 0x0e0; | ||
| 210 | 207 | ||
| 211 | kgd2kfd->device_init(adev->kfd, &gpu_resources); | 208 | kgd2kfd->device_init(adev->kfd, &gpu_resources); |
| 212 | } | 209 | } |
| @@ -267,7 +264,8 @@ void amdgpu_amdkfd_gpu_reset(struct kgd_dev *kgd) | |||
| 267 | { | 264 | { |
| 268 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; | 265 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; |
| 269 | 266 | ||
| 270 | amdgpu_device_gpu_recover(adev, NULL, false); | 267 | if (amdgpu_device_should_recover_gpu(adev)) |
| 268 | amdgpu_device_gpu_recover(adev, NULL); | ||
| 271 | } | 269 | } |
| 272 | 270 | ||
| 273 | int alloc_gtt_mem(struct kgd_dev *kgd, size_t size, | 271 | int alloc_gtt_mem(struct kgd_dev *kgd, size_t size, |
| @@ -437,6 +435,13 @@ uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd) | |||
| 437 | return amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]); | 435 | return amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]); |
| 438 | } | 436 | } |
| 439 | 437 | ||
| 438 | uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd) | ||
| 439 | { | ||
| 440 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; | ||
| 441 | |||
| 442 | return adev->gmc.xgmi.hive_id; | ||
| 443 | } | ||
| 444 | |||
| 440 | int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine, | 445 | int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine, |
| 441 | <|||
