xref: /dflybsd-src/sys/dev/drm/amd/amdgpu/amdgpu_amdkfd.c (revision 789731325bde747251c28a37e0a00ed4efb88c46)
1b843c749SSergey Zigachev /*
2b843c749SSergey Zigachev  * Copyright 2014 Advanced Micro Devices, Inc.
3b843c749SSergey Zigachev  *
4b843c749SSergey Zigachev  * Permission is hereby granted, free of charge, to any person obtaining a
5b843c749SSergey Zigachev  * copy of this software and associated documentation files (the "Software"),
6b843c749SSergey Zigachev  * to deal in the Software without restriction, including without limitation
7b843c749SSergey Zigachev  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b843c749SSergey Zigachev  * and/or sell copies of the Software, and to permit persons to whom the
9b843c749SSergey Zigachev  * Software is furnished to do so, subject to the following conditions:
10b843c749SSergey Zigachev  *
11b843c749SSergey Zigachev  * The above copyright notice and this permission notice shall be included in
12b843c749SSergey Zigachev  * all copies or substantial portions of the Software.
13b843c749SSergey Zigachev  *
14b843c749SSergey Zigachev  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15b843c749SSergey Zigachev  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16b843c749SSergey Zigachev  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17b843c749SSergey Zigachev  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18b843c749SSergey Zigachev  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19b843c749SSergey Zigachev  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20b843c749SSergey Zigachev  * OTHER DEALINGS IN THE SOFTWARE.
21b843c749SSergey Zigachev  */
22b843c749SSergey Zigachev 
23b843c749SSergey Zigachev #include "amdgpu_amdkfd.h"
24b843c749SSergey Zigachev #include "amd_shared.h"
25b843c749SSergey Zigachev #include <drm/drmP.h>
26b843c749SSergey Zigachev #include "amdgpu.h"
27b843c749SSergey Zigachev #include "amdgpu_gfx.h"
28b843c749SSergey Zigachev #include <linux/module.h>
29b843c749SSergey Zigachev 
30b843c749SSergey Zigachev const struct kgd2kfd_calls *kgd2kfd;
31b843c749SSergey Zigachev bool (*kgd2kfd_init_p)(unsigned int, const struct kgd2kfd_calls**);
32b843c749SSergey Zigachev 
33b843c749SSergey Zigachev static const unsigned int compute_vmid_bitmap = 0xFF00;
34b843c749SSergey Zigachev 
amdgpu_amdkfd_init(void)35b843c749SSergey Zigachev int amdgpu_amdkfd_init(void)
36b843c749SSergey Zigachev {
37b843c749SSergey Zigachev 	int ret;
38b843c749SSergey Zigachev 
39b843c749SSergey Zigachev #if defined(CONFIG_HSA_AMD_MODULE)
40b843c749SSergey Zigachev 	int (*kgd2kfd_init_p)(unsigned int, const struct kgd2kfd_calls**);
41b843c749SSergey Zigachev 
42b843c749SSergey Zigachev 	kgd2kfd_init_p = symbol_request(kgd2kfd_init);
43b843c749SSergey Zigachev 
44b843c749SSergey Zigachev 	if (kgd2kfd_init_p == NULL)
45b843c749SSergey Zigachev 		return -ENOENT;
46b843c749SSergey Zigachev 
47b843c749SSergey Zigachev 	ret = kgd2kfd_init_p(KFD_INTERFACE_VERSION, &kgd2kfd);
48b843c749SSergey Zigachev 	if (ret) {
49*78973132SSergey Zigachev #if 0
50b843c749SSergey Zigachev 		symbol_put(kgd2kfd_init);
51*78973132SSergey Zigachev #endif
52b843c749SSergey Zigachev 		kgd2kfd = NULL;
53b843c749SSergey Zigachev 	}
54b843c749SSergey Zigachev 
55b843c749SSergey Zigachev 
56b843c749SSergey Zigachev #elif defined(CONFIG_HSA_AMD)
57b843c749SSergey Zigachev 
58b843c749SSergey Zigachev 	ret = kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd);
59b843c749SSergey Zigachev 	if (ret)
60b843c749SSergey Zigachev 		kgd2kfd = NULL;
61b843c749SSergey Zigachev 
62b843c749SSergey Zigachev #else
63b843c749SSergey Zigachev 	kgd2kfd = NULL;
64b843c749SSergey Zigachev 	ret = -ENOENT;
65b843c749SSergey Zigachev #endif
66b843c749SSergey Zigachev 
67b843c749SSergey Zigachev #if defined(CONFIG_HSA_AMD_MODULE) || defined(CONFIG_HSA_AMD)
68b843c749SSergey Zigachev 	amdgpu_amdkfd_gpuvm_init_mem_limits();
69b843c749SSergey Zigachev #endif
70b843c749SSergey Zigachev 
71b843c749SSergey Zigachev 	return ret;
72b843c749SSergey Zigachev }
73b843c749SSergey Zigachev 
amdgpu_amdkfd_fini(void)74b843c749SSergey Zigachev void amdgpu_amdkfd_fini(void)
75b843c749SSergey Zigachev {
76b843c749SSergey Zigachev 	if (kgd2kfd) {
77b843c749SSergey Zigachev 		kgd2kfd->exit();
78*78973132SSergey Zigachev #if 0
79b843c749SSergey Zigachev 		symbol_put(kgd2kfd_init);
80*78973132SSergey Zigachev #endif
81b843c749SSergey Zigachev 	}
82b843c749SSergey Zigachev }
83b843c749SSergey Zigachev 
amdgpu_amdkfd_device_probe(struct amdgpu_device * adev)84b843c749SSergey Zigachev void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev)
85b843c749SSergey Zigachev {
86b843c749SSergey Zigachev 	const struct kfd2kgd_calls *kfd2kgd;
87b843c749SSergey Zigachev 
88b843c749SSergey Zigachev 	if (!kgd2kfd)
89b843c749SSergey Zigachev 		return;
90b843c749SSergey Zigachev 
91b843c749SSergey Zigachev 	switch (adev->asic_type) {
92b843c749SSergey Zigachev #ifdef CONFIG_DRM_AMDGPU_CIK
93b843c749SSergey Zigachev 	case CHIP_KAVERI:
94b843c749SSergey Zigachev 	case CHIP_HAWAII:
95b843c749SSergey Zigachev 		kfd2kgd = amdgpu_amdkfd_gfx_7_get_functions();
96b843c749SSergey Zigachev 		break;
97b843c749SSergey Zigachev #endif
98b843c749SSergey Zigachev 	case CHIP_CARRIZO:
99b843c749SSergey Zigachev 	case CHIP_TONGA:
100b843c749SSergey Zigachev 	case CHIP_FIJI:
101b843c749SSergey Zigachev 	case CHIP_POLARIS10:
102b843c749SSergey Zigachev 	case CHIP_POLARIS11:
103b843c749SSergey Zigachev 		kfd2kgd = amdgpu_amdkfd_gfx_8_0_get_functions();
104b843c749SSergey Zigachev 		break;
105b843c749SSergey Zigachev 	case CHIP_VEGA10:
106b843c749SSergey Zigachev 	case CHIP_RAVEN:
107b843c749SSergey Zigachev 		kfd2kgd = amdgpu_amdkfd_gfx_9_0_get_functions();
108b843c749SSergey Zigachev 		break;
109b843c749SSergey Zigachev 	default:
110b843c749SSergey Zigachev 		dev_info(adev->dev, "kfd not supported on this ASIC\n");
111b843c749SSergey Zigachev 		return;
112b843c749SSergey Zigachev 	}
113b843c749SSergey Zigachev 
114b843c749SSergey Zigachev 	adev->kfd = kgd2kfd->probe((struct kgd_dev *)adev,
115b843c749SSergey Zigachev 				   adev->pdev, kfd2kgd);
116b843c749SSergey Zigachev }
117b843c749SSergey Zigachev 
118b843c749SSergey Zigachev /**
119b843c749SSergey Zigachev  * amdgpu_doorbell_get_kfd_info - Report doorbell configuration required to
120b843c749SSergey Zigachev  *                                setup amdkfd
121b843c749SSergey Zigachev  *
122b843c749SSergey Zigachev  * @adev: amdgpu_device pointer
123b843c749SSergey Zigachev  * @aperture_base: output returning doorbell aperture base physical address
124b843c749SSergey Zigachev  * @aperture_size: output returning doorbell aperture size in bytes
125b843c749SSergey Zigachev  * @start_offset: output returning # of doorbell bytes reserved for amdgpu.
126b843c749SSergey Zigachev  *
127b843c749SSergey Zigachev  * amdgpu and amdkfd share the doorbell aperture. amdgpu sets it up,
128b843c749SSergey Zigachev  * takes doorbells required for its own rings and reports the setup to amdkfd.
129b843c749SSergey Zigachev  * amdgpu reserved doorbells are at the start of the doorbell aperture.
130b843c749SSergey Zigachev  */
amdgpu_doorbell_get_kfd_info(struct amdgpu_device * adev,phys_addr_t * aperture_base,size_t * aperture_size,size_t * start_offset)131b843c749SSergey Zigachev static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
132b843c749SSergey Zigachev 					 phys_addr_t *aperture_base,
133b843c749SSergey Zigachev 					 size_t *aperture_size,
134b843c749SSergey Zigachev 					 size_t *start_offset)
135b843c749SSergey Zigachev {
136b843c749SSergey Zigachev 	/*
137b843c749SSergey Zigachev 	 * The first num_doorbells are used by amdgpu.
138b843c749SSergey Zigachev 	 * amdkfd takes whatever's left in the aperture.
139b843c749SSergey Zigachev 	 */
140b843c749SSergey Zigachev 	if (adev->doorbell.size > adev->doorbell.num_doorbells * sizeof(u32)) {
141b843c749SSergey Zigachev 		*aperture_base = adev->doorbell.base;
142b843c749SSergey Zigachev 		*aperture_size = adev->doorbell.size;
143b843c749SSergey Zigachev 		*start_offset = adev->doorbell.num_doorbells * sizeof(u32);
144b843c749SSergey Zigachev 	} else {
145b843c749SSergey Zigachev 		*aperture_base = 0;
146b843c749SSergey Zigachev 		*aperture_size = 0;
147b843c749SSergey Zigachev 		*start_offset = 0;
148b843c749SSergey Zigachev 	}
149b843c749SSergey Zigachev }
150b843c749SSergey Zigachev 
amdgpu_amdkfd_device_init(struct amdgpu_device * adev)151b843c749SSergey Zigachev void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
152b843c749SSergey Zigachev {
153b843c749SSergey Zigachev 	int i;
154b843c749SSergey Zigachev 	int last_valid_bit;
155b843c749SSergey Zigachev 	if (adev->kfd) {
156b843c749SSergey Zigachev 		struct kgd2kfd_shared_resources gpu_resources = {
157b843c749SSergey Zigachev 			.compute_vmid_bitmap = compute_vmid_bitmap,
158b843c749SSergey Zigachev 			.num_pipe_per_mec = adev->gfx.mec.num_pipe_per_mec,
159b843c749SSergey Zigachev 			.num_queue_per_pipe = adev->gfx.mec.num_queue_per_pipe,
160b843c749SSergey Zigachev 			.gpuvm_size = min(adev->vm_manager.max_pfn
161b843c749SSergey Zigachev 					  << AMDGPU_GPU_PAGE_SHIFT,
162b843c749SSergey Zigachev 					  AMDGPU_VA_HOLE_START),
163b843c749SSergey Zigachev 			.drm_render_minor = adev->ddev->render->index
164b843c749SSergey Zigachev 		};
165b843c749SSergey Zigachev 
166b843c749SSergey Zigachev 		/* this is going to have a few of the MSBs set that we need to
167b843c749SSergey Zigachev 		 * clear */
168b843c749SSergey Zigachev 		bitmap_complement(gpu_resources.queue_bitmap,
169b843c749SSergey Zigachev 				  adev->gfx.mec.queue_bitmap,
170b843c749SSergey Zigachev 				  KGD_MAX_QUEUES);
171b843c749SSergey Zigachev 
172b843c749SSergey Zigachev 		/* remove the KIQ bit as well */
173b843c749SSergey Zigachev 		if (adev->gfx.kiq.ring.ready)
174b843c749SSergey Zigachev 			clear_bit(amdgpu_gfx_queue_to_bit(adev,
175b843c749SSergey Zigachev 							  adev->gfx.kiq.ring.me - 1,
176b843c749SSergey Zigachev 							  adev->gfx.kiq.ring.pipe,
177b843c749SSergey Zigachev 							  adev->gfx.kiq.ring.queue),
178b843c749SSergey Zigachev 				  gpu_resources.queue_bitmap);
179b843c749SSergey Zigachev 
180b843c749SSergey Zigachev 		/* According to linux/bitmap.h we shouldn't use bitmap_clear if
181b843c749SSergey Zigachev 		 * nbits is not compile time constant */
182b843c749SSergey Zigachev 		last_valid_bit = 1 /* only first MEC can have compute queues */
183b843c749SSergey Zigachev 				* adev->gfx.mec.num_pipe_per_mec
184b843c749SSergey Zigachev 				* adev->gfx.mec.num_queue_per_pipe;
185b843c749SSergey Zigachev 		for (i = last_valid_bit; i < KGD_MAX_QUEUES; ++i)
186b843c749SSergey Zigachev 			clear_bit(i, gpu_resources.queue_bitmap);
187b843c749SSergey Zigachev 
188b843c749SSergey Zigachev 		amdgpu_doorbell_get_kfd_info(adev,
189b843c749SSergey Zigachev 				&gpu_resources.doorbell_physical_address,
190b843c749SSergey Zigachev 				&gpu_resources.doorbell_aperture_size,
191b843c749SSergey Zigachev 				&gpu_resources.doorbell_start_offset);
192b843c749SSergey Zigachev 		if (adev->asic_type >= CHIP_VEGA10) {
193b843c749SSergey Zigachev 			/* On SOC15 the BIF is involved in routing
194b843c749SSergey Zigachev 			 * doorbells using the low 12 bits of the
195b843c749SSergey Zigachev 			 * address. Communicate the assignments to
196b843c749SSergey Zigachev 			 * KFD. KFD uses two doorbell pages per
197b843c749SSergey Zigachev 			 * process in case of 64-bit doorbells so we
198b843c749SSergey Zigachev 			 * can use each doorbell assignment twice.
199b843c749SSergey Zigachev 			 */
200b843c749SSergey Zigachev 			gpu_resources.sdma_doorbell[0][0] =
201b843c749SSergey Zigachev 				AMDGPU_DOORBELL64_sDMA_ENGINE0;
202b843c749SSergey Zigachev 			gpu_resources.sdma_doorbell[0][1] =
203b843c749SSergey Zigachev 				AMDGPU_DOORBELL64_sDMA_ENGINE0 + 0x200;
204b843c749SSergey Zigachev 			gpu_resources.sdma_doorbell[1][0] =
205b843c749SSergey Zigachev 				AMDGPU_DOORBELL64_sDMA_ENGINE1;
206b843c749SSergey Zigachev 			gpu_resources.sdma_doorbell[1][1] =
207b843c749SSergey Zigachev 				AMDGPU_DOORBELL64_sDMA_ENGINE1 + 0x200;
208b843c749SSergey Zigachev 			/* Doorbells 0x0f0-0ff and 0x2f0-2ff are reserved for
209b843c749SSergey Zigachev 			 * SDMA, IH and VCN. So don't use them for the CP.
210b843c749SSergey Zigachev 			 */
211b843c749SSergey Zigachev 			gpu_resources.reserved_doorbell_mask = 0x1f0;
212b843c749SSergey Zigachev 			gpu_resources.reserved_doorbell_val  = 0x0f0;
213b843c749SSergey Zigachev 		}
214b843c749SSergey Zigachev 
215b843c749SSergey Zigachev 		kgd2kfd->device_init(adev->kfd, &gpu_resources);
216b843c749SSergey Zigachev 	}
217b843c749SSergey Zigachev }
218b843c749SSergey Zigachev 
amdgpu_amdkfd_device_fini(struct amdgpu_device * adev)219b843c749SSergey Zigachev void amdgpu_amdkfd_device_fini(struct amdgpu_device *adev)
220b843c749SSergey Zigachev {
221b843c749SSergey Zigachev 	if (adev->kfd) {
222b843c749SSergey Zigachev 		kgd2kfd->device_exit(adev->kfd);
223b843c749SSergey Zigachev 		adev->kfd = NULL;
224b843c749SSergey Zigachev 	}
225b843c749SSergey Zigachev }
226b843c749SSergey Zigachev 
amdgpu_amdkfd_interrupt(struct amdgpu_device * adev,const void * ih_ring_entry)227b843c749SSergey Zigachev void amdgpu_amdkfd_interrupt(struct amdgpu_device *adev,
228b843c749SSergey Zigachev 		const void *ih_ring_entry)
229b843c749SSergey Zigachev {
230b843c749SSergey Zigachev 	if (adev->kfd)
231b843c749SSergey Zigachev 		kgd2kfd->interrupt(adev->kfd, ih_ring_entry);
232b843c749SSergey Zigachev }
233b843c749SSergey Zigachev 
amdgpu_amdkfd_suspend(struct amdgpu_device * adev)234b843c749SSergey Zigachev void amdgpu_amdkfd_suspend(struct amdgpu_device *adev)
235b843c749SSergey Zigachev {
236b843c749SSergey Zigachev 	if (adev->kfd)
237b843c749SSergey Zigachev 		kgd2kfd->suspend(adev->kfd);
238b843c749SSergey Zigachev }
239b843c749SSergey Zigachev 
amdgpu_amdkfd_resume(struct amdgpu_device * adev)240b843c749SSergey Zigachev int amdgpu_amdkfd_resume(struct amdgpu_device *adev)
241b843c749SSergey Zigachev {
242b843c749SSergey Zigachev 	int r = 0;
243b843c749SSergey Zigachev 
244b843c749SSergey Zigachev 	if (adev->kfd)
245b843c749SSergey Zigachev 		r = kgd2kfd->resume(adev->kfd);
246b843c749SSergey Zigachev 
247b843c749SSergey Zigachev 	return r;
248b843c749SSergey Zigachev }
249b843c749SSergey Zigachev 
amdgpu_amdkfd_pre_reset(struct amdgpu_device * adev)250b843c749SSergey Zigachev int amdgpu_amdkfd_pre_reset(struct amdgpu_device *adev)
251b843c749SSergey Zigachev {
252b843c749SSergey Zigachev 	int r = 0;
253b843c749SSergey Zigachev 
254b843c749SSergey Zigachev 	if (adev->kfd)
255b843c749SSergey Zigachev 		r = kgd2kfd->pre_reset(adev->kfd);
256b843c749SSergey Zigachev 
257b843c749SSergey Zigachev 	return r;
258b843c749SSergey Zigachev }
259b843c749SSergey Zigachev 
amdgpu_amdkfd_post_reset(struct amdgpu_device * adev)260b843c749SSergey Zigachev int amdgpu_amdkfd_post_reset(struct amdgpu_device *adev)
261b843c749SSergey Zigachev {
262b843c749SSergey Zigachev 	int r = 0;
263b843c749SSergey Zigachev 
264b843c749SSergey Zigachev 	if (adev->kfd)
265b843c749SSergey Zigachev 		r = kgd2kfd->post_reset(adev->kfd);
266b843c749SSergey Zigachev 
267b843c749SSergey Zigachev 	return r;
268b843c749SSergey Zigachev }
269b843c749SSergey Zigachev 
amdgpu_amdkfd_gpu_reset(struct kgd_dev * kgd)270b843c749SSergey Zigachev void amdgpu_amdkfd_gpu_reset(struct kgd_dev *kgd)
271b843c749SSergey Zigachev {
272b843c749SSergey Zigachev 	struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
273b843c749SSergey Zigachev 
274b843c749SSergey Zigachev 	amdgpu_device_gpu_recover(adev, NULL, false);
275b843c749SSergey Zigachev }
276b843c749SSergey Zigachev 
alloc_gtt_mem(struct kgd_dev * kgd,size_t size,void ** mem_obj,uint64_t * gpu_addr,void ** cpu_ptr,bool mqd_gfx9)277b843c749SSergey Zigachev int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
278b843c749SSergey Zigachev 			void **mem_obj, uint64_t *gpu_addr,
279b843c749SSergey Zigachev 			void **cpu_ptr, bool mqd_gfx9)
280b843c749SSergey Zigachev {
281b843c749SSergey Zigachev 	struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
282b843c749SSergey Zigachev 	struct amdgpu_bo *bo = NULL;
283b843c749SSergey Zigachev 	struct amdgpu_bo_param bp;
284b843c749SSergey Zigachev 	int r;
285b843c749SSergey Zigachev 	void *cpu_ptr_tmp = NULL;
286b843c749SSergey Zigachev 
287b843c749SSergey Zigachev 	memset(&bp, 0, sizeof(bp));
288b843c749SSergey Zigachev 	bp.size = size;
289b843c749SSergey Zigachev 	bp.byte_align = PAGE_SIZE;
290b843c749SSergey Zigachev 	bp.domain = AMDGPU_GEM_DOMAIN_GTT;
291b843c749SSergey Zigachev 	bp.flags = AMDGPU_GEM_CREATE_CPU_GTT_USWC;
292b843c749SSergey Zigachev 	bp.type = ttm_bo_type_kernel;
293b843c749SSergey Zigachev 	bp.resv = NULL;
294b843c749SSergey Zigachev 
295b843c749SSergey Zigachev 	if (mqd_gfx9)
296b843c749SSergey Zigachev 		bp.flags |= AMDGPU_GEM_CREATE_MQD_GFX9;
297b843c749SSergey Zigachev 
298b843c749SSergey Zigachev 	r = amdgpu_bo_create(adev, &bp, &bo);
299b843c749SSergey Zigachev 	if (r) {
300b843c749SSergey Zigachev 		dev_err(adev->dev,
301b843c749SSergey Zigachev 			"failed to allocate BO for amdkfd (%d)\n", r);
302b843c749SSergey Zigachev 		return r;
303b843c749SSergey Zigachev 	}
304b843c749SSergey Zigachev 
305b843c749SSergey Zigachev 	/* map the buffer */
306b843c749SSergey Zigachev 	r = amdgpu_bo_reserve(bo, true);
307b843c749SSergey Zigachev 	if (r) {
308b843c749SSergey Zigachev 		dev_err(adev->dev, "(%d) failed to reserve bo for amdkfd\n", r);
309b843c749SSergey Zigachev 		goto allocate_mem_reserve_bo_failed;
310b843c749SSergey Zigachev 	}
311b843c749SSergey Zigachev 
312b843c749SSergey Zigachev 	r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT);
313b843c749SSergey Zigachev 	if (r) {
314b843c749SSergey Zigachev 		dev_err(adev->dev, "(%d) failed to pin bo for amdkfd\n", r);
315b843c749SSergey Zigachev 		goto allocate_mem_pin_bo_failed;
316b843c749SSergey Zigachev 	}
317b843c749SSergey Zigachev 
318b843c749SSergey Zigachev 	r = amdgpu_ttm_alloc_gart(&bo->tbo);
319b843c749SSergey Zigachev 	if (r) {
320b843c749SSergey Zigachev 		dev_err(adev->dev, "%p bind failed\n", bo);
321b843c749SSergey Zigachev 		goto allocate_mem_kmap_bo_failed;
322b843c749SSergey Zigachev 	}
323b843c749SSergey Zigachev 
324b843c749SSergey Zigachev 	r = amdgpu_bo_kmap(bo, &cpu_ptr_tmp);
325b843c749SSergey Zigachev 	if (r) {
326b843c749SSergey Zigachev 		dev_err(adev->dev,
327b843c749SSergey Zigachev 			"(%d) failed to map bo to kernel for amdkfd\n", r);
328b843c749SSergey Zigachev 		goto allocate_mem_kmap_bo_failed;
329b843c749SSergey Zigachev 	}
330b843c749SSergey Zigachev 
331b843c749SSergey Zigachev 	*mem_obj = bo;
332b843c749SSergey Zigachev 	*gpu_addr = amdgpu_bo_gpu_offset(bo);
333b843c749SSergey Zigachev 	*cpu_ptr = cpu_ptr_tmp;
334b843c749SSergey Zigachev 
335b843c749SSergey Zigachev 	amdgpu_bo_unreserve(bo);
336b843c749SSergey Zigachev 
337b843c749SSergey Zigachev 	return 0;
338b843c749SSergey Zigachev 
339b843c749SSergey Zigachev allocate_mem_kmap_bo_failed:
340b843c749SSergey Zigachev 	amdgpu_bo_unpin(bo);
341b843c749SSergey Zigachev allocate_mem_pin_bo_failed:
342b843c749SSergey Zigachev 	amdgpu_bo_unreserve(bo);
343b843c749SSergey Zigachev allocate_mem_reserve_bo_failed:
344b843c749SSergey Zigachev 	amdgpu_bo_unref(&bo);
345b843c749SSergey Zigachev 
346b843c749SSergey Zigachev 	return r;
347b843c749SSergey Zigachev }
348b843c749SSergey Zigachev 
free_gtt_mem(struct kgd_dev * kgd,void * mem_obj)349b843c749SSergey Zigachev void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj)
350b843c749SSergey Zigachev {
351b843c749SSergey Zigachev 	struct amdgpu_bo *bo = (struct amdgpu_bo *) mem_obj;
352b843c749SSergey Zigachev 
353b843c749SSergey Zigachev 	amdgpu_bo_reserve(bo, true);
354b843c749SSergey Zigachev 	amdgpu_bo_kunmap(bo);
355b843c749SSergey Zigachev 	amdgpu_bo_unpin(bo);
356b843c749SSergey Zigachev 	amdgpu_bo_unreserve(bo);
357b843c749SSergey Zigachev 	amdgpu_bo_unref(&(bo));
358b843c749SSergey Zigachev }
359b843c749SSergey Zigachev 
get_local_mem_info(struct kgd_dev * kgd,struct kfd_local_mem_info * mem_info)360b843c749SSergey Zigachev void get_local_mem_info(struct kgd_dev *kgd,
361b843c749SSergey Zigachev 			struct kfd_local_mem_info *mem_info)
362b843c749SSergey Zigachev {
363*78973132SSergey Zigachev 	STUB();
364*78973132SSergey Zigachev #if 0
365b843c749SSergey Zigachev 	struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
366b843c749SSergey Zigachev 	uint64_t address_mask = adev->dev->dma_mask ? ~*adev->dev->dma_mask :
367b843c749SSergey Zigachev 					     ~((1ULL << 32) - 1);
368b843c749SSergey Zigachev 	resource_size_t aper_limit = adev->gmc.aper_base + adev->gmc.aper_size;
369b843c749SSergey Zigachev 
370b843c749SSergey Zigachev 	memset(mem_info, 0, sizeof(*mem_info));
371b843c749SSergey Zigachev 	if (!(adev->gmc.aper_base & address_mask || aper_limit & address_mask)) {
372b843c749SSergey Zigachev 		mem_info->local_mem_size_public = adev->gmc.visible_vram_size;
373b843c749SSergey Zigachev 		mem_info->local_mem_size_private = adev->gmc.real_vram_size -
374b843c749SSergey Zigachev 				adev->gmc.visible_vram_size;
375b843c749SSergey Zigachev 	} else {
376b843c749SSergey Zigachev 		mem_info->local_mem_size_public = 0;
377b843c749SSergey Zigachev 		mem_info->local_mem_size_private = adev->gmc.real_vram_size;
378b843c749SSergey Zigachev 	}
379b843c749SSergey Zigachev 	mem_info->vram_width = adev->gmc.vram_width;
380b843c749SSergey Zigachev 
381*78973132SSergey Zigachev 	pr_debug("Address base: %pap limit %pap public 0x%lx private 0x%lx\n",
382b843c749SSergey Zigachev 			&adev->gmc.aper_base, &aper_limit,
383b843c749SSergey Zigachev 			mem_info->local_mem_size_public,
384b843c749SSergey Zigachev 			mem_info->local_mem_size_private);
385b843c749SSergey Zigachev 
386b843c749SSergey Zigachev 	if (amdgpu_sriov_vf(adev))
387b843c749SSergey Zigachev 		mem_info->mem_clk_max = adev->clock.default_mclk / 100;
388b843c749SSergey Zigachev 	else if (adev->powerplay.pp_funcs)
389b843c749SSergey Zigachev 		mem_info->mem_clk_max = amdgpu_dpm_get_mclk(adev, false) / 100;
390b843c749SSergey Zigachev 	else
391b843c749SSergey Zigachev 		mem_info->mem_clk_max = 100;
392*78973132SSergey Zigachev #endif
393b843c749SSergey Zigachev }
394b843c749SSergey Zigachev 
get_gpu_clock_counter(struct kgd_dev * kgd)395b843c749SSergey Zigachev uint64_t get_gpu_clock_counter(struct kgd_dev *kgd)
396b843c749SSergey Zigachev {
397b843c749SSergey Zigachev 	struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
398b843c749SSergey Zigachev 
399b843c749SSergey Zigachev 	if (adev->gfx.funcs->get_gpu_clock_counter)
400b843c749SSergey Zigachev 		return adev->gfx.funcs->get_gpu_clock_counter(adev);
401b843c749SSergey Zigachev 	return 0;
402b843c749SSergey Zigachev }
403b843c749SSergey Zigachev 
get_max_engine_clock_in_mhz(struct kgd_dev * kgd)404b843c749SSergey Zigachev uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd)
405b843c749SSergey Zigachev {
406b843c749SSergey Zigachev 	struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
407b843c749SSergey Zigachev 
408b843c749SSergey Zigachev 	/* the sclk is in quantas of 10kHz */
409b843c749SSergey Zigachev 	if (amdgpu_sriov_vf(adev))
410b843c749SSergey Zigachev 		return adev->clock.default_sclk / 100;
411b843c749SSergey Zigachev 	else if (adev->powerplay.pp_funcs)
412b843c749SSergey Zigachev 		return amdgpu_dpm_get_sclk(adev, false) / 100;
413b843c749SSergey Zigachev 	else
414b843c749SSergey Zigachev 		return 100;
415b843c749SSergey Zigachev }
416b843c749SSergey Zigachev 
get_cu_info(struct kgd_dev * kgd,struct kfd_cu_info * cu_info)417b843c749SSergey Zigachev void get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info)
418b843c749SSergey Zigachev {
419b843c749SSergey Zigachev 	struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
420b843c749SSergey Zigachev 	struct amdgpu_cu_info acu_info = adev->gfx.cu_info;
421b843c749SSergey Zigachev 
422b843c749SSergey Zigachev 	memset(cu_info, 0, sizeof(*cu_info));
423b843c749SSergey Zigachev 	if (sizeof(cu_info->cu_bitmap) != sizeof(acu_info.bitmap))
424b843c749SSergey Zigachev 		return;
425b843c749SSergey Zigachev 
426b843c749SSergey Zigachev 	cu_info->cu_active_number = acu_info.number;
427b843c749SSergey Zigachev 	cu_info->cu_ao_mask = acu_info.ao_cu_mask;
428b843c749SSergey Zigachev 	memcpy(&cu_info->cu_bitmap[0], &acu_info.bitmap[0],
429b843c749SSergey Zigachev 	       sizeof(acu_info.bitmap));
430b843c749SSergey Zigachev 	cu_info->num_shader_engines = adev->gfx.config.max_shader_engines;
431b843c749SSergey Zigachev 	cu_info->num_shader_arrays_per_engine = adev->gfx.config.max_sh_per_se;
432b843c749SSergey Zigachev 	cu_info->num_cu_per_sh = adev->gfx.config.max_cu_per_sh;
433b843c749SSergey Zigachev 	cu_info->simd_per_cu = acu_info.simd_per_cu;
434b843c749SSergey Zigachev 	cu_info->max_waves_per_simd = acu_info.max_waves_per_simd;
435b843c749SSergey Zigachev 	cu_info->wave_front_size = acu_info.wave_front_size;
436b843c749SSergey Zigachev 	cu_info->max_scratch_slots_per_cu = acu_info.max_scratch_slots_per_cu;
437b843c749SSergey Zigachev 	cu_info->lds_size = acu_info.lds_size;
438b843c749SSergey Zigachev }
439b843c749SSergey Zigachev 
amdgpu_amdkfd_get_vram_usage(struct kgd_dev * kgd)440b843c749SSergey Zigachev uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd)
441b843c749SSergey Zigachev {
442b843c749SSergey Zigachev 	struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
443b843c749SSergey Zigachev 
444b843c749SSergey Zigachev 	return amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
445b843c749SSergey Zigachev }
446b843c749SSergey Zigachev 
amdgpu_amdkfd_submit_ib(struct kgd_dev * kgd,enum kgd_engine_type engine,uint32_t vmid,uint64_t gpu_addr,uint32_t * ib_cmd,uint32_t ib_len)447b843c749SSergey Zigachev int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine,
448b843c749SSergey Zigachev 				uint32_t vmid, uint64_t gpu_addr,
449b843c749SSergey Zigachev 				uint32_t *ib_cmd, uint32_t ib_len)
450b843c749SSergey Zigachev {
451b843c749SSergey Zigachev 	struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
452b843c749SSergey Zigachev 	struct amdgpu_job *job;
453b843c749SSergey Zigachev 	struct amdgpu_ib *ib;
454b843c749SSergey Zigachev 	struct amdgpu_ring *ring;
455b843c749SSergey Zigachev 	struct dma_fence *f = NULL;
456b843c749SSergey Zigachev 	int ret;
457b843c749SSergey Zigachev 
458b843c749SSergey Zigachev 	switch (engine) {
459b843c749SSergey Zigachev 	case KGD_ENGINE_MEC1:
460b843c749SSergey Zigachev 		ring = &adev->gfx.compute_ring[0];
461b843c749SSergey Zigachev 		break;
462b843c749SSergey Zigachev 	case KGD_ENGINE_SDMA1:
463b843c749SSergey Zigachev 		ring = &adev->sdma.instance[0].ring;
464b843c749SSergey Zigachev 		break;
465b843c749SSergey Zigachev 	case KGD_ENGINE_SDMA2:
466b843c749SSergey Zigachev 		ring = &adev->sdma.instance[1].ring;
467b843c749SSergey Zigachev 		break;
468b843c749SSergey Zigachev 	default:
469b843c749SSergey Zigachev 		pr_err("Invalid engine in IB submission: %d\n", engine);
470b843c749SSergey Zigachev 		ret = -EINVAL;
471b843c749SSergey Zigachev 		goto err;
472b843c749SSergey Zigachev 	}
473b843c749SSergey Zigachev 
474b843c749SSergey Zigachev 	ret = amdgpu_job_alloc(adev, 1, &job, NULL);
475b843c749SSergey Zigachev 	if (ret)
476b843c749SSergey Zigachev 		goto err;
477b843c749SSergey Zigachev 
478b843c749SSergey Zigachev 	ib = &job->ibs[0];
479b843c749SSergey Zigachev 	memset(ib, 0, sizeof(struct amdgpu_ib));
480b843c749SSergey Zigachev 
481b843c749SSergey Zigachev 	ib->gpu_addr = gpu_addr;
482b843c749SSergey Zigachev 	ib->ptr = ib_cmd;
483b843c749SSergey Zigachev 	ib->length_dw = ib_len;
484b843c749SSergey Zigachev 	/* This works for NO_HWS. TODO: need to handle without knowing VMID */
485b843c749SSergey Zigachev 	job->vmid = vmid;
486b843c749SSergey Zigachev 
487b843c749SSergey Zigachev 	ret = amdgpu_ib_schedule(ring, 1, ib, job, &f);
488b843c749SSergey Zigachev 	if (ret) {
489b843c749SSergey Zigachev 		DRM_ERROR("amdgpu: failed to schedule IB.\n");
490b843c749SSergey Zigachev 		goto err_ib_sched;
491b843c749SSergey Zigachev 	}
492b843c749SSergey Zigachev 
493b843c749SSergey Zigachev 	ret = dma_fence_wait(f, false);
494b843c749SSergey Zigachev 
495b843c749SSergey Zigachev err_ib_sched:
496b843c749SSergey Zigachev 	dma_fence_put(f);
497b843c749SSergey Zigachev 	amdgpu_job_free(job);
498b843c749SSergey Zigachev err:
499b843c749SSergey Zigachev 	return ret;
500b843c749SSergey Zigachev }
501b843c749SSergey Zigachev 
amdgpu_amdkfd_set_compute_idle(struct kgd_dev * kgd,bool idle)502b843c749SSergey Zigachev void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle)
503b843c749SSergey Zigachev {
504b843c749SSergey Zigachev 	struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
505b843c749SSergey Zigachev 
506b843c749SSergey Zigachev 	if (adev->powerplay.pp_funcs &&
507b843c749SSergey Zigachev 	    adev->powerplay.pp_funcs->switch_power_profile)
508b843c749SSergey Zigachev 		amdgpu_dpm_switch_power_profile(adev,
509b843c749SSergey Zigachev 						PP_SMC_POWER_PROFILE_COMPUTE,
510b843c749SSergey Zigachev 						!idle);
511b843c749SSergey Zigachev }
512b843c749SSergey Zigachev 
amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device * adev,u32 vmid)513b843c749SSergey Zigachev bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid)
514b843c749SSergey Zigachev {
515b843c749SSergey Zigachev 	if (adev->kfd) {
516b843c749SSergey Zigachev 		if ((1 << vmid) & compute_vmid_bitmap)
517b843c749SSergey Zigachev 			return true;
518b843c749SSergey Zigachev 	}
519b843c749SSergey Zigachev 
520b843c749SSergey Zigachev 	return false;
521b843c749SSergey Zigachev }
522b843c749SSergey Zigachev 
523b843c749SSergey Zigachev #if !defined(CONFIG_HSA_AMD_MODULE) && !defined(CONFIG_HSA_AMD)
amdkfd_fence_check_mm(struct dma_fence * f,struct mm_struct * mm)524b843c749SSergey Zigachev bool amdkfd_fence_check_mm(struct dma_fence *f, struct mm_struct *mm)
525b843c749SSergey Zigachev {
526b843c749SSergey Zigachev 	return false;
527b843c749SSergey Zigachev }
528b843c749SSergey Zigachev 
amdgpu_amdkfd_unreserve_system_memory_limit(struct amdgpu_bo * bo)529b843c749SSergey Zigachev void amdgpu_amdkfd_unreserve_system_memory_limit(struct amdgpu_bo *bo)
530b843c749SSergey Zigachev {
531b843c749SSergey Zigachev }
532b843c749SSergey Zigachev 
amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device * adev,struct amdgpu_vm * vm)533b843c749SSergey Zigachev void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
534b843c749SSergey Zigachev 					struct amdgpu_vm *vm)
535b843c749SSergey Zigachev {
536b843c749SSergey Zigachev }
537b843c749SSergey Zigachev 
to_amdgpu_amdkfd_fence(struct dma_fence * f)538b843c749SSergey Zigachev struct amdgpu_amdkfd_fence *to_amdgpu_amdkfd_fence(struct dma_fence *f)
539b843c749SSergey Zigachev {
540b843c749SSergey Zigachev 	return NULL;
541b843c749SSergey Zigachev }
542b843c749SSergey Zigachev 
amdgpu_amdkfd_evict_userptr(struct kgd_mem * mem,struct mm_struct * mm)543b843c749SSergey Zigachev int amdgpu_amdkfd_evict_userptr(struct kgd_mem *mem, struct mm_struct *mm)
544b843c749SSergey Zigachev {
545b843c749SSergey Zigachev 	return 0;
546b843c749SSergey Zigachev }
547b843c749SSergey Zigachev 
amdgpu_amdkfd_gfx_7_get_functions(void)548b843c749SSergey Zigachev struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void)
549b843c749SSergey Zigachev {
550b843c749SSergey Zigachev 	return NULL;
551b843c749SSergey Zigachev }
552b843c749SSergey Zigachev 
amdgpu_amdkfd_gfx_8_0_get_functions(void)553b843c749SSergey Zigachev struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void)
554b843c749SSergey Zigachev {
555b843c749SSergey Zigachev 	return NULL;
556b843c749SSergey Zigachev }
557b843c749SSergey Zigachev 
amdgpu_amdkfd_gfx_9_0_get_functions(void)558b843c749SSergey Zigachev struct kfd2kgd_calls *amdgpu_amdkfd_gfx_9_0_get_functions(void)
559b843c749SSergey Zigachev {
560b843c749SSergey Zigachev 	return NULL;
561b843c749SSergey Zigachev }
562b843c749SSergey Zigachev #endif
563