diff options
author | Ben Goz <ben.goz@amd.com> | 2014-12-02 09:38:57 -0500 |
---|---|---|
committer | Oded Gabbay <oded.gabbay@amd.com> | 2014-12-02 09:38:57 -0500 |
commit | 6898f0a568742b3d751e82899b8e1b0fe1b134f5 (patch) | |
tree | d1eff33cfd2258992b74808fdbdf0f180c6790f7 /drivers/gpu/drm/amd | |
parent | 443fbd5f115feba160a8d7ed6ac708cb91e3b955 (diff) |
drm/amdkfd: Add initial VI support for KQ
This patch starts to add support for the VI APU in the KQ (kernel queue)
module.
Because most (more than 90%) of the KQ code is shared among AMD's APUs, we
chose a design that performs most/all the code in the shared KQ file
(kfd_kernel_queue.c). If there is H/W specific code to be executed,
than it is written in an asic-specific extension function for that H/W.
That asic-specific extension function is called from the shared function at the
appropriate time. This requires that for every asic-specific extension function
that is implemented in a specific ASIC, there will be an equivalent
implementation in ALL ASICs, even if those implementations are just stubs.
That way we achieve:
- Maintainability: by having one copy of most of the code, we only need to
fix bugs at one locations
- Readability: very clear what is the shared code and what is done per ASIC
- Extensibility: very easy to add new H/W specific files/functions
Signed-off-by: Ben Goz <ben.goz@amd.com>
Signed-off-by: Oded Gabbay <oded.gabbay@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/Makefile | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_cik.c | 44 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_vi.c | 56 |
5 files changed, 127 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index 7558683c6935..cd09c05ee7e4 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile | |||
@@ -8,7 +8,8 @@ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ | |||
8 | kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ | 8 | kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ |
9 | kfd_process.o kfd_queue.o kfd_mqd_manager.o \ | 9 | kfd_process.o kfd_queue.o kfd_mqd_manager.o \ |
10 | kfd_mqd_manager_cik.o kfd_mqd_manager_vi.o \ | 10 | kfd_mqd_manager_cik.o kfd_mqd_manager_vi.o \ |
11 | kfd_kernel_queue.o kfd_packet_manager.o \ | 11 | kfd_kernel_queue.o kfd_kernel_queue_cik.o \ |
12 | kfd_kernel_queue_vi.o kfd_packet_manager.o \ | ||
12 | kfd_process_queue_manager.o kfd_device_queue_manager.o \ | 13 | kfd_process_queue_manager.o kfd_device_queue_manager.o \ |
13 | kfd_device_queue_manager_cik.o kfd_device_queue_manager_vi.o \ | 14 | kfd_device_queue_manager_cik.o kfd_device_queue_manager_vi.o \ |
14 | kfd_interrupt.o | 15 | kfd_interrupt.o |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c index 731635dace90..75950ed7a1bc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c | |||
@@ -73,13 +73,16 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev, | |||
73 | goto err_get_kernel_doorbell; | 73 | goto err_get_kernel_doorbell; |
74 | 74 | ||
75 | retval = kfd_gtt_sa_allocate(dev, queue_size, &kq->pq); | 75 | retval = kfd_gtt_sa_allocate(dev, queue_size, &kq->pq); |
76 | |||
77 | if (retval != 0) | 76 | if (retval != 0) |
78 | goto err_pq_allocate_vidmem; | 77 | goto err_pq_allocate_vidmem; |
79 | 78 | ||
80 | kq->pq_kernel_addr = kq->pq->cpu_ptr; | 79 | kq->pq_kernel_addr = kq->pq->cpu_ptr; |
81 | kq->pq_gpu_addr = kq->pq->gpu_addr; | 80 | kq->pq_gpu_addr = kq->pq->gpu_addr; |
82 | 81 | ||
82 | retval = kq->ops_asic_specific.initialize(kq, dev, type, queue_size); | ||
83 | if (retval == false) | ||
84 | goto err_eop_allocate_vidmem; | ||
85 | |||
83 | retval = kfd_gtt_sa_allocate(dev, sizeof(*kq->rptr_kernel), | 86 | retval = kfd_gtt_sa_allocate(dev, sizeof(*kq->rptr_kernel), |
84 | &kq->rptr_mem); | 87 | &kq->rptr_mem); |
85 | 88 | ||
@@ -111,6 +114,8 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev, | |||
111 | prop.queue_address = kq->pq_gpu_addr; | 114 | prop.queue_address = kq->pq_gpu_addr; |
112 | prop.read_ptr = (uint32_t *) kq->rptr_gpu_addr; | 115 | prop.read_ptr = (uint32_t *) kq->rptr_gpu_addr; |
113 | prop.write_ptr = (uint32_t *) kq->wptr_gpu_addr; | 116 | prop.write_ptr = (uint32_t *) kq->wptr_gpu_addr; |
117 | prop.eop_ring_buffer_address = kq->eop_gpu_addr; | ||
118 | prop.eop_ring_buffer_size = PAGE_SIZE; | ||
114 | 119 | ||
115 | if (init_queue(&kq->queue, prop) != 0) | 120 | if (init_queue(&kq->queue, prop) != 0) |
116 | goto err_init_queue; | 121 | goto err_init_queue; |
@@ -156,6 +161,8 @@ err_init_queue: | |||
156 | err_wptr_allocate_vidmem: | 161 | err_wptr_allocate_vidmem: |
157 | kfd_gtt_sa_free(dev, kq->rptr_mem); | 162 | kfd_gtt_sa_free(dev, kq->rptr_mem); |
158 | err_rptr_allocate_vidmem: | 163 | err_rptr_allocate_vidmem: |
164 | kfd_gtt_sa_free(dev, kq->eop_mem); | ||
165 | err_eop_allocate_vidmem: | ||
159 | kfd_gtt_sa_free(dev, kq->pq); | 166 | kfd_gtt_sa_free(dev, kq->pq); |
160 | err_pq_allocate_vidmem: | 167 | err_pq_allocate_vidmem: |
161 | pr_err("kfd: error init pq\n"); | 168 | pr_err("kfd: error init pq\n"); |
@@ -182,6 +189,7 @@ static void uninitialize(struct kernel_queue *kq) | |||
182 | 189 | ||
183 | kfd_gtt_sa_free(kq->dev, kq->rptr_mem); | 190 | kfd_gtt_sa_free(kq->dev, kq->rptr_mem); |
184 | kfd_gtt_sa_free(kq->dev, kq->wptr_mem); | 191 | kfd_gtt_sa_free(kq->dev, kq->wptr_mem); |
192 | kq->ops_asic_specific.uninitialize(kq); | ||
185 | kfd_gtt_sa_free(kq->dev, kq->pq); | 193 | kfd_gtt_sa_free(kq->dev, kq->pq); |
186 | kfd_release_kernel_doorbell(kq->dev, | 194 | kfd_release_kernel_doorbell(kq->dev, |
187 | kq->queue->properties.doorbell_ptr); | 195 | kq->queue->properties.doorbell_ptr); |
@@ -300,6 +308,13 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev, | |||
300 | kq->ops.sync_with_hw = sync_with_hw; | 308 | kq->ops.sync_with_hw = sync_with_hw; |
301 | kq->ops.rollback_packet = rollback_packet; | 309 | kq->ops.rollback_packet = rollback_packet; |
302 | 310 | ||
311 | switch (dev->device_info->asic_family) { | ||
312 | case CHIP_CARRIZO: | ||
313 | kernel_queue_init_vi(&kq->ops_asic_specific); | ||
314 | case CHIP_KAVERI: | ||
315 | kernel_queue_init_cik(&kq->ops_asic_specific); | ||
316 | } | ||
317 | |||
303 | if (kq->ops.initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) { | 318 | if (kq->ops.initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) { |
304 | pr_err("kfd: failed to init kernel queue\n"); | 319 | pr_err("kfd: failed to init kernel queue\n"); |
305 | kfree(kq); | 320 | kfree(kq); |
@@ -324,7 +339,7 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev) | |||
324 | 339 | ||
325 | BUG_ON(!dev); | 340 | BUG_ON(!dev); |
326 | 341 | ||
327 | pr_debug("kfd: starting kernel queue test\n"); | 342 | pr_err("kfd: starting kernel queue test\n"); |
328 | 343 | ||
329 | kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ); | 344 | kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ); |
330 | BUG_ON(!kq); | 345 | BUG_ON(!kq); |
@@ -336,7 +351,7 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev) | |||
336 | kq->ops.submit_packet(kq); | 351 | kq->ops.submit_packet(kq); |
337 | kq->ops.sync_with_hw(kq, 1000); | 352 | kq->ops.sync_with_hw(kq, 1000); |
338 | 353 | ||
339 | pr_debug("kfd: ending kernel queue test\n"); | 354 | pr_err("kfd: ending kernel queue test\n"); |
340 | } | 355 | } |
341 | 356 | ||
342 | 357 | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h index e01b77b28500..2659d936ba73 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h | |||
@@ -68,6 +68,7 @@ struct kernel_queue_ops { | |||
68 | 68 | ||
69 | struct kernel_queue { | 69 | struct kernel_queue { |
70 | struct kernel_queue_ops ops; | 70 | struct kernel_queue_ops ops; |
71 | struct kernel_queue_ops ops_asic_specific; | ||
71 | 72 | ||
72 | /* data */ | 73 | /* data */ |
73 | struct kfd_dev *dev; | 74 | struct kfd_dev *dev; |
@@ -85,6 +86,9 @@ struct kernel_queue { | |||
85 | struct kfd_mem_obj *pq; | 86 | struct kfd_mem_obj *pq; |
86 | uint64_t pq_gpu_addr; | 87 | uint64_t pq_gpu_addr; |
87 | uint32_t *pq_kernel_addr; | 88 | uint32_t *pq_kernel_addr; |
89 | struct kfd_mem_obj *eop_mem; | ||
90 | uint64_t eop_gpu_addr; | ||
91 | uint32_t *eop_kernel_addr; | ||
88 | 92 | ||
89 | struct kfd_mem_obj *fence_mem_obj; | 93 | struct kfd_mem_obj *fence_mem_obj; |
90 | uint64_t fence_gpu_addr; | 94 | uint64_t fence_gpu_addr; |
@@ -93,4 +97,7 @@ struct kernel_queue { | |||
93 | struct list_head list; | 97 | struct list_head list; |
94 | }; | 98 | }; |
95 | 99 | ||
100 | void kernel_queue_init_cik(struct kernel_queue_ops *ops); | ||
101 | void kernel_queue_init_vi(struct kernel_queue_ops *ops); | ||
102 | |||
96 | #endif /* KFD_KERNEL_QUEUE_H_ */ | 103 | #endif /* KFD_KERNEL_QUEUE_H_ */ |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_cik.c new file mode 100644 index 000000000000..a90eb440b1fb --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_cik.c | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * Copyright 2014 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include "kfd_kernel_queue.h" | ||
25 | |||
26 | static bool initialize_cik(struct kernel_queue *kq, struct kfd_dev *dev, | ||
27 | enum kfd_queue_type type, unsigned int queue_size); | ||
28 | static void uninitialize_cik(struct kernel_queue *kq); | ||
29 | |||
30 | void kernel_queue_init_cik(struct kernel_queue_ops *ops) | ||
31 | { | ||
32 | ops->initialize = initialize_cik; | ||
33 | ops->uninitialize = uninitialize_cik; | ||
34 | } | ||
35 | |||
36 | static bool initialize_cik(struct kernel_queue *kq, struct kfd_dev *dev, | ||
37 | enum kfd_queue_type type, unsigned int queue_size) | ||
38 | { | ||
39 | return true; | ||
40 | } | ||
41 | |||
42 | static void uninitialize_cik(struct kernel_queue *kq) | ||
43 | { | ||
44 | } | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_vi.c new file mode 100644 index 000000000000..f1d48281e322 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_vi.c | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * Copyright 2014 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include "kfd_kernel_queue.h" | ||
25 | |||
26 | static bool initialize_vi(struct kernel_queue *kq, struct kfd_dev *dev, | ||
27 | enum kfd_queue_type type, unsigned int queue_size); | ||
28 | static void uninitialize_vi(struct kernel_queue *kq); | ||
29 | |||
30 | void kernel_queue_init_vi(struct kernel_queue_ops *ops) | ||
31 | { | ||
32 | ops->initialize = initialize_vi; | ||
33 | ops->uninitialize = uninitialize_vi; | ||
34 | } | ||
35 | |||
36 | static bool initialize_vi(struct kernel_queue *kq, struct kfd_dev *dev, | ||
37 | enum kfd_queue_type type, unsigned int queue_size) | ||
38 | { | ||
39 | int retval; | ||
40 | |||
41 | retval = kfd_gtt_sa_allocate(dev, PAGE_SIZE, &kq->eop_mem); | ||
42 | if (retval != 0) | ||
43 | return false; | ||
44 | |||
45 | kq->eop_gpu_addr = kq->eop_mem->gpu_addr; | ||
46 | kq->eop_kernel_addr = kq->eop_mem->cpu_ptr; | ||
47 | |||
48 | memset(kq->eop_kernel_addr, 0, PAGE_SIZE); | ||
49 | |||
50 | return true; | ||
51 | } | ||
52 | |||
53 | static void uninitialize_vi(struct kernel_queue *kq) | ||
54 | { | ||
55 | kfd_gtt_sa_free(kq->dev, kq->eop_mem); | ||
56 | } | ||