diff options
author | Dave Airlie <airlied@redhat.com> | 2015-03-30 23:36:25 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-03-30 23:36:25 -0400 |
commit | b1f389ecc20b95f0f64515588d3736e85146848f (patch) | |
tree | c8a37c4ad4af5c8b9dd770be141e3973b42d05e5 /drivers | |
parent | 517bc04582afbd3cd441d363656a064d0e285fbe (diff) | |
parent | cea405b172e3b1fd2cf9da5ec05c7d808d6af03d (diff) |
Merge tag 'drm-amdkfd-next-2015-03-25' of git://people.freedesktop.org/~gabbayo/linux into drm-next
- Allow amdkfd to work with multiple kgd instances. This is in preparation for
AMD's new open source kernel graphic driver (amdgpu), and for the new
AMD APU, Carrizo.
- Convert timestamping to use 64bit time accessors
- Three other minor changes.
* tag 'drm-amdkfd-next-2015-03-25' of git://people.freedesktop.org/~gabbayo/linux:
drm/amdkfd: Add multiple kgd support
drm/amdkfd: Convert timestamping to use 64bit time accessors
drm/amdkfd: add debug prints for process teardown
drm/amdkfd: Remove unused field from struct qcm_process_device
drm/amdkfd: rename fence_wait_timeout
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_device.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_module.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_process.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/include/kgd_kfd_interface.h | 64 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_kfd.c | 10 |
11 files changed, 103 insertions, 93 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 5c50aa8a8908..19a4fba46e4e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | |||
@@ -435,21 +435,22 @@ static int kfd_ioctl_get_clock_counters(struct file *filep, | |||
435 | { | 435 | { |
436 | struct kfd_ioctl_get_clock_counters_args *args = data; | 436 | struct kfd_ioctl_get_clock_counters_args *args = data; |
437 | struct kfd_dev *dev; | 437 | struct kfd_dev *dev; |
438 | struct timespec time; | 438 | struct timespec64 time; |
439 | 439 | ||
440 | dev = kfd_device_by_id(args->gpu_id); | 440 | dev = kfd_device_by_id(args->gpu_id); |
441 | if (dev == NULL) | 441 | if (dev == NULL) |
442 | return -EINVAL; | 442 | return -EINVAL; |
443 | 443 | ||
444 | /* Reading GPU clock counter from KGD */ | 444 | /* Reading GPU clock counter from KGD */ |
445 | args->gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd); | 445 | args->gpu_clock_counter = |
446 | dev->kfd2kgd->get_gpu_clock_counter(dev->kgd); | ||
446 | 447 | ||
447 | /* No access to rdtsc. Using raw monotonic time */ | 448 | /* No access to rdtsc. Using raw monotonic time */ |
448 | getrawmonotonic(&time); | 449 | getrawmonotonic64(&time); |
449 | args->cpu_clock_counter = (uint64_t)timespec_to_ns(&time); | 450 | args->cpu_clock_counter = (uint64_t)timespec64_to_ns(&time); |
450 | 451 | ||
451 | get_monotonic_boottime(&time); | 452 | get_monotonic_boottime64(&time); |
452 | args->system_clock_counter = (uint64_t)timespec_to_ns(&time); | 453 | args->system_clock_counter = (uint64_t)timespec64_to_ns(&time); |
453 | 454 | ||
454 | /* Since the counter is in nano-seconds we use 1GHz frequency */ | 455 | /* Since the counter is in nano-seconds we use 1GHz frequency */ |
455 | args->system_clock_freq = 1000000000; | 456 | args->system_clock_freq = 1000000000; |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 5bc32c26b989..ca7f2d3af2ff 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c | |||
@@ -94,7 +94,8 @@ static const struct kfd_device_info *lookup_device_info(unsigned short did) | |||
94 | return NULL; | 94 | return NULL; |
95 | } | 95 | } |
96 | 96 | ||
97 | struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev) | 97 | struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, |
98 | struct pci_dev *pdev, const struct kfd2kgd_calls *f2g) | ||
98 | { | 99 | { |
99 | struct kfd_dev *kfd; | 100 | struct kfd_dev *kfd; |
100 | 101 | ||
@@ -112,6 +113,11 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev) | |||
112 | kfd->device_info = device_info; | 113 | kfd->device_info = device_info; |
113 | kfd->pdev = pdev; | 114 | kfd->pdev = pdev; |
114 | kfd->init_complete = false; | 115 | kfd->init_complete = false; |
116 | kfd->kfd2kgd = f2g; | ||
117 | |||
118 | mutex_init(&kfd->doorbell_mutex); | ||
119 | memset(&kfd->doorbell_available_index, 0, | ||
120 | sizeof(kfd->doorbell_available_index)); | ||
115 | 121 | ||
116 | return kfd; | 122 | return kfd; |
117 | } | 123 | } |
@@ -200,8 +206,9 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, | |||
200 | /* add another 512KB for all other allocations on gart (HPD, fences) */ | 206 | /* add another 512KB for all other allocations on gart (HPD, fences) */ |
201 | size += 512 * 1024; | 207 | size += 512 * 1024; |
202 | 208 | ||
203 | if (kfd2kgd->init_gtt_mem_allocation(kfd->kgd, size, &kfd->gtt_mem, | 209 | if (kfd->kfd2kgd->init_gtt_mem_allocation( |
204 | &kfd->gtt_start_gpu_addr, &kfd->gtt_start_cpu_ptr)) { | 210 | kfd->kgd, size, &kfd->gtt_mem, |
211 | &kfd->gtt_start_gpu_addr, &kfd->gtt_start_cpu_ptr)){ | ||
205 | dev_err(kfd_device, | 212 | dev_err(kfd_device, |
206 | "Could not allocate %d bytes for device (%x:%x)\n", | 213 | "Could not allocate %d bytes for device (%x:%x)\n", |
207 | size, kfd->pdev->vendor, kfd->pdev->device); | 214 | size, kfd->pdev->vendor, kfd->pdev->device); |
@@ -270,7 +277,7 @@ device_iommu_pasid_error: | |||
270 | kfd_topology_add_device_error: | 277 | kfd_topology_add_device_error: |
271 | kfd_gtt_sa_fini(kfd); | 278 | kfd_gtt_sa_fini(kfd); |
272 | kfd_gtt_sa_init_error: | 279 | kfd_gtt_sa_init_error: |
273 | kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem); | 280 | kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem); |
274 | dev_err(kfd_device, | 281 | dev_err(kfd_device, |
275 | "device (%x:%x) NOT added due to errors\n", | 282 | "device (%x:%x) NOT added due to errors\n", |
276 | kfd->pdev->vendor, kfd->pdev->device); | 283 | kfd->pdev->vendor, kfd->pdev->device); |
@@ -285,7 +292,7 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd) | |||
285 | amd_iommu_free_device(kfd->pdev); | 292 | amd_iommu_free_device(kfd->pdev); |
286 | kfd_topology_remove_device(kfd); | 293 | kfd_topology_remove_device(kfd); |
287 | kfd_gtt_sa_fini(kfd); | 294 | kfd_gtt_sa_fini(kfd); |
288 | kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem); | 295 | kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem); |
289 | } | 296 | } |
290 | 297 | ||
291 | kfree(kfd); | 298 | kfree(kfd); |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 910ff8ab9c9c..d7174300f501 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | |||
@@ -82,7 +82,8 @@ static inline unsigned int get_pipes_num_cpsch(void) | |||
82 | void program_sh_mem_settings(struct device_queue_manager *dqm, | 82 | void program_sh_mem_settings(struct device_queue_manager *dqm, |
83 | struct qcm_process_device *qpd) | 83 | struct qcm_process_device *qpd) |
84 | { | 84 | { |
85 | return kfd2kgd->program_sh_mem_settings(dqm->dev->kgd, qpd->vmid, | 85 | return dqm->dev->kfd2kgd->program_sh_mem_settings( |
86 | dqm->dev->kgd, qpd->vmid, | ||
86 | qpd->sh_mem_config, | 87 | qpd->sh_mem_config, |
87 | qpd->sh_mem_ape1_base, | 88 | qpd->sh_mem_ape1_base, |
88 | qpd->sh_mem_ape1_limit, | 89 | qpd->sh_mem_ape1_limit, |
@@ -457,9 +458,12 @@ set_pasid_vmid_mapping(struct device_queue_manager *dqm, unsigned int pasid, | |||
457 | { | 458 | { |
458 | uint32_t pasid_mapping; | 459 | uint32_t pasid_mapping; |
459 | 460 | ||
460 | pasid_mapping = (pasid == 0) ? 0 : (uint32_t)pasid | | 461 | pasid_mapping = (pasid == 0) ? 0 : |
461 | ATC_VMID_PASID_MAPPING_VALID; | 462 | (uint32_t)pasid | |
462 | return kfd2kgd->set_pasid_vmid_mapping(dqm->dev->kgd, pasid_mapping, | 463 | ATC_VMID_PASID_MAPPING_VALID; |
464 | |||
465 | return dqm->dev->kfd2kgd->set_pasid_vmid_mapping( | ||
466 | dqm->dev->kgd, pasid_mapping, | ||
463 | vmid); | 467 | vmid); |
464 | } | 468 | } |
465 | 469 | ||
@@ -511,7 +515,7 @@ int init_pipelines(struct device_queue_manager *dqm, | |||
511 | pipe_hpd_addr = dqm->pipelines_addr + i * CIK_HPD_EOP_BYTES; | 515 | pipe_hpd_addr = dqm->pipelines_addr + i * CIK_HPD_EOP_BYTES; |
512 | pr_debug("kfd: pipeline address %llX\n", pipe_hpd_addr); | 516 | pr_debug("kfd: pipeline address %llX\n", pipe_hpd_addr); |
513 | /* = log2(bytes/4)-1 */ | 517 | /* = log2(bytes/4)-1 */ |
514 | kfd2kgd->init_pipeline(dqm->dev->kgd, inx, | 518 | dqm->dev->kfd2kgd->init_pipeline(dqm->dev->kgd, inx, |
515 | CIK_HPD_EOP_BYTES_LOG2 - 3, pipe_hpd_addr); | 519 | CIK_HPD_EOP_BYTES_LOG2 - 3, pipe_hpd_addr); |
516 | } | 520 | } |
517 | 521 | ||
@@ -897,7 +901,7 @@ out: | |||
897 | return retval; | 901 | return retval; |
898 | } | 902 | } |
899 | 903 | ||
900 | static int fence_wait_timeout(unsigned int *fence_addr, | 904 | static int amdkfd_fence_wait_timeout(unsigned int *fence_addr, |
901 | unsigned int fence_value, | 905 | unsigned int fence_value, |
902 | unsigned long timeout) | 906 | unsigned long timeout) |
903 | { | 907 | { |
@@ -953,7 +957,7 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock) | |||
953 | pm_send_query_status(&dqm->packets, dqm->fence_gpu_addr, | 957 | pm_send_query_status(&dqm->packets, dqm->fence_gpu_addr, |
954 | KFD_FENCE_COMPLETED); | 958 | KFD_FENCE_COMPLETED); |
955 | /* should be timed out */ | 959 | /* should be timed out */ |
956 | fence_wait_timeout(dqm->fence_addr, KFD_FENCE_COMPLETED, | 960 | amdkfd_fence_wait_timeout(dqm->fence_addr, KFD_FENCE_COMPLETED, |
957 | QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS); | 961 | QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS); |
958 | pm_release_ib(&dqm->packets); | 962 | pm_release_ib(&dqm->packets); |
959 | dqm->active_runlist = false; | 963 | dqm->active_runlist = false; |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c index 1a9b355dd114..17e56dcc8540 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c | |||
@@ -32,9 +32,6 @@ | |||
32 | * and that's assures that any user process won't get access to the | 32 | * and that's assures that any user process won't get access to the |
33 | * kernel doorbells page | 33 | * kernel doorbells page |
34 | */ | 34 | */ |
35 | static DEFINE_MUTEX(doorbell_mutex); | ||
36 | static unsigned long doorbell_available_index[ | ||
37 | DIV_ROUND_UP(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, BITS_PER_LONG)] = { 0 }; | ||
38 | 35 | ||
39 | #define KERNEL_DOORBELL_PASID 1 | 36 | #define KERNEL_DOORBELL_PASID 1 |
40 | #define KFD_SIZE_OF_DOORBELL_IN_BYTES 4 | 37 | #define KFD_SIZE_OF_DOORBELL_IN_BYTES 4 |
@@ -170,12 +167,12 @@ u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd, | |||
170 | 167 | ||
171 | BUG_ON(!kfd || !doorbell_off); | 168 | BUG_ON(!kfd || !doorbell_off); |
172 | 169 | ||
173 | mutex_lock(&doorbell_mutex); | 170 | mutex_lock(&kfd->doorbell_mutex); |
174 | inx = find_first_zero_bit(doorbell_available_index, | 171 | inx = find_first_zero_bit(kfd->doorbell_available_index, |
175 | KFD_MAX_NUM_OF_QUEUES_PER_PROCESS); | 172 | KFD_MAX_NUM_OF_QUEUES_PER_PROCESS); |
176 | 173 | ||
177 | __set_bit(inx, doorbell_available_index); | 174 | __set_bit(inx, kfd->doorbell_available_index); |
178 | mutex_unlock(&doorbell_mutex); | 175 | mutex_unlock(&kfd->doorbell_mutex); |
179 | 176 | ||
180 | if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) | 177 | if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) |
181 | return NULL; | 178 | return NULL; |
@@ -203,9 +200,9 @@ void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr) | |||
203 | 200 | ||
204 | inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr); | 201 | inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr); |
205 | 202 | ||
206 | mutex_lock(&doorbell_mutex); | 203 | mutex_lock(&kfd->doorbell_mutex); |
207 | __clear_bit(inx, doorbell_available_index); | 204 | __clear_bit(inx, kfd->doorbell_available_index); |
208 | mutex_unlock(&doorbell_mutex); | 205 | mutex_unlock(&kfd->doorbell_mutex); |
209 | } | 206 | } |
210 | 207 | ||
211 | inline void write_kernel_doorbell(u32 __iomem *db, u32 value) | 208 | inline void write_kernel_doorbell(u32 __iomem *db, u32 value) |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c index 3f34ae16f075..4e0a68f13a77 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #define KFD_DRIVER_MINOR 7 | 34 | #define KFD_DRIVER_MINOR 7 |
35 | #define KFD_DRIVER_PATCHLEVEL 1 | 35 | #define KFD_DRIVER_PATCHLEVEL 1 |
36 | 36 | ||
37 | const struct kfd2kgd_calls *kfd2kgd; | ||
38 | static const struct kgd2kfd_calls kgd2kfd = { | 37 | static const struct kgd2kfd_calls kgd2kfd = { |
39 | .exit = kgd2kfd_exit, | 38 | .exit = kgd2kfd_exit, |
40 | .probe = kgd2kfd_probe, | 39 | .probe = kgd2kfd_probe, |
@@ -55,9 +54,7 @@ module_param(max_num_of_queues_per_device, int, 0444); | |||
55 | MODULE_PARM_DESC(max_num_of_queues_per_device, | 54 | MODULE_PARM_DESC(max_num_of_queues_per_device, |
56 | "Maximum number of supported queues per device (1 = Minimum, 4096 = default)"); | 55 | "Maximum number of supported queues per device (1 = Minimum, 4096 = default)"); |
57 | 56 | ||
58 | bool kgd2kfd_init(unsigned interface_version, | 57 | bool kgd2kfd_init(unsigned interface_version, const struct kgd2kfd_calls **g2f) |
59 | const struct kfd2kgd_calls *f2g, | ||
60 | const struct kgd2kfd_calls **g2f) | ||
61 | { | 58 | { |
62 | /* | 59 | /* |
63 | * Only one interface version is supported, | 60 | * Only one interface version is supported, |
@@ -66,11 +63,6 @@ bool kgd2kfd_init(unsigned interface_version, | |||
66 | if (interface_version != KFD_INTERFACE_VERSION) | 63 | if (interface_version != KFD_INTERFACE_VERSION) |
67 | return false; | 64 | return false; |
68 | 65 | ||
69 | /* Protection against multiple amd kgd loads */ | ||
70 | if (kfd2kgd) | ||
71 | return true; | ||
72 | |||
73 | kfd2kgd = f2g; | ||
74 | *g2f = &kgd2kfd; | 66 | *g2f = &kgd2kfd; |
75 | 67 | ||
76 | return true; | 68 | return true; |
@@ -85,8 +77,6 @@ static int __init kfd_module_init(void) | |||
85 | { | 77 | { |
86 | int err; | 78 | int err; |
87 | 79 | ||
88 | kfd2kgd = NULL; | ||
89 | |||
90 | /* Verify module parameters */ | 80 | /* Verify module parameters */ |
91 | if ((sched_policy < KFD_SCHED_POLICY_HWS) || | 81 | if ((sched_policy < KFD_SCHED_POLICY_HWS) || |
92 | (sched_policy > KFD_SCHED_POLICY_NO_HWS)) { | 82 | (sched_policy > KFD_SCHED_POLICY_NO_HWS)) { |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c index a09e18a339f3..434979428fc0 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c | |||
@@ -151,14 +151,15 @@ static void uninit_mqd_sdma(struct mqd_manager *mm, void *mqd, | |||
151 | static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id, | 151 | static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id, |
152 | uint32_t queue_id, uint32_t __user *wptr) | 152 | uint32_t queue_id, uint32_t __user *wptr) |
153 | { | 153 | { |
154 | return kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id, wptr); | 154 | return mm->dev->kfd2kgd->hqd_load |
155 | (mm->dev->kgd, mqd, pipe_id, queue_id, wptr); | ||
155 | } | 156 | } |
156 | 157 | ||
157 | static int load_mqd_sdma(struct mqd_manager *mm, void *mqd, | 158 | static int load_mqd_sdma(struct mqd_manager *mm, void *mqd, |
158 | uint32_t pipe_id, uint32_t queue_id, | 159 | uint32_t pipe_id, uint32_t queue_id, |
159 | uint32_t __user *wptr) | 160 | uint32_t __user *wptr) |
160 | { | 161 | { |
161 | return kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd); | 162 | return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd); |
162 | } | 163 | } |
163 | 164 | ||
164 | static int update_mqd(struct mqd_manager *mm, void *mqd, | 165 | static int update_mqd(struct mqd_manager *mm, void *mqd, |
@@ -245,7 +246,7 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd, | |||
245 | unsigned int timeout, uint32_t pipe_id, | 246 | unsigned int timeout, uint32_t pipe_id, |
246 | uint32_t queue_id) | 247 | uint32_t queue_id) |
247 | { | 248 | { |
248 | return kfd2kgd->hqd_destroy(mm->dev->kgd, type, timeout, | 249 | return mm->dev->kfd2kgd->hqd_destroy(mm->dev->kgd, type, timeout, |
249 | pipe_id, queue_id); | 250 | pipe_id, queue_id); |
250 | } | 251 | } |
251 | 252 | ||
@@ -258,7 +259,7 @@ static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd, | |||
258 | unsigned int timeout, uint32_t pipe_id, | 259 | unsigned int timeout, uint32_t pipe_id, |
259 | uint32_t queue_id) | 260 | uint32_t queue_id) |
260 | { | 261 | { |
261 | return kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout); | 262 | return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout); |
262 | } | 263 | } |
263 | 264 | ||
264 | static bool is_occupied(struct mqd_manager *mm, void *mqd, | 265 | static bool is_occupied(struct mqd_manager *mm, void *mqd, |
@@ -266,7 +267,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd, | |||
266 | uint32_t queue_id) | 267 | uint32_t queue_id) |
267 | { | 268 | { |
268 | 269 | ||
269 | return kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address, | 270 | return mm->dev->kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address, |
270 | pipe_id, queue_id); | 271 | pipe_id, queue_id); |
271 | 272 | ||
272 | } | 273 | } |
@@ -275,7 +276,7 @@ static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd, | |||
275 | uint64_t queue_address, uint32_t pipe_id, | 276 | uint64_t queue_address, uint32_t pipe_id, |
276 | uint32_t queue_id) | 277 | uint32_t queue_id) |
277 | { | 278 | { |
278 | return kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd); | 279 | return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd); |
279 | } | 280 | } |
280 | 281 | ||
281 | /* | 282 | /* |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 5a44f2fecf38..f21fccebd75b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h | |||
@@ -148,6 +148,11 @@ struct kfd_dev { | |||
148 | 148 | ||
149 | struct kgd2kfd_shared_resources shared_resources; | 149 | struct kgd2kfd_shared_resources shared_resources; |
150 | 150 | ||
151 | const struct kfd2kgd_calls *kfd2kgd; | ||
152 | struct mutex doorbell_mutex; | ||
153 | unsigned long doorbell_available_index[DIV_ROUND_UP( | ||
154 | KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, BITS_PER_LONG)]; | ||
155 | |||
151 | void *gtt_mem; | 156 | void *gtt_mem; |
152 | uint64_t gtt_start_gpu_addr; | 157 | uint64_t gtt_start_gpu_addr; |
153 | void *gtt_start_cpu_ptr; | 158 | void *gtt_start_cpu_ptr; |
@@ -164,13 +169,12 @@ struct kfd_dev { | |||
164 | 169 | ||
165 | /* KGD2KFD callbacks */ | 170 | /* KGD2KFD callbacks */ |
166 | void kgd2kfd_exit(void); | 171 | void kgd2kfd_exit(void); |
167 | struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev); | 172 | struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, |
173 | struct pci_dev *pdev, const struct kfd2kgd_calls *f2g); | ||
168 | bool kgd2kfd_device_init(struct kfd_dev *kfd, | 174 | bool kgd2kfd_device_init(struct kfd_dev *kfd, |
169 | const struct kgd2kfd_shared_resources *gpu_resources); | 175 | const struct kgd2kfd_shared_resources *gpu_resources); |
170 | void kgd2kfd_device_exit(struct kfd_dev *kfd); | 176 | void kgd2kfd_device_exit(struct kfd_dev *kfd); |
171 | 177 | ||
172 | extern const struct kfd2kgd_calls *kfd2kgd; | ||
173 | |||
174 | enum kfd_mempool { | 178 | enum kfd_mempool { |
175 | KFD_MEMPOOL_SYSTEM_CACHEABLE = 1, | 179 | KFD_MEMPOOL_SYSTEM_CACHEABLE = 1, |
176 | KFD_MEMPOOL_SYSTEM_WRITECOMBINE = 2, | 180 | KFD_MEMPOOL_SYSTEM_WRITECOMBINE = 2, |
@@ -378,8 +382,6 @@ struct qcm_process_device { | |||
378 | /* The Device Queue Manager that owns this data */ | 382 | /* The Device Queue Manager that owns this data */ |
379 | struct device_queue_manager *dqm; | 383 | struct device_queue_manager *dqm; |
380 | struct process_queue_manager *pqm; | 384 | struct process_queue_manager *pqm; |
381 | /* Device Queue Manager lock */ | ||
382 | struct mutex *lock; | ||
383 | /* Queues list */ | 385 | /* Queues list */ |
384 | struct list_head queues_list; | 386 | struct list_head queues_list; |
385 | struct list_head priv_queue_list; | 387 | struct list_head priv_queue_list; |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index a369c149d172..945d6226dc51 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c | |||
@@ -162,10 +162,16 @@ static void kfd_process_wq_release(struct work_struct *work) | |||
162 | 162 | ||
163 | p = my_work->p; | 163 | p = my_work->p; |
164 | 164 | ||
165 | pr_debug("Releasing process (pasid %d) in workqueue\n", | ||
166 | p->pasid); | ||
167 | |||
165 | mutex_lock(&p->mutex); | 168 | mutex_lock(&p->mutex); |
166 | 169 | ||
167 | list_for_each_entry_safe(pdd, temp, &p->per_device_data, | 170 | list_for_each_entry_safe(pdd, temp, &p->per_device_data, |
168 | per_device_list) { | 171 | per_device_list) { |
172 | pr_debug("Releasing pdd (topology id %d) for process (pasid %d) in workqueue\n", | ||
173 | pdd->dev->id, p->pasid); | ||
174 | |||
169 | amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid); | 175 | amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid); |
170 | list_del(&pdd->per_device_list); | 176 | list_del(&pdd->per_device_list); |
171 | 177 | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 498399323a8c..661c6605d31b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c | |||
@@ -726,13 +726,14 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, | |||
726 | } | 726 | } |
727 | 727 | ||
728 | sysfs_show_32bit_prop(buffer, "max_engine_clk_fcompute", | 728 | sysfs_show_32bit_prop(buffer, "max_engine_clk_fcompute", |
729 | kfd2kgd->get_max_engine_clock_in_mhz( | 729 | dev->gpu->kfd2kgd->get_max_engine_clock_in_mhz( |
730 | dev->gpu->kgd)); | 730 | dev->gpu->kgd)); |
731 | sysfs_show_64bit_prop(buffer, "local_mem_size", | 731 | sysfs_show_64bit_prop(buffer, "local_mem_size", |
732 | kfd2kgd->get_vmem_size(dev->gpu->kgd)); | 732 | dev->gpu->kfd2kgd->get_vmem_size( |
733 | dev->gpu->kgd)); | ||
733 | 734 | ||
734 | sysfs_show_32bit_prop(buffer, "fw_version", | 735 | sysfs_show_32bit_prop(buffer, "fw_version", |
735 | kfd2kgd->get_fw_version( | 736 | dev->gpu->kfd2kgd->get_fw_version( |
736 | dev->gpu->kgd, | 737 | dev->gpu->kgd, |
737 | KGD_ENGINE_MEC1)); | 738 | KGD_ENGINE_MEC1)); |
738 | } | 739 | } |
@@ -1099,8 +1100,9 @@ static uint32_t kfd_generate_gpu_id(struct kfd_dev *gpu) | |||
1099 | buf[2] = gpu->pdev->subsystem_device; | 1100 | buf[2] = gpu->pdev->subsystem_device; |
1100 | buf[3] = gpu->pdev->device; | 1101 | buf[3] = gpu->pdev->device; |
1101 | buf[4] = gpu->pdev->bus->number; | 1102 | buf[4] = gpu->pdev->bus->number; |
1102 | buf[5] = (uint32_t)(kfd2kgd->get_vmem_size(gpu->kgd) & 0xffffffff); | 1103 | buf[5] = (uint32_t)(gpu->kfd2kgd->get_vmem_size(gpu->kgd) |
1103 | buf[6] = (uint32_t)(kfd2kgd->get_vmem_size(gpu->kgd) >> 32); | 1104 | & 0xffffffff); |
1105 | buf[6] = (uint32_t)(gpu->kfd2kgd->get_vmem_size(gpu->kgd) >> 32); | ||
1104 | 1106 | ||
1105 | for (i = 0, hashout = 0; i < 7; i++) | 1107 | for (i = 0, hashout = 0; i < 7; i++) |
1106 | hashout ^= hash_32(buf[i], KFD_GPU_ID_HASH_WIDTH); | 1108 | hashout ^= hash_32(buf[i], KFD_GPU_ID_HASH_WIDTH); |
diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h index 239bc16a1ddd..dabd94446b7b 100644 --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h | |||
@@ -77,37 +77,6 @@ struct kgd2kfd_shared_resources { | |||
77 | }; | 77 | }; |
78 | 78 | ||
79 | /** | 79 | /** |
80 | * struct kgd2kfd_calls | ||
81 | * | ||
82 | * @exit: Notifies amdkfd that kgd module is unloaded | ||
83 | * | ||
84 | * @probe: Notifies amdkfd about a probe done on a device in the kgd driver. | ||
85 | * | ||
86 | * @device_init: Initialize the newly probed device (if it is a device that | ||
87 | * amdkfd supports) | ||
88 | * | ||
89 | * @device_exit: Notifies amdkfd about a removal of a kgd device | ||
90 | * | ||
91 | * @suspend: Notifies amdkfd about a suspend action done to a kgd device | ||
92 | * | ||
93 | * @resume: Notifies amdkfd about a resume action done to a kgd device | ||
94 | * | ||
95 | * This structure contains function callback pointers so the kgd driver | ||
96 | * will notify to the amdkfd about certain status changes. | ||
97 | * | ||
98 | */ | ||
99 | struct kgd2kfd_calls { | ||
100 | void (*exit)(void); | ||
101 | struct kfd_dev* (*probe)(struct kgd_dev *kgd, struct pci_dev *pdev); | ||
102 | bool (*device_init)(struct kfd_dev *kfd, | ||
103 | const struct kgd2kfd_shared_resources *gpu_resources); | ||
104 | void (*device_exit)(struct kfd_dev *kfd); | ||
105 | void (*interrupt)(struct kfd_dev *kfd, const void *ih_ring_entry); | ||
106 | void (*suspend)(struct kfd_dev *kfd); | ||
107 | int (*resume)(struct kfd_dev *kfd); | ||
108 | }; | ||
109 | |||
110 | /** | ||
111 | * struct kfd2kgd_calls | 80 | * struct kfd2kgd_calls |
112 | * | 81 | * |
113 | * @init_gtt_mem_allocation: Allocate a buffer on the gart aperture. | 82 | * @init_gtt_mem_allocation: Allocate a buffer on the gart aperture. |
@@ -196,8 +165,39 @@ struct kfd2kgd_calls { | |||
196 | enum kgd_engine_type type); | 165 | enum kgd_engine_type type); |
197 | }; | 166 | }; |
198 | 167 | ||
168 | /** | ||
169 | * struct kgd2kfd_calls | ||
170 | * | ||
171 | * @exit: Notifies amdkfd that kgd module is unloaded | ||
172 | * | ||
173 | * @probe: Notifies amdkfd about a probe done on a device in the kgd driver. | ||
174 | * | ||
175 | * @device_init: Initialize the newly probed device (if it is a device that | ||
176 | * amdkfd supports) | ||
177 | * | ||
178 | * @device_exit: Notifies amdkfd about a removal of a kgd device | ||
179 | * | ||
180 | * @suspend: Notifies amdkfd about a suspend action done to a kgd device | ||
181 | * | ||
182 | * @resume: Notifies amdkfd about a resume action done to a kgd device | ||
183 | * | ||
184 | * This structure contains function callback pointers so the kgd driver | ||
185 | * will notify to the amdkfd about certain status changes. | ||
186 | * | ||
187 | */ | ||
188 | struct kgd2kfd_calls { | ||
189 | void (*exit)(void); | ||
190 | struct kfd_dev* (*probe)(struct kgd_dev *kgd, struct pci_dev *pdev, | ||
191 | const struct kfd2kgd_calls *f2g); | ||
192 | bool (*device_init)(struct kfd_dev *kfd, | ||
193 | const struct kgd2kfd_shared_resources *gpu_resources); | ||
194 | void (*device_exit)(struct kfd_dev *kfd); | ||
195 | void (*interrupt)(struct kfd_dev *kfd, const void *ih_ring_entry); | ||
196 | void (*suspend)(struct kfd_dev *kfd); | ||
197 | int (*resume)(struct kfd_dev *kfd); | ||
198 | }; | ||
199 | |||
199 | bool kgd2kfd_init(unsigned interface_version, | 200 | bool kgd2kfd_init(unsigned interface_version, |
200 | const struct kfd2kgd_calls *f2g, | ||
201 | const struct kgd2kfd_calls **g2f); | 201 | const struct kgd2kfd_calls **g2f); |
202 | 202 | ||
203 | #endif /* KGD_KFD_INTERFACE_H_INCLUDED */ | 203 | #endif /* KGD_KFD_INTERFACE_H_INCLUDED */ |
diff --git a/drivers/gpu/drm/radeon/radeon_kfd.c b/drivers/gpu/drm/radeon/radeon_kfd.c index 061eaa9c19c7..4cdcaf8361e1 100644 --- a/drivers/gpu/drm/radeon/radeon_kfd.c +++ b/drivers/gpu/drm/radeon/radeon_kfd.c | |||
@@ -103,15 +103,14 @@ static const struct kgd2kfd_calls *kgd2kfd; | |||
103 | bool radeon_kfd_init(void) | 103 | bool radeon_kfd_init(void) |
104 | { | 104 | { |
105 | #if defined(CONFIG_HSA_AMD_MODULE) | 105 | #if defined(CONFIG_HSA_AMD_MODULE) |
106 | bool (*kgd2kfd_init_p)(unsigned, const struct kfd2kgd_calls*, | 106 | bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**); |
107 | const struct kgd2kfd_calls**); | ||
108 | 107 | ||
109 | kgd2kfd_init_p = symbol_request(kgd2kfd_init); | 108 | kgd2kfd_init_p = symbol_request(kgd2kfd_init); |
110 | 109 | ||
111 | if (kgd2kfd_init_p == NULL) | 110 | if (kgd2kfd_init_p == NULL) |
112 | return false; | 111 | return false; |
113 | 112 | ||
114 | if (!kgd2kfd_init_p(KFD_INTERFACE_VERSION, &kfd2kgd, &kgd2kfd)) { | 113 | if (!kgd2kfd_init_p(KFD_INTERFACE_VERSION, &kgd2kfd)) { |
115 | symbol_put(kgd2kfd_init); | 114 | symbol_put(kgd2kfd_init); |
116 | kgd2kfd = NULL; | 115 | kgd2kfd = NULL; |
117 | 116 | ||
@@ -120,7 +119,7 @@ bool radeon_kfd_init(void) | |||
120 | 119 | ||
121 | return true; | 120 | return true; |
122 | #elif defined(CONFIG_HSA_AMD) | 121 | #elif defined(CONFIG_HSA_AMD) |
123 | if (!kgd2kfd_init(KFD_INTERFACE_VERSION, &kfd2kgd, &kgd2kfd)) { | 122 | if (!kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd)) { |
124 | kgd2kfd = NULL; | 123 | kgd2kfd = NULL; |
125 | 124 | ||
126 | return false; | 125 | return false; |
@@ -143,7 +142,8 @@ void radeon_kfd_fini(void) | |||
143 | void radeon_kfd_device_probe(struct radeon_device *rdev) | 142 | void radeon_kfd_device_probe(struct radeon_device *rdev) |
144 | { | 143 | { |
145 | if (kgd2kfd) | 144 | if (kgd2kfd) |
146 | rdev->kfd = kgd2kfd->probe((struct kgd_dev *)rdev, rdev->pdev); | 145 | rdev->kfd = kgd2kfd->probe((struct kgd_dev *)rdev, |
146 | rdev->pdev, &kfd2kgd); | ||
147 | } | 147 | } |
148 | 148 | ||
149 | void radeon_kfd_device_init(struct radeon_device *rdev) | 149 | void radeon_kfd_device_init(struct radeon_device *rdev) |