AMD-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
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


  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