From: "David (Ming Qiang) Wu" <David.Wu3@amd.com>
To: <amd-gfx@lists.freedesktop.org>, <Christian.Koenig@amd.com>,
<alexander.deucher@amd.com>
Cc: <leo.liu@amd.com>, <Boyuan.Zhang@amd.com>, <David.Wu3@amd.com>,
"Saleemkhan Jamadar" <saleemkhan.jamadar@amd.com>
Subject: [PATCH 13/14] drm/amdgpu/umsch: userq suspend and resume context
Date: Tue, 10 Feb 2026 16:47:28 -0500 [thread overview]
Message-ID: <20260210214729.80964-14-David.Wu3@amd.com> (raw)
In-Reply-To: <20260210214729.80964-1-David.Wu3@amd.com>
UMSCH supports context suspend and resume whenever buffer
evection and restore is initiated.
Using new function format due to api change (David)
V2 - remove powergating call as it is not needed for resume
use drv_err() instead of DRM_ERROR()
Signed-off-by: Saleemkhan Jamadar <saleemkhan.jamadar@amd.com>
Signed-off-by: David (Ming Qiang) Wu <David.Wu3@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 52 +++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.h | 24 +++++++
drivers/gpu/drm/amd/amdgpu/umsch_mm_v4_0.c | 66 ++++++++++++++++++++
3 files changed, 142 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
index 5a9589b56534..20e9b81fbe06 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
@@ -656,6 +656,56 @@ static void amdgpu_umsch_destroy_queue(struct amdgpu_usermode_queue *queue)
mutex_unlock(&umsch->mutex_hidden);
}
+static int amdgpu_umsch_queue_preempt(struct amdgpu_usermode_queue *queue)
+{
+ struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
+ struct amdgpu_device *adev = uq_mgr->adev;
+ struct amdgpu_umsch_mm *umsch = &adev->umsch_mm;
+ struct amdgpu_userq_obj *ctx = &queue->fw_obj;
+ struct amdgpu_userq_obj *sfence = &queue->suspend_fence_obj;
+ struct umsch_suspend args;
+ int r;
+
+ memset(&args, 0, sizeof(struct umsch_suspend));
+ args.context_csa_addr = ctx->gpu_addr + PAGE_SIZE;
+ args.suspend_fence_addr = sfence->gpu_addr;
+ args.suspend_fence_value = umsch->ring.fence_drv.sync_seq + 1;
+
+ amdgpu_umsch_mm_lock(&adev->umsch_mm);
+ r = umsch->funcs->suspend_queue_ctx(umsch, &args);
+ amdgpu_umsch_mm_unlock(&adev->umsch_mm);
+ if (r)
+ dev_err(adev->dev, "Failed to suspend queue for IP %d err %d.\n",
+ queue->queue_type, r);
+
+ return r;
+}
+
+static int amdgpu_umsch_queue_restore(struct amdgpu_usermode_queue *queue)
+{
+ struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
+ struct amdgpu_device *adev = uq_mgr->adev;
+ struct amdgpu_umsch_mm *umsch = &adev->umsch_mm;
+ struct amdgpu_userq_obj *ctx = &queue->fw_obj;
+ struct umsch_resume args;
+ int r;
+
+ memset(&args, 0, sizeof(struct umsch_resume));
+ args.context_csa_addr = ctx->gpu_addr + PAGE_SIZE;
+ if (queue->queue_type == AMDGPU_HW_IP_VCN_ENC)
+ args.engine_type = UMSCH_SWIP_ENGINE_TYPE_VCN;
+
+ args.resume_option = RESUME_CONTEXT;
+ amdgpu_umsch_mm_lock(&adev->umsch_mm);
+ r = umsch->funcs->resume_queue_ctx(umsch, &args);
+ amdgpu_umsch_mm_unlock(&adev->umsch_mm);
+ if (r)
+ dev_err(adev->dev, "Failed to resume queue for IP %d err %d.\n",
+ queue->queue_type, r);
+
+ return r;
+}
+
void amdgpu_umsch_fwlog_init(struct amdgpu_umsch_mm *umsch_mm)
{
#if defined(CONFIG_DEBUG_FS)
@@ -781,4 +831,6 @@ const struct amdgpu_userq_funcs userq_umsch_4_0_funcs = {
.mqd_destroy = amdgpu_umsch_destroy_queue,
.map = amdgpu_umsch_userq_map,
.unmap = amdgpu_umsch_userq_unmap,
+ .preempt = amdgpu_umsch_queue_preempt,
+ .restore = amdgpu_umsch_queue_restore,
};
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.h
index 6b827c92e817..cbe1ec7363a3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.h
@@ -41,6 +41,11 @@ enum UMSCH_CONTEXT_PRIORITY_LEVEL {
CONTEXT_PRIORITY_NUM_LEVELS
};
+enum UMSCH_RESUME_OPTIONS {
+ RESUME_CONTEXT = 0,
+ RESUME_ENGINE_SCHEDULE = 1,
+};
+
struct umsch_mm_set_resource_input {
uint32_t vmid_mask_mm_vcn;
uint32_t vmid_mask_mm_vpe;
@@ -117,6 +122,20 @@ struct MQD_INFO {
uint32_t vmid;
};
+struct umsch_suspend {
+ uint64_t context_csa_addr;
+ uint64_t suspend_fence_addr;
+ uint32_t suspend_fence_value;
+ uint32_t context_csa_array_index;
+};
+
+struct umsch_resume {
+ enum UMSCH_RESUME_OPTIONS resume_option;
+ uint64_t context_csa_addr;
+ enum UMSCH_SWIP_ENGINE_TYPE engine_type;
+ uint32_t context_csa_array_index;
+};
+
struct amdgpu_umsch_mm;
struct umsch_mm_funcs {
@@ -132,6 +151,11 @@ struct umsch_mm_funcs {
int (*ring_start)(struct amdgpu_umsch_mm *umsch);
int (*ring_stop)(struct amdgpu_umsch_mm *umsch);
int (*ring_fini)(struct amdgpu_umsch_mm *umsch);
+ int (*suspend_queue_ctx)(struct amdgpu_umsch_mm *umsch,
+ struct umsch_suspend *input);
+ int (*resume_queue_ctx)(struct amdgpu_umsch_mm *umsch,
+ struct umsch_resume *input);
+
};
struct amdgpu_umsch_mm {
diff --git a/drivers/gpu/drm/amd/amdgpu/umsch_mm_v4_0.c b/drivers/gpu/drm/amd/amdgpu/umsch_mm_v4_0.c
index 60d1fdfb2af5..c1e47ea8e82a 100644
--- a/drivers/gpu/drm/amd/amdgpu/umsch_mm_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/umsch_mm_v4_0.c
@@ -411,6 +411,70 @@ static int umsch_mm_v4_0_remove_queue(struct amdgpu_umsch_mm *umsch,
return 0;
}
+static int umsch_mm_v4_0_suspend_context(struct amdgpu_umsch_mm *umsch,
+ struct umsch_suspend *input_ptr)
+{
+ union UMSCHAPI__SUSPEND suspend = { 0 };
+ struct amdgpu_device *adev = umsch->ring.adev;
+ int r;
+
+ suspend.header.type = UMSCH_API_TYPE_SCHEDULER;
+ suspend.header.opcode = UMSCH_API_SUSPEND;
+ suspend.header.dwsize = API_FRAME_SIZE_IN_DWORDS;
+
+ suspend.context_csa_addr = input_ptr->context_csa_addr;
+ suspend.suspend_fence_addr = input_ptr->suspend_fence_addr;
+ suspend.suspend_fence_value = input_ptr->suspend_fence_value;
+
+ suspend.api_status.api_completion_fence_addr = umsch->ring.fence_drv.gpu_addr;
+ suspend.api_status.api_completion_fence_value = ++umsch->ring.fence_drv.sync_seq;
+
+ r = amdgpu_umsch_mm_submit_pkt(umsch, &suspend.max_dwords_in_api,
+ API_FRAME_SIZE_IN_DWORDS);
+ if (r)
+ return r;
+
+ r = amdgpu_umsch_mm_query_fence(umsch);
+ if (r) {
+ dev_err(adev->dev, "UMSCH suspend queue: Failed ret %d\n", r);
+ return r;
+ }
+
+ return r;
+}
+
+static int umsch_mm_v4_0_resume_context(struct amdgpu_umsch_mm *umsch,
+ struct umsch_resume *input_ptr)
+{
+ union UMSCHAPI__RESUME resume = { 0 };
+ struct amdgpu_device *adev = umsch->ring.adev;
+ int r;
+
+ resume.header.type = UMSCH_API_TYPE_SCHEDULER;
+ resume.header.opcode = UMSCH_API_RESUME;
+ resume.header.dwsize = API_FRAME_SIZE_IN_DWORDS;
+
+ resume.resume_option = (enum UMSCH_RESUME_OPTION)input_ptr->resume_option;
+ resume.context_csa_addr = input_ptr->context_csa_addr;
+ resume.engine_type = (enum UMSCH_ENGINE_TYPE)input_ptr->engine_type;
+
+ resume.api_status.api_completion_fence_addr = umsch->ring.fence_drv.gpu_addr;
+ resume.api_status.api_completion_fence_value = ++umsch->ring.fence_drv.sync_seq;
+
+ r = amdgpu_umsch_mm_submit_pkt(umsch, &resume.max_dwords_in_api,
+ API_FRAME_SIZE_IN_DWORDS);
+ if (r)
+ return r;
+
+ r = amdgpu_umsch_mm_query_fence(umsch);
+ if (r) {
+ dev_err(adev->dev, "UMSCH resume queue: Failed ret %d\n", r);
+ return r;
+ }
+
+ return r;
+}
+
static int umsch_mm_v4_0_set_regs(struct amdgpu_umsch_mm *umsch)
{
struct amdgpu_device *adev = container_of(umsch, struct amdgpu_device, umsch_mm);
@@ -431,6 +495,8 @@ static const struct umsch_mm_funcs umsch_mm_v4_0_funcs = {
.ring_init = amdgpu_umsch_mm_ring_init,
.ring_start = umsch_mm_v4_0_ring_start,
.ring_stop = umsch_mm_v4_0_ring_stop,
+ .suspend_queue_ctx = umsch_mm_v4_0_suspend_context,
+ .resume_queue_ctx = umsch_mm_v4_0_resume_context,
};
void umsch_mm_v4_0_set_funcs(struct amdgpu_umsch_mm *umsch)
--
2.43.0
next prev parent reply other threads:[~2026-02-10 21:48 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-10 21:47 [PATCH 00/14] user queue support for VCN 4.0.5 David (Ming Qiang) Wu
2026-02-10 21:47 ` [PATCH 01/14] amdgpu: add global aggregated doorbell bo David (Ming Qiang) Wu
2026-02-10 21:47 ` [PATCH 02/14] drm/amdgpu: add AMDGPU_GEM_GLOBAL_AGGREGATED_DOORBELL David (Ming Qiang) Wu
2026-02-10 21:47 ` [PATCH 03/14] drm/amdgpu/userq: add doorbell size for VCN and VPE David (Ming Qiang) Wu
2026-02-10 21:47 ` [PATCH 04/14] amdgpu/umsch: Update UMSCH interface and mqd structure David (Ming Qiang) Wu
2026-02-10 21:47 ` [PATCH 05/14] drm/amdgpu: use amdgpu_user_queue instead of amdgpu_umsch_mm David (Ming Qiang) Wu
2026-02-10 21:47 ` [PATCH 06/14] drm/amdgpu/vcn: changes when kernel queue is disabled David (Ming Qiang) Wu
2026-02-10 21:47 ` [PATCH 07/14] amdgpu/umsch: Add VCN IP init to umsch driver David (Ming Qiang) Wu
2026-02-10 21:47 ` [PATCH 08/14] drm/amdgpu/userq: change mes_userq_create_wptr_mapping() to be common David (Ming Qiang) Wu
2026-02-10 21:47 ` [PATCH 09/14] drm/amdgpu/userq: rework on amdgpu_userq_create_wptr_mapping David (Ming Qiang) Wu
2026-04-24 13:37 ` Alex Deucher
2026-04-27 8:44 ` Zhang, Jesse(Jie)
2026-02-10 21:47 ` [PATCH 10/14] drm/amdgpu/umsch: user queue support for vcn David (Ming Qiang) Wu
2026-02-10 21:47 ` [PATCH 11/14] drm/amdgpu: add AMDGPU_INFO_DOORBELL David (Ming Qiang) Wu
2026-02-10 21:47 ` [PATCH 12/14] drm/amdgpu/vcn: handle interrupt received from fw David (Ming Qiang) Wu
2026-02-10 21:47 ` David (Ming Qiang) Wu [this message]
2026-02-10 21:47 ` [PATCH 14/14] drm/amdgpu/vcn: handle the suspend context interrupt David (Ming Qiang) Wu
2026-02-18 15:37 ` [PATCH 00/14] user queue support for VCN 4.0.5 Saleemkhan
2026-02-18 18:13 ` Wu, David
2026-02-18 23:59 ` Saleemkhan
2026-02-19 18:00 ` David Wu
2026-04-17 15:22 ` Wu, David
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260210214729.80964-14-David.Wu3@amd.com \
--to=david.wu3@amd.com \
--cc=Boyuan.Zhang@amd.com \
--cc=Christian.Koenig@amd.com \
--cc=alexander.deucher@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=leo.liu@amd.com \
--cc=saleemkhan.jamadar@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox