]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/misc/habanalabs/device.c
2423588ecf229dc5067acf4434f93ec61b58f1fe
[linux.git] / drivers / misc / habanalabs / device.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 /*
4  * Copyright 2016-2019 HabanaLabs, Ltd.
5  * All Rights Reserved.
6  */
7
8 #include "habanalabs.h"
9
10 #include <linux/pci.h>
11 #include <linux/delay.h>
12
13 static void hpriv_release(struct kref *ref)
14 {
15         struct hl_fpriv *hpriv;
16         struct hl_device *hdev;
17
18         hpriv = container_of(ref, struct hl_fpriv, refcount);
19
20         hdev = hpriv->hdev;
21
22         put_pid(hpriv->taskpid);
23
24         kfree(hpriv);
25
26         /* Now the FD is really closed */
27         atomic_dec(&hdev->fd_open_cnt);
28
29         /* This allows a new user context to open the device */
30         hdev->user_ctx = NULL;
31 }
32
33 void hl_hpriv_get(struct hl_fpriv *hpriv)
34 {
35         kref_get(&hpriv->refcount);
36 }
37
38 void hl_hpriv_put(struct hl_fpriv *hpriv)
39 {
40         kref_put(&hpriv->refcount, hpriv_release);
41 }
42
43 /*
44  * hl_device_release - release function for habanalabs device
45  *
46  * @inode: pointer to inode structure
47  * @filp: pointer to file structure
48  *
49  * Called when process closes an habanalabs device
50  */
51 static int hl_device_release(struct inode *inode, struct file *filp)
52 {
53         struct hl_fpriv *hpriv = filp->private_data;
54
55         hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr);
56
57         filp->private_data = NULL;
58
59         hl_hpriv_put(hpriv);
60
61         return 0;
62 }
63
64 static const struct file_operations hl_ops = {
65         .owner = THIS_MODULE,
66         .open = hl_device_open,
67         .release = hl_device_release
68 };
69
70 /*
71  * device_setup_cdev - setup cdev and device for habanalabs device
72  *
73  * @hdev: pointer to habanalabs device structure
74  * @hclass: pointer to the class object of the device
75  * @minor: minor number of the specific device
76  * @fpos : file operations to install for this device
77  *
78  * Create a cdev and a Linux device for habanalabs's device. Need to be
79  * called at the end of the habanalabs device initialization process,
80  * because this function exposes the device to the user
81  */
82 static int device_setup_cdev(struct hl_device *hdev, struct class *hclass,
83                                 int minor, const struct file_operations *fops)
84 {
85         int err, devno = MKDEV(hdev->major, minor);
86         struct cdev *hdev_cdev = &hdev->cdev;
87         char *name;
88
89         name = kasprintf(GFP_KERNEL, "hl%d", hdev->id);
90         if (!name)
91                 return -ENOMEM;
92
93         cdev_init(hdev_cdev, fops);
94         hdev_cdev->owner = THIS_MODULE;
95         err = cdev_add(hdev_cdev, devno, 1);
96         if (err) {
97                 pr_err("Failed to add char device %s\n", name);
98                 goto err_cdev_add;
99         }
100
101         hdev->dev = device_create(hclass, NULL, devno, NULL, "%s", name);
102         if (IS_ERR(hdev->dev)) {
103                 pr_err("Failed to create device %s\n", name);
104                 err = PTR_ERR(hdev->dev);
105                 goto err_device_create;
106         }
107
108         dev_set_drvdata(hdev->dev, hdev);
109
110         kfree(name);
111
112         return 0;
113
114 err_device_create:
115         cdev_del(hdev_cdev);
116 err_cdev_add:
117         kfree(name);
118         return err;
119 }
120
121 /*
122  * device_early_init - do some early initialization for the habanalabs device
123  *
124  * @hdev: pointer to habanalabs device structure
125  *
126  * Install the relevant function pointers and call the early_init function,
127  * if such a function exists
128  */
129 static int device_early_init(struct hl_device *hdev)
130 {
131         int rc;
132
133         switch (hdev->asic_type) {
134         case ASIC_GOYA:
135                 goya_set_asic_funcs(hdev);
136                 strlcpy(hdev->asic_name, "GOYA", sizeof(hdev->asic_name));
137                 break;
138         default:
139                 dev_err(hdev->dev, "Unrecognized ASIC type %d\n",
140                         hdev->asic_type);
141                 return -EINVAL;
142         }
143
144         rc = hdev->asic_funcs->early_init(hdev);
145         if (rc)
146                 return rc;
147
148         rc = hl_asid_init(hdev);
149         if (rc)
150                 goto early_fini;
151
152         mutex_init(&hdev->fd_open_cnt_lock);
153         atomic_set(&hdev->fd_open_cnt, 0);
154
155         return 0;
156
157 early_fini:
158         if (hdev->asic_funcs->early_fini)
159                 hdev->asic_funcs->early_fini(hdev);
160
161         return rc;
162 }
163
164 /*
165  * device_early_fini - finalize all that was done in device_early_init
166  *
167  * @hdev: pointer to habanalabs device structure
168  *
169  */
170 static void device_early_fini(struct hl_device *hdev)
171 {
172
173         hl_asid_fini(hdev);
174
175         if (hdev->asic_funcs->early_fini)
176                 hdev->asic_funcs->early_fini(hdev);
177
178         mutex_destroy(&hdev->fd_open_cnt_lock);
179 }
180
181 /*
182  * hl_device_suspend - initiate device suspend
183  *
184  * @hdev: pointer to habanalabs device structure
185  *
186  * Puts the hw in the suspend state (all asics).
187  * Returns 0 for success or an error on failure.
188  * Called at driver suspend.
189  */
190 int hl_device_suspend(struct hl_device *hdev)
191 {
192         int rc;
193
194         pci_save_state(hdev->pdev);
195
196         rc = hdev->asic_funcs->suspend(hdev);
197         if (rc)
198                 dev_err(hdev->dev,
199                         "Failed to disable PCI access of device CPU\n");
200
201         /* Shut down the device */
202         pci_disable_device(hdev->pdev);
203         pci_set_power_state(hdev->pdev, PCI_D3hot);
204
205         return 0;
206 }
207
208 /*
209  * hl_device_resume - initiate device resume
210  *
211  * @hdev: pointer to habanalabs device structure
212  *
213  * Bring the hw back to operating state (all asics).
214  * Returns 0 for success or an error on failure.
215  * Called at driver resume.
216  */
217 int hl_device_resume(struct hl_device *hdev)
218 {
219         int rc;
220
221         pci_set_power_state(hdev->pdev, PCI_D0);
222         pci_restore_state(hdev->pdev);
223         rc = pci_enable_device(hdev->pdev);
224         if (rc) {
225                 dev_err(hdev->dev,
226                         "Failed to enable PCI device in resume\n");
227                 return rc;
228         }
229
230         rc = hdev->asic_funcs->resume(hdev);
231         if (rc) {
232                 dev_err(hdev->dev,
233                         "Failed to enable PCI access from device CPU\n");
234                 return rc;
235         }
236
237         return 0;
238 }
239
240 /*
241  * hl_device_init - main initialization function for habanalabs device
242  *
243  * @hdev: pointer to habanalabs device structure
244  *
245  * Allocate an id for the device, do early initialization and then call the
246  * ASIC specific initialization functions. Finally, create the cdev and the
247  * Linux device to expose it to the user
248  */
249 int hl_device_init(struct hl_device *hdev, struct class *hclass)
250 {
251         int rc;
252
253         /* Create device */
254         rc = device_setup_cdev(hdev, hclass, hdev->id, &hl_ops);
255
256         if (rc)
257                 goto out_disabled;
258
259         /* Initialize ASIC function pointers and perform early init */
260         rc = device_early_init(hdev);
261         if (rc)
262                 goto release_device;
263
264         /*
265          * Start calling ASIC initialization. First S/W then H/W and finally
266          * late init
267          */
268         rc = hdev->asic_funcs->sw_init(hdev);
269         if (rc)
270                 goto early_fini;
271
272         /* Allocate the kernel context */
273         hdev->kernel_ctx = kzalloc(sizeof(*hdev->kernel_ctx), GFP_KERNEL);
274         if (!hdev->kernel_ctx) {
275                 rc = -ENOMEM;
276                 goto sw_fini;
277         }
278
279         hdev->user_ctx = NULL;
280
281         rc = hl_ctx_init(hdev, hdev->kernel_ctx, true);
282         if (rc) {
283                 dev_err(hdev->dev, "failed to initialize kernel context\n");
284                 goto free_ctx;
285         }
286
287         dev_notice(hdev->dev,
288                 "Successfully added device to habanalabs driver\n");
289
290         return 0;
291
292 free_ctx:
293         kfree(hdev->kernel_ctx);
294 sw_fini:
295         hdev->asic_funcs->sw_fini(hdev);
296 early_fini:
297         device_early_fini(hdev);
298 release_device:
299         device_destroy(hclass, hdev->dev->devt);
300         cdev_del(&hdev->cdev);
301 out_disabled:
302         hdev->disabled = true;
303         if (hdev->pdev)
304                 dev_err(&hdev->pdev->dev,
305                         "Failed to initialize hl%d. Device is NOT usable !\n",
306                         hdev->id);
307         else
308                 pr_err("Failed to initialize hl%d. Device is NOT usable !\n",
309                         hdev->id);
310
311         return rc;
312 }
313
314 /*
315  * hl_device_fini - main tear-down function for habanalabs device
316  *
317  * @hdev: pointer to habanalabs device structure
318  *
319  * Destroy the device, call ASIC fini functions and release the id
320  */
321 void hl_device_fini(struct hl_device *hdev)
322 {
323         dev_info(hdev->dev, "Removing device\n");
324
325         /* Mark device as disabled */
326         hdev->disabled = true;
327
328         /* Release kernel context */
329         if ((hdev->kernel_ctx) && (hl_ctx_put(hdev->kernel_ctx) != 1))
330                 dev_err(hdev->dev, "kernel ctx is still alive\n");
331
332         /* Call ASIC S/W finalize function */
333         hdev->asic_funcs->sw_fini(hdev);
334
335         device_early_fini(hdev);
336
337         /* Hide device from user */
338         device_destroy(hdev->dev->class, hdev->dev->devt);
339         cdev_del(&hdev->cdev);
340
341         pr_info("removed device successfully\n");
342 }
343
344 /*
345  * hl_poll_timeout_memory - Periodically poll a host memory address
346  *                              until it is not zero or a timeout occurs
347  * @hdev: pointer to habanalabs device structure
348  * @addr: Address to poll
349  * @timeout_us: timeout in us
350  * @val: Variable to read the value into
351  *
352  * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
353  * case, the last read value at @addr is stored in @val. Must not
354  * be called from atomic context if sleep_us or timeout_us are used.
355  *
356  * The function sleeps for 100us with timeout value of
357  * timeout_us
358  */
359 int hl_poll_timeout_memory(struct hl_device *hdev, u64 addr,
360                                 u32 timeout_us, u32 *val)
361 {
362         /*
363          * address in this function points always to a memory location in the
364          * host's (server's) memory. That location is updated asynchronously
365          * either by the direct access of the device or by another core
366          */
367         u32 *paddr = (u32 *) (uintptr_t) addr;
368         ktime_t timeout = ktime_add_us(ktime_get(), timeout_us);
369
370         might_sleep();
371
372         for (;;) {
373                 /*
374                  * Flush CPU read/write buffers to make sure we read updates
375                  * done by other cores or by the device
376                  */
377                 mb();
378                 *val = *paddr;
379                 if (*val)
380                         break;
381                 if (ktime_compare(ktime_get(), timeout) > 0) {
382                         *val = *paddr;
383                         break;
384                 }
385                 usleep_range((100 >> 2) + 1, 100);
386         }
387
388         return *val ? 0 : -ETIMEDOUT;
389 }
390
391 /*
392  * hl_poll_timeout_devicememory - Periodically poll a device memory address
393  *                                until it is not zero or a timeout occurs
394  * @hdev: pointer to habanalabs device structure
395  * @addr: Device address to poll
396  * @timeout_us: timeout in us
397  * @val: Variable to read the value into
398  *
399  * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
400  * case, the last read value at @addr is stored in @val. Must not
401  * be called from atomic context if sleep_us or timeout_us are used.
402  *
403  * The function sleeps for 100us with timeout value of
404  * timeout_us
405  */
406 int hl_poll_timeout_device_memory(struct hl_device *hdev, void __iomem *addr,
407                                 u32 timeout_us, u32 *val)
408 {
409         ktime_t timeout = ktime_add_us(ktime_get(), timeout_us);
410
411         might_sleep();
412
413         for (;;) {
414                 *val = readl(addr);
415                 if (*val)
416                         break;
417                 if (ktime_compare(ktime_get(), timeout) > 0) {
418                         *val = readl(addr);
419                         break;
420                 }
421                 usleep_range((100 >> 2) + 1, 100);
422         }
423
424         return *val ? 0 : -ETIMEDOUT;
425 }
426
427 /*
428  * MMIO register access helper functions.
429  */
430
431 /*
432  * hl_rreg - Read an MMIO register
433  *
434  * @hdev: pointer to habanalabs device structure
435  * @reg: MMIO register offset (in bytes)
436  *
437  * Returns the value of the MMIO register we are asked to read
438  *
439  */
440 inline u32 hl_rreg(struct hl_device *hdev, u32 reg)
441 {
442         return readl(hdev->rmmio + reg);
443 }
444
445 /*
446  * hl_wreg - Write to an MMIO register
447  *
448  * @hdev: pointer to habanalabs device structure
449  * @reg: MMIO register offset (in bytes)
450  * @val: 32-bit value
451  *
452  * Writes the 32-bit value into the MMIO register
453  *
454  */
455 inline void hl_wreg(struct hl_device *hdev, u32 reg, u32 val)
456 {
457         writel(val, hdev->rmmio + reg);
458 }