diff options
Diffstat (limited to 'drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c')
-rw-r--r-- | drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 99 |
1 files changed, 65 insertions, 34 deletions
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index dcbe3a72da09..7c191a5d6db9 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -78,8 +78,6 @@ #define smnPCIE_ESM_CTRL 0x111003D0 -#define CLOCK_VALID (1 << 31) - static const struct cmn2asic_msg_mapping aldebaran_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -209,7 +207,7 @@ static int aldebaran_tables_init(struct smu_context *smu) return -ENOMEM; smu_table->metrics_time = 0; - smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_1); + smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_2); smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL); if (!smu_table->gpu_metrics_table) { kfree(smu_table->metrics_table); @@ -455,12 +453,18 @@ static int aldebaran_populate_umd_state_clk(struct smu_context *smu) pstate_table->gfxclk_pstate.min = gfx_table->min; pstate_table->gfxclk_pstate.peak = gfx_table->max; + pstate_table->gfxclk_pstate.curr.min = gfx_table->min; + pstate_table->gfxclk_pstate.curr.max = gfx_table->max; pstate_table->uclk_pstate.min = mem_table->min; pstate_table->uclk_pstate.peak = mem_table->max; + pstate_table->uclk_pstate.curr.min = mem_table->min; + pstate_table->uclk_pstate.curr.max = mem_table->max; pstate_table->socclk_pstate.min = soc_table->min; pstate_table->socclk_pstate.peak = soc_table->max; + pstate_table->socclk_pstate.curr.min = soc_table->min; + pstate_table->socclk_pstate.curr.max = soc_table->max; if (gfx_table->count > ALDEBARAN_UMD_PSTATE_GFXCLK_LEVEL && mem_table->count > ALDEBARAN_UMD_PSTATE_MCLK_LEVEL && @@ -669,6 +673,7 @@ static int aldebaran_print_clk_levels(struct smu_context *smu, { int i, now, size = 0; int ret = 0; + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; struct pp_clock_levels_with_latency clocks; struct smu_13_0_dpm_table *single_dpm_table; struct smu_dpm_context *smu_dpm = &smu->smu_dpm; @@ -703,12 +708,8 @@ static int aldebaran_print_clk_levels(struct smu_context *smu, display_levels = clocks.num_levels; - min_clk = smu->gfx_actual_hard_min_freq & CLOCK_VALID ? - smu->gfx_actual_hard_min_freq & ~CLOCK_VALID : - single_dpm_table->dpm_levels[0].value; - max_clk = smu->gfx_actual_soft_max_freq & CLOCK_VALID ? - smu->gfx_actual_soft_max_freq & ~CLOCK_VALID : - single_dpm_table->dpm_levels[1].value; + min_clk = pstate_table->gfxclk_pstate.curr.min; + max_clk = pstate_table->gfxclk_pstate.curr.max; freq_values[0] = min_clk; freq_values[1] = max_clk; @@ -1128,15 +1129,17 @@ static int aldebaran_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level) { struct smu_dpm_context *smu_dpm = &(smu->smu_dpm); + struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context; + struct smu_13_0_dpm_table *gfx_table = + &dpm_context->dpm_tables.gfx_table; + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; /* Disable determinism if switching to another mode */ - if ((smu_dpm->dpm_level == AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) - && (level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)) + if ((smu_dpm->dpm_level == AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) && + (level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)) { smu_cmn_send_smc_msg(smu, SMU_MSG_DisableDeterminism, NULL); - - /* Reset user min/max gfx clock */ - smu->gfx_actual_hard_min_freq = 0; - smu->gfx_actual_soft_max_freq = 0; + pstate_table->gfxclk_pstate.curr.max = gfx_table->max; + } switch (level) { @@ -1163,6 +1166,7 @@ static int aldebaran_set_soft_freq_limited_range(struct smu_context *smu, { struct smu_dpm_context *smu_dpm = &(smu->smu_dpm); struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context; + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; struct amdgpu_device *adev = smu->adev; uint32_t min_clk; uint32_t max_clk; @@ -1176,15 +1180,23 @@ static int aldebaran_set_soft_freq_limited_range(struct smu_context *smu, return -EINVAL; if (smu_dpm->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) { - min_clk = max(min, dpm_context->dpm_tables.gfx_table.min); - max_clk = min(max, dpm_context->dpm_tables.gfx_table.max); - ret = smu_v13_0_set_soft_freq_limited_range(smu, SMU_GFXCLK, - min_clk, max_clk); + if (min >= max) { + dev_err(smu->adev->dev, + "Minimum GFX clk should be less than the maximum allowed clock\n"); + return -EINVAL; + } + if ((min == pstate_table->gfxclk_pstate.curr.min) && + (max == pstate_table->gfxclk_pstate.curr.max)) + return 0; + + ret = smu_v13_0_set_soft_freq_limited_range(smu, SMU_GFXCLK, + min, max); if (!ret) { - smu->gfx_actual_hard_min_freq = min_clk | CLOCK_VALID; - smu->gfx_actual_soft_max_freq = max_clk | CLOCK_VALID; + pstate_table->gfxclk_pstate.curr.min = min; + pstate_table->gfxclk_pstate.curr.max = max; } + return ret; } @@ -1209,10 +1221,8 @@ static int aldebaran_set_soft_freq_limited_range(struct smu_context *smu, dev_err(adev->dev, "Failed to enable determinism at GFX clock %d MHz\n", max); } else { - smu->gfx_actual_hard_min_freq = - min_clk | CLOCK_VALID; - smu->gfx_actual_soft_max_freq = - max | CLOCK_VALID; + pstate_table->gfxclk_pstate.curr.min = min_clk; + pstate_table->gfxclk_pstate.curr.max = max; } } } @@ -1225,6 +1235,7 @@ static int aldebaran_usr_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_ { struct smu_dpm_context *smu_dpm = &(smu->smu_dpm); struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context; + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; uint32_t min_clk; uint32_t max_clk; int ret = 0; @@ -1245,16 +1256,22 @@ static int aldebaran_usr_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_ if (input[1] < dpm_context->dpm_tables.gfx_table.min) { dev_warn(smu->adev->dev, "Minimum GFX clk (%ld) MHz specified is less than the minimum allowed (%d) MHz\n", input[1], dpm_context->dpm_tables.gfx_table.min); + pstate_table->gfxclk_pstate.custom.min = + pstate_table->gfxclk_pstate.curr.min; return -EINVAL; } - smu->gfx_actual_hard_min_freq = input[1]; + + pstate_table->gfxclk_pstate.custom.min = input[1]; } else if (input[0] == 1) { if (input[1] > dpm_context->dpm_tables.gfx_table.max) { dev_warn(smu->adev->dev, "Maximum GFX clk (%ld) MHz specified is greater than the maximum allowed (%d) MHz\n", input[1], dpm_context->dpm_tables.gfx_table.max); + pstate_table->gfxclk_pstate.custom.max = + pstate_table->gfxclk_pstate.curr.max; return -EINVAL; } - smu->gfx_actual_soft_max_freq = input[1]; + + pstate_table->gfxclk_pstate.custom.max = input[1]; } else { return -EINVAL; } @@ -1276,8 +1293,17 @@ static int aldebaran_usr_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_ dev_err(smu->adev->dev, "Input parameter number not correct\n"); return -EINVAL; } else { - min_clk = smu->gfx_actual_hard_min_freq; - max_clk = smu->gfx_actual_soft_max_freq; + if (!pstate_table->gfxclk_pstate.custom.min) + pstate_table->gfxclk_pstate.custom.min = + pstate_table->gfxclk_pstate.curr.min; + + if (!pstate_table->gfxclk_pstate.custom.max) + pstate_table->gfxclk_pstate.custom.max = + pstate_table->gfxclk_pstate.curr.max; + + min_clk = pstate_table->gfxclk_pstate.custom.min; + max_clk = pstate_table->gfxclk_pstate.custom.max; + return aldebaran_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk); } break; @@ -1632,8 +1658,8 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu, void **table) { struct smu_table_context *smu_table = &smu->smu_table; - struct gpu_metrics_v1_1 *gpu_metrics = - (struct gpu_metrics_v1_1 *)smu_table->gpu_metrics_table; + struct gpu_metrics_v1_2 *gpu_metrics = + (struct gpu_metrics_v1_2 *)smu_table->gpu_metrics_table; SmuMetrics_t metrics; int i, ret = 0; @@ -1643,7 +1669,7 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu, if (ret) return ret; - smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 1); + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 2); gpu_metrics->temperature_edge = metrics.TemperatureEdge; gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot; @@ -1657,7 +1683,9 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu, gpu_metrics->average_mm_activity = 0; gpu_metrics->average_socket_power = metrics.AverageSocketPower; - gpu_metrics->energy_accumulator = 0; + gpu_metrics->energy_accumulator = + (uint64_t)metrics.EnergyAcc64bitHigh << 32 | + metrics.EnergyAcc64bitLow; gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequency; gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency; @@ -1688,9 +1716,12 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu, for (i = 0; i < NUM_HBM_INSTANCES; i++) gpu_metrics->temperature_hbm[i] = metrics.TemperatureAllHBM[i]; + gpu_metrics->firmware_timestamp = ((uint64_t)metrics.TimeStampHigh << 32) | + metrics.TimeStampLow; + *table = (void *)gpu_metrics; - return sizeof(struct gpu_metrics_v1_1); + return sizeof(struct gpu_metrics_v1_2); } static int aldebaran_mode2_reset(struct smu_context *smu) |