These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / gpu / drm / amd / amdkfd / kfd_packet_manager.c
index e2533d8..90f3914 100644 (file)
@@ -27,6 +27,7 @@
 #include "kfd_kernel_queue.h"
 #include "kfd_priv.h"
 #include "kfd_pm4_headers.h"
+#include "kfd_pm4_headers_vi.h"
 #include "kfd_pm4_opcodes.h"
 
 static inline void inc_wptr(unsigned int *wptr, unsigned int increment_bytes,
@@ -55,6 +56,7 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
                                bool *over_subscription)
 {
        unsigned int process_count, queue_count;
+       unsigned int map_queue_size;
 
        BUG_ON(!pm || !rlib_size || !over_subscription);
 
@@ -69,9 +71,13 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
                pr_debug("kfd: over subscribed runlist\n");
        }
 
+       map_queue_size =
+               (pm->dqm->dev->device_info->asic_family == CHIP_CARRIZO) ?
+               sizeof(struct pm4_mes_map_queues) :
+               sizeof(struct pm4_map_queues);
        /* calculate run list ib allocation size */
        *rlib_size = process_count * sizeof(struct pm4_map_process) +
-                    queue_count * sizeof(struct pm4_map_queues);
+                    queue_count * map_queue_size;
 
        /*
         * Increase the allocation size in case we need a chained run list
@@ -163,7 +169,7 @@ static int pm_create_map_process(struct packet_manager *pm, uint32_t *buffer,
        num_queues = 0;
        list_for_each_entry(cur, &qpd->queues_list, list)
                num_queues++;
-       packet->bitfields10.num_queues = num_queues;
+       packet->bitfields10.num_queues = (qpd->is_debug) ? 0 : num_queues;
 
        packet->sh_mem_config = qpd->sh_mem_config;
        packet->sh_mem_bases = qpd->sh_mem_bases;
@@ -176,10 +182,76 @@ static int pm_create_map_process(struct packet_manager *pm, uint32_t *buffer,
        return 0;
 }
 
+static int pm_create_map_queue_vi(struct packet_manager *pm, uint32_t *buffer,
+               struct queue *q, bool is_static)
+{
+       struct pm4_mes_map_queues *packet;
+       bool use_static = is_static;
+
+       BUG_ON(!pm || !buffer || !q);
+
+       pr_debug("kfd: In func %s\n", __func__);
+
+       packet = (struct pm4_mes_map_queues *)buffer;
+       memset(buffer, 0, sizeof(struct pm4_map_queues));
+
+       packet->header.u32all = build_pm4_header(IT_MAP_QUEUES,
+                                               sizeof(struct pm4_map_queues));
+       packet->bitfields2.alloc_format =
+               alloc_format__mes_map_queues__one_per_pipe_vi;
+       packet->bitfields2.num_queues = 1;
+       packet->bitfields2.queue_sel =
+               queue_sel__mes_map_queues__map_to_hws_determined_queue_slots_vi;
+
+       packet->bitfields2.engine_sel =
+               engine_sel__mes_map_queues__compute_vi;
+       packet->bitfields2.queue_type =
+               queue_type__mes_map_queues__normal_compute_vi;
+
+       switch (q->properties.type) {
+       case KFD_QUEUE_TYPE_COMPUTE:
+               if (use_static)
+                       packet->bitfields2.queue_type =
+               queue_type__mes_map_queues__normal_latency_static_queue_vi;
+               break;
+       case KFD_QUEUE_TYPE_DIQ:
+               packet->bitfields2.queue_type =
+                       queue_type__mes_map_queues__debug_interface_queue_vi;
+               break;
+       case KFD_QUEUE_TYPE_SDMA:
+               packet->bitfields2.engine_sel =
+                               engine_sel__mes_map_queues__sdma0_vi;
+               use_static = false; /* no static queues under SDMA */
+               break;
+       default:
+               pr_err("kfd: in %s queue type %d\n", __func__,
+                               q->properties.type);
+               BUG();
+               break;
+       }
+       packet->bitfields3.doorbell_offset =
+                       q->properties.doorbell_off;
+
+       packet->mqd_addr_lo =
+                       lower_32_bits(q->gart_mqd_addr);
+
+       packet->mqd_addr_hi =
+                       upper_32_bits(q->gart_mqd_addr);
+
+       packet->wptr_addr_lo =
+                       lower_32_bits((uint64_t)q->properties.write_ptr);
+
+       packet->wptr_addr_hi =
+                       upper_32_bits((uint64_t)q->properties.write_ptr);
+
+       return 0;
+}
+
 static int pm_create_map_queue(struct packet_manager *pm, uint32_t *buffer,
-                               struct queue *q)
+                               struct queue *q, bool is_static)
 {
        struct pm4_map_queues *packet;
+       bool use_static = is_static;
 
        BUG_ON(!pm || !buffer || !q);
 
@@ -209,6 +281,7 @@ static int pm_create_map_queue(struct packet_manager *pm, uint32_t *buffer,
        case KFD_QUEUE_TYPE_SDMA:
                packet->bitfields2.engine_sel =
                                engine_sel__mes_map_queues__sdma0;
+               use_static = false; /* no static queues under SDMA */
                break;
        default:
                BUG();
@@ -218,6 +291,9 @@ static int pm_create_map_queue(struct packet_manager *pm, uint32_t *buffer,
        packet->mes_map_queues_ordinals[0].bitfields3.doorbell_offset =
                        q->properties.doorbell_off;
 
+       packet->mes_map_queues_ordinals[0].bitfields3.is_static =
+                       (use_static == true) ? 1 : 0;
+
        packet->mes_map_queues_ordinals[0].mqd_addr_lo =
                        lower_32_bits(q->gart_mqd_addr);
 
@@ -271,9 +347,11 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
                        pm_release_ib(pm);
                        return -ENOMEM;
                }
+
                retval = pm_create_map_process(pm, &rl_buffer[rl_wptr], qpd);
                if (retval != 0)
                        return retval;
+
                proccesses_mapped++;
                inc_wptr(&rl_wptr, sizeof(struct pm4_map_process),
                                alloc_size_bytes);
@@ -281,23 +359,54 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
                list_for_each_entry(kq, &qpd->priv_queue_list, list) {
                        if (kq->queue->properties.is_active != true)
                                continue;
-                       retval = pm_create_map_queue(pm, &rl_buffer[rl_wptr],
-                                                       kq->queue);
+
+                       pr_debug("kfd: static_queue, mapping kernel q %d, is debug status %d\n",
+                               kq->queue->queue, qpd->is_debug);
+
+                       if (pm->dqm->dev->device_info->asic_family ==
+                                       CHIP_CARRIZO)
+                               retval = pm_create_map_queue_vi(pm,
+                                               &rl_buffer[rl_wptr],
+                                               kq->queue,
+                                               qpd->is_debug);
+                       else
+                               retval = pm_create_map_queue(pm,
+                                               &rl_buffer[rl_wptr],
+                                               kq->queue,
+                                               qpd->is_debug);
                        if (retval != 0)
                                return retval;
-                       inc_wptr(&rl_wptr, sizeof(struct pm4_map_queues),
-                                       alloc_size_bytes);
+
+                       inc_wptr(&rl_wptr,
+                               sizeof(struct pm4_map_queues),
+                               alloc_size_bytes);
                }
 
                list_for_each_entry(q, &qpd->queues_list, list) {
                        if (q->properties.is_active != true)
                                continue;
-                       retval = pm_create_map_queue(pm,
-                                               &rl_buffer[rl_wptr], q);
+
+                       pr_debug("kfd: static_queue, mapping user queue %d, is debug status %d\n",
+                               q->queue, qpd->is_debug);
+
+                       if (pm->dqm->dev->device_info->asic_family ==
+                                       CHIP_CARRIZO)
+                               retval = pm_create_map_queue_vi(pm,
+                                               &rl_buffer[rl_wptr],
+                                               q,
+                                               qpd->is_debug);
+                       else
+                               retval = pm_create_map_queue(pm,
+                                               &rl_buffer[rl_wptr],
+                                               q,
+                                               qpd->is_debug);
+
                        if (retval != 0)
                                return retval;
-                       inc_wptr(&rl_wptr, sizeof(struct pm4_map_queues),
-                                       alloc_size_bytes);
+
+                       inc_wptr(&rl_wptr,
+                               sizeof(struct pm4_map_queues),
+                               alloc_size_bytes);
                }
        }
 
@@ -488,7 +597,8 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
 
        packet = (struct pm4_unmap_queues *)buffer;
        memset(buffer, 0, sizeof(struct pm4_unmap_queues));
-
+       pr_debug("kfd: static_queue: unmapping queues: mode is %d , reset is %d , type is %d\n",
+               mode, reset, type);
        packet->header.u32all = build_pm4_header(IT_UNMAP_QUEUES,
                                        sizeof(struct pm4_unmap_queues));
        switch (type) {
@@ -529,6 +639,11 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
                packet->bitfields2.queue_sel =
                                queue_sel__mes_unmap_queues__perform_request_on_all_active_queues;
                break;
+       case KFD_PREEMPT_TYPE_FILTER_DYNAMIC_QUEUES:
+               /* in this case, we do not preempt static queues */
+               packet->bitfields2.queue_sel =
+                               queue_sel__mes_unmap_queues__perform_request_on_dynamic_queues_only;
+               break;
        default:
                BUG();
                break;