Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions drivers/accel/ivpu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,10 @@ 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)
is a CPU-integrated inference accelerator for Computer Vision
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.
8 changes: 1 addition & 7 deletions drivers/accel/ivpu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,8 @@ 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

subdir-ccflags-$(CONFIG_DRM_ACCEL_IVPU_DEBUG) += -DDEBUG

CFLAGS_ivpu_trace_points.o = -I$(src)
39 changes: 0 additions & 39 deletions drivers/accel/ivpu/ivpu_coredump.c

This file was deleted.

25 changes: 0 additions & 25 deletions drivers/accel/ivpu/ivpu_coredump.h

This file was deleted.

86 changes: 56 additions & 30 deletions drivers/accel/ivpu/ivpu_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -127,7 +119,6 @@ static int firewall_irq_counter_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},
Expand All @@ -136,23 +127,32 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = {
{"firewall_irq_counter", firewall_irq_counter_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)
Expand Down Expand Up @@ -201,7 +201,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;
}

Expand Down Expand Up @@ -346,23 +346,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)
{
Expand Down Expand Up @@ -406,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,
Expand Down
50 changes: 16 additions & 34 deletions drivers/accel/ivpu/ivpu_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/pm_runtime.h>
#include <generated/utsrelease.h>

#include <drm/drm_accel.h>
#include <drm/drm_file.h>
#include <drm/drm_gem.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_prime.h>

#include "ivpu_coredump.h"
#include "vpu_boot_api.h"
#include "ivpu_debugfs.h"
#include "ivpu_drv.h"
#include "ivpu_fw.h"
Expand All @@ -30,10 +29,10 @@
#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 "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;
Expand All @@ -43,10 +42,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);
Expand All @@ -56,9 +53,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);
Expand Down Expand Up @@ -106,8 +103,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);

Expand All @@ -121,6 +116,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));

Expand Down Expand Up @@ -260,13 +257,6 @@ 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;

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);

Expand Down Expand Up @@ -352,7 +342,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);
Expand Down Expand Up @@ -386,7 +376,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_fw_log_dump(vdev);
return ret;
}

ivpu_hw_irq_clear(vdev);
Expand All @@ -397,20 +390,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)
Expand Down Expand Up @@ -457,8 +442,8 @@ static const struct drm_driver driver = {

.name = DRIVER_NAME,
.desc = DRIVER_DESC,

.major = 1,
.major = DRM_IVPU_DRIVER_MAJOR,
.minor = DRM_IVPU_DRIVER_MINOR,
};

static void ivpu_context_abort_invalid(struct ivpu_device *vdev)
Expand Down Expand Up @@ -616,9 +601,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->db_limit.min = IVPU_MIN_DB;
vdev->db_limit.max = IVPU_MAX_DB;

ret = drmm_mutex_init(&vdev->drm, &vdev->context_list_lock);
if (ret)
goto err_xa_destroy;
Expand Down
Loading