aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1508-drm-amdkfd-Add-flag-to-allocate-a-doorbell-BO.patch
blob: c007b3fbdd128cd9f47f8909659c391b645106b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
From 9370d4e443c64b682c606a43535772086f6790f3 Mon Sep 17 00:00:00 2001
From: Felix Kuehling <Felix.Kuehling@amd.com>
Date: Fri, 16 Sep 2016 15:53:34 -0400
Subject: [PATCH 1508/4131] drm/amdkfd: Add flag to allocate a doorbell BO

Change-Id: Ib59d36572da42382c6c55fdcf57ecec04faaca66
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
---
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c  | 12 +++++++++++-
 drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c | 26 +++++++++++++-------------
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h     |  1 +
 3 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index cbc7f69..d42b415 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -1257,6 +1257,11 @@ static uint32_t kfd_convert_user_mem_alloction_flags(
 		kernel_allocation_flags = ALLOC_MEM_FLAGS_USERPTR;
 		goto out;
 	}
+	/* Allocate doorbell BO */
+	if (userspace_flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL) {
+		kernel_allocation_flags = ALLOC_MEM_FLAGS_DOORBELL;
+		goto out;
+	}
 
 out:
 	if (userspace_flags & KFD_IOC_ALLOC_MEM_FLAGS_DGPU_AQL_QUEUE_MEM)
@@ -1300,7 +1305,12 @@ static int kfd_ioctl_alloc_memory_of_gpu_new(struct file *filep,
 	if (IS_ERR(pdd) < 0)
 		return PTR_ERR(pdd);
 
-	offset = args->mmap_offset;
+	if (args->flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL) {
+		if (args->size != kfd_doorbell_process_slice())
+			return -EINVAL;
+		offset = kfd_get_process_doorbells(dev, p);
+	} else
+		offset = args->mmap_offset;
 	err = dev->kfd2kgd->alloc_memory_of_gpu(
 		dev->kgd, args->va_addr, args->size,
 		pdd->vm, (struct kgd_mem **) &mem, &offset,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
index d6a7e2a..9387b1d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
@@ -51,7 +51,7 @@
  */
 
 /* # of doorbell bytes allocated for each process. */
-static inline size_t doorbell_process_allocation(void)
+size_t kfd_doorbell_process_slice(void)
 {
 	return roundup(KFD_SIZE_OF_DOORBELL_IN_BYTES *
 			KFD_MAX_NUM_OF_QUEUES_PER_PROCESS,
@@ -73,16 +73,16 @@ void kfd_doorbell_init(struct kfd_dev *kfd)
 
 	doorbell_start_offset =
 			roundup(kfd->shared_resources.doorbell_start_offset,
-					doorbell_process_allocation());
+					kfd_doorbell_process_slice());
 
 	doorbell_aperture_size =
 			rounddown(kfd->shared_resources.doorbell_aperture_size,
-					doorbell_process_allocation());
+					kfd_doorbell_process_slice());
 
 	if (doorbell_aperture_size > doorbell_start_offset)
 		doorbell_process_limit =
 			(doorbell_aperture_size - doorbell_start_offset) /
-						doorbell_process_allocation();
+						kfd_doorbell_process_slice();
 	else
 		doorbell_process_limit = 0;
 
@@ -93,7 +93,7 @@ void kfd_doorbell_init(struct kfd_dev *kfd)
 	kfd->doorbell_process_limit = doorbell_process_limit - 1;
 
 	kfd->doorbell_kernel_ptr = ioremap(kfd->doorbell_base,
-						doorbell_process_allocation());
+						kfd_doorbell_process_slice());
 
 	BUG_ON(!kfd->doorbell_kernel_ptr);
 
@@ -126,7 +126,7 @@ int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma)
 	 * For simplicitly we only allow mapping of the entire doorbell
 	 * allocation of a single device & process.
 	 */
-	if (vma->vm_end - vma->vm_start != doorbell_process_allocation())
+	if (vma->vm_end - vma->vm_start != kfd_doorbell_process_slice())
 		return -EINVAL;
 
 	/* Find kfd device according to gpu id */
@@ -148,13 +148,13 @@ int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma)
 		 "     vm_flags            == 0x%04lX\n"
 		 "     size                == 0x%04lX\n",
 		 (unsigned long long) vma->vm_start, address, vma->vm_flags,
-		 doorbell_process_allocation());
+		 kfd_doorbell_process_slice());
 
 
 	return io_remap_pfn_range(vma,
 				vma->vm_start,
 				address >> PAGE_SHIFT,
-				doorbell_process_allocation(),
+				kfd_doorbell_process_slice(),
 				vma->vm_page_prot);
 }
 
@@ -181,7 +181,7 @@ u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
 	 * Calculating the kernel doorbell offset using "faked" kernel
 	 * pasid that allocated for kernel queues only
 	 */
-	*doorbell_off = KERNEL_DOORBELL_PASID * (doorbell_process_allocation() /
+	*doorbell_off = KERNEL_DOORBELL_PASID * (kfd_doorbell_process_slice() /
 							sizeof(u32)) + inx;
 
 	pr_debug("kfd: get kernel queue doorbell\n"
@@ -223,11 +223,11 @@ unsigned int kfd_queue_id_to_doorbell(struct kfd_dev *kfd,
 {
 	/*
 	 * doorbell_id_offset accounts for doorbells taken by KGD.
-	 * pasid * doorbell_process_allocation/sizeof(u32) adjusts
+	 * pasid * kfd_doorbell_process_slice/sizeof(u32) adjusts
 	 * to the process's doorbells
 	 */
 	return kfd->doorbell_id_offset +
-		process->pasid * (doorbell_process_allocation()/sizeof(u32)) +
+		process->pasid * (kfd_doorbell_process_slice()/sizeof(u32)) +
 		queue_id;
 }
 
@@ -235,7 +235,7 @@ uint64_t kfd_get_number_elems(struct kfd_dev *kfd)
 {
 	uint64_t num_of_elems = (kfd->shared_resources.doorbell_aperture_size -
 				kfd->shared_resources.doorbell_start_offset) /
-					doorbell_process_allocation() + 1;
+					kfd_doorbell_process_slice() + 1;
 
 	return num_of_elems;
 
@@ -245,5 +245,5 @@ phys_addr_t kfd_get_process_doorbells(struct kfd_dev *dev,
 					struct kfd_process *process)
 {
 	return dev->doorbell_base +
-		process->pasid * doorbell_process_allocation();
+		process->pasid * kfd_doorbell_process_slice();
 }
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 4eb7354..b4b7281 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -744,6 +744,7 @@ unsigned int kfd_pasid_alloc(void);
 void kfd_pasid_free(unsigned int pasid);
 
 /* Doorbells */
+size_t kfd_doorbell_process_slice(void);
 void kfd_doorbell_init(struct kfd_dev *kfd);
 int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma);
 u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
-- 
2.7.4