]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amd/pm: add read arg support to smu_cmn_update_table
authorYang Wang <kevinyang.wang@amd.com>
Fri, 3 Apr 2026 03:30:22 +0000 (23:30 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 17 Apr 2026 18:52:47 +0000 (14:52 -0400)
Extend the smu_cmn_update_table function to support reading a 32-bit return
argument from the SMU firmware during table transfer operations.

- Rename the original function to smu_cmn_update_table_read_arg
- Add a uint32_t *read_arg output parameter to capture firmware response
- Pass the read_arg pointer to the SMU message command
- Keep full backward compatibility using a macro wrapper for the old API

This allows the driver to retrieve status codes, results, or configuration
feedback from the SMU firmware after table data transfer.

No functional changes for existing users of the original smu_cmn_update_table()
API.

Signed-off-by: Yang Wang <kevinyang.wang@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h

index 126fc54cb5113221653e1e65d71e9490a1480045..d76e0b005308f03c1f4d71e63da8319d509d1b8f 100644 (file)
@@ -584,6 +584,7 @@ struct cmn2asic_mapping {
 /* Message flags for smu_msg_args */
 #define SMU_MSG_FLAG_ASYNC     BIT(0) /* Async send - skip post-poll */
 #define SMU_MSG_FLAG_LOCK_HELD BIT(1) /* Caller holds ctl->lock */
+#define SMU_MSG_FLAG_FORCE_READ_ARG    BIT(2)  /* force read smu arg from pmfw */
 
 /* smu_msg_ctl flags */
 #define SMU_MSG_CTL_DEBUG_MAILBOX      BIT(0) /* Debug mailbox supported */
index 006ef585a377fe626ba13cf99d298cd33e69abfc..3d49e58794d29f050af9a45355d15032a4518ebb 100644 (file)
@@ -496,7 +496,8 @@ static int smu_msg_v1_send_msg(struct smu_msg_ctl *ctl,
        }
 
        /* Read output args */
-       if (ret == 0 && args->num_out_args > 0) {
+       if ((ret == 0 || (args->flags & SMU_MSG_FLAG_FORCE_READ_ARG)) &&
+           args->num_out_args > 0) {
                __smu_msg_v1_read_out_args(ctl, args);
                dev_dbg(adev->dev, "smu send message: %s(%d) resp : 0x%08x",
                        smu_get_message_name(smu, args->msg), index, reg);
@@ -1060,20 +1061,24 @@ int smu_cmn_check_fw_version(struct smu_context *smu)
        return 0;
 }
 
-int smu_cmn_update_table(struct smu_context *smu,
-                        enum smu_table_id table_index,
-                        int argument,
-                        void *table_data,
-                        bool drv2smu)
+int smu_cmn_update_table_read_arg(struct smu_context *smu,
+                                   enum smu_table_id table_index,
+                                   int argument,
+                                   void *table_data,
+                                   uint32_t *read_arg,
+                                   bool drv2smu)
 {
-       struct smu_table_context *smu_table = &smu->smu_table;
        struct amdgpu_device *adev = smu->adev;
+       struct smu_table_context *smu_table = &smu->smu_table;
        struct smu_table *table = &smu_table->driver_table;
+       struct smu_msg_ctl *ctl = &smu->msg_ctl;
+       struct smu_msg_args args;
        int table_id = smu_cmn_to_asic_specific_index(smu,
                                                      CMN2ASIC_MAPPING_TABLE,
                                                      table_index);
        uint32_t table_size;
        int ret = 0;
+
        if (!table_data || table_index >= SMU_TABLE_COUNT || table_id < 0)
                return -EINVAL;
 
@@ -1088,11 +1093,19 @@ int smu_cmn_update_table(struct smu_context *smu,
                amdgpu_hdp_flush(adev, NULL);
        }
 
-       ret = smu_cmn_send_smc_msg_with_param(smu, drv2smu ?
-                                         SMU_MSG_TransferTableDram2Smu :
-                                         SMU_MSG_TransferTableSmu2Dram,
-                                         table_id | ((argument & 0xFFFF) << 16),
-                                         NULL);
+       args.msg = drv2smu ? SMU_MSG_TransferTableDram2Smu : SMU_MSG_TransferTableSmu2Dram;
+       args.args[0] = ((argument & 0xFFFF) << 16) | (table_id  & 0xffff);
+       args.num_args = 1;
+       args.out_args[0] = 0;
+       args.num_out_args = read_arg ? 1 : 0;
+       args.flags = read_arg ? SMU_MSG_FLAG_FORCE_READ_ARG : 0;
+       args.timeout = 0;
+
+       ret = ctl->ops->send_msg(ctl, &args);
+
+       if (read_arg)
+               *read_arg = args.out_args[0];
+
        if (ret)
                return ret;
 
index d129907535bd06ca5bd0efc57a885164cfffe425..c6ac0e876aeabee9072b3dee7d4ee1a4ae32329c 100644 (file)
@@ -102,6 +102,9 @@ int smu_msg_send_async_locked(struct smu_msg_ctl *ctl,
 #define SMU_DPM_PCIE_GEN_IDX(gen)      smu_cmn_dpm_pcie_gen_idx((gen))
 #define SMU_DPM_PCIE_WIDTH_IDX(width)  smu_cmn_dpm_pcie_width_idx((width))
 
+#define smu_cmn_update_table(smu, table_index, argument, table_data, drv2smu) \
+       smu_cmn_update_table_read_arg((smu), (table_index), (argument), (table_data), NULL, (drv2smu))
+
 extern const int link_speed[];
 
 /* Helper to Convert from PCIE Gen 1/2/3/4/5/6 to 0.1 GT/s speed units */
@@ -168,11 +171,12 @@ int smu_cmn_get_smc_version(struct smu_context *smu,
                            uint32_t *if_version,
                            uint32_t *smu_version);
 
-int smu_cmn_update_table(struct smu_context *smu,
-                        enum smu_table_id table_index,
-                        int argument,
-                        void *table_data,
-                        bool drv2smu);
+int smu_cmn_update_table_read_arg(struct smu_context *smu,
+                                 enum smu_table_id table_index,
+                                 int argument,
+                                 void *table_data,
+                                 uint32_t *read_arg,
+                                 bool drv2smu);
 
 int smu_cmn_vram_cpy(struct smu_context *smu, void *dst,
                     const void *src, size_t len);