From 275c4dac9fe565b304814a80f3f563623e65d1ba Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 01/64] Revert "accel/ivpu: remove driver date from struct drm_driver and all drivers" This reverts commit 1f3bdedb0eec6e63d11328b5737a2f43a9c6287f. --- drivers/accel/ivpu/ivpu_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 1e8ffbe25eee..1f359dbe5150 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -458,6 +458,7 @@ static const struct drm_driver driver = { .name = DRIVER_NAME, .desc = DRIVER_DESC, + .date = UTS_RELEASE, .major = 1, }; From 90193c4d1d31e19124dcf129235710d1dcda62ec Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 02/64] Revert "accel/ivpu: remove DRIVER_DATE conditional drm_driver init" This reverts commit b0fb21c957b3241aa9d4712a042304b15696b420. --- drivers/accel/ivpu/ivpu_drv.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 1f359dbe5150..ca2bf47ce248 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -458,8 +458,15 @@ static const struct drm_driver driver = { .name = DRIVER_NAME, .desc = DRIVER_DESC, +#ifdef DRIVER_DATE + .date = DRIVER_DATE, + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, + .patchlevel = DRIVER_PATCHLEVEL, +#else .date = UTS_RELEASE, .major = 1, +#endif }; static void ivpu_context_abort_invalid(struct ivpu_device *vdev) From 5175ebd1481711be5e49014ab15fcb5afacd5952 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 03/64] Revert "accel/ivpu: Fix Qemu crash when running in passthrough" This reverts commit e7c695219dfe965de4733e188d4de9ba08550882. --- drivers/accel/ivpu/ivpu_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 87d7411ae059..949f4233946c 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -78,8 +78,8 @@ static int ivpu_resume(struct ivpu_device *vdev) int ret; retry: - pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D0); pci_restore_state(to_pci_dev(vdev->drm.dev)); + pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D0); ret = ivpu_hw_power_up(vdev); if (ret) { From ce740acbf3416df65031cd90dec0b9279bae1135 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 04/64] Revert "accel/ivpu: Fix WARN in ivpu_ipc_send_receive_internal()" This reverts commit 922c8bb776f20f2827fb9972d15ef4d052801ccb. --- drivers/accel/ivpu/ivpu_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 949f4233946c..dbc0711e28d1 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -378,7 +378,6 @@ void ivpu_pm_init(struct ivpu_device *vdev) pm_runtime_use_autosuspend(dev); pm_runtime_set_autosuspend_delay(dev, delay); - pm_runtime_set_active(dev); ivpu_dbg(vdev, PM, "Autosuspend delay = %d\n", delay); } @@ -393,6 +392,7 @@ void ivpu_pm_enable(struct ivpu_device *vdev) { struct device *dev = vdev->drm.dev; + pm_runtime_set_active(dev); pm_runtime_allow(dev); pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); From c0d15622f0ca29d869352c4ecb89ff15a88c8b57 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 05/64] Revert "accel/ivpu: Fix memory leak in ivpu_mmu_reserved_context_init()" This reverts commit 23d02fbe6ad427e806ebe9b3ce0787e3c8e41212. --- drivers/accel/ivpu/ivpu_mmu_context.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c index 0af614dfb6f9..891967a95bc3 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.c +++ b/drivers/accel/ivpu/ivpu_mmu_context.c @@ -612,22 +612,18 @@ int ivpu_mmu_reserved_context_init(struct ivpu_device *vdev) if (!ivpu_mmu_ensure_pgd(vdev, &vdev->rctx.pgtable)) { ivpu_err(vdev, "Failed to allocate root page table for reserved context\n"); ret = -ENOMEM; - goto err_ctx_fini; + goto unlock; } ret = ivpu_mmu_cd_set(vdev, vdev->rctx.id, &vdev->rctx.pgtable); if (ret) { ivpu_err(vdev, "Failed to set context descriptor for reserved context\n"); - goto err_ctx_fini; + goto unlock; } +unlock: mutex_unlock(&vdev->rctx.lock); return ret; - -err_ctx_fini: - mutex_unlock(&vdev->rctx.lock); - ivpu_mmu_context_fini(vdev, &vdev->rctx); - return ret; } void ivpu_mmu_reserved_context_fini(struct ivpu_device *vdev) From 9758427076d71a4a54ad699cc9a60a595d1e03dd Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 06/64] Revert "accel/ivpu: Fix general protection fault in ivpu_bo_list()" This reverts commit 11b1be5dd31ff7a2ea719d59ba3651ceb9b937ab. --- drivers/accel/ivpu/ivpu_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c index 16178054e629..d8e97a760fbc 100644 --- a/drivers/accel/ivpu/ivpu_gem.c +++ b/drivers/accel/ivpu/ivpu_gem.c @@ -409,7 +409,7 @@ static void ivpu_bo_print_info(struct ivpu_bo *bo, struct drm_printer *p) mutex_lock(&bo->lock); drm_printf(p, "%-9p %-3u 0x%-12llx %-10lu 0x%-8x %-4u", - bo, bo->ctx ? bo->ctx->id : 0, bo->vpu_addr, bo->base.base.size, + bo, bo->ctx->id, bo->vpu_addr, bo->base.base.size, bo->flags, kref_read(&bo->base.base.refcount)); if (bo->base.pages) From 93e5c3be0fb6ae6bb7e02c5c3886bdfe93e830b6 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 07/64] Revert "accel/ivpu: Move secondary preemption buffer allocation to DMA range" This reverts commit df10ce0a370e04eb92b8d3b6dbe28d68ca1a9d9c. --- drivers/accel/ivpu/ivpu_job.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 7149312f16e1..39ba6d3d8b0d 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -46,7 +46,7 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, return -ENOMEM; } - cmdq->secondary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.dma, + cmdq->secondary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.shave, secondary_size, DRM_IVPU_BO_WC); if (!cmdq->secondary_preempt_buf) { ivpu_err(vdev, "Failed to create secondary preemption buffer\n"); From 433892baa76911c56aca5c3bec7b8258e55db87f Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 08/64] Revert "accel/ivpu: Increase DMA address range" This reverts commit 5ab399673929a0295abd4f496c71dc0d08aa7d80. --- drivers/accel/ivpu/ivpu_fw.c | 6 ++---- drivers/accel/ivpu/ivpu_hw.c | 10 +++++----- drivers/accel/ivpu/ivpu_mmu_context.c | 4 ++-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index 6037ec0b3096..d358cf0b0f97 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -584,10 +584,8 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params boot_params->ipc_payload_area_start = ipc_mem_rx->vpu_addr + ivpu_bo_size(ipc_mem_rx) / 2; boot_params->ipc_payload_area_size = ivpu_bo_size(ipc_mem_rx) / 2; - if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) { - boot_params->global_aliased_pio_base = vdev->hw->ranges.user.start; - boot_params->global_aliased_pio_size = ivpu_hw_range_size(&vdev->hw->ranges.user); - } + boot_params->global_aliased_pio_base = vdev->hw->ranges.user.start; + boot_params->global_aliased_pio_size = ivpu_hw_range_size(&vdev->hw->ranges.user); /* Allow configuration for L2C_PAGE_TABLE with boot param value */ boot_params->autoconfig = 1; diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index 4e1054f3466e..f1f5e0c4961b 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -114,14 +114,14 @@ static void memory_ranges_init(struct ivpu_device *vdev) { if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) { ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M); - ivpu_hw_range_init(&vdev->hw->ranges.user, 0x88000000, 511 * SZ_1M); + ivpu_hw_range_init(&vdev->hw->ranges.user, 0xc0000000, 255 * SZ_1M); ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x180000000, SZ_2G); - ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_128G); + ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_8G); } else { ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M); - ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x80000000, SZ_2G); - ivpu_hw_range_init(&vdev->hw->ranges.user, 0x100000000, SZ_256G); - vdev->hw->ranges.dma = vdev->hw->ranges.user; + ivpu_hw_range_init(&vdev->hw->ranges.user, 0x80000000, SZ_256M); + ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x80000000 + SZ_256M, SZ_2G - SZ_256M); + ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_8G); } } diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c index 891967a95bc3..697b57071d54 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.c +++ b/drivers/accel/ivpu/ivpu_mmu_context.c @@ -571,8 +571,8 @@ void ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ct start = vdev->hw->ranges.global.start; end = vdev->hw->ranges.shave.end; } else { - start = min_t(u64, vdev->hw->ranges.user.start, vdev->hw->ranges.shave.start); - end = max_t(u64, vdev->hw->ranges.user.end, vdev->hw->ranges.dma.end); + start = vdev->hw->ranges.user.start; + end = vdev->hw->ranges.dma.end; } drm_mm_init(&ctx->mm, start, end - start); From 658cc029838cb34ffd8e324a18c2494fcc9c9fae Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 09/64] Revert "accel/ivpu: Add debug Kconfig option" This reverts commit f62f0769b5b7e90936577ac4decfe9a990286943. --- drivers/accel/ivpu/Kconfig | 9 --------- drivers/accel/ivpu/Makefile | 2 -- drivers/accel/ivpu/ivpu_drv.c | 2 -- drivers/accel/ivpu/ivpu_fw.c | 2 -- drivers/accel/ivpu/ivpu_pm.c | 2 -- 5 files changed, 17 deletions(-) diff --git a/drivers/accel/ivpu/Kconfig b/drivers/accel/ivpu/Kconfig index 9e055b5ce03d..e4d418b44626 100644 --- a/drivers/accel/ivpu/Kconfig +++ b/drivers/accel/ivpu/Kconfig @@ -16,12 +16,3 @@ config DRM_ACCEL_IVPU and Deep Learning applications. If "M" is selected, the module will be called intel_vpu. - -config DRM_ACCEL_IVPU_DEBUG - bool "Intel NPU debug mode" - depends on DRM_ACCEL_IVPU - help - Choose this option to enable additional - debug features for the Intel NPU driver: - - Always print debug messages regardless of dyndbg config, - - Enable unsafe module params. diff --git a/drivers/accel/ivpu/Makefile b/drivers/accel/ivpu/Makefile index 1029e0bab061..e73937c86d9a 100644 --- a/drivers/accel/ivpu/Makefile +++ b/drivers/accel/ivpu/Makefile @@ -24,6 +24,4 @@ intel_vpu-$(CONFIG_DEV_COREDUMP) += ivpu_coredump.o obj-$(CONFIG_DRM_ACCEL_IVPU) += intel_vpu.o -subdir-ccflags-$(CONFIG_DRM_ACCEL_IVPU_DEBUG) += -DDEBUG - CFLAGS_ivpu_trace_points.o = -I$(src) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index ca2bf47ce248..f5a8d93fe2a5 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -43,10 +43,8 @@ module_param_named(dbg_mask, ivpu_dbg_mask, int, 0644); MODULE_PARM_DESC(dbg_mask, "Driver debug mask. See IVPU_DBG_* macros."); int ivpu_test_mode; -#if IS_ENABLED(CONFIG_DRM_ACCEL_IVPU_DEBUG) module_param_named_unsafe(test_mode, ivpu_test_mode, int, 0644); MODULE_PARM_DESC(test_mode, "Test mode mask. See IVPU_TEST_MODE_* macros."); -#endif u8 ivpu_pll_min_ratio; module_param_named(pll_min_ratio, ivpu_pll_min_ratio, byte, 0644); diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index d358cf0b0f97..be367465e7df 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -46,10 +46,8 @@ #define IVPU_FOCUS_PRESENT_TIMER_MS 1000 static char *ivpu_firmware; -#if IS_ENABLED(CONFIG_DRM_ACCEL_IVPU_DEBUG) module_param_named_unsafe(firmware, ivpu_firmware, charp, 0644); MODULE_PARM_DESC(firmware, "NPU firmware binary in /lib/firmware/.."); -#endif static struct { int gen; diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index dbc0711e28d1..e567df79a612 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -24,10 +24,8 @@ #include "vpu_boot_api.h" static bool ivpu_disable_recovery; -#if IS_ENABLED(CONFIG_DRM_ACCEL_IVPU_DEBUG) module_param_named_unsafe(disable_recovery, ivpu_disable_recovery, bool, 0644); MODULE_PARM_DESC(disable_recovery, "Disables recovery when NPU hang is detected"); -#endif static unsigned long ivpu_tdr_timeout_ms; module_param_named(tdr_timeout_ms, ivpu_tdr_timeout_ms, ulong, 0644); From 363008127b7b17017342496084ba9eefb54dcbca Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 10/64] Revert "accel/ivpu: Don't allocate preemption buffers when MIP is disabled" This reverts commit 5bdb9a77ee52589f49ee0612b7376077eb98fb8e. --- drivers/accel/ivpu/ivpu_drv.h | 2 +- drivers/accel/ivpu/ivpu_job.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 3fdff3f6cffd..8e79d78906bf 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -197,7 +197,7 @@ extern bool ivpu_force_snoop; #define IVPU_TEST_MODE_NULL_SUBMISSION BIT(2) #define IVPU_TEST_MODE_D0I3_MSG_DISABLE BIT(4) #define IVPU_TEST_MODE_D0I3_MSG_ENABLE BIT(5) -#define IVPU_TEST_MODE_MIP_DISABLE BIT(6) +#define IVPU_TEST_MODE_PREEMPTION_DISABLE BIT(6) #define IVPU_TEST_MODE_DISABLE_TIMEOUTS BIT(8) #define IVPU_TEST_MODE_TURBO BIT(9) extern int ivpu_test_mode; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 39ba6d3d8b0d..82a57a30244d 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -35,8 +35,7 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, u64 primary_size = ALIGN(vdev->fw->primary_preempt_buf_size, PAGE_SIZE); u64 secondary_size = ALIGN(vdev->fw->secondary_preempt_buf_size, PAGE_SIZE); - if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW || - ivpu_test_mode & IVPU_TEST_MODE_MIP_DISABLE) + if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) return 0; cmdq->primary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.user, @@ -348,7 +347,8 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_SUBMISSION)) entry->flags = VPU_JOB_FLAGS_NULL_SUBMISSION_MASK; - if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW && + (unlikely(!(ivpu_test_mode & IVPU_TEST_MODE_PREEMPTION_DISABLE)))) { if (cmdq->primary_preempt_buf) { entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr; entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf); From c4164086cebd3719563fd5d08dc5d0e11a2af6b5 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 11/64] Revert "accel/ivpu: Make command queue ID allocated on XArray" This reverts commit d90710ac8ecacba367421a69c38537ce57dffb43. --- drivers/accel/ivpu/ivpu_drv.c | 6 --- drivers/accel/ivpu/ivpu_drv.h | 7 +-- drivers/accel/ivpu/ivpu_job.c | 91 +++++++++++++++++------------------ drivers/accel/ivpu/ivpu_job.h | 2 - 4 files changed, 46 insertions(+), 60 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index f5a8d93fe2a5..383e3eb98898 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -104,8 +104,6 @@ static void file_priv_release(struct kref *ref) pm_runtime_get_sync(vdev->drm.dev); mutex_lock(&vdev->context_list_lock); file_priv_unbind(vdev, file_priv); - drm_WARN_ON(&vdev->drm, !xa_empty(&file_priv->cmdq_xa)); - xa_destroy(&file_priv->cmdq_xa); mutex_unlock(&vdev->context_list_lock); pm_runtime_put_autosuspend(vdev->drm.dev); @@ -261,10 +259,6 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) file_priv->job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); file_priv->job_limit.max = file_priv->job_limit.min | IVPU_JOB_ID_JOB_MASK; - xa_init_flags(&file_priv->cmdq_xa, XA_FLAGS_ALLOC1); - file_priv->cmdq_limit.min = IVPU_CMDQ_MIN_ID; - file_priv->cmdq_limit.max = IVPU_CMDQ_MAX_ID; - mutex_unlock(&vdev->context_list_lock); drm_dev_exit(idx); diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 8e79d78906bf..677440282170 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -52,9 +52,6 @@ #define IVPU_NUM_PRIORITIES 4 #define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_PRIORITIES) -#define IVPU_CMDQ_MIN_ID 1 -#define IVPU_CMDQ_MAX_ID 255 - #define IVPU_PLATFORM_SILICON 0 #define IVPU_PLATFORM_SIMICS 2 #define IVPU_PLATFORM_FPGA 3 @@ -171,15 +168,13 @@ struct ivpu_file_priv { struct kref ref; struct ivpu_device *vdev; struct mutex lock; /* Protects cmdq */ - struct xarray cmdq_xa; + struct ivpu_cmdq *cmdq[IVPU_NUM_CMDQS_PER_CTX]; struct ivpu_mmu_context ctx; struct mutex ms_lock; /* Protects ms_instance_list, ms_info_bo */ struct list_head ms_instance_list; struct ivpu_bo *ms_info_bo; struct xa_limit job_limit; u32 job_id_next; - struct xa_limit cmdq_limit; - u32 cmdq_id_next; bool has_mmu_faults; bool bound; bool aborted; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 82a57a30244d..9154c2e14245 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -89,16 +89,9 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) goto err_free_cmdq; } - ret = xa_alloc_cyclic(&file_priv->cmdq_xa, &cmdq->id, cmdq, file_priv->cmdq_limit, - &file_priv->cmdq_id_next, GFP_KERNEL); - if (ret < 0) { - ivpu_err(vdev, "Failed to allocate command queue id: %d\n", ret); - goto err_erase_db_xa; - } - cmdq->mem = ivpu_bo_create_global(vdev, SZ_4K, DRM_IVPU_BO_WC | DRM_IVPU_BO_MAPPABLE); if (!cmdq->mem) - goto err_erase_cmdq_xa; + goto err_erase_xa; ret = ivpu_preemption_buffers_create(vdev, file_priv, cmdq); if (ret) @@ -106,9 +99,7 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) return cmdq; -err_erase_cmdq_xa: - xa_erase(&file_priv->cmdq_xa, cmdq->id); -err_erase_db_xa: +err_erase_xa: xa_erase(&vdev->db_xa, cmdq->db_id); err_free_cmdq: kfree(cmdq); @@ -132,13 +123,13 @@ static int ivpu_hws_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq struct ivpu_device *vdev = file_priv->vdev; int ret; - ret = ivpu_jsm_hws_create_cmdq(vdev, file_priv->ctx.id, file_priv->ctx.id, cmdq->id, + ret = ivpu_jsm_hws_create_cmdq(vdev, file_priv->ctx.id, file_priv->ctx.id, cmdq->db_id, task_pid_nr(current), engine, cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); if (ret) return ret; - ret = ivpu_jsm_hws_set_context_sched_properties(vdev, file_priv->ctx.id, cmdq->id, + ret = ivpu_jsm_hws_set_context_sched_properties(vdev, file_priv->ctx.id, cmdq->db_id, priority); if (ret) return ret; @@ -152,21 +143,20 @@ static int ivpu_register_db(struct ivpu_file_priv *file_priv, struct ivpu_cmdq * int ret; if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) - ret = ivpu_jsm_hws_register_db(vdev, file_priv->ctx.id, cmdq->id, cmdq->db_id, + ret = ivpu_jsm_hws_register_db(vdev, file_priv->ctx.id, cmdq->db_id, cmdq->db_id, cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); else ret = ivpu_jsm_register_db(vdev, file_priv->ctx.id, cmdq->db_id, cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); if (!ret) - ivpu_dbg(vdev, JOB, "DB %d registered to cmdq %d ctx %d\n", - cmdq->db_id, cmdq->id, file_priv->ctx.id); + ivpu_dbg(vdev, JOB, "DB %d registered to ctx %d\n", cmdq->db_id, file_priv->ctx.id); return ret; } static int -ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u8 priority) +ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 engine, u8 priority) { struct ivpu_device *vdev = file_priv->vdev; struct vpu_job_queue_header *jobq_header; @@ -182,7 +172,7 @@ ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u8 prio cmdq->jobq = (struct vpu_job_queue *)ivpu_bo_vaddr(cmdq->mem); jobq_header = &cmdq->jobq->header; - jobq_header->engine_idx = VPU_ENGINE_COMPUTE; + jobq_header->engine_idx = engine; jobq_header->head = 0; jobq_header->tail = 0; if (ivpu_test_mode & IVPU_TEST_MODE_TURBO) { @@ -193,7 +183,7 @@ ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u8 prio wmb(); /* Flush WC buffer for jobq->header */ if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { - ret = ivpu_hws_cmdq_init(file_priv, cmdq, VPU_ENGINE_COMPUTE, priority); + ret = ivpu_hws_cmdq_init(file_priv, cmdq, engine, priority); if (ret) return ret; } @@ -220,9 +210,9 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm cmdq->db_registered = false; if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { - ret = ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->id); + ret = ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->db_id); if (!ret) - ivpu_dbg(vdev, JOB, "Command queue %d destroyed\n", cmdq->id); + ivpu_dbg(vdev, JOB, "Command queue %d destroyed\n", cmdq->db_id); } ret = ivpu_jsm_unregister_db(vdev, cmdq->db_id); @@ -232,46 +222,51 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm return 0; } -static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u8 priority) +static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 engine, + u8 priority) { - struct ivpu_cmdq *cmdq; - unsigned long cmdq_id; + struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; int ret; lockdep_assert_held(&file_priv->lock); - xa_for_each(&file_priv->cmdq_xa, cmdq_id, cmdq) - if (cmdq->priority == priority) - break; - if (!cmdq) { cmdq = ivpu_cmdq_alloc(file_priv); if (!cmdq) return NULL; - cmdq->priority = priority; + file_priv->cmdq[priority] = cmdq; } - ret = ivpu_cmdq_init(file_priv, cmdq, priority); + ret = ivpu_cmdq_init(file_priv, cmdq, engine, priority); if (ret) return NULL; return cmdq; } -void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) +static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u8 priority) { - struct ivpu_cmdq *cmdq; - unsigned long cmdq_id; + struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; lockdep_assert_held(&file_priv->lock); - xa_for_each(&file_priv->cmdq_xa, cmdq_id, cmdq) { - xa_erase(&file_priv->cmdq_xa, cmdq_id); + if (cmdq) { + file_priv->cmdq[priority] = NULL; ivpu_cmdq_fini(file_priv, cmdq); ivpu_cmdq_free(file_priv, cmdq); } } +void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) +{ + u8 priority; + + lockdep_assert_held(&file_priv->lock); + + for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) + ivpu_cmdq_release_locked(file_priv, priority); +} + /* * Mark the doorbell as unregistered * This function needs to be called when the VPU hardware is restarted @@ -280,13 +275,16 @@ void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) */ static void ivpu_cmdq_reset(struct ivpu_file_priv *file_priv) { - struct ivpu_cmdq *cmdq; - unsigned long cmdq_id; + u8 priority; mutex_lock(&file_priv->lock); - xa_for_each(&file_priv->cmdq_xa, cmdq_id, cmdq) - cmdq->db_registered = false; + for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { + struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; + + if (cmdq) + cmdq->db_registered = false; + } mutex_unlock(&file_priv->lock); } @@ -306,11 +304,12 @@ void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev) static void ivpu_cmdq_fini_all(struct ivpu_file_priv *file_priv) { - struct ivpu_cmdq *cmdq; - unsigned long cmdq_id; + u8 priority; - xa_for_each(&file_priv->cmdq_xa, cmdq_id, cmdq) - ivpu_cmdq_fini(file_priv, cmdq); + for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { + if (file_priv->cmdq[priority]) + ivpu_cmdq_fini(file_priv, file_priv->cmdq[priority]); + } } void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv) @@ -335,8 +334,8 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) /* Check if there is space left in job queue */ if (next_entry == header->head) { - ivpu_dbg(vdev, JOB, "Job queue full: ctx %d cmdq %d db %d head %d tail %d\n", - job->file_priv->ctx.id, cmdq->id, cmdq->db_id, header->head, tail); + ivpu_dbg(vdev, JOB, "Job queue full: ctx %d engine %d db %d head %d tail %d\n", + job->file_priv->ctx.id, job->engine_idx, cmdq->db_id, header->head, tail); return -EBUSY; } @@ -523,7 +522,7 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) mutex_lock(&file_priv->lock); - cmdq = ivpu_cmdq_acquire(file_priv, priority); + cmdq = ivpu_cmdq_acquire(file_priv, job->engine_idx, priority); if (!cmdq) { ivpu_warn_ratelimited(vdev, "Failed to get job queue, ctx %d engine %d prio %d\n", file_priv->ctx.id, job->engine_idx, priority); diff --git a/drivers/accel/ivpu/ivpu_job.h b/drivers/accel/ivpu/ivpu_job.h index 8b19e3f8b4cf..6accb94028c7 100644 --- a/drivers/accel/ivpu/ivpu_job.h +++ b/drivers/accel/ivpu/ivpu_job.h @@ -28,10 +28,8 @@ struct ivpu_cmdq { struct ivpu_bo *secondary_preempt_buf; struct ivpu_bo *mem; u32 entry_count; - u32 id; u32 db_id; bool db_registered; - u8 priority; }; /** From 41aee0fab8852594fc40487c245d3103a0a1a3b9 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 12/64] Revert "accel/ivpu: Use xa_alloc_cyclic() instead of custom function" This reverts commit 7da82982efba58e8e143f6d93cc612a1b5d6a17b. --- drivers/accel/ivpu/ivpu_drv.c | 11 +++++++---- drivers/accel/ivpu/ivpu_drv.h | 4 ++-- drivers/accel/ivpu/ivpu_job.c | 34 ++++++++++++++++++++++++++++------ 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 383e3eb98898..34e3e9b1c3f2 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -256,8 +256,10 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) ivpu_mmu_context_init(vdev, &file_priv->ctx, ctx_id); - file_priv->job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); - file_priv->job_limit.max = file_priv->job_limit.min | IVPU_JOB_ID_JOB_MASK; + file_priv->default_job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, + (file_priv->ctx.id - 1)); + file_priv->default_job_limit.max = file_priv->default_job_limit.min | IVPU_JOB_ID_JOB_MASK; + file_priv->job_limit = file_priv->default_job_limit; mutex_unlock(&vdev->context_list_lock); drm_dev_exit(idx); @@ -616,8 +618,9 @@ static int ivpu_dev_init(struct ivpu_device *vdev) lockdep_set_class(&vdev->submitted_jobs_xa.xa_lock, &submitted_jobs_xa_lock_class_key); INIT_LIST_HEAD(&vdev->bo_list); - vdev->db_limit.min = IVPU_MIN_DB; - vdev->db_limit.max = IVPU_MAX_DB; + vdev->default_db_limit.min = IVPU_MIN_DB; + vdev->default_db_limit.max = IVPU_MAX_DB; + vdev->db_limit = vdev->default_db_limit; ret = drmm_mutex_init(&vdev->drm, &vdev->context_list_lock); if (ret) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 677440282170..5b4f5104b470 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -137,7 +137,7 @@ struct ivpu_device { struct xarray db_xa; struct xa_limit db_limit; - u32 db_next; + struct xa_limit default_db_limit; struct mutex bo_list_lock; /* Protects bo_list */ struct list_head bo_list; @@ -174,7 +174,7 @@ struct ivpu_file_priv { struct list_head ms_instance_list; struct ivpu_bo *ms_info_bo; struct xa_limit job_limit; - u32 job_id_next; + struct xa_limit default_job_limit; bool has_mmu_faults; bool bound; bool aborted; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 9154c2e14245..f580959e8778 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -72,6 +72,26 @@ static void ivpu_preemption_buffers_free(struct ivpu_device *vdev, ivpu_bo_free(cmdq->secondary_preempt_buf); } +static int ivpu_id_alloc(struct xarray *xa, u32 *id, void *entry, struct xa_limit *limit, + const struct xa_limit default_limit) +{ + int ret; + + ret = __xa_alloc(xa, id, entry, *limit, GFP_KERNEL); + if (ret) { + limit->min = default_limit.min; + ret = __xa_alloc(xa, id, entry, *limit, GFP_KERNEL); + if (ret) + return ret; + } + + limit->min = *id + 1; + if (limit->min > limit->max) + limit->min = default_limit.min; + + return ret; +} + static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) { struct ivpu_device *vdev = file_priv->vdev; @@ -82,9 +102,11 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) if (!cmdq) return NULL; - ret = xa_alloc_cyclic(&vdev->db_xa, &cmdq->db_id, NULL, vdev->db_limit, &vdev->db_next, - GFP_KERNEL); - if (ret < 0) { + xa_lock(&vdev->db_xa); /* lock here to protect db_limit */ + ret = ivpu_id_alloc(&vdev->db_xa, &cmdq->db_id, NULL, &vdev->db_limit, + vdev->default_db_limit); + xa_unlock(&vdev->db_xa); + if (ret) { ivpu_err(vdev, "Failed to allocate doorbell id: %d\n", ret); goto err_free_cmdq; } @@ -532,9 +554,9 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) xa_lock(&vdev->submitted_jobs_xa); is_first_job = xa_empty(&vdev->submitted_jobs_xa); - ret = __xa_alloc_cyclic(&vdev->submitted_jobs_xa, &job->job_id, job, file_priv->job_limit, - &file_priv->job_id_next, GFP_KERNEL); - if (ret < 0) { + ret = ivpu_id_alloc(&vdev->submitted_jobs_xa, &job->job_id, job, &file_priv->job_limit, + file_priv->default_job_limit); + if (ret) { ivpu_dbg(vdev, JOB, "Too many active jobs in ctx %d\n", file_priv->ctx.id); ret = -EBUSY; From 0cd1a902290be9107d7fb7e2a3d33443bce4c09c Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 13/64] Revert "accel/ivpu: Unmap partially mapped BOs in case of errors" This reverts commit 08203ff6288319e2c03e832ec46d44a67adf302b. --- drivers/accel/ivpu/ivpu_mmu_context.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c index 697b57071d54..8992fe93b679 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.c +++ b/drivers/accel/ivpu/ivpu_mmu_context.c @@ -432,7 +432,6 @@ int ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u64 vpu_addr, struct sg_table *sgt, bool llc_coherent) { - size_t start_vpu_addr = vpu_addr; struct scatterlist *sg; int ret; u64 prot; @@ -463,7 +462,7 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, ret = ivpu_mmu_context_map_pages(vdev, ctx, vpu_addr, dma_addr, size, prot); if (ret) { ivpu_err(vdev, "Failed to map context pages\n"); - goto err_unmap_pages; + goto err_unlock; } vpu_addr += size; } @@ -473,7 +472,7 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, if (ret) { ivpu_err(vdev, "Failed to set context descriptor for context %u: %d\n", ctx->id, ret); - goto err_unmap_pages; + goto err_unlock; } ctx->is_cd_valid = true; } @@ -481,19 +480,17 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, /* Ensure page table modifications are flushed from wc buffers to memory */ wmb(); + mutex_unlock(&ctx->lock); + ret = ivpu_mmu_invalidate_tlb(vdev, ctx->id); - if (ret) { + if (ret) ivpu_err(vdev, "Failed to invalidate TLB for ctx %u: %d\n", ctx->id, ret); - goto err_unmap_pages; - } - - mutex_unlock(&ctx->lock); - return 0; + return ret; -err_unmap_pages: - ivpu_mmu_context_unmap_pages(ctx, start_vpu_addr, vpu_addr - start_vpu_addr); +err_unlock: mutex_unlock(&ctx->lock); return ret; + } void From bbe97f9e8e229efb41e6f270e6cc2cf9ba693fc4 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 14/64] Revert "accel/ivpu: Clear CDTAB entry in case of failure" This reverts commit cc524b834abd6a0e9d6453c25bd77fb3e8c31d25. --- drivers/accel/ivpu/ivpu_mmu.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_mmu.c b/drivers/accel/ivpu/ivpu_mmu.c index 26ef52fbb93e..4ff0d7a51985 100644 --- a/drivers/accel/ivpu/ivpu_mmu.c +++ b/drivers/accel/ivpu/ivpu_mmu.c @@ -749,17 +749,10 @@ static int ivpu_mmu_cdtab_entry_set(struct ivpu_device *vdev, u32 ssid, u64 cd_d ret = ivpu_mmu_cmdq_write_cfgi_all(vdev); if (ret) - goto err_invalidate; + goto unlock; ret = ivpu_mmu_cmdq_sync(vdev); - if (ret) - goto err_invalidate; unlock: - mutex_unlock(&mmu->lock); - return 0; - -err_invalidate: - WRITE_ONCE(entry[0], 0); mutex_unlock(&mmu->lock); return ret; } From 5bfb980609b1af7cc1aba7acec5eb0cf00819f08 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 15/64] Revert "accel/ivpu: Remove copy engine support" This reverts commit cbc5254d932a45fbe85e0c6d33ff31b9dea62386. --- drivers/accel/ivpu/ivpu_drv.h | 5 +++- drivers/accel/ivpu/ivpu_job.c | 43 ++++++++++++++++++++----------- drivers/accel/ivpu/ivpu_jsm_msg.c | 8 +++--- include/uapi/drm/ivpu_accel.h | 6 ++++- 4 files changed, 41 insertions(+), 21 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 5b4f5104b470..f905021ac174 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -49,8 +49,11 @@ #define IVPU_JOB_ID_JOB_MASK GENMASK(7, 0) #define IVPU_JOB_ID_CONTEXT_MASK GENMASK(31, 8) +#define IVPU_NUM_ENGINES 2 #define IVPU_NUM_PRIORITIES 4 -#define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_PRIORITIES) +#define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_ENGINES * IVPU_NUM_PRIORITIES) + +#define IVPU_CMDQ_INDEX(engine, priority) ((engine) * IVPU_NUM_PRIORITIES + (priority)) #define IVPU_PLATFORM_SILICON 0 #define IVPU_PLATFORM_SIMICS 2 diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index f580959e8778..98e0b7b61407 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -247,7 +247,8 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 engine, u8 priority) { - struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; + int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority); + struct ivpu_cmdq *cmdq = file_priv->cmdq[cmdq_idx]; int ret; lockdep_assert_held(&file_priv->lock); @@ -256,7 +257,7 @@ static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 cmdq = ivpu_cmdq_alloc(file_priv); if (!cmdq) return NULL; - file_priv->cmdq[priority] = cmdq; + file_priv->cmdq[cmdq_idx] = cmdq; } ret = ivpu_cmdq_init(file_priv, cmdq, engine, priority); @@ -266,14 +267,15 @@ static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 return cmdq; } -static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u8 priority) +static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u16 engine, u8 priority) { - struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; + int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority); + struct ivpu_cmdq *cmdq = file_priv->cmdq[cmdq_idx]; lockdep_assert_held(&file_priv->lock); if (cmdq) { - file_priv->cmdq[priority] = NULL; + file_priv->cmdq[cmdq_idx] = NULL; ivpu_cmdq_fini(file_priv, cmdq); ivpu_cmdq_free(file_priv, cmdq); } @@ -281,12 +283,14 @@ static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u8 priori void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) { + u16 engine; u8 priority; lockdep_assert_held(&file_priv->lock); - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) - ivpu_cmdq_release_locked(file_priv, priority); + for (engine = 0; engine < IVPU_NUM_ENGINES; engine++) + for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) + ivpu_cmdq_release_locked(file_priv, engine, priority); } /* @@ -297,15 +301,19 @@ void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) */ static void ivpu_cmdq_reset(struct ivpu_file_priv *file_priv) { + u16 engine; u8 priority; mutex_lock(&file_priv->lock); - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { - struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; + for (engine = 0; engine < IVPU_NUM_ENGINES; engine++) { + for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { + int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority); + struct ivpu_cmdq *cmdq = file_priv->cmdq[cmdq_idx]; - if (cmdq) - cmdq->db_registered = false; + if (cmdq) + cmdq->db_registered = false; + } } mutex_unlock(&file_priv->lock); @@ -326,11 +334,16 @@ void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev) static void ivpu_cmdq_fini_all(struct ivpu_file_priv *file_priv) { + u16 engine; u8 priority; - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { - if (file_priv->cmdq[priority]) - ivpu_cmdq_fini(file_priv, file_priv->cmdq[priority]); + for (engine = 0; engine < IVPU_NUM_ENGINES; engine++) { + for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { + int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority); + + if (file_priv->cmdq[cmdq_idx]) + ivpu_cmdq_fini(file_priv, file_priv->cmdq[cmdq_idx]); + } } } @@ -686,7 +699,7 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file) int idx, ret; u8 priority; - if (params->engine != DRM_IVPU_ENGINE_COMPUTE) + if (params->engine > DRM_IVPU_ENGINE_COPY) return -EINVAL; if (params->priority > DRM_IVPU_JOB_PRIORITY_REALTIME) diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index 30a40be76930..8f5d904ca1ed 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -132,7 +132,7 @@ int ivpu_jsm_get_heartbeat(struct ivpu_device *vdev, u32 engine, u64 *heartbeat) struct vpu_jsm_msg resp; int ret; - if (engine != VPU_ENGINE_COMPUTE) + if (engine > VPU_ENGINE_COPY) return -EINVAL; req.payload.query_engine_hb.engine_idx = engine; @@ -155,7 +155,7 @@ int ivpu_jsm_reset_engine(struct ivpu_device *vdev, u32 engine) struct vpu_jsm_msg resp; int ret; - if (engine != VPU_ENGINE_COMPUTE) + if (engine > VPU_ENGINE_COPY) return -EINVAL; req.payload.engine_reset.engine_idx = engine; @@ -174,7 +174,7 @@ int ivpu_jsm_preempt_engine(struct ivpu_device *vdev, u32 engine, u32 preempt_id struct vpu_jsm_msg resp; int ret; - if (engine != VPU_ENGINE_COMPUTE) + if (engine > VPU_ENGINE_COPY) return -EINVAL; req.payload.engine_preempt.engine_idx = engine; @@ -346,7 +346,7 @@ int ivpu_jsm_hws_resume_engine(struct ivpu_device *vdev, u32 engine) struct vpu_jsm_msg resp; int ret; - if (engine != VPU_ENGINE_COMPUTE) + if (engine >= VPU_ENGINE_NB) return -EINVAL; req.payload.hws_resume_engine.engine_idx = engine; diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h index a35b97b097bf..234664d35250 100644 --- a/include/uapi/drm/ivpu_accel.h +++ b/include/uapi/drm/ivpu_accel.h @@ -258,7 +258,7 @@ struct drm_ivpu_bo_info { /* drm_ivpu_submit engines */ #define DRM_IVPU_ENGINE_COMPUTE 0 -#define DRM_IVPU_ENGINE_COPY 1 /* Deprecated */ +#define DRM_IVPU_ENGINE_COPY 1 /** * struct drm_ivpu_submit - Submit commands to the VPU @@ -289,6 +289,10 @@ struct drm_ivpu_submit { * %DRM_IVPU_ENGINE_COMPUTE: * * Performs Deep Learning Neural Compute Inference Operations + * + * %DRM_IVPU_ENGINE_COPY: + * + * Performs memory copy operations to/from system memory allocated for VPU */ __u32 engine; From 158fe4bdb1077cb7dc677447b1b5487afb3c7f36 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 16/64] Revert "accel/ivpu: Defer MMU root page table allocation" This reverts commit f291cc5478f387a2306b9ee4c6e476907d61903f. --- drivers/accel/ivpu/ivpu_drv.c | 12 ++- drivers/accel/ivpu/ivpu_mmu.c | 94 +++++++++++------ drivers/accel/ivpu/ivpu_mmu.h | 4 +- drivers/accel/ivpu/ivpu_mmu_context.c | 145 +++++++++++++------------- drivers/accel/ivpu/ivpu_mmu_context.h | 9 +- 5 files changed, 149 insertions(+), 115 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 34e3e9b1c3f2..e7d8967c02f2 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -86,7 +86,7 @@ static void file_priv_unbind(struct ivpu_device *vdev, struct ivpu_file_priv *fi ivpu_cmdq_release_all_locked(file_priv); ivpu_bo_unbind_all_bos_from_context(vdev, &file_priv->ctx); - ivpu_mmu_context_fini(vdev, &file_priv->ctx); + ivpu_mmu_user_context_fini(vdev, &file_priv->ctx); file_priv->bound = false; drm_WARN_ON(&vdev->drm, !xa_erase_irq(&vdev->context_xa, file_priv->ctx.id)); } @@ -254,7 +254,9 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) goto err_unlock; } - ivpu_mmu_context_init(vdev, &file_priv->ctx, ctx_id); + ret = ivpu_mmu_user_context_init(vdev, &file_priv->ctx, ctx_id); + if (ret) + goto err_xa_erase; file_priv->default_job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); @@ -271,6 +273,8 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) return 0; +err_xa_erase: + xa_erase_irq(&vdev->context_xa, ctx_id); err_unlock: mutex_unlock(&vdev->context_list_lock); mutex_destroy(&file_priv->ms_lock); @@ -648,7 +652,9 @@ static int ivpu_dev_init(struct ivpu_device *vdev) if (ret) goto err_shutdown; - ivpu_mmu_global_context_init(vdev); + ret = ivpu_mmu_global_context_init(vdev); + if (ret) + goto err_shutdown; ret = ivpu_mmu_init(vdev); if (ret) diff --git a/drivers/accel/ivpu/ivpu_mmu.c b/drivers/accel/ivpu/ivpu_mmu.c index 4ff0d7a51985..c078e214b221 100644 --- a/drivers/accel/ivpu/ivpu_mmu.c +++ b/drivers/accel/ivpu/ivpu_mmu.c @@ -696,7 +696,7 @@ int ivpu_mmu_invalidate_tlb(struct ivpu_device *vdev, u16 ssid) return ret; } -static int ivpu_mmu_cdtab_entry_set(struct ivpu_device *vdev, u32 ssid, u64 cd_dma, bool valid) +static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma) { struct ivpu_mmu_info *mmu = vdev->mmu; struct ivpu_mmu_cdtab *cdtab = &mmu->cdtab; @@ -708,29 +708,30 @@ static int ivpu_mmu_cdtab_entry_set(struct ivpu_device *vdev, u32 ssid, u64 cd_d return -EINVAL; entry = cdtab->base + (ssid * IVPU_MMU_CDTAB_ENT_SIZE); - drm_WARN_ON(&vdev->drm, (entry[0] & IVPU_MMU_CD_0_V) == valid); - - cd[0] = FIELD_PREP(IVPU_MMU_CD_0_TCR_T0SZ, IVPU_MMU_T0SZ_48BIT) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_TG0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_IRGN0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_ORGN0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_SH0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_IPS, IVPU_MMU_IPS_48BIT) | - FIELD_PREP(IVPU_MMU_CD_0_ASID, ssid) | - IVPU_MMU_CD_0_TCR_EPD1 | - IVPU_MMU_CD_0_AA64 | - IVPU_MMU_CD_0_R | - IVPU_MMU_CD_0_ASET; - cd[1] = cd_dma & IVPU_MMU_CD_1_TTB0_MASK; - cd[2] = 0; - cd[3] = 0x0000000000007444; - - /* For global context generate memory fault on VPU */ - if (ssid == IVPU_GLOBAL_CONTEXT_MMU_SSID) - cd[0] |= IVPU_MMU_CD_0_A; - - if (valid) - cd[0] |= IVPU_MMU_CD_0_V; + + if (cd_dma != 0) { + cd[0] = FIELD_PREP(IVPU_MMU_CD_0_TCR_T0SZ, IVPU_MMU_T0SZ_48BIT) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_TG0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_IRGN0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_ORGN0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_SH0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_IPS, IVPU_MMU_IPS_48BIT) | + FIELD_PREP(IVPU_MMU_CD_0_ASID, ssid) | + IVPU_MMU_CD_0_TCR_EPD1 | + IVPU_MMU_CD_0_AA64 | + IVPU_MMU_CD_0_R | + IVPU_MMU_CD_0_ASET | + IVPU_MMU_CD_0_V; + cd[1] = cd_dma & IVPU_MMU_CD_1_TTB0_MASK; + cd[2] = 0; + cd[3] = 0x0000000000007444; + + /* For global context generate memory fault on VPU */ + if (ssid == IVPU_GLOBAL_CONTEXT_MMU_SSID) + cd[0] |= IVPU_MMU_CD_0_A; + } else { + memset(cd, 0, sizeof(cd)); + } WRITE_ONCE(entry[1], cd[1]); WRITE_ONCE(entry[2], cd[2]); @@ -740,8 +741,8 @@ static int ivpu_mmu_cdtab_entry_set(struct ivpu_device *vdev, u32 ssid, u64 cd_d if (!ivpu_is_force_snoop_enabled(vdev)) clflush_cache_range(entry, IVPU_MMU_CDTAB_ENT_SIZE); - ivpu_dbg(vdev, MMU, "CDTAB set %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n", - valid ? "valid" : "invalid", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]); + ivpu_dbg(vdev, MMU, "CDTAB %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n", + cd_dma ? "write" : "clear", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]); mutex_lock(&mmu->lock); if (!mmu->on) @@ -757,6 +758,33 @@ static int ivpu_mmu_cdtab_entry_set(struct ivpu_device *vdev, u32 ssid, u64 cd_d return ret; } +static int ivpu_mmu_cd_add_gbl(struct ivpu_device *vdev) +{ + int ret; + + ret = ivpu_mmu_cd_add(vdev, 0, vdev->gctx.pgtable.pgd_dma); + if (ret) + ivpu_err(vdev, "Failed to add global CD entry: %d\n", ret); + + return ret; +} + +static int ivpu_mmu_cd_add_user(struct ivpu_device *vdev, u32 ssid, dma_addr_t cd_dma) +{ + int ret; + + if (ssid == 0) { + ivpu_err(vdev, "Invalid SSID: %u\n", ssid); + return -EINVAL; + } + + ret = ivpu_mmu_cd_add(vdev, ssid, cd_dma); + if (ret) + ivpu_err(vdev, "Failed to add CD entry SSID=%u: %d\n", ssid, ret); + + return ret; +} + int ivpu_mmu_init(struct ivpu_device *vdev) { struct ivpu_mmu_info *mmu = vdev->mmu; @@ -780,6 +808,12 @@ int ivpu_mmu_init(struct ivpu_device *vdev) return ret; } + ret = ivpu_mmu_cd_add_gbl(vdev); + if (ret) { + ivpu_err(vdev, "Failed to initialize strtab: %d\n", ret); + return ret; + } + ret = ivpu_mmu_enable(vdev); if (ret) { ivpu_err(vdev, "Failed to resume MMU: %d\n", ret); @@ -932,12 +966,12 @@ void ivpu_mmu_irq_gerr_handler(struct ivpu_device *vdev) REGV_WR32(IVPU_MMU_REG_GERRORN, gerror_val); } -int ivpu_mmu_cd_set(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable) +int ivpu_mmu_set_pgtable(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable) { - return ivpu_mmu_cdtab_entry_set(vdev, ssid, pgtable->pgd_dma, true); + return ivpu_mmu_cd_add_user(vdev, ssid, pgtable->pgd_dma); } -void ivpu_mmu_cd_clear(struct ivpu_device *vdev, int ssid) +void ivpu_mmu_clear_pgtable(struct ivpu_device *vdev, int ssid) { - ivpu_mmu_cdtab_entry_set(vdev, ssid, 0, false); + ivpu_mmu_cd_add_user(vdev, ssid, 0); /* 0 will clear CD entry */ } diff --git a/drivers/accel/ivpu/ivpu_mmu.h b/drivers/accel/ivpu/ivpu_mmu.h index 7afea9cd8731..6fa35c240710 100644 --- a/drivers/accel/ivpu/ivpu_mmu.h +++ b/drivers/accel/ivpu/ivpu_mmu.h @@ -40,8 +40,8 @@ struct ivpu_mmu_info { int ivpu_mmu_init(struct ivpu_device *vdev); void ivpu_mmu_disable(struct ivpu_device *vdev); int ivpu_mmu_enable(struct ivpu_device *vdev); -int ivpu_mmu_cd_set(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable); -void ivpu_mmu_cd_clear(struct ivpu_device *vdev, int ssid); +int ivpu_mmu_set_pgtable(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable); +void ivpu_mmu_clear_pgtable(struct ivpu_device *vdev, int ssid); int ivpu_mmu_invalidate_tlb(struct ivpu_device *vdev, u16 ssid); void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev); diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c index 8992fe93b679..bbe652a7019d 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.c +++ b/drivers/accel/ivpu/ivpu_mmu_context.c @@ -90,6 +90,19 @@ static void ivpu_pgtable_free_page(struct ivpu_device *vdev, u64 *cpu_addr, dma_ } } +static int ivpu_mmu_pgtable_init(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable) +{ + dma_addr_t pgd_dma; + + pgtable->pgd_dma_ptr = ivpu_pgtable_alloc_page(vdev, &pgd_dma); + if (!pgtable->pgd_dma_ptr) + return -ENOMEM; + + pgtable->pgd_dma = pgd_dma; + + return 0; +} + static void ivpu_mmu_pgtables_free(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable) { int pgd_idx, pud_idx, pmd_idx; @@ -127,27 +140,6 @@ static void ivpu_mmu_pgtables_free(struct ivpu_device *vdev, struct ivpu_mmu_pgt } ivpu_pgtable_free_page(vdev, pgtable->pgd_dma_ptr, pgtable->pgd_dma); - pgtable->pgd_dma_ptr = NULL; - pgtable->pgd_dma = 0; -} - -static u64* -ivpu_mmu_ensure_pgd(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable) -{ - u64 *pgd_dma_ptr = pgtable->pgd_dma_ptr; - dma_addr_t pgd_dma; - - if (pgd_dma_ptr) - return pgd_dma_ptr; - - pgd_dma_ptr = ivpu_pgtable_alloc_page(vdev, &pgd_dma); - if (!pgd_dma_ptr) - return NULL; - - pgtable->pgd_dma_ptr = pgd_dma_ptr; - pgtable->pgd_dma = pgd_dma; - - return pgd_dma_ptr; } static u64* @@ -245,12 +237,6 @@ ivpu_mmu_context_map_page(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx int pmd_idx = FIELD_GET(IVPU_MMU_PMD_INDEX_MASK, vpu_addr); int pte_idx = FIELD_GET(IVPU_MMU_PTE_INDEX_MASK, vpu_addr); - drm_WARN_ON(&vdev->drm, ctx->id == IVPU_RESERVED_CONTEXT_MMU_SSID); - - /* Allocate PGD - first level page table if needed */ - if (!ivpu_mmu_ensure_pgd(vdev, &ctx->pgtable)) - return -ENOMEM; - /* Allocate PUD - second level page table if needed */ if (!ivpu_mmu_ensure_pud(vdev, &ctx->pgtable, pgd_idx)) return -ENOMEM; @@ -462,21 +448,12 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, ret = ivpu_mmu_context_map_pages(vdev, ctx, vpu_addr, dma_addr, size, prot); if (ret) { ivpu_err(vdev, "Failed to map context pages\n"); - goto err_unlock; + mutex_unlock(&ctx->lock); + return ret; } vpu_addr += size; } - if (!ctx->is_cd_valid) { - ret = ivpu_mmu_cd_set(vdev, ctx->id, &ctx->pgtable); - if (ret) { - ivpu_err(vdev, "Failed to set context descriptor for context %u: %d\n", - ctx->id, ret); - goto err_unlock; - } - ctx->is_cd_valid = true; - } - /* Ensure page table modifications are flushed from wc buffers to memory */ wmb(); @@ -486,11 +463,6 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, if (ret) ivpu_err(vdev, "Failed to invalidate TLB for ctx %u: %d\n", ctx->id, ret); return ret; - -err_unlock: - mutex_unlock(&ctx->lock); - return ret; - } void @@ -558,12 +530,20 @@ ivpu_mmu_context_remove_node(struct ivpu_mmu_context *ctx, struct drm_mm_node *n mutex_unlock(&ctx->lock); } -void ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 context_id) +static int +ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 context_id) { u64 start, end; + int ret; mutex_init(&ctx->lock); + ret = ivpu_mmu_pgtable_init(vdev, &ctx->pgtable); + if (ret) { + ivpu_err(vdev, "Failed to initialize pgtable for ctx %u: %d\n", context_id, ret); + return ret; + } + if (!context_id) { start = vdev->hw->ranges.global.start; end = vdev->hw->ranges.shave.end; @@ -574,59 +554,41 @@ void ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ct drm_mm_init(&ctx->mm, start, end - start); ctx->id = context_id; + + return 0; } -void ivpu_mmu_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx) +static void ivpu_mmu_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx) { - if (ctx->is_cd_valid) { - ivpu_mmu_cd_clear(vdev, ctx->id); - ctx->is_cd_valid = false; - } + if (drm_WARN_ON(&vdev->drm, !ctx->pgtable.pgd_dma_ptr)) + return; mutex_destroy(&ctx->lock); ivpu_mmu_pgtables_free(vdev, &ctx->pgtable); drm_mm_takedown(&ctx->mm); + + ctx->pgtable.pgd_dma_ptr = NULL; + ctx->pgtable.pgd_dma = 0; } -void ivpu_mmu_global_context_init(struct ivpu_device *vdev) +int ivpu_mmu_global_context_init(struct ivpu_device *vdev) { - ivpu_mmu_context_init(vdev, &vdev->gctx, IVPU_GLOBAL_CONTEXT_MMU_SSID); + return ivpu_mmu_context_init(vdev, &vdev->gctx, IVPU_GLOBAL_CONTEXT_MMU_SSID); } void ivpu_mmu_global_context_fini(struct ivpu_device *vdev) { - ivpu_mmu_context_fini(vdev, &vdev->gctx); + return ivpu_mmu_context_fini(vdev, &vdev->gctx); } int ivpu_mmu_reserved_context_init(struct ivpu_device *vdev) { - int ret; - - ivpu_mmu_context_init(vdev, &vdev->rctx, IVPU_RESERVED_CONTEXT_MMU_SSID); - - mutex_lock(&vdev->rctx.lock); - - if (!ivpu_mmu_ensure_pgd(vdev, &vdev->rctx.pgtable)) { - ivpu_err(vdev, "Failed to allocate root page table for reserved context\n"); - ret = -ENOMEM; - goto unlock; - } - - ret = ivpu_mmu_cd_set(vdev, vdev->rctx.id, &vdev->rctx.pgtable); - if (ret) { - ivpu_err(vdev, "Failed to set context descriptor for reserved context\n"); - goto unlock; - } - -unlock: - mutex_unlock(&vdev->rctx.lock); - return ret; + return ivpu_mmu_user_context_init(vdev, &vdev->rctx, IVPU_RESERVED_CONTEXT_MMU_SSID); } void ivpu_mmu_reserved_context_fini(struct ivpu_device *vdev) { - ivpu_mmu_cd_clear(vdev, vdev->rctx.id); - ivpu_mmu_context_fini(vdev, &vdev->rctx); + return ivpu_mmu_user_context_fini(vdev, &vdev->rctx); } void ivpu_mmu_user_context_mark_invalid(struct ivpu_device *vdev, u32 ssid) @@ -641,3 +603,36 @@ void ivpu_mmu_user_context_mark_invalid(struct ivpu_device *vdev, u32 ssid) xa_unlock(&vdev->context_xa); } + +int ivpu_mmu_user_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 ctx_id) +{ + int ret; + + drm_WARN_ON(&vdev->drm, !ctx_id); + + ret = ivpu_mmu_context_init(vdev, ctx, ctx_id); + if (ret) { + ivpu_err(vdev, "Failed to initialize context %u: %d\n", ctx_id, ret); + return ret; + } + + ret = ivpu_mmu_set_pgtable(vdev, ctx_id, &ctx->pgtable); + if (ret) { + ivpu_err(vdev, "Failed to set page table for context %u: %d\n", ctx_id, ret); + goto err_context_fini; + } + + return 0; + +err_context_fini: + ivpu_mmu_context_fini(vdev, ctx); + return ret; +} + +void ivpu_mmu_user_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx) +{ + drm_WARN_ON(&vdev->drm, !ctx->id); + + ivpu_mmu_clear_pgtable(vdev, ctx->id); + ivpu_mmu_context_fini(vdev, ctx); +} diff --git a/drivers/accel/ivpu/ivpu_mmu_context.h b/drivers/accel/ivpu/ivpu_mmu_context.h index 8042fc067062..7f9aaf3d10c2 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.h +++ b/drivers/accel/ivpu/ivpu_mmu_context.h @@ -23,20 +23,19 @@ struct ivpu_mmu_pgtable { }; struct ivpu_mmu_context { - struct mutex lock; /* Protects: mm, pgtable, is_cd_valid */ + struct mutex lock; /* Protects: mm, pgtable */ struct drm_mm mm; struct ivpu_mmu_pgtable pgtable; - bool is_cd_valid; u32 id; }; -void ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 context_id); -void ivpu_mmu_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx); -void ivpu_mmu_global_context_init(struct ivpu_device *vdev); +int ivpu_mmu_global_context_init(struct ivpu_device *vdev); void ivpu_mmu_global_context_fini(struct ivpu_device *vdev); int ivpu_mmu_reserved_context_init(struct ivpu_device *vdev); void ivpu_mmu_reserved_context_fini(struct ivpu_device *vdev); +int ivpu_mmu_user_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 ctx_id); +void ivpu_mmu_user_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx); void ivpu_mmu_user_context_mark_invalid(struct ivpu_device *vdev, u32 ssid); int ivpu_mmu_context_insert_node(struct ivpu_mmu_context *ctx, const struct ivpu_addr_range *range, From d1d7b4d02055532ca839117885bb792a57fc4925 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 17/64] Revert "accel/ivpu: Do not fail when more than 1 tile is fused" This reverts commit bfe65cb6f0434f5074c857929da71e068e55b6a9. --- drivers/accel/ivpu/ivpu_hw_btrs.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index 3212c99f3682..6d5f1cc71143 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -141,10 +141,16 @@ static int read_tile_config_fuse(struct ivpu_device *vdev, u32 *tile_fuse_config } config = REG_GET_FLD(VPU_HW_BTRS_LNL_TILE_FUSE, CONFIG, fuse); - if (!tile_disable_check(config)) - ivpu_warn(vdev, "More than 1 tile disabled, tile fuse config mask: 0x%x\n", config); + if (!tile_disable_check(config)) { + ivpu_err(vdev, "Fuse: Invalid tile disable config (0x%x)\n", config); + return -EIO; + } - ivpu_dbg(vdev, MISC, "Tile disable config mask: 0x%x\n", config); + if (config) + ivpu_dbg(vdev, MISC, "Fuse: %d tiles enabled. Tile number %d disabled\n", + BTRS_LNL_TILE_MAX_NUM - 1, ffs(config) - 1); + else + ivpu_dbg(vdev, MISC, "Fuse: All %d tiles enabled\n", BTRS_LNL_TILE_MAX_NUM); *tile_fuse_config = config; return 0; From f55b3cc29f19d28eb628448e725c83b9e15353ad Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 18/64] Revert "accel/ivpu: Fix NOC firewall interrupt handling" This reverts commit bbca9e4c48fe002f9bf3530b8d9062a0d90235de. --- drivers/accel/ivpu/ivpu_debugfs.c | 9 --------- drivers/accel/ivpu/ivpu_hw.c | 1 - drivers/accel/ivpu/ivpu_hw.h | 1 - drivers/accel/ivpu/ivpu_hw_ip.c | 5 +---- 4 files changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index 8180b95ed69d..8958145c49ad 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -116,14 +116,6 @@ static int reset_pending_show(struct seq_file *s, void *v) return 0; } -static int firewall_irq_counter_show(struct seq_file *s, void *v) -{ - struct ivpu_device *vdev = seq_to_ivpu(s); - - seq_printf(s, "%d\n", atomic_read(&vdev->hw->firewall_irq_counter)); - return 0; -} - static const struct drm_debugfs_info vdev_debugfs_list[] = { {"bo_list", bo_list_show, 0}, {"fw_name", fw_name_show, 0}, @@ -133,7 +125,6 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = { {"last_bootmode", last_bootmode_show, 0}, {"reset_counter", reset_counter_show, 0}, {"reset_pending", reset_pending_show, 0}, - {"firewall_irq_counter", firewall_irq_counter_show, 0}, }; static int dvfs_mode_get(void *data, u64 *dvfs_mode) diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index f1f5e0c4961b..1c259d717815 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -252,7 +252,6 @@ int ivpu_hw_init(struct ivpu_device *vdev) platform_init(vdev); wa_init(vdev); timeouts_init(vdev); - atomic_set(&vdev->hw->firewall_irq_counter, 0); return 0; } diff --git a/drivers/accel/ivpu/ivpu_hw.h b/drivers/accel/ivpu/ivpu_hw.h index fc4dbfc980c8..dc5518248c40 100644 --- a/drivers/accel/ivpu/ivpu_hw.h +++ b/drivers/accel/ivpu/ivpu_hw.h @@ -51,7 +51,6 @@ struct ivpu_hw_info { int dma_bits; ktime_t d0i3_entry_host_ts; u64 d0i3_entry_vpu_ts; - atomic_t firewall_irq_counter; }; int ivpu_hw_init(struct ivpu_device *vdev); diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c index 029dd065614b..b9b16f404143 100644 --- a/drivers/accel/ivpu/ivpu_hw_ip.c +++ b/drivers/accel/ivpu/ivpu_hw_ip.c @@ -1073,10 +1073,7 @@ static void irq_wdt_mss_handler(struct ivpu_device *vdev) static void irq_noc_firewall_handler(struct ivpu_device *vdev) { - atomic_inc(&vdev->hw->firewall_irq_counter); - - ivpu_dbg(vdev, IRQ, "NOC Firewall interrupt detected, counter %d\n", - atomic_read(&vdev->hw->firewall_irq_counter)); + ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ"); } /* Handler for IRQs from NPU core */ From 5e374d40de158ddbfa48a0f09d53d0a7d4e77421 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 19/64] Revert "accel/ivpu: Update power island delays" This reverts commit e7e29b9d6e9528c7e4452548fc8903c21141178b. --- drivers/accel/ivpu/ivpu_hw_40xx_reg.h | 2 -- drivers/accel/ivpu/ivpu_hw_ip.c | 49 ++++++++++----------------- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_40xx_reg.h b/drivers/accel/ivpu/ivpu_hw_40xx_reg.h index fc0ee8d637f9..d0b795b344c7 100644 --- a/drivers/accel/ivpu/ivpu_hw_40xx_reg.h +++ b/drivers/accel/ivpu/ivpu_hw_40xx_reg.h @@ -115,8 +115,6 @@ #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY 0x00030068u #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY_POST_DLY_MASK GENMASK(7, 0) -#define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY_POST1_DLY_MASK GENMASK(15, 8) -#define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY_POST2_DLY_MASK GENMASK(23, 16) #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY 0x0003006cu #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY_STATUS_DLY_MASK GENMASK(7, 0) diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c index b9b16f404143..cfcbb99168e6 100644 --- a/drivers/accel/ivpu/ivpu_hw_ip.c +++ b/drivers/accel/ivpu/ivpu_hw_ip.c @@ -8,12 +8,15 @@ #include "ivpu_hw.h" #include "ivpu_hw_37xx_reg.h" #include "ivpu_hw_40xx_reg.h" -#include "ivpu_hw_btrs.h" #include "ivpu_hw_ip.h" #include "ivpu_hw_reg_io.h" #include "ivpu_mmu.h" #include "ivpu_pm.h" +#define PWR_ISLAND_EN_POST_DLY_FREQ_DEFAULT 0 +#define PWR_ISLAND_EN_POST_DLY_FREQ_HIGH 18 +#define PWR_ISLAND_STATUS_DLY_FREQ_DEFAULT 3 +#define PWR_ISLAND_STATUS_DLY_FREQ_HIGH 46 #define PWR_ISLAND_STATUS_TIMEOUT_US (5 * USEC_PER_MSEC) #define TIM_SAFE_ENABLE 0xf1d0dead @@ -265,15 +268,20 @@ void ivpu_hw_ip_idle_gen_disable(struct ivpu_device *vdev) idle_gen_drive_40xx(vdev, false); } -static void -pwr_island_delay_set_50xx(struct ivpu_device *vdev, u32 post, u32 post1, u32 post2, u32 status) +static void pwr_island_delay_set_50xx(struct ivpu_device *vdev) { - u32 val; + u32 val, post, status; + + if (vdev->hw->pll.profiling_freq == PLL_PROFILING_FREQ_DEFAULT) { + post = PWR_ISLAND_EN_POST_DLY_FREQ_DEFAULT; + status = PWR_ISLAND_STATUS_DLY_FREQ_DEFAULT; + } else { + post = PWR_ISLAND_EN_POST_DLY_FREQ_HIGH; + status = PWR_ISLAND_STATUS_DLY_FREQ_HIGH; + } val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY); val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST_DLY, post, val); - val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST1_DLY, post1, val); - val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST2_DLY, post2, val); REGV_WR32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, val); val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY); @@ -674,36 +682,13 @@ static void dpu_active_drive_37xx(struct ivpu_device *vdev, bool enable) REGV_WR32(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, val); } -static void pwr_island_delay_set(struct ivpu_device *vdev) -{ - bool high = vdev->hw->pll.profiling_freq == PLL_PROFILING_FREQ_HIGH; - u32 post, post1, post2, status; - - if (ivpu_hw_ip_gen(vdev) < IVPU_HW_IP_50XX) - return; - - switch (ivpu_device_id(vdev)) { - case PCI_DEVICE_ID_PTL_P: - post = high ? 18 : 0; - post1 = 0; - post2 = 0; - status = high ? 46 : 3; - break; - - default: - dump_stack(); - ivpu_err(vdev, "Unknown device ID\n"); - return; - } - - pwr_island_delay_set_50xx(vdev, post, post1, post2, status); -} - int ivpu_hw_ip_pwr_domain_enable(struct ivpu_device *vdev) { int ret; - pwr_island_delay_set(vdev); + if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_50XX) + pwr_island_delay_set_50xx(vdev); + pwr_island_enable(vdev); ret = wait_for_pwr_island_status(vdev, 0x1); From 8b47acaae084f26de9e23e74992223cd661a3116 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 20/64] Revert "accel/ivpu: Add initial Panther Lake support" This reverts commit 86022b731439f90f8f4654bbf45cdbd49131e890. --- drivers/accel/ivpu/ivpu_drv.c | 1 - drivers/accel/ivpu/ivpu_drv.h | 10 +++------- drivers/accel/ivpu/ivpu_fw.c | 3 --- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index e7d8967c02f2..dc983140128b 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -742,7 +742,6 @@ static struct pci_device_id ivpu_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_MTL) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_ARL) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_LNL) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PTL_P) }, { } }; MODULE_DEVICE_TABLE(pci, ivpu_pci_ids); diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index f905021ac174..5b43f91f2015 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -22,10 +22,9 @@ #define DRIVER_NAME "intel_vpu" #define DRIVER_DESC "Driver for Intel NPU (Neural Processing Unit)" -#define PCI_DEVICE_ID_MTL 0x7d1d -#define PCI_DEVICE_ID_ARL 0xad1d -#define PCI_DEVICE_ID_LNL 0x643e -#define PCI_DEVICE_ID_PTL_P 0xb03e +#define PCI_DEVICE_ID_MTL 0x7d1d +#define PCI_DEVICE_ID_ARL 0xad1d +#define PCI_DEVICE_ID_LNL 0x643e #define IVPU_HW_IP_37XX 37 #define IVPU_HW_IP_40XX 40 @@ -225,8 +224,6 @@ static inline int ivpu_hw_ip_gen(struct ivpu_device *vdev) return IVPU_HW_IP_37XX; case PCI_DEVICE_ID_LNL: return IVPU_HW_IP_40XX; - case PCI_DEVICE_ID_PTL_P: - return IVPU_HW_IP_50XX; default: dump_stack(); ivpu_err(vdev, "Unknown NPU IP generation\n"); @@ -241,7 +238,6 @@ static inline int ivpu_hw_btrs_gen(struct ivpu_device *vdev) case PCI_DEVICE_ID_ARL: return IVPU_HW_BTRS_MTL; case PCI_DEVICE_ID_LNL: - case PCI_DEVICE_ID_PTL_P: return IVPU_HW_BTRS_LNL; default: dump_stack(); diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index be367465e7df..4d59dd19f684 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -57,14 +57,11 @@ static struct { { IVPU_HW_IP_37XX, "intel/vpu/vpu_37xx_v0.0.bin" }, { IVPU_HW_IP_40XX, "vpu_40xx.bin" }, { IVPU_HW_IP_40XX, "intel/vpu/vpu_40xx_v0.0.bin" }, - { IVPU_HW_IP_50XX, "vpu_50xx.bin" }, - { IVPU_HW_IP_50XX, "intel/vpu/vpu_50xx_v0.0.bin" }, }; /* Production fw_names from the table above */ MODULE_FIRMWARE("intel/vpu/vpu_37xx_v0.0.bin"); MODULE_FIRMWARE("intel/vpu/vpu_40xx_v0.0.bin"); -MODULE_FIRMWARE("intel/vpu/vpu_50xx_v0.0.bin"); static int ivpu_fw_request(struct ivpu_device *vdev) { From be52cd8d8d87070e5555864122486c451a9b07e0 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 21/64] Revert "accel/ivpu: Fix typos in ivpu_pm.c" This reverts commit 28f2ab476dd2729d646474d64799ca0ee94ef215. --- drivers/accel/ivpu/ivpu_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index e567df79a612..6d180c81e6df 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -423,7 +423,7 @@ int ivpu_pm_dct_enable(struct ivpu_device *vdev, u8 active_percent) ret = ivpu_jsm_dct_enable(vdev, active_us, inactive_us); if (ret) { - ivpu_err_ratelimited(vdev, "Failed to enable DCT: %d\n", ret); + ivpu_err_ratelimited(vdev, "Filed to enable DCT: %d\n", ret); return ret; } @@ -440,7 +440,7 @@ int ivpu_pm_dct_disable(struct ivpu_device *vdev) ret = ivpu_jsm_dct_disable(vdev); if (ret) { - ivpu_err_ratelimited(vdev, "Failed to disable DCT: %d\n", ret); + ivpu_err_ratelimited(vdev, "Filed to disable DCT: %d\n", ret); return ret; } From 6e6d5283859a9973094c02ee498a292d41ed6f1d Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 22/64] Revert "accel/ivpu: Add tracing for IPC/PM/JOB" This reverts commit 889ca5bb3f0207db508e1fde278c2e1a82aa8aea. --- drivers/accel/ivpu/Makefile | 5 +- drivers/accel/ivpu/ivpu_ipc.c | 3 -- drivers/accel/ivpu/ivpu_job.c | 4 -- drivers/accel/ivpu/ivpu_pm.c | 9 ---- drivers/accel/ivpu/ivpu_trace.h | 73 -------------------------- drivers/accel/ivpu/ivpu_trace_points.c | 9 ---- 6 files changed, 1 insertion(+), 102 deletions(-) delete mode 100644 drivers/accel/ivpu/ivpu_trace.h delete mode 100644 drivers/accel/ivpu/ivpu_trace_points.c diff --git a/drivers/accel/ivpu/Makefile b/drivers/accel/ivpu/Makefile index e73937c86d9a..232ea6d28c6e 100644 --- a/drivers/accel/ivpu/Makefile +++ b/drivers/accel/ivpu/Makefile @@ -16,12 +16,9 @@ intel_vpu-y := \ ivpu_mmu_context.o \ ivpu_ms.o \ ivpu_pm.o \ - ivpu_sysfs.o \ - ivpu_trace_points.o + ivpu_sysfs.o intel_vpu-$(CONFIG_DEBUG_FS) += ivpu_debugfs.o intel_vpu-$(CONFIG_DEV_COREDUMP) += ivpu_coredump.o obj-$(CONFIG_DRM_ACCEL_IVPU) += intel_vpu.o - -CFLAGS_ivpu_trace_points.o = -I$(src) diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index 01ebf88fe6ef..c8ae69a529c0 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -15,7 +15,6 @@ #include "ivpu_ipc.h" #include "ivpu_jsm_msg.h" #include "ivpu_pm.h" -#include "ivpu_trace.h" #define IPC_MAX_RX_MSG 128 @@ -228,7 +227,6 @@ int ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, stru goto unlock; ivpu_ipc_tx(vdev, cons->tx_vpu_addr); - trace_jsm("[tx]", req); unlock: mutex_unlock(&ipc->lock); @@ -286,7 +284,6 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, if (jsm_msg) memcpy(jsm_msg, rx_msg->jsm_msg, size); - trace_jsm("[rx]", rx_msg->jsm_msg); } ivpu_ipc_rx_msg_del(vdev, rx_msg); diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 98e0b7b61407..cd41b8771505 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -18,7 +18,6 @@ #include "ivpu_job.h" #include "ivpu_jsm_msg.h" #include "ivpu_pm.h" -#include "ivpu_trace.h" #include "vpu_boot_api.h" #define CMD_BUF_IDX 0 @@ -483,7 +482,6 @@ ivpu_job_create(struct ivpu_file_priv *file_priv, u32 engine_idx, u32 bo_count) job->file_priv = ivpu_file_priv_get(file_priv); - trace_job("create", job); ivpu_dbg(vdev, JOB, "Job created: ctx %2d engine %d", file_priv->ctx.id, job->engine_idx); return job; @@ -523,7 +521,6 @@ static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32 job->bos[CMD_BUF_IDX]->job_status = job_status; dma_fence_signal(job->done_fence); - trace_job("done", job); ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d engine %d status 0x%x\n", job->job_id, job->file_priv->ctx.id, job->engine_idx, job_status); @@ -591,7 +588,6 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) vdev->busy_start_ts = ktime_get(); } - trace_job("submit", job); ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d engine %d prio %d addr 0x%llx next %d\n", job->job_id, file_priv->ctx.id, job->engine_idx, priority, job->cmd_buf_vpu_addr, cmdq->jobq->header.tail); diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 6d180c81e6df..b5a69941e6e0 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -20,7 +20,6 @@ #include "ivpu_mmu.h" #include "ivpu_ms.h" #include "ivpu_pm.h" -#include "ivpu_trace.h" #include "vpu_boot_api.h" static bool ivpu_disable_recovery; @@ -199,7 +198,6 @@ int ivpu_pm_suspend_cb(struct device *dev) struct ivpu_device *vdev = to_ivpu_device(drm); unsigned long timeout; - trace_pm("suspend"); ivpu_dbg(vdev, PM, "Suspend..\n"); timeout = jiffies + msecs_to_jiffies(vdev->timeout.tdr); @@ -217,7 +215,6 @@ int ivpu_pm_suspend_cb(struct device *dev) ivpu_pm_prepare_warm_boot(vdev); ivpu_dbg(vdev, PM, "Suspend done.\n"); - trace_pm("suspend done"); return 0; } @@ -228,7 +225,6 @@ int ivpu_pm_resume_cb(struct device *dev) struct ivpu_device *vdev = to_ivpu_device(drm); int ret; - trace_pm("resume"); ivpu_dbg(vdev, PM, "Resume..\n"); ret = ivpu_resume(vdev); @@ -236,7 +232,6 @@ int ivpu_pm_resume_cb(struct device *dev) ivpu_err(vdev, "Failed to resume: %d\n", ret); ivpu_dbg(vdev, PM, "Resume done.\n"); - trace_pm("resume done"); return ret; } @@ -251,7 +246,6 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev) drm_WARN_ON(&vdev->drm, !xa_empty(&vdev->submitted_jobs_xa)); drm_WARN_ON(&vdev->drm, work_pending(&vdev->pm->recovery_work)); - trace_pm("runtime suspend"); ivpu_dbg(vdev, PM, "Runtime suspend..\n"); ivpu_mmu_disable(vdev); @@ -278,7 +272,6 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev) } ivpu_dbg(vdev, PM, "Runtime suspend done.\n"); - trace_pm("runtime suspend done"); return 0; } @@ -289,7 +282,6 @@ int ivpu_pm_runtime_resume_cb(struct device *dev) struct ivpu_device *vdev = to_ivpu_device(drm); int ret; - trace_pm("runtime resume"); ivpu_dbg(vdev, PM, "Runtime resume..\n"); ret = ivpu_resume(vdev); @@ -297,7 +289,6 @@ int ivpu_pm_runtime_resume_cb(struct device *dev) ivpu_err(vdev, "Failed to set RESUME state: %d\n", ret); ivpu_dbg(vdev, PM, "Runtime resume done.\n"); - trace_pm("runtime resume done"); return ret; } diff --git a/drivers/accel/ivpu/ivpu_trace.h b/drivers/accel/ivpu/ivpu_trace.h deleted file mode 100644 index eb792038e701..000000000000 --- a/drivers/accel/ivpu/ivpu_trace.h +++ /dev/null @@ -1,73 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2020-2024 Intel Corporation - */ - -#if !defined(__IVPU_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ) -#define __IVPU_TRACE_H__ - -#include -#include "ivpu_drv.h" -#include "ivpu_job.h" -#include "vpu_jsm_api.h" -#include "ivpu_jsm_msg.h" -#include "ivpu_ipc.h" - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM vpu -#define TRACE_INCLUDE_FILE ivpu_trace - -TRACE_EVENT(pm, - TP_PROTO(const char *event), - TP_ARGS(event), - TP_STRUCT__entry(__field(const char *, event)), - TP_fast_assign(__entry->event = event;), - TP_printk("%s", __entry->event) -); - -TRACE_EVENT(job, - TP_PROTO(const char *event, struct ivpu_job *job), - TP_ARGS(event, job), - TP_STRUCT__entry(__field(const char *, event) - __field(u32, ctx_id) - __field(u32, engine_id) - __field(u32, job_id) - ), - TP_fast_assign(__entry->event = event; - __entry->ctx_id = job->file_priv->ctx.id; - __entry->engine_id = job->engine_idx; - __entry->job_id = job->job_id;), - TP_printk("%s context:%d engine:%d job:%d", - __entry->event, - __entry->ctx_id, - __entry->engine_id, - __entry->job_id) -); - -TRACE_EVENT(jsm, - TP_PROTO(const char *event, struct vpu_jsm_msg *msg), - TP_ARGS(event, msg), - TP_STRUCT__entry(__field(const char *, event) - __field(const char *, type) - __field(enum vpu_ipc_msg_status, status) - __field(u32, request_id) - __field(u32, result) - ), - TP_fast_assign(__entry->event = event; - __entry->type = ivpu_jsm_msg_type_to_str(msg->type); - __entry->status = msg->status; - __entry->request_id = msg->request_id; - __entry->result = msg->result;), - TP_printk("%s type:%s, status:%#x, id:%#x, result:%#x", - __entry->event, - __entry->type, - __entry->status, - __entry->request_id, - __entry->result) -); - -#endif /* __IVPU_TRACE_H__ */ - -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH . -#include diff --git a/drivers/accel/ivpu/ivpu_trace_points.c b/drivers/accel/ivpu/ivpu_trace_points.c deleted file mode 100644 index f8fb99de0de3..000000000000 --- a/drivers/accel/ivpu/ivpu_trace_points.c +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2020-2024 Intel Corporation - */ - -#ifndef __CHECKER__ -#define CREATE_TRACE_POINTS -#include "ivpu_trace.h" -#endif From a628e1d318eeb74080d97020fe8def1f990fdf87 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 23/64] Revert "accel/ivpu: Remove HWS_EXTRA_EVENTS from test modes" This reverts commit 510413041eba737151f3536da8c1d44d09cf7c92. --- drivers/accel/ivpu/ivpu_drv.h | 1 + drivers/accel/ivpu/ivpu_jsm_msg.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 5b43f91f2015..151ab9f2ddc9 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -195,6 +195,7 @@ extern bool ivpu_force_snoop; #define IVPU_TEST_MODE_D0I3_MSG_DISABLE BIT(4) #define IVPU_TEST_MODE_D0I3_MSG_ENABLE BIT(5) #define IVPU_TEST_MODE_PREEMPTION_DISABLE BIT(6) +#define IVPU_TEST_MODE_HWS_EXTRA_EVENTS BIT(7) #define IVPU_TEST_MODE_DISABLE_TIMEOUTS BIT(8) #define IVPU_TEST_MODE_TURBO BIT(9) extern int ivpu_test_mode; diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index 8f5d904ca1ed..494ebc2475b1 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -394,6 +394,8 @@ int ivpu_jsm_hws_set_scheduling_log(struct ivpu_device *vdev, u32 engine_idx, u3 req.payload.hws_set_scheduling_log.host_ssid = host_ssid; req.payload.hws_set_scheduling_log.vpu_log_buffer_va = vpu_log_buffer_va; req.payload.hws_set_scheduling_log.notify_index = 0; + req.payload.hws_set_scheduling_log.enable_extra_events = + ivpu_test_mode & IVPU_TEST_MODE_HWS_EXTRA_EVENTS; ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG_RSP, &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); From 65de539866e9ac8fd2050616d68a15bc807d40dc Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 24/64] Revert "accel/ivpu: Fix ivpu_jsm_dyndbg_control()" This reverts commit 71f743b9250e24b67cc8cda83e1525097f03a0ba. --- drivers/accel/ivpu/ivpu_jsm_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index 494ebc2475b1..ae91ad24d10d 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -197,7 +197,7 @@ int ivpu_jsm_dyndbg_control(struct ivpu_device *vdev, char *command, size_t size strscpy(req.payload.dyndbg_control.dyndbg_cmd, command, VPU_DYNDBG_CMD_MAX_LEN); ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_DYNDBG_CONTROL_RSP, &resp, - VPU_IPC_CHAN_GEN_CMD, vdev->timeout.jsm); + VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); if (ret) ivpu_warn_ratelimited(vdev, "Failed to send command \"%s\": ret %d\n", command, ret); From 8db580f59eeebc3447bcf7ef65de536f5a9b897b Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 25/64] Revert "accel/ivpu: Increase MS info buffer size" This reverts commit 3fc15abe3876d88d0e7a0ce3553bf6ad1fc3bff0. --- drivers/accel/ivpu/ivpu_ms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_ms.c b/drivers/accel/ivpu/ivpu_ms.c index ffe7b10f8a76..2f9d37f5c208 100644 --- a/drivers/accel/ivpu/ivpu_ms.c +++ b/drivers/accel/ivpu/ivpu_ms.c @@ -11,7 +11,7 @@ #include "ivpu_ms.h" #include "ivpu_pm.h" -#define MS_INFO_BUFFER_SIZE SZ_64K +#define MS_INFO_BUFFER_SIZE SZ_16K #define MS_NUM_BUFFERS 2 #define MS_READ_PERIOD_MULTIPLIER 2 #define MS_MIN_SAMPLE_PERIOD_NS 1000000 From 952a9c1d1b79293413faaf4302c55445eca2f055 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 26/64] Revert "accel/ivpu: Use whole user and shave ranges for preemption buffers" This reverts commit 34b023383fca9ce961da00e4f06df21517ae83c0. --- drivers/accel/ivpu/ivpu_job.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index cd41b8771505..48272bc853e0 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -33,19 +33,24 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, { u64 primary_size = ALIGN(vdev->fw->primary_preempt_buf_size, PAGE_SIZE); u64 secondary_size = ALIGN(vdev->fw->secondary_preempt_buf_size, PAGE_SIZE); + struct ivpu_addr_range range; if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) return 0; - cmdq->primary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.user, - primary_size, DRM_IVPU_BO_WC); + range.start = vdev->hw->ranges.user.end - (primary_size * IVPU_NUM_CMDQS_PER_CTX); + range.end = vdev->hw->ranges.user.end; + cmdq->primary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &range, primary_size, + DRM_IVPU_BO_WC); if (!cmdq->primary_preempt_buf) { ivpu_err(vdev, "Failed to create primary preemption buffer\n"); return -ENOMEM; } - cmdq->secondary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.shave, - secondary_size, DRM_IVPU_BO_WC); + range.start = vdev->hw->ranges.shave.end - (secondary_size * IVPU_NUM_CMDQS_PER_CTX); + range.end = vdev->hw->ranges.shave.end; + cmdq->secondary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &range, secondary_size, + DRM_IVPU_BO_WC); if (!cmdq->secondary_preempt_buf) { ivpu_err(vdev, "Failed to create secondary preemption buffer\n"); goto err_free_primary; From b72f9887de4f5900aa594f5e4666696b77df7416 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 27/64] Revert "accel/ivpu: Do not fail on cmdq if failed to allocate preemption buffers" This reverts commit 600e906605ab770226270dd9be411e374e85d758. --- drivers/accel/ivpu/ivpu_job.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 48272bc853e0..dc5cf7ded943 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -60,7 +60,6 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, err_free_primary: ivpu_bo_free(cmdq->primary_preempt_buf); - cmdq->primary_preempt_buf = NULL; return -ENOMEM; } @@ -70,10 +69,10 @@ static void ivpu_preemption_buffers_free(struct ivpu_device *vdev, if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) return; - if (cmdq->primary_preempt_buf) - ivpu_bo_free(cmdq->primary_preempt_buf); - if (cmdq->secondary_preempt_buf) - ivpu_bo_free(cmdq->secondary_preempt_buf); + drm_WARN_ON(&vdev->drm, !cmdq->primary_preempt_buf); + drm_WARN_ON(&vdev->drm, !cmdq->secondary_preempt_buf); + ivpu_bo_free(cmdq->primary_preempt_buf); + ivpu_bo_free(cmdq->secondary_preempt_buf); } static int ivpu_id_alloc(struct xarray *xa, u32 *id, void *entry, struct xa_limit *limit, @@ -121,10 +120,12 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) ret = ivpu_preemption_buffers_create(vdev, file_priv, cmdq); if (ret) - ivpu_warn(vdev, "Failed to allocate preemption buffers, preemption limited\n"); + goto err_free_cmdq_mem; return cmdq; +err_free_cmdq_mem: + ivpu_bo_free(cmdq->mem); err_erase_xa: xa_erase(&vdev->db_xa, cmdq->db_id); err_free_cmdq: @@ -387,16 +388,10 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW && (unlikely(!(ivpu_test_mode & IVPU_TEST_MODE_PREEMPTION_DISABLE)))) { - if (cmdq->primary_preempt_buf) { - entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr; - entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf); - } - - if (cmdq->secondary_preempt_buf) { - entry->secondary_preempt_buf_addr = cmdq->secondary_preempt_buf->vpu_addr; - entry->secondary_preempt_buf_size = - ivpu_bo_size(cmdq->secondary_preempt_buf); - } + entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr; + entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf); + entry->secondary_preempt_buf_addr = cmdq->secondary_preempt_buf->vpu_addr; + entry->secondary_preempt_buf_size = ivpu_bo_size(cmdq->secondary_preempt_buf); } wmb(); /* Ensure that tail is updated after filling entry */ From bf95af01e01fbe4e61c210d079451bae1d46dcf8 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 28/64] Revert "accel/ivpu: Remove invalid warnings" This reverts commit 501b3b9c092065ef127147a216fac49d0da0f1ef. --- drivers/accel/ivpu/ivpu_drv.c | 2 ++ drivers/accel/ivpu/ivpu_ipc.c | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index dc983140128b..14c2412c6f8e 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -117,6 +117,8 @@ void ivpu_file_priv_put(struct ivpu_file_priv **link) struct ivpu_file_priv *file_priv = *link; struct ivpu_device *vdev = file_priv->vdev; + drm_WARN_ON(&vdev->drm, !file_priv); + ivpu_dbg(vdev, KREF, "file_priv put: ctx %u refcount %u\n", file_priv->ctx.id, kref_read(&file_priv->ref)); diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index c8ae69a529c0..a4ebb761354c 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -533,6 +533,7 @@ void ivpu_ipc_fini(struct ivpu_device *vdev) { struct ivpu_ipc_info *ipc = vdev->ipc; + drm_WARN_ON(&vdev->drm, ipc->on); drm_WARN_ON(&vdev->drm, !list_empty(&ipc->cons_list)); drm_WARN_ON(&vdev->drm, !list_empty(&ipc->cb_msg_list)); drm_WARN_ON(&vdev->drm, atomic_read(&ipc->rx_msg_count) > 0); From 071cecb7374722224bccfbf2a9556738b0a3a019 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 29/64] Revert "accel/ivpu: Refactor failure diagnostics during boot" This reverts commit 37ac5d915de82bf636ca288e4573757f4178c1a8. --- drivers/accel/ivpu/ivpu_drv.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 14c2412c6f8e..ffb8309a4f65 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -386,7 +386,10 @@ int ivpu_boot(struct ivpu_device *vdev) ret = ivpu_wait_for_ready(vdev); if (ret) { ivpu_err(vdev, "Failed to boot the firmware: %d\n", ret); - goto err_diagnose_failure; + ivpu_hw_diagnose_failure(vdev); + ivpu_mmu_evtq_dump(vdev); + ivpu_dev_coredump(vdev); + return ret; } ivpu_hw_irq_clear(vdev); @@ -397,20 +400,12 @@ int ivpu_boot(struct ivpu_device *vdev) if (ivpu_fw_is_cold_boot(vdev)) { ret = ivpu_pm_dct_init(vdev); if (ret) - goto err_diagnose_failure; + return ret; - ret = ivpu_hw_sched_init(vdev); - if (ret) - goto err_diagnose_failure; + return ivpu_hw_sched_init(vdev); } return 0; - -err_diagnose_failure: - ivpu_hw_diagnose_failure(vdev); - ivpu_mmu_evtq_dump(vdev); - ivpu_dev_coredump(vdev); - return ret; } void ivpu_prepare_for_reset(struct ivpu_device *vdev) From 7ea2709f9decb5e89875b27cfa17de052180f08e Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 30/64] Revert "accel/ivpu: Prevent recovery invocation during probe and resume" This reverts commit 6aa2272caac50ab5f0232f88f9d339c63063c632. --- drivers/accel/ivpu/ivpu_ipc.c | 35 ++++++++++++++++++++----------- drivers/accel/ivpu/ivpu_ipc.h | 7 ++++--- drivers/accel/ivpu/ivpu_jsm_msg.c | 19 ++++++++++------- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index a4ebb761354c..e7bccc20e4e4 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -291,16 +291,15 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, return ret; } -int +static int ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req, enum vpu_ipc_msg_type expected_resp_type, - struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms) + struct vpu_jsm_msg *resp, u32 channel, + unsigned long timeout_ms) { struct ivpu_ipc_consumer cons; int ret; - drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev)); - ivpu_ipc_consumer_add(vdev, &cons, channel, NULL); ret = ivpu_ipc_send(vdev, &cons, req); @@ -326,21 +325,19 @@ ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req return ret; } -int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, - enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, - u32 channel, unsigned long timeout_ms) +int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *req, + enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, + u32 channel, unsigned long timeout_ms) { struct vpu_jsm_msg hb_req = { .type = VPU_JSM_MSG_QUERY_ENGINE_HB }; struct vpu_jsm_msg hb_resp; int ret, hb_ret; - ret = ivpu_rpm_get(vdev); - if (ret < 0) - return ret; + drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev)); ret = ivpu_ipc_send_receive_internal(vdev, req, expected_resp, resp, channel, timeout_ms); if (ret != -ETIMEDOUT) - goto rpm_put; + return ret; hb_ret = ivpu_ipc_send_receive_internal(vdev, &hb_req, VPU_JSM_MSG_QUERY_ENGINE_HB_DONE, &hb_resp, VPU_IPC_CHAN_ASYNC_CMD, @@ -348,7 +345,21 @@ int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, if (hb_ret == -ETIMEDOUT) ivpu_pm_trigger_recovery(vdev, "IPC timeout"); -rpm_put: + return ret; +} + +int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, + enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, + u32 channel, unsigned long timeout_ms) +{ + int ret; + + ret = ivpu_rpm_get(vdev); + if (ret < 0) + return ret; + + ret = ivpu_ipc_send_receive_active(vdev, req, expected_resp, resp, channel, timeout_ms); + ivpu_rpm_put(vdev); return ret; } diff --git a/drivers/accel/ivpu/ivpu_ipc.h b/drivers/accel/ivpu/ivpu_ipc.h index b4dfb504679b..6bbe6e32c874 100644 --- a/drivers/accel/ivpu/ivpu_ipc.h +++ b/drivers/accel/ivpu/ivpu_ipc.h @@ -101,9 +101,10 @@ int ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct ivpu_ipc_hdr *ipc_buf, struct vpu_jsm_msg *jsm_msg, unsigned long timeout_ms); -int ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req, - enum vpu_ipc_msg_type expected_resp_type, - struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms); + +int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *req, + enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, + u32 channel, unsigned long timeout_ms); int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms); diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index ae91ad24d10d..cd33964d292b 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -271,8 +271,9 @@ int ivpu_jsm_pwr_d0i3_enter(struct ivpu_device *vdev) req.payload.pwr_d0i3_enter.send_response = 1; - ret = ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_PWR_D0I3_ENTER_DONE, &resp, - VPU_IPC_CHAN_GEN_CMD, vdev->timeout.d0i3_entry_msg); + ret = ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_PWR_D0I3_ENTER_DONE, + &resp, VPU_IPC_CHAN_GEN_CMD, + vdev->timeout.d0i3_entry_msg); if (ret) return ret; @@ -430,8 +431,8 @@ int ivpu_jsm_hws_setup_priority_bands(struct ivpu_device *vdev) req.payload.hws_priority_band_setup.normal_band_percentage = 10; - ret = ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP_RSP, - &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); + ret = ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP_RSP, + &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); if (ret) ivpu_warn_ratelimited(vdev, "Failed to set priority bands: %d\n", ret); @@ -544,8 +545,9 @@ int ivpu_jsm_dct_enable(struct ivpu_device *vdev, u32 active_us, u32 inactive_us req.payload.pwr_dct_control.dct_active_us = active_us; req.payload.pwr_dct_control.dct_inactive_us = inactive_us; - return ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_DCT_ENABLE_DONE, &resp, - VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); + return ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_DCT_ENABLE_DONE, + &resp, VPU_IPC_CHAN_ASYNC_CMD, + vdev->timeout.jsm); } int ivpu_jsm_dct_disable(struct ivpu_device *vdev) @@ -553,8 +555,9 @@ int ivpu_jsm_dct_disable(struct ivpu_device *vdev) struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_DCT_DISABLE }; struct vpu_jsm_msg resp; - return ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_DCT_DISABLE_DONE, &resp, - VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); + return ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_DCT_DISABLE_DONE, + &resp, VPU_IPC_CHAN_ASYNC_CMD, + vdev->timeout.jsm); } int ivpu_jsm_state_dump(struct ivpu_device *vdev) From 4583a9d55dd19a7bca2987372c5c503662c38873 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 31/64] Revert "accel/ivpu: Fix reset_engine debugfs file logic" This reverts commit 2a658dea3e63635cf443e8eccea3986602a0ad6b. --- drivers/accel/ivpu/ivpu_debugfs.c | 42 +++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index 8958145c49ad..f873119e56fe 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -337,23 +337,49 @@ static const struct file_operations ivpu_force_recovery_fops = { .write = ivpu_force_recovery_fn, }; -static int ivpu_reset_engine_fn(void *data, u64 val) +static ssize_t +ivpu_reset_engine_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) { - struct ivpu_device *vdev = (struct ivpu_device *)data; + struct ivpu_device *vdev = file->private_data; + + if (!size) + return -EINVAL; - return ivpu_jsm_reset_engine(vdev, (u32)val); + if (ivpu_jsm_reset_engine(vdev, DRM_IVPU_ENGINE_COMPUTE)) + return -ENODEV; + if (ivpu_jsm_reset_engine(vdev, DRM_IVPU_ENGINE_COPY)) + return -ENODEV; + + return size; } -DEFINE_DEBUGFS_ATTRIBUTE(ivpu_reset_engine_fops, NULL, ivpu_reset_engine_fn, "0x%02llx\n"); +static const struct file_operations ivpu_reset_engine_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .write = ivpu_reset_engine_fn, +}; -static int ivpu_resume_engine_fn(void *data, u64 val) +static ssize_t +ivpu_resume_engine_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) { - struct ivpu_device *vdev = (struct ivpu_device *)data; + struct ivpu_device *vdev = file->private_data; + + if (!size) + return -EINVAL; - return ivpu_jsm_hws_resume_engine(vdev, (u32)val); + if (ivpu_jsm_hws_resume_engine(vdev, DRM_IVPU_ENGINE_COMPUTE)) + return -ENODEV; + if (ivpu_jsm_hws_resume_engine(vdev, DRM_IVPU_ENGINE_COPY)) + return -ENODEV; + + return size; } -DEFINE_DEBUGFS_ATTRIBUTE(ivpu_resume_engine_fops, NULL, ivpu_resume_engine_fn, "0x%02llx\n"); +static const struct file_operations ivpu_resume_engine_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .write = ivpu_resume_engine_fn, +}; static int dct_active_get(void *data, u64 *active_percent) { From b78ea78e5a2eb58f9ab7ec7fa48e034f9f5ddd09 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 32/64] Revert "accel/ivpu: Remove skip of clock own resource ack on Simics" This reverts commit bd6322680519216d9f2425e6addddd4fcdc76c9d. --- drivers/accel/ivpu/ivpu_hw_btrs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index 6d5f1cc71143..7dc8e333dcec 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -459,6 +459,9 @@ int ivpu_hw_btrs_wait_for_clock_res_own_ack(struct ivpu_device *vdev) if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) return 0; + if (ivpu_is_simics(vdev)) + return 0; + return REGB_POLL_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, CLOCK_RESOURCE_OWN_ACK, 1, TIMEOUT_US); } From fe3b76432bf6dbdb68a4ebb88560562470cfa831 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 33/64] Revert "accel/ivpu: Add test_mode bit to force turbo" This reverts commit 4c4fa0fece31c0051e143fed630d4855930bfaa8. --- drivers/accel/ivpu/ivpu_drv.h | 1 - drivers/accel/ivpu/ivpu_job.c | 5 ----- 2 files changed, 6 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 151ab9f2ddc9..9acef14deab5 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -197,7 +197,6 @@ extern bool ivpu_force_snoop; #define IVPU_TEST_MODE_PREEMPTION_DISABLE BIT(6) #define IVPU_TEST_MODE_HWS_EXTRA_EVENTS BIT(7) #define IVPU_TEST_MODE_DISABLE_TIMEOUTS BIT(8) -#define IVPU_TEST_MODE_TURBO BIT(9) extern int ivpu_test_mode; struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv); diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index dc5cf7ded943..8798fb2046ab 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -202,11 +202,6 @@ ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 eng jobq_header->engine_idx = engine; jobq_header->head = 0; jobq_header->tail = 0; - if (ivpu_test_mode & IVPU_TEST_MODE_TURBO) { - ivpu_dbg(vdev, JOB, "Turbo mode enabled"); - jobq_header->flags = VPU_JOB_QUEUE_FLAGS_TURBO_MODE; - } - wmb(); /* Flush WC buffer for jobq->header */ if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { From 30d5bb3de218216fa52a195d36e5b1f9a9000055 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 34/64] Revert "accel/ivpu: Make DB_ID and JOB_ID allocations incremental" This reverts commit 5622ac7cdfa430faeb3975e5163d47a71b921567. --- drivers/accel/ivpu/ivpu_drv.c | 9 --------- drivers/accel/ivpu/ivpu_drv.h | 7 ------- drivers/accel/ivpu/ivpu_job.c | 37 ++++++++++------------------------- 3 files changed, 10 insertions(+), 43 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index ffb8309a4f65..fcf26e6d4e9c 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -260,11 +260,6 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) if (ret) goto err_xa_erase; - file_priv->default_job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, - (file_priv->ctx.id - 1)); - file_priv->default_job_limit.max = file_priv->default_job_limit.min | IVPU_JOB_ID_JOB_MASK; - file_priv->job_limit = file_priv->default_job_limit; - mutex_unlock(&vdev->context_list_lock); drm_dev_exit(idx); @@ -619,10 +614,6 @@ static int ivpu_dev_init(struct ivpu_device *vdev) lockdep_set_class(&vdev->submitted_jobs_xa.xa_lock, &submitted_jobs_xa_lock_class_key); INIT_LIST_HEAD(&vdev->bo_list); - vdev->default_db_limit.min = IVPU_MIN_DB; - vdev->default_db_limit.max = IVPU_MAX_DB; - vdev->db_limit = vdev->default_db_limit; - ret = drmm_mutex_init(&vdev->drm, &vdev->context_list_lock); if (ret) goto err_xa_destroy; diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 9acef14deab5..c4bd8757f8de 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -45,9 +45,6 @@ #define IVPU_MIN_DB 1 #define IVPU_MAX_DB 255 -#define IVPU_JOB_ID_JOB_MASK GENMASK(7, 0) -#define IVPU_JOB_ID_CONTEXT_MASK GENMASK(31, 8) - #define IVPU_NUM_ENGINES 2 #define IVPU_NUM_PRIORITIES 4 #define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_ENGINES * IVPU_NUM_PRIORITIES) @@ -138,8 +135,6 @@ struct ivpu_device { struct xa_limit context_xa_limit; struct xarray db_xa; - struct xa_limit db_limit; - struct xa_limit default_db_limit; struct mutex bo_list_lock; /* Protects bo_list */ struct list_head bo_list; @@ -175,8 +170,6 @@ struct ivpu_file_priv { struct mutex ms_lock; /* Protects ms_instance_list, ms_info_bo */ struct list_head ms_instance_list; struct ivpu_bo *ms_info_bo; - struct xa_limit job_limit; - struct xa_limit default_job_limit; bool has_mmu_faults; bool bound; bool aborted; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 8798fb2046ab..b1abdca5891c 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -21,6 +21,8 @@ #include "vpu_boot_api.h" #define CMD_BUF_IDX 0 +#define JOB_ID_JOB_MASK GENMASK(7, 0) +#define JOB_ID_CONTEXT_MASK GENMASK(31, 8) #define JOB_MAX_BUFFER_COUNT 65535 static void ivpu_cmdq_ring_db(struct ivpu_device *vdev, struct ivpu_cmdq *cmdq) @@ -75,28 +77,9 @@ static void ivpu_preemption_buffers_free(struct ivpu_device *vdev, ivpu_bo_free(cmdq->secondary_preempt_buf); } -static int ivpu_id_alloc(struct xarray *xa, u32 *id, void *entry, struct xa_limit *limit, - const struct xa_limit default_limit) -{ - int ret; - - ret = __xa_alloc(xa, id, entry, *limit, GFP_KERNEL); - if (ret) { - limit->min = default_limit.min; - ret = __xa_alloc(xa, id, entry, *limit, GFP_KERNEL); - if (ret) - return ret; - } - - limit->min = *id + 1; - if (limit->min > limit->max) - limit->min = default_limit.min; - - return ret; -} - static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) { + struct xa_limit db_xa_limit = {.max = IVPU_MAX_DB, .min = IVPU_MIN_DB}; struct ivpu_device *vdev = file_priv->vdev; struct ivpu_cmdq *cmdq; int ret; @@ -105,10 +88,7 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) if (!cmdq) return NULL; - xa_lock(&vdev->db_xa); /* lock here to protect db_limit */ - ret = ivpu_id_alloc(&vdev->db_xa, &cmdq->db_id, NULL, &vdev->db_limit, - vdev->default_db_limit); - xa_unlock(&vdev->db_xa); + ret = xa_alloc(&vdev->db_xa, &cmdq->db_id, NULL, db_xa_limit, GFP_KERNEL); if (ret) { ivpu_err(vdev, "Failed to allocate doorbell id: %d\n", ret); goto err_free_cmdq; @@ -539,6 +519,7 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) { struct ivpu_file_priv *file_priv = job->file_priv; struct ivpu_device *vdev = job->vdev; + struct xa_limit job_id_range; struct ivpu_cmdq *cmdq; bool is_first_job; int ret; @@ -549,7 +530,7 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) mutex_lock(&file_priv->lock); - cmdq = ivpu_cmdq_acquire(file_priv, job->engine_idx, priority); + cmdq = ivpu_cmdq_acquire(job->file_priv, job->engine_idx, priority); if (!cmdq) { ivpu_warn_ratelimited(vdev, "Failed to get job queue, ctx %d engine %d prio %d\n", file_priv->ctx.id, job->engine_idx, priority); @@ -557,10 +538,12 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) goto err_unlock_file_priv; } + job_id_range.min = FIELD_PREP(JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); + job_id_range.max = job_id_range.min | JOB_ID_JOB_MASK; + xa_lock(&vdev->submitted_jobs_xa); is_first_job = xa_empty(&vdev->submitted_jobs_xa); - ret = ivpu_id_alloc(&vdev->submitted_jobs_xa, &job->job_id, job, &file_priv->job_limit, - file_priv->default_job_limit); + ret = __xa_alloc(&vdev->submitted_jobs_xa, &job->job_id, job, job_id_range, GFP_KERNEL); if (ret) { ivpu_dbg(vdev, JOB, "Too many active jobs in ctx %d\n", file_priv->ctx.id); From 34916f21f25ce17e28332091bb722042758373b6 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 35/64] Revert "accel/ivpu: Print JSM message result in case of error" This reverts commit 4a72f38a40f1056b8092444bf072d2dc79d56c8d. --- drivers/accel/ivpu/ivpu_ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index e7bccc20e4e4..83b4ba4f3e20 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -278,7 +278,7 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, u32 size = min_t(int, rx_msg->ipc_hdr->data_size, sizeof(*jsm_msg)); if (rx_msg->jsm_msg->result != VPU_JSM_STATUS_SUCCESS) { - ivpu_err(vdev, "IPC resp result error: %d\n", rx_msg->jsm_msg->result); + ivpu_dbg(vdev, IPC, "IPC resp result error: %d\n", rx_msg->jsm_msg->result); ret = -EBADMSG; } From 974e04aaaec64ac7fb8c5b1f36f6437b9e562975 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 36/64] Revert "accel/ivpu: Add auto selection logic for job scheduler" This reverts commit ebac4503c1578e1e2c79606abaa4b9696a532f73. --- drivers/accel/ivpu/ivpu_drv.c | 6 +++--- drivers/accel/ivpu/ivpu_drv.h | 2 -- drivers/accel/ivpu/ivpu_fw.c | 15 ++------------- drivers/accel/ivpu/ivpu_fw.h | 3 --- drivers/accel/ivpu/ivpu_hw.h | 1 + drivers/accel/ivpu/ivpu_hw_btrs.c | 2 ++ drivers/accel/ivpu/ivpu_job.c | 14 +++++++------- drivers/accel/ivpu/ivpu_sysfs.c | 24 ------------------------ 8 files changed, 15 insertions(+), 52 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index fcf26e6d4e9c..9fd371af5814 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -54,9 +54,9 @@ u8 ivpu_pll_max_ratio = U8_MAX; module_param_named(pll_max_ratio, ivpu_pll_max_ratio, byte, 0644); MODULE_PARM_DESC(pll_max_ratio, "Maximum PLL ratio used to set NPU frequency"); -int ivpu_sched_mode = IVPU_SCHED_MODE_AUTO; +int ivpu_sched_mode; module_param_named(sched_mode, ivpu_sched_mode, int, 0444); -MODULE_PARM_DESC(sched_mode, "Scheduler mode: -1 - Use default scheduler, 0 - Use OS scheduler, 1 - Use HW scheduler"); +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, 0444); @@ -347,7 +347,7 @@ static int ivpu_hw_sched_init(struct ivpu_device *vdev) { int ret = 0; - if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { + if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) { ret = ivpu_jsm_hws_setup_priority_bands(vdev); if (ret) { ivpu_err(vdev, "Failed to enable hw scheduler: %d", ret); diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index c4bd8757f8de..471478281021 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -56,8 +56,6 @@ #define IVPU_PLATFORM_FPGA 3 #define IVPU_PLATFORM_INVALID 8 -#define IVPU_SCHED_MODE_AUTO -1 - #define IVPU_DBG_REG BIT(0) #define IVPU_DBG_IRQ BIT(1) #define IVPU_DBG_MMU BIT(2) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index 4d59dd19f684..7e8593c831ec 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -134,15 +134,6 @@ static bool is_within_range(u64 addr, size_t size, u64 range_start, size_t range return true; } -static u32 -ivpu_fw_sched_mode_select(struct ivpu_device *vdev, const struct vpu_firmware_header *fw_hdr) -{ - if (ivpu_sched_mode != IVPU_SCHED_MODE_AUTO) - return ivpu_sched_mode; - - return VPU_SCHEDULING_MODE_OS; -} - static int ivpu_fw_parse(struct ivpu_device *vdev) { struct ivpu_fw_info *fw = vdev->fw; @@ -224,10 +215,8 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) fw->dvfs_mode = 0; - fw->sched_mode = ivpu_fw_sched_mode_select(vdev, fw_hdr); fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size; fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size; - ivpu_info(vdev, "Scheduler mode: %s\n", fw->sched_mode ? "HW" : "OS"); if (fw_hdr->ro_section_start_address && !is_within_range(fw_hdr->ro_section_start_address, fw_hdr->ro_section_size, @@ -616,8 +605,8 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params boot_params->punit_telemetry_sram_base = ivpu_hw_telemetry_offset_get(vdev); boot_params->punit_telemetry_sram_size = ivpu_hw_telemetry_size_get(vdev); boot_params->vpu_telemetry_enable = ivpu_hw_telemetry_enable_get(vdev); - boot_params->vpu_scheduling_mode = vdev->fw->sched_mode; - if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) + boot_params->vpu_scheduling_mode = vdev->hw->sched_mode; + if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) boot_params->vpu_focus_present_timer_ms = IVPU_FOCUS_PRESENT_TIMER_MS; boot_params->dvfs_mode = vdev->fw->dvfs_mode; if (!IVPU_WA(disable_d0i3_msg)) diff --git a/drivers/accel/ivpu/ivpu_fw.h b/drivers/accel/ivpu/ivpu_fw.h index 1d0b2bd9d65c..5e8eb608b70f 100644 --- a/drivers/accel/ivpu/ivpu_fw.h +++ b/drivers/accel/ivpu/ivpu_fw.h @@ -6,8 +6,6 @@ #ifndef __IVPU_FW_H__ #define __IVPU_FW_H__ -#include "vpu_jsm_api.h" - #define FW_VERSION_HEADER_SIZE SZ_4K #define FW_VERSION_STR_SIZE SZ_256 @@ -38,7 +36,6 @@ struct ivpu_fw_info { u32 secondary_preempt_buf_size; u64 read_only_addr; u32 read_only_size; - u32 sched_mode; }; int ivpu_fw_init(struct ivpu_device *vdev); diff --git a/drivers/accel/ivpu/ivpu_hw.h b/drivers/accel/ivpu/ivpu_hw.h index dc5518248c40..1c0c98e3afb8 100644 --- a/drivers/accel/ivpu/ivpu_hw.h +++ b/drivers/accel/ivpu/ivpu_hw.h @@ -46,6 +46,7 @@ struct ivpu_hw_info { u32 profiling_freq; } pll; u32 tile_fuse; + u32 sched_mode; u32 sku; u16 config; int dma_bits; diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index 7dc8e333dcec..cad2ce7f2e24 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -163,6 +163,7 @@ static int info_init_mtl(struct ivpu_device *vdev) hw->tile_fuse = BTRS_MTL_TILE_FUSE_ENABLE_BOTH; hw->sku = BTRS_MTL_TILE_SKU_BOTH; hw->config = BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO; + hw->sched_mode = ivpu_sched_mode; return 0; } @@ -177,6 +178,7 @@ static int info_init_lnl(struct ivpu_device *vdev) if (ret) return ret; + hw->sched_mode = ivpu_sched_mode; hw->tile_fuse = tile_fuse_config; hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index b1abdca5891c..b00634af8bc3 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -37,7 +37,7 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, u64 secondary_size = ALIGN(vdev->fw->secondary_preempt_buf_size, PAGE_SIZE); struct ivpu_addr_range range; - if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) + if (vdev->hw->sched_mode != VPU_SCHEDULING_MODE_HW) return 0; range.start = vdev->hw->ranges.user.end - (primary_size * IVPU_NUM_CMDQS_PER_CTX); @@ -68,7 +68,7 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, static void ivpu_preemption_buffers_free(struct ivpu_device *vdev, struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq) { - if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) + if (vdev->hw->sched_mode != VPU_SCHEDULING_MODE_HW) return; drm_WARN_ON(&vdev->drm, !cmdq->primary_preempt_buf); @@ -149,7 +149,7 @@ static int ivpu_register_db(struct ivpu_file_priv *file_priv, struct ivpu_cmdq * struct ivpu_device *vdev = file_priv->vdev; int ret; - if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) + if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) ret = ivpu_jsm_hws_register_db(vdev, file_priv->ctx.id, cmdq->db_id, cmdq->db_id, cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); else @@ -184,7 +184,7 @@ ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 eng jobq_header->tail = 0; wmb(); /* Flush WC buffer for jobq->header */ - if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { + if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) { ret = ivpu_hws_cmdq_init(file_priv, cmdq, engine, priority); if (ret) return ret; @@ -211,7 +211,7 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm cmdq->db_registered = false; - if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { + if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) { ret = ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->db_id); if (!ret) ivpu_dbg(vdev, JOB, "Command queue %d destroyed\n", cmdq->db_id); @@ -335,7 +335,7 @@ void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv) ivpu_cmdq_fini_all(file_priv); - if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_OS) + if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_OS) ivpu_jsm_context_release(vdev, file_priv->ctx.id); } @@ -361,7 +361,7 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_SUBMISSION)) entry->flags = VPU_JOB_FLAGS_NULL_SUBMISSION_MASK; - if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW && + if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW && (unlikely(!(ivpu_test_mode & IVPU_TEST_MODE_PREEMPTION_DISABLE)))) { entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr; entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf); diff --git a/drivers/accel/ivpu/ivpu_sysfs.c b/drivers/accel/ivpu/ivpu_sysfs.c index 616477fc17fa..913669f1786e 100644 --- a/drivers/accel/ivpu/ivpu_sysfs.c +++ b/drivers/accel/ivpu/ivpu_sysfs.c @@ -6,8 +6,6 @@ #include #include -#include "ivpu_drv.h" -#include "ivpu_fw.h" #include "ivpu_hw.h" #include "ivpu_sysfs.h" @@ -41,30 +39,8 @@ npu_busy_time_us_show(struct device *dev, struct device_attribute *attr, char *b static DEVICE_ATTR_RO(npu_busy_time_us); -/** - * DOC: sched_mode - * - * The sched_mode is used to report current NPU scheduling mode. - * - * It returns following strings: - * - "HW" - Hardware Scheduler mode - * - "OS" - Operating System Scheduler mode - * - */ -static ssize_t -sched_mode_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct drm_device *drm = dev_get_drvdata(dev); - struct ivpu_device *vdev = to_ivpu_device(drm); - - return sysfs_emit(buf, "%s\n", vdev->fw->sched_mode ? "HW" : "OS"); -} - -static DEVICE_ATTR_RO(sched_mode); - static struct attribute *ivpu_dev_attrs[] = { &dev_attr_npu_busy_time_us.attr, - &dev_attr_sched_mode.attr, NULL, }; From 6cb6393950a9717e72786e339c7ec455c7f6b727 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 37/64] Revert "accel/ivpu: Add one jiffy to bo_wait_ioctl timeout value" This reverts commit 3d34cdb6e88e86e45e681b12bdcb5b244d42903e. --- drivers/accel/ivpu/ivpu_gem.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c index d8e97a760fbc..1b409dbd332d 100644 --- a/drivers/accel/ivpu/ivpu_gem.c +++ b/drivers/accel/ivpu/ivpu_gem.c @@ -384,9 +384,6 @@ int ivpu_bo_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file timeout = drm_timeout_abs_to_jiffies(args->timeout_ns); - /* Add 1 jiffy to ensure the wait function never times out before intended timeout_ns */ - timeout += 1; - obj = drm_gem_object_lookup(file, args->handle); if (!obj) return -EINVAL; From 947d29f81954566c08ab0961a6683c14a48b4626 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 38/64] Revert "accel/ivpu: Allow reading dvfs_mode debugfs file" This reverts commit 179f7d54e598668935f3e8d7d4110235643c9282. --- drivers/accel/ivpu/ivpu_debugfs.c | 33 ++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index f873119e56fe..55dc2d883b44 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -127,23 +127,32 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = { {"reset_pending", reset_pending_show, 0}, }; -static int dvfs_mode_get(void *data, u64 *dvfs_mode) +static ssize_t +dvfs_mode_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) { - struct ivpu_device *vdev = (struct ivpu_device *)data; + struct ivpu_device *vdev = file->private_data; + struct ivpu_fw_info *fw = vdev->fw; + u32 dvfs_mode; + int ret; - *dvfs_mode = vdev->fw->dvfs_mode; - return 0; -} + ret = kstrtou32_from_user(user_buf, size, 0, &dvfs_mode); + if (ret < 0) + return ret; -static int dvfs_mode_set(void *data, u64 dvfs_mode) -{ - struct ivpu_device *vdev = (struct ivpu_device *)data; + fw->dvfs_mode = dvfs_mode; - vdev->fw->dvfs_mode = (u32)dvfs_mode; - return pci_try_reset_function(to_pci_dev(vdev->drm.dev)); + ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev)); + if (ret) + return ret; + + return size; } -DEFINE_DEBUGFS_ATTRIBUTE(dvfs_mode_fops, dvfs_mode_get, dvfs_mode_set, "%llu\n"); +static const struct file_operations dvfs_mode_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .write = dvfs_mode_fops_write, +}; static ssize_t fw_dyndbg_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) @@ -423,7 +432,7 @@ void ivpu_debugfs_init(struct ivpu_device *vdev) debugfs_create_file("force_recovery", 0200, debugfs_root, vdev, &ivpu_force_recovery_fops); - debugfs_create_file("dvfs_mode", 0644, debugfs_root, vdev, + debugfs_create_file("dvfs_mode", 0200, debugfs_root, vdev, &dvfs_mode_fops); debugfs_create_file("fw_dyndbg", 0200, debugfs_root, vdev, From 83f2e56d72a9fdcb9bdec737a864d30d0bf79afd Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 39/64] Revert "accel/ivpu: Remove 1-tile power up Simics workaround" This reverts commit 92e7274612ce92f22ded871a5241125fa584a1aa. --- drivers/accel/ivpu/ivpu_hw_btrs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index cad2ce7f2e24..745e5248803d 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -315,6 +315,10 @@ static void prepare_wp_request(struct ivpu_device *vdev, struct wp_request *wp, wp->cdyn = enable ? PLL_CDYN_DEFAULT : 0; wp->epp = enable ? PLL_EPP_DEFAULT : 0; } + + /* Simics cannot start without at least one tile */ + if (enable && ivpu_is_simics(vdev)) + wp->cfg = 1; } static int wait_for_pll_lock(struct ivpu_device *vdev, bool enable) From 149a0ca136fdfbd6141af5ee66e47e150784436e Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 40/64] Revert "accel/ivpu: Stop using hardcoded DRIVER_DATE" This reverts commit 91bacfa43a2d2abd4e90f0d3f1e7424d4bb00890. --- drivers/accel/ivpu/ivpu_drv.c | 15 ++++----------- drivers/accel/ivpu/ivpu_drv.h | 1 + include/uapi/drm/ivpu_accel.h | 3 +++ 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 9fd371af5814..38b4158f5278 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include @@ -33,7 +32,8 @@ #include "vpu_boot_api.h" #ifndef DRIVER_VERSION_STR -#define DRIVER_VERSION_STR "1.0.0 " UTS_RELEASE +#define DRIVER_VERSION_STR __stringify(DRM_IVPU_DRIVER_MAJOR) "." \ + __stringify(DRM_IVPU_DRIVER_MINOR) "." #endif static struct lock_class_key submitted_jobs_xa_lock_class_key; @@ -447,16 +447,9 @@ static const struct drm_driver driver = { .name = DRIVER_NAME, .desc = DRIVER_DESC, - -#ifdef DRIVER_DATE .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -#else - .date = UTS_RELEASE, - .major = 1, -#endif + .major = DRM_IVPU_DRIVER_MAJOR, + .minor = DRM_IVPU_DRIVER_MINOR, }; static void ivpu_context_abort_invalid(struct ivpu_device *vdev) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 471478281021..2b30cc2e9272 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -21,6 +21,7 @@ #define DRIVER_NAME "intel_vpu" #define DRIVER_DESC "Driver for Intel NPU (Neural Processing Unit)" +#define DRIVER_DATE "20230117" #define PCI_DEVICE_ID_MTL 0x7d1d #define PCI_DEVICE_ID_ARL 0xad1d diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h index 234664d35250..084fb529e1e9 100644 --- a/include/uapi/drm/ivpu_accel.h +++ b/include/uapi/drm/ivpu_accel.h @@ -12,6 +12,9 @@ extern "C" { #endif +#define DRM_IVPU_DRIVER_MAJOR 1 +#define DRM_IVPU_DRIVER_MINOR 0 + #define DRM_IVPU_GET_PARAM 0x00 #define DRM_IVPU_SET_PARAM 0x01 #define DRM_IVPU_BO_CREATE 0x02 From 6e38b4ed7c06f99005145c27ec08aa1fc59969e6 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 41/64] Revert "accel/ivpu: Add FW version debugfs entry" This reverts commit f03bbdc4189bb58b30375c867d95cdc6dae60b73. --- drivers/accel/ivpu/ivpu_debugfs.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index 55dc2d883b44..cd3ac08f0409 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -45,14 +45,6 @@ static int fw_name_show(struct seq_file *s, void *v) return 0; } -static int fw_version_show(struct seq_file *s, void *v) -{ - struct ivpu_device *vdev = seq_to_ivpu(s); - - seq_printf(s, "%s\n", vdev->fw->version); - return 0; -} - static int fw_trace_capability_show(struct seq_file *s, void *v) { struct ivpu_device *vdev = seq_to_ivpu(s); @@ -119,7 +111,6 @@ static int reset_pending_show(struct seq_file *s, void *v) static const struct drm_debugfs_info vdev_debugfs_list[] = { {"bo_list", bo_list_show, 0}, {"fw_name", fw_name_show, 0}, - {"fw_version", fw_version_show, 0}, {"fw_trace_capability", fw_trace_capability_show, 0}, {"fw_trace_config", fw_trace_config_show, 0}, {"last_bootmode", last_bootmode_show, 0}, From 02ba94a8a0eee619f8a06067a3f791fe9ef48f7b Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 42/64] Revert "accel/ivpu: Turn on autosuspend on Simics" This reverts commit 9ea936b7f23701f36b353bf107958e623852839a. --- drivers/accel/ivpu/ivpu_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index 1c259d717815..85219e959621 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -94,7 +94,7 @@ static void timeouts_init(struct ivpu_device *vdev) vdev->timeout.boot = 50; vdev->timeout.jsm = 500; vdev->timeout.tdr = 10000; - vdev->timeout.autosuspend = 100; + vdev->timeout.autosuspend = -1; vdev->timeout.d0i3_entry_msg = 100; vdev->timeout.state_dump_msg = 10; } else { From e9bfd4fed7b7628fbcad7daf36bff95e24e9fe5f Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 43/64] Revert "accel/ivpu: Set 500 ns delay between power island TRICKLE and ENABLE" This reverts commit 83e194a12cc734be9f8b11b50004803693e8ebd2. --- drivers/accel/ivpu/ivpu_hw_ip.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c index cfcbb99168e6..dfd2f4a5b526 100644 --- a/drivers/accel/ivpu/ivpu_hw_ip.c +++ b/drivers/accel/ivpu/ivpu_hw_ip.c @@ -311,6 +311,9 @@ static void pwr_island_trickle_drive_40xx(struct ivpu_device *vdev, bool enable) val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, CSS_CPU, val); REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, val); + + if (enable) + ndelay(500); } static void pwr_island_drive_37xx(struct ivpu_device *vdev, bool enable) @@ -323,6 +326,9 @@ static void pwr_island_drive_37xx(struct ivpu_device *vdev, bool enable) val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, CSS_CPU, val); REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, val); + + if (!enable) + ndelay(500); } static void pwr_island_drive_40xx(struct ivpu_device *vdev, bool enable) @@ -341,11 +347,9 @@ static void pwr_island_enable(struct ivpu_device *vdev) { if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) { pwr_island_trickle_drive_37xx(vdev, true); - ndelay(500); pwr_island_drive_37xx(vdev, true); } else { pwr_island_trickle_drive_40xx(vdev, true); - ndelay(500); pwr_island_drive_40xx(vdev, true); } } From b52df7d79a783a23745bc0899299f92d554c68b3 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 44/64] Revert "accel/ivpu: Add FW state dump on TDR" This reverts commit 9813aacbed43a692f0019296171543e93ad72cde. --- drivers/accel/ivpu/ivpu_drv.h | 1 - drivers/accel/ivpu/ivpu_hw.c | 3 --- drivers/accel/ivpu/ivpu_ipc.c | 26 -------------------------- drivers/accel/ivpu/ivpu_ipc.h | 2 -- drivers/accel/ivpu/ivpu_jsm_msg.c | 8 -------- drivers/accel/ivpu/ivpu_jsm_msg.h | 2 -- drivers/accel/ivpu/ivpu_pm.c | 1 - 7 files changed, 43 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 2b30cc2e9272..63f13b697eed 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -152,7 +152,6 @@ struct ivpu_device { int tdr; int autosuspend; int d0i3_entry_msg; - int state_dump_msg; } timeout; }; diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index 85219e959621..27f0fe4d54e0 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -89,14 +89,12 @@ static void timeouts_init(struct ivpu_device *vdev) vdev->timeout.tdr = 2000000; vdev->timeout.autosuspend = -1; vdev->timeout.d0i3_entry_msg = 500; - vdev->timeout.state_dump_msg = 10; } else if (ivpu_is_simics(vdev)) { vdev->timeout.boot = 50; vdev->timeout.jsm = 500; vdev->timeout.tdr = 10000; vdev->timeout.autosuspend = -1; vdev->timeout.d0i3_entry_msg = 100; - vdev->timeout.state_dump_msg = 10; } else { vdev->timeout.boot = 1000; vdev->timeout.jsm = 500; @@ -106,7 +104,6 @@ static void timeouts_init(struct ivpu_device *vdev) else vdev->timeout.autosuspend = 100; vdev->timeout.d0i3_entry_msg = 5; - vdev->timeout.state_dump_msg = 10; } } diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index 83b4ba4f3e20..78b32a823241 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -364,32 +364,6 @@ int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, return ret; } -int ivpu_ipc_send_and_wait(struct ivpu_device *vdev, struct vpu_jsm_msg *req, - u32 channel, unsigned long timeout_ms) -{ - struct ivpu_ipc_consumer cons; - int ret; - - ret = ivpu_rpm_get(vdev); - if (ret < 0) - return ret; - - ivpu_ipc_consumer_add(vdev, &cons, channel, NULL); - - ret = ivpu_ipc_send(vdev, &cons, req); - if (ret) { - ivpu_warn_ratelimited(vdev, "IPC send failed: %d\n", ret); - goto consumer_del; - } - - msleep(timeout_ms); - -consumer_del: - ivpu_ipc_consumer_del(vdev, &cons); - ivpu_rpm_put(vdev); - return ret; -} - static bool ivpu_ipc_match_consumer(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct ivpu_ipc_hdr *ipc_hdr, struct vpu_jsm_msg *jsm_msg) diff --git a/drivers/accel/ivpu/ivpu_ipc.h b/drivers/accel/ivpu/ivpu_ipc.h index 6bbe6e32c874..4fe38141045e 100644 --- a/drivers/accel/ivpu/ivpu_ipc.h +++ b/drivers/accel/ivpu/ivpu_ipc.h @@ -108,7 +108,5 @@ int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *r int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms); -int ivpu_ipc_send_and_wait(struct ivpu_device *vdev, struct vpu_jsm_msg *req, - u32 channel, unsigned long timeout_ms); #endif /* __IVPU_IPC_H__ */ diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index cd33964d292b..b06da8f50fd3 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -559,11 +559,3 @@ int ivpu_jsm_dct_disable(struct ivpu_device *vdev) &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); } - -int ivpu_jsm_state_dump(struct ivpu_device *vdev) -{ - struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_STATE_DUMP }; - - return ivpu_ipc_send_and_wait(vdev, &req, VPU_IPC_CHAN_ASYNC_CMD, - vdev->timeout.state_dump_msg); -} diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.h b/drivers/accel/ivpu/ivpu_jsm_msg.h index 9e84d3526a14..e4e42c0ff6e6 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.h +++ b/drivers/accel/ivpu/ivpu_jsm_msg.h @@ -43,6 +43,4 @@ int ivpu_jsm_metric_streamer_info(struct ivpu_device *vdev, u64 metric_group_mas u64 buffer_size, u32 *sample_size, u64 *info_size); int ivpu_jsm_dct_enable(struct ivpu_device *vdev, u32 active_us, u32 inactive_us); int ivpu_jsm_dct_disable(struct ivpu_device *vdev); -int ivpu_jsm_state_dump(struct ivpu_device *vdev); - #endif diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index b5a69941e6e0..bf77395ffcb7 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -125,7 +125,6 @@ static void ivpu_pm_recovery_work(struct work_struct *work) if (ret) ivpu_err(vdev, "Failed to resume NPU: %d\n", ret); - ivpu_jsm_state_dump(vdev); ivpu_dev_coredump(vdev); atomic_inc(&vdev->pm->reset_counter); From 7e5337c8b9e4b0e5a5931126061a7d3aa039a477 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 45/64] Revert "accel/ivpu: Add coredump support" This reverts commit 217ab111cc5d27689b489d5dcf156a555672e6b2. --- drivers/accel/ivpu/Kconfig | 1 - drivers/accel/ivpu/Makefile | 1 - drivers/accel/ivpu/ivpu_coredump.c | 39 ------------------------------ drivers/accel/ivpu/ivpu_coredump.h | 25 ------------------- drivers/accel/ivpu/ivpu_drv.c | 5 ++-- drivers/accel/ivpu/ivpu_fw_log.h | 8 ++++++ drivers/accel/ivpu/ivpu_pm.c | 9 +++---- 7 files changed, 14 insertions(+), 74 deletions(-) delete mode 100644 drivers/accel/ivpu/ivpu_coredump.c delete mode 100644 drivers/accel/ivpu/ivpu_coredump.h diff --git a/drivers/accel/ivpu/Kconfig b/drivers/accel/ivpu/Kconfig index e4d418b44626..682c53245286 100644 --- a/drivers/accel/ivpu/Kconfig +++ b/drivers/accel/ivpu/Kconfig @@ -8,7 +8,6 @@ config DRM_ACCEL_IVPU select FW_LOADER select DRM_GEM_SHMEM_HELPER select GENERIC_ALLOCATOR - select WANT_DEV_COREDUMP help Choose this option if you have a system with an 14th generation Intel CPU (Meteor Lake) or newer. Intel NPU (formerly called Intel VPU) diff --git a/drivers/accel/ivpu/Makefile b/drivers/accel/ivpu/Makefile index 232ea6d28c6e..ebd682a42eb1 100644 --- a/drivers/accel/ivpu/Makefile +++ b/drivers/accel/ivpu/Makefile @@ -19,6 +19,5 @@ intel_vpu-y := \ ivpu_sysfs.o intel_vpu-$(CONFIG_DEBUG_FS) += ivpu_debugfs.o -intel_vpu-$(CONFIG_DEV_COREDUMP) += ivpu_coredump.o obj-$(CONFIG_DRM_ACCEL_IVPU) += intel_vpu.o diff --git a/drivers/accel/ivpu/ivpu_coredump.c b/drivers/accel/ivpu/ivpu_coredump.c deleted file mode 100644 index 16ad0c30818c..000000000000 --- a/drivers/accel/ivpu/ivpu_coredump.c +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2020-2024 Intel Corporation - */ - -#include -#include - -#include "ivpu_coredump.h" -#include "ivpu_fw.h" -#include "ivpu_gem.h" -#include "vpu_boot_api.h" - -#define CRASH_DUMP_HEADER "Intel NPU crash dump" -#define CRASH_DUMP_HEADERS_SIZE SZ_4K - -void ivpu_dev_coredump(struct ivpu_device *vdev) -{ - struct drm_print_iterator pi = {}; - struct drm_printer p; - size_t coredump_size; - char *coredump; - - coredump_size = CRASH_DUMP_HEADERS_SIZE + FW_VERSION_HEADER_SIZE + - ivpu_bo_size(vdev->fw->mem_log_crit) + ivpu_bo_size(vdev->fw->mem_log_verb); - coredump = vmalloc(coredump_size); - if (!coredump) - return; - - pi.data = coredump; - pi.remain = coredump_size; - p = drm_coredump_printer(&pi); - - drm_printf(&p, "%s\n", CRASH_DUMP_HEADER); - drm_printf(&p, "FW version: %s\n", vdev->fw->version); - ivpu_fw_log_print(vdev, false, &p); - - dev_coredumpv(vdev->drm.dev, coredump, pi.offset, GFP_KERNEL); -} diff --git a/drivers/accel/ivpu/ivpu_coredump.h b/drivers/accel/ivpu/ivpu_coredump.h deleted file mode 100644 index 8efb09d02441..000000000000 --- a/drivers/accel/ivpu/ivpu_coredump.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2020-2024 Intel Corporation - */ - -#ifndef __IVPU_COREDUMP_H__ -#define __IVPU_COREDUMP_H__ - -#include - -#include "ivpu_drv.h" -#include "ivpu_fw_log.h" - -#ifdef CONFIG_DEV_COREDUMP -void ivpu_dev_coredump(struct ivpu_device *vdev); -#else -static inline void ivpu_dev_coredump(struct ivpu_device *vdev) -{ - struct drm_printer p = drm_info_printer(vdev->drm.dev); - - ivpu_fw_log_print(vdev, false, &p); -} -#endif - -#endif /* __IVPU_COREDUMP_H__ */ diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 38b4158f5278..c91400ecf926 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -14,7 +14,7 @@ #include #include -#include "ivpu_coredump.h" +#include "vpu_boot_api.h" #include "ivpu_debugfs.h" #include "ivpu_drv.h" #include "ivpu_fw.h" @@ -29,7 +29,6 @@ #include "ivpu_ms.h" #include "ivpu_pm.h" #include "ivpu_sysfs.h" -#include "vpu_boot_api.h" #ifndef DRIVER_VERSION_STR #define DRIVER_VERSION_STR __stringify(DRM_IVPU_DRIVER_MAJOR) "." \ @@ -383,7 +382,7 @@ int ivpu_boot(struct ivpu_device *vdev) ivpu_err(vdev, "Failed to boot the firmware: %d\n", ret); ivpu_hw_diagnose_failure(vdev); ivpu_mmu_evtq_dump(vdev); - ivpu_dev_coredump(vdev); + ivpu_fw_log_dump(vdev); return ret; } diff --git a/drivers/accel/ivpu/ivpu_fw_log.h b/drivers/accel/ivpu/ivpu_fw_log.h index 8bb528a73cb7..41c85b74cc7f 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.h +++ b/drivers/accel/ivpu/ivpu_fw_log.h @@ -8,6 +8,8 @@ #include +#include + #include "ivpu_drv.h" #define IVPU_FW_LOG_DEFAULT 0 @@ -27,5 +29,11 @@ void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_ void ivpu_fw_log_mark_read(struct ivpu_device *vdev); void ivpu_fw_log_reset(struct ivpu_device *vdev); +static inline void ivpu_fw_log_dump(struct ivpu_device *vdev) +{ + struct drm_printer p = drm_info_printer(vdev->drm.dev); + + ivpu_fw_log_print(vdev, false, &p); +} #endif /* __IVPU_FW_LOG_H__ */ diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index bf77395ffcb7..3c36b55c01d5 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -9,18 +9,17 @@ #include #include -#include "ivpu_coredump.h" +#include "vpu_boot_api.h" #include "ivpu_drv.h" +#include "ivpu_hw.h" #include "ivpu_fw.h" #include "ivpu_fw_log.h" -#include "ivpu_hw.h" #include "ivpu_ipc.h" #include "ivpu_job.h" #include "ivpu_jsm_msg.h" #include "ivpu_mmu.h" #include "ivpu_ms.h" #include "ivpu_pm.h" -#include "vpu_boot_api.h" static bool ivpu_disable_recovery; module_param_named_unsafe(disable_recovery, ivpu_disable_recovery, bool, 0644); @@ -125,7 +124,7 @@ static void ivpu_pm_recovery_work(struct work_struct *work) if (ret) ivpu_err(vdev, "Failed to resume NPU: %d\n", ret); - ivpu_dev_coredump(vdev); + ivpu_fw_log_dump(vdev); atomic_inc(&vdev->pm->reset_counter); atomic_set(&vdev->pm->reset_pending, 1); @@ -264,7 +263,7 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev) if (!is_idle || ret_d0i3) { ivpu_err(vdev, "Forcing cold boot due to previous errors\n"); atomic_inc(&vdev->pm->reset_counter); - ivpu_dev_coredump(vdev); + ivpu_fw_log_dump(vdev); ivpu_pm_prepare_cold_boot(vdev); } else { ivpu_pm_prepare_warm_boot(vdev); From f836950b977f40742d8bf676a84fa3b9e9bce246 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 46/64] Revert "accel/ivpu: Limit FW version string length" This reverts commit 33ea696beebcd5b50af849ff1b929f476d0eb38c. --- drivers/accel/ivpu/ivpu_fw.c | 7 +++---- drivers/accel/ivpu/ivpu_fw.h | 6 +----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index 7e8593c831ec..00e27e2c1477 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -25,6 +25,7 @@ #define FW_SHAVE_NN_MAX_SIZE SZ_2M #define FW_RUNTIME_MIN_ADDR (FW_GLOBAL_MEM_START) #define FW_RUNTIME_MAX_ADDR (FW_GLOBAL_MEM_END - FW_SHARED_MEM_SIZE) +#define FW_VERSION_HEADER_SIZE SZ_4K #define FW_FILE_IMAGE_OFFSET (VPU_FW_HEADER_SIZE + FW_VERSION_HEADER_SIZE) #define WATCHDOG_MSS_REDIRECT 32 @@ -190,10 +191,8 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) ivpu_dbg(vdev, FW_BOOT, "Header version: 0x%x, format 0x%x\n", fw_hdr->header_version, fw_hdr->image_format); - if (!scnprintf(fw->version, sizeof(fw->version), "%s", fw->file->data + VPU_FW_HEADER_SIZE)) - ivpu_warn(vdev, "Missing firmware version\n"); - - ivpu_info(vdev, "Firmware: %s, version: %s\n", fw->name, fw->version); + ivpu_info(vdev, "Firmware: %s, version: %s", fw->name, + (const char *)fw_hdr + VPU_FW_HEADER_SIZE); if (IVPU_FW_CHECK_API_COMPAT(vdev, fw_hdr, BOOT, 3)) return -EINVAL; diff --git a/drivers/accel/ivpu/ivpu_fw.h b/drivers/accel/ivpu/ivpu_fw.h index 5e8eb608b70f..40d9d17be3f5 100644 --- a/drivers/accel/ivpu/ivpu_fw.h +++ b/drivers/accel/ivpu/ivpu_fw.h @@ -1,14 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2020-2024 Intel Corporation + * Copyright (C) 2020-2023 Intel Corporation */ #ifndef __IVPU_FW_H__ #define __IVPU_FW_H__ -#define FW_VERSION_HEADER_SIZE SZ_4K -#define FW_VERSION_STR_SIZE SZ_256 - struct ivpu_device; struct ivpu_bo; struct vpu_boot_params; @@ -16,7 +13,6 @@ struct vpu_boot_params; struct ivpu_fw_info { const struct firmware *file; const char *name; - char version[FW_VERSION_STR_SIZE]; struct ivpu_bo *mem; struct ivpu_bo *mem_shave_nn; struct ivpu_bo *mem_log_crit; From ff040aa57b6734e5f9c684daefdec3418a2c4e3b Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 47/64] Revert "accel/ivpu: Fix fw log printing" This reverts commit 822ba2dd1406824c31557b8c35757a5152be94fc. --- drivers/accel/ivpu/ivpu_fw_log.c | 49 +++++++++++--------------------- 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index 337c906b0210..343ebfd30d28 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -87,7 +87,7 @@ static void fw_log_print_lines(char *buffer, u32 size, struct drm_printer *p) } line[index] = 0; if (index != 0) - drm_printf(p, "%s", line); + drm_printf(p, "%s\n", line); } static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const char *prefix, @@ -95,29 +95,23 @@ static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const cha { char *log_data = (void *)log + log->header_size; u32 data_size = log->size - log->header_size; - u32 log_start = only_new_msgs ? READ_ONCE(log->read_index) : 0; - u32 log_end = READ_ONCE(log->write_index); + u32 log_start = log->read_index; + u32 log_end = log->write_index; - if (log->wrap_count == log->read_wrap_count) { - if (log_end <= log_start) { - drm_printf(p, "==== %s \"%s\" log empty ====\n", prefix, log->name); - return; - } - } else if (log->wrap_count == log->read_wrap_count + 1) { - if (log_end > log_start) - log_start = log_end; - } else { - log_start = log_end; + if (!(log->write_index || log->wrap_count) || + (log->write_index == log->read_index && only_new_msgs)) { + drm_printf(p, "==== %s \"%s\" log empty ====\n", prefix, log->name); + return; } drm_printf(p, "==== %s \"%s\" log start ====\n", prefix, log->name); - if (log_end > log_start) { + if (log->write_index > log->read_index) { fw_log_print_lines(log_data + log_start, log_end - log_start, p); } else { - fw_log_print_lines(log_data + log_start, data_size - log_start, p); + fw_log_print_lines(log_data + log_end, data_size - log_end, p); fw_log_print_lines(log_data, log_end, p); } - drm_printf(p, "\n\x1b[0m"); /* add new line and clear formatting */ + drm_printf(p, "\x1b[0m"); drm_printf(p, "==== %s \"%s\" log end ====\n", prefix, log->name); } @@ -141,19 +135,14 @@ void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_ void ivpu_fw_log_mark_read(struct ivpu_device *vdev) { struct vpu_tracing_buffer_header *log; - u32 next; + u32 next = 0; - next = 0; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) { - log->read_index = READ_ONCE(log->write_index); - log->read_wrap_count = READ_ONCE(log->wrap_count); - } + while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) + log->read_index = log->write_index; next = 0; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) { - log->read_index = READ_ONCE(log->write_index); - log->read_wrap_count = READ_ONCE(log->wrap_count); - } + while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) + log->read_index = log->write_index; } void ivpu_fw_log_reset(struct ivpu_device *vdev) @@ -162,14 +151,10 @@ void ivpu_fw_log_reset(struct ivpu_device *vdev) u32 next; next = 0; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) { + while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) log->read_index = 0; - log->read_wrap_count = 0; - } next = 0; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) { + while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) log->read_index = 0; - log->read_wrap_count = 0; - } } From 687bf30ec27b51cd96d88f31cf53f10577fea4d7 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 48/64] Revert "accel/ivpu: Refactor functions in ivpu_fw_log.c" This reverts commit 92eb20d7f244ac5b195a7ec9bcee8045bfa75acf. --- drivers/accel/ivpu/ivpu_debugfs.c | 2 +- drivers/accel/ivpu/ivpu_fw_log.c | 62 +++++++++++++++---------------- drivers/accel/ivpu/ivpu_fw_log.h | 2 +- 3 files changed, 31 insertions(+), 35 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index cd3ac08f0409..6f86f8df30db 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -192,7 +192,7 @@ fw_log_fops_write(struct file *file, const char __user *user_buf, size_t size, l if (!size) return -EINVAL; - ivpu_fw_log_mark_read(vdev); + ivpu_fw_log_clear(vdev); return size; } diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index 343ebfd30d28..817210e35f70 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -26,8 +26,8 @@ MODULE_PARM_DESC(fw_log_level, " error=" __stringify(IVPU_FW_LOG_ERROR) " fatal=" __stringify(IVPU_FW_LOG_FATAL)); -static int fw_log_from_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset, - struct vpu_tracing_buffer_header **out_log) +static int fw_log_ptr(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset, + struct vpu_tracing_buffer_header **log_header) { struct vpu_tracing_buffer_header *log; @@ -48,7 +48,7 @@ static int fw_log_from_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *off return -EINVAL; } - *out_log = log; + *log_header = log; *offset += log->size; ivpu_dbg(vdev, FW_BOOT, @@ -59,7 +59,7 @@ static int fw_log_from_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *off return 0; } -static void fw_log_print_lines(char *buffer, u32 size, struct drm_printer *p) +static void buffer_print(char *buffer, u32 size, struct drm_printer *p) { char line[IVPU_FW_LOG_LINE_LENGTH]; u32 index = 0; @@ -90,11 +90,11 @@ static void fw_log_print_lines(char *buffer, u32 size, struct drm_printer *p) drm_printf(p, "%s\n", line); } -static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const char *prefix, - bool only_new_msgs, struct drm_printer *p) +static void fw_log_print_buffer(struct ivpu_device *vdev, struct vpu_tracing_buffer_header *log, + const char *prefix, bool only_new_msgs, struct drm_printer *p) { - char *log_data = (void *)log + log->header_size; - u32 data_size = log->size - log->header_size; + char *log_buffer = (void *)log + log->header_size; + u32 log_size = log->size - log->header_size; u32 log_start = log->read_index; u32 log_end = log->write_index; @@ -106,55 +106,51 @@ static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const cha drm_printf(p, "==== %s \"%s\" log start ====\n", prefix, log->name); if (log->write_index > log->read_index) { - fw_log_print_lines(log_data + log_start, log_end - log_start, p); + buffer_print(log_buffer + log_start, log_end - log_start, p); } else { - fw_log_print_lines(log_data + log_end, data_size - log_end, p); - fw_log_print_lines(log_data, log_end, p); + buffer_print(log_buffer + log_end, log_size - log_end, p); + buffer_print(log_buffer, log_end, p); } drm_printf(p, "\x1b[0m"); drm_printf(p, "==== %s \"%s\" log end ====\n", prefix, log->name); } -static void -fw_log_print_all_in_bo(struct ivpu_device *vdev, const char *name, - struct ivpu_bo *bo, bool only_new_msgs, struct drm_printer *p) +void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p) { - struct vpu_tracing_buffer_header *log; + struct vpu_tracing_buffer_header *log_header; u32 next = 0; - while (fw_log_from_bo(vdev, bo, &next, &log) == 0) - fw_log_print_buffer(log, name, only_new_msgs, p); -} + while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0) + fw_log_print_buffer(vdev, log_header, "NPU critical", only_new_msgs, p); -void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p) -{ - fw_log_print_all_in_bo(vdev, "NPU critical", vdev->fw->mem_log_crit, only_new_msgs, p); - fw_log_print_all_in_bo(vdev, "NPU verbose", vdev->fw->mem_log_verb, only_new_msgs, p); + next = 0; + while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) + fw_log_print_buffer(vdev, log_header, "NPU verbose", only_new_msgs, p); } -void ivpu_fw_log_mark_read(struct ivpu_device *vdev) +void ivpu_fw_log_clear(struct ivpu_device *vdev) { - struct vpu_tracing_buffer_header *log; + struct vpu_tracing_buffer_header *log_header; u32 next = 0; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) - log->read_index = log->write_index; + while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0) + log_header->read_index = log_header->write_index; next = 0; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) - log->read_index = log->write_index; + while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) + log_header->read_index = log_header->write_index; } void ivpu_fw_log_reset(struct ivpu_device *vdev) { - struct vpu_tracing_buffer_header *log; + struct vpu_tracing_buffer_header *log_header; u32 next; next = 0; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) - log->read_index = 0; + while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0) + log_header->read_index = 0; next = 0; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) - log->read_index = 0; + while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) + log_header->read_index = 0; } diff --git a/drivers/accel/ivpu/ivpu_fw_log.h b/drivers/accel/ivpu/ivpu_fw_log.h index 41c85b74cc7f..a033ce2d642f 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.h +++ b/drivers/accel/ivpu/ivpu_fw_log.h @@ -26,7 +26,7 @@ extern unsigned int ivpu_fw_log_level; void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p); -void ivpu_fw_log_mark_read(struct ivpu_device *vdev); +void ivpu_fw_log_clear(struct ivpu_device *vdev); void ivpu_fw_log_reset(struct ivpu_device *vdev); static inline void ivpu_fw_log_dump(struct ivpu_device *vdev) From 04f85c63cb56b5e85014d8a9acae838a55897ee4 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 49/64] Revert "accel/ivpu: Reset fw log on cold boot" This reverts commit 20348813a1d28a4574d10751801c9de019753e97. --- drivers/accel/ivpu/ivpu_fw_log.c | 14 -------------- drivers/accel/ivpu/ivpu_fw_log.h | 1 - drivers/accel/ivpu/ivpu_pm.c | 1 - 3 files changed, 16 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index 817210e35f70..2f2d3242f21b 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -140,17 +140,3 @@ void ivpu_fw_log_clear(struct ivpu_device *vdev) while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) log_header->read_index = log_header->write_index; } - -void ivpu_fw_log_reset(struct ivpu_device *vdev) -{ - struct vpu_tracing_buffer_header *log_header; - u32 next; - - next = 0; - while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0) - log_header->read_index = 0; - - next = 0; - while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) - log_header->read_index = 0; -} diff --git a/drivers/accel/ivpu/ivpu_fw_log.h b/drivers/accel/ivpu/ivpu_fw_log.h index a033ce2d642f..ccef4298e45b 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.h +++ b/drivers/accel/ivpu/ivpu_fw_log.h @@ -27,7 +27,6 @@ extern unsigned int ivpu_fw_log_level; void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p); void ivpu_fw_log_clear(struct ivpu_device *vdev); -void ivpu_fw_log_reset(struct ivpu_device *vdev); static inline void ivpu_fw_log_dump(struct ivpu_device *vdev) { diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 3c36b55c01d5..59d3170f5e35 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -37,7 +37,6 @@ static void ivpu_pm_prepare_cold_boot(struct ivpu_device *vdev) ivpu_cmdq_reset_all_contexts(vdev); ivpu_ipc_reset(vdev); - ivpu_fw_log_reset(vdev); ivpu_fw_load(vdev); fw->entry_point = fw->cold_boot_entry_point; } From 234d1905b397af22f0aedcdfd5fb886eb5cb9592 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 50/64] Revert "accel/ivpu: Rename ivpu_log_level to fw_log_level" This reverts commit 5555951f90fd553dd5fed812c34a44a7288730f2. --- drivers/accel/ivpu/ivpu_fw.c | 4 ++-- drivers/accel/ivpu/ivpu_fw_log.c | 12 ++++++------ drivers/accel/ivpu/ivpu_fw_log.h | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index 00e27e2c1477..ede6165e09d9 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -208,7 +208,7 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) fw->cold_boot_entry_point = fw_hdr->entry_point; fw->entry_point = fw->cold_boot_entry_point; - fw->trace_level = min_t(u32, ivpu_fw_log_level, IVPU_FW_LOG_FATAL); + fw->trace_level = min_t(u32, ivpu_log_level, IVPU_FW_LOG_FATAL); fw->trace_destination_mask = VPU_TRACE_DESTINATION_VERBOSE_TRACING; fw->trace_hw_component_mask = -1; @@ -311,7 +311,7 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev) goto err_free_fw_mem; } - if (ivpu_fw_log_level <= IVPU_FW_LOG_INFO) + if (ivpu_log_level <= IVPU_FW_LOG_INFO) log_verb_size = IVPU_FW_VERBOSE_BUFFER_LARGE_SIZE; else log_verb_size = IVPU_FW_VERBOSE_BUFFER_SMALL_SIZE; diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index 2f2d3242f21b..ef0adb5e0fbe 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2020-2024 Intel Corporation + * Copyright (C) 2020-2023 Intel Corporation */ #include @@ -15,12 +15,12 @@ #include "ivpu_fw_log.h" #include "ivpu_gem.h" -#define IVPU_FW_LOG_LINE_LENGTH 256 +#define IVPU_FW_LOG_LINE_LENGTH 256 -unsigned int ivpu_fw_log_level = IVPU_FW_LOG_ERROR; -module_param_named(fw_log_level, ivpu_fw_log_level, uint, 0444); -MODULE_PARM_DESC(fw_log_level, - "NPU firmware default log level: debug=" __stringify(IVPU_FW_LOG_DEBUG) +unsigned int ivpu_log_level = IVPU_FW_LOG_ERROR; +module_param(ivpu_log_level, uint, 0444); +MODULE_PARM_DESC(ivpu_log_level, + "NPU firmware default trace level: debug=" __stringify(IVPU_FW_LOG_DEBUG) " info=" __stringify(IVPU_FW_LOG_INFO) " warn=" __stringify(IVPU_FW_LOG_WARN) " error=" __stringify(IVPU_FW_LOG_ERROR) diff --git a/drivers/accel/ivpu/ivpu_fw_log.h b/drivers/accel/ivpu/ivpu_fw_log.h index ccef4298e45b..0b2573f6f315 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.h +++ b/drivers/accel/ivpu/ivpu_fw_log.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2020-2024 Intel Corporation + * Copyright (C) 2020-2023 Intel Corporation */ #ifndef __IVPU_FW_LOG_H__ @@ -19,12 +19,12 @@ #define IVPU_FW_LOG_ERROR 4 #define IVPU_FW_LOG_FATAL 5 +extern unsigned int ivpu_log_level; + #define IVPU_FW_VERBOSE_BUFFER_SMALL_SIZE SZ_1M #define IVPU_FW_VERBOSE_BUFFER_LARGE_SIZE SZ_8M #define IVPU_FW_CRITICAL_BUFFER_SIZE SZ_512K -extern unsigned int ivpu_fw_log_level; - void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p); void ivpu_fw_log_clear(struct ivpu_device *vdev); From 385b8d338f6ccc85961bbb1cd7f9f4079700ba65 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 51/64] Revert "accel/ivpu: Update VPU FW API headers" This reverts commit bc34b707116cddeb5aa93c4dd3ee67205bbdf1a7. --- drivers/accel/ivpu/ivpu_job.c | 2 +- drivers/accel/ivpu/ivpu_jsm_msg.c | 3 +- drivers/accel/ivpu/vpu_boot_api.h | 43 ++--- drivers/accel/ivpu/vpu_jsm_api.h | 303 +++++------------------------- 4 files changed, 59 insertions(+), 292 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index b00634af8bc3..be2e2bf0f43f 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -354,7 +354,7 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) return -EBUSY; } - entry = &cmdq->jobq->slot[tail].job; + entry = &cmdq->jobq->job[tail]; entry->batch_buf_addr = job->cmd_buf_vpu_addr; entry->job_id = job->job_id; entry->flags = 0; diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index b06da8f50fd3..46ef16c3c069 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -48,10 +48,9 @@ const char *ivpu_jsm_msg_type_to_str(enum vpu_ipc_msg_type type) IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_RESUME_ENGINE_DONE); IVPU_CASE_TO_STR(VPU_JSM_MSG_STATE_DUMP); IVPU_CASE_TO_STR(VPU_JSM_MSG_STATE_DUMP_RSP); - IVPU_CASE_TO_STR(VPU_JSM_MSG_BLOB_DEINIT_DEPRECATED); + IVPU_CASE_TO_STR(VPU_JSM_MSG_BLOB_DEINIT); IVPU_CASE_TO_STR(VPU_JSM_MSG_DYNDBG_CONTROL); IVPU_CASE_TO_STR(VPU_JSM_MSG_JOB_DONE); - IVPU_CASE_TO_STR(VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED); IVPU_CASE_TO_STR(VPU_JSM_MSG_ENGINE_RESET_DONE); IVPU_CASE_TO_STR(VPU_JSM_MSG_ENGINE_PREEMPT_DONE); IVPU_CASE_TO_STR(VPU_JSM_MSG_REGISTER_DB_DONE); diff --git a/drivers/accel/ivpu/vpu_boot_api.h b/drivers/accel/ivpu/vpu_boot_api.h index 908e68ea1c39..d474bc7b15c0 100644 --- a/drivers/accel/ivpu/vpu_boot_api.h +++ b/drivers/accel/ivpu/vpu_boot_api.h @@ -1,12 +1,13 @@ /* SPDX-License-Identifier: MIT */ /* - * Copyright (c) 2020-2024, Intel Corporation. + * Copyright (c) 2020-2023, Intel Corporation. */ #ifndef VPU_BOOT_API_H #define VPU_BOOT_API_H /* + * =========== FW API version information beginning ================ * The below values will be used to construct the version info this way: * fw_bin_header->api_version[VPU_BOOT_API_VER_ID] = (VPU_BOOT_API_VER_MAJOR << 16) | * VPU_BOOT_API_VER_MINOR; @@ -26,18 +27,19 @@ * Minor version changes when API backward compatibility is preserved. * Resets to 0 if Major version is incremented. */ -#define VPU_BOOT_API_VER_MINOR 26 +#define VPU_BOOT_API_VER_MINOR 24 /* * API header changed (field names, documentation, formatting) but API itself has not been changed */ -#define VPU_BOOT_API_VER_PATCH 3 +#define VPU_BOOT_API_VER_PATCH 0 /* * Index in the API version table * Must be unique for each API */ #define VPU_BOOT_API_VER_INDEX 0 +/* ------------ FW API version information end ---------------------*/ #pragma pack(push, 4) @@ -162,6 +164,8 @@ enum vpu_trace_destination { /* VPU 30xx HW component IDs are sequential, so define first and last IDs. */ #define VPU_TRACE_PROC_BIT_30XX_FIRST VPU_TRACE_PROC_BIT_LRT #define VPU_TRACE_PROC_BIT_30XX_LAST VPU_TRACE_PROC_BIT_SHV_15 +#define VPU_TRACE_PROC_BIT_KMB_FIRST VPU_TRACE_PROC_BIT_30XX_FIRST +#define VPU_TRACE_PROC_BIT_KMB_LAST VPU_TRACE_PROC_BIT_30XX_LAST struct vpu_boot_l2_cache_config { u8 use; @@ -195,17 +199,6 @@ struct vpu_warm_boot_section { */ #define POWER_PROFILE_SURVIVABILITY 0x1 -/** - * Enum for dvfs_mode boot param. - */ -enum vpu_governor { - VPU_GOV_DEFAULT = 0, /* Default Governor for the system */ - VPU_GOV_MAX_PERFORMANCE = 1, /* Maximum performance governor */ - VPU_GOV_ON_DEMAND = 2, /* On Demand frequency control governor */ - VPU_GOV_POWER_SAVE = 3, /* Power save governor */ - VPU_GOV_ON_DEMAND_PRIORITY_AWARE = 4 /* On Demand priority based governor */ -}; - struct vpu_boot_params { u32 magic; u32 vpu_id; @@ -308,14 +301,7 @@ struct vpu_boot_params { u32 temp_sensor_period_ms; /** PLL ratio for efficient clock frequency */ u32 pn_freq_pll_ratio; - /** - * DVFS Mode: - * 0 - Default, DVFS mode selected by the firmware - * 1 - Max Performance - * 2 - On Demand - * 3 - Power Save - * 4 - On Demand Priority Aware - */ + /** DVFS Mode: Default: 0, Max Performance: 1, On Demand: 2, Power Save: 3 */ u32 dvfs_mode; /** * Depending on DVFS Mode: @@ -346,8 +332,8 @@ struct vpu_boot_params { u64 d0i3_entry_vpu_ts; /* * The system time of the host operating system in microseconds. - * E.g the number of microseconds since 1st of January 1970, or whatever - * date the host operating system uses to maintain system time. + * E.g the number of microseconds since 1st of January 1970, or whatever date the + * host operating system uses to maintain system time. * This value will be used to track system time on the VPU. * The KMD is required to update this value on every VPU reset. */ @@ -396,7 +382,10 @@ struct vpu_boot_params { u32 pad6[734]; }; -/* Magic numbers set between host and vpu to detect corruption of tracing init */ +/* + * Magic numbers set between host and vpu to detect corruptio of tracing init + */ + #define VPU_TRACING_BUFFER_CANARY (0xCAFECAFE) /* Tracing buffer message format definitions */ @@ -416,9 +405,7 @@ struct vpu_tracing_buffer_header { u32 host_canary_start; /* offset from start of buffer for trace entries */ u32 read_index; - /* keeps track of wrapping on the reader side */ - u32 read_wrap_count; - u32 pad_to_cache_line_size_0[13]; + u32 pad_to_cache_line_size_0[14]; /* End of first cache line */ /** diff --git a/drivers/accel/ivpu/vpu_jsm_api.h b/drivers/accel/ivpu/vpu_jsm_api.h index 7215c144158c..33f462b1a25d 100644 --- a/drivers/accel/ivpu/vpu_jsm_api.h +++ b/drivers/accel/ivpu/vpu_jsm_api.h @@ -22,7 +22,7 @@ /* * Minor version changes when API backward compatibility is preserved. */ -#define VPU_JSM_API_VER_MINOR 25 +#define VPU_JSM_API_VER_MINOR 16 /* * API header changed (field names, documentation, formatting) but API itself has not been changed @@ -36,7 +36,7 @@ /* * Number of Priority Bands for Hardware Scheduling - * Bands: Idle(0), Normal(1), Focus(2), RealTime(3) + * Bands: RealTime, Focus, Normal, Idle */ #define VPU_HWS_NUM_PRIORITY_BANDS 4 @@ -74,7 +74,6 @@ #define VPU_JSM_STATUS_MVNCI_INTERNAL_ERROR 0xCU /* Job status returned when the job was preempted mid-inference */ #define VPU_JSM_STATUS_PREEMPTED_MID_INFERENCE 0xDU -#define VPU_JSM_STATUS_MVNCI_CONTEXT_VIOLATION_HW 0xEU /* * Host <-> VPU IPC channels. @@ -87,58 +86,18 @@ /* * Job flags bit masks. */ -enum { - /* - * Null submission mask. - * When set, batch buffer's commands are not processed but returned as - * successful immediately, except fences and timestamps. - * When cleared, batch buffer's commands are processed normally. - * Used for testing and profiling purposes. - */ - VPU_JOB_FLAGS_NULL_SUBMISSION_MASK = (1 << 0U), - /* - * Inline command mask. - * When set, the object in job queue is an inline command (see struct vpu_inline_cmd below). - * When cleared, the object in job queue is a job (see struct vpu_job_queue_entry below). - */ - VPU_JOB_FLAGS_INLINE_CMD_MASK = (1 << 1U), - /* - * VPU private data mask. - * Reserved for the VPU to store private data about the job (or inline command) - * while being processed. - */ - VPU_JOB_FLAGS_PRIVATE_DATA_MASK = 0xFFFF0000U -}; +#define VPU_JOB_FLAGS_NULL_SUBMISSION_MASK 0x00000001 +#define VPU_JOB_FLAGS_PRIVATE_DATA_MASK 0xFF000000 /* - * Job queue flags bit masks. + * Sizes of the reserved areas in jobs, in bytes. */ -enum { - /* - * No job done notification mask. - * When set, indicates that no job done notification should be sent for any - * job from this queue. When cleared, indicates that job done notification - * should be sent for every job completed from this queue. - */ - VPU_JOB_QUEUE_FLAGS_NO_JOB_DONE_MASK = (1 << 0U), - /* - * Native fence usage mask. - * When set, indicates that job queue uses native fences (as inline commands - * in job queue). Such queues may also use legacy fences (as commands in batch buffers). - * When cleared, indicates the job queue only uses legacy fences. - * NOTE: For queues using native fences, VPU expects that all jobs in the queue - * are immediately followed by an inline command object. This object is expected - * to be a fence signal command in most cases, but can also be a NOP in case the host - * does not need per-job fence signalling. Other inline commands objects can be - * inserted between "job and inline command" pairs. - */ - VPU_JOB_QUEUE_FLAGS_USE_NATIVE_FENCE_MASK = (1 << 1U), +#define VPU_JOB_RESERVED_BYTES 8 - /* - * Enable turbo mode for testing NPU performance; not recommended for regular usage. - */ - VPU_JOB_QUEUE_FLAGS_TURBO_MODE = (1 << 2U) -}; +/* + * Sizes of the reserved areas in job queues, in bytes. + */ +#define VPU_JOB_QUEUE_RESERVED_BYTES 52 /* * Max length (including trailing NULL char) of trace entity name (e.g., the @@ -181,113 +140,24 @@ enum { */ #define VPU_HWS_INVALID_CMDQ_HANDLE 0ULL -/* - * Inline commands types. - */ -/* - * NOP. - * VPU does nothing other than consuming the inline command object. - */ -#define VPU_INLINE_CMD_TYPE_NOP 0x0 -/* - * Fence wait. - * VPU waits for the fence current value to reach monitored value. - * Fence wait operations are executed upon job dispatching. While waiting for - * the fence to be satisfied, VPU blocks fetching of the next objects in the queue. - * Jobs present in the queue prior to the fence wait object may be processed - * concurrently. - */ -#define VPU_INLINE_CMD_TYPE_FENCE_WAIT 0x1 -/* - * Fence signal. - * VPU sets the fence current value to the provided value. If new current value - * is equal to or higher than monitored value, VPU sends fence signalled notification - * to the host. Fence signal operations are executed upon completion of all the jobs - * present in the queue prior to them, and in-order relative to each other in the queue. - * But jobs in-between them may be processed concurrently and may complete out-of-order. - */ -#define VPU_INLINE_CMD_TYPE_FENCE_SIGNAL 0x2 - -/* - * Job scheduling priority bands for both hardware scheduling and OS scheduling. - */ -enum vpu_job_scheduling_priority_band { - VPU_JOB_SCHEDULING_PRIORITY_BAND_IDLE = 0, - VPU_JOB_SCHEDULING_PRIORITY_BAND_NORMAL = 1, - VPU_JOB_SCHEDULING_PRIORITY_BAND_FOCUS = 2, - VPU_JOB_SCHEDULING_PRIORITY_BAND_REALTIME = 3, - VPU_JOB_SCHEDULING_PRIORITY_BAND_COUNT = 4, -}; - /* * Job format. - * Jobs defines the actual workloads to be executed by a given engine. */ struct vpu_job_queue_entry { - /**< Address of VPU commands batch buffer */ - u64 batch_buf_addr; - /**< Job ID */ - u32 job_id; - /**< Flags bit field, see VPU_JOB_FLAGS_* above */ - u32 flags; - /** - * Doorbell ring timestamp taken by KMD from SoC's global system clock, in - * microseconds. NPU can convert this value to its own fixed clock's timebase, - * to match other profiling timestamps. - */ - u64 doorbell_timestamp; - /**< Extra id for job tracking, used only in the firmware perf traces */ - u64 host_tracking_id; - /**< Address of the primary preemption buffer to use for this job */ + u64 batch_buf_addr; /**< Address of VPU commands batch buffer */ + u32 job_id; /**< Job ID */ + u32 flags; /**< Flags bit field, see VPU_JOB_FLAGS_* above */ + u64 root_page_table_addr; /**< Address of root page table to use for this job */ + u64 root_page_table_update_counter; /**< Page tables update events counter */ u64 primary_preempt_buf_addr; - /**< Size of the primary preemption buffer to use for this job */ + /**< Address of the primary preemption buffer to use for this job */ u32 primary_preempt_buf_size; - /**< Size of secondary preemption buffer to use for this job */ + /**< Size of the primary preemption buffer to use for this job */ u32 secondary_preempt_buf_size; - /**< Address of secondary preemption buffer to use for this job */ + /**< Size of secondary preemption buffer to use for this job */ u64 secondary_preempt_buf_addr; - u64 reserved_0; -}; - -/* - * Inline command format. - * Inline commands are the commands executed at scheduler level (typically, - * synchronization directives). Inline command and job objects must be of - * the same size and have flags field at same offset. - */ -struct vpu_inline_cmd { - u64 reserved_0; - /* Inline command type, see VPU_INLINE_CMD_TYPE_* defines. */ - u32 type; - /* Flags bit field, see VPU_JOB_FLAGS_* above. */ - u32 flags; - /* Inline command payload. Depends on inline command type. */ - union { - /* Fence (wait and signal) commands' payload. */ - struct { - /* Fence object handle. */ - u64 fence_handle; - /* User VA of the current fence value. */ - u64 current_value_va; - /* User VA of the monitored fence value (read-only). */ - u64 monitored_value_va; - /* Value to wait for or write in fence location. */ - u64 value; - /* User VA of the log buffer in which to add log entry on completion. */ - u64 log_buffer_va; - } fence; - /* Other commands do not have a payload. */ - /* Payload definition for future inline commands can be inserted here. */ - u64 reserved_1[6]; - } payload; -}; - -/* - * Job queue slots can be populated either with job objects or inline command objects. - */ -union vpu_jobq_slot { - struct vpu_job_queue_entry job; - struct vpu_inline_cmd inline_cmd; + /**< Address of secondary preemption buffer to use for this job */ + u8 reserved_0[VPU_JOB_RESERVED_BYTES]; }; /* @@ -297,21 +167,7 @@ struct vpu_job_queue_header { u32 engine_idx; u32 head; u32 tail; - u32 flags; - /* Set to 1 to indicate priority_band field is valid */ - u32 priority_band_valid; - /* - * Priority for the work of this job queue, valid only if the HWS is NOT used - * and the `priority_band_valid` is set to 1. It is applied only during - * the VPU_JSM_MSG_REGISTER_DB message processing. - * The device firmware might use the `priority_band` to optimize the power - * management logic, but it will not affect the order of jobs. - * Available priority bands: @see enum vpu_job_scheduling_priority_band - */ - u32 priority_band; - /* Inside realtime band assigns a further priority, limited to 0..31 range */ - u32 realtime_priority_level; - u32 reserved_0[9]; + u8 reserved_0[VPU_JOB_QUEUE_RESERVED_BYTES]; }; /* @@ -319,7 +175,7 @@ struct vpu_job_queue_header { */ struct vpu_job_queue { struct vpu_job_queue_header header; - union vpu_jobq_slot slot[]; + struct vpu_job_queue_entry job[]; }; /** @@ -341,7 +197,9 @@ enum vpu_trace_entity_type { struct vpu_hws_log_buffer_header { /* Written by VPU after adding a log entry. Initialised by host to 0. */ u32 first_free_entry_index; - /* Incremented by VPU every time the VPU writes the 0th entry; initialised by host to 0. */ + /* Incremented by VPU every time the VPU overwrites the 0th entry; + * initialised by host to 0. + */ u32 wraparound_count; /* * This is the number of buffers that can be stored in the log buffer provided by the host. @@ -372,80 +230,14 @@ struct vpu_hws_log_buffer_entry { u64 operation_data[2]; }; -/* Native fence log buffer types. */ -enum vpu_hws_native_fence_log_type { - VPU_HWS_NATIVE_FENCE_LOG_TYPE_WAITS = 1, - VPU_HWS_NATIVE_FENCE_LOG_TYPE_SIGNALS = 2 -}; - -/* HWS native fence log buffer header. */ -struct vpu_hws_native_fence_log_header { - union { - struct { - /* Index of the first free entry in buffer. */ - u32 first_free_entry_idx; - /* Incremented each time NPU wraps around the buffer to write next entry. */ - u32 wraparound_count; - }; - /* Field allowing atomic update of both fields above. */ - u64 atomic_wraparound_and_entry_idx; - }; - /* Log buffer type, see enum vpu_hws_native_fence_log_type. */ - u64 type; - /* Allocated number of entries in the log buffer. */ - u64 entry_nb; - u64 reserved[2]; -}; - -/* Native fence log operation types. */ -enum vpu_hws_native_fence_log_op { - VPU_HWS_NATIVE_FENCE_LOG_OP_SIGNAL_EXECUTED = 0, - VPU_HWS_NATIVE_FENCE_LOG_OP_WAIT_UNBLOCKED = 1 -}; - -/* HWS native fence log entry. */ -struct vpu_hws_native_fence_log_entry { - /* Newly signaled/unblocked fence value. */ - u64 fence_value; - /* Native fence object handle to which this operation belongs. */ - u64 fence_handle; - /* Operation type, see enum vpu_hws_native_fence_log_op. */ - u64 op_type; - u64 reserved_0; - /* - * VPU_HWS_NATIVE_FENCE_LOG_OP_WAIT_UNBLOCKED only: Timestamp at which fence - * wait was started (in NPU SysTime). - */ - u64 fence_wait_start_ts; - u64 reserved_1; - /* Timestamp at which fence operation was completed (in NPU SysTime). */ - u64 fence_end_ts; -}; - -/* Native fence log buffer. */ -struct vpu_hws_native_fence_log_buffer { - struct vpu_hws_native_fence_log_header header; - struct vpu_hws_native_fence_log_entry entry[]; -}; - /* * Host <-> VPU IPC messages types. */ enum vpu_ipc_msg_type { VPU_JSM_MSG_UNKNOWN = 0xFFFFFFFF, - /* IPC Host -> Device, Async commands */ VPU_JSM_MSG_ASYNC_CMD = 0x1100, VPU_JSM_MSG_ENGINE_RESET = VPU_JSM_MSG_ASYNC_CMD, - /** - * Preempt engine. The NPU stops (preempts) all the jobs currently - * executing on the target engine making the engine become idle and ready to - * execute new jobs. - * NOTE: The NPU does not remove unstarted jobs (if any) from job queues of - * the target engine, but it stops processing them (until the queue doorbell - * is rung again); the host is responsible to reset the job queue, either - * after preemption or when resubmitting jobs to the queue. - */ VPU_JSM_MSG_ENGINE_PREEMPT = 0x1101, VPU_JSM_MSG_REGISTER_DB = 0x1102, VPU_JSM_MSG_UNREGISTER_DB = 0x1103, @@ -531,10 +323,9 @@ enum vpu_ipc_msg_type { * NOTE: Please introduce new ASYNC commands before this one. * */ VPU_JSM_MSG_STATE_DUMP = 0x11FF, - /* IPC Host -> Device, General commands */ VPU_JSM_MSG_GENERAL_CMD = 0x1200, - VPU_JSM_MSG_BLOB_DEINIT_DEPRECATED = VPU_JSM_MSG_GENERAL_CMD, + VPU_JSM_MSG_BLOB_DEINIT = VPU_JSM_MSG_GENERAL_CMD, /** * Control dyndbg behavior by executing a dyndbg command; equivalent to * Linux command: `echo '' > /dynamic_debug/control`. @@ -544,12 +335,8 @@ enum vpu_ipc_msg_type { * Perform the save procedure for the D0i3 entry */ VPU_JSM_MSG_PWR_D0I3_ENTER = 0x1202, - /* IPC Device -> Host, Job completion */ VPU_JSM_MSG_JOB_DONE = 0x2100, - /* IPC Device -> Host, Fence signalled */ - VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED = 0x2101, - /* IPC Device -> Host, Async command completion */ VPU_JSM_MSG_ASYNC_CMD_DONE = 0x2200, VPU_JSM_MSG_ENGINE_RESET_DONE = VPU_JSM_MSG_ASYNC_CMD_DONE, @@ -635,7 +422,6 @@ enum vpu_ipc_msg_type { * NOTE: Please introduce new ASYNC responses before this one. * */ VPU_JSM_MSG_STATE_DUMP_RSP = 0x22FF, - /* IPC Device -> Host, General command completion */ VPU_JSM_MSG_GENERAL_CMD_DONE = 0x2300, VPU_JSM_MSG_BLOB_DEINIT_DONE = VPU_JSM_MSG_GENERAL_CMD_DONE, @@ -814,6 +600,11 @@ struct vpu_jsm_metric_streamer_update { u64 next_buffer_size; }; +struct vpu_ipc_msg_payload_blob_deinit { + /* 64-bit unique ID for the blob to be de-initialized. */ + u64 blob_id; +}; + struct vpu_ipc_msg_payload_job_done { /* Engine to which the job was submitted. */ u32 engine_idx; @@ -831,21 +622,6 @@ struct vpu_ipc_msg_payload_job_done { u64 cmdq_id; }; -/* - * Notification message upon native fence signalling. - * @see VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED - */ -struct vpu_ipc_msg_payload_native_fence_signalled { - /* Engine ID. */ - u32 engine_idx; - /* Host SSID. */ - u32 host_ssid; - /* CMDQ ID */ - u64 cmdq_id; - /* Fence object handle. */ - u64 fence_handle; -}; - struct vpu_jsm_engine_reset_context { /* Host SSID */ u32 host_ssid; @@ -924,6 +700,11 @@ struct vpu_ipc_msg_payload_get_power_level_count_done { u8 power_limit[16]; }; +struct vpu_ipc_msg_payload_blob_deinit_done { + /* 64-bit unique ID for the blob de-initialized. */ + u64 blob_id; +}; + /* HWS priority band setup request / response */ struct vpu_ipc_msg_payload_hws_priority_band_setup { /* @@ -1013,10 +794,7 @@ struct vpu_ipc_msg_payload_hws_set_context_sched_properties { u32 reserved_0; /* Command queue id */ u64 cmdq_id; - /* - * Priority band to assign to work of this context. - * Available priority bands: @see enum vpu_job_scheduling_priority_band - */ + /* Priority band to assign to work of this context */ u32 priority_band; /* Inside realtime band assigns a further priority */ u32 realtime_priority_level; @@ -1091,7 +869,9 @@ struct vpu_ipc_msg_payload_hws_set_scheduling_log { */ u64 notify_index; /* - * Field is now deprecated, will be removed when KMD is updated to support removal + * Enable extra events to be output to log for debug of scheduling algorithm. + * Interpreted by VPU as a boolean to enable or disable, expected values are + * 0 and 1. */ u32 enable_extra_events; /* Zero Padding */ @@ -1463,10 +1243,10 @@ union vpu_ipc_msg_payload { struct vpu_jsm_metric_streamer_start metric_streamer_start; struct vpu_jsm_metric_streamer_stop metric_streamer_stop; struct vpu_jsm_metric_streamer_update metric_streamer_update; + struct vpu_ipc_msg_payload_blob_deinit blob_deinit; struct vpu_ipc_msg_payload_ssid_release ssid_release; struct vpu_jsm_hws_register_db hws_register_db; struct vpu_ipc_msg_payload_job_done job_done; - struct vpu_ipc_msg_payload_native_fence_signalled native_fence_signalled; struct vpu_ipc_msg_payload_engine_reset_done engine_reset_done; struct vpu_ipc_msg_payload_engine_preempt_done engine_preempt_done; struct vpu_ipc_msg_payload_register_db_done register_db_done; @@ -1474,6 +1254,7 @@ union vpu_ipc_msg_payload { struct vpu_ipc_msg_payload_query_engine_hb_done query_engine_hb_done; struct vpu_ipc_msg_payload_get_power_level_count_done get_power_level_count_done; struct vpu_jsm_metric_streamer_done metric_streamer_done; + struct vpu_ipc_msg_payload_blob_deinit_done blob_deinit_done; struct vpu_ipc_msg_payload_trace_config trace_config; struct vpu_ipc_msg_payload_trace_capability_rsp trace_capability; struct vpu_ipc_msg_payload_trace_get_name trace_get_name; From 8128f4c3b86b88066e5a8685fd4241dc48ff79e1 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 52/64] Revert "accel/ivpu: Fix a typo" This reverts commit 12df1b9c4da49e26b3d074ce8fb68f508ce8aa5b. --- drivers/accel/ivpu/vpu_boot_api.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/vpu_boot_api.h b/drivers/accel/ivpu/vpu_boot_api.h index d474bc7b15c0..82954b91b748 100644 --- a/drivers/accel/ivpu/vpu_boot_api.h +++ b/drivers/accel/ivpu/vpu_boot_api.h @@ -8,7 +8,7 @@ /* * =========== FW API version information beginning ================ - * The below values will be used to construct the version info this way: + * The bellow values will be used to construct the version info this way: * fw_bin_header->api_version[VPU_BOOT_API_VER_ID] = (VPU_BOOT_API_VER_MAJOR << 16) | * VPU_BOOT_API_VER_MINOR; * VPU_BOOT_API_VER_PATCH will be ignored. KMD and compatibility is not affected if this changes From 5ba5e7c13622146eddee46c224a649cdb977f277 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 53/64] Revert "Revert "accel/ivpu: Fix NOC firewall interrupt handling"" This reverts commit 863e04b44227a6d91a6a3f42d548381bd320b1c3. --- drivers/accel/ivpu/ivpu_debugfs.c | 9 +++++++++ drivers/accel/ivpu/ivpu_hw.c | 1 + drivers/accel/ivpu/ivpu_hw.h | 1 + drivers/accel/ivpu/ivpu_hw_ip.c | 5 ++++- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index 6f86f8df30db..8d50981594d1 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -108,6 +108,14 @@ static int reset_pending_show(struct seq_file *s, void *v) return 0; } +static int firewall_irq_counter_show(struct seq_file *s, void *v) +{ + struct ivpu_device *vdev = seq_to_ivpu(s); + + seq_printf(s, "%d\n", atomic_read(&vdev->hw->firewall_irq_counter)); + return 0; +} + static const struct drm_debugfs_info vdev_debugfs_list[] = { {"bo_list", bo_list_show, 0}, {"fw_name", fw_name_show, 0}, @@ -116,6 +124,7 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = { {"last_bootmode", last_bootmode_show, 0}, {"reset_counter", reset_counter_show, 0}, {"reset_pending", reset_pending_show, 0}, + {"firewall_irq_counter", firewall_irq_counter_show, 0}, }; static ssize_t diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index 27f0fe4d54e0..e69c0613513f 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -249,6 +249,7 @@ int ivpu_hw_init(struct ivpu_device *vdev) platform_init(vdev); wa_init(vdev); timeouts_init(vdev); + atomic_set(&vdev->hw->firewall_irq_counter, 0); return 0; } diff --git a/drivers/accel/ivpu/ivpu_hw.h b/drivers/accel/ivpu/ivpu_hw.h index 1c0c98e3afb8..a96a05b2acda 100644 --- a/drivers/accel/ivpu/ivpu_hw.h +++ b/drivers/accel/ivpu/ivpu_hw.h @@ -52,6 +52,7 @@ struct ivpu_hw_info { int dma_bits; ktime_t d0i3_entry_host_ts; u64 d0i3_entry_vpu_ts; + atomic_t firewall_irq_counter; }; int ivpu_hw_init(struct ivpu_device *vdev); diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c index dfd2f4a5b526..60b33fc59d96 100644 --- a/drivers/accel/ivpu/ivpu_hw_ip.c +++ b/drivers/accel/ivpu/ivpu_hw_ip.c @@ -1062,7 +1062,10 @@ static void irq_wdt_mss_handler(struct ivpu_device *vdev) static void irq_noc_firewall_handler(struct ivpu_device *vdev) { - ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ"); + atomic_inc(&vdev->hw->firewall_irq_counter); + + ivpu_dbg(vdev, IRQ, "NOC Firewall interrupt detected, counter %d\n", + atomic_read(&vdev->hw->firewall_irq_counter)); } /* Handler for IRQs from NPU core */ From d0192c9f9efe2c86aa37abdefbf0c6be1a3eafed Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 54/64] Revert "Revert "accel/ivpu: Prevent recovery invocation during probe and resume"" This reverts commit 803eeb353e5a15a8ca4d80d33a156158d71c4372. --- drivers/accel/ivpu/ivpu_ipc.c | 35 +++++++++++-------------------- drivers/accel/ivpu/ivpu_ipc.h | 7 +++---- drivers/accel/ivpu/ivpu_jsm_msg.c | 19 +++++++---------- 3 files changed, 23 insertions(+), 38 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index 78b32a823241..29b723039a34 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -291,15 +291,16 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, return ret; } -static int +int ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req, enum vpu_ipc_msg_type expected_resp_type, - struct vpu_jsm_msg *resp, u32 channel, - unsigned long timeout_ms) + struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms) { struct ivpu_ipc_consumer cons; int ret; + drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev)); + ivpu_ipc_consumer_add(vdev, &cons, channel, NULL); ret = ivpu_ipc_send(vdev, &cons, req); @@ -325,19 +326,21 @@ ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req return ret; } -int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *req, - enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, - u32 channel, unsigned long timeout_ms) +int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, + enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, + u32 channel, unsigned long timeout_ms) { struct vpu_jsm_msg hb_req = { .type = VPU_JSM_MSG_QUERY_ENGINE_HB }; struct vpu_jsm_msg hb_resp; int ret, hb_ret; - drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev)); + ret = ivpu_rpm_get(vdev); + if (ret < 0) + return ret; ret = ivpu_ipc_send_receive_internal(vdev, req, expected_resp, resp, channel, timeout_ms); if (ret != -ETIMEDOUT) - return ret; + goto rpm_put; hb_ret = ivpu_ipc_send_receive_internal(vdev, &hb_req, VPU_JSM_MSG_QUERY_ENGINE_HB_DONE, &hb_resp, VPU_IPC_CHAN_ASYNC_CMD, @@ -345,21 +348,7 @@ int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *r if (hb_ret == -ETIMEDOUT) ivpu_pm_trigger_recovery(vdev, "IPC timeout"); - return ret; -} - -int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, - enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, - u32 channel, unsigned long timeout_ms) -{ - int ret; - - ret = ivpu_rpm_get(vdev); - if (ret < 0) - return ret; - - ret = ivpu_ipc_send_receive_active(vdev, req, expected_resp, resp, channel, timeout_ms); - +rpm_put: ivpu_rpm_put(vdev); return ret; } diff --git a/drivers/accel/ivpu/ivpu_ipc.h b/drivers/accel/ivpu/ivpu_ipc.h index 4fe38141045e..fb4de7fb8210 100644 --- a/drivers/accel/ivpu/ivpu_ipc.h +++ b/drivers/accel/ivpu/ivpu_ipc.h @@ -101,10 +101,9 @@ int ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct ivpu_ipc_hdr *ipc_buf, struct vpu_jsm_msg *jsm_msg, unsigned long timeout_ms); - -int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *req, - enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, - u32 channel, unsigned long timeout_ms); +int ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req, + enum vpu_ipc_msg_type expected_resp_type, + struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms); int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms); diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index 46ef16c3c069..88105963c1b2 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -270,9 +270,8 @@ int ivpu_jsm_pwr_d0i3_enter(struct ivpu_device *vdev) req.payload.pwr_d0i3_enter.send_response = 1; - ret = ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_PWR_D0I3_ENTER_DONE, - &resp, VPU_IPC_CHAN_GEN_CMD, - vdev->timeout.d0i3_entry_msg); + ret = ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_PWR_D0I3_ENTER_DONE, &resp, + VPU_IPC_CHAN_GEN_CMD, vdev->timeout.d0i3_entry_msg); if (ret) return ret; @@ -430,8 +429,8 @@ int ivpu_jsm_hws_setup_priority_bands(struct ivpu_device *vdev) req.payload.hws_priority_band_setup.normal_band_percentage = 10; - ret = ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP_RSP, - &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); + ret = ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP_RSP, + &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); if (ret) ivpu_warn_ratelimited(vdev, "Failed to set priority bands: %d\n", ret); @@ -544,9 +543,8 @@ int ivpu_jsm_dct_enable(struct ivpu_device *vdev, u32 active_us, u32 inactive_us req.payload.pwr_dct_control.dct_active_us = active_us; req.payload.pwr_dct_control.dct_inactive_us = inactive_us; - return ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_DCT_ENABLE_DONE, - &resp, VPU_IPC_CHAN_ASYNC_CMD, - vdev->timeout.jsm); + return ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_DCT_ENABLE_DONE, &resp, + VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); } int ivpu_jsm_dct_disable(struct ivpu_device *vdev) @@ -554,7 +552,6 @@ int ivpu_jsm_dct_disable(struct ivpu_device *vdev) struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_DCT_DISABLE }; struct vpu_jsm_msg resp; - return ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_DCT_DISABLE_DONE, - &resp, VPU_IPC_CHAN_ASYNC_CMD, - vdev->timeout.jsm); + return ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_DCT_DISABLE_DONE, &resp, + VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); } From d4d80bbea2adbfb40ec8db55e98526c5745b3e14 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 55/64] Revert "Revert "accel/ivpu: Fix general protection fault in ivpu_bo_list()"" This reverts commit ab47cd926733d18d583fc32e6cf32a1ad6339017. --- drivers/accel/ivpu/ivpu_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c index 1b409dbd332d..c8daffd90f30 100644 --- a/drivers/accel/ivpu/ivpu_gem.c +++ b/drivers/accel/ivpu/ivpu_gem.c @@ -406,7 +406,7 @@ static void ivpu_bo_print_info(struct ivpu_bo *bo, struct drm_printer *p) mutex_lock(&bo->lock); drm_printf(p, "%-9p %-3u 0x%-12llx %-10lu 0x%-8x %-4u", - bo, bo->ctx->id, bo->vpu_addr, bo->base.base.size, + bo, bo->ctx ? bo->ctx->id : 0, bo->vpu_addr, bo->base.base.size, bo->flags, kref_read(&bo->base.base.refcount)); if (bo->base.pages) From 9aafcf2d75b9a4af43cb2b94633c379e955d8300 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 56/64] Revert "Revert "accel/ivpu: Fix WARN in ivpu_ipc_send_receive_internal()"" This reverts commit 300e30065e72c8b340f00f79d4c99edee87b0ea9. --- drivers/accel/ivpu/ivpu_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 59d3170f5e35..10b7ae0f866c 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -364,6 +364,7 @@ void ivpu_pm_init(struct ivpu_device *vdev) pm_runtime_use_autosuspend(dev); pm_runtime_set_autosuspend_delay(dev, delay); + pm_runtime_set_active(dev); ivpu_dbg(vdev, PM, "Autosuspend delay = %d\n", delay); } @@ -378,7 +379,6 @@ void ivpu_pm_enable(struct ivpu_device *vdev) { struct device *dev = vdev->drm.dev; - pm_runtime_set_active(dev); pm_runtime_allow(dev); pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); From d9f3615c39f95180dc92363b9da779298982702e Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 57/64] Revert "Revert "accel/ivpu: Add initial Panther Lake support"" This reverts commit d734b7f5b2b6a892479f3936978d7683f78eb23c. --- drivers/accel/ivpu/ivpu_drv.c | 1 + drivers/accel/ivpu/ivpu_drv.h | 10 +++++++--- drivers/accel/ivpu/ivpu_fw.c | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index c91400ecf926..1b3127ce0ee2 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -722,6 +722,7 @@ static struct pci_device_id ivpu_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_MTL) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_ARL) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_LNL) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PTL_P) }, { } }; MODULE_DEVICE_TABLE(pci, ivpu_pci_ids); diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 63f13b697eed..d0f750c5c453 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -23,9 +23,10 @@ #define DRIVER_DESC "Driver for Intel NPU (Neural Processing Unit)" #define DRIVER_DATE "20230117" -#define PCI_DEVICE_ID_MTL 0x7d1d -#define PCI_DEVICE_ID_ARL 0xad1d -#define PCI_DEVICE_ID_LNL 0x643e +#define PCI_DEVICE_ID_MTL 0x7d1d +#define PCI_DEVICE_ID_ARL 0xad1d +#define PCI_DEVICE_ID_LNL 0x643e +#define PCI_DEVICE_ID_PTL_P 0xb03e #define IVPU_HW_IP_37XX 37 #define IVPU_HW_IP_40XX 40 @@ -215,6 +216,8 @@ static inline int ivpu_hw_ip_gen(struct ivpu_device *vdev) return IVPU_HW_IP_37XX; case PCI_DEVICE_ID_LNL: return IVPU_HW_IP_40XX; + case PCI_DEVICE_ID_PTL_P: + return IVPU_HW_IP_50XX; default: dump_stack(); ivpu_err(vdev, "Unknown NPU IP generation\n"); @@ -229,6 +232,7 @@ static inline int ivpu_hw_btrs_gen(struct ivpu_device *vdev) case PCI_DEVICE_ID_ARL: return IVPU_HW_BTRS_MTL; case PCI_DEVICE_ID_LNL: + case PCI_DEVICE_ID_PTL_P: return IVPU_HW_BTRS_LNL; default: dump_stack(); diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index ede6165e09d9..33ce4680c2cd 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -58,11 +58,14 @@ static struct { { IVPU_HW_IP_37XX, "intel/vpu/vpu_37xx_v0.0.bin" }, { IVPU_HW_IP_40XX, "vpu_40xx.bin" }, { IVPU_HW_IP_40XX, "intel/vpu/vpu_40xx_v0.0.bin" }, + { IVPU_HW_IP_50XX, "vpu_50xx.bin" }, + { IVPU_HW_IP_50XX, "intel/vpu/vpu_50xx_v0.0.bin" }, }; /* Production fw_names from the table above */ MODULE_FIRMWARE("intel/vpu/vpu_37xx_v0.0.bin"); MODULE_FIRMWARE("intel/vpu/vpu_40xx_v0.0.bin"); +MODULE_FIRMWARE("intel/vpu/vpu_50xx_v0.0.bin"); static int ivpu_fw_request(struct ivpu_device *vdev) { From 194d3b3eea1f81492be23302391cb75736de2347 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 58/64] Revert "Revert "ivpu: fix build error due to undefined "date" use from struct drm_driver"" This reverts commit 33456d44e87f28f8cee4a188facaaedbf07e2360. --- drivers/accel/ivpu/ivpu_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 1b3127ce0ee2..ec761b9923cb 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -446,7 +446,6 @@ static const struct drm_driver driver = { .name = DRIVER_NAME, .desc = DRIVER_DESC, - .date = DRIVER_DATE, .major = DRM_IVPU_DRIVER_MAJOR, .minor = DRM_IVPU_DRIVER_MINOR, }; From 5b18279e5410abc193d4f5459aa3e662c5082e21 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 59/64] Revert "Revert "accel/ivpu: Update power island delays"" This reverts commit bcdaba5ab974ebebdcb8648ec1e460dc4717e00b. --- drivers/accel/ivpu/ivpu_hw_40xx_reg.h | 2 ++ drivers/accel/ivpu/ivpu_hw_ip.c | 49 +++++++++++++++++---------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_40xx_reg.h b/drivers/accel/ivpu/ivpu_hw_40xx_reg.h index d0b795b344c7..fc0ee8d637f9 100644 --- a/drivers/accel/ivpu/ivpu_hw_40xx_reg.h +++ b/drivers/accel/ivpu/ivpu_hw_40xx_reg.h @@ -115,6 +115,8 @@ #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY 0x00030068u #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY_POST_DLY_MASK GENMASK(7, 0) +#define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY_POST1_DLY_MASK GENMASK(15, 8) +#define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY_POST2_DLY_MASK GENMASK(23, 16) #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY 0x0003006cu #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY_STATUS_DLY_MASK GENMASK(7, 0) diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c index 60b33fc59d96..bd2582a8c80f 100644 --- a/drivers/accel/ivpu/ivpu_hw_ip.c +++ b/drivers/accel/ivpu/ivpu_hw_ip.c @@ -8,15 +8,12 @@ #include "ivpu_hw.h" #include "ivpu_hw_37xx_reg.h" #include "ivpu_hw_40xx_reg.h" +#include "ivpu_hw_btrs.h" #include "ivpu_hw_ip.h" #include "ivpu_hw_reg_io.h" #include "ivpu_mmu.h" #include "ivpu_pm.h" -#define PWR_ISLAND_EN_POST_DLY_FREQ_DEFAULT 0 -#define PWR_ISLAND_EN_POST_DLY_FREQ_HIGH 18 -#define PWR_ISLAND_STATUS_DLY_FREQ_DEFAULT 3 -#define PWR_ISLAND_STATUS_DLY_FREQ_HIGH 46 #define PWR_ISLAND_STATUS_TIMEOUT_US (5 * USEC_PER_MSEC) #define TIM_SAFE_ENABLE 0xf1d0dead @@ -268,20 +265,15 @@ void ivpu_hw_ip_idle_gen_disable(struct ivpu_device *vdev) idle_gen_drive_40xx(vdev, false); } -static void pwr_island_delay_set_50xx(struct ivpu_device *vdev) +static void +pwr_island_delay_set_50xx(struct ivpu_device *vdev, u32 post, u32 post1, u32 post2, u32 status) { - u32 val, post, status; - - if (vdev->hw->pll.profiling_freq == PLL_PROFILING_FREQ_DEFAULT) { - post = PWR_ISLAND_EN_POST_DLY_FREQ_DEFAULT; - status = PWR_ISLAND_STATUS_DLY_FREQ_DEFAULT; - } else { - post = PWR_ISLAND_EN_POST_DLY_FREQ_HIGH; - status = PWR_ISLAND_STATUS_DLY_FREQ_HIGH; - } + u32 val; val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY); val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST_DLY, post, val); + val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST1_DLY, post1, val); + val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST2_DLY, post2, val); REGV_WR32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, val); val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY); @@ -686,13 +678,36 @@ static void dpu_active_drive_37xx(struct ivpu_device *vdev, bool enable) REGV_WR32(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, val); } +static void pwr_island_delay_set(struct ivpu_device *vdev) +{ + bool high = vdev->hw->pll.profiling_freq == PLL_PROFILING_FREQ_HIGH; + u32 post, post1, post2, status; + + if (ivpu_hw_ip_gen(vdev) < IVPU_HW_IP_50XX) + return; + + switch (ivpu_device_id(vdev)) { + case PCI_DEVICE_ID_PTL_P: + post = high ? 18 : 0; + post1 = 0; + post2 = 0; + status = high ? 46 : 3; + break; + + default: + dump_stack(); + ivpu_err(vdev, "Unknown device ID\n"); + return; + } + + pwr_island_delay_set_50xx(vdev, post, post1, post2, status); +} + int ivpu_hw_ip_pwr_domain_enable(struct ivpu_device *vdev) { int ret; - if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_50XX) - pwr_island_delay_set_50xx(vdev); - + pwr_island_delay_set(vdev); pwr_island_enable(vdev); ret = wait_for_pwr_island_status(vdev, 0x1); From c34c2dac6132e29b61154f0a1ae46994108adfc1 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 60/64] Revert "Revert "accel/ivpu: Do not fail when more than 1 tile is fused"" This reverts commit 8c76a1d799e9758ed43a51da51dfada032503824. --- drivers/accel/ivpu/ivpu_hw_btrs.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index 745e5248803d..f3a0312f4e7f 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -141,16 +141,10 @@ static int read_tile_config_fuse(struct ivpu_device *vdev, u32 *tile_fuse_config } config = REG_GET_FLD(VPU_HW_BTRS_LNL_TILE_FUSE, CONFIG, fuse); - if (!tile_disable_check(config)) { - ivpu_err(vdev, "Fuse: Invalid tile disable config (0x%x)\n", config); - return -EIO; - } + if (!tile_disable_check(config)) + ivpu_warn(vdev, "More than 1 tile disabled, tile fuse config mask: 0x%x\n", config); - if (config) - ivpu_dbg(vdev, MISC, "Fuse: %d tiles enabled. Tile number %d disabled\n", - BTRS_LNL_TILE_MAX_NUM - 1, ffs(config) - 1); - else - ivpu_dbg(vdev, MISC, "Fuse: All %d tiles enabled\n", BTRS_LNL_TILE_MAX_NUM); + ivpu_dbg(vdev, MISC, "Tile disable config mask: 0x%x\n", config); *tile_fuse_config = config; return 0; From db0d1d4f280c56b034957819b287fd96974c2a31 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 61/64] Revert "Revert "accel/ivpu: Defer MMU root page table allocation"" This reverts commit 1a67c6739b2ce0dc517617c5b75fad2d4179c7ce. --- drivers/accel/ivpu/ivpu_drv.c | 12 +-- drivers/accel/ivpu/ivpu_mmu.c | 94 ++++++----------- drivers/accel/ivpu/ivpu_mmu.h | 4 +- drivers/accel/ivpu/ivpu_mmu_context.c | 145 +++++++++++++------------- drivers/accel/ivpu/ivpu_mmu_context.h | 9 +- 5 files changed, 115 insertions(+), 149 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index ec761b9923cb..cc90466bdb24 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -85,7 +85,7 @@ static void file_priv_unbind(struct ivpu_device *vdev, struct ivpu_file_priv *fi ivpu_cmdq_release_all_locked(file_priv); ivpu_bo_unbind_all_bos_from_context(vdev, &file_priv->ctx); - ivpu_mmu_user_context_fini(vdev, &file_priv->ctx); + ivpu_mmu_context_fini(vdev, &file_priv->ctx); file_priv->bound = false; drm_WARN_ON(&vdev->drm, !xa_erase_irq(&vdev->context_xa, file_priv->ctx.id)); } @@ -255,9 +255,7 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) goto err_unlock; } - ret = ivpu_mmu_user_context_init(vdev, &file_priv->ctx, ctx_id); - if (ret) - goto err_xa_erase; + ivpu_mmu_context_init(vdev, &file_priv->ctx, ctx_id); mutex_unlock(&vdev->context_list_lock); drm_dev_exit(idx); @@ -269,8 +267,6 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) return 0; -err_xa_erase: - xa_erase_irq(&vdev->context_xa, ctx_id); err_unlock: mutex_unlock(&vdev->context_list_lock); mutex_destroy(&file_priv->ms_lock); @@ -631,9 +627,7 @@ static int ivpu_dev_init(struct ivpu_device *vdev) if (ret) goto err_shutdown; - ret = ivpu_mmu_global_context_init(vdev); - if (ret) - goto err_shutdown; + ivpu_mmu_global_context_init(vdev); ret = ivpu_mmu_init(vdev); if (ret) diff --git a/drivers/accel/ivpu/ivpu_mmu.c b/drivers/accel/ivpu/ivpu_mmu.c index c078e214b221..4ff0d7a51985 100644 --- a/drivers/accel/ivpu/ivpu_mmu.c +++ b/drivers/accel/ivpu/ivpu_mmu.c @@ -696,7 +696,7 @@ int ivpu_mmu_invalidate_tlb(struct ivpu_device *vdev, u16 ssid) return ret; } -static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma) +static int ivpu_mmu_cdtab_entry_set(struct ivpu_device *vdev, u32 ssid, u64 cd_dma, bool valid) { struct ivpu_mmu_info *mmu = vdev->mmu; struct ivpu_mmu_cdtab *cdtab = &mmu->cdtab; @@ -708,30 +708,29 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma) return -EINVAL; entry = cdtab->base + (ssid * IVPU_MMU_CDTAB_ENT_SIZE); - - if (cd_dma != 0) { - cd[0] = FIELD_PREP(IVPU_MMU_CD_0_TCR_T0SZ, IVPU_MMU_T0SZ_48BIT) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_TG0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_IRGN0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_ORGN0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_SH0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_IPS, IVPU_MMU_IPS_48BIT) | - FIELD_PREP(IVPU_MMU_CD_0_ASID, ssid) | - IVPU_MMU_CD_0_TCR_EPD1 | - IVPU_MMU_CD_0_AA64 | - IVPU_MMU_CD_0_R | - IVPU_MMU_CD_0_ASET | - IVPU_MMU_CD_0_V; - cd[1] = cd_dma & IVPU_MMU_CD_1_TTB0_MASK; - cd[2] = 0; - cd[3] = 0x0000000000007444; - - /* For global context generate memory fault on VPU */ - if (ssid == IVPU_GLOBAL_CONTEXT_MMU_SSID) - cd[0] |= IVPU_MMU_CD_0_A; - } else { - memset(cd, 0, sizeof(cd)); - } + drm_WARN_ON(&vdev->drm, (entry[0] & IVPU_MMU_CD_0_V) == valid); + + cd[0] = FIELD_PREP(IVPU_MMU_CD_0_TCR_T0SZ, IVPU_MMU_T0SZ_48BIT) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_TG0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_IRGN0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_ORGN0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_SH0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_IPS, IVPU_MMU_IPS_48BIT) | + FIELD_PREP(IVPU_MMU_CD_0_ASID, ssid) | + IVPU_MMU_CD_0_TCR_EPD1 | + IVPU_MMU_CD_0_AA64 | + IVPU_MMU_CD_0_R | + IVPU_MMU_CD_0_ASET; + cd[1] = cd_dma & IVPU_MMU_CD_1_TTB0_MASK; + cd[2] = 0; + cd[3] = 0x0000000000007444; + + /* For global context generate memory fault on VPU */ + if (ssid == IVPU_GLOBAL_CONTEXT_MMU_SSID) + cd[0] |= IVPU_MMU_CD_0_A; + + if (valid) + cd[0] |= IVPU_MMU_CD_0_V; WRITE_ONCE(entry[1], cd[1]); WRITE_ONCE(entry[2], cd[2]); @@ -741,8 +740,8 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma) if (!ivpu_is_force_snoop_enabled(vdev)) clflush_cache_range(entry, IVPU_MMU_CDTAB_ENT_SIZE); - ivpu_dbg(vdev, MMU, "CDTAB %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n", - cd_dma ? "write" : "clear", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]); + ivpu_dbg(vdev, MMU, "CDTAB set %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n", + valid ? "valid" : "invalid", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]); mutex_lock(&mmu->lock); if (!mmu->on) @@ -758,33 +757,6 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma) return ret; } -static int ivpu_mmu_cd_add_gbl(struct ivpu_device *vdev) -{ - int ret; - - ret = ivpu_mmu_cd_add(vdev, 0, vdev->gctx.pgtable.pgd_dma); - if (ret) - ivpu_err(vdev, "Failed to add global CD entry: %d\n", ret); - - return ret; -} - -static int ivpu_mmu_cd_add_user(struct ivpu_device *vdev, u32 ssid, dma_addr_t cd_dma) -{ - int ret; - - if (ssid == 0) { - ivpu_err(vdev, "Invalid SSID: %u\n", ssid); - return -EINVAL; - } - - ret = ivpu_mmu_cd_add(vdev, ssid, cd_dma); - if (ret) - ivpu_err(vdev, "Failed to add CD entry SSID=%u: %d\n", ssid, ret); - - return ret; -} - int ivpu_mmu_init(struct ivpu_device *vdev) { struct ivpu_mmu_info *mmu = vdev->mmu; @@ -808,12 +780,6 @@ int ivpu_mmu_init(struct ivpu_device *vdev) return ret; } - ret = ivpu_mmu_cd_add_gbl(vdev); - if (ret) { - ivpu_err(vdev, "Failed to initialize strtab: %d\n", ret); - return ret; - } - ret = ivpu_mmu_enable(vdev); if (ret) { ivpu_err(vdev, "Failed to resume MMU: %d\n", ret); @@ -966,12 +932,12 @@ void ivpu_mmu_irq_gerr_handler(struct ivpu_device *vdev) REGV_WR32(IVPU_MMU_REG_GERRORN, gerror_val); } -int ivpu_mmu_set_pgtable(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable) +int ivpu_mmu_cd_set(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable) { - return ivpu_mmu_cd_add_user(vdev, ssid, pgtable->pgd_dma); + return ivpu_mmu_cdtab_entry_set(vdev, ssid, pgtable->pgd_dma, true); } -void ivpu_mmu_clear_pgtable(struct ivpu_device *vdev, int ssid) +void ivpu_mmu_cd_clear(struct ivpu_device *vdev, int ssid) { - ivpu_mmu_cd_add_user(vdev, ssid, 0); /* 0 will clear CD entry */ + ivpu_mmu_cdtab_entry_set(vdev, ssid, 0, false); } diff --git a/drivers/accel/ivpu/ivpu_mmu.h b/drivers/accel/ivpu/ivpu_mmu.h index 6fa35c240710..7afea9cd8731 100644 --- a/drivers/accel/ivpu/ivpu_mmu.h +++ b/drivers/accel/ivpu/ivpu_mmu.h @@ -40,8 +40,8 @@ struct ivpu_mmu_info { int ivpu_mmu_init(struct ivpu_device *vdev); void ivpu_mmu_disable(struct ivpu_device *vdev); int ivpu_mmu_enable(struct ivpu_device *vdev); -int ivpu_mmu_set_pgtable(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable); -void ivpu_mmu_clear_pgtable(struct ivpu_device *vdev, int ssid); +int ivpu_mmu_cd_set(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable); +void ivpu_mmu_cd_clear(struct ivpu_device *vdev, int ssid); int ivpu_mmu_invalidate_tlb(struct ivpu_device *vdev, u16 ssid); void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev); diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c index bbe652a7019d..8992fe93b679 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.c +++ b/drivers/accel/ivpu/ivpu_mmu_context.c @@ -90,19 +90,6 @@ static void ivpu_pgtable_free_page(struct ivpu_device *vdev, u64 *cpu_addr, dma_ } } -static int ivpu_mmu_pgtable_init(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable) -{ - dma_addr_t pgd_dma; - - pgtable->pgd_dma_ptr = ivpu_pgtable_alloc_page(vdev, &pgd_dma); - if (!pgtable->pgd_dma_ptr) - return -ENOMEM; - - pgtable->pgd_dma = pgd_dma; - - return 0; -} - static void ivpu_mmu_pgtables_free(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable) { int pgd_idx, pud_idx, pmd_idx; @@ -140,6 +127,27 @@ static void ivpu_mmu_pgtables_free(struct ivpu_device *vdev, struct ivpu_mmu_pgt } ivpu_pgtable_free_page(vdev, pgtable->pgd_dma_ptr, pgtable->pgd_dma); + pgtable->pgd_dma_ptr = NULL; + pgtable->pgd_dma = 0; +} + +static u64* +ivpu_mmu_ensure_pgd(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable) +{ + u64 *pgd_dma_ptr = pgtable->pgd_dma_ptr; + dma_addr_t pgd_dma; + + if (pgd_dma_ptr) + return pgd_dma_ptr; + + pgd_dma_ptr = ivpu_pgtable_alloc_page(vdev, &pgd_dma); + if (!pgd_dma_ptr) + return NULL; + + pgtable->pgd_dma_ptr = pgd_dma_ptr; + pgtable->pgd_dma = pgd_dma; + + return pgd_dma_ptr; } static u64* @@ -237,6 +245,12 @@ ivpu_mmu_context_map_page(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx int pmd_idx = FIELD_GET(IVPU_MMU_PMD_INDEX_MASK, vpu_addr); int pte_idx = FIELD_GET(IVPU_MMU_PTE_INDEX_MASK, vpu_addr); + drm_WARN_ON(&vdev->drm, ctx->id == IVPU_RESERVED_CONTEXT_MMU_SSID); + + /* Allocate PGD - first level page table if needed */ + if (!ivpu_mmu_ensure_pgd(vdev, &ctx->pgtable)) + return -ENOMEM; + /* Allocate PUD - second level page table if needed */ if (!ivpu_mmu_ensure_pud(vdev, &ctx->pgtable, pgd_idx)) return -ENOMEM; @@ -448,12 +462,21 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, ret = ivpu_mmu_context_map_pages(vdev, ctx, vpu_addr, dma_addr, size, prot); if (ret) { ivpu_err(vdev, "Failed to map context pages\n"); - mutex_unlock(&ctx->lock); - return ret; + goto err_unlock; } vpu_addr += size; } + if (!ctx->is_cd_valid) { + ret = ivpu_mmu_cd_set(vdev, ctx->id, &ctx->pgtable); + if (ret) { + ivpu_err(vdev, "Failed to set context descriptor for context %u: %d\n", + ctx->id, ret); + goto err_unlock; + } + ctx->is_cd_valid = true; + } + /* Ensure page table modifications are flushed from wc buffers to memory */ wmb(); @@ -463,6 +486,11 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, if (ret) ivpu_err(vdev, "Failed to invalidate TLB for ctx %u: %d\n", ctx->id, ret); return ret; + +err_unlock: + mutex_unlock(&ctx->lock); + return ret; + } void @@ -530,20 +558,12 @@ ivpu_mmu_context_remove_node(struct ivpu_mmu_context *ctx, struct drm_mm_node *n mutex_unlock(&ctx->lock); } -static int -ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 context_id) +void ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 context_id) { u64 start, end; - int ret; mutex_init(&ctx->lock); - ret = ivpu_mmu_pgtable_init(vdev, &ctx->pgtable); - if (ret) { - ivpu_err(vdev, "Failed to initialize pgtable for ctx %u: %d\n", context_id, ret); - return ret; - } - if (!context_id) { start = vdev->hw->ranges.global.start; end = vdev->hw->ranges.shave.end; @@ -554,41 +574,59 @@ ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u3 drm_mm_init(&ctx->mm, start, end - start); ctx->id = context_id; - - return 0; } -static void ivpu_mmu_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx) +void ivpu_mmu_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx) { - if (drm_WARN_ON(&vdev->drm, !ctx->pgtable.pgd_dma_ptr)) - return; + if (ctx->is_cd_valid) { + ivpu_mmu_cd_clear(vdev, ctx->id); + ctx->is_cd_valid = false; + } mutex_destroy(&ctx->lock); ivpu_mmu_pgtables_free(vdev, &ctx->pgtable); drm_mm_takedown(&ctx->mm); - - ctx->pgtable.pgd_dma_ptr = NULL; - ctx->pgtable.pgd_dma = 0; } -int ivpu_mmu_global_context_init(struct ivpu_device *vdev) +void ivpu_mmu_global_context_init(struct ivpu_device *vdev) { - return ivpu_mmu_context_init(vdev, &vdev->gctx, IVPU_GLOBAL_CONTEXT_MMU_SSID); + ivpu_mmu_context_init(vdev, &vdev->gctx, IVPU_GLOBAL_CONTEXT_MMU_SSID); } void ivpu_mmu_global_context_fini(struct ivpu_device *vdev) { - return ivpu_mmu_context_fini(vdev, &vdev->gctx); + ivpu_mmu_context_fini(vdev, &vdev->gctx); } int ivpu_mmu_reserved_context_init(struct ivpu_device *vdev) { - return ivpu_mmu_user_context_init(vdev, &vdev->rctx, IVPU_RESERVED_CONTEXT_MMU_SSID); + int ret; + + ivpu_mmu_context_init(vdev, &vdev->rctx, IVPU_RESERVED_CONTEXT_MMU_SSID); + + mutex_lock(&vdev->rctx.lock); + + if (!ivpu_mmu_ensure_pgd(vdev, &vdev->rctx.pgtable)) { + ivpu_err(vdev, "Failed to allocate root page table for reserved context\n"); + ret = -ENOMEM; + goto unlock; + } + + ret = ivpu_mmu_cd_set(vdev, vdev->rctx.id, &vdev->rctx.pgtable); + if (ret) { + ivpu_err(vdev, "Failed to set context descriptor for reserved context\n"); + goto unlock; + } + +unlock: + mutex_unlock(&vdev->rctx.lock); + return ret; } void ivpu_mmu_reserved_context_fini(struct ivpu_device *vdev) { - return ivpu_mmu_user_context_fini(vdev, &vdev->rctx); + ivpu_mmu_cd_clear(vdev, vdev->rctx.id); + ivpu_mmu_context_fini(vdev, &vdev->rctx); } void ivpu_mmu_user_context_mark_invalid(struct ivpu_device *vdev, u32 ssid) @@ -603,36 +641,3 @@ void ivpu_mmu_user_context_mark_invalid(struct ivpu_device *vdev, u32 ssid) xa_unlock(&vdev->context_xa); } - -int ivpu_mmu_user_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 ctx_id) -{ - int ret; - - drm_WARN_ON(&vdev->drm, !ctx_id); - - ret = ivpu_mmu_context_init(vdev, ctx, ctx_id); - if (ret) { - ivpu_err(vdev, "Failed to initialize context %u: %d\n", ctx_id, ret); - return ret; - } - - ret = ivpu_mmu_set_pgtable(vdev, ctx_id, &ctx->pgtable); - if (ret) { - ivpu_err(vdev, "Failed to set page table for context %u: %d\n", ctx_id, ret); - goto err_context_fini; - } - - return 0; - -err_context_fini: - ivpu_mmu_context_fini(vdev, ctx); - return ret; -} - -void ivpu_mmu_user_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx) -{ - drm_WARN_ON(&vdev->drm, !ctx->id); - - ivpu_mmu_clear_pgtable(vdev, ctx->id); - ivpu_mmu_context_fini(vdev, ctx); -} diff --git a/drivers/accel/ivpu/ivpu_mmu_context.h b/drivers/accel/ivpu/ivpu_mmu_context.h index 7f9aaf3d10c2..8042fc067062 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.h +++ b/drivers/accel/ivpu/ivpu_mmu_context.h @@ -23,19 +23,20 @@ struct ivpu_mmu_pgtable { }; struct ivpu_mmu_context { - struct mutex lock; /* Protects: mm, pgtable */ + struct mutex lock; /* Protects: mm, pgtable, is_cd_valid */ struct drm_mm mm; struct ivpu_mmu_pgtable pgtable; + bool is_cd_valid; u32 id; }; -int ivpu_mmu_global_context_init(struct ivpu_device *vdev); +void ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 context_id); +void ivpu_mmu_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx); +void ivpu_mmu_global_context_init(struct ivpu_device *vdev); void ivpu_mmu_global_context_fini(struct ivpu_device *vdev); int ivpu_mmu_reserved_context_init(struct ivpu_device *vdev); void ivpu_mmu_reserved_context_fini(struct ivpu_device *vdev); -int ivpu_mmu_user_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 ctx_id); -void ivpu_mmu_user_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx); void ivpu_mmu_user_context_mark_invalid(struct ivpu_device *vdev, u32 ssid); int ivpu_mmu_context_insert_node(struct ivpu_mmu_context *ctx, const struct ivpu_addr_range *range, From 5b26c277b98f358dec41e1d15e814933e9d4aeef Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 62/64] Revert "Revert "accel/ivpu: Clear CDTAB entry in case of failure"" This reverts commit be3e8cb966e54dfb4191cc49746dd0698c4b06c9. --- drivers/accel/ivpu/ivpu_mmu.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_mmu.c b/drivers/accel/ivpu/ivpu_mmu.c index 4ff0d7a51985..26ef52fbb93e 100644 --- a/drivers/accel/ivpu/ivpu_mmu.c +++ b/drivers/accel/ivpu/ivpu_mmu.c @@ -749,10 +749,17 @@ static int ivpu_mmu_cdtab_entry_set(struct ivpu_device *vdev, u32 ssid, u64 cd_d ret = ivpu_mmu_cmdq_write_cfgi_all(vdev); if (ret) - goto unlock; + goto err_invalidate; ret = ivpu_mmu_cmdq_sync(vdev); + if (ret) + goto err_invalidate; unlock: + mutex_unlock(&mmu->lock); + return 0; + +err_invalidate: + WRITE_ONCE(entry[0], 0); mutex_unlock(&mmu->lock); return ret; } From 39b203c888cfd0a1a8a0f76f1e549fbb54ce213a Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 63/64] Revert "Revert "accel/ivpu: Unmap partially mapped BOs in case of errors"" This reverts commit 1090f0f8019393da0aff7a2b24390c4f5845f1c4. --- drivers/accel/ivpu/ivpu_mmu_context.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c index 8992fe93b679..697b57071d54 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.c +++ b/drivers/accel/ivpu/ivpu_mmu_context.c @@ -432,6 +432,7 @@ int ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u64 vpu_addr, struct sg_table *sgt, bool llc_coherent) { + size_t start_vpu_addr = vpu_addr; struct scatterlist *sg; int ret; u64 prot; @@ -462,7 +463,7 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, ret = ivpu_mmu_context_map_pages(vdev, ctx, vpu_addr, dma_addr, size, prot); if (ret) { ivpu_err(vdev, "Failed to map context pages\n"); - goto err_unlock; + goto err_unmap_pages; } vpu_addr += size; } @@ -472,7 +473,7 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, if (ret) { ivpu_err(vdev, "Failed to set context descriptor for context %u: %d\n", ctx->id, ret); - goto err_unlock; + goto err_unmap_pages; } ctx->is_cd_valid = true; } @@ -480,17 +481,19 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, /* Ensure page table modifications are flushed from wc buffers to memory */ wmb(); - mutex_unlock(&ctx->lock); - ret = ivpu_mmu_invalidate_tlb(vdev, ctx->id); - if (ret) + if (ret) { ivpu_err(vdev, "Failed to invalidate TLB for ctx %u: %d\n", ctx->id, ret); - return ret; + goto err_unmap_pages; + } -err_unlock: mutex_unlock(&ctx->lock); - return ret; + return 0; +err_unmap_pages: + ivpu_mmu_context_unmap_pages(ctx, start_vpu_addr, vpu_addr - start_vpu_addr); + mutex_unlock(&ctx->lock); + return ret; } void From 8a77bdcd472220ff98f46ac7b0cd96b04063e580 Mon Sep 17 00:00:00 2001 From: "SUN, Jing" Date: Thu, 18 Sep 2025 15:05:23 +0800 Subject: [PATCH 64/64] Revert "Revert "accel/ivpu: Increase DMA address range"" This reverts commit df8ec74f08b67ba460d2487e096440dce6688b8f. --- drivers/accel/ivpu/ivpu_fw.c | 6 ++++-- drivers/accel/ivpu/ivpu_hw.c | 10 +++++----- drivers/accel/ivpu/ivpu_mmu_context.c | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index 33ce4680c2cd..ab7c7f157c60 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -570,8 +570,10 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params boot_params->ipc_payload_area_start = ipc_mem_rx->vpu_addr + ivpu_bo_size(ipc_mem_rx) / 2; boot_params->ipc_payload_area_size = ivpu_bo_size(ipc_mem_rx) / 2; - boot_params->global_aliased_pio_base = vdev->hw->ranges.user.start; - boot_params->global_aliased_pio_size = ivpu_hw_range_size(&vdev->hw->ranges.user); + if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) { + boot_params->global_aliased_pio_base = vdev->hw->ranges.user.start; + boot_params->global_aliased_pio_size = ivpu_hw_range_size(&vdev->hw->ranges.user); + } /* Allow configuration for L2C_PAGE_TABLE with boot param value */ boot_params->autoconfig = 1; diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index e69c0613513f..ac095fa00973 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -111,14 +111,14 @@ static void memory_ranges_init(struct ivpu_device *vdev) { if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) { ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M); - ivpu_hw_range_init(&vdev->hw->ranges.user, 0xc0000000, 255 * SZ_1M); + ivpu_hw_range_init(&vdev->hw->ranges.user, 0x88000000, 511 * SZ_1M); ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x180000000, SZ_2G); - ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_8G); + ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_128G); } else { ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M); - ivpu_hw_range_init(&vdev->hw->ranges.user, 0x80000000, SZ_256M); - ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x80000000 + SZ_256M, SZ_2G - SZ_256M); - ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_8G); + ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x80000000, SZ_2G); + ivpu_hw_range_init(&vdev->hw->ranges.user, 0x100000000, SZ_256G); + vdev->hw->ranges.dma = vdev->hw->ranges.user; } } diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c index 697b57071d54..891967a95bc3 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.c +++ b/drivers/accel/ivpu/ivpu_mmu_context.c @@ -571,8 +571,8 @@ void ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ct start = vdev->hw->ranges.global.start; end = vdev->hw->ranges.shave.end; } else { - start = vdev->hw->ranges.user.start; - end = vdev->hw->ranges.dma.end; + start = min_t(u64, vdev->hw->ranges.user.start, vdev->hw->ranges.shave.start); + end = max_t(u64, vdev->hw->ranges.user.end, vdev->hw->ranges.dma.end); } drm_mm_init(&ctx->mm, start, end - start);