[AMD Official Use Only]

Ping..

> -----Original Message-----
> From: Quan, Evan <[email protected]>
> Sent: Friday, June 25, 2021 4:12 PM
> To: [email protected]
> Cc: Deucher, Alexander <[email protected]>; Quan, Evan
> <[email protected]>
> Subject: [PATCH 1/2] drm/amd/pm: update the gpu metrics data retrieving
> for Sienna Cichlid
> 
> Due to the structure layout change: "uint32_t ThrottlerStatus" -> "
> uint8_t  ThrottlingPercentage[THROTTLER_COUNT]".
> 
> Change-Id: Id5c148b0584d972ae73fb9d7347a312944cec13d
> Signed-off-by: Evan Quan <[email protected]>
> ---
>  .../pm/inc/smu11_driver_if_sienna_cichlid.h   |  63 ++++-
>  .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c   | 234 ++++++++++++------
>  2 files changed, 222 insertions(+), 75 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_sienna_cichlid.h
> b/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_sienna_cichlid.h
> index 61c87c39be80..0b916a1933df 100644
> --- a/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_sienna_cichlid.h
> +++ b/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_sienna_cichlid.h
> @@ -211,6 +211,7 @@ typedef enum {
>  #define THROTTLER_FIT_BIT          17
>  #define THROTTLER_PPM_BIT          18
>  #define THROTTLER_APCC_BIT         19
> +#define THROTTLER_COUNT            20
> 
>  // FW DState Features Control Bits
>  // FW DState Features Control Bits
> @@ -1406,7 +1407,67 @@ typedef struct {
>  } SmuMetrics_t;
> 
>  typedef struct {
> -  SmuMetrics_t SmuMetrics;
> +  uint32_t CurrClock[PPCLK_COUNT];
> +
> +  uint16_t AverageGfxclkFrequencyPreDs;  uint16_t
> + AverageGfxclkFrequencyPostDs;  uint16_t AverageFclkFrequencyPreDs;
> + uint16_t AverageFclkFrequencyPostDs;  uint16_t
> + AverageUclkFrequencyPreDs  ;  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 AccCnt                ;
> +  uint8_t  ThrottlingPercentage[THROTTLER_COUNT];
> +
> +
> +  uint8_t  LinkDpmLevel;
> +  uint8_t  CurrFanPwm;
> +  uint16_t CurrFanSpeed;
> +
> +  //BACO metrics, PMFW-1721
> +  //metrics for D3hot entry/exit and driver ARM msgs  uint8_t
> + D3HotEntryCountPerMode[D3HOT_SEQUENCE_COUNT];
> +  uint8_t D3HotExitCountPerMode[D3HOT_SEQUENCE_COUNT];
> +  uint8_t ArmMsgReceivedCountPerMode[D3HOT_SEQUENCE_COUNT];
> +
> +  //PMFW-4362
> +  uint32_t EnergyAccumulator;
> +  uint16_t AverageVclk0Frequency  ;
> +  uint16_t AverageDclk0Frequency  ;
> +  uint16_t AverageVclk1Frequency  ;
> +  uint16_t AverageDclk1Frequency  ;
> +  uint16_t VcnActivityPercentage  ; //place holder, David N. to provide full
> sequence
> +  uint8_t  PcieRate               ;
> +  uint8_t  PcieWidth              ;
> +  uint16_t AverageGfxclkFrequencyTarget;  uint16_t Padding16_2;
> +
> +} SmuMetrics_V2_t;
> +
> +typedef struct {
> +  union {
> +    SmuMetrics_t SmuMetrics;
> +    SmuMetrics_V2_t SmuMetrics_V2;
> +  };
>    uint32_t Spare[1];
> 
>    // Padding - ignore
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
> b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
> index 0c3407025eb2..f882c6756bf0 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
> @@ -80,6 +80,13 @@
>               (*member) = (smu->smu_table.driver_pptable +
> offsetof(PPTable_t, field));\  } while(0)
> 
> +#define GET_METRICS_MEMBER(field, member) do { \
> +     if ((smu->adev->asic_type == CHIP_SIENNA_CICHLID) && (smu-
> >smc_fw_version >= 0x3A4300)) \
> +             (*member) = ((void *)(&(((SmuMetricsExternal_t *)(smu-
> >smu_table.metrics_table))->SmuMetrics_V2)) + offsetof(SmuMetrics_V2_t,
> field)); \
> +     else \
> +             (*member) = ((void *)(&(((SmuMetricsExternal_t
> +*)(smu->smu_table.metrics_table))->SmuMetrics)) +
> +offsetof(SmuMetrics_t, field)); \ } while(0)
> +
>  static int get_table_size(struct smu_context *smu)  {
>       if (smu->adev->asic_type == CHIP_BEIGE_GOBY) @@ -489,13
> +496,33 @@ static int sienna_cichlid_tables_init(struct smu_context *smu)
>       return -ENOMEM;
>  }
> 
> +static uint32_t sienna_cichlid_get_throttler_status_locked(struct
> +smu_context *smu) {
> +     struct smu_table_context *smu_table= &smu->smu_table;
> +     SmuMetricsExternal_t *metrics_ext =
> +             (SmuMetricsExternal_t *)(smu_table->metrics_table);
> +     uint32_t throttler_status = 0;
> +     int i;
> +
> +     if ((smu->adev->asic_type == CHIP_SIENNA_CICHLID) &&
> +          (smu->smc_fw_version >= 0x3A4300)) {
> +             for (i = 0; i < THROTTLER_COUNT; i++) {
> +                     if (metrics_ext-
> >SmuMetrics_V2.ThrottlingPercentage[i])
> +                             throttler_status |= 1U << i;
> +             }
> +     } else {
> +             throttler_status = metrics_ext->SmuMetrics.ThrottlerStatus;
> +     }
> +
> +     return throttler_status;
> +}
> +
>  static int sienna_cichlid_get_smu_metrics_data(struct smu_context *smu,
>                                              MetricsMember_t member,
>                                              uint32_t *value)
>  {
> -     struct smu_table_context *smu_table= &smu->smu_table;
> -     SmuMetrics_t *metrics =
> -             &(((SmuMetricsExternal_t *)(smu_table->metrics_table))-
> >SmuMetrics);
> +     uint32_t *data_u32;
> +     uint16_t *data_u16;
>       int ret = 0;
> 
>       mutex_lock(&smu->metrics_lock);
> @@ -510,78 +537,100 @@ static int
> sienna_cichlid_get_smu_metrics_data(struct smu_context *smu,
> 
>       switch (member) {
>       case METRICS_CURR_GFXCLK:
> -             *value = metrics->CurrClock[PPCLK_GFXCLK];
> +             GET_METRICS_MEMBER(CurrClock, &data_u32);
> +             *value = data_u32[PPCLK_GFXCLK];
>               break;
>       case METRICS_CURR_SOCCLK:
> -             *value = metrics->CurrClock[PPCLK_SOCCLK];
> +             GET_METRICS_MEMBER(CurrClock, &data_u32);
> +             *value = data_u32[PPCLK_SOCCLK];
>               break;
>       case METRICS_CURR_UCLK:
> -             *value = metrics->CurrClock[PPCLK_UCLK];
> +             GET_METRICS_MEMBER(CurrClock, &data_u32);
> +             *value = data_u32[PPCLK_UCLK];
>               break;
>       case METRICS_CURR_VCLK:
> -             *value = metrics->CurrClock[PPCLK_VCLK_0];
> +             GET_METRICS_MEMBER(CurrClock, &data_u32);
> +             *value = data_u32[PPCLK_VCLK_0];
>               break;
>       case METRICS_CURR_VCLK1:
> -             *value = metrics->CurrClock[PPCLK_VCLK_1];
> +             GET_METRICS_MEMBER(CurrClock, &data_u32);
> +             *value = data_u32[PPCLK_VCLK_1];
>               break;
>       case METRICS_CURR_DCLK:
> -             *value = metrics->CurrClock[PPCLK_DCLK_0];
> +             GET_METRICS_MEMBER(CurrClock, &data_u32);
> +             *value = data_u32[PPCLK_DCLK_0];
>               break;
>       case METRICS_CURR_DCLK1:
> -             *value = metrics->CurrClock[PPCLK_DCLK_1];
> +             GET_METRICS_MEMBER(CurrClock, &data_u32);
> +             *value = data_u32[PPCLK_DCLK_1];
>               break;
>       case METRICS_CURR_DCEFCLK:
> -             *value = metrics->CurrClock[PPCLK_DCEFCLK];
> +             GET_METRICS_MEMBER(CurrClock, &data_u32);
> +             *value = data_u32[PPCLK_DCEFCLK];
>               break;
>       case METRICS_CURR_FCLK:
> -             *value = metrics->CurrClock[PPCLK_FCLK];
> +             GET_METRICS_MEMBER(CurrClock, &data_u32);
> +             *value = data_u32[PPCLK_FCLK];
>               break;
>       case METRICS_AVERAGE_GFXCLK:
> -             if (metrics->AverageGfxActivity <=
> SMU_11_0_7_GFX_BUSY_THRESHOLD)
> -                     *value = metrics->AverageGfxclkFrequencyPostDs;
> +             GET_METRICS_MEMBER(AverageGfxActivity, &data_u16);
> +             if (*data_u16 <= SMU_11_0_7_GFX_BUSY_THRESHOLD)
> +
>       GET_METRICS_MEMBER(AverageGfxclkFrequencyPostDs,
> &data_u16);
>               else
> -                     *value = metrics->AverageGfxclkFrequencyPreDs;
> +
>       GET_METRICS_MEMBER(AverageGfxclkFrequencyPreDs,
> &data_u16);
> +             *value = *data_u16;
>               break;
>       case METRICS_AVERAGE_FCLK:
> -             *value = metrics->AverageFclkFrequencyPostDs;
> +             GET_METRICS_MEMBER(AverageFclkFrequencyPostDs,
> &data_u16);
> +             *value = *data_u16;
>               break;
>       case METRICS_AVERAGE_UCLK:
> -             *value = metrics->AverageUclkFrequencyPostDs;
> +             GET_METRICS_MEMBER(AverageUclkFrequencyPostDs,
> &data_u16);
> +             *value = *data_u16;
>               break;
>       case METRICS_AVERAGE_GFXACTIVITY:
> -             *value = metrics->AverageGfxActivity;
> +             GET_METRICS_MEMBER(AverageGfxActivity, &data_u16);
> +             *value = *data_u16;
>               break;
>       case METRICS_AVERAGE_MEMACTIVITY:
> -             *value = metrics->AverageUclkActivity;
> +             GET_METRICS_MEMBER(AverageUclkActivity, &data_u16);
> +             *value = *data_u16;
>               break;
>       case METRICS_AVERAGE_SOCKETPOWER:
> -             *value = metrics->AverageSocketPower << 8;
> +             GET_METRICS_MEMBER(AverageSocketPower, &data_u16);
> +             *value = *data_u16 << 8;
>               break;
>       case METRICS_TEMPERATURE_EDGE:
> -             *value = metrics->TemperatureEdge *
> +             GET_METRICS_MEMBER(TemperatureEdge, &data_u16);
> +             *value = *data_u16 *
>                       SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
>               break;
>       case METRICS_TEMPERATURE_HOTSPOT:
> -             *value = metrics->TemperatureHotspot *
> +             GET_METRICS_MEMBER(TemperatureHotspot, &data_u16);
> +             *value = *data_u16 *
>                       SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
>               break;
>       case METRICS_TEMPERATURE_MEM:
> -             *value = metrics->TemperatureMem *
> +             GET_METRICS_MEMBER(TemperatureMem, &data_u16);
> +             *value = *data_u16 *
>                       SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
>               break;
>       case METRICS_TEMPERATURE_VRGFX:
> -             *value = metrics->TemperatureVrGfx *
> +             GET_METRICS_MEMBER(TemperatureVrGfx, &data_u16);
> +             *value = *data_u16 *
>                       SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
>               break;
>       case METRICS_TEMPERATURE_VRSOC:
> -             *value = metrics->TemperatureVrSoc *
> +             GET_METRICS_MEMBER(TemperatureVrSoc, &data_u16);
> +             *value = *data_u16 *
>                       SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
>               break;
>       case METRICS_THROTTLER_STATUS:
> -             *value = metrics->ThrottlerStatus;
> +             *value = sienna_cichlid_get_throttler_status_locked(smu);
>               break;
>       case METRICS_CURR_FANSPEED:
> -             *value = metrics->CurrFanSpeed;
> +             GET_METRICS_MEMBER(CurrFanSpeed, &data_u16);
> +             *value = *data_u16;
>               break;
>       default:
>               *value = UINT_MAX;
> @@ -3564,68 +3613,103 @@ static ssize_t
> sienna_cichlid_get_gpu_metrics(struct smu_context *smu,
>       struct smu_table_context *smu_table = &smu->smu_table;
>       struct gpu_metrics_v1_3 *gpu_metrics =
>               (struct gpu_metrics_v1_3 *)smu_table->gpu_metrics_table;
> -     SmuMetricsExternal_t metrics_external;
> -     SmuMetrics_t *metrics =
> -             &(metrics_external.SmuMetrics);
> -     struct amdgpu_device *adev = smu->adev;
> -     uint32_t smu_version;
> +     uint32_t *data_u32;
> +     uint16_t *data_u16;
> +     uint8_t *data_u8;
>       int ret = 0;
> 
> -     ret = smu_cmn_get_metrics_table(smu,
> -                                     &metrics_external,
> -                                     true);
> -     if (ret)
> +     mutex_lock(&smu->metrics_lock);
> +
> +     ret = smu_cmn_get_metrics_table_locked(smu,
> +                                            NULL,
> +                                            true);
> +     if (ret) {
> +             mutex_unlock(&smu->metrics_lock);
>               return ret;
> +     }
> 
>       smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3);
> 
> -     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;
> +     GET_METRICS_MEMBER(TemperatureEdge, &data_u16);
> +     gpu_metrics->temperature_edge = *data_u16;
> +
> +     GET_METRICS_MEMBER(TemperatureHotspot, &data_u16);
> +     gpu_metrics->temperature_hotspot = *data_u16;
> +
> +     GET_METRICS_MEMBER(TemperatureMem, &data_u16);
> +     gpu_metrics->temperature_mem = *data_u16;
> +
> +     GET_METRICS_MEMBER(TemperatureVrGfx, &data_u16);
> +     gpu_metrics->temperature_vrgfx = *data_u16;
> +
> +     GET_METRICS_MEMBER(TemperatureVrSoc, &data_u16);
> +     gpu_metrics->temperature_vrsoc = *data_u16;
> +
> +     GET_METRICS_MEMBER(TemperatureVrMem0, &data_u16);
> +     gpu_metrics->temperature_vrmem = *data_u16;
> 
> -     gpu_metrics->average_gfx_activity = metrics->AverageGfxActivity;
> -     gpu_metrics->average_umc_activity = metrics->AverageUclkActivity;
> -     gpu_metrics->average_mm_activity = metrics-
> >VcnActivityPercentage;
> +     GET_METRICS_MEMBER(AverageGfxActivity, &data_u16);
> +     gpu_metrics->average_gfx_activity = *data_u16;
> 
> -     gpu_metrics->average_socket_power = metrics-
> >AverageSocketPower;
> -     gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
> +     GET_METRICS_MEMBER(AverageUclkActivity, &data_u16);
> +     gpu_metrics->average_umc_activity = *data_u16;
> 
> -     if (metrics->AverageGfxActivity <=
> SMU_11_0_7_GFX_BUSY_THRESHOLD)
> -             gpu_metrics->average_gfxclk_frequency = metrics-
> >AverageGfxclkFrequencyPostDs;
> +     GET_METRICS_MEMBER(VcnActivityPercentage, &data_u16);
> +     gpu_metrics->average_mm_activity = *data_u16;
> +
> +     GET_METRICS_MEMBER(AverageSocketPower, &data_u16);
> +     gpu_metrics->average_socket_power = *data_u16;
> +
> +     GET_METRICS_MEMBER(EnergyAccumulator, &data_u32);
> +     gpu_metrics->energy_accumulator = *data_u32;
> +
> +     GET_METRICS_MEMBER(AverageGfxActivity, &data_u16);
> +     if (*data_u16 <= SMU_11_0_7_GFX_BUSY_THRESHOLD)
> +             GET_METRICS_MEMBER(AverageGfxclkFrequencyPostDs,
> &data_u16);
>       else
> -             gpu_metrics->average_gfxclk_frequency = metrics-
> >AverageGfxclkFrequencyPreDs;
> -     gpu_metrics->average_uclk_frequency = metrics-
> >AverageUclkFrequencyPostDs;
> -     gpu_metrics->average_vclk0_frequency = metrics-
> >AverageVclk0Frequency;
> -     gpu_metrics->average_dclk0_frequency = metrics-
> >AverageDclk0Frequency;
> -     gpu_metrics->average_vclk1_frequency = metrics-
> >AverageVclk1Frequency;
> -     gpu_metrics->average_dclk1_frequency = metrics-
> >AverageDclk1Frequency;
> -
> -     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_0];
> -     gpu_metrics->current_dclk0 = metrics->CurrClock[PPCLK_DCLK_0];
> -     gpu_metrics->current_vclk1 = metrics->CurrClock[PPCLK_VCLK_1];
> -     gpu_metrics->current_dclk1 = metrics->CurrClock[PPCLK_DCLK_1];
> -
> -     gpu_metrics->throttle_status = metrics->ThrottlerStatus;
> +             GET_METRICS_MEMBER(AverageGfxclkFrequencyPreDs,
> &data_u16);
> +     gpu_metrics->average_gfxclk_frequency = *data_u16;
> +
> +     GET_METRICS_MEMBER(AverageUclkFrequencyPostDs, &data_u16);
> +     gpu_metrics->average_uclk_frequency = *data_u16;
> +
> +     GET_METRICS_MEMBER(AverageVclk0Frequency, &data_u16);
> +     gpu_metrics->average_vclk0_frequency = *data_u16;
> +
> +     GET_METRICS_MEMBER(AverageDclk0Frequency, &data_u16);
> +     gpu_metrics->average_dclk0_frequency = *data_u16;
> +
> +     GET_METRICS_MEMBER(AverageVclk1Frequency, &data_u16);
> +     gpu_metrics->average_vclk1_frequency = *data_u16;
> +
> +     GET_METRICS_MEMBER(AverageDclk1Frequency, &data_u16);
> +     gpu_metrics->average_dclk1_frequency = *data_u16;
> +
> +     GET_METRICS_MEMBER(CurrClock, &data_u32);
> +     gpu_metrics->current_gfxclk = data_u32[PPCLK_GFXCLK];
> +     gpu_metrics->current_socclk = data_u32[PPCLK_SOCCLK];
> +     gpu_metrics->current_uclk = data_u32[PPCLK_UCLK];
> +     gpu_metrics->current_vclk0 = data_u32[PPCLK_VCLK_0];
> +     gpu_metrics->current_dclk0 = data_u32[PPCLK_DCLK_0];
> +     gpu_metrics->current_vclk1 = data_u32[PPCLK_VCLK_1];
> +     gpu_metrics->current_dclk1 = data_u32[PPCLK_DCLK_1];
> +
> +     gpu_metrics->throttle_status =
> +                     sienna_cichlid_get_throttler_status_locked(smu);
>       gpu_metrics->indep_throttle_status =
> -                     smu_cmn_get_indep_throttler_status(metrics-
> >ThrottlerStatus,
> +                     smu_cmn_get_indep_throttler_status(gpu_metrics-
> >throttle_status,
> 
> sienna_cichlid_throttler_map);
> 
> -     gpu_metrics->current_fan_speed = metrics->CurrFanSpeed;
> +     GET_METRICS_MEMBER(CurrFanSpeed, &data_u16);
> +     gpu_metrics->current_fan_speed = *data_u16;
> 
> -     ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
> -     if (ret)
> -             return ret;
> +     if (((smu->adev->asic_type == CHIP_SIENNA_CICHLID) && smu-
> >smc_fw_version > 0x003A1E00) ||
> +           ((smu->adev->asic_type == CHIP_NAVY_FLOUNDER) && smu-
> >smc_fw_version > 0x00410400)) {
> +             GET_METRICS_MEMBER(PcieWidth, &data_u8);
> +             gpu_metrics->pcie_link_width = *data_u8;
> 
> -     if (((adev->asic_type == CHIP_SIENNA_CICHLID) && smu_version >
> 0x003A1E00) ||
> -           ((adev->asic_type == CHIP_NAVY_FLOUNDER) && smu_version >
> 0x00410400)) {
> -             gpu_metrics->pcie_link_width = metrics->PcieWidth;
> -             gpu_metrics->pcie_link_speed = link_speed[metrics-
> >PcieRate];
> +             GET_METRICS_MEMBER(PcieRate, &data_u8);
> +             gpu_metrics->pcie_link_speed = link_speed[*data_u8];
>       } else {
>               gpu_metrics->pcie_link_width =
> 
>       smu_v11_0_get_current_pcie_link_width(smu);
> @@ -3633,6 +3717,8 @@ static ssize_t
> sienna_cichlid_get_gpu_metrics(struct smu_context *smu,
> 
>       smu_v11_0_get_current_pcie_link_speed(smu);
>       }
> 
> +     mutex_unlock(&smu->metrics_lock);
> +
>       gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
> 
>       *table = (void *)gpu_metrics;
> --
> 2.29.0
_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to