xref: /linux/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c (revision 2f7d10b393c83acd3eedc3d6ab94dce29ac6a890)
1130e0371SOded Gabbay /*
2130e0371SOded Gabbay  * Copyright 2014 Advanced Micro Devices, Inc.
3130e0371SOded Gabbay  *
4130e0371SOded Gabbay  * Permission is hereby granted, free of charge, to any person obtaining a
5130e0371SOded Gabbay  * copy of this software and associated documentation files (the "Software"),
6130e0371SOded Gabbay  * to deal in the Software without restriction, including without limitation
7130e0371SOded Gabbay  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8130e0371SOded Gabbay  * and/or sell copies of the Software, and to permit persons to whom the
9130e0371SOded Gabbay  * Software is furnished to do so, subject to the following conditions:
10130e0371SOded Gabbay  *
11130e0371SOded Gabbay  * The above copyright notice and this permission notice shall be included in
12130e0371SOded Gabbay  * all copies or substantial portions of the Software.
13130e0371SOded Gabbay  *
14130e0371SOded Gabbay  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15130e0371SOded Gabbay  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16130e0371SOded Gabbay  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17130e0371SOded Gabbay  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18130e0371SOded Gabbay  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19130e0371SOded Gabbay  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20130e0371SOded Gabbay  * OTHER DEALINGS IN THE SOFTWARE.
21130e0371SOded Gabbay  */
22130e0371SOded Gabbay 
23130e0371SOded Gabbay #include "amdgpu_amdkfd.h"
24*2f7d10b3SJammy Zhou #include "amd_shared.h"
25130e0371SOded Gabbay #include <drm/drmP.h>
26130e0371SOded Gabbay #include "amdgpu.h"
27130e0371SOded Gabbay #include <linux/module.h>
28130e0371SOded Gabbay 
29130e0371SOded Gabbay const struct kfd2kgd_calls *kfd2kgd;
30130e0371SOded Gabbay const struct kgd2kfd_calls *kgd2kfd;
31130e0371SOded Gabbay bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**);
32130e0371SOded Gabbay 
33130e0371SOded Gabbay bool amdgpu_amdkfd_init(void)
34130e0371SOded Gabbay {
35130e0371SOded Gabbay #if defined(CONFIG_HSA_AMD_MODULE)
36130e0371SOded Gabbay 	bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**);
37130e0371SOded Gabbay 
38130e0371SOded Gabbay 	kgd2kfd_init_p = symbol_request(kgd2kfd_init);
39130e0371SOded Gabbay 
40130e0371SOded Gabbay 	if (kgd2kfd_init_p == NULL)
41130e0371SOded Gabbay 		return false;
42130e0371SOded Gabbay #endif
43130e0371SOded Gabbay 	return true;
44130e0371SOded Gabbay }
45130e0371SOded Gabbay 
46130e0371SOded Gabbay bool amdgpu_amdkfd_load_interface(struct amdgpu_device *rdev)
47130e0371SOded Gabbay {
48130e0371SOded Gabbay #if defined(CONFIG_HSA_AMD_MODULE)
49130e0371SOded Gabbay 	bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**);
50130e0371SOded Gabbay #endif
51130e0371SOded Gabbay 
52130e0371SOded Gabbay 	switch (rdev->asic_type) {
53130e0371SOded Gabbay 	case CHIP_KAVERI:
5432c22e99SOded Gabbay 		kfd2kgd = amdgpu_amdkfd_gfx_7_get_functions();
5532c22e99SOded Gabbay 		break;
56ff758a12SBen Goz 	case CHIP_CARRIZO:
57ff758a12SBen Goz 		kfd2kgd = amdgpu_amdkfd_gfx_8_0_get_functions();
58ff758a12SBen Goz 		break;
59130e0371SOded Gabbay 	default:
60130e0371SOded Gabbay 		return false;
61130e0371SOded Gabbay 	}
62130e0371SOded Gabbay 
63130e0371SOded Gabbay #if defined(CONFIG_HSA_AMD_MODULE)
64130e0371SOded Gabbay 	kgd2kfd_init_p = symbol_request(kgd2kfd_init);
65130e0371SOded Gabbay 
66130e0371SOded Gabbay 	if (kgd2kfd_init_p == NULL) {
67130e0371SOded Gabbay 		kfd2kgd = NULL;
68130e0371SOded Gabbay 		return false;
69130e0371SOded Gabbay 	}
70130e0371SOded Gabbay 
71130e0371SOded Gabbay 	if (!kgd2kfd_init_p(KFD_INTERFACE_VERSION, &kgd2kfd)) {
72130e0371SOded Gabbay 		symbol_put(kgd2kfd_init);
73130e0371SOded Gabbay 		kfd2kgd = NULL;
74130e0371SOded Gabbay 		kgd2kfd = NULL;
75130e0371SOded Gabbay 
76130e0371SOded Gabbay 		return false;
77130e0371SOded Gabbay 	}
78130e0371SOded Gabbay 
79130e0371SOded Gabbay 	return true;
80130e0371SOded Gabbay #elif defined(CONFIG_HSA_AMD)
81130e0371SOded Gabbay 	if (!kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd)) {
82130e0371SOded Gabbay 		kfd2kgd = NULL;
83130e0371SOded Gabbay 		kgd2kfd = NULL;
84130e0371SOded Gabbay 		return false;
85130e0371SOded Gabbay 	}
86130e0371SOded Gabbay 
87130e0371SOded Gabbay 	return true;
88130e0371SOded Gabbay #else
89130e0371SOded Gabbay 	kfd2kgd = NULL;
90130e0371SOded Gabbay 	return false;
91130e0371SOded Gabbay #endif
92130e0371SOded Gabbay }
93130e0371SOded Gabbay 
94130e0371SOded Gabbay void amdgpu_amdkfd_fini(void)
95130e0371SOded Gabbay {
96130e0371SOded Gabbay 	if (kgd2kfd) {
97130e0371SOded Gabbay 		kgd2kfd->exit();
98130e0371SOded Gabbay 		symbol_put(kgd2kfd_init);
99130e0371SOded Gabbay 	}
100130e0371SOded Gabbay }
101130e0371SOded Gabbay 
102130e0371SOded Gabbay void amdgpu_amdkfd_device_probe(struct amdgpu_device *rdev)
103130e0371SOded Gabbay {
104130e0371SOded Gabbay 	if (kgd2kfd)
105130e0371SOded Gabbay 		rdev->kfd = kgd2kfd->probe((struct kgd_dev *)rdev,
106130e0371SOded Gabbay 					rdev->pdev, kfd2kgd);
107130e0371SOded Gabbay }
108130e0371SOded Gabbay 
109130e0371SOded Gabbay void amdgpu_amdkfd_device_init(struct amdgpu_device *rdev)
110130e0371SOded Gabbay {
111130e0371SOded Gabbay 	if (rdev->kfd) {
112130e0371SOded Gabbay 		struct kgd2kfd_shared_resources gpu_resources = {
113130e0371SOded Gabbay 			.compute_vmid_bitmap = 0xFF00,
114130e0371SOded Gabbay 
115130e0371SOded Gabbay 			.first_compute_pipe = 1,
116130e0371SOded Gabbay 			.compute_pipe_count = 4 - 1,
117130e0371SOded Gabbay 		};
118130e0371SOded Gabbay 
119130e0371SOded Gabbay 		amdgpu_doorbell_get_kfd_info(rdev,
120130e0371SOded Gabbay 				&gpu_resources.doorbell_physical_address,
121130e0371SOded Gabbay 				&gpu_resources.doorbell_aperture_size,
122130e0371SOded Gabbay 				&gpu_resources.doorbell_start_offset);
123130e0371SOded Gabbay 
124130e0371SOded Gabbay 		kgd2kfd->device_init(rdev->kfd, &gpu_resources);
125130e0371SOded Gabbay 	}
126130e0371SOded Gabbay }
127130e0371SOded Gabbay 
128130e0371SOded Gabbay void amdgpu_amdkfd_device_fini(struct amdgpu_device *rdev)
129130e0371SOded Gabbay {
130130e0371SOded Gabbay 	if (rdev->kfd) {
131130e0371SOded Gabbay 		kgd2kfd->device_exit(rdev->kfd);
132130e0371SOded Gabbay 		rdev->kfd = NULL;
133130e0371SOded Gabbay 	}
134130e0371SOded Gabbay }
135130e0371SOded Gabbay 
136130e0371SOded Gabbay void amdgpu_amdkfd_interrupt(struct amdgpu_device *rdev,
137130e0371SOded Gabbay 		const void *ih_ring_entry)
138130e0371SOded Gabbay {
139130e0371SOded Gabbay 	if (rdev->kfd)
140130e0371SOded Gabbay 		kgd2kfd->interrupt(rdev->kfd, ih_ring_entry);
141130e0371SOded Gabbay }
142130e0371SOded Gabbay 
143130e0371SOded Gabbay void amdgpu_amdkfd_suspend(struct amdgpu_device *rdev)
144130e0371SOded Gabbay {
145130e0371SOded Gabbay 	if (rdev->kfd)
146130e0371SOded Gabbay 		kgd2kfd->suspend(rdev->kfd);
147130e0371SOded Gabbay }
148130e0371SOded Gabbay 
149130e0371SOded Gabbay int amdgpu_amdkfd_resume(struct amdgpu_device *rdev)
150130e0371SOded Gabbay {
151130e0371SOded Gabbay 	int r = 0;
152130e0371SOded Gabbay 
153130e0371SOded Gabbay 	if (rdev->kfd)
154130e0371SOded Gabbay 		r = kgd2kfd->resume(rdev->kfd);
155130e0371SOded Gabbay 
156130e0371SOded Gabbay 	return r;
157130e0371SOded Gabbay }
158130e0371SOded Gabbay 
159130e0371SOded Gabbay u32 pool_to_domain(enum kgd_memory_pool p)
160130e0371SOded Gabbay {
161130e0371SOded Gabbay 	switch (p) {
162130e0371SOded Gabbay 	case KGD_POOL_FRAMEBUFFER: return AMDGPU_GEM_DOMAIN_VRAM;
163130e0371SOded Gabbay 	default: return AMDGPU_GEM_DOMAIN_GTT;
164130e0371SOded Gabbay 	}
165130e0371SOded Gabbay }
166130e0371SOded Gabbay 
167130e0371SOded Gabbay int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
168130e0371SOded Gabbay 			void **mem_obj, uint64_t *gpu_addr,
169130e0371SOded Gabbay 			void **cpu_ptr)
170130e0371SOded Gabbay {
171130e0371SOded Gabbay 	struct amdgpu_device *rdev = (struct amdgpu_device *)kgd;
172130e0371SOded Gabbay 	struct kgd_mem **mem = (struct kgd_mem **) mem_obj;
173130e0371SOded Gabbay 	int r;
174130e0371SOded Gabbay 
175130e0371SOded Gabbay 	BUG_ON(kgd == NULL);
176130e0371SOded Gabbay 	BUG_ON(gpu_addr == NULL);
177130e0371SOded Gabbay 	BUG_ON(cpu_ptr == NULL);
178130e0371SOded Gabbay 
179130e0371SOded Gabbay 	*mem = kmalloc(sizeof(struct kgd_mem), GFP_KERNEL);
180130e0371SOded Gabbay 	if ((*mem) == NULL)
181130e0371SOded Gabbay 		return -ENOMEM;
182130e0371SOded Gabbay 
183130e0371SOded Gabbay 	r = amdgpu_bo_create(rdev, size, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_GTT,
184130e0371SOded Gabbay 			AMDGPU_GEM_CREATE_CPU_GTT_USWC, NULL, &(*mem)->bo);
185130e0371SOded Gabbay 	if (r) {
186130e0371SOded Gabbay 		dev_err(rdev->dev,
187130e0371SOded Gabbay 			"failed to allocate BO for amdkfd (%d)\n", r);
188130e0371SOded Gabbay 		return r;
189130e0371SOded Gabbay 	}
190130e0371SOded Gabbay 
191130e0371SOded Gabbay 	/* map the buffer */
192130e0371SOded Gabbay 	r = amdgpu_bo_reserve((*mem)->bo, true);
193130e0371SOded Gabbay 	if (r) {
194130e0371SOded Gabbay 		dev_err(rdev->dev, "(%d) failed to reserve bo for amdkfd\n", r);
195130e0371SOded Gabbay 		goto allocate_mem_reserve_bo_failed;
196130e0371SOded Gabbay 	}
197130e0371SOded Gabbay 
198130e0371SOded Gabbay 	r = amdgpu_bo_pin((*mem)->bo, AMDGPU_GEM_DOMAIN_GTT,
199130e0371SOded Gabbay 				&(*mem)->gpu_addr);
200130e0371SOded Gabbay 	if (r) {
201130e0371SOded Gabbay 		dev_err(rdev->dev, "(%d) failed to pin bo for amdkfd\n", r);
202130e0371SOded Gabbay 		goto allocate_mem_pin_bo_failed;
203130e0371SOded Gabbay 	}
204130e0371SOded Gabbay 	*gpu_addr = (*mem)->gpu_addr;
205130e0371SOded Gabbay 
206130e0371SOded Gabbay 	r = amdgpu_bo_kmap((*mem)->bo, &(*mem)->cpu_ptr);
207130e0371SOded Gabbay 	if (r) {
208130e0371SOded Gabbay 		dev_err(rdev->dev,
209130e0371SOded Gabbay 			"(%d) failed to map bo to kernel for amdkfd\n", r);
210130e0371SOded Gabbay 		goto allocate_mem_kmap_bo_failed;
211130e0371SOded Gabbay 	}
212130e0371SOded Gabbay 	*cpu_ptr = (*mem)->cpu_ptr;
213130e0371SOded Gabbay 
214130e0371SOded Gabbay 	amdgpu_bo_unreserve((*mem)->bo);
215130e0371SOded Gabbay 
216130e0371SOded Gabbay 	return 0;
217130e0371SOded Gabbay 
218130e0371SOded Gabbay allocate_mem_kmap_bo_failed:
219130e0371SOded Gabbay 	amdgpu_bo_unpin((*mem)->bo);
220130e0371SOded Gabbay allocate_mem_pin_bo_failed:
221130e0371SOded Gabbay 	amdgpu_bo_unreserve((*mem)->bo);
222130e0371SOded Gabbay allocate_mem_reserve_bo_failed:
223130e0371SOded Gabbay 	amdgpu_bo_unref(&(*mem)->bo);
224130e0371SOded Gabbay 
225130e0371SOded Gabbay 	return r;
226130e0371SOded Gabbay }
227130e0371SOded Gabbay 
228130e0371SOded Gabbay void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj)
229130e0371SOded Gabbay {
230130e0371SOded Gabbay 	struct kgd_mem *mem = (struct kgd_mem *) mem_obj;
231130e0371SOded Gabbay 
232130e0371SOded Gabbay 	BUG_ON(mem == NULL);
233130e0371SOded Gabbay 
234130e0371SOded Gabbay 	amdgpu_bo_reserve(mem->bo, true);
235130e0371SOded Gabbay 	amdgpu_bo_kunmap(mem->bo);
236130e0371SOded Gabbay 	amdgpu_bo_unpin(mem->bo);
237130e0371SOded Gabbay 	amdgpu_bo_unreserve(mem->bo);
238130e0371SOded Gabbay 	amdgpu_bo_unref(&(mem->bo));
239130e0371SOded Gabbay 	kfree(mem);
240130e0371SOded Gabbay }
241130e0371SOded Gabbay 
242130e0371SOded Gabbay uint64_t get_vmem_size(struct kgd_dev *kgd)
243130e0371SOded Gabbay {
244130e0371SOded Gabbay 	struct amdgpu_device *rdev =
245130e0371SOded Gabbay 		(struct amdgpu_device *)kgd;
246130e0371SOded Gabbay 
247130e0371SOded Gabbay 	BUG_ON(kgd == NULL);
248130e0371SOded Gabbay 
249130e0371SOded Gabbay 	return rdev->mc.real_vram_size;
250130e0371SOded Gabbay }
251130e0371SOded Gabbay 
252130e0371SOded Gabbay uint64_t get_gpu_clock_counter(struct kgd_dev *kgd)
253130e0371SOded Gabbay {
254130e0371SOded Gabbay 	struct amdgpu_device *rdev = (struct amdgpu_device *)kgd;
255130e0371SOded Gabbay 
256130e0371SOded Gabbay 	if (rdev->asic_funcs->get_gpu_clock_counter)
257130e0371SOded Gabbay 		return rdev->asic_funcs->get_gpu_clock_counter(rdev);
258130e0371SOded Gabbay 	return 0;
259130e0371SOded Gabbay }
260130e0371SOded Gabbay 
261130e0371SOded Gabbay uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd)
262130e0371SOded Gabbay {
263130e0371SOded Gabbay 	struct amdgpu_device *rdev = (struct amdgpu_device *)kgd;
264130e0371SOded Gabbay 
265130e0371SOded Gabbay 	/* The sclk is in quantas of 10kHz */
266130e0371SOded Gabbay 	return rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk / 100;
267130e0371SOded Gabbay }
268