Merge tag 'defconfig-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / amdkfd / kfd_device_queue_manager.c
index 16a1713..f8fce9d 100644 (file)
@@ -211,6 +211,15 @@ static void deallocate_doorbell(struct qcm_process_device *qpd,
        WARN_ON(!old);
 }
 
+static void program_trap_handler_settings(struct device_queue_manager *dqm,
+                               struct qcm_process_device *qpd)
+{
+       if (dqm->dev->kfd2kgd->program_trap_handler_settings)
+               dqm->dev->kfd2kgd->program_trap_handler_settings(
+                                               dqm->dev->kgd, qpd->vmid,
+                                               qpd->tba_addr, qpd->tma_addr);
+}
+
 static int allocate_vmid(struct device_queue_manager *dqm,
                        struct qcm_process_device *qpd,
                        struct queue *q)
@@ -241,6 +250,10 @@ static int allocate_vmid(struct device_queue_manager *dqm,
 
        program_sh_mem_settings(dqm, qpd);
 
+       if (dqm->dev->device_info->asic_family >= CHIP_VEGA10 &&
+           dqm->dev->cwsr_enabled)
+               program_trap_handler_settings(dqm, qpd);
+
        /* qpd->page_table_base is set earlier when register_process()
         * is called, i.e. when the first queue is created.
         */
@@ -260,7 +273,7 @@ static int allocate_vmid(struct device_queue_manager *dqm,
 static int flush_texture_cache_nocpsch(struct kfd_dev *kdev,
                                struct qcm_process_device *qpd)
 {
-       const struct packet_manager_funcs *pmf = qpd->dqm->packets.pmf;
+       const struct packet_manager_funcs *pmf = qpd->dqm->packet_mgr.pmf;
        int ret;
 
        if (!qpd->ib_kaddr)
@@ -582,7 +595,9 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
                }
 
                retval = mqd_mgr->destroy_mqd(mqd_mgr, q->mqd,
-                               KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN,
+                               (dqm->dev->cwsr_enabled?
+                                KFD_PREEMPT_TYPE_WAVEFRONT_SAVE:
+                               KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN),
                                KFD_UNMAP_LATENCY_MS, q->pipe, q->queue);
                if (retval) {
                        pr_err("destroy mqd failed\n");
@@ -675,7 +690,9 @@ static int evict_process_queues_nocpsch(struct device_queue_manager *dqm,
                        continue;
 
                retval = mqd_mgr->destroy_mqd(mqd_mgr, q->mqd,
-                               KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN,
+                               (dqm->dev->cwsr_enabled?
+                                KFD_PREEMPT_TYPE_WAVEFRONT_SAVE:
+                               KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN),
                                KFD_UNMAP_LATENCY_MS, q->pipe, q->queue);
                if (retval && !ret)
                        /* Return the first error, but keep going to
@@ -1000,7 +1017,7 @@ static int start_nocpsch(struct device_queue_manager *dqm)
        init_interrupts(dqm);
        
        if (dqm->dev->device_info->asic_family == CHIP_HAWAII)
-               return pm_init(&dqm->packets, dqm);
+               return pm_init(&dqm->packet_mgr, dqm);
        dqm->sched_running = true;
 
        return 0;
@@ -1009,7 +1026,7 @@ static int start_nocpsch(struct device_queue_manager *dqm)
 static int stop_nocpsch(struct device_queue_manager *dqm)
 {
        if (dqm->dev->device_info->asic_family == CHIP_HAWAII)
-               pm_uninit(&dqm->packets, false);
+               pm_uninit(&dqm->packet_mgr, false);
        dqm->sched_running = false;
 
        return 0;
@@ -1124,7 +1141,7 @@ static int set_sched_resources(struct device_queue_manager *dqm)
                        "queue mask: 0x%8llX\n",
                        res.vmid_mask, res.queue_mask);
 
-       return pm_send_set_resources(&dqm->packets, &res);
+       return pm_send_set_resources(&dqm->packet_mgr, &res);
 }
 
 static int initialize_cpsch(struct device_queue_manager *dqm)
@@ -1164,7 +1181,8 @@ static int start_cpsch(struct device_queue_manager *dqm)
 
        retval = 0;
 
-       retval = pm_init(&dqm->packets, dqm);
+       dqm_lock(dqm);
+       retval = pm_init(&dqm->packet_mgr, dqm);
        if (retval)
                goto fail_packet_manager_init;
 
@@ -1186,7 +1204,6 @@ static int start_cpsch(struct device_queue_manager *dqm)
 
        init_interrupts(dqm);
 
-       dqm_lock(dqm);
        /* clear hang status when driver try to start the hw scheduler */
        dqm->is_hws_hang = false;
        dqm->is_resetting = false;
@@ -1197,8 +1214,9 @@ static int start_cpsch(struct device_queue_manager *dqm)
        return 0;
 fail_allocate_vidmem:
 fail_set_sched_resources:
-       pm_uninit(&dqm->packets, false);
+       pm_uninit(&dqm->packet_mgr, false);
 fail_packet_manager_init:
+       dqm_unlock(dqm);
        return retval;
 }
 
@@ -1211,12 +1229,12 @@ static int stop_cpsch(struct device_queue_manager *dqm)
                unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0);
        hanging = dqm->is_hws_hang || dqm->is_resetting;
        dqm->sched_running = false;
-       dqm_unlock(dqm);
 
-       pm_release_ib(&dqm->packets);
+       pm_release_ib(&dqm->packet_mgr);
 
        kfd_gtt_sa_free(dqm->dev, dqm->fence_mem);
-       pm_uninit(&dqm->packets, hanging);
+       pm_uninit(&dqm->packet_mgr, hanging);
+       dqm_unlock(dqm);
 
        return 0;
 }
@@ -1390,7 +1408,7 @@ static int map_queues_cpsch(struct device_queue_manager *dqm)
        if (dqm->active_runlist)
                return 0;
 
-       retval = pm_send_runlist(&dqm->packets, &dqm->queues);
+       retval = pm_send_runlist(&dqm->packet_mgr, &dqm->queues);
        pr_debug("%s sent runlist\n", __func__);
        if (retval) {
                pr_err("failed to execute runlist\n");
@@ -1416,13 +1434,13 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm,
        if (!dqm->active_runlist)
                return retval;
 
-       retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_COMPUTE,
+       retval = pm_send_unmap_queue(&dqm->packet_mgr, KFD_QUEUE_TYPE_COMPUTE,
                        filter, filter_param, false, 0);
        if (retval)
                return retval;
 
        *dqm->fence_addr = KFD_FENCE_INIT;
-       pm_send_query_status(&dqm->packets, dqm->fence_gpu_addr,
+       pm_send_query_status(&dqm->packet_mgr, dqm->fence_gpu_addr,
                                KFD_FENCE_COMPLETED);
        /* should be timed out */
        retval = amdkfd_fence_wait_timeout(dqm->fence_addr, KFD_FENCE_COMPLETED,
@@ -1448,14 +1466,14 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm,
         * check those fields
         */
        mqd_mgr = dqm->mqd_mgrs[KFD_MQD_TYPE_HIQ];
-       if (mqd_mgr->read_doorbell_id(dqm->packets.priv_queue->queue->mqd)) {
+       if (mqd_mgr->read_doorbell_id(dqm->packet_mgr.priv_queue->queue->mqd)) {
                pr_err("HIQ MQD's queue_doorbell_id0 is not 0, Queue preemption time out\n");
                while (halt_if_hws_hang)
                        schedule();
                return -ETIME;
        }
 
-       pm_release_ib(&dqm->packets);
+       pm_release_ib(&dqm->packet_mgr);
        dqm->active_runlist = false;
 
        return retval;
@@ -1946,6 +1964,7 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
        case CHIP_DIMGREY_CAVEFISH:
        case CHIP_BEIGE_GOBY:
        case CHIP_YELLOW_CARP:
+       case CHIP_CYAN_SKILLFISH:
                device_queue_manager_init_v10_navi10(&dqm->asic_ops);
                break;
        default:
@@ -2099,11 +2118,16 @@ int dqm_debugfs_hqds(struct seq_file *m, void *data)
        return r;
 }
 
-int dqm_debugfs_execute_queues(struct device_queue_manager *dqm)
+int dqm_debugfs_hang_hws(struct device_queue_manager *dqm)
 {
        int r = 0;
 
        dqm_lock(dqm);
+       r = pm_debugfs_hang_hws(&dqm->packet_mgr);
+       if (r) {
+               dqm_unlock(dqm);
+               return r;
+       }
        dqm->active_runlist = true;
        r = execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0);
        dqm_unlock(dqm);