]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/misc/habanalabs/habanalabs_drv.c
Merge branch 'stable/for-linus-5.2' of git://git.kernel.org/pub/scm/linux/kernel...
[linux.git] / drivers / misc / habanalabs / habanalabs_drv.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 /*
4  * Copyright 2016-2019 HabanaLabs, Ltd.
5  * All Rights Reserved.
6  *
7  */
8
9 #define pr_fmt(fmt)             "habanalabs: " fmt
10
11 #include "habanalabs.h"
12
13 #include <linux/pci.h>
14 #include <linux/module.h>
15
16 #define HL_DRIVER_AUTHOR        "HabanaLabs Kernel Driver Team"
17
18 #define HL_DRIVER_DESC          "Driver for HabanaLabs's AI Accelerators"
19
20 MODULE_AUTHOR(HL_DRIVER_AUTHOR);
21 MODULE_DESCRIPTION(HL_DRIVER_DESC);
22 MODULE_LICENSE("GPL v2");
23
24 static int hl_major;
25 static struct class *hl_class;
26 static DEFINE_IDR(hl_devs_idr);
27 static DEFINE_MUTEX(hl_devs_idr_lock);
28
29 static int timeout_locked = 5;
30 static int reset_on_lockup = 1;
31
32 module_param(timeout_locked, int, 0444);
33 MODULE_PARM_DESC(timeout_locked,
34         "Device lockup timeout in seconds (0 = disabled, default 5s)");
35
36 module_param(reset_on_lockup, int, 0444);
37 MODULE_PARM_DESC(reset_on_lockup,
38         "Do device reset on lockup (0 = no, 1 = yes, default yes)");
39
40 #define PCI_VENDOR_ID_HABANALABS        0x1da3
41
42 #define PCI_IDS_GOYA                    0x0001
43
44 static const struct pci_device_id ids[] = {
45         { PCI_DEVICE(PCI_VENDOR_ID_HABANALABS, PCI_IDS_GOYA), },
46         { 0, }
47 };
48 MODULE_DEVICE_TABLE(pci, ids);
49
50 /*
51  * get_asic_type - translate device id to asic type
52  *
53  * @device: id of the PCI device
54  *
55  * Translate device id to asic type.
56  * In case of unidentified device, return -1
57  */
58 static enum hl_asic_type get_asic_type(u16 device)
59 {
60         enum hl_asic_type asic_type;
61
62         switch (device) {
63         case PCI_IDS_GOYA:
64                 asic_type = ASIC_GOYA;
65                 break;
66         default:
67                 asic_type = ASIC_INVALID;
68                 break;
69         }
70
71         return asic_type;
72 }
73
74 /*
75  * hl_device_open - open function for habanalabs device
76  *
77  * @inode: pointer to inode structure
78  * @filp: pointer to file structure
79  *
80  * Called when process opens an habanalabs device.
81  */
82 int hl_device_open(struct inode *inode, struct file *filp)
83 {
84         struct hl_device *hdev;
85         struct hl_fpriv *hpriv;
86         int rc;
87
88         mutex_lock(&hl_devs_idr_lock);
89         hdev = idr_find(&hl_devs_idr, iminor(inode));
90         mutex_unlock(&hl_devs_idr_lock);
91
92         if (!hdev) {
93                 pr_err("Couldn't find device %d:%d\n",
94                         imajor(inode), iminor(inode));
95                 return -ENXIO;
96         }
97
98         mutex_lock(&hdev->fd_open_cnt_lock);
99
100         if (hl_device_disabled_or_in_reset(hdev)) {
101                 dev_err_ratelimited(hdev->dev,
102                         "Can't open %s because it is disabled or in reset\n",
103                         dev_name(hdev->dev));
104                 mutex_unlock(&hdev->fd_open_cnt_lock);
105                 return -EPERM;
106         }
107
108         if (atomic_read(&hdev->fd_open_cnt)) {
109                 dev_info_ratelimited(hdev->dev,
110                         "Device %s is already attached to application\n",
111                         dev_name(hdev->dev));
112                 mutex_unlock(&hdev->fd_open_cnt_lock);
113                 return -EBUSY;
114         }
115
116         atomic_inc(&hdev->fd_open_cnt);
117
118         mutex_unlock(&hdev->fd_open_cnt_lock);
119
120         hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL);
121         if (!hpriv) {
122                 rc = -ENOMEM;
123                 goto close_device;
124         }
125
126         hpriv->hdev = hdev;
127         filp->private_data = hpriv;
128         hpriv->filp = filp;
129         mutex_init(&hpriv->restore_phase_mutex);
130         kref_init(&hpriv->refcount);
131         nonseekable_open(inode, filp);
132
133         hl_cb_mgr_init(&hpriv->cb_mgr);
134         hl_ctx_mgr_init(&hpriv->ctx_mgr);
135
136         rc = hl_ctx_create(hdev, hpriv);
137         if (rc) {
138                 dev_err(hdev->dev, "Failed to open FD (CTX fail)\n");
139                 goto out_err;
140         }
141
142         hpriv->taskpid = find_get_pid(current->pid);
143
144         /*
145          * Device is IDLE at this point so it is legal to change PLLs. There
146          * is no need to check anything because if the PLL is already HIGH, the
147          * set function will return without doing anything
148          */
149         hl_device_set_frequency(hdev, PLL_HIGH);
150
151         hl_debugfs_add_file(hpriv);
152
153         return 0;
154
155 out_err:
156         filp->private_data = NULL;
157         hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr);
158         hl_cb_mgr_fini(hpriv->hdev, &hpriv->cb_mgr);
159         mutex_destroy(&hpriv->restore_phase_mutex);
160         kfree(hpriv);
161
162 close_device:
163         atomic_dec(&hdev->fd_open_cnt);
164         return rc;
165 }
166
167 /*
168  * create_hdev - create habanalabs device instance
169  *
170  * @dev: will hold the pointer to the new habanalabs device structure
171  * @pdev: pointer to the pci device
172  * @asic_type: in case of simulator device, which device is it
173  * @minor: in case of simulator device, the minor of the device
174  *
175  * Allocate memory for habanalabs device and initialize basic fields
176  * Identify the ASIC type
177  * Allocate ID (minor) for the device (only for real devices)
178  */
179 int create_hdev(struct hl_device **dev, struct pci_dev *pdev,
180                 enum hl_asic_type asic_type, int minor)
181 {
182         struct hl_device *hdev;
183         int rc;
184
185         *dev = NULL;
186
187         hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
188         if (!hdev)
189                 return -ENOMEM;
190
191         hdev->major = hl_major;
192         hdev->reset_on_lockup = reset_on_lockup;
193
194         /* Parameters for bring-up - set them to defaults */
195         hdev->mmu_enable = 1;
196         hdev->cpu_enable = 1;
197         hdev->reset_pcilink = 0;
198         hdev->cpu_queues_enable = 1;
199         hdev->fw_loading = 1;
200         hdev->pldm = 0;
201         hdev->heartbeat = 1;
202
203         /* If CPU is disabled, no point in loading FW */
204         if (!hdev->cpu_enable)
205                 hdev->fw_loading = 0;
206
207         /* If we don't load FW, no need to initialize CPU queues */
208         if (!hdev->fw_loading)
209                 hdev->cpu_queues_enable = 0;
210
211         /* If CPU queues not enabled, no way to do heartbeat */
212         if (!hdev->cpu_queues_enable)
213                 hdev->heartbeat = 0;
214
215         if (timeout_locked)
216                 hdev->timeout_jiffies = msecs_to_jiffies(timeout_locked * 1000);
217         else
218                 hdev->timeout_jiffies = MAX_SCHEDULE_TIMEOUT;
219
220         hdev->disabled = true;
221         hdev->pdev = pdev; /* can be NULL in case of simulator device */
222
223         if (pdev) {
224                 hdev->asic_type = get_asic_type(pdev->device);
225                 if (hdev->asic_type == ASIC_INVALID) {
226                         dev_err(&pdev->dev, "Unsupported ASIC\n");
227                         rc = -ENODEV;
228                         goto free_hdev;
229                 }
230         } else {
231                 hdev->asic_type = asic_type;
232         }
233
234         /* Set default DMA mask to 32 bits */
235         hdev->dma_mask = 32;
236
237         mutex_lock(&hl_devs_idr_lock);
238
239         if (minor == -1) {
240                 rc = idr_alloc(&hl_devs_idr, hdev, 0, HL_MAX_MINORS,
241                                 GFP_KERNEL);
242         } else {
243                 void *old_idr = idr_replace(&hl_devs_idr, hdev, minor);
244
245                 if (IS_ERR_VALUE(old_idr)) {
246                         rc = PTR_ERR(old_idr);
247                         pr_err("Error %d when trying to replace minor %d\n",
248                                 rc, minor);
249                         mutex_unlock(&hl_devs_idr_lock);
250                         goto free_hdev;
251                 }
252                 rc = minor;
253         }
254
255         mutex_unlock(&hl_devs_idr_lock);
256
257         if (rc < 0) {
258                 if (rc == -ENOSPC) {
259                         pr_err("too many devices in the system\n");
260                         rc = -EBUSY;
261                 }
262                 goto free_hdev;
263         }
264
265         hdev->id = rc;
266
267         *dev = hdev;
268
269         return 0;
270
271 free_hdev:
272         kfree(hdev);
273         return rc;
274 }
275
276 /*
277  * destroy_hdev - destroy habanalabs device instance
278  *
279  * @dev: pointer to the habanalabs device structure
280  *
281  */
282 void destroy_hdev(struct hl_device *hdev)
283 {
284         /* Remove device from the device list */
285         mutex_lock(&hl_devs_idr_lock);
286         idr_remove(&hl_devs_idr, hdev->id);
287         mutex_unlock(&hl_devs_idr_lock);
288
289         kfree(hdev);
290 }
291
292 static int hl_pmops_suspend(struct device *dev)
293 {
294         struct pci_dev *pdev = to_pci_dev(dev);
295         struct hl_device *hdev = pci_get_drvdata(pdev);
296
297         pr_debug("Going to suspend PCI device\n");
298
299         if (!hdev) {
300                 pr_err("device pointer is NULL in suspend\n");
301                 return 0;
302         }
303
304         return hl_device_suspend(hdev);
305 }
306
307 static int hl_pmops_resume(struct device *dev)
308 {
309         struct pci_dev *pdev = to_pci_dev(dev);
310         struct hl_device *hdev = pci_get_drvdata(pdev);
311
312         pr_debug("Going to resume PCI device\n");
313
314         if (!hdev) {
315                 pr_err("device pointer is NULL in resume\n");
316                 return 0;
317         }
318
319         return hl_device_resume(hdev);
320 }
321
322 /*
323  * hl_pci_probe - probe PCI habanalabs devices
324  *
325  * @pdev: pointer to pci device
326  * @id: pointer to pci device id structure
327  *
328  * Standard PCI probe function for habanalabs device.
329  * Create a new habanalabs device and initialize it according to the
330  * device's type
331  */
332 static int hl_pci_probe(struct pci_dev *pdev,
333                                 const struct pci_device_id *id)
334 {
335         struct hl_device *hdev;
336         int rc;
337
338         dev_info(&pdev->dev, HL_NAME
339                  " device found [%04x:%04x] (rev %x)\n",
340                  (int)pdev->vendor, (int)pdev->device, (int)pdev->revision);
341
342         rc = create_hdev(&hdev, pdev, ASIC_INVALID, -1);
343         if (rc)
344                 return rc;
345
346         pci_set_drvdata(pdev, hdev);
347
348         rc = hl_device_init(hdev, hl_class);
349         if (rc) {
350                 dev_err(&pdev->dev, "Fatal error during habanalabs device init\n");
351                 rc = -ENODEV;
352                 goto disable_device;
353         }
354
355         return 0;
356
357 disable_device:
358         pci_set_drvdata(pdev, NULL);
359         destroy_hdev(hdev);
360
361         return rc;
362 }
363
364 /*
365  * hl_pci_remove - remove PCI habanalabs devices
366  *
367  * @pdev: pointer to pci device
368  *
369  * Standard PCI remove function for habanalabs device
370  */
371 static void hl_pci_remove(struct pci_dev *pdev)
372 {
373         struct hl_device *hdev;
374
375         hdev = pci_get_drvdata(pdev);
376         if (!hdev)
377                 return;
378
379         hl_device_fini(hdev);
380         pci_set_drvdata(pdev, NULL);
381
382         destroy_hdev(hdev);
383 }
384
385 static const struct dev_pm_ops hl_pm_ops = {
386         .suspend = hl_pmops_suspend,
387         .resume = hl_pmops_resume,
388 };
389
390 static struct pci_driver hl_pci_driver = {
391         .name = HL_NAME,
392         .id_table = ids,
393         .probe = hl_pci_probe,
394         .remove = hl_pci_remove,
395         .driver.pm = &hl_pm_ops,
396 };
397
398 /*
399  * hl_init - Initialize the habanalabs kernel driver
400  */
401 static int __init hl_init(void)
402 {
403         int rc;
404         dev_t dev;
405
406         pr_info("loading driver\n");
407
408         rc = alloc_chrdev_region(&dev, 0, HL_MAX_MINORS, HL_NAME);
409         if (rc < 0) {
410                 pr_err("unable to get major\n");
411                 return rc;
412         }
413
414         hl_major = MAJOR(dev);
415
416         hl_class = class_create(THIS_MODULE, HL_NAME);
417         if (IS_ERR(hl_class)) {
418                 pr_err("failed to allocate class\n");
419                 rc = PTR_ERR(hl_class);
420                 goto remove_major;
421         }
422
423         hl_debugfs_init();
424
425         rc = pci_register_driver(&hl_pci_driver);
426         if (rc) {
427                 pr_err("failed to register pci device\n");
428                 goto remove_debugfs;
429         }
430
431         pr_debug("driver loaded\n");
432
433         return 0;
434
435 remove_debugfs:
436         hl_debugfs_fini();
437         class_destroy(hl_class);
438 remove_major:
439         unregister_chrdev_region(MKDEV(hl_major, 0), HL_MAX_MINORS);
440         return rc;
441 }
442
443 /*
444  * hl_exit - Release all resources of the habanalabs kernel driver
445  */
446 static void __exit hl_exit(void)
447 {
448         pci_unregister_driver(&hl_pci_driver);
449
450         /*
451          * Removing debugfs must be after all devices or simulator devices
452          * have been removed because otherwise we get a bug in the
453          * debugfs module for referencing NULL objects
454          */
455         hl_debugfs_fini();
456
457         class_destroy(hl_class);
458         unregister_chrdev_region(MKDEV(hl_major, 0), HL_MAX_MINORS);
459
460         idr_destroy(&hl_devs_idr);
461
462         pr_debug("driver removed\n");
463 }
464
465 module_init(hl_init);
466 module_exit(hl_exit);