Add new functions for sending multi param send msg
and read response

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);
-- 
2.43.0

Reply via email to