1 /*
2  * Copyright 2014 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include <linux/amd-iommu.h>
24 #include <linux/bsearch.h>
25 #include <linux/pci.h>
26 #include <linux/slab.h>
27 #include "kfd_priv.h"
28 #include "kfd_device_queue_manager.h"
29 #include "kfd_pm4_headers.h"
30 
31 #define MQD_SIZE_ALIGNED 768
32 
33 static const struct kfd_device_info kaveri_device_info = {
34 	.max_pasid_bits = 16,
35 	.ih_ring_entry_size = 4 * sizeof(uint32_t),
36 	.mqd_size_aligned = MQD_SIZE_ALIGNED
37 };
38 
39 struct kfd_deviceid {
40 	unsigned short did;
41 	const struct kfd_device_info *device_info;
42 };
43 
44 /* Please keep this sorted by increasing device id. */
45 static const struct kfd_deviceid supported_devices[] = {
46 	{ 0x1304, &kaveri_device_info },	/* Kaveri */
47 	{ 0x1305, &kaveri_device_info },	/* Kaveri */
48 	{ 0x1306, &kaveri_device_info },	/* Kaveri */
49 	{ 0x1307, &kaveri_device_info },	/* Kaveri */
50 	{ 0x1309, &kaveri_device_info },	/* Kaveri */
51 	{ 0x130A, &kaveri_device_info },	/* Kaveri */
52 	{ 0x130B, &kaveri_device_info },	/* Kaveri */
53 	{ 0x130C, &kaveri_device_info },	/* Kaveri */
54 	{ 0x130D, &kaveri_device_info },	/* Kaveri */
55 	{ 0x130E, &kaveri_device_info },	/* Kaveri */
56 	{ 0x130F, &kaveri_device_info },	/* Kaveri */
57 	{ 0x1310, &kaveri_device_info },	/* Kaveri */
58 	{ 0x1311, &kaveri_device_info },	/* Kaveri */
59 	{ 0x1312, &kaveri_device_info },	/* Kaveri */
60 	{ 0x1313, &kaveri_device_info },	/* Kaveri */
61 	{ 0x1315, &kaveri_device_info },	/* Kaveri */
62 	{ 0x1316, &kaveri_device_info },	/* Kaveri */
63 	{ 0x1317, &kaveri_device_info },	/* Kaveri */
64 	{ 0x1318, &kaveri_device_info },	/* Kaveri */
65 	{ 0x131B, &kaveri_device_info },	/* Kaveri */
66 	{ 0x131C, &kaveri_device_info },	/* Kaveri */
67 	{ 0x131D, &kaveri_device_info },	/* Kaveri */
68 };
69 
70 static const struct kfd_device_info *lookup_device_info(unsigned short did)
71 {
72 	size_t i;
73 
74 	for (i = 0; i < ARRAY_SIZE(supported_devices); i++) {
75 		if (supported_devices[i].did == did) {
76 			BUG_ON(supported_devices[i].device_info == NULL);
77 			return supported_devices[i].device_info;
78 		}
79 	}
80 
81 	return NULL;
82 }
83 
84 struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev)
85 {
86 	struct kfd_dev *kfd;
87 
88 	const struct kfd_device_info *device_info =
89 					lookup_device_info(pdev->device);
90 
91 	if (!device_info)
92 		return NULL;
93 
94 	kfd = kzalloc(sizeof(*kfd), GFP_KERNEL);
95 	if (!kfd)
96 		return NULL;
97 
98 	kfd->kgd = kgd;
99 	kfd->device_info = device_info;
100 	kfd->pdev = pdev;
101 	kfd->init_complete = false;
102 
103 	return kfd;
104 }
105 
106 static bool device_iommu_pasid_init(struct kfd_dev *kfd)
107 {
108 	const u32 required_iommu_flags = AMD_IOMMU_DEVICE_FLAG_ATS_SUP |
109 					AMD_IOMMU_DEVICE_FLAG_PRI_SUP |
110 					AMD_IOMMU_DEVICE_FLAG_PASID_SUP;
111 
112 	struct amd_iommu_device_info iommu_info;
113 	unsigned int pasid_limit;
114 	int err;
115 
116 	err = amd_iommu_device_info(kfd->pdev, &iommu_info);
117 	if (err < 0) {
118 		dev_err(kfd_device,
119 			"error getting iommu info. is the iommu enabled?\n");
120 		return false;
121 	}
122 
123 	if ((iommu_info.flags & required_iommu_flags) != required_iommu_flags) {
124 		dev_err(kfd_device, "error required iommu flags ats(%i), pri(%i), pasid(%i)\n",
125 		       (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_ATS_SUP) != 0,
126 		       (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_PRI_SUP) != 0,
127 		       (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_PASID_SUP) != 0);
128 		return false;
129 	}
130 
131 	pasid_limit = min_t(unsigned int,
132 			(unsigned int)1 << kfd->device_info->max_pasid_bits,
133 			iommu_info.max_pasids);
134 	/*
135 	 * last pasid is used for kernel queues doorbells
136 	 * in the future the last pasid might be used for a kernel thread.
137 	 */
138 	pasid_limit = min_t(unsigned int,
139 				pasid_limit,
140 				kfd->doorbell_process_limit - 1);
141 
142 	err = amd_iommu_init_device(kfd->pdev, pasid_limit);
143 	if (err < 0) {
144 		dev_err(kfd_device, "error initializing iommu device\n");
145 		return false;
146 	}
147 
148 	if (!kfd_set_pasid_limit(pasid_limit)) {
149 		dev_err(kfd_device, "error setting pasid limit\n");
150 		amd_iommu_free_device(kfd->pdev);
151 		return false;
152 	}
153 
154 	return true;
155 }
156 
157 static void iommu_pasid_shutdown_callback(struct pci_dev *pdev, int pasid)
158 {
159 	struct kfd_dev *dev = kfd_device_by_pci_dev(pdev);
160 
161 	if (dev)
162 		kfd_unbind_process_from_device(dev, pasid);
163 }
164 
165 bool kgd2kfd_device_init(struct kfd_dev *kfd,
166 			 const struct kgd2kfd_shared_resources *gpu_resources)
167 {
168 	unsigned int size;
169 
170 	kfd->shared_resources = *gpu_resources;
171 
172 	/* calculate max size of mqds needed for queues */
173 	size = max_num_of_queues_per_device *
174 			kfd->device_info->mqd_size_aligned;
175 
176 	/* add another 512KB for all other allocations on gart */
177 	size += 512 * 1024;
178 
179 	if (kfd2kgd->init_sa_manager(kfd->kgd, size)) {
180 		dev_err(kfd_device,
181 			"Error initializing sa manager for device (%x:%x)\n",
182 			kfd->pdev->vendor, kfd->pdev->device);
183 		goto out;
184 	}
185 
186 	kfd_doorbell_init(kfd);
187 
188 	if (kfd_topology_add_device(kfd) != 0) {
189 		dev_err(kfd_device,
190 			"Error adding device (%x:%x) to topology\n",
191 			kfd->pdev->vendor, kfd->pdev->device);
192 		goto kfd_topology_add_device_error;
193 	}
194 
195 	if (!device_iommu_pasid_init(kfd)) {
196 		dev_err(kfd_device,
197 			"Error initializing iommuv2 for device (%x:%x)\n",
198 			kfd->pdev->vendor, kfd->pdev->device);
199 		goto device_iommu_pasid_error;
200 	}
201 	amd_iommu_set_invalidate_ctx_cb(kfd->pdev,
202 						iommu_pasid_shutdown_callback);
203 
204 	kfd->dqm = device_queue_manager_init(kfd);
205 	if (!kfd->dqm) {
206 		dev_err(kfd_device,
207 			"Error initializing queue manager for device (%x:%x)\n",
208 			kfd->pdev->vendor, kfd->pdev->device);
209 		goto device_queue_manager_error;
210 	}
211 
212 	if (kfd->dqm->start(kfd->dqm) != 0) {
213 		dev_err(kfd_device,
214 			"Error starting queuen manager for device (%x:%x)\n",
215 			kfd->pdev->vendor, kfd->pdev->device);
216 		goto dqm_start_error;
217 	}
218 
219 	kfd->init_complete = true;
220 	dev_info(kfd_device, "added device (%x:%x)\n", kfd->pdev->vendor,
221 		 kfd->pdev->device);
222 
223 	pr_debug("kfd: Starting kfd with the following scheduling policy %d\n",
224 		sched_policy);
225 
226 	goto out;
227 
228 dqm_start_error:
229 	device_queue_manager_uninit(kfd->dqm);
230 device_queue_manager_error:
231 	amd_iommu_free_device(kfd->pdev);
232 device_iommu_pasid_error:
233 	kfd_topology_remove_device(kfd);
234 kfd_topology_add_device_error:
235 	kfd2kgd->fini_sa_manager(kfd->kgd);
236 	dev_err(kfd_device,
237 		"device (%x:%x) NOT added due to errors\n",
238 		kfd->pdev->vendor, kfd->pdev->device);
239 out:
240 	return kfd->init_complete;
241 }
242 
243 void kgd2kfd_device_exit(struct kfd_dev *kfd)
244 {
245 	if (kfd->init_complete) {
246 		device_queue_manager_uninit(kfd->dqm);
247 		amd_iommu_free_device(kfd->pdev);
248 		kfd_topology_remove_device(kfd);
249 	}
250 
251 	kfree(kfd);
252 }
253 
254 void kgd2kfd_suspend(struct kfd_dev *kfd)
255 {
256 	BUG_ON(kfd == NULL);
257 
258 	if (kfd->init_complete) {
259 		kfd->dqm->stop(kfd->dqm);
260 		amd_iommu_set_invalidate_ctx_cb(kfd->pdev, NULL);
261 		amd_iommu_free_device(kfd->pdev);
262 	}
263 }
264 
265 int kgd2kfd_resume(struct kfd_dev *kfd)
266 {
267 	unsigned int pasid_limit;
268 	int err;
269 
270 	BUG_ON(kfd == NULL);
271 
272 	pasid_limit = kfd_get_pasid_limit();
273 
274 	if (kfd->init_complete) {
275 		err = amd_iommu_init_device(kfd->pdev, pasid_limit);
276 		if (err < 0)
277 			return -ENXIO;
278 		amd_iommu_set_invalidate_ctx_cb(kfd->pdev,
279 						iommu_pasid_shutdown_callback);
280 		kfd->dqm->start(kfd->dqm);
281 	}
282 
283 	return 0;
284 }
285 
286 /* This is called directly from KGD at ISR. */
287 void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry)
288 {
289 	/* Process interrupts / schedule work as necessary */
290 }
291