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    | 61 +++++++++++++++++++
 .../drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c  | 38 ++++++++++++
 3 files changed, 104 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..7ab6cf2367df 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,67 @@ 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);
+       struct smu_table *memory_pool = &smu_table->memory_pool;
+       uint64_t address;
+       uint32_t table_size;
+       int ret = 0;
+       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);
+
+       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;
+               }
+       }
 
        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;
 }
 
-- 
2.43.0

Reply via email to