Add asynchronous messaging (message which doesn't wait for response) using message control block.
Signed-off-by: Lijo Lazar <[email protected]> --- drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 3 +- drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 37 +++++++++++++++++-- drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h | 2 + 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 41f27fb4af4b..e98a1e765f1c 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 3c06ac5d23fa..03cd724a0bf8 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c @@ -671,6 +671,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) @@ -695,7 +696,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, @@ -727,8 +729,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; } @@ -775,7 +777,8 @@ static int smu_msg_v1_send_msg(struct smu_msg_ctl *ctl, WARN_ON(1); } - mutex_unlock(&ctl->lock); + if (!lock_held) + mutex_unlock(&ctl->lock); return ret; } @@ -812,6 +815,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) -- 2.49.0
