diff options
Diffstat (limited to 'drivers/accel/ivpu/ivpu_drv.c')
-rw-r--r-- | drivers/accel/ivpu/ivpu_drv.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index f3e0d55f4adb..c91400ecf926 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -58,11 +58,11 @@ module_param_named(sched_mode, ivpu_sched_mode, int, 0444); MODULE_PARM_DESC(sched_mode, "Scheduler mode: 0 - Default scheduler, 1 - Force HW scheduler"); bool ivpu_disable_mmu_cont_pages; -module_param_named(disable_mmu_cont_pages, ivpu_disable_mmu_cont_pages, bool, 0644); +module_param_named(disable_mmu_cont_pages, ivpu_disable_mmu_cont_pages, bool, 0444); MODULE_PARM_DESC(disable_mmu_cont_pages, "Disable MMU contiguous pages optimization"); bool ivpu_force_snoop; -module_param_named(force_snoop, ivpu_force_snoop, bool, 0644); +module_param_named(force_snoop, ivpu_force_snoop, bool, 0444); MODULE_PARM_DESC(force_snoop, "Force snooping for NPU host memory access"); struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv) @@ -391,8 +391,13 @@ int ivpu_boot(struct ivpu_device *vdev) ivpu_hw_irq_enable(vdev); ivpu_ipc_enable(vdev); - if (ivpu_fw_is_cold_boot(vdev)) + if (ivpu_fw_is_cold_boot(vdev)) { + ret = ivpu_pm_dct_init(vdev); + if (ret) + return ret; + return ivpu_hw_sched_init(vdev); + } return 0; } @@ -446,6 +451,26 @@ static const struct drm_driver driver = { .minor = DRM_IVPU_DRIVER_MINOR, }; +static void ivpu_context_abort_invalid(struct ivpu_device *vdev) +{ + struct ivpu_file_priv *file_priv; + unsigned long ctx_id; + + mutex_lock(&vdev->context_list_lock); + + xa_for_each(&vdev->context_xa, ctx_id, file_priv) { + if (!file_priv->has_mmu_faults || file_priv->aborted) + continue; + + mutex_lock(&file_priv->lock); + ivpu_context_abort_locked(file_priv); + file_priv->aborted = true; + mutex_unlock(&file_priv->lock); + } + + mutex_unlock(&vdev->context_list_lock); +} + static irqreturn_t ivpu_irq_thread_handler(int irq, void *arg) { struct ivpu_device *vdev = arg; @@ -459,6 +484,12 @@ static irqreturn_t ivpu_irq_thread_handler(int irq, void *arg) case IVPU_HW_IRQ_SRC_IPC: ivpu_ipc_irq_thread_handler(vdev); break; + case IVPU_HW_IRQ_SRC_MMU_EVTQ: + ivpu_context_abort_invalid(vdev); + break; + case IVPU_HW_IRQ_SRC_DCT: + ivpu_pm_dct_irq_thread_handler(vdev); + break; default: ivpu_err_ratelimited(vdev, "Unknown IRQ source: %u\n", irq_src); break; @@ -664,14 +695,14 @@ static void ivpu_bo_unbind_all_user_contexts(struct ivpu_device *vdev) static void ivpu_dev_fini(struct ivpu_device *vdev) { + ivpu_jobs_abort_all(vdev); + ivpu_pm_cancel_recovery(vdev); ivpu_pm_disable(vdev); ivpu_prepare_for_reset(vdev); ivpu_shutdown(vdev); ivpu_ms_cleanup_all(vdev); - ivpu_jobs_abort_all(vdev); ivpu_job_done_consumer_fini(vdev); - ivpu_pm_cancel_recovery(vdev); ivpu_bo_unbind_all_user_contexts(vdev); ivpu_ipc_fini(vdev); |