Signed-off-by: Pratik Vishwakarma <[email protected]>
---
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 91 ++++++++++++++++++++++++++
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h | 10 +++
2 files changed, 101 insertions(+)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
index 6fd50c2fd20e..d5823f475596 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
@@ -183,6 +183,68 @@ int smu_cmn_send_smc_msg_with_param(struct smu_context
*smu,
return ret;
}
+/**
+ * smu_cmn_send_smc_msg_with_multi_param -- send a message with parameter
+ * @smu: pointer to an SMU context
+ * @msg: message to send
+ * @param: parameter arr to send to the SMU
+ * @read_arg: pointer to u32 arr to return a value from the SMU back
+ * to the caller
+ * @num_args: number of param arguments
+ * @num_out_args: number of read_arg
+ *
+ * Send the message @msg with parameter @param to the SMU, wait for
+ * completion of the command, and return back a value from the SMU in
+ * @read_arg pointer.
+ *
+ * Return 0 on success, -errno when a problem is encountered sending
+ * message or receiving reply. If there is a PCI bus recovery or
+ * the destination is a virtual GPU which does not allow this message
+ * type, the message is simply dropped and success is also returned.
+ * See smu_msg_v1_decode_response() for details of the -errno.
+ *
+ * If we weren't able to send the message to the SMU, we also print
+ * the error to the standard log.
+ *
+ * Command completion status is printed only if the -errno is
+ * -EREMOTEIO, indicating that the SMU returned back an
+ * undefined/unknown/unspecified result. All other cases are
+ * well-defined, not printed, but instead given back to the client to
+ * decide what further to do.
+ *
+ * The return value, @read_arg is read back regardless, to give back
+ * more information to the client, which on error would most likely be
+ * @param, but we can't assume that. This also eliminates more
+ * conditionals.
+ */
+int smu_cmn_send_smc_msg_with_multi_param(struct smu_context *smu,
+ enum smu_message_type msg,
+ uint32_t *param,
+ uint32_t *read_arg,
+ uint32_t num_args,
+ uint32_t num_out_args)
+{
+ struct smu_msg_ctl *ctl = &smu->msg_ctl;
+ struct smu_msg_args args = {
+ .msg = msg,
+ .args = param,
+ .num_args = num_args,
+ .num_out_args = read_arg ? num_out_args : 0,
+ .flags = 0,
+ .timeout = 0,
+ };
+ int ret;
+ int i;
+
+ ret = ctl->ops->send_msg(ctl, &args);
+
+ if (read_arg)
+ for (i = 0; i < args.num_out_args; i++)
+ read_arg[i] = args.out_args[i];
+
+ return ret;
+}
+
int smu_cmn_send_smc_msg(struct smu_context *smu,
enum smu_message_type msg,
uint32_t *read_arg)
@@ -591,6 +653,35 @@ int smu_msg_send_async_locked(struct smu_msg_ctl *ctl,
return ctl->ops->send_msg(ctl, &args);
}
+/**
+ * smu_msg_send_async_locked_multi_param - Send message asynchronously, caller
holds lock
+ * @ctl: Message control block
+ * @msg: Message type
+ * @param: Message parameter array of len ctl->config.num_arg_regs
+ * @num_args: Number of write message parameters
+ * @num_out_args: Number of read message parameters
+ *
+ * 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_multi_param(struct smu_msg_ctl *ctl,
+ enum smu_message_type msg, u32 param[],
+ u32 num_args, u32 num_out_args)
+{
+ struct smu_msg_args args = {
+ .msg = msg,
+ .args[0] = param,
+ .num_args = num_args,
+ .num_out_args = num_out_args,
+ .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 b7bfddc65fb2..839dd03021ae 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
@@ -30,6 +30,9 @@ 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);
+int smu_msg_send_async_locked_multi_param(struct smu_msg_ctl *ctl,
+ enum smu_message_type msg, u32 param[],
+ u32 num_args, u32 num_out_args);
#if defined(SWSMU_CODE_LAYER_L2) || defined(SWSMU_CODE_LAYER_L3) || defined(SWSMU_CODE_LAYER_L4)
@@ -115,6 +118,13 @@ int smu_cmn_send_smc_msg_with_param(struct smu_context *smu,
uint32_t param,
uint32_t *read_arg);
+int smu_cmn_send_smc_msg_with_multi_param(struct smu_context *smu,
+ enum smu_message_type msg,
+ uint32_t *param,
+ uint32_t *read_arg,
+ uint32_t num_args,
+ uint32_t num_out_args);
+
int smu_cmn_send_smc_msg(struct smu_context *smu,
enum smu_message_type msg,
uint32_t *read_arg);