On Fri, Feb 26, 2021 at 1:09 AM Evan Quan <evan.quan@xxxxxxx> wrote: > > New changes were involved for the SmuMetrics structure. > > Change-Id: Ib45443db03977ccd18618bcfdfd3574ac13d50d1 > Signed-off-by: Evan Quan <evan.quan@xxxxxxx> Reviewed-by: Alex Deucher <alexander.deucher@xxxxxxx> > --- > .../drm/amd/pm/inc/smu11_driver_if_navi10.h | 98 ++- > drivers/gpu/drm/amd/pm/inc/smu_v11_0.h | 6 +- > .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 609 +++++++++++++++++- > 3 files changed, 673 insertions(+), 40 deletions(-) > > diff --git a/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_navi10.h b/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_navi10.h > index 246d3951a78a..04752ade1016 100644 > --- a/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_navi10.h > +++ b/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_navi10.h > @@ -843,11 +843,15 @@ typedef struct { > uint16_t FanMaximumRpm; > uint16_t FanMinimumPwm; > uint16_t FanTargetTemperature; // Degree Celcius > + uint16_t FanMode; > + uint16_t FanMaxPwm; > + uint16_t FanMinPwm; > + uint16_t FanMaxTemp; // Degree Celcius > + uint16_t FanMinTemp; // Degree Celcius > uint16_t MaxOpTemp; // Degree Celcius > uint16_t FanZeroRpmEnable; > - uint16_t Padding; > > - uint32_t MmHubPadding[8]; // SMU internal use > + uint32_t MmHubPadding[6]; // SMU internal use > > } OverDriveTable_t; > > @@ -880,6 +884,45 @@ typedef struct { > uint8_t Padding8_2; > uint16_t CurrFanSpeed; > > + // Padding - ignore > + uint32_t MmHubPadding[8]; // SMU internal use > +} SmuMetrics_legacy_t; > + > +typedef struct { > + uint16_t CurrClock[PPCLK_COUNT]; > + uint16_t AverageGfxclkFrequencyPostDs; > + uint16_t AverageSocclkFrequency; > + uint16_t AverageUclkFrequencyPostDs; > + uint16_t AverageGfxActivity ; > + uint16_t AverageUclkActivity ; > + uint8_t CurrSocVoltageOffset ; > + uint8_t CurrGfxVoltageOffset ; > + uint8_t CurrMemVidOffset ; > + uint8_t Padding8 ; > + uint16_t AverageSocketPower ; > + uint16_t TemperatureEdge ; > + uint16_t TemperatureHotspot ; > + uint16_t TemperatureMem ; > + uint16_t TemperatureVrGfx ; > + uint16_t TemperatureVrMem0 ; > + uint16_t TemperatureVrMem1 ; > + uint16_t TemperatureVrSoc ; > + uint16_t TemperatureLiquid0 ; > + uint16_t TemperatureLiquid1 ; > + uint16_t TemperaturePlx ; > + uint16_t Padding16 ; > + uint32_t ThrottlerStatus ; > + > + uint8_t LinkDpmLevel; > + uint8_t Padding8_2; > + uint16_t CurrFanSpeed; > + > + uint16_t AverageGfxclkFrequencyPreDs; > + uint16_t AverageUclkFrequencyPreDs; > + uint8_t PcieRate; > + uint8_t PcieWidth; > + uint8_t Padding8_3[2]; > + > // Padding - ignore > uint32_t MmHubPadding[8]; // SMU internal use > } SmuMetrics_t; > @@ -919,10 +962,61 @@ typedef struct { > uint16_t VcnActivityPercentage ; > uint16_t padding16_2; > > + // Padding - ignore > + uint32_t MmHubPadding[8]; // SMU internal use > +} SmuMetrics_NV12_legacy_t; > + > +typedef struct { > + uint16_t CurrClock[PPCLK_COUNT]; > + uint16_t AverageGfxclkFrequencyPostDs; > + uint16_t AverageSocclkFrequency; > + uint16_t AverageUclkFrequencyPostDs; > + uint16_t AverageGfxActivity ; > + uint16_t AverageUclkActivity ; > + uint8_t CurrSocVoltageOffset ; > + uint8_t CurrGfxVoltageOffset ; > + uint8_t CurrMemVidOffset ; > + uint8_t Padding8 ; > + uint16_t AverageSocketPower ; > + uint16_t TemperatureEdge ; > + uint16_t TemperatureHotspot ; > + uint16_t TemperatureMem ; > + uint16_t TemperatureVrGfx ; > + uint16_t TemperatureVrMem0 ; > + uint16_t TemperatureVrMem1 ; > + uint16_t TemperatureVrSoc ; > + uint16_t TemperatureLiquid0 ; > + uint16_t TemperatureLiquid1 ; > + uint16_t TemperaturePlx ; > + uint16_t Padding16 ; > + uint32_t ThrottlerStatus ; > + > + uint8_t LinkDpmLevel; > + uint8_t Padding8_2; > + uint16_t CurrFanSpeed; > + > + uint16_t AverageVclkFrequency ; > + uint16_t AverageDclkFrequency ; > + uint16_t VcnActivityPercentage ; > + uint16_t AverageGfxclkFrequencyPreDs; > + uint16_t AverageUclkFrequencyPreDs; > + uint8_t PcieRate; > + uint8_t PcieWidth; > + > + uint32_t Padding32_1; > + uint64_t EnergyAccumulator; > + > // Padding - ignore > uint32_t MmHubPadding[8]; // SMU internal use > } SmuMetrics_NV12_t; > > +typedef union SmuMetrics { > + SmuMetrics_legacy_t nv10_legacy_metrics; > + SmuMetrics_t nv10_metrics; > + SmuMetrics_NV12_legacy_t nv12_legacy_metrics; > + SmuMetrics_NV12_t nv12_metrics; > +} SmuMetrics_NV1X_t; > + > typedef struct { > uint16_t MinClock; // This is either DCEFCLK or SOCCLK (in MHz) > uint16_t MaxClock; // This is either DCEFCLK or SOCCLK (in MHz) > diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h > index 281835f23f6d..50dd1529b994 100644 > --- a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h > +++ b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h > @@ -27,9 +27,9 @@ > > #define SMU11_DRIVER_IF_VERSION_INV 0xFFFFFFFF > #define SMU11_DRIVER_IF_VERSION_ARCT 0x17 > -#define SMU11_DRIVER_IF_VERSION_NV10 0x36 > -#define SMU11_DRIVER_IF_VERSION_NV12 0x36 > -#define SMU11_DRIVER_IF_VERSION_NV14 0x36 > +#define SMU11_DRIVER_IF_VERSION_NV10 0x37 > +#define SMU11_DRIVER_IF_VERSION_NV12 0x38 > +#define SMU11_DRIVER_IF_VERSION_NV14 0x38 > #define SMU11_DRIVER_IF_VERSION_Sienna_Cichlid 0x3D > #define SMU11_DRIVER_IF_VERSION_Navy_Flounder 0xE > #define SMU11_DRIVER_IF_VERSION_VANGOGH 0x02 > diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c > index ada97d12cb43..ffd37b8a3882 100644 > --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c > +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c > @@ -70,6 +70,8 @@ > FEATURE_MASK(FEATURE_DPM_LINK_BIT) | \ > FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT)) > > +#define SMU_11_0_GFX_BUSY_THRESHOLD 15 > + > static struct cmn2asic_msg_mapping navi10_message_map[SMU_MSG_MAX_COUNT] = { > MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), > MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), > @@ -456,18 +458,13 @@ static int navi10_tables_init(struct smu_context *smu) > { > struct smu_table_context *smu_table = &smu->smu_table; > struct smu_table *tables = smu_table->tables; > - struct amdgpu_device *adev = smu->adev; > > SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t), > PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); > SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t), > PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); > - if (adev->asic_type == CHIP_NAVI12) > - SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_NV12_t), > - PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); > - else > - SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t), > - PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); > + SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_NV1X_t), > + PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); > SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t), > PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); > SMU_TABLE_INIT(tables, SMU_TABLE_OVERDRIVE, sizeof(OverDriveTable_t), > @@ -478,9 +475,8 @@ static int navi10_tables_init(struct smu_context *smu) > sizeof(DpmActivityMonitorCoeffInt_t), PAGE_SIZE, > AMDGPU_GEM_DOMAIN_VRAM); > > - smu_table->metrics_table = kzalloc(adev->asic_type == CHIP_NAVI12 ? > - sizeof(SmuMetrics_NV12_t) : > - sizeof(SmuMetrics_t), GFP_KERNEL); > + smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_NV1X_t), > + GFP_KERNEL); > if (!smu_table->metrics_table) > goto err0_out; > smu_table->metrics_time = 0; > @@ -504,17 +500,200 @@ static int navi10_tables_init(struct smu_context *smu) > return -ENOMEM; > } > > +static int navi10_get_legacy_smu_metrics_data(struct smu_context *smu, > + MetricsMember_t member, > + uint32_t *value) > +{ > + struct smu_table_context *smu_table= &smu->smu_table; > + SmuMetrics_legacy_t *metrics = > + (SmuMetrics_legacy_t *)smu_table->metrics_table; > + int ret = 0; > + > + mutex_lock(&smu->metrics_lock); > + > + ret = smu_cmn_get_metrics_table_locked(smu, > + NULL, > + false); > + if (ret) { > + mutex_unlock(&smu->metrics_lock); > + return ret; > + } > + > + switch (member) { > + case METRICS_CURR_GFXCLK: > + *value = metrics->CurrClock[PPCLK_GFXCLK]; > + break; > + case METRICS_CURR_SOCCLK: > + *value = metrics->CurrClock[PPCLK_SOCCLK]; > + break; > + case METRICS_CURR_UCLK: > + *value = metrics->CurrClock[PPCLK_UCLK]; > + break; > + case METRICS_CURR_VCLK: > + *value = metrics->CurrClock[PPCLK_VCLK]; > + break; > + case METRICS_CURR_DCLK: > + *value = metrics->CurrClock[PPCLK_DCLK]; > + break; > + case METRICS_CURR_DCEFCLK: > + *value = metrics->CurrClock[PPCLK_DCEFCLK]; > + break; > + case METRICS_AVERAGE_GFXCLK: > + *value = metrics->AverageGfxclkFrequency; > + break; > + case METRICS_AVERAGE_SOCCLK: > + *value = metrics->AverageSocclkFrequency; > + break; > + case METRICS_AVERAGE_UCLK: > + *value = metrics->AverageUclkFrequency; > + break; > + case METRICS_AVERAGE_GFXACTIVITY: > + *value = metrics->AverageGfxActivity; > + break; > + case METRICS_AVERAGE_MEMACTIVITY: > + *value = metrics->AverageUclkActivity; > + break; > + case METRICS_AVERAGE_SOCKETPOWER: > + *value = metrics->AverageSocketPower << 8; > + break; > + case METRICS_TEMPERATURE_EDGE: > + *value = metrics->TemperatureEdge * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_TEMPERATURE_HOTSPOT: > + *value = metrics->TemperatureHotspot * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_TEMPERATURE_MEM: > + *value = metrics->TemperatureMem * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_TEMPERATURE_VRGFX: > + *value = metrics->TemperatureVrGfx * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_TEMPERATURE_VRSOC: > + *value = metrics->TemperatureVrSoc * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_THROTTLER_STATUS: > + *value = metrics->ThrottlerStatus; > + break; > + case METRICS_CURR_FANSPEED: > + *value = metrics->CurrFanSpeed; > + break; > + default: > + *value = UINT_MAX; > + break; > + } > + > + mutex_unlock(&smu->metrics_lock); > + > + return ret; > +} > + > static int navi10_get_smu_metrics_data(struct smu_context *smu, > MetricsMember_t member, > uint32_t *value) > { > struct smu_table_context *smu_table= &smu->smu_table; > - /* > - * This works for NV12 also. As although NV12 uses a different > - * SmuMetrics structure from other NV1X ASICs, they share the > - * same offsets for the heading parts(those members used here). > - */ > - SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; > + SmuMetrics_t *metrics = > + (SmuMetrics_t *)smu_table->metrics_table; > + int ret = 0; > + > + mutex_lock(&smu->metrics_lock); > + > + ret = smu_cmn_get_metrics_table_locked(smu, > + NULL, > + false); > + if (ret) { > + mutex_unlock(&smu->metrics_lock); > + return ret; > + } > + > + switch (member) { > + case METRICS_CURR_GFXCLK: > + *value = metrics->CurrClock[PPCLK_GFXCLK]; > + break; > + case METRICS_CURR_SOCCLK: > + *value = metrics->CurrClock[PPCLK_SOCCLK]; > + break; > + case METRICS_CURR_UCLK: > + *value = metrics->CurrClock[PPCLK_UCLK]; > + break; > + case METRICS_CURR_VCLK: > + *value = metrics->CurrClock[PPCLK_VCLK]; > + break; > + case METRICS_CURR_DCLK: > + *value = metrics->CurrClock[PPCLK_DCLK]; > + break; > + case METRICS_CURR_DCEFCLK: > + *value = metrics->CurrClock[PPCLK_DCEFCLK]; > + break; > + case METRICS_AVERAGE_GFXCLK: > + if (metrics->AverageGfxActivity > SMU_11_0_GFX_BUSY_THRESHOLD) > + *value = metrics->AverageGfxclkFrequencyPreDs; > + else > + *value = metrics->AverageGfxclkFrequencyPostDs; > + break; > + case METRICS_AVERAGE_SOCCLK: > + *value = metrics->AverageSocclkFrequency; > + break; > + case METRICS_AVERAGE_UCLK: > + *value = metrics->AverageUclkFrequencyPostDs; > + break; > + case METRICS_AVERAGE_GFXACTIVITY: > + *value = metrics->AverageGfxActivity; > + break; > + case METRICS_AVERAGE_MEMACTIVITY: > + *value = metrics->AverageUclkActivity; > + break; > + case METRICS_AVERAGE_SOCKETPOWER: > + *value = metrics->AverageSocketPower << 8; > + break; > + case METRICS_TEMPERATURE_EDGE: > + *value = metrics->TemperatureEdge * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_TEMPERATURE_HOTSPOT: > + *value = metrics->TemperatureHotspot * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_TEMPERATURE_MEM: > + *value = metrics->TemperatureMem * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_TEMPERATURE_VRGFX: > + *value = metrics->TemperatureVrGfx * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_TEMPERATURE_VRSOC: > + *value = metrics->TemperatureVrSoc * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_THROTTLER_STATUS: > + *value = metrics->ThrottlerStatus; > + break; > + case METRICS_CURR_FANSPEED: > + *value = metrics->CurrFanSpeed; > + break; > + default: > + *value = UINT_MAX; > + break; > + } > + > + mutex_unlock(&smu->metrics_lock); > + > + return ret; > +} > + > +static int navi12_get_legacy_smu_metrics_data(struct smu_context *smu, > + MetricsMember_t member, > + uint32_t *value) > +{ > + struct smu_table_context *smu_table= &smu->smu_table; > + SmuMetrics_NV12_legacy_t *metrics = > + (SmuMetrics_NV12_legacy_t *)smu_table->metrics_table; > int ret = 0; > > mutex_lock(&smu->metrics_lock); > @@ -600,6 +779,136 @@ static int navi10_get_smu_metrics_data(struct smu_context *smu, > return ret; > } > > +static int navi12_get_smu_metrics_data(struct smu_context *smu, > + MetricsMember_t member, > + uint32_t *value) > +{ > + struct smu_table_context *smu_table= &smu->smu_table; > + SmuMetrics_NV12_t *metrics = > + (SmuMetrics_NV12_t *)smu_table->metrics_table; > + int ret = 0; > + > + mutex_lock(&smu->metrics_lock); > + > + ret = smu_cmn_get_metrics_table_locked(smu, > + NULL, > + false); > + if (ret) { > + mutex_unlock(&smu->metrics_lock); > + return ret; > + } > + > + switch (member) { > + case METRICS_CURR_GFXCLK: > + *value = metrics->CurrClock[PPCLK_GFXCLK]; > + break; > + case METRICS_CURR_SOCCLK: > + *value = metrics->CurrClock[PPCLK_SOCCLK]; > + break; > + case METRICS_CURR_UCLK: > + *value = metrics->CurrClock[PPCLK_UCLK]; > + break; > + case METRICS_CURR_VCLK: > + *value = metrics->CurrClock[PPCLK_VCLK]; > + break; > + case METRICS_CURR_DCLK: > + *value = metrics->CurrClock[PPCLK_DCLK]; > + break; > + case METRICS_CURR_DCEFCLK: > + *value = metrics->CurrClock[PPCLK_DCEFCLK]; > + break; > + case METRICS_AVERAGE_GFXCLK: > + if (metrics->AverageGfxActivity > SMU_11_0_GFX_BUSY_THRESHOLD) > + *value = metrics->AverageGfxclkFrequencyPreDs; > + else > + *value = metrics->AverageGfxclkFrequencyPostDs; > + break; > + case METRICS_AVERAGE_SOCCLK: > + *value = metrics->AverageSocclkFrequency; > + break; > + case METRICS_AVERAGE_UCLK: > + *value = metrics->AverageUclkFrequencyPostDs; > + break; > + case METRICS_AVERAGE_GFXACTIVITY: > + *value = metrics->AverageGfxActivity; > + break; > + case METRICS_AVERAGE_MEMACTIVITY: > + *value = metrics->AverageUclkActivity; > + break; > + case METRICS_AVERAGE_SOCKETPOWER: > + *value = metrics->AverageSocketPower << 8; > + break; > + case METRICS_TEMPERATURE_EDGE: > + *value = metrics->TemperatureEdge * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_TEMPERATURE_HOTSPOT: > + *value = metrics->TemperatureHotspot * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_TEMPERATURE_MEM: > + *value = metrics->TemperatureMem * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_TEMPERATURE_VRGFX: > + *value = metrics->TemperatureVrGfx * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_TEMPERATURE_VRSOC: > + *value = metrics->TemperatureVrSoc * > + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; > + break; > + case METRICS_THROTTLER_STATUS: > + *value = metrics->ThrottlerStatus; > + break; > + case METRICS_CURR_FANSPEED: > + *value = metrics->CurrFanSpeed; > + break; > + default: > + *value = UINT_MAX; > + break; > + } > + > + mutex_unlock(&smu->metrics_lock); > + > + return ret; > +} > + > +static int navi1x_get_smu_metrics_data(struct smu_context *smu, > + MetricsMember_t member, > + uint32_t *value) > +{ > + struct amdgpu_device *adev = smu->adev; > + uint32_t smu_version; > + int ret = 0; > + > + ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); > + if (ret) { > + dev_err(adev->dev, "Failed to get smu version!\n"); > + return ret; > + } > + > + switch (adev->asic_type) { > + case CHIP_NAVI12: > + if (smu_version > 0x00341C00) > + ret = navi12_get_smu_metrics_data(smu, member, value); > + else > + ret = navi12_get_legacy_smu_metrics_data(smu, member, value); > + break; > + case CHIP_NAVI10: > + case CHIP_NAVI14: > + default: > + if (((adev->asic_type == CHIP_NAVI14) && smu_version > 0x00351F00) || > + ((adev->asic_type == CHIP_NAVI10) && smu_version > 0x002A3B00)) > + ret = navi10_get_smu_metrics_data(smu, member, value); > + else > + ret = navi10_get_legacy_smu_metrics_data(smu, member, value); > + break; > + } > + > + return ret; > +} > + > static int navi10_allocate_dpm_context(struct smu_context *smu) > { > struct smu_dpm_context *smu_dpm = &smu->smu_dpm; > @@ -880,7 +1189,7 @@ static int navi10_get_current_clk_freq_by_table(struct smu_context *smu, > return -EINVAL; > } > > - return navi10_get_smu_metrics_data(smu, > + return navi1x_get_smu_metrics_data(smu, > member_type, > value); > } > @@ -1327,7 +1636,7 @@ static int navi10_get_fan_speed_rpm(struct smu_context *smu, > > switch (smu_v11_0_get_fan_control_mode(smu)) { > case AMD_FAN_CTRL_AUTO: > - ret = navi10_get_smu_metrics_data(smu, > + ret = navi1x_get_smu_metrics_data(smu, > METRICS_CURR_FANSPEED, > speed); > break; > @@ -1644,37 +1953,37 @@ static int navi10_read_sensor(struct smu_context *smu, > *size = 4; > break; > case AMDGPU_PP_SENSOR_MEM_LOAD: > - ret = navi10_get_smu_metrics_data(smu, > + ret = navi1x_get_smu_metrics_data(smu, > METRICS_AVERAGE_MEMACTIVITY, > (uint32_t *)data); > *size = 4; > break; > case AMDGPU_PP_SENSOR_GPU_LOAD: > - ret = navi10_get_smu_metrics_data(smu, > + ret = navi1x_get_smu_metrics_data(smu, > METRICS_AVERAGE_GFXACTIVITY, > (uint32_t *)data); > *size = 4; > break; > case AMDGPU_PP_SENSOR_GPU_POWER: > - ret = navi10_get_smu_metrics_data(smu, > + ret = navi1x_get_smu_metrics_data(smu, > METRICS_AVERAGE_SOCKETPOWER, > (uint32_t *)data); > *size = 4; > break; > case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: > - ret = navi10_get_smu_metrics_data(smu, > + ret = navi1x_get_smu_metrics_data(smu, > METRICS_TEMPERATURE_HOTSPOT, > (uint32_t *)data); > *size = 4; > break; > case AMDGPU_PP_SENSOR_EDGE_TEMP: > - ret = navi10_get_smu_metrics_data(smu, > + ret = navi1x_get_smu_metrics_data(smu, > METRICS_TEMPERATURE_EDGE, > (uint32_t *)data); > *size = 4; > break; > case AMDGPU_PP_SENSOR_MEM_TEMP: > - ret = navi10_get_smu_metrics_data(smu, > + ret = navi1x_get_smu_metrics_data(smu, > METRICS_TEMPERATURE_MEM, > (uint32_t *)data); > *size = 4; > @@ -1685,7 +1994,7 @@ static int navi10_read_sensor(struct smu_context *smu, > *size = 4; > break; > case AMDGPU_PP_SENSOR_GFX_SCLK: > - ret = navi10_get_smu_metrics_data(smu, METRICS_AVERAGE_GFXCLK, (uint32_t *)data); > + ret = navi1x_get_smu_metrics_data(smu, METRICS_AVERAGE_GFXCLK, (uint32_t *)data); > *(uint32_t *)data *= 100; > *size = 4; > break; > @@ -2289,14 +2598,75 @@ static int navi10_run_umc_cdr_workaround(struct smu_context *smu) > return 0; > } > > +static ssize_t navi10_get_legacy_gpu_metrics(struct smu_context *smu, > + void **table) > +{ > + struct smu_table_context *smu_table = &smu->smu_table; > + struct gpu_metrics_v1_0 *gpu_metrics = > + (struct gpu_metrics_v1_0 *)smu_table->gpu_metrics_table; > + SmuMetrics_legacy_t metrics; > + int ret = 0; > + > + mutex_lock(&smu->metrics_lock); > + > + ret = smu_cmn_get_metrics_table_locked(smu, > + NULL, > + true); > + if (ret) { > + mutex_unlock(&smu->metrics_lock); > + return ret; > + } > + > + memcpy(&metrics, smu_table->metrics_table, sizeof(SmuMetrics_legacy_t)); > + > + mutex_unlock(&smu->metrics_lock); > + > + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 0); > + > + gpu_metrics->temperature_edge = metrics.TemperatureEdge; > + gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot; > + gpu_metrics->temperature_mem = metrics.TemperatureMem; > + gpu_metrics->temperature_vrgfx = metrics.TemperatureVrGfx; > + gpu_metrics->temperature_vrsoc = metrics.TemperatureVrSoc; > + gpu_metrics->temperature_vrmem = metrics.TemperatureVrMem0; > + > + gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity; > + gpu_metrics->average_umc_activity = metrics.AverageUclkActivity; > + > + gpu_metrics->average_socket_power = metrics.AverageSocketPower; > + > + gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequency; > + gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency; > + gpu_metrics->average_uclk_frequency = metrics.AverageUclkFrequency; > + > + gpu_metrics->current_gfxclk = metrics.CurrClock[PPCLK_GFXCLK]; > + gpu_metrics->current_socclk = metrics.CurrClock[PPCLK_SOCCLK]; > + gpu_metrics->current_uclk = metrics.CurrClock[PPCLK_UCLK]; > + gpu_metrics->current_vclk0 = metrics.CurrClock[PPCLK_VCLK]; > + gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK]; > + > + gpu_metrics->throttle_status = metrics.ThrottlerStatus; > + > + gpu_metrics->current_fan_speed = metrics.CurrFanSpeed; > + > + gpu_metrics->pcie_link_width = > + smu_v11_0_get_current_pcie_link_width(smu); > + gpu_metrics->pcie_link_speed = > + smu_v11_0_get_current_pcie_link_speed(smu); > + > + gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); > + > + *table = (void *)gpu_metrics; > + > + return sizeof(struct gpu_metrics_v1_0); > +} > + > static ssize_t navi10_get_gpu_metrics(struct smu_context *smu, > void **table) > { > struct smu_table_context *smu_table = &smu->smu_table; > struct gpu_metrics_v1_0 *gpu_metrics = > (struct gpu_metrics_v1_0 *)smu_table->gpu_metrics_table; > - struct amdgpu_device *adev = smu->adev; > - SmuMetrics_NV12_t nv12_metrics = { 0 }; > SmuMetrics_t metrics; > int ret = 0; > > @@ -2311,8 +2681,73 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu, > } > > memcpy(&metrics, smu_table->metrics_table, sizeof(SmuMetrics_t)); > - if (adev->asic_type == CHIP_NAVI12) > - memcpy(&nv12_metrics, smu_table->metrics_table, sizeof(SmuMetrics_NV12_t)); > + > + mutex_unlock(&smu->metrics_lock); > + > + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 0); > + > + gpu_metrics->temperature_edge = metrics.TemperatureEdge; > + gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot; > + gpu_metrics->temperature_mem = metrics.TemperatureMem; > + gpu_metrics->temperature_vrgfx = metrics.TemperatureVrGfx; > + gpu_metrics->temperature_vrsoc = metrics.TemperatureVrSoc; > + gpu_metrics->temperature_vrmem = metrics.TemperatureVrMem0; > + > + gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity; > + gpu_metrics->average_umc_activity = metrics.AverageUclkActivity; > + > + gpu_metrics->average_socket_power = metrics.AverageSocketPower; > + > + if (metrics.AverageGfxActivity > SMU_11_0_GFX_BUSY_THRESHOLD) > + gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequencyPreDs; > + else > + gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequencyPostDs; > + > + gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency; > + gpu_metrics->average_uclk_frequency = metrics.AverageUclkFrequencyPostDs; > + > + gpu_metrics->current_gfxclk = metrics.CurrClock[PPCLK_GFXCLK]; > + gpu_metrics->current_socclk = metrics.CurrClock[PPCLK_SOCCLK]; > + gpu_metrics->current_uclk = metrics.CurrClock[PPCLK_UCLK]; > + gpu_metrics->current_vclk0 = metrics.CurrClock[PPCLK_VCLK]; > + gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK]; > + > + gpu_metrics->throttle_status = metrics.ThrottlerStatus; > + > + gpu_metrics->current_fan_speed = metrics.CurrFanSpeed; > + > + gpu_metrics->pcie_link_width = > + smu_v11_0_get_current_pcie_link_width(smu); > + gpu_metrics->pcie_link_speed = > + smu_v11_0_get_current_pcie_link_speed(smu); > + > + gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); > + > + *table = (void *)gpu_metrics; > + > + return sizeof(struct gpu_metrics_v1_0); > +} > + > +static ssize_t navi12_get_legacy_gpu_metrics(struct smu_context *smu, > + void **table) > +{ > + struct smu_table_context *smu_table = &smu->smu_table; > + struct gpu_metrics_v1_0 *gpu_metrics = > + (struct gpu_metrics_v1_0 *)smu_table->gpu_metrics_table; > + SmuMetrics_NV12_legacy_t metrics; > + int ret = 0; > + > + mutex_lock(&smu->metrics_lock); > + > + ret = smu_cmn_get_metrics_table_locked(smu, > + NULL, > + true); > + if (ret) { > + mutex_unlock(&smu->metrics_lock); > + return ret; > + } > + > + memcpy(&metrics, smu_table->metrics_table, sizeof(SmuMetrics_NV12_legacy_t)); > > mutex_unlock(&smu->metrics_lock); > > @@ -2334,13 +2769,83 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu, > gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency; > gpu_metrics->average_uclk_frequency = metrics.AverageUclkFrequency; > > - if (adev->asic_type == CHIP_NAVI12) { > - gpu_metrics->energy_accumulator = nv12_metrics.EnergyAccumulator; > - gpu_metrics->average_vclk0_frequency = nv12_metrics.AverageVclkFrequency; > - gpu_metrics->average_dclk0_frequency = nv12_metrics.AverageDclkFrequency; > - gpu_metrics->average_mm_activity = nv12_metrics.VcnActivityPercentage; > + gpu_metrics->energy_accumulator = metrics.EnergyAccumulator; > + gpu_metrics->average_vclk0_frequency = metrics.AverageVclkFrequency; > + gpu_metrics->average_dclk0_frequency = metrics.AverageDclkFrequency; > + gpu_metrics->average_mm_activity = metrics.VcnActivityPercentage; > + > + gpu_metrics->current_gfxclk = metrics.CurrClock[PPCLK_GFXCLK]; > + gpu_metrics->current_socclk = metrics.CurrClock[PPCLK_SOCCLK]; > + gpu_metrics->current_uclk = metrics.CurrClock[PPCLK_UCLK]; > + gpu_metrics->current_vclk0 = metrics.CurrClock[PPCLK_VCLK]; > + gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK]; > + > + gpu_metrics->throttle_status = metrics.ThrottlerStatus; > + > + gpu_metrics->current_fan_speed = metrics.CurrFanSpeed; > + > + gpu_metrics->pcie_link_width = > + smu_v11_0_get_current_pcie_link_width(smu); > + gpu_metrics->pcie_link_speed = > + smu_v11_0_get_current_pcie_link_speed(smu); > + > + gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); > + > + *table = (void *)gpu_metrics; > + > + return sizeof(struct gpu_metrics_v1_0); > +} > + > +static ssize_t navi12_get_gpu_metrics(struct smu_context *smu, > + void **table) > +{ > + struct smu_table_context *smu_table = &smu->smu_table; > + struct gpu_metrics_v1_0 *gpu_metrics = > + (struct gpu_metrics_v1_0 *)smu_table->gpu_metrics_table; > + SmuMetrics_NV12_t metrics; > + int ret = 0; > + > + mutex_lock(&smu->metrics_lock); > + > + ret = smu_cmn_get_metrics_table_locked(smu, > + NULL, > + true); > + if (ret) { > + mutex_unlock(&smu->metrics_lock); > + return ret; > } > > + memcpy(&metrics, smu_table->metrics_table, sizeof(SmuMetrics_NV12_t)); > + > + mutex_unlock(&smu->metrics_lock); > + > + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 0); > + > + gpu_metrics->temperature_edge = metrics.TemperatureEdge; > + gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot; > + gpu_metrics->temperature_mem = metrics.TemperatureMem; > + gpu_metrics->temperature_vrgfx = metrics.TemperatureVrGfx; > + gpu_metrics->temperature_vrsoc = metrics.TemperatureVrSoc; > + gpu_metrics->temperature_vrmem = metrics.TemperatureVrMem0; > + > + gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity; > + gpu_metrics->average_umc_activity = metrics.AverageUclkActivity; > + > + gpu_metrics->average_socket_power = metrics.AverageSocketPower; > + > + if (metrics.AverageGfxActivity > SMU_11_0_GFX_BUSY_THRESHOLD) > + gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequencyPreDs; > + else > + gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequencyPostDs; > + > + gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency; > + gpu_metrics->average_uclk_frequency = metrics.AverageUclkFrequencyPostDs; > + > + gpu_metrics->energy_accumulator = metrics.EnergyAccumulator; > + gpu_metrics->average_vclk0_frequency = metrics.AverageVclkFrequency; > + gpu_metrics->average_dclk0_frequency = metrics.AverageDclkFrequency; > + gpu_metrics->average_mm_activity = metrics.VcnActivityPercentage; > + > gpu_metrics->current_gfxclk = metrics.CurrClock[PPCLK_GFXCLK]; > gpu_metrics->current_socclk = metrics.CurrClock[PPCLK_SOCCLK]; > gpu_metrics->current_uclk = metrics.CurrClock[PPCLK_UCLK]; > @@ -2363,6 +2868,40 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu, > return sizeof(struct gpu_metrics_v1_0); > } > > +static ssize_t navi1x_get_gpu_metrics(struct smu_context *smu, > + void **table) > +{ > + struct amdgpu_device *adev = smu->adev; > + uint32_t smu_version; > + int ret = 0; > + > + ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); > + if (ret) { > + dev_err(adev->dev, "Failed to get smu version!\n"); > + return ret; > + } > + > + switch (adev->asic_type) { > + case CHIP_NAVI12: > + if (smu_version > 0x00341C00) > + ret = navi12_get_gpu_metrics(smu, table); > + else > + ret = navi12_get_legacy_gpu_metrics(smu, table); > + break; > + case CHIP_NAVI10: > + case CHIP_NAVI14: > + default: > + if (((adev->asic_type == CHIP_NAVI14) && smu_version > 0x00351F00) || > + ((adev->asic_type == CHIP_NAVI10) && smu_version > 0x002A3B00)) > + ret = navi10_get_gpu_metrics(smu, table); > + else > + ret =navi10_get_legacy_gpu_metrics(smu, table); > + break; > + } > + > + return ret; > +} > + > static int navi10_enable_mgpu_fan_boost(struct smu_context *smu) > { > struct amdgpu_device *adev = smu->adev; > @@ -2493,7 +3032,7 @@ static const struct pptable_funcs navi10_ppt_funcs = { > .set_power_source = smu_v11_0_set_power_source, > .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, > .set_pp_feature_mask = smu_cmn_set_pp_feature_mask, > - .get_gpu_metrics = navi10_get_gpu_metrics, > + .get_gpu_metrics = navi1x_get_gpu_metrics, > .enable_mgpu_fan_boost = navi10_enable_mgpu_fan_boost, > .gfx_ulv_control = smu_v11_0_gfx_ulv_control, > .deep_sleep_control = smu_v11_0_deep_sleep_control, > -- > 2.29.0 > > _______________________________________________ > amd-gfx mailing list > amd-gfx@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/amd-gfx _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx