| .. | .. |
|---|
| 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 | } |
|---|