On 06-Feb-26 7:30 PM, Pratik Vishwakarma wrote:
Add update_table for SMU 15_0_0
Signed-off-by: Pratik Vishwakarma <[email protected]>
---
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h | 5 ++
.../gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c | 60 +++++++++++++++++++
.../drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c | 38 ++++++++++++
3 files changed, 103 insertions(+)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h
b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h
index 14e8d8c7a80a..af87c31ca9a4 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h
@@ -241,5 +241,10 @@ int smu_v15_0_enable_thermal_alert(struct smu_context
*smu);
int smu_v15_0_disable_thermal_alert(struct smu_context *smu);
+int smu_v15_0_0_update_table(struct smu_context *smu,
+ enum smu_table_id table_index,
+ int argument, void *table_data,
+ bool drv2smu);
+
#endif
#endif
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c
b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c
index a2854d528bab..70dd5586c53e 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c
@@ -1726,6 +1726,66 @@ int smu_v15_0_set_gfx_power_up_by_imu(struct smu_context
*smu)
return ret;
}
+int smu_v15_0_0_update_table(struct smu_context *smu,
+ enum smu_table_id table_index,
+ int argument,
+ void *table_data,
+ bool drv2smu)
+{
+ struct smu_table_context *smu_table = &smu->smu_table;
+ struct amdgpu_device *adev = smu->adev;
+ struct smu_table *table = &smu_table->driver_table;
+ int table_id = smu_cmn_to_asic_specific_index(smu,
+ CMN2ASIC_MAPPING_TABLE,
+ table_index);
+ uint64_t address;
+ uint32_t table_size;
+ int ret;
+ struct smu_msg_ctl *ctl = &smu->msg_ctl;
+
+ if (!table_data || table_index >= SMU_TABLE_COUNT || table_id < 0)
+ return -EINVAL;
+
+ table_size = smu_table->tables[table_index].size;
+
+ if (drv2smu) {
+ memcpy(table->cpu_addr, table_data, table_size);
+ /*
+ * Flush hdp cache: to guard the content seen by
+ * GPU is consitent with CPU.
+ */
+ amdgpu_hdp_flush(adev, NULL);
+ }
+
+ address = smu_table->tables[table_index].mc_address;
+
+ struct smu_msg_args args = {
+ .msg = drv2smu ?
+ SMU_MSG_TransferTableDram2Smu :
+ SMU_MSG_TransferTableSmu2Dram,
+ .num_args = 3,
+ .num_out_args = 0,
+ .flags = SMU_MSG_FLAG_ASYNC | SMU_MSG_FLAG_LOCK_HELD,
+ .timeout = 0,
+ };
+
+ args.args[0] = table_id;
+ args.args[1] = (uint32_t)lower_32_bits(address);
+ args.args[2] = (uint32_t)upper_32_bits(address);
+
+ ret = ctl->ops->send_msg(ctl, &args);
+
+ if (ret)
+ return ret;
+
+ if (!drv2smu) {
+ amdgpu_hdp_invalidate(adev, NULL);
+ memcpy(table_data, table->cpu_addr, table_size);
+ }
+
+ return 0;
+}
+
int smu_v15_0_set_default_dpm_tables(struct smu_context *smu)
{
struct smu_table_context *smu_table = &smu->smu_table;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c
b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c
index d58b0bc2bf78..9a2e2c2f4e06 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c
@@ -190,11 +190,38 @@ static int smu_v15_0_0_init_smc_tables(struct smu_context
*smu)
if (!smu_table->metrics_table)
goto err0_out;
smu_table->metrics_time = 0;
+ if (tables[SMU_TABLE_SMU_METRICS].size) {
+ ret = amdgpu_bo_create_kernel(smu->adev,
+
tables[SMU_TABLE_SMU_METRICS].size,
+
tables[SMU_TABLE_SMU_METRICS].align,
+
tables[SMU_TABLE_SMU_METRICS].domain,
+ &tables[SMU_TABLE_SMU_METRICS].bo,
+
&tables[SMU_TABLE_SMU_METRICS].mc_address,
+
&tables[SMU_TABLE_SMU_METRICS].cpu_addr);
+ if (ret) {
+ dev_err(smu->adev->dev, "VRAM allocation for Metrics table
failed!\n");
+ goto err0_out;
+ }
+ }
Should have clarified better with my previous comment.
In general, what is done is to allocate big buffer that is sufficient to
hold all other tables. That one is called driver table. That buffer is
the one typically used for all table transfers.
https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c#L998
FW messaging/transfer is also one at a time. So you don't need these
allocations, you could use driver table mc address in
smu_v15_0_0_update_table.
Thanks,
Lijo
smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL);
if (!smu_table->clocks_table)
goto err1_out;
+ if (tables[SMU_TABLE_DPMCLOCKS].size) {
+ ret = amdgpu_bo_create_kernel(smu->adev,
+ tables[SMU_TABLE_DPMCLOCKS].size,
+ tables[SMU_TABLE_DPMCLOCKS].align,
+
tables[SMU_TABLE_DPMCLOCKS].domain,
+ &tables[SMU_TABLE_DPMCLOCKS].bo,
+
&tables[SMU_TABLE_DPMCLOCKS].mc_address,
+
&tables[SMU_TABLE_DPMCLOCKS].cpu_addr);
+ if (ret) {
+ dev_err(smu->adev->dev, "VRAM allocation for DPM table
failed!\n");
+ goto err1_out;
+ }
+ }
+
smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL);
if (!smu_table->watermarks_table)
goto err2_out;
@@ -220,6 +247,7 @@ static int smu_v15_0_0_init_smc_tables(struct smu_context
*smu)
static int smu_v15_0_0_fini_smc_tables(struct smu_context *smu)
{
struct smu_table_context *smu_table = &smu->smu_table;
+ struct smu_table *tables = smu_table->tables;
kfree(smu_table->clocks_table);
smu_table->clocks_table = NULL;
@@ -232,6 +260,16 @@ static int smu_v15_0_0_fini_smc_tables(struct smu_context
*smu)
smu_driver_table_fini(smu, SMU_DRIVER_TABLE_GPU_METRICS);
+ if (tables[SMU_TABLE_DPMCLOCKS].mc_address)
+ amdgpu_bo_free_kernel(&tables[SMU_TABLE_DPMCLOCKS].bo,
+ &tables[SMU_TABLE_DPMCLOCKS].mc_address,
+ &tables[SMU_TABLE_DPMCLOCKS].cpu_addr);
+ if (tables[SMU_TABLE_SMU_METRICS].mc_address)
+ amdgpu_bo_free_kernel(&tables[SMU_TABLE_SMU_METRICS].bo,
+
&tables[SMU_TABLE_SMU_METRICS].mc_address,
+
&tables[SMU_TABLE_SMU_METRICS].cpu_addr);
+
+
return 0;
}