summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorLijo Lazar <lijo.lazar@amd.com>2025-12-16 12:46:40 +0530
committerAlex Deucher <alexander.deucher@amd.com>2026-01-10 14:08:27 -0500
commitc42852d83d0154cdb41626246a90aa64d1e4fb52 (patch)
treee2167833ae766f64c6cdc93c44f78d9ce1b9bb75 /drivers/gpu
parent28665cad86f2830b966547afa996c3c20a432dfb (diff)
drm/amd/pm: Add async message call support
Add asynchronous messaging (message which doesn't wait for response) using message control block. Signed-off-by: Lijo Lazar <lijo.lazar@amd.com> Reviewed-by: Asad Kamal <asad.kamal@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h3
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c37
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h2
3 files changed, 37 insertions, 5 deletions
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
index 842ae201a8ca..3b2937c07cad 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
@@ -554,7 +554,8 @@ struct cmn2asic_mapping {
#define SMU_MSG_MAX_ARGS 4
/* Message flags for smu_msg_args */
-#define SMU_MSG_FLAG_NO_WAIT BIT(0) /* Skip post-poll (for split send/wait) */
+#define SMU_MSG_FLAG_ASYNC BIT(0) /* Async send - skip post-poll */
+#define SMU_MSG_FLAG_LOCK_HELD BIT(1) /* Caller holds ctl->lock */
struct smu_msg_ctl;
/**
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
index ef603a4d57f6..ce2986276a81 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
@@ -546,6 +546,7 @@ static int smu_msg_v1_send_msg(struct smu_msg_ctl *ctl,
u32 reg, msg_flags;
int ret, index;
bool skip_pre_poll = false;
+ bool lock_held = args->flags & SMU_MSG_FLAG_LOCK_HELD;
/* Early exit if no HW access */
if (adev->no_hw_access)
@@ -570,7 +571,8 @@ static int smu_msg_v1_send_msg(struct smu_msg_ctl *ctl,
if (amdgpu_sriov_vf(adev) && !(msg_flags & SMU_MSG_VF_FLAG))
return 0;
- mutex_lock(&ctl->lock);
+ if (!lock_held)
+ mutex_lock(&ctl->lock);
/* RAS priority filter */
ret = __smu_msg_v1_ras_filter(ctl, args->msg, msg_flags,
@@ -602,8 +604,8 @@ static int smu_msg_v1_send_msg(struct smu_msg_ctl *ctl,
/* Send message */
__smu_msg_v1_send(ctl, (u16)index, args);
- /* Post-poll (skip if NO_WAIT) */
- if (args->flags & SMU_MSG_FLAG_NO_WAIT) {
+ /* Post-poll (skip if ASYNC) */
+ if (args->flags & SMU_MSG_FLAG_ASYNC) {
ret = 0;
goto out;
}
@@ -650,7 +652,8 @@ out:
WARN_ON(1);
}
- mutex_unlock(&ctl->lock);
+ if (!lock_held)
+ mutex_unlock(&ctl->lock);
return ret;
}
@@ -687,6 +690,32 @@ int smu_msg_wait_response(struct smu_msg_ctl *ctl, u32 timeout_us)
return ctl->ops->wait_response(ctl, timeout_us);
}
+/**
+ * smu_msg_send_async_locked - Send message asynchronously, caller holds lock
+ * @ctl: Message control block
+ * @msg: Message type
+ * @param: Message parameter
+ *
+ * Send an SMU message without waiting for response. Caller must hold ctl->lock
+ * and call smu_msg_wait_response() later to get the result.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int smu_msg_send_async_locked(struct smu_msg_ctl *ctl,
+ enum smu_message_type msg, u32 param)
+{
+ struct smu_msg_args args = {
+ .msg = msg,
+ .args[0] = param,
+ .num_args = 1,
+ .num_out_args = 0,
+ .flags = SMU_MSG_FLAG_ASYNC | SMU_MSG_FLAG_LOCK_HELD,
+ .timeout = 0,
+ };
+
+ return ctl->ops->send_msg(ctl, &args);
+}
+
int smu_cmn_to_asic_specific_index(struct smu_context *smu,
enum smu_cmn2asic_mapping_type type,
uint32_t index)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
index d9a37ed4e720..13a5c1320874 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
@@ -28,6 +28,8 @@
extern const struct smu_msg_ops smu_msg_v1_ops;
int smu_msg_wait_response(struct smu_msg_ctl *ctl, u32 timeout_us);
+int smu_msg_send_async_locked(struct smu_msg_ctl *ctl,
+ enum smu_message_type msg, u32 param);
#if defined(SWSMU_CODE_LAYER_L2) || defined(SWSMU_CODE_LAYER_L3) || defined(SWSMU_CODE_LAYER_L4)