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 126fc54cb511..d76e0b005308 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -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 */ diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c index 006ef585a377..3d49e58794d2 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c @@ -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; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h index d129907535bd..c6ac0e876aea 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h @@ -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);