1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright 2016-2019 HabanaLabs, Ltd.
8 #include "habanalabs.h"
10 #include <linux/pci.h>
11 #include <linux/delay.h>
13 static void hpriv_release(struct kref *ref)
15 struct hl_fpriv *hpriv;
16 struct hl_device *hdev;
18 hpriv = container_of(ref, struct hl_fpriv, refcount);
22 put_pid(hpriv->taskpid);
26 /* Now the FD is really closed */
27 atomic_dec(&hdev->fd_open_cnt);
29 /* This allows a new user context to open the device */
30 hdev->user_ctx = NULL;
33 void hl_hpriv_get(struct hl_fpriv *hpriv)
35 kref_get(&hpriv->refcount);
38 void hl_hpriv_put(struct hl_fpriv *hpriv)
40 kref_put(&hpriv->refcount, hpriv_release);
44 * hl_device_release - release function for habanalabs device
46 * @inode: pointer to inode structure
47 * @filp: pointer to file structure
49 * Called when process closes an habanalabs device
51 static int hl_device_release(struct inode *inode, struct file *filp)
53 struct hl_fpriv *hpriv = filp->private_data;
55 hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr);
57 filp->private_data = NULL;
64 static const struct file_operations hl_ops = {
66 .open = hl_device_open,
67 .release = hl_device_release
71 * device_setup_cdev - setup cdev and device for habanalabs device
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
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
82 static int device_setup_cdev(struct hl_device *hdev, struct class *hclass,
83 int minor, const struct file_operations *fops)
85 int err, devno = MKDEV(hdev->major, minor);
86 struct cdev *hdev_cdev = &hdev->cdev;
89 name = kasprintf(GFP_KERNEL, "hl%d", hdev->id);
93 cdev_init(hdev_cdev, fops);
94 hdev_cdev->owner = THIS_MODULE;
95 err = cdev_add(hdev_cdev, devno, 1);
97 pr_err("Failed to add char device %s\n", name);
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;
108 dev_set_drvdata(hdev->dev, hdev);
122 * device_early_init - do some early initialization for the habanalabs device
124 * @hdev: pointer to habanalabs device structure
126 * Install the relevant function pointers and call the early_init function,
127 * if such a function exists
129 static int device_early_init(struct hl_device *hdev)
133 switch (hdev->asic_type) {
135 goya_set_asic_funcs(hdev);
136 strlcpy(hdev->asic_name, "GOYA", sizeof(hdev->asic_name));
139 dev_err(hdev->dev, "Unrecognized ASIC type %d\n",
144 rc = hdev->asic_funcs->early_init(hdev);
148 rc = hl_asid_init(hdev);
152 mutex_init(&hdev->fd_open_cnt_lock);
153 atomic_set(&hdev->fd_open_cnt, 0);
158 if (hdev->asic_funcs->early_fini)
159 hdev->asic_funcs->early_fini(hdev);
165 * device_early_fini - finalize all that was done in device_early_init
167 * @hdev: pointer to habanalabs device structure
170 static void device_early_fini(struct hl_device *hdev)
175 if (hdev->asic_funcs->early_fini)
176 hdev->asic_funcs->early_fini(hdev);
178 mutex_destroy(&hdev->fd_open_cnt_lock);
182 * hl_device_suspend - initiate device suspend
184 * @hdev: pointer to habanalabs device structure
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.
190 int hl_device_suspend(struct hl_device *hdev)
194 pci_save_state(hdev->pdev);
196 rc = hdev->asic_funcs->suspend(hdev);
199 "Failed to disable PCI access of device CPU\n");
201 /* Shut down the device */
202 pci_disable_device(hdev->pdev);
203 pci_set_power_state(hdev->pdev, PCI_D3hot);
209 * hl_device_resume - initiate device resume
211 * @hdev: pointer to habanalabs device structure
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.
217 int hl_device_resume(struct hl_device *hdev)
221 pci_set_power_state(hdev->pdev, PCI_D0);
222 pci_restore_state(hdev->pdev);
223 rc = pci_enable_device(hdev->pdev);
226 "Failed to enable PCI device in resume\n");
230 rc = hdev->asic_funcs->resume(hdev);
233 "Failed to enable PCI access from device CPU\n");
241 * hl_device_init - main initialization function for habanalabs device
243 * @hdev: pointer to habanalabs device structure
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
249 int hl_device_init(struct hl_device *hdev, struct class *hclass)
254 rc = device_setup_cdev(hdev, hclass, hdev->id, &hl_ops);
259 /* Initialize ASIC function pointers and perform early init */
260 rc = device_early_init(hdev);
265 * Start calling ASIC initialization. First S/W then H/W and finally
268 rc = hdev->asic_funcs->sw_init(hdev);
272 /* Allocate the kernel context */
273 hdev->kernel_ctx = kzalloc(sizeof(*hdev->kernel_ctx), GFP_KERNEL);
274 if (!hdev->kernel_ctx) {
279 hdev->user_ctx = NULL;
281 rc = hl_ctx_init(hdev, hdev->kernel_ctx, true);
283 dev_err(hdev->dev, "failed to initialize kernel context\n");
287 dev_notice(hdev->dev,
288 "Successfully added device to habanalabs driver\n");
293 kfree(hdev->kernel_ctx);
295 hdev->asic_funcs->sw_fini(hdev);
297 device_early_fini(hdev);
299 device_destroy(hclass, hdev->dev->devt);
300 cdev_del(&hdev->cdev);
302 hdev->disabled = true;
304 dev_err(&hdev->pdev->dev,
305 "Failed to initialize hl%d. Device is NOT usable !\n",
308 pr_err("Failed to initialize hl%d. Device is NOT usable !\n",
315 * hl_device_fini - main tear-down function for habanalabs device
317 * @hdev: pointer to habanalabs device structure
319 * Destroy the device, call ASIC fini functions and release the id
321 void hl_device_fini(struct hl_device *hdev)
323 dev_info(hdev->dev, "Removing device\n");
325 /* Mark device as disabled */
326 hdev->disabled = true;
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");
332 /* Call ASIC S/W finalize function */
333 hdev->asic_funcs->sw_fini(hdev);
335 device_early_fini(hdev);
337 /* Hide device from user */
338 device_destroy(hdev->dev->class, hdev->dev->devt);
339 cdev_del(&hdev->cdev);
341 pr_info("removed device successfully\n");
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
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.
356 * The function sleeps for 100us with timeout value of
359 int hl_poll_timeout_memory(struct hl_device *hdev, u64 addr,
360 u32 timeout_us, u32 *val)
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
367 u32 *paddr = (u32 *) (uintptr_t) addr;
368 ktime_t timeout = ktime_add_us(ktime_get(), timeout_us);
374 * Flush CPU read/write buffers to make sure we read updates
375 * done by other cores or by the device
381 if (ktime_compare(ktime_get(), timeout) > 0) {
385 usleep_range((100 >> 2) + 1, 100);
388 return *val ? 0 : -ETIMEDOUT;
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
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.
403 * The function sleeps for 100us with timeout value of
406 int hl_poll_timeout_device_memory(struct hl_device *hdev, void __iomem *addr,
407 u32 timeout_us, u32 *val)
409 ktime_t timeout = ktime_add_us(ktime_get(), timeout_us);
417 if (ktime_compare(ktime_get(), timeout) > 0) {
421 usleep_range((100 >> 2) + 1, 100);
424 return *val ? 0 : -ETIMEDOUT;
428 * MMIO register access helper functions.
432 * hl_rreg - Read an MMIO register
434 * @hdev: pointer to habanalabs device structure
435 * @reg: MMIO register offset (in bytes)
437 * Returns the value of the MMIO register we are asked to read
440 inline u32 hl_rreg(struct hl_device *hdev, u32 reg)
442 return readl(hdev->rmmio + reg);
446 * hl_wreg - Write to an MMIO register
448 * @hdev: pointer to habanalabs device structure
449 * @reg: MMIO register offset (in bytes)
452 * Writes the 32-bit value into the MMIO register
455 inline void hl_wreg(struct hl_device *hdev, u32 reg, u32 val)
457 writel(val, hdev->rmmio + reg);