Skip to content

Commit 5e861a6

Browse files
akacprowjlawryno
authored andcommitted
accel/ivpu: Add turbo flag to the DRM_IVPU_CMDQ_CREATE ioctl
Introduce a new parameter to the DRM_IVPU_CMDQ_CREATE ioctl, enabling turbo mode for jobs submitted via the command queue. Turbo mode allows jobs to run at higher frequencies, potentially improving performance for demanding workloads. Also adds the IVPU_TEST_MODE_TURBO_DISABLE flag to allow test mode to explicitly disable turbo mode requested by the application. The IVPU_TEST_MODE_TURBO mode has been renamed to IVPU_TEST_MODE_TURBO_ENABLE for clarity and consistency. Signed-off-by: Andrzej Kacprowski <[email protected]> Signed-off-by: Maciej Falkowski <[email protected]> Reviewed-by: Jeff Hugo <[email protected]> Signed-off-by: Jacek Lawrynowicz <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 8346440 commit 5e861a6

File tree

3 files changed

+73
-33
lines changed

3 files changed

+73
-33
lines changed

drivers/accel/ivpu/ivpu_drv.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* SPDX-License-Identifier: GPL-2.0-only */
22
/*
3-
* Copyright (C) 2020-2024 Intel Corporation
3+
* Copyright (C) 2020-2025 Intel Corporation
44
*/
55

66
#ifndef __IVPU_DRV_H__
@@ -209,10 +209,11 @@ extern bool ivpu_force_snoop;
209209
#define IVPU_TEST_MODE_D0I3_MSG_ENABLE BIT(5)
210210
#define IVPU_TEST_MODE_MIP_DISABLE BIT(6)
211211
#define IVPU_TEST_MODE_DISABLE_TIMEOUTS BIT(8)
212-
#define IVPU_TEST_MODE_TURBO BIT(9)
213-
#define IVPU_TEST_MODE_CLK_RELINQ_DISABLE BIT(10)
214-
#define IVPU_TEST_MODE_CLK_RELINQ_ENABLE BIT(11)
215-
#define IVPU_TEST_MODE_D0I2_DISABLE BIT(12)
212+
#define IVPU_TEST_MODE_TURBO_ENABLE BIT(9)
213+
#define IVPU_TEST_MODE_TURBO_DISABLE BIT(10)
214+
#define IVPU_TEST_MODE_CLK_RELINQ_DISABLE BIT(11)
215+
#define IVPU_TEST_MODE_CLK_RELINQ_ENABLE BIT(12)
216+
#define IVPU_TEST_MODE_D0I2_DISABLE BIT(13)
216217
extern int ivpu_test_mode;
217218

218219
struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv);

drivers/accel/ivpu/ivpu_job.c

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
/*
3-
* Copyright (C) 2020-2024 Intel Corporation
3+
* Copyright (C) 2020-2025 Intel Corporation
44
*/
55

66
#include <drm/drm_file.h>
@@ -100,15 +100,51 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv)
100100
return NULL;
101101
}
102102

103+
/**
104+
* ivpu_cmdq_get_entry_count - Calculate the number of entries in the command queue.
105+
* @cmdq: Pointer to the command queue structure.
106+
*
107+
* Returns the number of entries that can fit in the command queue memory.
108+
*/
109+
static inline u32 ivpu_cmdq_get_entry_count(struct ivpu_cmdq *cmdq)
110+
{
111+
size_t size = ivpu_bo_size(cmdq->mem) - sizeof(struct vpu_job_queue_header);
112+
113+
return size / sizeof(struct vpu_job_queue_entry);
114+
}
115+
116+
/**
117+
* ivpu_cmdq_get_flags - Get command queue flags based on input flags and test mode.
118+
* @vdev: Pointer to the ivpu device structure.
119+
* @flags: Input flags to determine the command queue flags.
120+
*
121+
* Returns the calculated command queue flags, considering both the input flags
122+
* and the current test mode settings.
123+
*/
124+
static u32 ivpu_cmdq_get_flags(struct ivpu_device *vdev, u32 flags)
125+
{
126+
u32 cmdq_flags = 0;
127+
128+
if ((flags & DRM_IVPU_CMDQ_FLAG_TURBO) && (ivpu_hw_ip_gen(vdev) >= IVPU_HW_IP_40XX))
129+
cmdq_flags |= VPU_JOB_QUEUE_FLAGS_TURBO_MODE;
130+
131+
/* Test mode can override the TURBO flag coming from the application */
132+
if (ivpu_test_mode & IVPU_TEST_MODE_TURBO_ENABLE)
133+
cmdq_flags |= VPU_JOB_QUEUE_FLAGS_TURBO_MODE;
134+
if (ivpu_test_mode & IVPU_TEST_MODE_TURBO_DISABLE)
135+
cmdq_flags &= ~VPU_JOB_QUEUE_FLAGS_TURBO_MODE;
136+
137+
return cmdq_flags;
138+
}
139+
103140
static void ivpu_cmdq_free(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)
104141
{
105142
ivpu_preemption_buffers_free(file_priv->vdev, file_priv, cmdq);
106143
ivpu_bo_free(cmdq->mem);
107144
kfree(cmdq);
108145
}
109146

