[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