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 {
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)
......
......@@ -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
......
......@@ -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,17 +458,12 @@ 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),
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);
......@@ -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);
}
......@@ -1328,7 +1637,7 @@ static int navi10_get_fan_speed_percent(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,
&rpm);
if (!ret && smu->fan_max_rpm)
......@@ -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;
......@@ -2287,14 +2596,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;
......@@ -2309,8 +2679,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);
......@@ -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_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];
......@@ -2361,6 +2866,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;
......@@ -2489,7 +3028,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,
......
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