110-
static struct ivpu_cmdq *ivpu_cmdq_create(struct ivpu_file_priv *file_priv, u8 priority,
111-
bool is_legacy)
147+
static struct ivpu_cmdq *ivpu_cmdq_create(struct ivpu_file_priv *file_priv, u8 priority, u32 flags)
112148
{
113149
struct ivpu_device *vdev = file_priv->vdev;
114150
struct ivpu_cmdq *cmdq = NULL;
@@ -121,18 +157,22 @@ static struct ivpu_cmdq *ivpu_cmdq_create(struct ivpu_file_priv *file_priv, u8 p
121157
ivpu_err(vdev, "Failed to allocate command queue\n");
122158
return NULL;
123159
}
124-
125-
cmdq->priority = priority;
126-
cmdq->is_legacy = is_legacy;
127-
128160
ret = xa_alloc_cyclic(&file_priv->cmdq_xa, &cmdq->id, cmdq, file_priv->cmdq_limit,
129161
&file_priv->cmdq_id_next, GFP_KERNEL);
130162
if (ret < 0) {
131163
ivpu_err(vdev, "Failed to allocate command queue ID: %d\n", ret);
132164
goto err_free_cmdq;
133165
}
134166

135-
ivpu_dbg(vdev, JOB, "Command queue %d created, ctx %d\n", cmdq->id, file_priv->ctx.id);
167+
cmdq->entry_count = ivpu_cmdq_get_entry_count(cmdq);
168+
cmdq->priority = priority;
169+
170+
cmdq->jobq = (struct vpu_job_queue *)ivpu_bo_vaddr(cmdq->mem);
171+
cmdq->jobq->header.engine_idx = VPU_ENGINE_COMPUTE;
172+
cmdq->jobq->header.flags = ivpu_cmdq_get_flags(vdev, flags);
173+
174+
ivpu_dbg(vdev, JOB, "Command queue %d created, ctx %d, flags 0x%08x\n",
175+
cmdq->id, file_priv->ctx.id, cmdq->jobq->header.flags);
136176
return cmdq;
137177

138178
err_free_cmdq:
@@ -188,27 +228,14 @@ static int ivpu_register_db(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *
188228
return ret;
189229
}
190230

191-
static void ivpu_cmdq_jobq_init(struct ivpu_device *vdev, struct vpu_job_queue *jobq)
231+
static void ivpu_cmdq_jobq_reset(struct ivpu_device *vdev, struct vpu_job_queue *jobq)
192232
{
193-
jobq->header.engine_idx = VPU_ENGINE_COMPUTE;
194233
jobq->header.head = 0;
195234
jobq->header.tail = 0;
196235

197-
if (ivpu_test_mode & IVPU_TEST_MODE_TURBO) {
198-
ivpu_dbg(vdev, JOB, "Turbo mode enabled");
199-
jobq->header.flags = VPU_JOB_QUEUE_FLAGS_TURBO_MODE;
200-
}
201-
202236
wmb(); /* Flush WC buffer for jobq->header */
203237
}
204238

205-
static inline u32 ivpu_cmdq_get_entry_count(struct ivpu_cmdq *cmdq)
206-
{
207-
size_t size = ivpu_bo_size(cmdq->mem) - sizeof(struct vpu_job_queue_header);
208-
209-
return size / sizeof(struct vpu_job_queue_entry);
210-
}
211-
212239
static int ivpu_cmdq_register(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)
213240
{
214241
struct ivpu_device *vdev = file_priv->vdev;
@@ -219,10 +246,7 @@ static int ivpu_cmdq_register(struct ivpu_file_priv *file_priv, struct ivpu_cmdq
219246
if (cmdq->db_id)
220247
return 0;
221248

222-
cmdq->entry_count = ivpu_cmdq_get_entry_count(cmdq);
223-
cmdq->jobq = (struct vpu_job_queue *)ivpu_bo_vaddr(cmdq->mem);
224-
225-
ivpu_cmdq_jobq_init(vdev, cmdq->jobq);
249+
ivpu_cmdq_jobq_reset(vdev, cmdq->jobq);
226250

227251
if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) {
228252
ret = ivpu_hws_cmdq_init(file_priv, cmdq, VPU_ENGINE_COMPUTE, cmdq->priority);
@@ -291,9 +315,10 @@ static struct ivpu_cmdq *ivpu_cmdq_acquire_legacy(struct ivpu_file_priv *file_pr
291315
break;
292316

293317
if (!cmdq) {
294-
cmdq = ivpu_cmdq_create(file_priv, priority, true);
318+
cmdq = ivpu_cmdq_create(file_priv, priority, 0);
295319
if (!cmdq)
296320
return NULL;
321+
cmdq->is_legacy = true;
297322
}
298323

299324
return cmdq;
@@ -891,7 +916,7 @@ int ivpu_cmdq_create_ioctl(struct drm_device *dev, void *data, struct drm_file *
891916

892917
mutex_lock(&file_priv->lock);
893918

894-
cmdq = ivpu_cmdq_create(file_priv, ivpu_job_to_jsm_priority(args->priority), false);
919+
cmdq = ivpu_cmdq_create(file_priv, ivpu_job_to_jsm_priority(args->priority), args->flags);
895920
if (cmdq)
896921
args->cmdq_id = cmdq->id;
897922

include/uapi/drm/ivpu_accel.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,9 @@ struct drm_ivpu_metric_streamer_get_data {
445445
__u64 data_size;
446446
};
447447

448+
/* Command queue flags */
449+
#define DRM_IVPU_CMDQ_FLAG_TURBO 0x00000001
450+
448451
/**
449452
* struct drm_ivpu_cmdq_create - Create command queue for job submission
450453
*/
@@ -462,6 +465,17 @@ struct drm_ivpu_cmdq_create {
462465
* %DRM_IVPU_JOB_PRIORITY_REALTIME
463466
*/
464467
__u32 priority;
468+
/**
469+
* @flags:
470+
*
471+
* Supported flags:
472+
*
473+
* %DRM_IVPU_CMDQ_FLAG_TURBO
474+
*
475+
* Enable low-latency mode for the command queue. The NPU will maximize performance
476+
* when executing jobs from such queue at the cost of increased power usage.
477+
*/
478+
__u32 flags;
465479
};
466480

467481
/**

0 commit comments

Comments
 (0)