mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-07-10 15:55:22 +02:00
amdgpu/pm: Implement emit_clk_levels for navi10
(v4) Modifications to satisfy checkpatch --strict (v3) Rewrote patchset to order patches as (API, hw impl, usecase) - implement emit_clk_levels for navi10, based on print_clk_levels, but using sysfs_emit without smu_cmn_get_sysfs() workaround Signed-off-by: Darren Powell <darren.powell@amd.com> Reviewed-by: Evan Quan <evan.quan@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
69f915cc97
commit
b06b48d7dd
|
@ -1236,6 +1236,215 @@ static void navi10_od_setting_get_range(struct smu_11_0_overdrive_table *od_tabl
|
|||
*max = od_table->max[setting];
|
||||
}
|
||||
|
||||
static int navi10_emit_clk_levels(struct smu_context *smu,
|
||||
enum smu_clk_type clk_type,
|
||||
char *buf,
|
||||
int *offset)
|
||||
{
|
||||
uint16_t *curve_settings;
|
||||
int ret = 0;
|
||||
uint32_t cur_value = 0, value = 0;
|
||||
uint32_t freq_values[3] = {0};
|
||||
uint32_t i, levels, mark_index = 0, count = 0;
|
||||
struct smu_table_context *table_context = &smu->smu_table;
|
||||
uint32_t gen_speed, lane_width;
|
||||
struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
|
||||
struct smu_11_0_dpm_context *dpm_context = smu_dpm->dpm_context;
|
||||
PPTable_t *pptable = (PPTable_t *)table_context->driver_pptable;
|
||||
OverDriveTable_t *od_table =
|
||||
(OverDriveTable_t *)table_context->overdrive_table;
|
||||
struct smu_11_0_overdrive_table *od_settings = smu->od_settings;
|
||||
uint32_t min_value, max_value;
|
||||
|
||||
switch (clk_type) {
|
||||
case SMU_GFXCLK:
|
||||
case SMU_SCLK:
|
||||
case SMU_SOCCLK:
|
||||
case SMU_MCLK:
|
||||
case SMU_UCLK:
|
||||
case SMU_FCLK:
|
||||
case SMU_VCLK:
|
||||
case SMU_DCLK:
|
||||
case SMU_DCEFCLK:
|
||||
ret = navi10_get_current_clk_freq_by_table(smu, clk_type, &cur_value);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = smu_v11_0_get_dpm_level_count(smu, clk_type, &count);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) {
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = smu_v11_0_get_dpm_freq_by_index(smu,
|
||||
clk_type, i, &value);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*offset += sysfs_emit_at(buf, *offset,
|
||||
"%d: %uMhz %s\n",
|
||||
i, value,
|
||||
cur_value == value ? "*" : "");
|
||||
}
|
||||
} else {
|
||||
ret = smu_v11_0_get_dpm_freq_by_index(smu,
|
||||
clk_type, 0, &freq_values[0]);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = smu_v11_0_get_dpm_freq_by_index(smu,
|
||||
clk_type,
|
||||
count - 1,
|
||||
&freq_values[2]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
freq_values[1] = cur_value;
|
||||
mark_index = cur_value == freq_values[0] ? 0 :
|
||||
cur_value == freq_values[2] ? 2 : 1;
|
||||
|
||||
levels = 3;
|
||||
if (mark_index != 1) {
|
||||
levels = 2;
|
||||
freq_values[1] = freq_values[2];
|
||||
}
|
||||
|
||||
for (i = 0; i < levels; i++) {
|
||||
*offset += sysfs_emit_at(buf, *offset,
|
||||
"%d: %uMhz %s\n",
|
||||
i, freq_values[i],
|
||||
i == mark_index ? "*" : "");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SMU_PCIE:
|
||||
gen_speed = smu_v11_0_get_current_pcie_link_speed_level(smu);
|
||||
lane_width = smu_v11_0_get_current_pcie_link_width_level(smu);
|
||||
for (i = 0; i < NUM_LINK_LEVELS; i++) {
|
||||
*offset += sysfs_emit_at(buf, *offset, "%d: %s %s %dMhz %s\n", i,
|
||||
(dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 0) ? "2.5GT/s," :
|
||||
(dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 1) ? "5.0GT/s," :
|
||||
(dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 2) ? "8.0GT/s," :
|
||||
(dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 3) ? "16.0GT/s," : "",
|
||||
(dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 1) ? "x1" :
|
||||
(dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 2) ? "x2" :
|
||||
(dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 3) ? "x4" :
|
||||
(dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 4) ? "x8" :
|
||||
(dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 5) ? "x12" :
|
||||
(dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 6) ? "x16" : "",
|
||||
pptable->LclkFreq[i],
|
||||
(gen_speed == dpm_context->dpm_tables.pcie_table.pcie_gen[i]) &&
|
||||
(lane_width == dpm_context->dpm_tables.pcie_table.pcie_lane[i]) ?
|
||||
"*" : "");
|
||||
}
|
||||
break;
|
||||
case SMU_OD_SCLK:
|
||||
if (!smu->od_enabled || !od_table || !od_settings)
|
||||
return -EOPNOTSUPP;
|
||||
if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_LIMITS))
|
||||
break;
|
||||
*offset += sysfs_emit_at(buf, *offset, "OD_SCLK:\n0: %uMhz\n1: %uMhz\n",
|
||||
od_table->GfxclkFmin, od_table->GfxclkFmax);
|
||||
break;
|
||||
case SMU_OD_MCLK:
|
||||
if (!smu->od_enabled || !od_table || !od_settings)
|
||||
return -EOPNOTSUPP;
|
||||
if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_UCLK_MAX))
|
||||
break;
|
||||
*offset += sysfs_emit_at(buf, *offset, "OD_MCLK:\n1: %uMHz\n", od_table->UclkFmax);
|
||||
break;
|
||||
case SMU_OD_VDDC_CURVE:
|
||||
if (!smu->od_enabled || !od_table || !od_settings)
|
||||
return -EOPNOTSUPP;
|
||||
if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_CURVE))
|
||||
break;
|
||||
*offset += sysfs_emit_at(buf, *offset, "OD_VDDC_CURVE:\n");
|
||||
for (i = 0; i < 3; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
curve_settings = &od_table->GfxclkFreq1;
|
||||
break;
|
||||
case 1:
|
||||
curve_settings = &od_table->GfxclkFreq2;
|
||||
break;
|
||||
case 2:
|
||||
curve_settings = &od_table->GfxclkFreq3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*offset += sysfs_emit_at(buf, *offset, "%d: %uMHz %umV\n",
|
||||
i, curve_settings[0],
|
||||
curve_settings[1] / NAVI10_VOLTAGE_SCALE);
|
||||
}
|
||||
break;
|
||||
case SMU_OD_RANGE:
|
||||
if (!smu->od_enabled || !od_table || !od_settings)
|
||||
return -EOPNOTSUPP;
|
||||
*offset += sysfs_emit_at(buf, *offset, "%s:\n", "OD_RANGE");
|
||||
|
||||
if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_LIMITS)) {
|
||||
navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_GFXCLKFMIN,
|
||||
&min_value, NULL);
|
||||
navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_GFXCLKFMAX,
|
||||
NULL, &max_value);
|
||||
*offset += sysfs_emit_at(buf, *offset, "SCLK: %7uMhz %10uMhz\n",
|
||||
min_value, max_value);
|
||||
}
|
||||
|
||||
if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_UCLK_MAX)) {
|
||||
navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_UCLKFMAX,
|
||||
&min_value, &max_value);
|
||||
*offset += sysfs_emit_at(buf, *offset, "MCLK: %7uMhz %10uMhz\n",
|
||||
min_value, max_value);
|
||||
}
|
||||
|
||||
if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_CURVE)) {
|
||||
navi10_od_setting_get_range(od_settings,
|
||||
SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1,
|
||||
&min_value, &max_value);
|
||||
*offset += sysfs_emit_at(buf, *offset,
|
||||
"VDDC_CURVE_SCLK[0]: %7uMhz %10uMhz\n",
|
||||
min_value, max_value);
|
||||
navi10_od_setting_get_range(od_settings,
|
||||
SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1,
|
||||
&min_value, &max_value);
|
||||
*offset += sysfs_emit_at(buf, *offset,
|
||||
"VDDC_CURVE_VOLT[0]: %7dmV %11dmV\n",
|
||||
min_value, max_value);
|
||||
navi10_od_setting_get_range(od_settings,
|
||||
SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2,
|
||||
&min_value, &max_value);
|
||||
*offset += sysfs_emit_at(buf, *offset,
|
||||
"VDDC_CURVE_SCLK[1]: %7uMhz %10uMhz\n",
|
||||
min_value, max_value);
|
||||
navi10_od_setting_get_range(od_settings,
|
||||
SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2,
|
||||
&min_value, &max_value);
|
||||
*offset += sysfs_emit_at(buf, *offset,
|
||||
"VDDC_CURVE_VOLT[1]: %7dmV %11dmV\n",
|
||||
min_value, max_value);
|
||||
navi10_od_setting_get_range(od_settings,
|
||||
SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3,
|
||||
&min_value, &max_value);
|
||||
*offset += sysfs_emit_at(buf, *offset,
|
||||
"VDDC_CURVE_SCLK[2]: %7uMhz %10uMhz\n",
|
||||
min_value, max_value);
|
||||
navi10_od_setting_get_range(od_settings,
|
||||
SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3,
|
||||
&min_value, &max_value);
|
||||
*offset += sysfs_emit_at(buf, *offset,
|
||||
"VDDC_CURVE_VOLT[2]: %7dmV %11dmV\n",
|
||||
min_value, max_value);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int navi10_print_clk_levels(struct smu_context *smu,
|
||||
enum smu_clk_type clk_type, char *buf)
|
||||
{
|
||||
|
@ -3220,6 +3429,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
|
|||
.i2c_init = navi10_i2c_control_init,
|
||||
.i2c_fini = navi10_i2c_control_fini,
|
||||
.print_clk_levels = navi10_print_clk_levels,
|
||||
.emit_clk_levels = navi10_emit_clk_levels,
|
||||
.force_clk_levels = navi10_force_clk_levels,
|
||||
.populate_umd_state_clk = navi10_populate_umd_state_clk,
|
||||
.get_clock_by_type_with_latency = navi10_get_clock_by_type_with_latency,
|
||||
|
|
Loading…
Reference in New Issue
Block a user