aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
authorBen Goz <ben.goz@amd.com>2015-01-03 15:12:32 -0500
committerOded Gabbay <oded.gabbay@amd.com>2015-01-09 15:26:05 -0500
commitbcea308175748339b872cc50972e0a31c1999c64 (patch)
treebf9be96a29e8cf3f38610faeb16bcaaa3276eee8 /drivers/gpu/drm/amd
parent77669eb87a904ee983d6c31563be20981837705d (diff)
drm/amdkfd: Add SDMA user-mode queues support to QCM
This patch adds support for SDMA user-mode queues to the QCM - the Queue management system that manages queues-per-device and queues-per-process. v2: Remove calls to interface function that initializes sdma engines. v3: Use the new names of some of the defines. 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/kfd_device_queue_manager.c159
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h5
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c2
3 files changed, 154 insertions, 12 deletions
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 fb94f1a2b911..7ead0802883d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -46,9 +46,24 @@ static int set_pasid_vmid_mapping(struct device_queue_manager *dqm,
46static int create_compute_queue_nocpsch(struct device_queue_manager *dqm, 46static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,
47 struct queue *q, 47 struct queue *q,
48 struct qcm_process_device *qpd); 48 struct qcm_process_device *qpd);
49
49static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock); 50static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock);
50static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock); 51static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock);
51 52
53static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
54 struct queue *q,
55 struct qcm_process_device *qpd);
56
57static void deallocate_sdma_queue(struct device_queue_manager *dqm,
58 unsigned int sdma_queue_id);
59
60static inline
61enum KFD_MQD_TYPE get_mqd_type_from_queue_type(enum kfd_queue_type type)
62{
63 if (type == KFD_QUEUE_TYPE_SDMA)
64 return KFD_MQD_TYPE_CIK_SDMA;
65 return KFD_MQD_TYPE_CIK_CP;
66}
52 67
53static inline unsigned int get_pipes_num(struct device_queue_manager *dqm) 68static inline unsigned int get_pipes_num(struct device_queue_manager *dqm)
54{ 69{
@@ -189,7 +204,10 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
189 *allocated_vmid = qpd->vmid; 204 *allocated_vmid = qpd->vmid;
190 q->properties.vmid = qpd->vmid; 205 q->properties.vmid = qpd->vmid;
191 206
192 retval = create_compute_queue_nocpsch(dqm, q, qpd); 207 if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE)
208 retval = create_compute_queue_nocpsch(dqm, q, qpd);
209 if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
210 retval = create_sdma_queue_nocpsch(dqm, q, qpd);
193 211
194 if (retval != 0) { 212 if (retval != 0) {
195 if (list_empty(&qpd->queues_list)) { 213 if (list_empty(&qpd->queues_list)) {
@@ -202,7 +220,8 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
202 220
203 list_add(&q->list, &qpd->queues_list); 221 list_add(&q->list, &qpd->queues_list);
204 dqm->queue_count++; 222 dqm->queue_count++;
205 223 if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
224 dqm->sdma_queue_count++;
206 mutex_unlock(&dqm->lock); 225 mutex_unlock(&dqm->lock);
207 return 0; 226 return 0;
208} 227}
@@ -279,8 +298,7 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
279 struct queue *q) 298 struct queue *q)
280{ 299{
281 int retval; 300 int retval;
282 struct mqd_manager *mqd; 301 struct mqd_manager *mqd, *mqd_sdma;
283
284 BUG_ON(!dqm || !q || !q->mqd || !qpd); 302 BUG_ON(!dqm || !q || !q->mqd || !qpd);
285 303
286 retval = 0; 304 retval = 0;
@@ -294,6 +312,12 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
294 goto out; 312 goto out;
295 } 313 }
296 314
315 mqd_sdma = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_SDMA);
316 if (mqd_sdma == NULL) {
317 mutex_unlock(&dqm->lock);
318 return -ENOMEM;
319 }
320
297 retval = mqd->destroy_mqd(mqd, q->mqd, 321 retval = mqd->destroy_mqd(mqd, q->mqd,
298 KFD_PREEMPT_TYPE_WAVEFRONT, 322 KFD_PREEMPT_TYPE_WAVEFRONT,
299 QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS, 323 QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS,
@@ -302,7 +326,12 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
302 if (retval != 0) 326 if (retval != 0)
303 goto out; 327 goto out;
304 328
305 deallocate_hqd(dqm, q); 329 if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE)
330 deallocate_hqd(dqm, q);
331 else if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
332 dqm->sdma_queue_count--;
333 deallocate_sdma_queue(dqm, q->sdma_id);
334 }
306 335
307 mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); 336 mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
308 337
@@ -323,7 +352,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
323 BUG_ON(!dqm || !q || !q->mqd); 352 BUG_ON(!dqm || !q || !q->mqd);
324 353
325 mutex_lock(&dqm->lock); 354 mutex_lock(&dqm->lock);
326 mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE); 355 mqd = dqm->get_mqd_manager(dqm, q->properties.type);
327 if (mqd == NULL) { 356 if (mqd == NULL) {
328 mutex_unlock(&dqm->lock); 357 mutex_unlock(&dqm->lock);
329 return -ENOMEM; 358 return -ENOMEM;
@@ -526,7 +555,6 @@ static int init_pipelines(struct device_queue_manager *dqm,
526 return 0; 555 return 0;
527} 556}
528 557
529
530static int init_scheduler(struct device_queue_manager *dqm) 558static int init_scheduler(struct device_queue_manager *dqm)
531{ 559{
532 int retval; 560 int retval;
@@ -556,6 +584,7 @@ static int initialize_nocpsch(struct device_queue_manager *dqm)
556 mutex_init(&dqm->lock); 584 mutex_init(&dqm->lock);
557 INIT_LIST_HEAD(&dqm->queues); 585 INIT_LIST_HEAD(&dqm->queues);
558 dqm->queue_count = dqm->next_pipe_to_allocate = 0; 586 dqm->queue_count = dqm->next_pipe_to_allocate = 0;
587 dqm->sdma_queue_count = 0;
559 dqm->allocated_queues = kcalloc(get_pipes_num(dqm), 588 dqm->allocated_queues = kcalloc(get_pipes_num(dqm),
560 sizeof(unsigned int), GFP_KERNEL); 589 sizeof(unsigned int), GFP_KERNEL);
561 if (!dqm->allocated_queues) { 590 if (!dqm->allocated_queues) {
@@ -567,6 +596,7 @@ static int initialize_nocpsch(struct device_queue_manager *dqm)
567 dqm->allocated_queues[i] = (1 << QUEUES_PER_PIPE) - 1; 596 dqm->allocated_queues[i] = (1 << QUEUES_PER_PIPE) - 1;
568 597
569 dqm->vmid_bitmap = (1 << VMID_PER_DEVICE) - 1; 598 dqm->vmid_bitmap = (1 << VMID_PER_DEVICE) - 1;
599 dqm->sdma_bitmap = (1 << CIK_SDMA_QUEUES) - 1;
570 600
571 init_scheduler(dqm); 601 init_scheduler(dqm);
572 return 0; 602 return 0;
@@ -598,6 +628,77 @@ static int stop_nocpsch(struct device_queue_manager *dqm)
598 return 0; 628 return 0;
599} 629}
600 630
631static int allocate_sdma_queue(struct device_queue_manager *dqm,
632 unsigned int *sdma_queue_id)
633{
634 int bit;
635
636 if (dqm->sdma_bitmap == 0)
637 return -ENOMEM;
638
639 bit = find_first_bit((unsigned long *)&dqm->sdma_bitmap,
640 CIK_SDMA_QUEUES);
641
642 clear_bit(bit, (unsigned long *)&dqm->sdma_bitmap);
643 *sdma_queue_id = bit;
644
645 return 0;
646}
647
648static void deallocate_sdma_queue(struct device_queue_manager *dqm,
649 unsigned int sdma_queue_id)
650{
651 if (sdma_queue_id < 0 || sdma_queue_id >= CIK_SDMA_QUEUES)
652 return;
653 set_bit(sdma_queue_id, (unsigned long *)&dqm->sdma_bitmap);
654}
655
656static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q,
657 struct qcm_process_device *qpd)
658{
659 uint32_t value = SDMA_ATC;
660
661 if (q->process->is_32bit_user_mode)
662 value |= SDMA_VA_PTR32 | get_sh_mem_bases_32(qpd_to_pdd(qpd));
663 else
664 value |= SDMA_VA_SHARED_BASE(get_sh_mem_bases_nybble_64(
665 qpd_to_pdd(qpd)));
666 q->properties.sdma_vm_addr = value;
667}
668
669static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
670 struct queue *q,
671 struct qcm_process_device *qpd)
672{
673 struct mqd_manager *mqd;
674 int retval;
675
676 mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_SDMA);
677 if (!mqd)
678 return -ENOMEM;
679
680 retval = allocate_sdma_queue(dqm, &q->sdma_id);
681 if (retval != 0)
682 return retval;
683
684 q->properties.sdma_queue_id = q->sdma_id % CIK_SDMA_QUEUES_PER_ENGINE;
685 q->properties.sdma_engine_id = q->sdma_id / CIK_SDMA_ENGINE_NUM;
686
687 pr_debug("kfd: sdma id is: %d\n", q->sdma_id);
688 pr_debug(" sdma queue id: %d\n", q->properties.sdma_queue_id);
689 pr_debug(" sdma engine id: %d\n", q->properties.sdma_engine_id);
690
691 retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
692 &q->gart_mqd_addr, &q->properties);
693 if (retval != 0) {
694 deallocate_sdma_queue(dqm, q->sdma_id);
695 return retval;
696 }
697
698 init_sdma_vm(dqm, q, qpd);
699 return 0;
700}
701
601/* 702/*
602 * Device Queue Manager implementation for cp scheduler 703 * Device Queue Manager implementation for cp scheduler
603 */ 704 */
@@ -639,6 +740,7 @@ static int initialize_cpsch(struct device_queue_manager *dqm)
639 mutex_init(&dqm->lock); 740 mutex_init(&dqm->lock);
640 INIT_LIST_HEAD(&dqm->queues); 741 INIT_LIST_HEAD(&dqm->queues);
641 dqm->queue_count = dqm->processes_count = 0; 742 dqm->queue_count = dqm->processes_count = 0;
743 dqm->sdma_queue_count = 0;
642 dqm->active_runlist = false; 744 dqm->active_runlist = false;
643 retval = init_pipelines(dqm, get_pipes_num(dqm), 0); 745 retval = init_pipelines(dqm, get_pipes_num(dqm), 0);
644 if (retval != 0) 746 if (retval != 0)
@@ -682,7 +784,6 @@ static int start_cpsch(struct device_queue_manager *dqm)
682 784
683 dqm->fence_addr = dqm->fence_mem->cpu_ptr; 785 dqm->fence_addr = dqm->fence_mem->cpu_ptr;
684 dqm->fence_gpu_addr = dqm->fence_mem->gpu_addr; 786 dqm->fence_gpu_addr = dqm->fence_mem->gpu_addr;
685
686 list_for_each_entry(node, &dqm->queues, list) 787 list_for_each_entry(node, &dqm->queues, list)
687 if (node->qpd->pqm->process && dqm->dev) 788 if (node->qpd->pqm->process && dqm->dev)
688 kfd_bind_process_to_device(dqm->dev, 789 kfd_bind_process_to_device(dqm->dev,
@@ -753,6 +854,14 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm,
753 mutex_unlock(&dqm->lock); 854 mutex_unlock(&dqm->lock);
754} 855}
755 856
857static void select_sdma_engine_id(struct queue *q)
858{
859 static int sdma_id;
860
861 q->sdma_id = sdma_id;
862 sdma_id = (sdma_id + 1) % 2;
863}
864
756static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, 865static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
757 struct qcm_process_device *qpd, int *allocate_vmid) 866 struct qcm_process_device *qpd, int *allocate_vmid)
758{ 867{
@@ -768,7 +877,12 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
768 877
769 mutex_lock(&dqm->lock); 878 mutex_lock(&dqm->lock);
770 879
771 mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_CP); 880 if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
881 select_sdma_engine_id(q);
882
883 mqd = dqm->get_mqd_manager(dqm,
884 get_mqd_type_from_queue_type(q->properties.type));
885
772 if (mqd == NULL) { 886 if (mqd == NULL) {
773 mutex_unlock(&dqm->lock); 887 mutex_unlock(&dqm->lock);
774 return -ENOMEM; 888 return -ENOMEM;
@@ -785,6 +899,9 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
785 retval = execute_queues_cpsch(dqm, false); 899 retval = execute_queues_cpsch(dqm, false);
786 } 900 }
787 901
902 if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
903 dqm->sdma_queue_count++;
904
788out: 905out:
789 mutex_unlock(&dqm->lock); 906 mutex_unlock(&dqm->lock);
790 return retval; 907 return retval;
@@ -808,6 +925,14 @@ static int fence_wait_timeout(unsigned int *fence_addr,
808 return 0; 925 return 0;
809} 926}
810 927
928static int destroy_sdma_queues(struct device_queue_manager *dqm,
929 unsigned int sdma_engine)
930{
931 return pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_SDMA,
932 KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES, 0, false,
933 sdma_engine);
934}
935
811static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock) 936static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock)
812{ 937{
813 int retval; 938 int retval;
@@ -820,6 +945,15 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock)
820 mutex_lock(&dqm->lock); 945 mutex_lock(&dqm->lock);
821 if (dqm->active_runlist == false) 946 if (dqm->active_runlist == false)
822 goto out; 947 goto out;
948
949 pr_debug("kfd: Before destroying queues, sdma queue count is : %u\n",
950 dqm->sdma_queue_count);
951
952 if (dqm->sdma_queue_count > 0) {
953 destroy_sdma_queues(dqm, 0);
954 destroy_sdma_queues(dqm, 1);
955 }
956
823 retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_COMPUTE, 957 retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_COMPUTE,
824 KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES, 0, false, 0); 958 KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES, 0, false, 0);
825 if (retval != 0) 959 if (retval != 0)
@@ -891,13 +1025,16 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm,
891 1025
892 /* remove queue from list to prevent rescheduling after preemption */ 1026 /* remove queue from list to prevent rescheduling after preemption */
893 mutex_lock(&dqm->lock); 1027 mutex_lock(&dqm->lock);
894 1028 mqd = dqm->get_mqd_manager(dqm,
895 mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_CP); 1029 get_mqd_type_from_queue_type(q->properties.type));
896 if (!mqd) { 1030 if (!mqd) {
897 retval = -ENOMEM; 1031 retval = -ENOMEM;
898 goto failed; 1032 goto failed;
899 } 1033 }
900 1034
1035 if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
1036 dqm->sdma_queue_count--;
1037
901 list_del(&q->list); 1038 list_del(&q->list);
902 dqm->queue_count--; 1039 dqm->queue_count--;
903 1040
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
index c3f189e8ae35..554c06ee8892 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
@@ -36,6 +36,9 @@
36#define KFD_VMID_START_OFFSET (8) 36#define KFD_VMID_START_OFFSET (8)
37#define VMID_PER_DEVICE CIK_VMID_NUM 37#define VMID_PER_DEVICE CIK_VMID_NUM
38#define KFD_DQM_FIRST_PIPE (0) 38#define KFD_DQM_FIRST_PIPE (0)
39#define CIK_SDMA_QUEUES (4)
40#define CIK_SDMA_QUEUES_PER_ENGINE (2)
41#define CIK_SDMA_ENGINE_NUM (2)
39 42
40struct device_process_node { 43struct device_process_node {
41 struct qcm_process_device *qpd; 44 struct qcm_process_device *qpd;
@@ -130,8 +133,10 @@ struct device_queue_manager {
130 struct list_head queues; 133 struct list_head queues;
131 unsigned int processes_count; 134 unsigned int processes_count;
132 unsigned int queue_count; 135 unsigned int queue_count;
136 unsigned int sdma_queue_count;
133 unsigned int next_pipe_to_allocate; 137 unsigned int next_pipe_to_allocate;
134 unsigned int *allocated_queues; 138 unsigned int *allocated_queues;
139 unsigned int sdma_bitmap;
135 unsigned int vmid_bitmap; 140 unsigned int vmid_bitmap;
136 uint64_t pipelines_addr; 141 uint64_t pipelines_addr;
137 struct kfd_mem_obj *pipeline_mem; 142 struct kfd_mem_obj *pipeline_mem;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index d12f9d32275b..948b1ca8e7a2 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -128,7 +128,6 @@ static int create_cp_queue(struct process_queue_manager *pqm,
128 /* let DQM handle it*/ 128 /* let DQM handle it*/
129 q_properties->vmid = 0; 129 q_properties->vmid = 0;
130 q_properties->queue_id = qid; 130 q_properties->queue_id = qid;
131 q_properties->type = KFD_QUEUE_TYPE_COMPUTE;
132 131
133 retval = init_queue(q, *q_properties); 132 retval = init_queue(q, *q_properties);
134 if (retval != 0) 133 if (retval != 0)
@@ -189,6 +188,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
189 } 188 }
190 189
191 switch (type) { 190 switch (type) {
191 case KFD_QUEUE_TYPE_SDMA:
192 case KFD_QUEUE_TYPE_COMPUTE: 192 case KFD_QUEUE_TYPE_COMPUTE:
193 /* check if there is over subscription */ 193 /* check if there is over subscription */
194 if ((sched_policy == KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION) && 194 if ((sched_policy == KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION) &&