Commit a2b6df4f authored by Evan Quan's avatar Evan Quan Committed by Alex Deucher

drm/amd/pm: support overdrive vddgfx offset setting(V2)

This is supported by Sienna Cichlid, Navy Flounder and Dimgrey
Cavefish. For these ASICs, the target voltage calculation can be
illustrated by "voltage = voltage calculated from v/f curve +
overdrive vddgfx offset".

V2: limit the smu_version check for Sienna Cichlid only

Here are some sample usages about this new OD setting:
1. Check current vddgfx offset setting by
cat /sys/class/drm/card0/device/pp_od_clk_voltage
...
...
OD_VDDGFX_OFFSET:
0mV
...
...

2. Set new vddgfx offset by
echo "vo 10" > /sys/class/drm/card0/device/pp_od_clk_voltage
cat /sys/class/drm/card0/device/pp_od_clk_voltage
...
...
OD_VDDGFX_OFFSET:
10mV
...
...
3. Commit the new setting by
echo "c" > /sys/class/drm/card0/device/pp_od_clk_voltage
Signed-off-by: default avatarEvan Quan <evan.quan@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 37a58f69
......@@ -157,7 +157,8 @@ enum PP_OD_DPM_TABLE_COMMAND {
PP_OD_EDIT_MCLK_VDDC_TABLE,
PP_OD_EDIT_VDDC_CURVE,
PP_OD_RESTORE_DEFAULT_TABLE,
PP_OD_COMMIT_DPM_TABLE
PP_OD_COMMIT_DPM_TABLE,
PP_OD_EDIT_VDDGFX_OFFSET
};
struct pp_states_info {
......
......@@ -736,6 +736,12 @@ static ssize_t amdgpu_set_pp_table(struct device *dev,
* - three <frequency, voltage> points labeled OD_VDDC_CURVE.
* They can be used to calibrate the sclk voltage curve.
*
* - voltage offset(in mV) applied on target voltage calculation.
* This is available for Sienna Cichlid, Navy Flounder and Dimgrey
* Cavefish. For these ASICs, the target voltage calculation can be
* illustrated by "voltage = voltage calculated from v/f curve +
* overdrive vddgfx offset"
*
* - a list of valid ranges for sclk, mclk, and voltage curve points
* labeled OD_RANGE
*
......@@ -756,6 +762,11 @@ static ssize_t amdgpu_set_pp_table(struct device *dev,
* 600mV. "vc 2 1000 1000" will update point3 with clock set
* as 1000Mhz and voltage 1000mV.
*
* To update the voltage offset applied for gfxclk/voltage calculation,
* enter the new value by writing a string that contains "vo offset".
* This is supported by Sienna Cichlid, Navy Flounder and Dimgrey Cavefish.
* And the offset can be a positive or negative value.
*
* - When you have edited all of the states as needed, write "c" (commit)
* to the file to commit your changes
*
......@@ -796,6 +807,8 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,
type = PP_OD_COMMIT_DPM_TABLE;
else if (!strncmp(buf, "vc", 2))
type = PP_OD_EDIT_VDDC_CURVE;
else if (!strncmp(buf, "vo", 2))
type = PP_OD_EDIT_VDDGFX_OFFSET;
else
return -EINVAL;
......@@ -803,7 +816,8 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,
tmp_str = buf_cpy;
if (type == PP_OD_EDIT_VDDC_CURVE)
if ((type == PP_OD_EDIT_VDDC_CURVE) ||
(type == PP_OD_EDIT_VDDGFX_OFFSET))
tmp_str++;
while (isspace(*++tmp_str));
......@@ -899,6 +913,7 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev,
size = smu_print_clk_levels(&adev->smu, SMU_OD_SCLK, buf);
size += smu_print_clk_levels(&adev->smu, SMU_OD_MCLK, buf+size);
size += smu_print_clk_levels(&adev->smu, SMU_OD_VDDC_CURVE, buf+size);
size += smu_print_clk_levels(&adev->smu, SMU_OD_VDDGFX_OFFSET, buf+size);
size += smu_print_clk_levels(&adev->smu, SMU_OD_RANGE, buf+size);
} else if (adev->powerplay.pp_funcs->print_clock_levels) {
size = amdgpu_dpm_print_clock_levels(adev, OD_SCLK, buf);
......
......@@ -241,6 +241,7 @@ enum smu_clk_type {
SMU_OD_MCLK,
SMU_OD_VDDC_CURVE,
SMU_OD_RANGE,
SMU_OD_VDDGFX_OFFSET,
SMU_CLK_COUNT,
};
......
......@@ -946,6 +946,7 @@ static int sienna_cichlid_print_clk_levels(struct smu_context *smu,
uint32_t mark_index = 0;
uint32_t gen_speed, lane_width;
uint32_t min_value, max_value;
uint32_t smu_version;
switch (clk_type) {
case SMU_GFXCLK:
......@@ -1043,6 +1044,23 @@ static int sienna_cichlid_print_clk_levels(struct smu_context *smu,
size += sprintf(buf + size, "0: %uMhz\n1: %uMHz\n", od_table->UclkFmin, od_table->UclkFmax);
break;
case SMU_OD_VDDGFX_OFFSET:
if (!smu->od_enabled || !od_table || !od_settings)
break;
/*
* OD GFX Voltage Offset functionality is supported only by 58.41.0
* and onwards SMU firmwares.
*/
smu_cmn_get_smc_version(smu, NULL, &smu_version);
if ((adev->asic_type == CHIP_SIENNA_CICHLID) &&
(smu_version < 0x003a2900))
break;
size += sprintf(buf + size, "OD_VDDGFX_OFFSET:\n");
size += sprintf(buf + size, "%dmV\n", od_table->VddGfxOffset);
break;
case SMU_OD_RANGE:
if (!smu->od_enabled || !od_table || !od_settings)
break;
......@@ -1770,10 +1788,18 @@ static int sienna_cichlid_get_dpm_ultimate_freq(struct smu_context *smu,
static void sienna_cichlid_dump_od_table(struct smu_context *smu,
OverDriveTable_t *od_table)
{
struct amdgpu_device *adev = smu->adev;
uint32_t smu_version;
dev_dbg(smu->adev->dev, "OD: Gfxclk: (%d, %d)\n", od_table->GfxclkFmin,
od_table->GfxclkFmax);
dev_dbg(smu->adev->dev, "OD: Uclk: (%d, %d)\n", od_table->UclkFmin,
od_table->UclkFmax);
smu_cmn_get_smc_version(smu, NULL, &smu_version);
if (!((adev->asic_type == CHIP_SIENNA_CICHLID) &&
(smu_version < 0x003a2900)))
dev_dbg(smu->adev->dev, "OD: VddGfxOffset: %d\n", od_table->VddGfxOffset);
}
static int sienna_cichlid_set_default_od_settings(struct smu_context *smu)
......@@ -1826,9 +1852,11 @@ static int sienna_cichlid_od_edit_dpm_table(struct smu_context *smu,
(OverDriveTable_t *)table_context->overdrive_table;
struct smu_11_0_7_overdrive_table *od_settings =
(struct smu_11_0_7_overdrive_table *)smu->od_settings;
struct amdgpu_device *adev = smu->adev;
enum SMU_11_0_7_ODSETTING_ID freq_setting;
uint16_t *freq_ptr;
int i, ret = 0;
uint32_t smu_version;
if (!smu->od_enabled) {
dev_warn(smu->adev->dev, "OverDrive is not enabled!\n");
......@@ -1964,6 +1992,29 @@ static int sienna_cichlid_od_edit_dpm_table(struct smu_context *smu,
}
break;
case PP_OD_EDIT_VDDGFX_OFFSET:
if (size != 1) {
dev_info(smu->adev->dev, "invalid number of parameters: %d\n", size);
return -EINVAL;
}
/*
* OD GFX Voltage Offset functionality is supported only by 58.41.0
* and onwards SMU firmwares.
*/
smu_cmn_get_smc_version(smu, NULL, &smu_version);
if ((adev->asic_type == CHIP_SIENNA_CICHLID) &&
(smu_version < 0x003a2900)) {
dev_err(smu->adev->dev, "OD GFX Voltage offset functionality is supported "
"only by 58.41.0 and onwards SMU firmwares!\n");
return -EOPNOTSUPP;
}
od_table->VddGfxOffset = (int16_t)input[0];
sienna_cichlid_dump_od_table(smu, od_table);
break;
default:
return -ENOSYS;
}
......
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