.. | .. |
---|
31 | 31 | * kernel queues using the first doorbell page reserved for the kernel. |
---|
32 | 32 | */ |
---|
33 | 33 | |
---|
34 | | -static DEFINE_IDA(doorbell_ida); |
---|
35 | | -static unsigned int max_doorbell_slices; |
---|
36 | | - |
---|
37 | 34 | /* |
---|
38 | 35 | * Each device exposes a doorbell aperture, a PCI MMIO aperture that |
---|
39 | 36 | * receives 32-bit writes that are passed to queues as wptr values. |
---|
.. | .. |
---|
84 | 81 | else |
---|
85 | 82 | return -ENOSPC; |
---|
86 | 83 | |
---|
87 | | - if (!max_doorbell_slices || |
---|
88 | | - doorbell_process_limit < max_doorbell_slices) |
---|
89 | | - max_doorbell_slices = doorbell_process_limit; |
---|
| 84 | + if (!kfd->max_doorbell_slices || |
---|
| 85 | + doorbell_process_limit < kfd->max_doorbell_slices) |
---|
| 86 | + kfd->max_doorbell_slices = doorbell_process_limit; |
---|
90 | 87 | |
---|
91 | 88 | kfd->doorbell_base = kfd->shared_resources.doorbell_physical_address + |
---|
92 | 89 | doorbell_start_offset; |
---|
93 | 90 | |
---|
94 | | - kfd->doorbell_id_offset = doorbell_start_offset / sizeof(u32); |
---|
| 91 | + kfd->doorbell_base_dw_offset = doorbell_start_offset / sizeof(u32); |
---|
95 | 92 | |
---|
96 | 93 | kfd->doorbell_kernel_ptr = ioremap(kfd->doorbell_base, |
---|
97 | 94 | kfd_doorbell_process_slice(kfd)); |
---|
.. | .. |
---|
103 | 100 | pr_debug("doorbell base == 0x%08lX\n", |
---|
104 | 101 | (uintptr_t)kfd->doorbell_base); |
---|
105 | 102 | |
---|
106 | | - pr_debug("doorbell_id_offset == 0x%08lX\n", |
---|
107 | | - kfd->doorbell_id_offset); |
---|
| 103 | + pr_debug("doorbell_base_dw_offset == 0x%08lX\n", |
---|
| 104 | + kfd->doorbell_base_dw_offset); |
---|
108 | 105 | |
---|
109 | 106 | pr_debug("doorbell_process_limit == 0x%08lX\n", |
---|
110 | 107 | doorbell_process_limit); |
---|
.. | .. |
---|
130 | 127 | struct vm_area_struct *vma) |
---|
131 | 128 | { |
---|
132 | 129 | phys_addr_t address; |
---|
| 130 | + struct kfd_process_device *pdd; |
---|
133 | 131 | |
---|
134 | 132 | /* |
---|
135 | 133 | * For simplicitly we only allow mapping of the entire doorbell |
---|
.. | .. |
---|
138 | 136 | if (vma->vm_end - vma->vm_start != kfd_doorbell_process_slice(dev)) |
---|
139 | 137 | return -EINVAL; |
---|
140 | 138 | |
---|
141 | | - /* Calculate physical address of doorbell */ |
---|
142 | | - address = kfd_get_process_doorbells(dev, process); |
---|
| 139 | + pdd = kfd_get_process_device_data(dev, process); |
---|
| 140 | + if (!pdd) |
---|
| 141 | + return -EINVAL; |
---|
143 | 142 | |
---|
| 143 | + /* Calculate physical address of doorbell */ |
---|
| 144 | + address = kfd_get_process_doorbells(pdd); |
---|
144 | 145 | vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE | |
---|
145 | 146 | VM_DONTDUMP | VM_PFNMAP; |
---|
146 | 147 | |
---|
.. | .. |
---|
185 | 186 | * Calculating the kernel doorbell offset using the first |
---|
186 | 187 | * doorbell page. |
---|
187 | 188 | */ |
---|
188 | | - *doorbell_off = kfd->doorbell_id_offset + inx; |
---|
| 189 | + *doorbell_off = kfd->doorbell_base_dw_offset + inx; |
---|
189 | 190 | |
---|
190 | 191 | pr_debug("Get kernel queue doorbell\n" |
---|
191 | 192 | " doorbell offset == 0x%08X\n" |
---|
.. | .. |
---|
225 | 226 | } |
---|
226 | 227 | } |
---|
227 | 228 | |
---|
228 | | -unsigned int kfd_doorbell_id_to_offset(struct kfd_dev *kfd, |
---|
229 | | - struct kfd_process *process, |
---|
| 229 | +unsigned int kfd_get_doorbell_dw_offset_in_bar(struct kfd_dev *kfd, |
---|
| 230 | + struct kfd_process_device *pdd, |
---|
230 | 231 | unsigned int doorbell_id) |
---|
231 | 232 | { |
---|
232 | 233 | /* |
---|
233 | | - * doorbell_id_offset accounts for doorbells taken by KGD. |
---|
| 234 | + * doorbell_base_dw_offset accounts for doorbells taken by KGD. |
---|
234 | 235 | * index * kfd_doorbell_process_slice/sizeof(u32) adjusts to |
---|
235 | 236 | * the process's doorbells. The offset returned is in dword |
---|
236 | 237 | * units regardless of the ASIC-dependent doorbell size. |
---|
237 | 238 | */ |
---|
238 | | - return kfd->doorbell_id_offset + |
---|
239 | | - process->doorbell_index |
---|
| 239 | + return kfd->doorbell_base_dw_offset + |
---|
| 240 | + pdd->doorbell_index |
---|
240 | 241 | * kfd_doorbell_process_slice(kfd) / sizeof(u32) + |
---|
241 | 242 | doorbell_id * kfd->device_info->doorbell_size / sizeof(u32); |
---|
242 | 243 | } |
---|
.. | .. |
---|
251 | 252 | |
---|
252 | 253 | } |
---|
253 | 254 | |
---|
254 | | -phys_addr_t kfd_get_process_doorbells(struct kfd_dev *dev, |
---|
255 | | - struct kfd_process *process) |
---|
| 255 | +phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd) |
---|
256 | 256 | { |
---|
257 | | - return dev->doorbell_base + |
---|
258 | | - process->doorbell_index * kfd_doorbell_process_slice(dev); |
---|
| 257 | + return pdd->dev->doorbell_base + |
---|
| 258 | + pdd->doorbell_index * kfd_doorbell_process_slice(pdd->dev); |
---|
259 | 259 | } |
---|
260 | 260 | |
---|
261 | | -int kfd_alloc_process_doorbells(struct kfd_process *process) |
---|
| 261 | +int kfd_alloc_process_doorbells(struct kfd_dev *kfd, unsigned int *doorbell_index) |
---|
262 | 262 | { |
---|
263 | | - int r = ida_simple_get(&doorbell_ida, 1, max_doorbell_slices, |
---|
| 263 | + int r = ida_simple_get(&kfd->doorbell_ida, 1, kfd->max_doorbell_slices, |
---|
264 | 264 | GFP_KERNEL); |
---|
265 | 265 | if (r > 0) |
---|
266 | | - process->doorbell_index = r; |
---|
| 266 | + *doorbell_index = r; |
---|
267 | 267 | |
---|
268 | 268 | return r; |
---|
269 | 269 | } |
---|
270 | 270 | |
---|
271 | | -void kfd_free_process_doorbells(struct kfd_process *process) |
---|
| 271 | +void kfd_free_process_doorbells(struct kfd_dev *kfd, unsigned int doorbell_index) |
---|
272 | 272 | { |
---|
273 | | - if (process->doorbell_index) |
---|
274 | | - ida_simple_remove(&doorbell_ida, process->doorbell_index); |
---|
| 273 | + if (doorbell_index) |
---|
| 274 | + ida_simple_remove(&kfd->doorbell_ida, doorbell_index); |
---|
275 | 275 | } |
---|