1*e65e175bSOded Gabbay // SPDX-License-Identifier: GPL-2.0
2*e65e175bSOded Gabbay 
3*e65e175bSOded Gabbay /*
4*e65e175bSOded Gabbay  * Copyright 2016-2019 HabanaLabs, Ltd.
5*e65e175bSOded Gabbay  * All Rights Reserved.
6*e65e175bSOded Gabbay  */
7*e65e175bSOded Gabbay 
8*e65e175bSOded Gabbay #include "habanalabs.h"
9*e65e175bSOded Gabbay 
10*e65e175bSOded Gabbay #include <linux/slab.h>
11*e65e175bSOded Gabbay 
hl_asid_init(struct hl_device * hdev)12*e65e175bSOded Gabbay int hl_asid_init(struct hl_device *hdev)
13*e65e175bSOded Gabbay {
14*e65e175bSOded Gabbay 	hdev->asid_bitmap = bitmap_zalloc(hdev->asic_prop.max_asid, GFP_KERNEL);
15*e65e175bSOded Gabbay 	if (!hdev->asid_bitmap)
16*e65e175bSOded Gabbay 		return -ENOMEM;
17*e65e175bSOded Gabbay 
18*e65e175bSOded Gabbay 	mutex_init(&hdev->asid_mutex);
19*e65e175bSOded Gabbay 
20*e65e175bSOded Gabbay 	/* ASID 0 is reserved for the kernel driver and device CPU */
21*e65e175bSOded Gabbay 	set_bit(0, hdev->asid_bitmap);
22*e65e175bSOded Gabbay 
23*e65e175bSOded Gabbay 	return 0;
24*e65e175bSOded Gabbay }
25*e65e175bSOded Gabbay 
hl_asid_fini(struct hl_device * hdev)26*e65e175bSOded Gabbay void hl_asid_fini(struct hl_device *hdev)
27*e65e175bSOded Gabbay {
28*e65e175bSOded Gabbay 	mutex_destroy(&hdev->asid_mutex);
29*e65e175bSOded Gabbay 	bitmap_free(hdev->asid_bitmap);
30*e65e175bSOded Gabbay }
31*e65e175bSOded Gabbay 
hl_asid_alloc(struct hl_device * hdev)32*e65e175bSOded Gabbay unsigned long hl_asid_alloc(struct hl_device *hdev)
33*e65e175bSOded Gabbay {
34*e65e175bSOded Gabbay 	unsigned long found;
35*e65e175bSOded Gabbay 
36*e65e175bSOded Gabbay 	mutex_lock(&hdev->asid_mutex);
37*e65e175bSOded Gabbay 
38*e65e175bSOded Gabbay 	found = find_first_zero_bit(hdev->asid_bitmap,
39*e65e175bSOded Gabbay 					hdev->asic_prop.max_asid);
40*e65e175bSOded Gabbay 	if (found == hdev->asic_prop.max_asid)
41*e65e175bSOded Gabbay 		found = 0;
42*e65e175bSOded Gabbay 	else
43*e65e175bSOded Gabbay 		set_bit(found, hdev->asid_bitmap);
44*e65e175bSOded Gabbay 
45*e65e175bSOded Gabbay 	mutex_unlock(&hdev->asid_mutex);
46*e65e175bSOded Gabbay 
47*e65e175bSOded Gabbay 	return found;
48*e65e175bSOded Gabbay }
49*e65e175bSOded Gabbay 
hl_asid_free(struct hl_device * hdev,unsigned long asid)50*e65e175bSOded Gabbay void hl_asid_free(struct hl_device *hdev, unsigned long asid)
51*e65e175bSOded Gabbay {
52*e65e175bSOded Gabbay 	if (asid == HL_KERNEL_ASID_ID || asid >= hdev->asic_prop.max_asid) {
53*e65e175bSOded Gabbay 		dev_crit(hdev->dev, "Invalid ASID %lu", asid);
54*e65e175bSOded Gabbay 		return;
55*e65e175bSOded Gabbay 	}
56*e65e175bSOded Gabbay 
57*e65e175bSOded Gabbay 	clear_bit(asid, hdev->asid_bitmap);
58*e65e175bSOded Gabbay }
59