[PATCH] drm/amd/pm: bump Navi1x driver if version and related data structures V2
Alex Deucher
alexdeucher at gmail.com
Fri Feb 26 21:34:13 UTC 2021
On Fri, Feb 26, 2021 at 1:09 AM Evan Quan <evan.quan at amd.com> wrote:
>
> New changes were involved for the SmuMetrics structure.
>
> Change-Id: Ib45443db03977ccd18618bcfdfd3574ac13d50d1
> Signed-off-by: Evan Quan <evan.quan at amd.com>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
> ---
> .../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 at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
More information about the amd-gfx
mailing list