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

drm/amd/pm: correct SMU13 gfx voltage related OD settings

The voltage offset setting will be applied to the whole v/f curve line
instead of per anchor point base.
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 2c017263
...@@ -643,18 +643,14 @@ static ssize_t amdgpu_set_pp_table(struct device *dev, ...@@ -643,18 +643,14 @@ static ssize_t amdgpu_set_pp_table(struct device *dev,
* They can be used to calibrate the sclk voltage curve. This is * They can be used to calibrate the sclk voltage curve. This is
* available for Vega20 and NV1X. * available for Vega20 and NV1X.
* *
* - voltage offset for the six anchor points of the v/f curve labeled
* OD_VDDC_CURVE. They can be used to calibrate the v/f curve. This
* is only availabe for some SMU13 ASICs.
*
* - voltage offset(in mV) applied on target voltage calculation. * - voltage offset(in mV) applied on target voltage calculation.
* This is available for Sienna Cichlid, Navy Flounder and Dimgrey * This is available for Sienna Cichlid, Navy Flounder, Dimgrey
* Cavefish. For these ASICs, the target voltage calculation can be * Cavefish and some later SMU13 ASICs. For these ASICs, the target
* illustrated by "voltage = voltage calculated from v/f curve + * voltage calculation can be illustrated by "voltage = voltage
* overdrive vddgfx offset" * calculated from v/f curve + overdrive vddgfx offset"
* *
* - a list of valid ranges for sclk, mclk, and voltage curve points * - a list of valid ranges for sclk, mclk, voltage curve points
* labeled OD_RANGE * or voltage offset labeled OD_RANGE
* *
* < For APUs > * < For APUs >
* *
...@@ -686,24 +682,17 @@ static ssize_t amdgpu_set_pp_table(struct device *dev, ...@@ -686,24 +682,17 @@ static ssize_t amdgpu_set_pp_table(struct device *dev,
* E.g., "p 2 0 800" would set the minimum core clock on core * E.g., "p 2 0 800" would set the minimum core clock on core
* 2 to 800Mhz. * 2 to 800Mhz.
* *
* For sclk voltage curve, * For sclk voltage curve supported by Vega20 and NV1X, enter the new
* - For NV1X, enter the new values by writing a string that * values by writing a string that contains "vc point clock voltage"
* contains "vc point clock voltage" to the file. The points * to the file. The points are indexed by 0, 1 and 2. E.g., "vc 0 300
* are indexed by 0, 1 and 2. E.g., "vc 0 300 600" will update * 600" will update point1 with clock set as 300Mhz and voltage as 600mV.
* point1 with clock set as 300Mhz and voltage as 600mV. "vc 2 * "vc 2 1000 1000" will update point3 with clock set as 1000Mhz and
* 1000 1000" will update point3 with clock set as 1000Mhz and
* voltage 1000mV. * voltage 1000mV.
* - For SMU13 ASICs, enter the new values by writing a string that *
* contains "vc anchor_point_index voltage_offset" to the file. * For voltage offset supported by Sienna Cichlid, Navy Flounder, Dimgrey
* There are total six anchor points defined on the v/f curve with * Cavefish and some later SMU13 ASICs, enter the new value by writing a
* index as 0 - 5. * string that contains "vo offset". E.g., "vo -10" will update the extra
* - "vc 0 10" will update the voltage offset for point1 as 10mv. * voltage offset applied to the whole v/f curve line as -10mv.
* - "vc 5 -10" will update the voltage offset for point6 as -10mv.
*
* 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) * - When you have edited all of the states as needed, write "c" (commit)
* to the file to commit your changes * to the file to commit your changes
......
...@@ -1304,16 +1304,14 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, ...@@ -1304,16 +1304,14 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
od_table->OverDriveTable.UclkFmax); od_table->OverDriveTable.UclkFmax);
break; break;
case SMU_OD_VDDC_CURVE: case SMU_OD_VDDGFX_OFFSET:
if (!smu_v13_0_0_is_od_feature_supported(smu, if (!smu_v13_0_0_is_od_feature_supported(smu,
PP_OD_FEATURE_GFX_VF_CURVE_BIT)) PP_OD_FEATURE_GFX_VF_CURVE_BIT))
break; break;
size += sysfs_emit_at(buf, size, "OD_VDDC_CURVE:\n"); size += sysfs_emit_at(buf, size, "OD_VDDGFX_OFFSET:\n");
for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++) size += sysfs_emit_at(buf, size, "%dmV\n",
size += sysfs_emit_at(buf, size, "%d: %dmv\n", od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[0]);
i,
od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i]);
break; break;
case SMU_OD_RANGE: case SMU_OD_RANGE:
...@@ -1355,7 +1353,7 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, ...@@ -1355,7 +1353,7 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
PP_OD_FEATURE_GFX_VF_CURVE, PP_OD_FEATURE_GFX_VF_CURVE,
&min_value, &min_value,
&max_value); &max_value);
size += sysfs_emit_at(buf, size, "VDDC_CURVE: %7dmv %10dmv\n", size += sysfs_emit_at(buf, size, "VDDGFX_OFFSET: %7dmv %10dmv\n",
min_value, max_value); min_value, max_value);
} }
break; break;
...@@ -1504,29 +1502,26 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, ...@@ -1504,29 +1502,26 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
} }
break; break;
case PP_OD_EDIT_VDDC_CURVE: case PP_OD_EDIT_VDDGFX_OFFSET:
if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) { if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) {
dev_warn(adev->dev, "VF curve setting not supported!\n"); dev_warn(adev->dev, "Gfx offset setting not supported!\n");
return -ENOTSUPP; return -ENOTSUPP;
} }
if (input[0] >= PP_NUM_OD_VF_CURVE_POINTS ||
input[0] < 0)
return -EINVAL;
smu_v13_0_0_get_od_setting_limits(smu, smu_v13_0_0_get_od_setting_limits(smu,
PP_OD_FEATURE_GFX_VF_CURVE, PP_OD_FEATURE_GFX_VF_CURVE,
&minimum, &minimum,
&maximum); &maximum);
if (input[1] < minimum || if (input[0] < minimum ||
input[1] > maximum) { input[0] > maximum) {
dev_info(adev->dev, "Voltage offset (%ld) must be within [%d, %d]!\n", dev_info(adev->dev, "Voltage offset (%ld) must be within [%d, %d]!\n",
input[1], minimum, maximum); input[0], minimum, maximum);
return -EINVAL; return -EINVAL;
} }
od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[input[0]] = input[1]; for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++)
od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFX_VF_CURVE_BIT; od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i] = input[0];
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT);
break; break;
case PP_OD_RESTORE_DEFAULT_TABLE: case PP_OD_RESTORE_DEFAULT_TABLE:
......
...@@ -1284,16 +1284,14 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, ...@@ -1284,16 +1284,14 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
od_table->OverDriveTable.UclkFmax); od_table->OverDriveTable.UclkFmax);
break; break;
case SMU_OD_VDDC_CURVE: case SMU_OD_VDDGFX_OFFSET:
if (!smu_v13_0_7_is_od_feature_supported(smu, if (!smu_v13_0_7_is_od_feature_supported(smu,
PP_OD_FEATURE_GFX_VF_CURVE_BIT)) PP_OD_FEATURE_GFX_VF_CURVE_BIT))
break; break;
size += sysfs_emit_at(buf, size, "OD_VDDC_CURVE:\n"); size += sysfs_emit_at(buf, size, "OD_VDDGFX_OFFSET:\n");
for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++) size += sysfs_emit_at(buf, size, "%dmV\n",
size += sysfs_emit_at(buf, size, "%d: %dmv\n", od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[0]);
i,
od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i]);
break; break;
case SMU_OD_RANGE: case SMU_OD_RANGE:
...@@ -1335,7 +1333,7 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, ...@@ -1335,7 +1333,7 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
PP_OD_FEATURE_GFX_VF_CURVE, PP_OD_FEATURE_GFX_VF_CURVE,
&min_value, &min_value,
&max_value); &max_value);
size += sysfs_emit_at(buf, size, "VDDC_CURVE: %7dmv %10dmv\n", size += sysfs_emit_at(buf, size, "VDDGFX_OFFSET: %7dmv %10dmv\n",
min_value, max_value); min_value, max_value);
} }
break; break;
...@@ -1484,29 +1482,26 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, ...@@ -1484,29 +1482,26 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu,
} }
break; break;
case PP_OD_EDIT_VDDC_CURVE: case PP_OD_EDIT_VDDGFX_OFFSET:
if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) { if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) {
dev_warn(adev->dev, "VF curve setting not supported!\n"); dev_warn(adev->dev, "Gfx offset setting not supported!\n");
return -ENOTSUPP; return -ENOTSUPP;
} }
if (input[0] >= PP_NUM_OD_VF_CURVE_POINTS ||
input[0] < 0)
return -EINVAL;
smu_v13_0_7_get_od_setting_limits(smu, smu_v13_0_7_get_od_setting_limits(smu,
PP_OD_FEATURE_GFX_VF_CURVE, PP_OD_FEATURE_GFX_VF_CURVE,
&minimum, &minimum,
&maximum); &maximum);
if (input[1] < minimum || if (input[0] < minimum ||
input[1] > maximum) { input[0] > maximum) {
dev_info(adev->dev, "Voltage offset (%ld) must be within [%d, %d]!\n", dev_info(adev->dev, "Voltage offset (%ld) must be within [%d, %d]!\n",
input[1], minimum, maximum); input[0], minimum, maximum);
return -EINVAL; return -EINVAL;
} }
od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[input[0]] = input[1]; for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++)
od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFX_VF_CURVE_BIT; od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i] = input[0];
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT);
break; break;
case PP_OD_RESTORE_DEFAULT_TABLE: case PP_OD_RESTORE_DEFAULT_TABLE:
......
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