Commit 7d6c13ef authored by Evan Quan's avatar Evan Quan Committed by Alex Deucher

drm/amd/pm: bump Navi1x driver if version and related data structures V2

New changes were involved for the SmuMetrics structure.
Signed-off-by: default avatarEvan Quan <evan.quan@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 3e9e62c7
...@@ -843,11 +843,15 @@ typedef struct { ...@@ -843,11 +843,15 @@ typedef struct {
uint16_t FanMaximumRpm; uint16_t FanMaximumRpm;
uint16_t FanMinimumPwm; uint16_t FanMinimumPwm;
uint16_t FanTargetTemperature; // Degree Celcius 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 MaxOpTemp; // Degree Celcius
uint16_t FanZeroRpmEnable; uint16_t FanZeroRpmEnable;
uint16_t Padding;
uint32_t MmHubPadding[8]; // SMU internal use uint32_t MmHubPadding[6]; // SMU internal use
} OverDriveTable_t; } OverDriveTable_t;
...@@ -880,6 +884,45 @@ typedef struct { ...@@ -880,6 +884,45 @@ typedef struct {
uint8_t Padding8_2; uint8_t Padding8_2;
uint16_t CurrFanSpeed; 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 // Padding - ignore
uint32_t MmHubPadding[8]; // SMU internal use uint32_t MmHubPadding[8]; // SMU internal use
} SmuMetrics_t; } SmuMetrics_t;
...@@ -919,10 +962,61 @@ typedef struct { ...@@ -919,10 +962,61 @@ typedef struct {
uint16_t VcnActivityPercentage ; uint16_t VcnActivityPercentage ;
uint16_t padding16_2; 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 // Padding - ignore
uint32_t MmHubPadding[8]; // SMU internal use uint32_t MmHubPadding[8]; // SMU internal use
} SmuMetrics_NV12_t; } 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 { typedef struct {
uint16_t MinClock; // This is either DCEFCLK or SOCCLK (in MHz) uint16_t MinClock; // This is either DCEFCLK or SOCCLK (in MHz)
uint16_t MaxClock; // This is either DCEFCLK or SOCCLK (in MHz) uint16_t MaxClock; // This is either DCEFCLK or SOCCLK (in MHz)
......
...@@ -27,9 +27,9 @@ ...@@ -27,9 +27,9 @@
#define SMU11_DRIVER_IF_VERSION_INV 0xFFFFFFFF #define SMU11_DRIVER_IF_VERSION_INV 0xFFFFFFFF
#define SMU11_DRIVER_IF_VERSION_ARCT 0x17 #define SMU11_DRIVER_IF_VERSION_ARCT 0x17
#define SMU11_DRIVER_IF_VERSION_NV10 0x36 #define SMU11_DRIVER_IF_VERSION_NV10 0x37
#define SMU11_DRIVER_IF_VERSION_NV12 0x36 #define SMU11_DRIVER_IF_VERSION_NV12 0x38
#define SMU11_DRIVER_IF_VERSION_NV14 0x36 #define SMU11_DRIVER_IF_VERSION_NV14 0x38
#define SMU11_DRIVER_IF_VERSION_Sienna_Cichlid 0x3D #define SMU11_DRIVER_IF_VERSION_Sienna_Cichlid 0x3D
#define SMU11_DRIVER_IF_VERSION_Navy_Flounder 0xE #define SMU11_DRIVER_IF_VERSION_Navy_Flounder 0xE
#define SMU11_DRIVER_IF_VERSION_VANGOGH 0x02 #define SMU11_DRIVER_IF_VERSION_VANGOGH 0x02
......
...@@ -70,6 +70,8 @@ ...@@ -70,6 +70,8 @@
FEATURE_MASK(FEATURE_DPM_LINK_BIT) | \ FEATURE_MASK(FEATURE_DPM_LINK_BIT) | \
FEATURE_MASK(FEATURE_DPM_DCEFCLK_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] = { static struct cmn2asic_msg_mapping navi10_message_map[SMU_MSG_MAX_COUNT] = {
MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1),
MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1),
...@@ -456,18 +458,13 @@ static int navi10_tables_init(struct smu_context *smu) ...@@ -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_context *smu_table = &smu->smu_table;
struct smu_table *tables = smu_table->tables; struct smu_table *tables = smu_table->tables;
struct amdgpu_device *adev = smu->adev;
SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t), SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t),
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t), SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
if (adev->asic_type == CHIP_NAVI12) SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_NV1X_t),
SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_NV12_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
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_I2C_COMMANDS, sizeof(SwI2cRequest_t), SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t),
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
SMU_TABLE_INIT(tables, SMU_TABLE_OVERDRIVE, sizeof(OverDriveTable_t), SMU_TABLE_INIT(tables, SMU_TABLE_OVERDRIVE, sizeof(OverDriveTable_t),
...@@ -478,9 +475,8 @@ static int navi10_tables_init(struct smu_context *smu) ...@@ -478,9 +475,8 @@ static int navi10_tables_init(struct smu_context *smu)
sizeof(DpmActivityMonitorCoeffInt_t), PAGE_SIZE, sizeof(DpmActivityMonitorCoeffInt_t), PAGE_SIZE,
AMDGPU_GEM_DOMAIN_VRAM); AMDGPU_GEM_DOMAIN_VRAM);
smu_table->metrics_table = kzalloc(adev->asic_type == CHIP_NAVI12 ? smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_NV1X_t),
sizeof(SmuMetrics_NV12_t) : GFP_KERNEL);
sizeof(SmuMetrics_t), GFP_KERNEL);
if (!smu_table->metrics_table) if (!smu_table->metrics_table)
goto err0_out; goto err0_out;
smu_table->metrics_time = 0; smu_table->metrics_time = 0;
...@@ -504,17 +500,200 @@ static int navi10_tables_init(struct smu_context *smu) ...@@ -504,17 +500,200 @@ static int navi10_tables_init(struct smu_context *smu)
return -ENOMEM; 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, static int navi10_get_smu_metrics_data(struct smu_context *smu,
MetricsMember_t member, MetricsMember_t member,
uint32_t *value) uint32_t *value)
{ {
struct smu_table_context *smu_table= &smu->smu_table; struct smu_table_context *smu_table= &smu->smu_table;
/* SmuMetrics_t *metrics =
* This works for NV12 also. As although NV12 uses a different (SmuMetrics_t *)smu_table->metrics_table;
* SmuMetrics structure from other NV1X ASICs, they share the int ret = 0;
* same offsets for the heading parts(those members used here).
*/ mutex_lock(&smu->metrics_lock);
SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
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; int ret = 0;
mutex_lock(&smu->metrics_lock); mutex_lock(&smu->metrics_lock);
...@@ -600,6 +779,136 @@ static int navi10_get_smu_metrics_data(struct smu_context *smu, ...@@ -600,6 +779,136 @@ static int navi10_get_smu_metrics_data(struct smu_context *smu,
return ret; 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) static int navi10_allocate_dpm_context(struct smu_context *smu)
{ {
struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 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, ...@@ -880,7 +1189,7 @@ static int navi10_get_current_clk_freq_by_table(struct smu_context *smu,
return -EINVAL; return -EINVAL;
} }
return navi10_get_smu_metrics_data(smu, return navi1x_get_smu_metrics_data(smu,
member_type, member_type,
value); value);
} }
...@@ -1328,7 +1637,7 @@ static int navi10_get_fan_speed_percent(struct smu_context *smu, ...@@ -1328,7 +1637,7 @@ static int navi10_get_fan_speed_percent(struct smu_context *smu,
switch (smu_v11_0_get_fan_control_mode(smu)) { switch (smu_v11_0_get_fan_control_mode(smu)) {
case AMD_FAN_CTRL_AUTO: case AMD_FAN_CTRL_AUTO:
ret = navi10_get_smu_metrics_data(smu, ret = navi1x_get_smu_metrics_data(smu,
METRICS_CURR_FANSPEED, METRICS_CURR_FANSPEED,
&rpm); &rpm);
if (!ret && smu->fan_max_rpm) if (!ret && smu->fan_max_rpm)
...@@ -1644,37 +1953,37 @@ static int navi10_read_sensor(struct smu_context *smu, ...@@ -1644,37 +1953,37 @@ static int navi10_read_sensor(struct smu_context *smu,
*size = 4; *size = 4;
break; break;
case AMDGPU_PP_SENSOR_MEM_LOAD: case AMDGPU_PP_SENSOR_MEM_LOAD:
ret = navi10_get_smu_metrics_data(smu, ret = navi1x_get_smu_metrics_data(smu,
METRICS_AVERAGE_MEMACTIVITY, METRICS_AVERAGE_MEMACTIVITY,
(uint32_t *)data); (uint32_t *)data);
*size = 4; *size = 4;
break; break;
case AMDGPU_PP_SENSOR_GPU_LOAD: case AMDGPU_PP_SENSOR_GPU_LOAD:
ret = navi10_get_smu_metrics_data(smu, ret = navi1x_get_smu_metrics_data(smu,
METRICS_AVERAGE_GFXACTIVITY, METRICS_AVERAGE_GFXACTIVITY,
(uint32_t *)data); (uint32_t *)data);
*size = 4; *size = 4;
break; break;
case AMDGPU_PP_SENSOR_GPU_POWER: case AMDGPU_PP_SENSOR_GPU_POWER:
ret = navi10_get_smu_metrics_data(smu, ret = navi1x_get_smu_metrics_data(smu,
METRICS_AVERAGE_SOCKETPOWER, METRICS_AVERAGE_SOCKETPOWER,
(uint32_t *)data); (uint32_t *)data);
*size = 4; *size = 4;
break; break;
case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
ret = navi10_get_smu_metrics_data(smu, ret = navi1x_get_smu_metrics_data(smu,
METRICS_TEMPERATURE_HOTSPOT, METRICS_TEMPERATURE_HOTSPOT,
(uint32_t *)data); (uint32_t *)data);
*size = 4; *size = 4;
break; break;
case AMDGPU_PP_SENSOR_EDGE_TEMP: case AMDGPU_PP_SENSOR_EDGE_TEMP:
ret = navi10_get_smu_metrics_data(smu, ret = navi1x_get_smu_metrics_data(smu,
METRICS_TEMPERATURE_EDGE, METRICS_TEMPERATURE_EDGE,
(uint32_t *)data); (uint32_t *)data);
*size = 4; *size = 4;
break; break;
case AMDGPU_PP_SENSOR_MEM_TEMP: case AMDGPU_PP_SENSOR_MEM_TEMP:
ret = navi10_get_smu_metrics_data(smu, ret = navi1x_get_smu_metrics_data(smu,
METRICS_TEMPERATURE_MEM, METRICS_TEMPERATURE_MEM,
(uint32_t *)data); (uint32_t *)data);
*size = 4; *size = 4;
...@@ -1685,7 +1994,7 @@ static int navi10_read_sensor(struct smu_context *smu, ...@@ -1685,7 +1994,7 @@ static int navi10_read_sensor(struct smu_context *smu,
*size = 4; *size = 4;
break; break;
case AMDGPU_PP_SENSOR_GFX_SCLK: 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; *(uint32_t *)data *= 100;
*size = 4; *size = 4;
break; break;
...@@ -2287,14 +2596,75 @@ static int navi10_run_umc_cdr_workaround(struct smu_context *smu) ...@@ -2287,14 +2596,75 @@ static int navi10_run_umc_cdr_workaround(struct smu_context *smu)
return 0; 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, static ssize_t navi10_get_gpu_metrics(struct smu_context *smu,
void **table) void **table)
{ {
struct smu_table_context *smu_table = &smu->smu_table; struct smu_table_context *smu_table = &smu->smu_table;
struct gpu_metrics_v1_0 *gpu_metrics = struct gpu_metrics_v1_0 *gpu_metrics =
(struct gpu_metrics_v1_0 *)smu_table->gpu_metrics_table; (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; SmuMetrics_t metrics;
int ret = 0; int ret = 0;
...@@ -2309,8 +2679,73 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu, ...@@ -2309,8 +2679,73 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu,
} }
memcpy(&metrics, smu_table->metrics_table, sizeof(SmuMetrics_t)); 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); mutex_unlock(&smu->metrics_lock);
...@@ -2332,13 +2767,83 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu, ...@@ -2332,13 +2767,83 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency; gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency;
gpu_metrics->average_uclk_frequency = metrics.AverageUclkFrequency; gpu_metrics->average_uclk_frequency = metrics.AverageUclkFrequency;
if (adev->asic_type == CHIP_NAVI12) { gpu_metrics->energy_accumulator = metrics.EnergyAccumulator;
gpu_metrics->energy_accumulator = nv12_metrics.EnergyAccumulator; gpu_metrics->average_vclk0_frequency = metrics.AverageVclkFrequency;
gpu_metrics->average_vclk0_frequency = nv12_metrics.AverageVclkFrequency; gpu_metrics->average_dclk0_frequency = metrics.AverageDclkFrequency;
gpu_metrics->average_dclk0_frequency = nv12_metrics.AverageDclkFrequency; gpu_metrics->average_mm_activity = metrics.VcnActivityPercentage;
gpu_metrics->average_mm_activity = nv12_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_gfxclk = metrics.CurrClock[PPCLK_GFXCLK];
gpu_metrics->current_socclk = metrics.CurrClock[PPCLK_SOCCLK]; gpu_metrics->current_socclk = metrics.CurrClock[PPCLK_SOCCLK];
gpu_metrics->current_uclk = metrics.CurrClock[PPCLK_UCLK]; gpu_metrics->current_uclk = metrics.CurrClock[PPCLK_UCLK];
...@@ -2361,6 +2866,40 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu, ...@@ -2361,6 +2866,40 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu,
return sizeof(struct gpu_metrics_v1_0); 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) static int navi10_enable_mgpu_fan_boost(struct smu_context *smu)
{ {
struct amdgpu_device *adev = smu->adev; struct amdgpu_device *adev = smu->adev;
...@@ -2489,7 +3028,7 @@ static const struct pptable_funcs navi10_ppt_funcs = { ...@@ -2489,7 +3028,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
.set_power_source = smu_v11_0_set_power_source, .set_power_source = smu_v11_0_set_power_source,
.get_pp_feature_mask = smu_cmn_get_pp_feature_mask, .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
.set_pp_feature_mask = smu_cmn_set_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, .enable_mgpu_fan_boost = navi10_enable_mgpu_fan_boost,
.gfx_ulv_control = smu_v11_0_gfx_ulv_control, .gfx_ulv_control = smu_v11_0_gfx_ulv_control,
.deep_sleep_control = smu_v11_0_deep_sleep_control, .deep_sleep_control = smu_v11_0_deep_sleep_control,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment