summaryrefslogtreecommitdiff
path: root/drivers/misc/habanalabs/device.c
diff options
context:
space:
mode:
authorOmer Shpigelman <oshpigelman@habana.ai>2019-02-16 01:39:22 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-02-18 11:46:46 +0300
commit0feaf86d4e69507ab9b2af7dcc63a6886352d5db (patch)
tree9340f1c492c53b9c92dc0753f9b9c15402fa406f /drivers/misc/habanalabs/device.c
parenteff6f4a0e70b7bcf4674f471a768860a74e638a6 (diff)
downloadlinux-0feaf86d4e69507ab9b2af7dcc63a6886352d5db.tar.xz
habanalabs: add virtual memory and MMU modules
This patch adds the Virtual Memory and MMU modules. Goya has an internal MMU which provides process isolation on the internal DDR. The internal MMU also performs translations for transactions that go from Goya to the Host. The driver is responsible for allocating and freeing memory on the DDR upon user request. It also provides an interface to map and unmap DDR and Host memory to the device address space. The MMU in Goya supports 3-level and 4-level page tables. With 3-level, the size of each page is 2MB, while with 4-level the size of each page is 4KB. In the DDR, the physical pages are always 2MB. Reviewed-by: Mike Rapoport <rppt@linux.ibm.com> Signed-off-by: Omer Shpigelman <oshpigelman@habana.ai> Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/habanalabs/device.c')
-rw-r--r--drivers/misc/habanalabs/device.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/misc/habanalabs/device.c b/drivers/misc/habanalabs/device.c
index cc5f068df597..d0929022655b 100644
--- a/drivers/misc/habanalabs/device.c
+++ b/drivers/misc/habanalabs/device.c
@@ -615,8 +615,10 @@ again:
/* Reset the H/W. It will be in idle state after this returns */
hdev->asic_funcs->hw_fini(hdev, hard_reset);
- if (hard_reset)
+ if (hard_reset) {
+ hl_vm_fini(hdev);
hl_eq_reset(hdev, &hdev->event_queue);
+ }
/* Re-initialize PI,CI to 0 in all queues (hw queue, cq) */
hl_hw_queue_reset(hdev, hard_reset);
@@ -677,6 +679,13 @@ again:
goto out_err;
}
+ rc = hl_vm_init(hdev);
+ if (rc) {
+ dev_err(hdev->dev,
+ "Failed to init memory module after hard reset\n");
+ goto out_err;
+ }
+
hl_set_max_power(hdev, hdev->max_power);
hdev->hard_reset_pending = false;
@@ -861,6 +870,13 @@ int hl_device_init(struct hl_device *hdev, struct class *hclass)
hdev->asic_name,
hdev->asic_prop.dram_size / 1024 / 1024 / 1024);
+ rc = hl_vm_init(hdev);
+ if (rc) {
+ dev_err(hdev->dev, "Failed to initialize memory module\n");
+ rc = 0;
+ goto out_disabled;
+ }
+
/*
* hl_hwmon_init must be called after device_late_init, because only
* there we get the information from the device about which
@@ -977,6 +993,8 @@ void hl_device_fini(struct hl_device *hdev)
/* Reset the H/W. It will be in idle state after this returns */
hdev->asic_funcs->hw_fini(hdev, true);
+ hl_vm_fini(hdev);
+
hl_eq_fini(hdev, &hdev->event_queue);
for (i = 0 ; i < hdev->asic_prop.completion_queues_count ; i++)