mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 06:31:58 +02:00
drm/amd/pm: Setup driver pptable for smu 15.0.8
Setup driver pptable and initialize data from static metrics table for smu_v15_0_8 v2: Remove unrelated changes and update description (Lijo) v3: Use ARRAY_SIZE (Lijo) v4: Move structure to header file v5: squash in static metrics support (Asad) Signed-off-by: Yang Wang <kevinyang.wang@amd.com> Signed-off-by: Asad Kamal <asad.kamal@amd.com> Reviewed-by: Lijo Lazar <lijo.lazar@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
fde815f76f
commit
611e5af419
|
|
@ -690,6 +690,7 @@ enum amdgpu_uid_type {
|
|||
AMDGPU_UID_TYPE_XCD,
|
||||
AMDGPU_UID_TYPE_AID,
|
||||
AMDGPU_UID_TYPE_SOC,
|
||||
AMDGPU_UID_TYPE_MID,
|
||||
AMDGPU_UID_TYPE_MAX
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ struct smu_15_0_dpm_context {
|
|||
uint32_t workload_policy_mask;
|
||||
uint32_t dcef_min_ds_clk;
|
||||
uint64_t caps;
|
||||
uint32_t board_volt;
|
||||
};
|
||||
|
||||
enum smu_15_0_power_state {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "mp/mp_15_0_8_offset.h"
|
||||
#include "mp/mp_15_0_8_sh_mask.h"
|
||||
#include "smu_v15_0.h"
|
||||
#include "amdgpu_fru_eeprom.h"
|
||||
|
||||
#undef MP1_Public
|
||||
|
||||
|
|
@ -51,6 +52,10 @@
|
|||
#undef pr_info
|
||||
#undef pr_debug
|
||||
|
||||
#define SMUQ10_TO_UINT(x) ((x) >> 10)
|
||||
#define SMUQ10_FRAC(x) ((x) & 0x3ff)
|
||||
#define SMUQ10_ROUND(x) ((SMUQ10_TO_UINT(x)) + ((SMUQ10_FRAC(x)) >= 0x200))
|
||||
|
||||
#define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c))
|
||||
|
||||
#define SMU_15_0_8_FEA_MAP(smu_feature, smu_15_0_8_feature) \
|
||||
|
|
@ -161,6 +166,35 @@ static const struct cmn2asic_mapping smu_v15_0_8_table_map[SMU_TABLE_COUNT] = {
|
|||
|
||||
static int smu_v15_0_8_tables_init(struct smu_context *smu)
|
||||
{
|
||||
struct smu_table_context *smu_table = &smu->smu_table;
|
||||
struct smu_table *tables = smu_table->tables;
|
||||
int gpu_metrcs_size = sizeof(MetricsTable_t);
|
||||
void *driver_pptable __free(kfree) = NULL;
|
||||
void *metrics_table __free(kfree) = NULL;
|
||||
|
||||
SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU15_TOOL_SIZE,
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
|
||||
|
||||
SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS,
|
||||
gpu_metrcs_size,
|
||||
PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT);
|
||||
|
||||
metrics_table = kzalloc(gpu_metrcs_size, GFP_KERNEL);
|
||||
if (!metrics_table)
|
||||
return -ENOMEM;
|
||||
|
||||
smu_table->metrics_time = 0;
|
||||
|
||||
driver_pptable = kzalloc(sizeof(PPTable_t), GFP_KERNEL);
|
||||
if (!driver_pptable)
|
||||
return -ENOMEM;
|
||||
|
||||
smu_table->metrics_table = no_free_ptr(metrics_table);
|
||||
smu_table->driver_pptable = no_free_ptr(driver_pptable);
|
||||
|
||||
mutex_init(&smu_table->metrics_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -197,6 +231,30 @@ static int smu_v15_0_8_init_smc_tables(struct smu_context *smu)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int smu_v15_0_8_tables_fini(struct smu_context *smu)
|
||||
{
|
||||
struct smu_table_context *smu_table = &smu->smu_table;
|
||||
|
||||
mutex_destroy(&smu_table->metrics_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smu_v15_0_8_fini_smc_tables(struct smu_context *smu)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = smu_v15_0_8_tables_fini(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = smu_v15_0_fini_smc_tables(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int smu_v15_0_8_init_allowed_features(struct smu_context *smu)
|
||||
{
|
||||
/* pptable will handle the features to enable */
|
||||
|
|
@ -205,11 +263,6 @@ static int smu_v15_0_8_init_allowed_features(struct smu_context *smu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int smu_v15_0_8_set_default_dpm_table(struct smu_context *smu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smu_v15_0_8_setup_pptable(struct smu_context *smu)
|
||||
{
|
||||
struct smu_table_context *table_context = &smu->smu_table;
|
||||
|
|
@ -238,6 +291,173 @@ static int smu_v15_0_8_check_fw_status(struct smu_context *smu)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
static int smu_v15_0_8_get_static_metrics_table(struct smu_context *smu)
|
||||
{
|
||||
struct smu_table_context *smu_table = &smu->smu_table;
|
||||
uint32_t table_size = smu_table->tables[SMU_TABLE_SMU_METRICS].size;
|
||||
struct smu_table *table = &smu_table->driver_table;
|
||||
int ret;
|
||||
|
||||
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetStaticMetricsTable, NULL);
|
||||
if (ret) {
|
||||
dev_err(smu->adev->dev,
|
||||
"Failed to export static metrics table!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
amdgpu_hdp_invalidate(smu->adev, NULL);
|
||||
memcpy(smu_table->metrics_table, table->cpu_addr, table_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smu_v15_0_8_fru_get_product_info(struct smu_context *smu,
|
||||
StaticMetricsTable_t *static_metrics)
|
||||
{
|
||||
struct amdgpu_fru_info *fru_info;
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
|
||||
if (!adev->fru_info) {
|
||||
adev->fru_info = kzalloc(sizeof(*adev->fru_info), GFP_KERNEL);
|
||||
if (!adev->fru_info)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
fru_info = adev->fru_info;
|
||||
strscpy(fru_info->product_number, static_metrics->ProductInfo.ModelNumber,
|
||||
sizeof(fru_info->product_number));
|
||||
strscpy(fru_info->product_name, static_metrics->ProductInfo.Name,
|
||||
sizeof(fru_info->product_name));
|
||||
strscpy(fru_info->serial, static_metrics->ProductInfo.Serial,
|
||||
sizeof(fru_info->serial));
|
||||
strscpy(fru_info->manufacturer_name, static_metrics->ProductInfo.ManufacturerName,
|
||||
sizeof(fru_info->manufacturer_name));
|
||||
strscpy(fru_info->fru_id, static_metrics->ProductInfo.FruId,
|
||||
sizeof(fru_info->fru_id));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void smu_v15_0_8_init_xgmi_data(struct smu_context *smu,
|
||||
StaticMetricsTable_t *static_metrics)
|
||||
{
|
||||
uint16_t max_speed;
|
||||
uint8_t max_width;
|
||||
|
||||
max_width = (uint8_t)static_metrics->MaxXgmiWidth;
|
||||
max_speed = (uint16_t)static_metrics->MaxXgmiBitrate;
|
||||
amgpu_xgmi_set_max_speed_width(smu->adev, max_speed, max_width);
|
||||
}
|
||||
|
||||
static int smu_v15_0_8_set_driver_pptable(struct smu_context *smu)
|
||||
{
|
||||
struct smu_15_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
|
||||
struct smu_table_context *smu_table = &smu->smu_table;
|
||||
StaticMetricsTable_t *static_metrics = (StaticMetricsTable_t *)smu_table->metrics_table;
|
||||
PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable;
|
||||
int ret, i, n;
|
||||
uint32_t table_version;
|
||||
|
||||
if (!pptable->init) {
|
||||
ret = smu_v15_0_8_get_static_metrics_table(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetMetricsVersion,
|
||||
&table_version);
|
||||
if (ret)
|
||||
return ret;
|
||||
smu_table->tables[SMU_TABLE_SMU_METRICS].version =
|
||||
table_version;
|
||||
|
||||
pptable->MaxSocketPowerLimit =
|
||||
SMUQ10_ROUND(static_metrics->MaxSocketPowerLimit);
|
||||
pptable->MaxGfxclkFrequency =
|
||||
SMUQ10_ROUND(static_metrics->MaxGfxclkFrequency);
|
||||
pptable->MinGfxclkFrequency =
|
||||
SMUQ10_ROUND(static_metrics->MinGfxclkFrequency);
|
||||
pptable->MaxFclkFrequency =
|
||||
SMUQ10_ROUND(static_metrics->MaxFclkFrequency);
|
||||
pptable->MinFclkFrequency =
|
||||
SMUQ10_ROUND(static_metrics->MinFclkFrequency);
|
||||
pptable->MaxGl2clkFrequency =
|
||||
SMUQ10_ROUND(static_metrics->MaxGl2clkFrequency);
|
||||
pptable->MinGl2clkFrequency =
|
||||
SMUQ10_ROUND(static_metrics->MinGl2clkFrequency);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(static_metrics->UclkFrequencyTable); ++i)
|
||||
pptable->UclkFrequencyTable[i] =
|
||||
SMUQ10_ROUND(static_metrics->UclkFrequencyTable[i]);
|
||||
|
||||
pptable->SocclkFrequency = SMUQ10_ROUND(static_metrics->SocclkFrequency);
|
||||
pptable->LclkFrequency = SMUQ10_ROUND(static_metrics->LclkFrequency);
|
||||
pptable->VclkFrequency = SMUQ10_ROUND(static_metrics->VclkFrequency);
|
||||
pptable->DclkFrequency = SMUQ10_ROUND(static_metrics->DclkFrequency);
|
||||
|
||||
pptable->CTFLimitMID = SMUQ10_ROUND(static_metrics->CTFLimit_MID);
|
||||
pptable->CTFLimitAID = SMUQ10_ROUND(static_metrics->CTFLimit_AID);
|
||||
pptable->CTFLimitXCD = SMUQ10_ROUND(static_metrics->CTFLimit_XCD);
|
||||
pptable->CTFLimitHBM = SMUQ10_ROUND(static_metrics->CTFLimit_HBM);
|
||||
pptable->ThermalLimitMID = SMUQ10_ROUND(static_metrics->ThermalLimit_MID);
|
||||
pptable->ThermalLimitAID = SMUQ10_ROUND(static_metrics->ThermalLimit_AID);
|
||||
pptable->ThermalLimitXCD = SMUQ10_ROUND(static_metrics->ThermalLimit_XCD);
|
||||
pptable->ThermalLimitHBM = SMUQ10_ROUND(static_metrics->ThermalLimit_HBM);
|
||||
|
||||
/* use MID0 serial number by default */
|
||||
pptable->PublicSerialNumberMID =
|
||||
static_metrics->PublicSerialNumber_MID[0];
|
||||
|
||||
amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_SOC,
|
||||
0, pptable->PublicSerialNumberMID);
|
||||
pptable->PublicSerialNumberAID =
|
||||
static_metrics->PublicSerialNumber_AID[0];
|
||||
pptable->PublicSerialNumberXCD =
|
||||
static_metrics->PublicSerialNumber_XCD[0];
|
||||
n = ARRAY_SIZE(static_metrics->PublicSerialNumber_MID);
|
||||
for (i = 0; i < n; i++) {
|
||||
amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_MID, i,
|
||||
static_metrics->PublicSerialNumber_MID[i]);
|
||||
}
|
||||
n = ARRAY_SIZE(static_metrics->PublicSerialNumber_AID);
|
||||
for (i = 0; i < n; i++) {
|
||||
amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_AID, i,
|
||||
static_metrics->PublicSerialNumber_AID[i]);
|
||||
}
|
||||
n = ARRAY_SIZE(static_metrics->PublicSerialNumber_XCD);
|
||||
for (i = 0; i < n; i++) {
|
||||
amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_XCD, i,
|
||||
static_metrics->PublicSerialNumber_XCD[i]);
|
||||
}
|
||||
|
||||
ret = smu_v15_0_8_fru_get_product_info(smu, static_metrics);
|
||||
if (ret)
|
||||
return ret;
|
||||
pptable->PPT1Max = static_metrics->PPT1Max;
|
||||
pptable->PPT1Min = static_metrics->PPT1Min;
|
||||
pptable->PPT1Default = static_metrics->PPT1Default;
|
||||
|
||||
if (static_metrics->pldmVersion[0] != 0xFFFFFFFF)
|
||||
smu->adev->firmware.pldm_version =
|
||||
static_metrics->pldmVersion[0];
|
||||
dpm_context->board_volt = static_metrics->InputTelemetryVoltageInmV;
|
||||
smu_v15_0_8_init_xgmi_data(smu, static_metrics);
|
||||
pptable->init = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smu_v15_0_8_set_default_dpm_table(struct smu_context *smu)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = smu_v15_0_8_set_driver_pptable(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smu_v15_0_8_irq_process(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
|
|
@ -478,7 +698,7 @@ static const struct pptable_funcs smu_v15_0_8_ppt_funcs = {
|
|||
.set_default_dpm_table = smu_v15_0_8_set_default_dpm_table,
|
||||
.is_dpm_running = smu_v15_0_8_is_dpm_running,
|
||||
.init_smc_tables = smu_v15_0_8_init_smc_tables,
|
||||
.fini_smc_tables = smu_v15_0_fini_smc_tables,
|
||||
.fini_smc_tables = smu_v15_0_8_fini_smc_tables,
|
||||
.init_power = smu_v15_0_init_power,
|
||||
.fini_power = smu_v15_0_fini_power,
|
||||
.check_fw_status = smu_v15_0_8_check_fw_status,
|
||||
|
|
|
|||
|
|
@ -25,4 +25,34 @@
|
|||
|
||||
extern void smu_v15_0_8_set_ppt_funcs(struct smu_context *smu);
|
||||
|
||||
typedef struct {
|
||||
uint32_t MaxSocketPowerLimit;
|
||||
uint32_t MaxGfxclkFrequency;
|
||||
uint32_t MinGfxclkFrequency;
|
||||
uint32_t MaxFclkFrequency;
|
||||
uint32_t MinFclkFrequency;
|
||||
uint32_t MaxGl2clkFrequency;
|
||||
uint32_t MinGl2clkFrequency;
|
||||
uint32_t UclkFrequencyTable[4];
|
||||
uint32_t SocclkFrequency;
|
||||
uint32_t LclkFrequency;
|
||||
uint32_t VclkFrequency;
|
||||
uint32_t DclkFrequency;
|
||||
uint32_t CTFLimitMID;
|
||||
uint32_t CTFLimitAID;
|
||||
uint32_t CTFLimitXCD;
|
||||
uint32_t CTFLimitHBM;
|
||||
uint32_t ThermalLimitMID;
|
||||
uint32_t ThermalLimitAID;
|
||||
uint32_t ThermalLimitXCD;
|
||||
uint32_t ThermalLimitHBM;
|
||||
uint64_t PublicSerialNumberMID;
|
||||
uint64_t PublicSerialNumberAID;
|
||||
uint64_t PublicSerialNumberXCD;
|
||||
uint32_t PPT1Max;
|
||||
uint32_t PPT1Min;
|
||||
uint32_t PPT1Default;
|
||||
bool init;
|
||||
} PPTable_t;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user