blob: 06e2b7f324994cb7699d6bd65b5ce42542ede0c0 [file] [log] [blame]
Oded Gabbayc4d66342019-02-16 00:39:11 +02001// 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
13static 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);
Oded Gabbay0861e412019-02-16 00:39:14 +020025
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;
Oded Gabbayc4d66342019-02-16 00:39:11 +020031}
32
33void hl_hpriv_get(struct hl_fpriv *hpriv)
34{
35 kref_get(&hpriv->refcount);
36}
37
38void 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 */
51static int hl_device_release(struct inode *inode, struct file *filp)
52{
53 struct hl_fpriv *hpriv = filp->private_data;
54
Oded Gabbaybe5d9262019-02-16 00:39:15 +020055 hl_cb_mgr_fini(hpriv->hdev, &hpriv->cb_mgr);
Oded Gabbay0861e412019-02-16 00:39:14 +020056 hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr);
57
Oded Gabbayc4d66342019-02-16 00:39:11 +020058 filp->private_data = NULL;
59
60 hl_hpriv_put(hpriv);
61
62 return 0;
63}
64
Oded Gabbaybe5d9262019-02-16 00:39:15 +020065/*
66 * hl_mmap - mmap function for habanalabs device
67 *
68 * @*filp: pointer to file structure
69 * @*vma: pointer to vm_area_struct of the process
70 *
71 * Called when process does an mmap on habanalabs device. Call the device's mmap
72 * function at the end of the common code.
73 */
74static int hl_mmap(struct file *filp, struct vm_area_struct *vma)
75{
76 struct hl_fpriv *hpriv = filp->private_data;
77
78 if ((vma->vm_pgoff & HL_MMAP_CB_MASK) == HL_MMAP_CB_MASK) {
79 vma->vm_pgoff ^= HL_MMAP_CB_MASK;
80 return hl_cb_mmap(hpriv, vma);
81 }
82
83 return hpriv->hdev->asic_funcs->mmap(hpriv, vma);
84}
85
Oded Gabbayc4d66342019-02-16 00:39:11 +020086static const struct file_operations hl_ops = {
87 .owner = THIS_MODULE,
88 .open = hl_device_open,
Oded Gabbaybe5d9262019-02-16 00:39:15 +020089 .release = hl_device_release,
90 .mmap = hl_mmap,
91 .unlocked_ioctl = hl_ioctl,
92 .compat_ioctl = hl_ioctl
Oded Gabbayc4d66342019-02-16 00:39:11 +020093};
94
95/*
96 * device_setup_cdev - setup cdev and device for habanalabs device
97 *
98 * @hdev: pointer to habanalabs device structure
99 * @hclass: pointer to the class object of the device
100 * @minor: minor number of the specific device
101 * @fpos : file operations to install for this device
102 *
103 * Create a cdev and a Linux device for habanalabs's device. Need to be
104 * called at the end of the habanalabs device initialization process,
105 * because this function exposes the device to the user
106 */
107static int device_setup_cdev(struct hl_device *hdev, struct class *hclass,
108 int minor, const struct file_operations *fops)
109{
110 int err, devno = MKDEV(hdev->major, minor);
111 struct cdev *hdev_cdev = &hdev->cdev;
112 char *name;
113
114 name = kasprintf(GFP_KERNEL, "hl%d", hdev->id);
115 if (!name)
116 return -ENOMEM;
117
118 cdev_init(hdev_cdev, fops);
119 hdev_cdev->owner = THIS_MODULE;
120 err = cdev_add(hdev_cdev, devno, 1);
121 if (err) {
122 pr_err("Failed to add char device %s\n", name);
123 goto err_cdev_add;
124 }
125
126 hdev->dev = device_create(hclass, NULL, devno, NULL, "%s", name);
127 if (IS_ERR(hdev->dev)) {
128 pr_err("Failed to create device %s\n", name);
129 err = PTR_ERR(hdev->dev);
130 goto err_device_create;
131 }
132
133 dev_set_drvdata(hdev->dev, hdev);
134
135 kfree(name);
136
137 return 0;
138
139err_device_create:
140 cdev_del(hdev_cdev);
141err_cdev_add:
142 kfree(name);
143 return err;
144}
145
146/*
147 * device_early_init - do some early initialization for the habanalabs device
148 *
149 * @hdev: pointer to habanalabs device structure
150 *
151 * Install the relevant function pointers and call the early_init function,
152 * if such a function exists
153 */
154static int device_early_init(struct hl_device *hdev)
155{
Oded Gabbay99b9d7b2019-02-16 00:39:13 +0200156 int rc;
157
Oded Gabbayc4d66342019-02-16 00:39:11 +0200158 switch (hdev->asic_type) {
159 case ASIC_GOYA:
Oded Gabbay99b9d7b2019-02-16 00:39:13 +0200160 goya_set_asic_funcs(hdev);
Oded Gabbayc4d66342019-02-16 00:39:11 +0200161 strlcpy(hdev->asic_name, "GOYA", sizeof(hdev->asic_name));
162 break;
163 default:
164 dev_err(hdev->dev, "Unrecognized ASIC type %d\n",
165 hdev->asic_type);
166 return -EINVAL;
167 }
168
Oded Gabbay99b9d7b2019-02-16 00:39:13 +0200169 rc = hdev->asic_funcs->early_init(hdev);
170 if (rc)
171 return rc;
172
Oded Gabbay0861e412019-02-16 00:39:14 +0200173 rc = hl_asid_init(hdev);
174 if (rc)
175 goto early_fini;
176
Oded Gabbay9494a8d2019-02-16 00:39:17 +0200177 hdev->cq_wq = alloc_workqueue("hl-free-jobs", WQ_UNBOUND, 0);
178 if (hdev->cq_wq == NULL) {
179 dev_err(hdev->dev, "Failed to allocate CQ workqueue\n");
180 rc = -ENOMEM;
181 goto asid_fini;
182 }
183
Oded Gabbaybe5d9262019-02-16 00:39:15 +0200184 hl_cb_mgr_init(&hdev->kernel_cb_mgr);
185
Oded Gabbay0861e412019-02-16 00:39:14 +0200186 mutex_init(&hdev->fd_open_cnt_lock);
Oded Gabbay9494a8d2019-02-16 00:39:17 +0200187 mutex_init(&hdev->send_cpu_message_lock);
Oded Gabbay0861e412019-02-16 00:39:14 +0200188 atomic_set(&hdev->fd_open_cnt, 0);
189
Oded Gabbayc4d66342019-02-16 00:39:11 +0200190 return 0;
Oded Gabbay0861e412019-02-16 00:39:14 +0200191
Oded Gabbay9494a8d2019-02-16 00:39:17 +0200192asid_fini:
193 hl_asid_fini(hdev);
Oded Gabbay0861e412019-02-16 00:39:14 +0200194early_fini:
195 if (hdev->asic_funcs->early_fini)
196 hdev->asic_funcs->early_fini(hdev);
197
198 return rc;
Oded Gabbayc4d66342019-02-16 00:39:11 +0200199}
200
201/*
202 * device_early_fini - finalize all that was done in device_early_init
203 *
204 * @hdev: pointer to habanalabs device structure
205 *
206 */
207static void device_early_fini(struct hl_device *hdev)
208{
Oded Gabbay9494a8d2019-02-16 00:39:17 +0200209 mutex_destroy(&hdev->send_cpu_message_lock);
Oded Gabbay99b9d7b2019-02-16 00:39:13 +0200210
Oded Gabbaybe5d9262019-02-16 00:39:15 +0200211 hl_cb_mgr_fini(hdev, &hdev->kernel_cb_mgr);
212
Oded Gabbay9494a8d2019-02-16 00:39:17 +0200213 destroy_workqueue(hdev->cq_wq);
214
Oded Gabbay0861e412019-02-16 00:39:14 +0200215 hl_asid_fini(hdev);
216
Oded Gabbay99b9d7b2019-02-16 00:39:13 +0200217 if (hdev->asic_funcs->early_fini)
218 hdev->asic_funcs->early_fini(hdev);
219
Oded Gabbay0861e412019-02-16 00:39:14 +0200220 mutex_destroy(&hdev->fd_open_cnt_lock);
Oded Gabbayc4d66342019-02-16 00:39:11 +0200221}
222
223/*
224 * hl_device_suspend - initiate device suspend
225 *
226 * @hdev: pointer to habanalabs device structure
227 *
228 * Puts the hw in the suspend state (all asics).
229 * Returns 0 for success or an error on failure.
230 * Called at driver suspend.
231 */
232int hl_device_suspend(struct hl_device *hdev)
233{
Oded Gabbay99b9d7b2019-02-16 00:39:13 +0200234 int rc;
235
Oded Gabbayc4d66342019-02-16 00:39:11 +0200236 pci_save_state(hdev->pdev);
237
Oded Gabbay99b9d7b2019-02-16 00:39:13 +0200238 rc = hdev->asic_funcs->suspend(hdev);
239 if (rc)
240 dev_err(hdev->dev,
241 "Failed to disable PCI access of device CPU\n");
242
Oded Gabbayc4d66342019-02-16 00:39:11 +0200243 /* Shut down the device */
244 pci_disable_device(hdev->pdev);
245 pci_set_power_state(hdev->pdev, PCI_D3hot);
246
247 return 0;
248}
249
250/*
251 * hl_device_resume - initiate device resume
252 *
253 * @hdev: pointer to habanalabs device structure
254 *
255 * Bring the hw back to operating state (all asics).
256 * Returns 0 for success or an error on failure.
257 * Called at driver resume.
258 */
259int hl_device_resume(struct hl_device *hdev)
260{
261 int rc;
262
263 pci_set_power_state(hdev->pdev, PCI_D0);
264 pci_restore_state(hdev->pdev);
265 rc = pci_enable_device(hdev->pdev);
266 if (rc) {
267 dev_err(hdev->dev,
268 "Failed to enable PCI device in resume\n");
269 return rc;
270 }
271
Oded Gabbay99b9d7b2019-02-16 00:39:13 +0200272 rc = hdev->asic_funcs->resume(hdev);
273 if (rc) {
274 dev_err(hdev->dev,
275 "Failed to enable PCI access from device CPU\n");
276 return rc;
277 }
278
Oded Gabbayc4d66342019-02-16 00:39:11 +0200279 return 0;
280}
281
282/*
283 * hl_device_init - main initialization function for habanalabs device
284 *
285 * @hdev: pointer to habanalabs device structure
286 *
287 * Allocate an id for the device, do early initialization and then call the
288 * ASIC specific initialization functions. Finally, create the cdev and the
289 * Linux device to expose it to the user
290 */
291int hl_device_init(struct hl_device *hdev, struct class *hclass)
292{
Oded Gabbay9494a8d2019-02-16 00:39:17 +0200293 int i, rc, cq_ready_cnt;
Oded Gabbayc4d66342019-02-16 00:39:11 +0200294
295 /* Create device */
296 rc = device_setup_cdev(hdev, hclass, hdev->id, &hl_ops);
297
298 if (rc)
299 goto out_disabled;
300
301 /* Initialize ASIC function pointers and perform early init */
302 rc = device_early_init(hdev);
303 if (rc)
304 goto release_device;
305
Oded Gabbay99b9d7b2019-02-16 00:39:13 +0200306 /*
307 * Start calling ASIC initialization. First S/W then H/W and finally
308 * late init
309 */
310 rc = hdev->asic_funcs->sw_init(hdev);
311 if (rc)
312 goto early_fini;
313
Oded Gabbay9494a8d2019-02-16 00:39:17 +0200314 /*
315 * Initialize the H/W queues. Must be done before hw_init, because
316 * there the addresses of the kernel queue are being written to the
317 * registers of the device
318 */
319 rc = hl_hw_queues_create(hdev);
320 if (rc) {
321 dev_err(hdev->dev, "failed to initialize kernel queues\n");
322 goto sw_fini;
323 }
324
325 /*
326 * Initialize the completion queues. Must be done before hw_init,
327 * because there the addresses of the completion queues are being
328 * passed as arguments to request_irq
329 */
330 hdev->completion_queue =
331 kcalloc(hdev->asic_prop.completion_queues_count,
332 sizeof(*hdev->completion_queue), GFP_KERNEL);
333
334 if (!hdev->completion_queue) {
335 dev_err(hdev->dev, "failed to allocate completion queues\n");
336 rc = -ENOMEM;
337 goto hw_queues_destroy;
338 }
339
340 for (i = 0, cq_ready_cnt = 0;
341 i < hdev->asic_prop.completion_queues_count;
342 i++, cq_ready_cnt++) {
343 rc = hl_cq_init(hdev, &hdev->completion_queue[i], i);
344 if (rc) {
345 dev_err(hdev->dev,
346 "failed to initialize completion queue\n");
347 goto cq_fini;
348 }
349 }
350
Oded Gabbay0861e412019-02-16 00:39:14 +0200351 /* Allocate the kernel context */
352 hdev->kernel_ctx = kzalloc(sizeof(*hdev->kernel_ctx), GFP_KERNEL);
353 if (!hdev->kernel_ctx) {
354 rc = -ENOMEM;
Oded Gabbay9494a8d2019-02-16 00:39:17 +0200355 goto cq_fini;
Oded Gabbay0861e412019-02-16 00:39:14 +0200356 }
357
358 hdev->user_ctx = NULL;
359
360 rc = hl_ctx_init(hdev, hdev->kernel_ctx, true);
361 if (rc) {
362 dev_err(hdev->dev, "failed to initialize kernel context\n");
363 goto free_ctx;
364 }
365
Oded Gabbaybe5d9262019-02-16 00:39:15 +0200366 rc = hl_cb_pool_init(hdev);
367 if (rc) {
368 dev_err(hdev->dev, "failed to initialize CB pool\n");
369 goto release_ctx;
370 }
371
Oded Gabbay839c4802019-02-16 00:39:16 +0200372 rc = hdev->asic_funcs->hw_init(hdev);
373 if (rc) {
374 dev_err(hdev->dev, "failed to initialize the H/W\n");
375 rc = 0;
376 goto out_disabled;
377 }
378
379 hdev->disabled = false;
380
Oded Gabbay9494a8d2019-02-16 00:39:17 +0200381 /* Check that the communication with the device is working */
382 rc = hdev->asic_funcs->test_queues(hdev);
383 if (rc) {
384 dev_err(hdev->dev, "Failed to detect if device is alive\n");
385 rc = 0;
386 goto out_disabled;
387 }
388
Oded Gabbayc4d66342019-02-16 00:39:11 +0200389 dev_notice(hdev->dev,
390 "Successfully added device to habanalabs driver\n");
391
392 return 0;
393
Oded Gabbaybe5d9262019-02-16 00:39:15 +0200394release_ctx:
395 if (hl_ctx_put(hdev->kernel_ctx) != 1)
396 dev_err(hdev->dev,
397 "kernel ctx is still alive on initialization failure\n");
Oded Gabbay0861e412019-02-16 00:39:14 +0200398free_ctx:
399 kfree(hdev->kernel_ctx);
Oded Gabbay9494a8d2019-02-16 00:39:17 +0200400cq_fini:
401 for (i = 0 ; i < cq_ready_cnt ; i++)
402 hl_cq_fini(hdev, &hdev->completion_queue[i]);
403 kfree(hdev->completion_queue);
404hw_queues_destroy:
405 hl_hw_queues_destroy(hdev);
Oded Gabbay0861e412019-02-16 00:39:14 +0200406sw_fini:
407 hdev->asic_funcs->sw_fini(hdev);
Oded Gabbay99b9d7b2019-02-16 00:39:13 +0200408early_fini:
409 device_early_fini(hdev);
Oded Gabbayc4d66342019-02-16 00:39:11 +0200410release_device:
411 device_destroy(hclass, hdev->dev->devt);
412 cdev_del(&hdev->cdev);
413out_disabled:
414 hdev->disabled = true;
415 if (hdev->pdev)
416 dev_err(&hdev->pdev->dev,
417 "Failed to initialize hl%d. Device is NOT usable !\n",
418 hdev->id);
419 else
420 pr_err("Failed to initialize hl%d. Device is NOT usable !\n",
421 hdev->id);
422
423 return rc;
424}
425
426/*
427 * hl_device_fini - main tear-down function for habanalabs device
428 *
429 * @hdev: pointer to habanalabs device structure
430 *
431 * Destroy the device, call ASIC fini functions and release the id
432 */
433void hl_device_fini(struct hl_device *hdev)
434{
Oded Gabbay9494a8d2019-02-16 00:39:17 +0200435 int i;
Oded Gabbayc4d66342019-02-16 00:39:11 +0200436 dev_info(hdev->dev, "Removing device\n");
437
438 /* Mark device as disabled */
439 hdev->disabled = true;
440
Oded Gabbaybe5d9262019-02-16 00:39:15 +0200441 hl_cb_pool_fini(hdev);
442
Oded Gabbay0861e412019-02-16 00:39:14 +0200443 /* Release kernel context */
444 if ((hdev->kernel_ctx) && (hl_ctx_put(hdev->kernel_ctx) != 1))
445 dev_err(hdev->dev, "kernel ctx is still alive\n");
446
Oded Gabbay839c4802019-02-16 00:39:16 +0200447 /* Reset the H/W. It will be in idle state after this returns */
448 hdev->asic_funcs->hw_fini(hdev, true);
449
Oded Gabbay9494a8d2019-02-16 00:39:17 +0200450 for (i = 0 ; i < hdev->asic_prop.completion_queues_count ; i++)
451 hl_cq_fini(hdev, &hdev->completion_queue[i]);
452 kfree(hdev->completion_queue);
453
454 hl_hw_queues_destroy(hdev);
455
Oded Gabbay99b9d7b2019-02-16 00:39:13 +0200456 /* Call ASIC S/W finalize function */
457 hdev->asic_funcs->sw_fini(hdev);
458
Oded Gabbayc4d66342019-02-16 00:39:11 +0200459 device_early_fini(hdev);
460
461 /* Hide device from user */
462 device_destroy(hdev->dev->class, hdev->dev->devt);
463 cdev_del(&hdev->cdev);
464
465 pr_info("removed device successfully\n");
466}
467
468/*
469 * hl_poll_timeout_memory - Periodically poll a host memory address
470 * until it is not zero or a timeout occurs
471 * @hdev: pointer to habanalabs device structure
472 * @addr: Address to poll
473 * @timeout_us: timeout in us
474 * @val: Variable to read the value into
475 *
476 * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
477 * case, the last read value at @addr is stored in @val. Must not
478 * be called from atomic context if sleep_us or timeout_us are used.
479 *
480 * The function sleeps for 100us with timeout value of
481 * timeout_us
482 */
483int hl_poll_timeout_memory(struct hl_device *hdev, u64 addr,
484 u32 timeout_us, u32 *val)
485{
486 /*
487 * address in this function points always to a memory location in the
488 * host's (server's) memory. That location is updated asynchronously
489 * either by the direct access of the device or by another core
490 */
491 u32 *paddr = (u32 *) (uintptr_t) addr;
492 ktime_t timeout = ktime_add_us(ktime_get(), timeout_us);
493
494 might_sleep();
495
496 for (;;) {
497 /*
498 * Flush CPU read/write buffers to make sure we read updates
499 * done by other cores or by the device
500 */
501 mb();
502 *val = *paddr;
503 if (*val)
504 break;
505 if (ktime_compare(ktime_get(), timeout) > 0) {
506 *val = *paddr;
507 break;
508 }
509 usleep_range((100 >> 2) + 1, 100);
510 }
511
512 return *val ? 0 : -ETIMEDOUT;
513}
514
515/*
516 * hl_poll_timeout_devicememory - Periodically poll a device memory address
517 * until it is not zero or a timeout occurs
518 * @hdev: pointer to habanalabs device structure
519 * @addr: Device address to poll
520 * @timeout_us: timeout in us
521 * @val: Variable to read the value into
522 *
523 * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
524 * case, the last read value at @addr is stored in @val. Must not
525 * be called from atomic context if sleep_us or timeout_us are used.
526 *
527 * The function sleeps for 100us with timeout value of
528 * timeout_us
529 */
530int hl_poll_timeout_device_memory(struct hl_device *hdev, void __iomem *addr,
531 u32 timeout_us, u32 *val)
532{
533 ktime_t timeout = ktime_add_us(ktime_get(), timeout_us);
534
535 might_sleep();
536
537 for (;;) {
538 *val = readl(addr);
539 if (*val)
540 break;
541 if (ktime_compare(ktime_get(), timeout) > 0) {
542 *val = readl(addr);
543 break;
544 }
545 usleep_range((100 >> 2) + 1, 100);
546 }
547
548 return *val ? 0 : -ETIMEDOUT;
549}
Oded Gabbay99b9d7b2019-02-16 00:39:13 +0200550
551/*
552 * MMIO register access helper functions.
553 */
554
555/*
556 * hl_rreg - Read an MMIO register
557 *
558 * @hdev: pointer to habanalabs device structure
559 * @reg: MMIO register offset (in bytes)
560 *
561 * Returns the value of the MMIO register we are asked to read
562 *
563 */
564inline u32 hl_rreg(struct hl_device *hdev, u32 reg)
565{
566 return readl(hdev->rmmio + reg);
567}
568
569/*
570 * hl_wreg - Write to an MMIO register
571 *
572 * @hdev: pointer to habanalabs device structure
573 * @reg: MMIO register offset (in bytes)
574 * @val: 32-bit value
575 *
576 * Writes the 32-bit value into the MMIO register
577 *
578 */
579inline void hl_wreg(struct hl_device *hdev, u32 reg, u32 val)
580{
581 writel(val, hdev->rmmio + reg);
582}