mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 02:24:24 +02:00
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: Evan Quan <evan.quan@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
37a58f6915
commit
a2b6df4fd6
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user