Commit ce0d0ec3 authored by Evan Quan's avatar Evan Quan Committed by Alex Deucher

drm/amd/powerplay: unified VRAM address for driver table interaction with SMU V2

By this, we can avoid to pass in the VRAM address on every table
transferring. That puts extra unnecessary traffics on SMU on
some cases(e.g. polling the amdgpu_pm_info sysfs interface).

V2: document what the driver table is for and how it works
Signed-off-by: default avatarEvan Quan <evan.quan@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9fa1ed5b
...@@ -519,26 +519,19 @@ int smu_update_table(struct smu_context *smu, enum smu_table_id table_index, int ...@@ -519,26 +519,19 @@ int smu_update_table(struct smu_context *smu, enum smu_table_id table_index, int
{ {
struct smu_table_context *smu_table = &smu->smu_table; struct smu_table_context *smu_table = &smu->smu_table;
struct amdgpu_device *adev = smu->adev; struct amdgpu_device *adev = smu->adev;
struct smu_table *table = NULL; struct smu_table *table = &smu_table->driver_table;
int ret = 0;
int table_id = smu_table_get_index(smu, table_index); int table_id = smu_table_get_index(smu, table_index);
uint32_t table_size;
int ret = 0;
if (!table_data || table_id >= SMU_TABLE_COUNT || table_id < 0) if (!table_data || table_id >= SMU_TABLE_COUNT || table_id < 0)
return -EINVAL; return -EINVAL;
table = &smu_table->tables[table_index]; table_size = smu_table->tables[table_index].size;
if (drv2smu) if (drv2smu)
memcpy(table->cpu_addr, table_data, table->size); memcpy(table->cpu_addr, table_data, table_size);
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetDriverDramAddrHigh,
upper_32_bits(table->mc_address));
if (ret)
return ret;
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetDriverDramAddrLow,
lower_32_bits(table->mc_address));
if (ret)
return ret;
ret = smu_send_smc_msg_with_param(smu, drv2smu ? ret = smu_send_smc_msg_with_param(smu, drv2smu ?
SMU_MSG_TransferTableDram2Smu : SMU_MSG_TransferTableDram2Smu :
SMU_MSG_TransferTableSmu2Dram, SMU_MSG_TransferTableSmu2Dram,
...@@ -550,7 +543,7 @@ int smu_update_table(struct smu_context *smu, enum smu_table_id table_index, int ...@@ -550,7 +543,7 @@ int smu_update_table(struct smu_context *smu, enum smu_table_id table_index, int
adev->nbio.funcs->hdp_flush(adev, NULL); adev->nbio.funcs->hdp_flush(adev, NULL);
if (!drv2smu) if (!drv2smu)
memcpy(table_data, table->cpu_addr, table->size); memcpy(table_data, table->cpu_addr, table_size);
return ret; return ret;
} }
...@@ -976,32 +969,56 @@ static int smu_init_fb_allocations(struct smu_context *smu) ...@@ -976,32 +969,56 @@ static int smu_init_fb_allocations(struct smu_context *smu)
struct amdgpu_device *adev = smu->adev; struct amdgpu_device *adev = smu->adev;
struct smu_table_context *smu_table = &smu->smu_table; struct smu_table_context *smu_table = &smu->smu_table;
struct smu_table *tables = smu_table->tables; struct smu_table *tables = smu_table->tables;
struct smu_table *driver_table = &(smu_table->driver_table);
uint32_t max_table_size = 0;
int ret, i; int ret, i;
for (i = 0; i < SMU_TABLE_COUNT; i++) { /* VRAM allocation for tool table */
if (tables[i].size == 0) if (tables[SMU_TABLE_PMSTATUSLOG].size) {
continue;
ret = amdgpu_bo_create_kernel(adev, ret = amdgpu_bo_create_kernel(adev,
tables[i].size, tables[SMU_TABLE_PMSTATUSLOG].size,
tables[i].align, tables[SMU_TABLE_PMSTATUSLOG].align,
tables[i].domain, tables[SMU_TABLE_PMSTATUSLOG].domain,
&tables[i].bo, &tables[SMU_TABLE_PMSTATUSLOG].bo,
&tables[i].mc_address, &tables[SMU_TABLE_PMSTATUSLOG].mc_address,
&tables[i].cpu_addr); &tables[SMU_TABLE_PMSTATUSLOG].cpu_addr);
if (ret) if (ret) {
goto failed; pr_err("VRAM allocation for tool table failed!\n");
return ret;
}
} }
return 0; /* VRAM allocation for driver table */
failed: for (i = 0; i < SMU_TABLE_COUNT; i++) {
while (--i >= 0) {
if (tables[i].size == 0) if (tables[i].size == 0)
continue; continue;
amdgpu_bo_free_kernel(&tables[i].bo,
&tables[i].mc_address,
&tables[i].cpu_addr);
if (i == SMU_TABLE_PMSTATUSLOG)
continue;
if (max_table_size < tables[i].size)
max_table_size = tables[i].size;
}
driver_table->size = max_table_size;
driver_table->align = PAGE_SIZE;
driver_table->domain = AMDGPU_GEM_DOMAIN_VRAM;
ret = amdgpu_bo_create_kernel(adev,
driver_table->size,
driver_table->align,
driver_table->domain,
&driver_table->bo,
&driver_table->mc_address,
&driver_table->cpu_addr);
if (ret) {
pr_err("VRAM allocation for driver table failed!\n");
if (tables[SMU_TABLE_PMSTATUSLOG].mc_address)
amdgpu_bo_free_kernel(&tables[SMU_TABLE_PMSTATUSLOG].bo,
&tables[SMU_TABLE_PMSTATUSLOG].mc_address,
&tables[SMU_TABLE_PMSTATUSLOG].cpu_addr);
} }
return ret; return ret;
} }
...@@ -1009,18 +1026,19 @@ static int smu_fini_fb_allocations(struct smu_context *smu) ...@@ -1009,18 +1026,19 @@ static int smu_fini_fb_allocations(struct smu_context *smu)
{ {
struct smu_table_context *smu_table = &smu->smu_table; struct smu_table_context *smu_table = &smu->smu_table;
struct smu_table *tables = smu_table->tables; struct smu_table *tables = smu_table->tables;
uint32_t i = 0; struct smu_table *driver_table = &(smu_table->driver_table);
if (!tables) if (!tables)
return 0; return 0;
for (i = 0; i < SMU_TABLE_COUNT; i++) { if (tables[SMU_TABLE_PMSTATUSLOG].mc_address)
if (tables[i].size == 0) amdgpu_bo_free_kernel(&tables[SMU_TABLE_PMSTATUSLOG].bo,
continue; &tables[SMU_TABLE_PMSTATUSLOG].mc_address,
amdgpu_bo_free_kernel(&tables[i].bo, &tables[SMU_TABLE_PMSTATUSLOG].cpu_addr);
&tables[i].mc_address,
&tables[i].cpu_addr); amdgpu_bo_free_kernel(&driver_table->bo,
} &driver_table->mc_address,
&driver_table->cpu_addr);
return 0; return 0;
} }
...@@ -1091,6 +1109,10 @@ static int smu_smc_table_hw_init(struct smu_context *smu, ...@@ -1091,6 +1109,10 @@ static int smu_smc_table_hw_init(struct smu_context *smu,
/* smu_dump_pptable(smu); */ /* smu_dump_pptable(smu); */
if (!amdgpu_sriov_vf(adev)) { if (!amdgpu_sriov_vf(adev)) {
ret = smu_set_driver_table_location(smu);
if (ret)
return ret;
/* /*
* Copy pptable bo in the vram to smc with SMU MSGs such as * Copy pptable bo in the vram to smc with SMU MSGs such as
* SetDriverDramAddr and TransferTableDram2Smu. * SetDriverDramAddr and TransferTableDram2Smu.
......
...@@ -2022,7 +2022,7 @@ static int arcturus_i2c_eeprom_read_data(struct i2c_adapter *control, ...@@ -2022,7 +2022,7 @@ static int arcturus_i2c_eeprom_read_data(struct i2c_adapter *control,
SwI2cRequest_t req; SwI2cRequest_t req;
struct amdgpu_device *adev = to_amdgpu_device(control); struct amdgpu_device *adev = to_amdgpu_device(control);
struct smu_table_context *smu_table = &adev->smu.smu_table; struct smu_table_context *smu_table = &adev->smu.smu_table;
struct smu_table *table = &smu_table->tables[SMU_TABLE_I2C_COMMANDS]; struct smu_table *table = &smu_table->driver_table;
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
arcturus_fill_eeprom_i2c_req(&req, false, address, numbytes, data); arcturus_fill_eeprom_i2c_req(&req, false, address, numbytes, data);
...@@ -2261,6 +2261,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = { ...@@ -2261,6 +2261,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = {
.check_fw_version = smu_v11_0_check_fw_version, .check_fw_version = smu_v11_0_check_fw_version,
.write_pptable = smu_v11_0_write_pptable, .write_pptable = smu_v11_0_write_pptable,
.set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep, .set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep,
.set_driver_table_location = smu_v11_0_set_driver_table_location,
.set_tool_table_location = smu_v11_0_set_tool_table_location, .set_tool_table_location = smu_v11_0_set_tool_table_location,
.notify_memory_pool_location = smu_v11_0_notify_memory_pool_location, .notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
.system_features_control = smu_v11_0_system_features_control, .system_features_control = smu_v11_0_system_features_control,
......
...@@ -260,6 +260,15 @@ struct smu_table_context ...@@ -260,6 +260,15 @@ struct smu_table_context
struct smu_bios_boot_up_values boot_values; struct smu_bios_boot_up_values boot_values;
void *driver_pptable; void *driver_pptable;
struct smu_table *tables; struct smu_table *tables;
/*
* The driver table is just a staging buffer for
* uploading/downloading content from the SMU.
*
* And the table_id for SMU_MSG_TransferTableSmu2Dram/
* SMU_MSG_TransferTableDram2Smu instructs SMU
* which content driver is interested.
*/
struct smu_table driver_table;
struct smu_table memory_pool; struct smu_table memory_pool;
uint8_t thermal_controller_type; uint8_t thermal_controller_type;
...@@ -498,6 +507,7 @@ struct pptable_funcs { ...@@ -498,6 +507,7 @@ struct pptable_funcs {
int (*set_gfx_cgpg)(struct smu_context *smu, bool enable); int (*set_gfx_cgpg)(struct smu_context *smu, bool enable);
int (*write_pptable)(struct smu_context *smu); int (*write_pptable)(struct smu_context *smu);
int (*set_min_dcef_deep_sleep)(struct smu_context *smu); int (*set_min_dcef_deep_sleep)(struct smu_context *smu);
int (*set_driver_table_location)(struct smu_context *smu);
int (*set_tool_table_location)(struct smu_context *smu); int (*set_tool_table_location)(struct smu_context *smu);
int (*notify_memory_pool_location)(struct smu_context *smu); int (*notify_memory_pool_location)(struct smu_context *smu);
int (*set_last_dcef_min_deep_sleep_clk)(struct smu_context *smu); int (*set_last_dcef_min_deep_sleep_clk)(struct smu_context *smu);
......
...@@ -170,6 +170,8 @@ int smu_v11_0_write_pptable(struct smu_context *smu); ...@@ -170,6 +170,8 @@ int smu_v11_0_write_pptable(struct smu_context *smu);
int smu_v11_0_set_min_dcef_deep_sleep(struct smu_context *smu); int smu_v11_0_set_min_dcef_deep_sleep(struct smu_context *smu);
int smu_v11_0_set_driver_table_location(struct smu_context *smu);
int smu_v11_0_set_tool_table_location(struct smu_context *smu); int smu_v11_0_set_tool_table_location(struct smu_context *smu);
int smu_v11_0_notify_memory_pool_location(struct smu_context *smu); int smu_v11_0_notify_memory_pool_location(struct smu_context *smu);
......
...@@ -90,4 +90,6 @@ int smu_v12_0_mode2_reset(struct smu_context *smu); ...@@ -90,4 +90,6 @@ int smu_v12_0_mode2_reset(struct smu_context *smu);
int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type, int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
uint32_t min, uint32_t max); uint32_t min, uint32_t max);
int smu_v12_0_set_driver_table_location(struct smu_context *smu);
#endif #endif
...@@ -2147,6 +2147,7 @@ static const struct pptable_funcs navi10_ppt_funcs = { ...@@ -2147,6 +2147,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
.check_fw_version = smu_v11_0_check_fw_version, .check_fw_version = smu_v11_0_check_fw_version,
.write_pptable = smu_v11_0_write_pptable, .write_pptable = smu_v11_0_write_pptable,
.set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep, .set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep,
.set_driver_table_location = smu_v11_0_set_driver_table_location,
.set_tool_table_location = smu_v11_0_set_tool_table_location, .set_tool_table_location = smu_v11_0_set_tool_table_location,
.notify_memory_pool_location = smu_v11_0_notify_memory_pool_location, .notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
.system_features_control = smu_v11_0_system_features_control, .system_features_control = smu_v11_0_system_features_control,
......
...@@ -920,6 +920,7 @@ static const struct pptable_funcs renoir_ppt_funcs = { ...@@ -920,6 +920,7 @@ static const struct pptable_funcs renoir_ppt_funcs = {
.get_dpm_ultimate_freq = smu_v12_0_get_dpm_ultimate_freq, .get_dpm_ultimate_freq = smu_v12_0_get_dpm_ultimate_freq,
.mode2_reset = smu_v12_0_mode2_reset, .mode2_reset = smu_v12_0_mode2_reset,
.set_soft_freq_limited_range = smu_v12_0_set_soft_freq_limited_range, .set_soft_freq_limited_range = smu_v12_0_set_soft_freq_limited_range,
.set_driver_table_location = smu_v12_0_set_driver_table_location,
}; };
void renoir_set_ppt_funcs(struct smu_context *smu) void renoir_set_ppt_funcs(struct smu_context *smu)
......
...@@ -61,6 +61,8 @@ ...@@ -61,6 +61,8 @@
((smu)->ppt_funcs->write_pptable ? (smu)->ppt_funcs->write_pptable((smu)) : 0) ((smu)->ppt_funcs->write_pptable ? (smu)->ppt_funcs->write_pptable((smu)) : 0)
#define smu_set_min_dcef_deep_sleep(smu) \ #define smu_set_min_dcef_deep_sleep(smu) \
((smu)->ppt_funcs->set_min_dcef_deep_sleep ? (smu)->ppt_funcs->set_min_dcef_deep_sleep((smu)) : 0) ((smu)->ppt_funcs->set_min_dcef_deep_sleep ? (smu)->ppt_funcs->set_min_dcef_deep_sleep((smu)) : 0)
#define smu_set_driver_table_location(smu) \
((smu)->ppt_funcs->set_driver_table_location ? (smu)->ppt_funcs->set_driver_table_location((smu)) : 0)
#define smu_set_tool_table_location(smu) \ #define smu_set_tool_table_location(smu) \
((smu)->ppt_funcs->set_tool_table_location ? (smu)->ppt_funcs->set_tool_table_location((smu)) : 0) ((smu)->ppt_funcs->set_tool_table_location ? (smu)->ppt_funcs->set_tool_table_location((smu)) : 0)
#define smu_notify_memory_pool_location(smu) \ #define smu_notify_memory_pool_location(smu) \
......
...@@ -776,6 +776,24 @@ int smu_v11_0_set_min_dcef_deep_sleep(struct smu_context *smu) ...@@ -776,6 +776,24 @@ int smu_v11_0_set_min_dcef_deep_sleep(struct smu_context *smu)
return smu_v11_0_set_deep_sleep_dcefclk(smu, table_context->boot_values.dcefclk / 100); return smu_v11_0_set_deep_sleep_dcefclk(smu, table_context->boot_values.dcefclk / 100);
} }
int smu_v11_0_set_driver_table_location(struct smu_context *smu)
{
struct smu_table *driver_table = &smu->smu_table.driver_table;
int ret = 0;
if (driver_table->mc_address) {
ret = smu_send_smc_msg_with_param(smu,
SMU_MSG_SetDriverDramAddrHigh,
upper_32_bits(driver_table->mc_address));
if (!ret)
ret = smu_send_smc_msg_with_param(smu,
SMU_MSG_SetDriverDramAddrLow,
lower_32_bits(driver_table->mc_address));
}
return ret;
}
int smu_v11_0_set_tool_table_location(struct smu_context *smu) int smu_v11_0_set_tool_table_location(struct smu_context *smu)
{ {
int ret = 0; int ret = 0;
......
...@@ -318,14 +318,6 @@ int smu_v12_0_fini_smc_tables(struct smu_context *smu) ...@@ -318,14 +318,6 @@ int smu_v12_0_fini_smc_tables(struct smu_context *smu)
int smu_v12_0_populate_smc_tables(struct smu_context *smu) int smu_v12_0_populate_smc_tables(struct smu_context *smu)
{ {
struct smu_table_context *smu_table = &smu->smu_table; struct smu_table_context *smu_table = &smu->smu_table;
struct smu_table *table = NULL;
table = &smu_table->tables[SMU_TABLE_DPMCLOCKS];
if (!table)
return -EINVAL;
if (!table->cpu_addr)
return -EINVAL;
return smu_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false); return smu_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false);
} }
...@@ -514,3 +506,21 @@ int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_ ...@@ -514,3 +506,21 @@ int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_
return ret; return ret;
} }
int smu_v12_0_set_driver_table_location(struct smu_context *smu)
{
struct smu_table *driver_table = &smu->smu_table.driver_table;
int ret = 0;
if (driver_table->mc_address) {
ret = smu_send_smc_msg_with_param(smu,
SMU_MSG_SetDriverDramAddrHigh,
upper_32_bits(driver_table->mc_address));
if (!ret)
ret = smu_send_smc_msg_with_param(smu,
SMU_MSG_SetDriverDramAddrLow,
lower_32_bits(driver_table->mc_address));
}
return ret;
}
...@@ -3236,6 +3236,7 @@ static const struct pptable_funcs vega20_ppt_funcs = { ...@@ -3236,6 +3236,7 @@ static const struct pptable_funcs vega20_ppt_funcs = {
.check_fw_version = smu_v11_0_check_fw_version, .check_fw_version = smu_v11_0_check_fw_version,
.write_pptable = smu_v11_0_write_pptable, .write_pptable = smu_v11_0_write_pptable,
.set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep, .set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep,
.set_driver_table_location = smu_v11_0_set_driver_table_location,
.set_tool_table_location = smu_v11_0_set_tool_table_location, .set_tool_table_location = smu_v11_0_set_tool_table_location,
.notify_memory_pool_location = smu_v11_0_notify_memory_pool_location, .notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
.system_features_control = smu_v11_0_system_features_control, .system_features_control = smu_v11_0_system_features_control,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment