* [PATCH 0/3] navi10: Implement overdrive pp_od_clk_voltage
@ 2019-11-07 18:32 ` Matt Coffin
0 siblings, 0 replies; 14+ messages in thread
From: Matt Coffin @ 2019-11-07 18:32 UTC (permalink / raw)
To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Matt Coffin
[Why]
Before this patchset, navi10 users could not utilize the overdrive
functionality. This prevented them from overclocking, overvolting, or
undervolting their cards.
[How]
Similar to the vega20 implementation, add the pp_od_clk_voltage
interface to the navi10 powerplay table.
[Possible Alternatives]
This could also be done more generically in smu_v11_0 code, but would
require more significant changes to the vega20 code, and feature-gating
based on chip capabilities in the smu to disable overdrive for arcterus.
I chose this path so as not to completely refactor the vega20 side of
things, and introduce SMU code which would not play nicely with new
ASICs.
Matt Coffin (3):
drm/amdgpu/navi10: implement sclk/mclk OD via pp_od_clk_voltage
drm/amdgpu/navi10: implement GFXCLK_CURVE overdrive
drm/amdgpu/navi10: Implement od clk printing
drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h | 1 +
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 282 ++++++++++++++++++
drivers/gpu/drm/amd/powerplay/navi10_ppt.h | 2 +
drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 27 ++
4 files changed, 312 insertions(+)
--
2.23.0
From 8573e9199daf592f6e6e5a807b69b37bb80f156a Mon Sep 17 00:00:00 2001
Message-Id: <8573e9199daf592f6e6e5a807b69b37bb80f156a.1573151434.git.mcoffin13@gmail.com>
In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
References: <cover.1573151434.git.mcoffin13@gmail.com>
From: Matt Coffin <mcoffin13@gmail.com>
Date: Sat, 2 Nov 2019 02:24:09 -0600
Subject: [PATCH 1/3] drm/amdgpu/navi10: implement sclk/mclk OD via
pp_od_clk_voltage
To: amd-gfx@lists.freedesktop.org
[Why]
Before this patch, there was no way to use pp_od_clk_voltage on navi
[How]
Similar to the vega20 implementation, but using the common smc_v11_0
headers, implemented the pp_od_clk_voltage API for navi10's pptable
implementation
---
drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h | 1 +
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 185 ++++++++++++++++++
drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 27 +++
3 files changed, 213 insertions(+)
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
index 5bda8539447a..133a53da6785 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
@@ -130,6 +130,7 @@ enum smu_v11_0_baco_seq {
BACO_SEQ_COUNT,
};
+int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize, size_t overdrive_table_size);
void smu_v11_0_set_smu_funcs(struct smu_context *smu);
#endif
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index 0b461404af6b..6d0e511ad093 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -1591,6 +1591,189 @@ static int navi10_get_power_limit(struct smu_context *smu,
return 0;
}
+static inline void navi10_dump_od_table(OverDriveTable_t *od_table) {
+ pr_debug("OD: Gfxclk: (%d, %d)\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
+ pr_debug("OD: Gfx1: (%d, %d)\n", od_table->GfxclkFreq1, od_table->GfxclkVolt1);
+ pr_debug("OD: Gfx2: (%d, %d)\n", od_table->GfxclkFreq2, od_table->GfxclkVolt2);
+ pr_debug("OD: Gfx3: (%d, %d)\n", od_table->GfxclkFreq3, od_table->GfxclkVolt3);
+ pr_debug("OD: UclkFmax: %d\n", od_table->UclkFmax);
+ pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
+}
+
+static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
+{
+ return od_table->cap[feature];
+}
+
+static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
+{
+ if (value < od_table->min[setting]) {
+ pr_warn("OD setting (%d, %d) is less than the minimum allowed (%d)\n", setting, value, od_table->min[setting]);
+ return -EINVAL;
+ }
+ if (value > od_table->max[setting]) {
+ pr_warn("OD setting (%d, %d) is greater than the maximum allowed (%d)\n", setting, value, od_table->max[setting]);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int navi10_setup_od_limits(struct smu_context *smu) {
+ struct smu_11_0_overdrive_table *overdrive_table = NULL;
+ struct smu_11_0_powerplay_table *powerplay_table = NULL;
+
+ if (!smu->smu_table.power_play_table) {
+ pr_err("powerplay table uninitialized!\n");
+ return -ENOENT;
+ }
+ powerplay_table = (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
+ overdrive_table = &powerplay_table->overdrive_table;
+ if (!smu->od_settings) {
+ smu->od_settings = kmemdup(overdrive_table, sizeof(struct smu_11_0_overdrive_table), GFP_KERNEL);
+ } else {
+ memcpy(smu->od_settings, overdrive_table, sizeof(struct smu_11_0_overdrive_table));
+ }
+ return 0;
+}
+
+static int navi10_set_default_od_settings(struct smu_context *smu, bool initialize) {
+ OverDriveTable_t *od_table;
+ int ret = 0;
+
+ ret = smu_v11_0_set_default_od_settings(smu, initialize, sizeof(OverDriveTable_t));
+ if (ret)
+ return ret;
+
+ if (initialize) {
+ ret = navi10_setup_od_limits(smu);
+ if (ret) {
+ pr_err("Failed to retrieve board OD limits\n");
+ return ret;
+ }
+
+ }
+
+ od_table = (OverDriveTable_t *)smu->smu_table.overdrive_table;
+ if (od_table) {
+ navi10_dump_od_table(od_table);
+ }
+
+ return ret;
+}
+
+static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) {
+ int i;
+ int ret = 0;
+ struct smu_table_context *table_context = &smu->smu_table;
+ OverDriveTable_t *od_table;
+ struct smu_11_0_overdrive_table *od_settings;
+ od_table = (OverDriveTable_t *)table_context->overdrive_table;
+
+ if (!smu->od_enabled) {
+ pr_warn("OverDrive is not enabled!\n");
+ return -EINVAL;
+ }
+
+ if (!smu->od_settings) {
+ pr_err("OD board limits are not set!\n");
+ return -ENOENT;
+ }
+
+ od_settings = smu->od_settings;
+
+ switch (type) {
+ case PP_OD_EDIT_SCLK_VDDC_TABLE:
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS)) {
+ pr_warn("GFXCLK_LIMITS not supported!\n");
+ return -ENOTSUPP;
+ }
+ if (!table_context->overdrive_table) {
+ pr_err("Overdrive is not initialized\n");
+ return -EINVAL;
+ }
+ if (input[0] > input[1]) {
+ pr_info("GfxclkFmin must be less than GfxclkFmax\n");
+ return -EINVAL;
+ }
+ for (i = 0; i < size; i += 2) {
+ if (i + 2 > size) {
+ pr_info("invalid number of input parameters %d\n", size);
+ return -EINVAL;
+ }
+ switch (input[i]) {
+ case 0:
+ freq_setting = SMU_11_0_ODSETTING_GFXCLKFMIN;
+ freq_ptr = &od_table->GfxclkFmin;
+ if (input[i + 1] > od_table->GfxclkFmax) {
+ pr_info("GfxclkFmin (%ld) must be <= GfxclkFmax (%u)!\n",
+ input[i + 1],
+ od_table->GfxclkFmin);
+ return -EINVAL;
+ }
+ break;
+ case 1:
+ freq_setting = SMU_11_0_ODSETTING_GFXCLKFMAX;
+ freq_ptr = &od_table->GfxclkFmax;
+ if (input[i + 1] < od_table->GfxclkFmin) {
+ pr_info("GfxclkFmax (%ld) must be >= GfxclkFmin (%u)!\n",
+ input[i + 1],
+ od_table->GfxclkFmax);
+ return -EINVAL;
+ }
+ break;
+ default:
+ pr_info("Invalid SCLK_VDDC_TABLE index: %ld\n", input[i]);
+ pr_info("Supported indices: [0:min,1:max]\n");
+ return -EINVAL;
+ }
+ ret = navi10_od_setting_check_range(od_settings, freq_setting, input[i + 1]);
+ if (ret)
+ return ret;
+ *freq_ptr = input[i + 1];
+ }
+ break;
+ case PP_OD_EDIT_MCLK_VDDC_TABLE:
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX)) {
+ pr_warn("UCLK_MAX not supported!\n");
+ return -ENOTSUPP;
+ }
+ if (size < 2) {
+ pr_info("invalid number of parameters: %d\n", size);
+ return -EINVAL;
+ }
+ if (input[0] != 1) {
+ pr_info("Invalid MCLK_VDDC_TABLE index: %ld\n", input[0]);
+ pr_info("Supported indices: [1:max]\n");
+ return -EINVAL;
+ }
+ ret = navi10_od_setting_check_range(od_settings, SMU_11_0_ODSETTING_UCLKFMAX, input[1]);
+ if (ret)
+ return ret;
+ od_table->UclkFmax = input[1];
+ break;
+ case PP_OD_COMMIT_DPM_TABLE:
+ navi10_dump_od_table(od_table);
+ ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, (void *)od_table, true);
+ if (ret) {
+ pr_err("Failed to import overdrive table!\n");
+ return ret;
+ }
+ mutex_lock(&(smu->mutex));
+ ret = smu_handle_task(smu, smu->smu_dpm.dpm_level, AMD_PP_TASK_READJUST_POWER_STATE);
+ mutex_unlock(&(smu->mutex));
+ if (ret) {
+ return ret;
+ }
+ break;
+ case PP_OD_EDIT_VDDC_CURVE:
+ // TODO: implement
+ return -ENOSYS;
+ default:
+ return -ENOSYS;
+ }
+ return ret;
+}
+
static const struct pptable_funcs navi10_ppt_funcs = {
.tables_init = navi10_tables_init,
.alloc_dpm_context = navi10_allocate_dpm_context,
@@ -1629,6 +1812,8 @@ static const struct pptable_funcs navi10_ppt_funcs = {
.get_thermal_temperature_range = navi10_get_thermal_temperature_range,
.display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch,
.get_power_limit = navi10_get_power_limit,
+ .set_default_od_settings = navi10_set_default_od_settings,
+ .od_edit_dpm_table = navi10_od_edit_dpm_table,
};
void navi10_set_ppt_funcs(struct smu_context *smu)
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
index c5257ae3188a..029f0896146a 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
@@ -1828,3 +1828,30 @@ void smu_v11_0_set_smu_funcs(struct smu_context *smu)
pr_warn("Unknown asic for smu11\n");
}
}
+
+int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize, size_t overdrive_table_size)
+{
+ struct smu_table_context *table_context = &smu->smu_table;
+ int ret = 0;
+
+ if (initialize) {
+ if (table_context->overdrive_table) {
+ return -EINVAL;
+ }
+ table_context->overdrive_table = kzalloc(overdrive_table_size, GFP_KERNEL);
+ if (!table_context->overdrive_table) {
+ return -ENOMEM;
+ }
+ ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, table_context->overdrive_table, false);
+ if (ret) {
+ pr_err("Failed to export overdrive table!\n");
+ return ret;
+ }
+ }
+ ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, table_context->overdrive_table, true);
+ if (ret) {
+ pr_err("Failed to import overdrive table!\n");
+ return ret;
+ }
+ return ret;
+}
--
2.23.0
From 7bc07e0b053381ce7409d8251be18380fb6b3c43 Mon Sep 17 00:00:00 2001
Message-Id: <7bc07e0b053381ce7409d8251be18380fb6b3c43.1573151434.git.mcoffin13@gmail.com>
In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
References: <cover.1573151434.git.mcoffin13@gmail.com>
From: Matt Coffin <mcoffin13@gmail.com>
Date: Tue, 5 Nov 2019 12:39:27 -0700
Subject: [PATCH 2/3] drm/amdgpu/navi10: implement GFXCLK_CURVE overdrive
To: amd-gfx@lists.freedesktop.org
[Why]
Before this patch, there was no way to set the gfxclk voltage curve in
the overdrive settings for navi10 through pp_od_clk_voltage
[How]
Add the required implementation to navi10's ppt dpm table editing
implementation, similar to the vega20 implementation and interface.
---
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 55 +++++++++++++++++++++-
drivers/gpu/drm/amd/powerplay/navi10_ppt.h | 2 +
2 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index 6d0e511ad093..e717328f93ce 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -1667,6 +1667,8 @@ static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABL
struct smu_table_context *table_context = &smu->smu_table;
OverDriveTable_t *od_table;
struct smu_11_0_overdrive_table *od_settings;
+ enum SMU_11_0_ODSETTING_ID freq_setting, voltage_setting;
+ uint16_t *freq_ptr, *voltage_ptr;
od_table = (OverDriveTable_t *)table_context->overdrive_table;
if (!smu->od_enabled) {
@@ -1766,8 +1768,57 @@ static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABL
}
break;
case PP_OD_EDIT_VDDC_CURVE:
- // TODO: implement
- return -ENOSYS;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE)) {
+ pr_warn("GFXCLK_CURVE not supported!\n");
+ return -ENOTSUPP;
+ }
+ if (size < 3) {
+ pr_info("invalid number of parameters: %d\n", size);
+ return -EINVAL;
+ }
+ if (!od_table) {
+ pr_info("Overdrive is not initialized\n");
+ return -EINVAL;
+ }
+
+ switch (input[0]) {
+ case 0:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1;
+ freq_ptr = &od_table->GfxclkFreq1;
+ voltage_ptr = &od_table->GfxclkVolt1;
+ break;
+ case 1:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2;
+ freq_ptr = &od_table->GfxclkFreq2;
+ voltage_ptr = &od_table->GfxclkVolt2;
+ break;
+ case 2:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3;
+ freq_ptr = &od_table->GfxclkFreq3;
+ voltage_ptr = &od_table->GfxclkVolt3;
+ break;
+ default:
+ pr_info("Invalid VDDC_CURVE index: %ld\n", input[0]);
+ pr_info("Supported indices: [0, 1, 2]\n");
+ return -EINVAL;
+ }
+ ret = navi10_od_setting_check_range(od_settings, freq_setting, input[1]);
+ if (ret)
+ return ret;
+ // Allow setting zero to disable the OverDrive VDDC curve
+ if (input[2] != 0) {
+ ret = navi10_od_setting_check_range(od_settings, voltage_setting, input[2]);
+ if (ret)
+ return ret;
+ }
+ *freq_ptr = input[1];
+ *voltage_ptr = ((uint16_t)input[2]) * NAVI10_VOLTAGE_SCALE;
+ pr_debug("OD: set curve %ld: (%d, %d)\n", input[0], *freq_ptr, *voltage_ptr);
+ navi10_dump_od_table(od_table);
+ break;
default:
return -ENOSYS;
}
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
index 620ff17c2fef..484d2c58fc06 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
@@ -27,6 +27,8 @@
#define NAVI10_PEAK_SCLK_XT (1755)
#define NAVI10_PEAK_SCLK_XL (1625)
+#define NAVI10_VOLTAGE_SCALE (4)
+
extern void navi10_set_ppt_funcs(struct smu_context *smu);
#endif
--
2.23.0
From e091c4085ecc669ea907fe5d8515f14586863f9b Mon Sep 17 00:00:00 2001
Message-Id: <e091c4085ecc669ea907fe5d8515f14586863f9b.1573151434.git.mcoffin13@gmail.com>
In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
References: <cover.1573151434.git.mcoffin13@gmail.com>
From: Matt Coffin <mcoffin13@gmail.com>
Date: Wed, 6 Nov 2019 12:05:28 -0700
Subject: [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
To: amd-gfx@lists.freedesktop.org
[Why]
Before this patch, navi10 overdrive settings could not be printed via
pp_od_clk_voltage
[How]
Implement printing for the overdrive settings for the following clocks
in navi10's ppt print_clk_levels implementation:
* SMU_OD_SCLK
* SMU_OD_MCLK
* SMU_OD_VDDC_CURVE
---
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 ++++++++++++++++++++--
1 file changed, 51 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index e717328f93ce..506af59ff45f 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -677,13 +677,25 @@ static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu
return dpm_desc->SnapToDiscrete == 0 ? true : false;
}
+static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
+{
+ return od_table->cap[feature];
+}
+
+
static int navi10_print_clk_levels(struct smu_context *smu,
enum smu_clk_type clk_type, char *buf)
{
+ OverDriveTable_t *od_table;
+ struct smu_11_0_overdrive_table *od_settings;
+ uint16_t *curve_settings;
int i, size = 0, ret = 0;
uint32_t cur_value = 0, value = 0, count = 0;
uint32_t freq_values[3] = {0};
uint32_t mark_index = 0;
+ struct smu_table_context *table_context = &smu->smu_table;
+ od_table = (OverDriveTable_t *)table_context->overdrive_table;
+ od_settings = smu->od_settings;
switch (clk_type) {
case SMU_GFXCLK:
@@ -734,6 +746,45 @@ static int navi10_print_clk_levels(struct smu_context *smu,
}
break;
+ case SMU_OD_SCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS))
+ break;
+ size += sprintf(buf + size, "OD_SCLK:\n");
+ size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
+ break;
+ case SMU_OD_MCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX))
+ break;
+ size += sprintf(buf + size, "OD_MCLK:\n");
+ size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
+ break;
+ case SMU_OD_VDDC_CURVE:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE))
+ break;
+ size += sprintf(buf + size, "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;
+ }
+ size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i, curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
+ }
+ break;
default:
break;
}
@@ -1600,11 +1651,6 @@ static inline void navi10_dump_od_table(OverDriveTable_t *od_table) {
pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
}
-static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
-{
- return od_table->cap[feature];
-}
-
static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
{
if (value < od_table->min[setting]) {
--
2.23.0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 0/3] navi10: Implement overdrive pp_od_clk_voltage
@ 2019-11-07 18:32 ` Matt Coffin
0 siblings, 0 replies; 14+ messages in thread
From: Matt Coffin @ 2019-11-07 18:32 UTC (permalink / raw)
To: amd-gfx; +Cc: Matt Coffin
[Why]
Before this patchset, navi10 users could not utilize the overdrive
functionality. This prevented them from overclocking, overvolting, or
undervolting their cards.
[How]
Similar to the vega20 implementation, add the pp_od_clk_voltage
interface to the navi10 powerplay table.
[Possible Alternatives]
This could also be done more generically in smu_v11_0 code, but would
require more significant changes to the vega20 code, and feature-gating
based on chip capabilities in the smu to disable overdrive for arcterus.
I chose this path so as not to completely refactor the vega20 side of
things, and introduce SMU code which would not play nicely with new
ASICs.
Matt Coffin (3):
drm/amdgpu/navi10: implement sclk/mclk OD via pp_od_clk_voltage
drm/amdgpu/navi10: implement GFXCLK_CURVE overdrive
drm/amdgpu/navi10: Implement od clk printing
drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h | 1 +
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 282 ++++++++++++++++++
drivers/gpu/drm/amd/powerplay/navi10_ppt.h | 2 +
drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 27 ++
4 files changed, 312 insertions(+)
--
2.23.0
From 8573e9199daf592f6e6e5a807b69b37bb80f156a Mon Sep 17 00:00:00 2001
Message-Id: <8573e9199daf592f6e6e5a807b69b37bb80f156a.1573151434.git.mcoffin13@gmail.com>
In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
References: <cover.1573151434.git.mcoffin13@gmail.com>
From: Matt Coffin <mcoffin13@gmail.com>
Date: Sat, 2 Nov 2019 02:24:09 -0600
Subject: [PATCH 1/3] drm/amdgpu/navi10: implement sclk/mclk OD via
pp_od_clk_voltage
To: amd-gfx@lists.freedesktop.org
[Why]
Before this patch, there was no way to use pp_od_clk_voltage on navi
[How]
Similar to the vega20 implementation, but using the common smc_v11_0
headers, implemented the pp_od_clk_voltage API for navi10's pptable
implementation
---
drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h | 1 +
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 185 ++++++++++++++++++
drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 27 +++
3 files changed, 213 insertions(+)
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
index 5bda8539447a..133a53da6785 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
@@ -130,6 +130,7 @@ enum smu_v11_0_baco_seq {
BACO_SEQ_COUNT,
};
+int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize, size_t overdrive_table_size);
void smu_v11_0_set_smu_funcs(struct smu_context *smu);
#endif
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index 0b461404af6b..6d0e511ad093 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -1591,6 +1591,189 @@ static int navi10_get_power_limit(struct smu_context *smu,
return 0;
}
+static inline void navi10_dump_od_table(OverDriveTable_t *od_table) {
+ pr_debug("OD: Gfxclk: (%d, %d)\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
+ pr_debug("OD: Gfx1: (%d, %d)\n", od_table->GfxclkFreq1, od_table->GfxclkVolt1);
+ pr_debug("OD: Gfx2: (%d, %d)\n", od_table->GfxclkFreq2, od_table->GfxclkVolt2);
+ pr_debug("OD: Gfx3: (%d, %d)\n", od_table->GfxclkFreq3, od_table->GfxclkVolt3);
+ pr_debug("OD: UclkFmax: %d\n", od_table->UclkFmax);
+ pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
+}
+
+static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
+{
+ return od_table->cap[feature];
+}
+
+static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
+{
+ if (value < od_table->min[setting]) {
+ pr_warn("OD setting (%d, %d) is less than the minimum allowed (%d)\n", setting, value, od_table->min[setting]);
+ return -EINVAL;
+ }
+ if (value > od_table->max[setting]) {
+ pr_warn("OD setting (%d, %d) is greater than the maximum allowed (%d)\n", setting, value, od_table->max[setting]);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int navi10_setup_od_limits(struct smu_context *smu) {
+ struct smu_11_0_overdrive_table *overdrive_table = NULL;
+ struct smu_11_0_powerplay_table *powerplay_table = NULL;
+
+ if (!smu->smu_table.power_play_table) {
+ pr_err("powerplay table uninitialized!\n");
+ return -ENOENT;
+ }
+ powerplay_table = (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
+ overdrive_table = &powerplay_table->overdrive_table;
+ if (!smu->od_settings) {
+ smu->od_settings = kmemdup(overdrive_table, sizeof(struct smu_11_0_overdrive_table), GFP_KERNEL);
+ } else {
+ memcpy(smu->od_settings, overdrive_table, sizeof(struct smu_11_0_overdrive_table));
+ }
+ return 0;
+}
+
+static int navi10_set_default_od_settings(struct smu_context *smu, bool initialize) {
+ OverDriveTable_t *od_table;
+ int ret = 0;
+
+ ret = smu_v11_0_set_default_od_settings(smu, initialize, sizeof(OverDriveTable_t));
+ if (ret)
+ return ret;
+
+ if (initialize) {
+ ret = navi10_setup_od_limits(smu);
+ if (ret) {
+ pr_err("Failed to retrieve board OD limits\n");
+ return ret;
+ }
+
+ }
+
+ od_table = (OverDriveTable_t *)smu->smu_table.overdrive_table;
+ if (od_table) {
+ navi10_dump_od_table(od_table);
+ }
+
+ return ret;
+}
+
+static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) {
+ int i;
+ int ret = 0;
+ struct smu_table_context *table_context = &smu->smu_table;
+ OverDriveTable_t *od_table;
+ struct smu_11_0_overdrive_table *od_settings;
+ od_table = (OverDriveTable_t *)table_context->overdrive_table;
+
+ if (!smu->od_enabled) {
+ pr_warn("OverDrive is not enabled!\n");
+ return -EINVAL;
+ }
+
+ if (!smu->od_settings) {
+ pr_err("OD board limits are not set!\n");
+ return -ENOENT;
+ }
+
+ od_settings = smu->od_settings;
+
+ switch (type) {
+ case PP_OD_EDIT_SCLK_VDDC_TABLE:
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS)) {
+ pr_warn("GFXCLK_LIMITS not supported!\n");
+ return -ENOTSUPP;
+ }
+ if (!table_context->overdrive_table) {
+ pr_err("Overdrive is not initialized\n");
+ return -EINVAL;
+ }
+ if (input[0] > input[1]) {
+ pr_info("GfxclkFmin must be less than GfxclkFmax\n");
+ return -EINVAL;
+ }
+ for (i = 0; i < size; i += 2) {
+ if (i + 2 > size) {
+ pr_info("invalid number of input parameters %d\n", size);
+ return -EINVAL;
+ }
+ switch (input[i]) {
+ case 0:
+ freq_setting = SMU_11_0_ODSETTING_GFXCLKFMIN;
+ freq_ptr = &od_table->GfxclkFmin;
+ if (input[i + 1] > od_table->GfxclkFmax) {
+ pr_info("GfxclkFmin (%ld) must be <= GfxclkFmax (%u)!\n",
+ input[i + 1],
+ od_table->GfxclkFmin);
+ return -EINVAL;
+ }
+ break;
+ case 1:
+ freq_setting = SMU_11_0_ODSETTING_GFXCLKFMAX;
+ freq_ptr = &od_table->GfxclkFmax;
+ if (input[i + 1] < od_table->GfxclkFmin) {
+ pr_info("GfxclkFmax (%ld) must be >= GfxclkFmin (%u)!\n",
+ input[i + 1],
+ od_table->GfxclkFmax);
+ return -EINVAL;
+ }
+ break;
+ default:
+ pr_info("Invalid SCLK_VDDC_TABLE index: %ld\n", input[i]);
+ pr_info("Supported indices: [0:min,1:max]\n");
+ return -EINVAL;
+ }
+ ret = navi10_od_setting_check_range(od_settings, freq_setting, input[i + 1]);
+ if (ret)
+ return ret;
+ *freq_ptr = input[i + 1];
+ }
+ break;
+ case PP_OD_EDIT_MCLK_VDDC_TABLE:
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX)) {
+ pr_warn("UCLK_MAX not supported!\n");
+ return -ENOTSUPP;
+ }
+ if (size < 2) {
+ pr_info("invalid number of parameters: %d\n", size);
+ return -EINVAL;
+ }
+ if (input[0] != 1) {
+ pr_info("Invalid MCLK_VDDC_TABLE index: %ld\n", input[0]);
+ pr_info("Supported indices: [1:max]\n");
+ return -EINVAL;
+ }
+ ret = navi10_od_setting_check_range(od_settings, SMU_11_0_ODSETTING_UCLKFMAX, input[1]);
+ if (ret)
+ return ret;
+ od_table->UclkFmax = input[1];
+ break;
+ case PP_OD_COMMIT_DPM_TABLE:
+ navi10_dump_od_table(od_table);
+ ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, (void *)od_table, true);
+ if (ret) {
+ pr_err("Failed to import overdrive table!\n");
+ return ret;
+ }
+ mutex_lock(&(smu->mutex));
+ ret = smu_handle_task(smu, smu->smu_dpm.dpm_level, AMD_PP_TASK_READJUST_POWER_STATE);
+ mutex_unlock(&(smu->mutex));
+ if (ret) {
+ return ret;
+ }
+ break;
+ case PP_OD_EDIT_VDDC_CURVE:
+ // TODO: implement
+ return -ENOSYS;
+ default:
+ return -ENOSYS;
+ }
+ return ret;
+}
+
static const struct pptable_funcs navi10_ppt_funcs = {
.tables_init = navi10_tables_init,
.alloc_dpm_context = navi10_allocate_dpm_context,
@@ -1629,6 +1812,8 @@ static const struct pptable_funcs navi10_ppt_funcs = {
.get_thermal_temperature_range = navi10_get_thermal_temperature_range,
.display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch,
.get_power_limit = navi10_get_power_limit,
+ .set_default_od_settings = navi10_set_default_od_settings,
+ .od_edit_dpm_table = navi10_od_edit_dpm_table,
};
void navi10_set_ppt_funcs(struct smu_context *smu)
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
index c5257ae3188a..029f0896146a 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
@@ -1828,3 +1828,30 @@ void smu_v11_0_set_smu_funcs(struct smu_context *smu)
pr_warn("Unknown asic for smu11\n");
}
}
+
+int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize, size_t overdrive_table_size)
+{
+ struct smu_table_context *table_context = &smu->smu_table;
+ int ret = 0;
+
+ if (initialize) {
+ if (table_context->overdrive_table) {
+ return -EINVAL;
+ }
+ table_context->overdrive_table = kzalloc(overdrive_table_size, GFP_KERNEL);
+ if (!table_context->overdrive_table) {
+ return -ENOMEM;
+ }
+ ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, table_context->overdrive_table, false);
+ if (ret) {
+ pr_err("Failed to export overdrive table!\n");
+ return ret;
+ }
+ }
+ ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, table_context->overdrive_table, true);
+ if (ret) {
+ pr_err("Failed to import overdrive table!\n");
+ return ret;
+ }
+ return ret;
+}
--
2.23.0
From 7bc07e0b053381ce7409d8251be18380fb6b3c43 Mon Sep 17 00:00:00 2001
Message-Id: <7bc07e0b053381ce7409d8251be18380fb6b3c43.1573151434.git.mcoffin13@gmail.com>
In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
References: <cover.1573151434.git.mcoffin13@gmail.com>
From: Matt Coffin <mcoffin13@gmail.com>
Date: Tue, 5 Nov 2019 12:39:27 -0700
Subject: [PATCH 2/3] drm/amdgpu/navi10: implement GFXCLK_CURVE overdrive
To: amd-gfx@lists.freedesktop.org
[Why]
Before this patch, there was no way to set the gfxclk voltage curve in
the overdrive settings for navi10 through pp_od_clk_voltage
[How]
Add the required implementation to navi10's ppt dpm table editing
implementation, similar to the vega20 implementation and interface.
---
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 55 +++++++++++++++++++++-
drivers/gpu/drm/amd/powerplay/navi10_ppt.h | 2 +
2 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index 6d0e511ad093..e717328f93ce 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -1667,6 +1667,8 @@ static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABL
struct smu_table_context *table_context = &smu->smu_table;
OverDriveTable_t *od_table;
struct smu_11_0_overdrive_table *od_settings;
+ enum SMU_11_0_ODSETTING_ID freq_setting, voltage_setting;
+ uint16_t *freq_ptr, *voltage_ptr;
od_table = (OverDriveTable_t *)table_context->overdrive_table;
if (!smu->od_enabled) {
@@ -1766,8 +1768,57 @@ static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABL
}
break;
case PP_OD_EDIT_VDDC_CURVE:
- // TODO: implement
- return -ENOSYS;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE)) {
+ pr_warn("GFXCLK_CURVE not supported!\n");
+ return -ENOTSUPP;
+ }
+ if (size < 3) {
+ pr_info("invalid number of parameters: %d\n", size);
+ return -EINVAL;
+ }
+ if (!od_table) {
+ pr_info("Overdrive is not initialized\n");
+ return -EINVAL;
+ }
+
+ switch (input[0]) {
+ case 0:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1;
+ freq_ptr = &od_table->GfxclkFreq1;
+ voltage_ptr = &od_table->GfxclkVolt1;
+ break;
+ case 1:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2;
+ freq_ptr = &od_table->GfxclkFreq2;
+ voltage_ptr = &od_table->GfxclkVolt2;
+ break;
+ case 2:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3;
+ freq_ptr = &od_table->GfxclkFreq3;
+ voltage_ptr = &od_table->GfxclkVolt3;
+ break;
+ default:
+ pr_info("Invalid VDDC_CURVE index: %ld\n", input[0]);
+ pr_info("Supported indices: [0, 1, 2]\n");
+ return -EINVAL;
+ }
+ ret = navi10_od_setting_check_range(od_settings, freq_setting, input[1]);
+ if (ret)
+ return ret;
+ // Allow setting zero to disable the OverDrive VDDC curve
+ if (input[2] != 0) {
+ ret = navi10_od_setting_check_range(od_settings, voltage_setting, input[2]);
+ if (ret)
+ return ret;
+ }
+ *freq_ptr = input[1];
+ *voltage_ptr = ((uint16_t)input[2]) * NAVI10_VOLTAGE_SCALE;
+ pr_debug("OD: set curve %ld: (%d, %d)\n", input[0], *freq_ptr, *voltage_ptr);
+ navi10_dump_od_table(od_table);
+ break;
default:
return -ENOSYS;
}
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
index 620ff17c2fef..484d2c58fc06 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
@@ -27,6 +27,8 @@
#define NAVI10_PEAK_SCLK_XT (1755)
#define NAVI10_PEAK_SCLK_XL (1625)
+#define NAVI10_VOLTAGE_SCALE (4)
+
extern void navi10_set_ppt_funcs(struct smu_context *smu);
#endif
--
2.23.0
From e091c4085ecc669ea907fe5d8515f14586863f9b Mon Sep 17 00:00:00 2001
Message-Id: <e091c4085ecc669ea907fe5d8515f14586863f9b.1573151434.git.mcoffin13@gmail.com>
In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
References: <cover.1573151434.git.mcoffin13@gmail.com>
From: Matt Coffin <mcoffin13@gmail.com>
Date: Wed, 6 Nov 2019 12:05:28 -0700
Subject: [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
To: amd-gfx@lists.freedesktop.org
[Why]
Before this patch, navi10 overdrive settings could not be printed via
pp_od_clk_voltage
[How]
Implement printing for the overdrive settings for the following clocks
in navi10's ppt print_clk_levels implementation:
* SMU_OD_SCLK
* SMU_OD_MCLK
* SMU_OD_VDDC_CURVE
---
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 ++++++++++++++++++++--
1 file changed, 51 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index e717328f93ce..506af59ff45f 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -677,13 +677,25 @@ static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu
return dpm_desc->SnapToDiscrete == 0 ? true : false;
}
+static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
+{
+ return od_table->cap[feature];
+}
+
+
static int navi10_print_clk_levels(struct smu_context *smu,
enum smu_clk_type clk_type, char *buf)
{
+ OverDriveTable_t *od_table;
+ struct smu_11_0_overdrive_table *od_settings;
+ uint16_t *curve_settings;
int i, size = 0, ret = 0;
uint32_t cur_value = 0, value = 0, count = 0;
uint32_t freq_values[3] = {0};
uint32_t mark_index = 0;
+ struct smu_table_context *table_context = &smu->smu_table;
+ od_table = (OverDriveTable_t *)table_context->overdrive_table;
+ od_settings = smu->od_settings;
switch (clk_type) {
case SMU_GFXCLK:
@@ -734,6 +746,45 @@ static int navi10_print_clk_levels(struct smu_context *smu,
}
break;
+ case SMU_OD_SCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS))
+ break;
+ size += sprintf(buf + size, "OD_SCLK:\n");
+ size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
+ break;
+ case SMU_OD_MCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX))
+ break;
+ size += sprintf(buf + size, "OD_MCLK:\n");
+ size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
+ break;
+ case SMU_OD_VDDC_CURVE:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE))
+ break;
+ size += sprintf(buf + size, "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;
+ }
+ size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i, curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
+ }
+ break;
default:
break;
}
@@ -1600,11 +1651,6 @@ static inline void navi10_dump_od_table(OverDriveTable_t *od_table) {
pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
}
-static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
-{
- return od_table->cap[feature];
-}
-
static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
{
if (value < od_table->min[setting]) {
--
2.23.0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 1/3] drm/amdgpu/navi10: implement sclk/mclk OD via pp_od_clk_voltage
@ 2019-11-07 18:34 ` Matt Coffin
0 siblings, 0 replies; 14+ messages in thread
From: Matt Coffin @ 2019-11-07 18:34 UTC (permalink / raw)
To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Matt Coffin
[Why]
Before this patch, there was no way to use pp_od_clk_voltage on navi
[How]
Similar to the vega20 implementation, but using the common smc_v11_0
headers, implemented the pp_od_clk_voltage API for navi10's pptable
implementation
---
drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h | 1 +
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 185 ++++++++++++++++++
drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 27 +++
3 files changed, 213 insertions(+)
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
index 5bda8539447a..133a53da6785 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
@@ -130,6 +130,7 @@ enum smu_v11_0_baco_seq {
BACO_SEQ_COUNT,
};
+int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize, size_t overdrive_table_size);
void smu_v11_0_set_smu_funcs(struct smu_context *smu);
#endif
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index 0b461404af6b..6d0e511ad093 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -1591,6 +1591,189 @@ static int navi10_get_power_limit(struct smu_context *smu,
return 0;
}
+static inline void navi10_dump_od_table(OverDriveTable_t *od_table) {
+ pr_debug("OD: Gfxclk: (%d, %d)\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
+ pr_debug("OD: Gfx1: (%d, %d)\n", od_table->GfxclkFreq1, od_table->GfxclkVolt1);
+ pr_debug("OD: Gfx2: (%d, %d)\n", od_table->GfxclkFreq2, od_table->GfxclkVolt2);
+ pr_debug("OD: Gfx3: (%d, %d)\n", od_table->GfxclkFreq3, od_table->GfxclkVolt3);
+ pr_debug("OD: UclkFmax: %d\n", od_table->UclkFmax);
+ pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
+}
+
+static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
+{
+ return od_table->cap[feature];
+}
+
+static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
+{
+ if (value < od_table->min[setting]) {
+ pr_warn("OD setting (%d, %d) is less than the minimum allowed (%d)\n", setting, value, od_table->min[setting]);
+ return -EINVAL;
+ }
+ if (value > od_table->max[setting]) {
+ pr_warn("OD setting (%d, %d) is greater than the maximum allowed (%d)\n", setting, value, od_table->max[setting]);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int navi10_setup_od_limits(struct smu_context *smu) {
+ struct smu_11_0_overdrive_table *overdrive_table = NULL;
+ struct smu_11_0_powerplay_table *powerplay_table = NULL;
+
+ if (!smu->smu_table.power_play_table) {
+ pr_err("powerplay table uninitialized!\n");
+ return -ENOENT;
+ }
+ powerplay_table = (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
+ overdrive_table = &powerplay_table->overdrive_table;
+ if (!smu->od_settings) {
+ smu->od_settings = kmemdup(overdrive_table, sizeof(struct smu_11_0_overdrive_table), GFP_KERNEL);
+ } else {
+ memcpy(smu->od_settings, overdrive_table, sizeof(struct smu_11_0_overdrive_table));
+ }
+ return 0;
+}
+
+static int navi10_set_default_od_settings(struct smu_context *smu, bool initialize) {
+ OverDriveTable_t *od_table;
+ int ret = 0;
+
+ ret = smu_v11_0_set_default_od_settings(smu, initialize, sizeof(OverDriveTable_t));
+ if (ret)
+ return ret;
+
+ if (initialize) {
+ ret = navi10_setup_od_limits(smu);
+ if (ret) {
+ pr_err("Failed to retrieve board OD limits\n");
+ return ret;
+ }
+
+ }
+
+ od_table = (OverDriveTable_t *)smu->smu_table.overdrive_table;
+ if (od_table) {
+ navi10_dump_od_table(od_table);
+ }
+
+ return ret;
+}
+
+static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) {
+ int i;
+ int ret = 0;
+ struct smu_table_context *table_context = &smu->smu_table;
+ OverDriveTable_t *od_table;
+ struct smu_11_0_overdrive_table *od_settings;
+ od_table = (OverDriveTable_t *)table_context->overdrive_table;
+
+ if (!smu->od_enabled) {
+ pr_warn("OverDrive is not enabled!\n");
+ return -EINVAL;
+ }
+
+ if (!smu->od_settings) {
+ pr_err("OD board limits are not set!\n");
+ return -ENOENT;
+ }
+
+ od_settings = smu->od_settings;
+
+ switch (type) {
+ case PP_OD_EDIT_SCLK_VDDC_TABLE:
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS)) {
+ pr_warn("GFXCLK_LIMITS not supported!\n");
+ return -ENOTSUPP;
+ }
+ if (!table_context->overdrive_table) {
+ pr_err("Overdrive is not initialized\n");
+ return -EINVAL;
+ }
+ if (input[0] > input[1]) {
+ pr_info("GfxclkFmin must be less than GfxclkFmax\n");
+ return -EINVAL;
+ }
+ for (i = 0; i < size; i += 2) {
+ if (i + 2 > size) {
+ pr_info("invalid number of input parameters %d\n", size);
+ return -EINVAL;
+ }
+ switch (input[i]) {
+ case 0:
+ freq_setting = SMU_11_0_ODSETTING_GFXCLKFMIN;
+ freq_ptr = &od_table->GfxclkFmin;
+ if (input[i + 1] > od_table->GfxclkFmax) {
+ pr_info("GfxclkFmin (%ld) must be <= GfxclkFmax (%u)!\n",
+ input[i + 1],
+ od_table->GfxclkFmin);
+ return -EINVAL;
+ }
+ break;
+ case 1:
+ freq_setting = SMU_11_0_ODSETTING_GFXCLKFMAX;
+ freq_ptr = &od_table->GfxclkFmax;
+ if (input[i + 1] < od_table->GfxclkFmin) {
+ pr_info("GfxclkFmax (%ld) must be >= GfxclkFmin (%u)!\n",
+ input[i + 1],
+ od_table->GfxclkFmax);
+ return -EINVAL;
+ }
+ break;
+ default:
+ pr_info("Invalid SCLK_VDDC_TABLE index: %ld\n", input[i]);
+ pr_info("Supported indices: [0:min,1:max]\n");
+ return -EINVAL;
+ }
+ ret = navi10_od_setting_check_range(od_settings, freq_setting, input[i + 1]);
+ if (ret)
+ return ret;
+ *freq_ptr = input[i + 1];
+ }
+ break;
+ case PP_OD_EDIT_MCLK_VDDC_TABLE:
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX)) {
+ pr_warn("UCLK_MAX not supported!\n");
+ return -ENOTSUPP;
+ }
+ if (size < 2) {
+ pr_info("invalid number of parameters: %d\n", size);
+ return -EINVAL;
+ }
+ if (input[0] != 1) {
+ pr_info("Invalid MCLK_VDDC_TABLE index: %ld\n", input[0]);
+ pr_info("Supported indices: [1:max]\n");
+ return -EINVAL;
+ }
+ ret = navi10_od_setting_check_range(od_settings, SMU_11_0_ODSETTING_UCLKFMAX, input[1]);
+ if (ret)
+ return ret;
+ od_table->UclkFmax = input[1];
+ break;
+ case PP_OD_COMMIT_DPM_TABLE:
+ navi10_dump_od_table(od_table);
+ ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, (void *)od_table, true);
+ if (ret) {
+ pr_err("Failed to import overdrive table!\n");
+ return ret;
+ }
+ mutex_lock(&(smu->mutex));
+ ret = smu_handle_task(smu, smu->smu_dpm.dpm_level, AMD_PP_TASK_READJUST_POWER_STATE);
+ mutex_unlock(&(smu->mutex));
+ if (ret) {
+ return ret;
+ }
+ break;
+ case PP_OD_EDIT_VDDC_CURVE:
+ // TODO: implement
+ return -ENOSYS;
+ default:
+ return -ENOSYS;
+ }
+ return ret;
+}
+
static const struct pptable_funcs navi10_ppt_funcs = {
.tables_init = navi10_tables_init,
.alloc_dpm_context = navi10_allocate_dpm_context,
@@ -1629,6 +1812,8 @@ static const struct pptable_funcs navi10_ppt_funcs = {
.get_thermal_temperature_range = navi10_get_thermal_temperature_range,
.display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch,
.get_power_limit = navi10_get_power_limit,
+ .set_default_od_settings = navi10_set_default_od_settings,
+ .od_edit_dpm_table = navi10_od_edit_dpm_table,
};
void navi10_set_ppt_funcs(struct smu_context *smu)
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
index c5257ae3188a..029f0896146a 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
@@ -1828,3 +1828,30 @@ void smu_v11_0_set_smu_funcs(struct smu_context *smu)
pr_warn("Unknown asic for smu11\n");
}
}
+
+int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize, size_t overdrive_table_size)
+{
+ struct smu_table_context *table_context = &smu->smu_table;
+ int ret = 0;
+
+ if (initialize) {
+ if (table_context->overdrive_table) {
+ return -EINVAL;
+ }
+ table_context->overdrive_table = kzalloc(overdrive_table_size, GFP_KERNEL);
+ if (!table_context->overdrive_table) {
+ return -ENOMEM;
+ }
+ ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, table_context->overdrive_table, false);
+ if (ret) {
+ pr_err("Failed to export overdrive table!\n");
+ return ret;
+ }
+ }
+ ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, table_context->overdrive_table, true);
+ if (ret) {
+ pr_err("Failed to import overdrive table!\n");
+ return ret;
+ }
+ return ret;
+}
--
2.23.0
From 7bc07e0b053381ce7409d8251be18380fb6b3c43 Mon Sep 17 00:00:00 2001
Message-Id: <7bc07e0b053381ce7409d8251be18380fb6b3c43.1573151434.git.mcoffin13@gmail.com>
In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
References: <cover.1573151434.git.mcoffin13@gmail.com>
From: Matt Coffin <mcoffin13@gmail.com>
Date: Tue, 5 Nov 2019 12:39:27 -0700
Subject: [PATCH 2/3] drm/amdgpu/navi10: implement GFXCLK_CURVE overdrive
To: amd-gfx@lists.freedesktop.org
[Why]
Before this patch, there was no way to set the gfxclk voltage curve in
the overdrive settings for navi10 through pp_od_clk_voltage
[How]
Add the required implementation to navi10's ppt dpm table editing
implementation, similar to the vega20 implementation and interface.
---
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 55 +++++++++++++++++++++-
drivers/gpu/drm/amd/powerplay/navi10_ppt.h | 2 +
2 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index 6d0e511ad093..e717328f93ce 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -1667,6 +1667,8 @@ static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABL
struct smu_table_context *table_context = &smu->smu_table;
OverDriveTable_t *od_table;
struct smu_11_0_overdrive_table *od_settings;
+ enum SMU_11_0_ODSETTING_ID freq_setting, voltage_setting;
+ uint16_t *freq_ptr, *voltage_ptr;
od_table = (OverDriveTable_t *)table_context->overdrive_table;
if (!smu->od_enabled) {
@@ -1766,8 +1768,57 @@ static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABL
}
break;
case PP_OD_EDIT_VDDC_CURVE:
- // TODO: implement
- return -ENOSYS;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE)) {
+ pr_warn("GFXCLK_CURVE not supported!\n");
+ return -ENOTSUPP;
+ }
+ if (size < 3) {
+ pr_info("invalid number of parameters: %d\n", size);
+ return -EINVAL;
+ }
+ if (!od_table) {
+ pr_info("Overdrive is not initialized\n");
+ return -EINVAL;
+ }
+
+ switch (input[0]) {
+ case 0:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1;
+ freq_ptr = &od_table->GfxclkFreq1;
+ voltage_ptr = &od_table->GfxclkVolt1;
+ break;
+ case 1:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2;
+ freq_ptr = &od_table->GfxclkFreq2;
+ voltage_ptr = &od_table->GfxclkVolt2;
+ break;
+ case 2:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3;
+ freq_ptr = &od_table->GfxclkFreq3;
+ voltage_ptr = &od_table->GfxclkVolt3;
+ break;
+ default:
+ pr_info("Invalid VDDC_CURVE index: %ld\n", input[0]);
+ pr_info("Supported indices: [0, 1, 2]\n");
+ return -EINVAL;
+ }
+ ret = navi10_od_setting_check_range(od_settings, freq_setting, input[1]);
+ if (ret)
+ return ret;
+ // Allow setting zero to disable the OverDrive VDDC curve
+ if (input[2] != 0) {
+ ret = navi10_od_setting_check_range(od_settings, voltage_setting, input[2]);
+ if (ret)
+ return ret;
+ }
+ *freq_ptr = input[1];
+ *voltage_ptr = ((uint16_t)input[2]) * NAVI10_VOLTAGE_SCALE;
+ pr_debug("OD: set curve %ld: (%d, %d)\n", input[0], *freq_ptr, *voltage_ptr);
+ navi10_dump_od_table(od_table);
+ break;
default:
return -ENOSYS;
}
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
index 620ff17c2fef..484d2c58fc06 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
@@ -27,6 +27,8 @@
#define NAVI10_PEAK_SCLK_XT (1755)
#define NAVI10_PEAK_SCLK_XL (1625)
+#define NAVI10_VOLTAGE_SCALE (4)
+
extern void navi10_set_ppt_funcs(struct smu_context *smu);
#endif
--
2.23.0
From e091c4085ecc669ea907fe5d8515f14586863f9b Mon Sep 17 00:00:00 2001
Message-Id: <e091c4085ecc669ea907fe5d8515f14586863f9b.1573151434.git.mcoffin13@gmail.com>
In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
References: <cover.1573151434.git.mcoffin13@gmail.com>
From: Matt Coffin <mcoffin13@gmail.com>
Date: Wed, 6 Nov 2019 12:05:28 -0700
Subject: [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
To: amd-gfx@lists.freedesktop.org
[Why]
Before this patch, navi10 overdrive settings could not be printed via
pp_od_clk_voltage
[How]
Implement printing for the overdrive settings for the following clocks
in navi10's ppt print_clk_levels implementation:
* SMU_OD_SCLK
* SMU_OD_MCLK
* SMU_OD_VDDC_CURVE
---
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 ++++++++++++++++++++--
1 file changed, 51 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index e717328f93ce..506af59ff45f 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -677,13 +677,25 @@ static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu
return dpm_desc->SnapToDiscrete == 0 ? true : false;
}
+static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
+{
+ return od_table->cap[feature];
+}
+
+
static int navi10_print_clk_levels(struct smu_context *smu,
enum smu_clk_type clk_type, char *buf)
{
+ OverDriveTable_t *od_table;
+ struct smu_11_0_overdrive_table *od_settings;
+ uint16_t *curve_settings;
int i, size = 0, ret = 0;
uint32_t cur_value = 0, value = 0, count = 0;
uint32_t freq_values[3] = {0};
uint32_t mark_index = 0;
+ struct smu_table_context *table_context = &smu->smu_table;
+ od_table = (OverDriveTable_t *)table_context->overdrive_table;
+ od_settings = smu->od_settings;
switch (clk_type) {
case SMU_GFXCLK:
@@ -734,6 +746,45 @@ static int navi10_print_clk_levels(struct smu_context *smu,
}
break;
+ case SMU_OD_SCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS))
+ break;
+ size += sprintf(buf + size, "OD_SCLK:\n");
+ size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
+ break;
+ case SMU_OD_MCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX))
+ break;
+ size += sprintf(buf + size, "OD_MCLK:\n");
+ size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
+ break;
+ case SMU_OD_VDDC_CURVE:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE))
+ break;
+ size += sprintf(buf + size, "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;
+ }
+ size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i, curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
+ }
+ break;
default:
break;
}
@@ -1600,11 +1651,6 @@ static inline void navi10_dump_od_table(OverDriveTable_t *od_table) {
pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
}
-static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
-{
- return od_table->cap[feature];
-}
-
static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
{
if (value < od_table->min[setting]) {
--
2.23.0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 1/3] drm/amdgpu/navi10: implement sclk/mclk OD via pp_od_clk_voltage
@ 2019-11-07 18:34 ` Matt Coffin
0 siblings, 0 replies; 14+ messages in thread
From: Matt Coffin @ 2019-11-07 18:34 UTC (permalink / raw)
To: amd-gfx; +Cc: Matt Coffin
[Why]
Before this patch, there was no way to use pp_od_clk_voltage on navi
[How]
Similar to the vega20 implementation, but using the common smc_v11_0
headers, implemented the pp_od_clk_voltage API for navi10's pptable
implementation
---
drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h | 1 +
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 185 ++++++++++++++++++
drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 27 +++
3 files changed, 213 insertions(+)
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
index 5bda8539447a..133a53da6785 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
@@ -130,6 +130,7 @@ enum smu_v11_0_baco_seq {
BACO_SEQ_COUNT,
};
+int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize, size_t overdrive_table_size);
void smu_v11_0_set_smu_funcs(struct smu_context *smu);
#endif
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index 0b461404af6b..6d0e511ad093 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -1591,6 +1591,189 @@ static int navi10_get_power_limit(struct smu_context *smu,
return 0;
}
+static inline void navi10_dump_od_table(OverDriveTable_t *od_table) {
+ pr_debug("OD: Gfxclk: (%d, %d)\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
+ pr_debug("OD: Gfx1: (%d, %d)\n", od_table->GfxclkFreq1, od_table->GfxclkVolt1);
+ pr_debug("OD: Gfx2: (%d, %d)\n", od_table->GfxclkFreq2, od_table->GfxclkVolt2);
+ pr_debug("OD: Gfx3: (%d, %d)\n", od_table->GfxclkFreq3, od_table->GfxclkVolt3);
+ pr_debug("OD: UclkFmax: %d\n", od_table->UclkFmax);
+ pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
+}
+
+static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
+{
+ return od_table->cap[feature];
+}
+
+static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
+{
+ if (value < od_table->min[setting]) {
+ pr_warn("OD setting (%d, %d) is less than the minimum allowed (%d)\n", setting, value, od_table->min[setting]);
+ return -EINVAL;
+ }
+ if (value > od_table->max[setting]) {
+ pr_warn("OD setting (%d, %d) is greater than the maximum allowed (%d)\n", setting, value, od_table->max[setting]);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int navi10_setup_od_limits(struct smu_context *smu) {
+ struct smu_11_0_overdrive_table *overdrive_table = NULL;
+ struct smu_11_0_powerplay_table *powerplay_table = NULL;
+
+ if (!smu->smu_table.power_play_table) {
+ pr_err("powerplay table uninitialized!\n");
+ return -ENOENT;
+ }
+ powerplay_table = (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
+ overdrive_table = &powerplay_table->overdrive_table;
+ if (!smu->od_settings) {
+ smu->od_settings = kmemdup(overdrive_table, sizeof(struct smu_11_0_overdrive_table), GFP_KERNEL);
+ } else {
+ memcpy(smu->od_settings, overdrive_table, sizeof(struct smu_11_0_overdrive_table));
+ }
+ return 0;
+}
+
+static int navi10_set_default_od_settings(struct smu_context *smu, bool initialize) {
+ OverDriveTable_t *od_table;
+ int ret = 0;
+
+ ret = smu_v11_0_set_default_od_settings(smu, initialize, sizeof(OverDriveTable_t));
+ if (ret)
+ return ret;
+
+ if (initialize) {
+ ret = navi10_setup_od_limits(smu);
+ if (ret) {
+ pr_err("Failed to retrieve board OD limits\n");
+ return ret;
+ }
+
+ }
+
+ od_table = (OverDriveTable_t *)smu->smu_table.overdrive_table;
+ if (od_table) {
+ navi10_dump_od_table(od_table);
+ }
+
+ return ret;
+}
+
+static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) {
+ int i;
+ int ret = 0;
+ struct smu_table_context *table_context = &smu->smu_table;
+ OverDriveTable_t *od_table;
+ struct smu_11_0_overdrive_table *od_settings;
+ od_table = (OverDriveTable_t *)table_context->overdrive_table;
+
+ if (!smu->od_enabled) {
+ pr_warn("OverDrive is not enabled!\n");
+ return -EINVAL;
+ }
+
+ if (!smu->od_settings) {
+ pr_err("OD board limits are not set!\n");
+ return -ENOENT;
+ }
+
+ od_settings = smu->od_settings;
+
+ switch (type) {
+ case PP_OD_EDIT_SCLK_VDDC_TABLE:
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS)) {
+ pr_warn("GFXCLK_LIMITS not supported!\n");
+ return -ENOTSUPP;
+ }
+ if (!table_context->overdrive_table) {
+ pr_err("Overdrive is not initialized\n");
+ return -EINVAL;
+ }
+ if (input[0] > input[1]) {
+ pr_info("GfxclkFmin must be less than GfxclkFmax\n");
+ return -EINVAL;
+ }
+ for (i = 0; i < size; i += 2) {
+ if (i + 2 > size) {
+ pr_info("invalid number of input parameters %d\n", size);
+ return -EINVAL;
+ }
+ switch (input[i]) {
+ case 0:
+ freq_setting = SMU_11_0_ODSETTING_GFXCLKFMIN;
+ freq_ptr = &od_table->GfxclkFmin;
+ if (input[i + 1] > od_table->GfxclkFmax) {
+ pr_info("GfxclkFmin (%ld) must be <= GfxclkFmax (%u)!\n",
+ input[i + 1],
+ od_table->GfxclkFmin);
+ return -EINVAL;
+ }
+ break;
+ case 1:
+ freq_setting = SMU_11_0_ODSETTING_GFXCLKFMAX;
+ freq_ptr = &od_table->GfxclkFmax;
+ if (input[i + 1] < od_table->GfxclkFmin) {
+ pr_info("GfxclkFmax (%ld) must be >= GfxclkFmin (%u)!\n",
+ input[i + 1],
+ od_table->GfxclkFmax);
+ return -EINVAL;
+ }
+ break;
+ default:
+ pr_info("Invalid SCLK_VDDC_TABLE index: %ld\n", input[i]);
+ pr_info("Supported indices: [0:min,1:max]\n");
+ return -EINVAL;
+ }
+ ret = navi10_od_setting_check_range(od_settings, freq_setting, input[i + 1]);
+ if (ret)
+ return ret;
+ *freq_ptr = input[i + 1];
+ }
+ break;
+ case PP_OD_EDIT_MCLK_VDDC_TABLE:
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX)) {
+ pr_warn("UCLK_MAX not supported!\n");
+ return -ENOTSUPP;
+ }
+ if (size < 2) {
+ pr_info("invalid number of parameters: %d\n", size);
+ return -EINVAL;
+ }
+ if (input[0] != 1) {
+ pr_info("Invalid MCLK_VDDC_TABLE index: %ld\n", input[0]);
+ pr_info("Supported indices: [1:max]\n");
+ return -EINVAL;
+ }
+ ret = navi10_od_setting_check_range(od_settings, SMU_11_0_ODSETTING_UCLKFMAX, input[1]);
+ if (ret)
+ return ret;
+ od_table->UclkFmax = input[1];
+ break;
+ case PP_OD_COMMIT_DPM_TABLE:
+ navi10_dump_od_table(od_table);
+ ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, (void *)od_table, true);
+ if (ret) {
+ pr_err("Failed to import overdrive table!\n");
+ return ret;
+ }
+ mutex_lock(&(smu->mutex));
+ ret = smu_handle_task(smu, smu->smu_dpm.dpm_level, AMD_PP_TASK_READJUST_POWER_STATE);
+ mutex_unlock(&(smu->mutex));
+ if (ret) {
+ return ret;
+ }
+ break;
+ case PP_OD_EDIT_VDDC_CURVE:
+ // TODO: implement
+ return -ENOSYS;
+ default:
+ return -ENOSYS;
+ }
+ return ret;
+}
+
static const struct pptable_funcs navi10_ppt_funcs = {
.tables_init = navi10_tables_init,
.alloc_dpm_context = navi10_allocate_dpm_context,
@@ -1629,6 +1812,8 @@ static const struct pptable_funcs navi10_ppt_funcs = {
.get_thermal_temperature_range = navi10_get_thermal_temperature_range,
.display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch,
.get_power_limit = navi10_get_power_limit,
+ .set_default_od_settings = navi10_set_default_od_settings,
+ .od_edit_dpm_table = navi10_od_edit_dpm_table,
};
void navi10_set_ppt_funcs(struct smu_context *smu)
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
index c5257ae3188a..029f0896146a 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
@@ -1828,3 +1828,30 @@ void smu_v11_0_set_smu_funcs(struct smu_context *smu)
pr_warn("Unknown asic for smu11\n");
}
}
+
+int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize, size_t overdrive_table_size)
+{
+ struct smu_table_context *table_context = &smu->smu_table;
+ int ret = 0;
+
+ if (initialize) {
+ if (table_context->overdrive_table) {
+ return -EINVAL;
+ }
+ table_context->overdrive_table = kzalloc(overdrive_table_size, GFP_KERNEL);
+ if (!table_context->overdrive_table) {
+ return -ENOMEM;
+ }
+ ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, table_context->overdrive_table, false);
+ if (ret) {
+ pr_err("Failed to export overdrive table!\n");
+ return ret;
+ }
+ }
+ ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, table_context->overdrive_table, true);
+ if (ret) {
+ pr_err("Failed to import overdrive table!\n");
+ return ret;
+ }
+ return ret;
+}
--
2.23.0
From 7bc07e0b053381ce7409d8251be18380fb6b3c43 Mon Sep 17 00:00:00 2001
Message-Id: <7bc07e0b053381ce7409d8251be18380fb6b3c43.1573151434.git.mcoffin13@gmail.com>
In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
References: <cover.1573151434.git.mcoffin13@gmail.com>
From: Matt Coffin <mcoffin13@gmail.com>
Date: Tue, 5 Nov 2019 12:39:27 -0700
Subject: [PATCH 2/3] drm/amdgpu/navi10: implement GFXCLK_CURVE overdrive
To: amd-gfx@lists.freedesktop.org
[Why]
Before this patch, there was no way to set the gfxclk voltage curve in
the overdrive settings for navi10 through pp_od_clk_voltage
[How]
Add the required implementation to navi10's ppt dpm table editing
implementation, similar to the vega20 implementation and interface.
---
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 55 +++++++++++++++++++++-
drivers/gpu/drm/amd/powerplay/navi10_ppt.h | 2 +
2 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index 6d0e511ad093..e717328f93ce 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -1667,6 +1667,8 @@ static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABL
struct smu_table_context *table_context = &smu->smu_table;
OverDriveTable_t *od_table;
struct smu_11_0_overdrive_table *od_settings;
+ enum SMU_11_0_ODSETTING_ID freq_setting, voltage_setting;
+ uint16_t *freq_ptr, *voltage_ptr;
od_table = (OverDriveTable_t *)table_context->overdrive_table;
if (!smu->od_enabled) {
@@ -1766,8 +1768,57 @@ static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABL
}
break;
case PP_OD_EDIT_VDDC_CURVE:
- // TODO: implement
- return -ENOSYS;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE)) {
+ pr_warn("GFXCLK_CURVE not supported!\n");
+ return -ENOTSUPP;
+ }
+ if (size < 3) {
+ pr_info("invalid number of parameters: %d\n", size);
+ return -EINVAL;
+ }
+ if (!od_table) {
+ pr_info("Overdrive is not initialized\n");
+ return -EINVAL;
+ }
+
+ switch (input[0]) {
+ case 0:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1;
+ freq_ptr = &od_table->GfxclkFreq1;
+ voltage_ptr = &od_table->GfxclkVolt1;
+ break;
+ case 1:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2;
+ freq_ptr = &od_table->GfxclkFreq2;
+ voltage_ptr = &od_table->GfxclkVolt2;
+ break;
+ case 2:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3;
+ freq_ptr = &od_table->GfxclkFreq3;
+ voltage_ptr = &od_table->GfxclkVolt3;
+ break;
+ default:
+ pr_info("Invalid VDDC_CURVE index: %ld\n", input[0]);
+ pr_info("Supported indices: [0, 1, 2]\n");
+ return -EINVAL;
+ }
+ ret = navi10_od_setting_check_range(od_settings, freq_setting, input[1]);
+ if (ret)
+ return ret;
+ // Allow setting zero to disable the OverDrive VDDC curve
+ if (input[2] != 0) {
+ ret = navi10_od_setting_check_range(od_settings, voltage_setting, input[2]);
+ if (ret)
+ return ret;
+ }
+ *freq_ptr = input[1];
+ *voltage_ptr = ((uint16_t)input[2]) * NAVI10_VOLTAGE_SCALE;
+ pr_debug("OD: set curve %ld: (%d, %d)\n", input[0], *freq_ptr, *voltage_ptr);
+ navi10_dump_od_table(od_table);
+ break;
default:
return -ENOSYS;
}
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
index 620ff17c2fef..484d2c58fc06 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
@@ -27,6 +27,8 @@
#define NAVI10_PEAK_SCLK_XT (1755)
#define NAVI10_PEAK_SCLK_XL (1625)
+#define NAVI10_VOLTAGE_SCALE (4)
+
extern void navi10_set_ppt_funcs(struct smu_context *smu);
#endif
--
2.23.0
From e091c4085ecc669ea907fe5d8515f14586863f9b Mon Sep 17 00:00:00 2001
Message-Id: <e091c4085ecc669ea907fe5d8515f14586863f9b.1573151434.git.mcoffin13@gmail.com>
In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
References: <cover.1573151434.git.mcoffin13@gmail.com>
From: Matt Coffin <mcoffin13@gmail.com>
Date: Wed, 6 Nov 2019 12:05:28 -0700
Subject: [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
To: amd-gfx@lists.freedesktop.org
[Why]
Before this patch, navi10 overdrive settings could not be printed via
pp_od_clk_voltage
[How]
Implement printing for the overdrive settings for the following clocks
in navi10's ppt print_clk_levels implementation:
* SMU_OD_SCLK
* SMU_OD_MCLK
* SMU_OD_VDDC_CURVE
---
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 ++++++++++++++++++++--
1 file changed, 51 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index e717328f93ce..506af59ff45f 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -677,13 +677,25 @@ static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu
return dpm_desc->SnapToDiscrete == 0 ? true : false;
}
+static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
+{
+ return od_table->cap[feature];
+}
+
+
static int navi10_print_clk_levels(struct smu_context *smu,
enum smu_clk_type clk_type, char *buf)
{
+ OverDriveTable_t *od_table;
+ struct smu_11_0_overdrive_table *od_settings;
+ uint16_t *curve_settings;
int i, size = 0, ret = 0;
uint32_t cur_value = 0, value = 0, count = 0;
uint32_t freq_values[3] = {0};
uint32_t mark_index = 0;
+ struct smu_table_context *table_context = &smu->smu_table;
+ od_table = (OverDriveTable_t *)table_context->overdrive_table;
+ od_settings = smu->od_settings;
switch (clk_type) {
case SMU_GFXCLK:
@@ -734,6 +746,45 @@ static int navi10_print_clk_levels(struct smu_context *smu,
}
break;
+ case SMU_OD_SCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS))
+ break;
+ size += sprintf(buf + size, "OD_SCLK:\n");
+ size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
+ break;
+ case SMU_OD_MCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX))
+ break;
+ size += sprintf(buf + size, "OD_MCLK:\n");
+ size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
+ break;
+ case SMU_OD_VDDC_CURVE:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE))
+ break;
+ size += sprintf(buf + size, "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;
+ }
+ size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i, curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
+ }
+ break;
default:
break;
}
@@ -1600,11 +1651,6 @@ static inline void navi10_dump_od_table(OverDriveTable_t *od_table) {
pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
}
-static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
-{
- return od_table->cap[feature];
-}
-
static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
{
if (value < od_table->min[setting]) {
--
2.23.0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/3] drm/amdgpu/navi10: implement GFXCLK_CURVE overdrive
@ 2019-11-07 18:34 ` Matt Coffin
0 siblings, 0 replies; 14+ messages in thread
From: Matt Coffin @ 2019-11-07 18:34 UTC (permalink / raw)
To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Matt Coffin
[Why]
Before this patch, there was no way to set the gfxclk voltage curve in
the overdrive settings for navi10 through pp_od_clk_voltage
[How]
Add the required implementation to navi10's ppt dpm table editing
implementation, similar to the vega20 implementation and interface.
---
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 55 +++++++++++++++++++++-
drivers/gpu/drm/amd/powerplay/navi10_ppt.h | 2 +
2 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index 6d0e511ad093..e717328f93ce 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -1667,6 +1667,8 @@ static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABL
struct smu_table_context *table_context = &smu->smu_table;
OverDriveTable_t *od_table;
struct smu_11_0_overdrive_table *od_settings;
+ enum SMU_11_0_ODSETTING_ID freq_setting, voltage_setting;
+ uint16_t *freq_ptr, *voltage_ptr;
od_table = (OverDriveTable_t *)table_context->overdrive_table;
if (!smu->od_enabled) {
@@ -1766,8 +1768,57 @@ static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABL
}
break;
case PP_OD_EDIT_VDDC_CURVE:
- // TODO: implement
- return -ENOSYS;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE)) {
+ pr_warn("GFXCLK_CURVE not supported!\n");
+ return -ENOTSUPP;
+ }
+ if (size < 3) {
+ pr_info("invalid number of parameters: %d\n", size);
+ return -EINVAL;
+ }
+ if (!od_table) {
+ pr_info("Overdrive is not initialized\n");
+ return -EINVAL;
+ }
+
+ switch (input[0]) {
+ case 0:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1;
+ freq_ptr = &od_table->GfxclkFreq1;
+ voltage_ptr = &od_table->GfxclkVolt1;
+ break;
+ case 1:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2;
+ freq_ptr = &od_table->GfxclkFreq2;
+ voltage_ptr = &od_table->GfxclkVolt2;
+ break;
+ case 2:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3;
+ freq_ptr = &od_table->GfxclkFreq3;
+ voltage_ptr = &od_table->GfxclkVolt3;
+ break;
+ default:
+ pr_info("Invalid VDDC_CURVE index: %ld\n", input[0]);
+ pr_info("Supported indices: [0, 1, 2]\n");
+ return -EINVAL;
+ }
+ ret = navi10_od_setting_check_range(od_settings, freq_setting, input[1]);
+ if (ret)
+ return ret;
+ // Allow setting zero to disable the OverDrive VDDC curve
+ if (input[2] != 0) {
+ ret = navi10_od_setting_check_range(od_settings, voltage_setting, input[2]);
+ if (ret)
+ return ret;
+ }
+ *freq_ptr = input[1];
+ *voltage_ptr = ((uint16_t)input[2]) * NAVI10_VOLTAGE_SCALE;
+ pr_debug("OD: set curve %ld: (%d, %d)\n", input[0], *freq_ptr, *voltage_ptr);
+ navi10_dump_od_table(od_table);
+ break;
default:
return -ENOSYS;
}
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
index 620ff17c2fef..484d2c58fc06 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
@@ -27,6 +27,8 @@
#define NAVI10_PEAK_SCLK_XT (1755)
#define NAVI10_PEAK_SCLK_XL (1625)
+#define NAVI10_VOLTAGE_SCALE (4)
+
extern void navi10_set_ppt_funcs(struct smu_context *smu);
#endif
--
2.23.0
From e091c4085ecc669ea907fe5d8515f14586863f9b Mon Sep 17 00:00:00 2001
Message-Id: <e091c4085ecc669ea907fe5d8515f14586863f9b.1573151434.git.mcoffin13@gmail.com>
In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
References: <cover.1573151434.git.mcoffin13@gmail.com>
From: Matt Coffin <mcoffin13@gmail.com>
Date: Wed, 6 Nov 2019 12:05:28 -0700
Subject: [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
To: amd-gfx@lists.freedesktop.org
[Why]
Before this patch, navi10 overdrive settings could not be printed via
pp_od_clk_voltage
[How]
Implement printing for the overdrive settings for the following clocks
in navi10's ppt print_clk_levels implementation:
* SMU_OD_SCLK
* SMU_OD_MCLK
* SMU_OD_VDDC_CURVE
---
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 ++++++++++++++++++++--
1 file changed, 51 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index e717328f93ce..506af59ff45f 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -677,13 +677,25 @@ static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu
return dpm_desc->SnapToDiscrete == 0 ? true : false;
}
+static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
+{
+ return od_table->cap[feature];
+}
+
+
static int navi10_print_clk_levels(struct smu_context *smu,
enum smu_clk_type clk_type, char *buf)
{
+ OverDriveTable_t *od_table;
+ struct smu_11_0_overdrive_table *od_settings;
+ uint16_t *curve_settings;
int i, size = 0, ret = 0;
uint32_t cur_value = 0, value = 0, count = 0;
uint32_t freq_values[3] = {0};
uint32_t mark_index = 0;
+ struct smu_table_context *table_context = &smu->smu_table;
+ od_table = (OverDriveTable_t *)table_context->overdrive_table;
+ od_settings = smu->od_settings;
switch (clk_type) {
case SMU_GFXCLK:
@@ -734,6 +746,45 @@ static int navi10_print_clk_levels(struct smu_context *smu,
}
break;
+ case SMU_OD_SCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS))
+ break;
+ size += sprintf(buf + size, "OD_SCLK:\n");
+ size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
+ break;
+ case SMU_OD_MCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX))
+ break;
+ size += sprintf(buf + size, "OD_MCLK:\n");
+ size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
+ break;
+ case SMU_OD_VDDC_CURVE:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE))
+ break;
+ size += sprintf(buf + size, "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;
+ }
+ size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i, curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
+ }
+ break;
default:
break;
}
@@ -1600,11 +1651,6 @@ static inline void navi10_dump_od_table(OverDriveTable_t *od_table) {
pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
}
-static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
-{
- return od_table->cap[feature];
-}
-
static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
{
if (value < od_table->min[setting]) {
--
2.23.0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/3] drm/amdgpu/navi10: implement GFXCLK_CURVE overdrive
@ 2019-11-07 18:34 ` Matt Coffin
0 siblings, 0 replies; 14+ messages in thread
From: Matt Coffin @ 2019-11-07 18:34 UTC (permalink / raw)
To: amd-gfx; +Cc: Matt Coffin
[Why]
Before this patch, there was no way to set the gfxclk voltage curve in
the overdrive settings for navi10 through pp_od_clk_voltage
[How]
Add the required implementation to navi10's ppt dpm table editing
implementation, similar to the vega20 implementation and interface.
---
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 55 +++++++++++++++++++++-
drivers/gpu/drm/amd/powerplay/navi10_ppt.h | 2 +
2 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index 6d0e511ad093..e717328f93ce 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -1667,6 +1667,8 @@ static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABL
struct smu_table_context *table_context = &smu->smu_table;
OverDriveTable_t *od_table;
struct smu_11_0_overdrive_table *od_settings;
+ enum SMU_11_0_ODSETTING_ID freq_setting, voltage_setting;
+ uint16_t *freq_ptr, *voltage_ptr;
od_table = (OverDriveTable_t *)table_context->overdrive_table;
if (!smu->od_enabled) {
@@ -1766,8 +1768,57 @@ static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABL
}
break;
case PP_OD_EDIT_VDDC_CURVE:
- // TODO: implement
- return -ENOSYS;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE)) {
+ pr_warn("GFXCLK_CURVE not supported!\n");
+ return -ENOTSUPP;
+ }
+ if (size < 3) {
+ pr_info("invalid number of parameters: %d\n", size);
+ return -EINVAL;
+ }
+ if (!od_table) {
+ pr_info("Overdrive is not initialized\n");
+ return -EINVAL;
+ }
+
+ switch (input[0]) {
+ case 0:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1;
+ freq_ptr = &od_table->GfxclkFreq1;
+ voltage_ptr = &od_table->GfxclkVolt1;
+ break;
+ case 1:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2;
+ freq_ptr = &od_table->GfxclkFreq2;
+ voltage_ptr = &od_table->GfxclkVolt2;
+ break;
+ case 2:
+ freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3;
+ voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3;
+ freq_ptr = &od_table->GfxclkFreq3;
+ voltage_ptr = &od_table->GfxclkVolt3;
+ break;
+ default:
+ pr_info("Invalid VDDC_CURVE index: %ld\n", input[0]);
+ pr_info("Supported indices: [0, 1, 2]\n");
+ return -EINVAL;
+ }
+ ret = navi10_od_setting_check_range(od_settings, freq_setting, input[1]);
+ if (ret)
+ return ret;
+ // Allow setting zero to disable the OverDrive VDDC curve
+ if (input[2] != 0) {
+ ret = navi10_od_setting_check_range(od_settings, voltage_setting, input[2]);
+ if (ret)
+ return ret;
+ }
+ *freq_ptr = input[1];
+ *voltage_ptr = ((uint16_t)input[2]) * NAVI10_VOLTAGE_SCALE;
+ pr_debug("OD: set curve %ld: (%d, %d)\n", input[0], *freq_ptr, *voltage_ptr);
+ navi10_dump_od_table(od_table);
+ break;
default:
return -ENOSYS;
}
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
index 620ff17c2fef..484d2c58fc06 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
@@ -27,6 +27,8 @@
#define NAVI10_PEAK_SCLK_XT (1755)
#define NAVI10_PEAK_SCLK_XL (1625)
+#define NAVI10_VOLTAGE_SCALE (4)
+
extern void navi10_set_ppt_funcs(struct smu_context *smu);
#endif
--
2.23.0
From e091c4085ecc669ea907fe5d8515f14586863f9b Mon Sep 17 00:00:00 2001
Message-Id: <e091c4085ecc669ea907fe5d8515f14586863f9b.1573151434.git.mcoffin13@gmail.com>
In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
References: <cover.1573151434.git.mcoffin13@gmail.com>
From: Matt Coffin <mcoffin13@gmail.com>
Date: Wed, 6 Nov 2019 12:05:28 -0700
Subject: [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
To: amd-gfx@lists.freedesktop.org
[Why]
Before this patch, navi10 overdrive settings could not be printed via
pp_od_clk_voltage
[How]
Implement printing for the overdrive settings for the following clocks
in navi10's ppt print_clk_levels implementation:
* SMU_OD_SCLK
* SMU_OD_MCLK
* SMU_OD_VDDC_CURVE
---
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 ++++++++++++++++++++--
1 file changed, 51 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index e717328f93ce..506af59ff45f 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -677,13 +677,25 @@ static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu
return dpm_desc->SnapToDiscrete == 0 ? true : false;
}
+static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
+{
+ return od_table->cap[feature];
+}
+
+
static int navi10_print_clk_levels(struct smu_context *smu,
enum smu_clk_type clk_type, char *buf)
{
+ OverDriveTable_t *od_table;
+ struct smu_11_0_overdrive_table *od_settings;
+ uint16_t *curve_settings;
int i, size = 0, ret = 0;
uint32_t cur_value = 0, value = 0, count = 0;
uint32_t freq_values[3] = {0};
uint32_t mark_index = 0;
+ struct smu_table_context *table_context = &smu->smu_table;
+ od_table = (OverDriveTable_t *)table_context->overdrive_table;
+ od_settings = smu->od_settings;
switch (clk_type) {
case SMU_GFXCLK:
@@ -734,6 +746,45 @@ static int navi10_print_clk_levels(struct smu_context *smu,
}
break;
+ case SMU_OD_SCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS))
+ break;
+ size += sprintf(buf + size, "OD_SCLK:\n");
+ size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
+ break;
+ case SMU_OD_MCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX))
+ break;
+ size += sprintf(buf + size, "OD_MCLK:\n");
+ size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
+ break;
+ case SMU_OD_VDDC_CURVE:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE))
+ break;
+ size += sprintf(buf + size, "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;
+ }
+ size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i, curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
+ }
+ break;
default:
break;
}
@@ -1600,11 +1651,6 @@ static inline void navi10_dump_od_table(OverDriveTable_t *od_table) {
pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
}
-static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
-{
- return od_table->cap[feature];
-}
-
static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
{
if (value < od_table->min[setting]) {
--
2.23.0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
@ 2019-11-07 18:35 ` Matt Coffin
0 siblings, 0 replies; 14+ messages in thread
From: Matt Coffin @ 2019-11-07 18:35 UTC (permalink / raw)
To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Matt Coffin
[Why]
Before this patch, navi10 overdrive settings could not be printed via
pp_od_clk_voltage
[How]
Implement printing for the overdrive settings for the following clocks
in navi10's ppt print_clk_levels implementation:
* SMU_OD_SCLK
* SMU_OD_MCLK
* SMU_OD_VDDC_CURVE
---
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 ++++++++++++++++++++--
1 file changed, 51 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index e717328f93ce..506af59ff45f 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -677,13 +677,25 @@ static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu
return dpm_desc->SnapToDiscrete == 0 ? true : false;
}
+static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
+{
+ return od_table->cap[feature];
+}
+
+
static int navi10_print_clk_levels(struct smu_context *smu,
enum smu_clk_type clk_type, char *buf)
{
+ OverDriveTable_t *od_table;
+ struct smu_11_0_overdrive_table *od_settings;
+ uint16_t *curve_settings;
int i, size = 0, ret = 0;
uint32_t cur_value = 0, value = 0, count = 0;
uint32_t freq_values[3] = {0};
uint32_t mark_index = 0;
+ struct smu_table_context *table_context = &smu->smu_table;
+ od_table = (OverDriveTable_t *)table_context->overdrive_table;
+ od_settings = smu->od_settings;
switch (clk_type) {
case SMU_GFXCLK:
@@ -734,6 +746,45 @@ static int navi10_print_clk_levels(struct smu_context *smu,
}
break;
+ case SMU_OD_SCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS))
+ break;
+ size += sprintf(buf + size, "OD_SCLK:\n");
+ size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
+ break;
+ case SMU_OD_MCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX))
+ break;
+ size += sprintf(buf + size, "OD_MCLK:\n");
+ size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
+ break;
+ case SMU_OD_VDDC_CURVE:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE))
+ break;
+ size += sprintf(buf + size, "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;
+ }
+ size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i, curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
+ }
+ break;
default:
break;
}
@@ -1600,11 +1651,6 @@ static inline void navi10_dump_od_table(OverDriveTable_t *od_table) {
pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
}
-static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
-{
- return od_table->cap[feature];
-}
-
static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
{
if (value < od_table->min[setting]) {
--
2.23.0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
@ 2019-11-07 18:35 ` Matt Coffin
0 siblings, 0 replies; 14+ messages in thread
From: Matt Coffin @ 2019-11-07 18:35 UTC (permalink / raw)
To: amd-gfx; +Cc: Matt Coffin
[Why]
Before this patch, navi10 overdrive settings could not be printed via
pp_od_clk_voltage
[How]
Implement printing for the overdrive settings for the following clocks
in navi10's ppt print_clk_levels implementation:
* SMU_OD_SCLK
* SMU_OD_MCLK
* SMU_OD_VDDC_CURVE
---
drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 ++++++++++++++++++++--
1 file changed, 51 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index e717328f93ce..506af59ff45f 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -677,13 +677,25 @@ static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu
return dpm_desc->SnapToDiscrete == 0 ? true : false;
}
+static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
+{
+ return od_table->cap[feature];
+}
+
+
static int navi10_print_clk_levels(struct smu_context *smu,
enum smu_clk_type clk_type, char *buf)
{
+ OverDriveTable_t *od_table;
+ struct smu_11_0_overdrive_table *od_settings;
+ uint16_t *curve_settings;
int i, size = 0, ret = 0;
uint32_t cur_value = 0, value = 0, count = 0;
uint32_t freq_values[3] = {0};
uint32_t mark_index = 0;
+ struct smu_table_context *table_context = &smu->smu_table;
+ od_table = (OverDriveTable_t *)table_context->overdrive_table;
+ od_settings = smu->od_settings;
switch (clk_type) {
case SMU_GFXCLK:
@@ -734,6 +746,45 @@ static int navi10_print_clk_levels(struct smu_context *smu,
}
break;
+ case SMU_OD_SCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS))
+ break;
+ size += sprintf(buf + size, "OD_SCLK:\n");
+ size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
+ break;
+ case SMU_OD_MCLK:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX))
+ break;
+ size += sprintf(buf + size, "OD_MCLK:\n");
+ size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
+ break;
+ case SMU_OD_VDDC_CURVE:
+ if (!smu->od_enabled || !od_table || !od_settings)
+ break;
+ if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE))
+ break;
+ size += sprintf(buf + size, "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;
+ }
+ size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i, curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
+ }
+ break;
default:
break;
}
@@ -1600,11 +1651,6 @@ static inline void navi10_dump_od_table(OverDriveTable_t *od_table) {
pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
}
-static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature)
-{
- return od_table->cap[feature];
-}
-
static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
{
if (value < od_table->min[setting]) {
--
2.23.0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* RE: [PATCH 1/3] drm/amdgpu/navi10: implement sclk/mclk OD via pp_od_clk_voltage
@ 2019-11-08 5:48 ` Quan, Evan
0 siblings, 0 replies; 14+ messages in thread
From: Quan, Evan @ 2019-11-08 5:48 UTC (permalink / raw)
To: Matt Coffin, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Deucher, Alexander
Thanks for adding these. Some comments inline.
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Matt
> Coffin
> Sent: Friday, November 8, 2019 2:34 AM
> To: amd-gfx@lists.freedesktop.org
> Cc: Matt Coffin <mcoffin13@gmail.com>
> Subject: [PATCH 1/3] drm/amdgpu/navi10: implement sclk/mclk OD via
> pp_od_clk_voltage
>
> [Why]
> Before this patch, there was no way to use pp_od_clk_voltage on navi
>
> [How]
> Similar to the vega20 implementation, but using the common smc_v11_0
> headers, implemented the pp_od_clk_voltage API for navi10's pptable
> implementation
> ---
> drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h | 1 +
> drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 185 ++++++++++++++++++
> drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 27 +++
> 3 files changed, 213 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
> b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
> index 5bda8539447a..133a53da6785 100644
> --- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
> +++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
> @@ -130,6 +130,7 @@ enum smu_v11_0_baco_seq {
> BACO_SEQ_COUNT,
> };
>
> +int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool
> +initialize, size_t overdrive_table_size);
> void smu_v11_0_set_smu_funcs(struct smu_context *smu);
>
> #endif
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> index 0b461404af6b..6d0e511ad093 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> @@ -1591,6 +1591,189 @@ static int navi10_get_power_limit(struct
> smu_context *smu,
> return 0;
> }
>
> +static inline void navi10_dump_od_table(OverDriveTable_t *od_table) {
> + pr_debug("OD: Gfxclk: (%d, %d)\n", od_table->GfxclkFmin, od_table-
> >GfxclkFmax);
> + pr_debug("OD: Gfx1: (%d, %d)\n", od_table->GfxclkFreq1, od_table-
> >GfxclkVolt1);
> + pr_debug("OD: Gfx2: (%d, %d)\n", od_table->GfxclkFreq2, od_table-
> >GfxclkVolt2);
> + pr_debug("OD: Gfx3: (%d, %d)\n", od_table->GfxclkFreq3, od_table-
> >GfxclkVolt3);
> + pr_debug("OD: UclkFmax: %d\n", od_table->UclkFmax);
> + pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct); }
> +
> +static inline bool navi10_od_feature_is_supported(struct
> +smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID
> feature) {
> + return od_table->cap[feature];
> +}
> +
> +static int navi10_od_setting_check_range(struct
> +smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID
> setting, uint32_t value) {
> + if (value < od_table->min[setting]) {
> + pr_warn("OD setting (%d, %d) is less than the minimum
> allowed (%d)\n", setting, value, od_table->min[setting]);
> + return -EINVAL;
> + }
> + if (value > od_table->max[setting]) {
> + pr_warn("OD setting (%d, %d) is greater than the maximum
> allowed (%d)\n", setting, value, od_table->max[setting]);
> + return -EINVAL;
> + }
> + return 0;
> +}
> +
> +static int navi10_setup_od_limits(struct smu_context *smu) {
> + struct smu_11_0_overdrive_table *overdrive_table = NULL;
> + struct smu_11_0_powerplay_table *powerplay_table = NULL;
> +
> + if (!smu->smu_table.power_play_table) {
> + pr_err("powerplay table uninitialized!\n");
> + return -ENOENT;
> + }
> + powerplay_table = (struct smu_11_0_powerplay_table *)smu-
> >smu_table.power_play_table;
> + overdrive_table = &powerplay_table->overdrive_table;
> + if (!smu->od_settings) {
> + smu->od_settings = kmemdup(overdrive_table, sizeof(struct
> smu_11_0_overdrive_table), GFP_KERNEL);
> + } else {
> + memcpy(smu->od_settings, overdrive_table, sizeof(struct
> smu_11_0_overdrive_table));
> + }
> + return 0;
> +}
> +
> +static int navi10_set_default_od_settings(struct smu_context *smu, bool
> initialize) {
> + OverDriveTable_t *od_table;
> + int ret = 0;
> +
> + ret = smu_v11_0_set_default_od_settings(smu, initialize,
> sizeof(OverDriveTable_t));
> + if (ret)
> + return ret;
> +
> + if (initialize) {
> + ret = navi10_setup_od_limits(smu);
> + if (ret) {
> + pr_err("Failed to retrieve board OD limits\n");
> + return ret;
> + }
> +
> + }
> +
> + od_table = (OverDriveTable_t *)smu->smu_table.overdrive_table;
> + if (od_table) {
> + navi10_dump_od_table(od_table);
> + }
> +
> + return ret;
> +}
> +
> +static int navi10_od_edit_dpm_table(struct smu_context *smu, enum
> PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) {
> + int i;
> + int ret = 0;
> + struct smu_table_context *table_context = &smu->smu_table;
> + OverDriveTable_t *od_table;
> + struct smu_11_0_overdrive_table *od_settings;
> + od_table = (OverDriveTable_t *)table_context->overdrive_table;
> +
> + if (!smu->od_enabled) {
> + pr_warn("OverDrive is not enabled!\n");
> + return -EINVAL;
> + }
> +
> + if (!smu->od_settings) {
> + pr_err("OD board limits are not set!\n");
> + return -ENOENT;
> + }
> +
> + od_settings = smu->od_settings;
> +
> + switch (type) {
> + case PP_OD_EDIT_SCLK_VDDC_TABLE:
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_LIMITS)) {
> + pr_warn("GFXCLK_LIMITS not supported!\n");
> + return -ENOTSUPP;
> + }
> + if (!table_context->overdrive_table) {
> + pr_err("Overdrive is not initialized\n");
> + return -EINVAL;
> + }
> + if (input[0] > input[1]) {
> + pr_info("GfxclkFmin must be less than GfxclkFmax\n");
> + return -EINVAL;
> + }
[Quan, Evan] This judgement is a little weird. As input[0] is feature id while input[1] is the actual requested frequency.
> + for (i = 0; i < size; i += 2) {
> + if (i + 2 > size) {
> + pr_info("invalid number of input
> parameters %d\n", size);
> + return -EINVAL;
> + }
> + switch (input[i]) {
> + case 0:
> + freq_setting =
> SMU_11_0_ODSETTING_GFXCLKFMIN;
> + freq_ptr = &od_table->GfxclkFmin;
> + if (input[i + 1] > od_table->GfxclkFmax) {
> + pr_info("GfxclkFmin (%ld) must be <=
> GfxclkFmax (%u)!\n",
> + input[i + 1],
> + od_table->GfxclkFmin);
> + return -EINVAL;
> + }
> + break;
> + case 1:
> + freq_setting =
> SMU_11_0_ODSETTING_GFXCLKFMAX;
> + freq_ptr = &od_table->GfxclkFmax;
> + if (input[i + 1] < od_table->GfxclkFmin) {
> + pr_info("GfxclkFmax (%ld) must be >=
> GfxclkFmin (%u)!\n",
> + input[i + 1],
> + od_table->GfxclkFmax);
> + return -EINVAL;
> + }
> + break;
> + default:
> + pr_info("Invalid SCLK_VDDC_TABLE
> index: %ld\n", input[i]);
> + pr_info("Supported indices: [0:min,1:max]\n");
> + return -EINVAL;
> + }
> + ret = navi10_od_setting_check_range(od_settings,
> freq_setting, input[i + 1]);
> + if (ret)
> + return ret;
> + *freq_ptr = input[i + 1];
> + }
> + break;
> + case PP_OD_EDIT_MCLK_VDDC_TABLE:
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_UCLK_MAX)) {
> + pr_warn("UCLK_MAX not supported!\n");
> + return -ENOTSUPP;
> + }
> + if (size < 2) {
> + pr_info("invalid number of parameters: %d\n", size);
> + return -EINVAL;
> + }
> + if (input[0] != 1) {
> + pr_info("Invalid MCLK_VDDC_TABLE index: %ld\n",
> input[0]);
> + pr_info("Supported indices: [1:max]\n");
> + return -EINVAL;
> + }
> + ret = navi10_od_setting_check_range(od_settings,
> SMU_11_0_ODSETTING_UCLKFMAX, input[1]);
> + if (ret)
> + return ret;
> + od_table->UclkFmax = input[1];
> + break;
> + case PP_OD_COMMIT_DPM_TABLE:
> + navi10_dump_od_table(od_table);
> + ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0,
> (void *)od_table, true);
> + if (ret) {
> + pr_err("Failed to import overdrive table!\n");
> + return ret;
> + }
> + mutex_lock(&(smu->mutex));
> + ret = smu_handle_task(smu, smu->smu_dpm.dpm_level,
> AMD_PP_TASK_READJUST_POWER_STATE);
> + mutex_unlock(&(smu->mutex));
[Quan, Evan] This may be not based on the latest source code. As with the latest source code, there is already lock protection in smu_od_edit_dpm_table().
Then trying to get the lock again will dead lock.
> + if (ret) {
> + return ret;
> + }
> + break;
> + case PP_OD_EDIT_VDDC_CURVE:
> + // TODO: implement
> + return -ENOSYS;
> + default:
> + return -ENOSYS;
> + }
> + return ret;
> +}
> +
> static const struct pptable_funcs navi10_ppt_funcs = {
> .tables_init = navi10_tables_init,
> .alloc_dpm_context = navi10_allocate_dpm_context, @@ -1629,6
> +1812,8 @@ static const struct pptable_funcs navi10_ppt_funcs = {
> .get_thermal_temperature_range =
> navi10_get_thermal_temperature_range,
> .display_disable_memory_clock_switch =
> navi10_display_disable_memory_clock_switch,
> .get_power_limit = navi10_get_power_limit,
> + .set_default_od_settings = navi10_set_default_od_settings,
> + .od_edit_dpm_table = navi10_od_edit_dpm_table,
> };
>
> void navi10_set_ppt_funcs(struct smu_context *smu) diff --git
> a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
> b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
> index c5257ae3188a..029f0896146a 100644
> --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
> +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
> @@ -1828,3 +1828,30 @@ void smu_v11_0_set_smu_funcs(struct smu_context
> *smu)
> pr_warn("Unknown asic for smu11\n");
> }
> }
> +
> +int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool
> +initialize, size_t overdrive_table_size) {
> + struct smu_table_context *table_context = &smu->smu_table;
> + int ret = 0;
> +
> + if (initialize) {
> + if (table_context->overdrive_table) {
> + return -EINVAL;
> + }
> + table_context->overdrive_table = kzalloc(overdrive_table_size,
> GFP_KERNEL);
> + if (!table_context->overdrive_table) {
> + return -ENOMEM;
> + }
> + ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0,
> table_context->overdrive_table, false);
> + if (ret) {
> + pr_err("Failed to export overdrive table!\n");
> + return ret;
> + }
> + }
> + ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0,
> table_context->overdrive_table, true);
> + if (ret) {
> + pr_err("Failed to import overdrive table!\n");
> + return ret;
> + }
> + return ret;
> +}
> --
> 2.23.0
>
>
> From 7bc07e0b053381ce7409d8251be18380fb6b3c43 Mon Sep 17 00:00:00
> 2001
> Message-Id:
> <7bc07e0b053381ce7409d8251be18380fb6b3c43.1573151434.git.mcoffin13@g
> mail.com>
> In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
> References: <cover.1573151434.git.mcoffin13@gmail.com>
> From: Matt Coffin <mcoffin13@gmail.com>
> Date: Tue, 5 Nov 2019 12:39:27 -0700
> Subject: [PATCH 2/3] drm/amdgpu/navi10: implement GFXCLK_CURVE
> overdrive
> To: amd-gfx@lists.freedesktop.org
>
> [Why]
> Before this patch, there was no way to set the gfxclk voltage curve in
> the overdrive settings for navi10 through pp_od_clk_voltage
>
> [How]
> Add the required implementation to navi10's ppt dpm table editing
> implementation, similar to the vega20 implementation and interface.
> ---
> drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 55 +++++++++++++++++++++-
> drivers/gpu/drm/amd/powerplay/navi10_ppt.h | 2 +
> 2 files changed, 55 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> index 6d0e511ad093..e717328f93ce 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> @@ -1667,6 +1667,8 @@ static int navi10_od_edit_dpm_table(struct
> smu_context *smu, enum PP_OD_DPM_TABL
> struct smu_table_context *table_context = &smu->smu_table;
> OverDriveTable_t *od_table;
> struct smu_11_0_overdrive_table *od_settings;
> + enum SMU_11_0_ODSETTING_ID freq_setting, voltage_setting;
> + uint16_t *freq_ptr, *voltage_ptr;
> od_table = (OverDriveTable_t *)table_context->overdrive_table;
>
> if (!smu->od_enabled) {
> @@ -1766,8 +1768,57 @@ static int navi10_od_edit_dpm_table(struct
> smu_context *smu, enum PP_OD_DPM_TABL
> }
> break;
> case PP_OD_EDIT_VDDC_CURVE:
> - // TODO: implement
> - return -ENOSYS;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_CURVE)) {
> + pr_warn("GFXCLK_CURVE not supported!\n");
> + return -ENOTSUPP;
> + }
> + if (size < 3) {
> + pr_info("invalid number of parameters: %d\n", size);
> + return -EINVAL;
> + }
> + if (!od_table) {
> + pr_info("Overdrive is not initialized\n");
> + return -EINVAL;
> + }
> +
> + switch (input[0]) {
> + case 0:
> + freq_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1;
> + voltage_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1;
> + freq_ptr = &od_table->GfxclkFreq1;
> + voltage_ptr = &od_table->GfxclkVolt1;
> + break;
> + case 1:
> + freq_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2;
> + voltage_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2;
> + freq_ptr = &od_table->GfxclkFreq2;
> + voltage_ptr = &od_table->GfxclkVolt2;
> + break;
> + case 2:
> + freq_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3;
> + voltage_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3;
> + freq_ptr = &od_table->GfxclkFreq3;
> + voltage_ptr = &od_table->GfxclkVolt3;
> + break;
> + default:
> + pr_info("Invalid VDDC_CURVE index: %ld\n", input[0]);
> + pr_info("Supported indices: [0, 1, 2]\n");
> + return -EINVAL;
> + }
> + ret = navi10_od_setting_check_range(od_settings, freq_setting,
> input[1]);
> + if (ret)
> + return ret;
> + // Allow setting zero to disable the OverDrive VDDC curve
> + if (input[2] != 0) {
> + ret = navi10_od_setting_check_range(od_settings,
> voltage_setting, input[2]);
> + if (ret)
> + return ret;
> + }
> + *freq_ptr = input[1];
> + *voltage_ptr = ((uint16_t)input[2]) * NAVI10_VOLTAGE_SCALE;
> + pr_debug("OD: set curve %ld: (%d, %d)\n", input[0], *freq_ptr,
> *voltage_ptr);
> + navi10_dump_od_table(od_table);
> + break;
> default:
> return -ENOSYS;
> }
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> index 620ff17c2fef..484d2c58fc06 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> @@ -27,6 +27,8 @@
> #define NAVI10_PEAK_SCLK_XT (1755)
> #define NAVI10_PEAK_SCLK_XL (1625)
>
> +#define NAVI10_VOLTAGE_SCALE (4)
> +
> extern void navi10_set_ppt_funcs(struct smu_context *smu);
>
> #endif
> --
> 2.23.0
>
>
> From e091c4085ecc669ea907fe5d8515f14586863f9b Mon Sep 17 00:00:00
> 2001
> Message-Id:
> <e091c4085ecc669ea907fe5d8515f14586863f9b.1573151434.git.mcoffin13@g
> mail.com>
> In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
> References: <cover.1573151434.git.mcoffin13@gmail.com>
> From: Matt Coffin <mcoffin13@gmail.com>
> Date: Wed, 6 Nov 2019 12:05:28 -0700
> Subject: [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
> To: amd-gfx@lists.freedesktop.org
>
> [Why]
> Before this patch, navi10 overdrive settings could not be printed via
> pp_od_clk_voltage
>
> [How]
> Implement printing for the overdrive settings for the following clocks
> in navi10's ppt print_clk_levels implementation:
>
> * SMU_OD_SCLK
> * SMU_OD_MCLK
> * SMU_OD_VDDC_CURVE
> ---
> drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 ++++++++++++++++++++--
> 1 file changed, 51 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> index e717328f93ce..506af59ff45f 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> @@ -677,13 +677,25 @@ static bool
> navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu
> return dpm_desc->SnapToDiscrete == 0 ? true : false;
> }
>
> +static inline bool navi10_od_feature_is_supported(struct
> smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID
> feature)
> +{
> + return od_table->cap[feature];
> +}
> +
> +
> static int navi10_print_clk_levels(struct smu_context *smu,
> enum smu_clk_type clk_type, char *buf)
> {
> + OverDriveTable_t *od_table;
> + struct smu_11_0_overdrive_table *od_settings;
> + uint16_t *curve_settings;
> int i, size = 0, ret = 0;
> uint32_t cur_value = 0, value = 0, count = 0;
> uint32_t freq_values[3] = {0};
> uint32_t mark_index = 0;
> + struct smu_table_context *table_context = &smu->smu_table;
> + od_table = (OverDriveTable_t *)table_context->overdrive_table;
> + od_settings = smu->od_settings;
>
> switch (clk_type) {
> case SMU_GFXCLK:
> @@ -734,6 +746,45 @@ static int navi10_print_clk_levels(struct smu_context
> *smu,
>
> }
> break;
> + case SMU_OD_SCLK:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_LIMITS))
> + break;
> + size += sprintf(buf + size, "OD_SCLK:\n");
> + size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table-
> >GfxclkFmin, od_table->GfxclkFmax);
> + break;
> + case SMU_OD_MCLK:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_UCLK_MAX))
> + break;
> + size += sprintf(buf + size, "OD_MCLK:\n");
> + size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
> + break;
> + case SMU_OD_VDDC_CURVE:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_CURVE))
> + break;
> + size += sprintf(buf + size, "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;
> + }
> + size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i,
> curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
> + }
> + break;
> default:
> break;
> }
> @@ -1600,11 +1651,6 @@ static inline void
> navi10_dump_od_table(OverDriveTable_t *od_table) {
> pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
> }
>
> -static inline bool navi10_od_feature_is_supported(struct
> smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID
> feature)
> -{
> - return od_table->cap[feature];
> -}
> -
> static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table
> *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
> {
> if (value < od_table->min[setting]) {
> --
> 2.23.0
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH 1/3] drm/amdgpu/navi10: implement sclk/mclk OD via pp_od_clk_voltage
@ 2019-11-08 5:48 ` Quan, Evan
0 siblings, 0 replies; 14+ messages in thread
From: Quan, Evan @ 2019-11-08 5:48 UTC (permalink / raw)
To: Matt Coffin, amd-gfx; +Cc: Deucher, Alexander
Thanks for adding these. Some comments inline.
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Matt
> Coffin
> Sent: Friday, November 8, 2019 2:34 AM
> To: amd-gfx@lists.freedesktop.org
> Cc: Matt Coffin <mcoffin13@gmail.com>
> Subject: [PATCH 1/3] drm/amdgpu/navi10: implement sclk/mclk OD via
> pp_od_clk_voltage
>
> [Why]
> Before this patch, there was no way to use pp_od_clk_voltage on navi
>
> [How]
> Similar to the vega20 implementation, but using the common smc_v11_0
> headers, implemented the pp_od_clk_voltage API for navi10's pptable
> implementation
> ---
> drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h | 1 +
> drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 185 ++++++++++++++++++
> drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 27 +++
> 3 files changed, 213 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
> b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
> index 5bda8539447a..133a53da6785 100644
> --- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
> +++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
> @@ -130,6 +130,7 @@ enum smu_v11_0_baco_seq {
> BACO_SEQ_COUNT,
> };
>
> +int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool
> +initialize, size_t overdrive_table_size);
> void smu_v11_0_set_smu_funcs(struct smu_context *smu);
>
> #endif
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> index 0b461404af6b..6d0e511ad093 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> @@ -1591,6 +1591,189 @@ static int navi10_get_power_limit(struct
> smu_context *smu,
> return 0;
> }
>
> +static inline void navi10_dump_od_table(OverDriveTable_t *od_table) {
> + pr_debug("OD: Gfxclk: (%d, %d)\n", od_table->GfxclkFmin, od_table-
> >GfxclkFmax);
> + pr_debug("OD: Gfx1: (%d, %d)\n", od_table->GfxclkFreq1, od_table-
> >GfxclkVolt1);
> + pr_debug("OD: Gfx2: (%d, %d)\n", od_table->GfxclkFreq2, od_table-
> >GfxclkVolt2);
> + pr_debug("OD: Gfx3: (%d, %d)\n", od_table->GfxclkFreq3, od_table-
> >GfxclkVolt3);
> + pr_debug("OD: UclkFmax: %d\n", od_table->UclkFmax);
> + pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct); }
> +
> +static inline bool navi10_od_feature_is_supported(struct
> +smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID
> feature) {
> + return od_table->cap[feature];
> +}
> +
> +static int navi10_od_setting_check_range(struct
> +smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID
> setting, uint32_t value) {
> + if (value < od_table->min[setting]) {
> + pr_warn("OD setting (%d, %d) is less than the minimum
> allowed (%d)\n", setting, value, od_table->min[setting]);
> + return -EINVAL;
> + }
> + if (value > od_table->max[setting]) {
> + pr_warn("OD setting (%d, %d) is greater than the maximum
> allowed (%d)\n", setting, value, od_table->max[setting]);
> + return -EINVAL;
> + }
> + return 0;
> +}
> +
> +static int navi10_setup_od_limits(struct smu_context *smu) {
> + struct smu_11_0_overdrive_table *overdrive_table = NULL;
> + struct smu_11_0_powerplay_table *powerplay_table = NULL;
> +
> + if (!smu->smu_table.power_play_table) {
> + pr_err("powerplay table uninitialized!\n");
> + return -ENOENT;
> + }
> + powerplay_table = (struct smu_11_0_powerplay_table *)smu-
> >smu_table.power_play_table;
> + overdrive_table = &powerplay_table->overdrive_table;
> + if (!smu->od_settings) {
> + smu->od_settings = kmemdup(overdrive_table, sizeof(struct
> smu_11_0_overdrive_table), GFP_KERNEL);
> + } else {
> + memcpy(smu->od_settings, overdrive_table, sizeof(struct
> smu_11_0_overdrive_table));
> + }
> + return 0;
> +}
> +
> +static int navi10_set_default_od_settings(struct smu_context *smu, bool
> initialize) {
> + OverDriveTable_t *od_table;
> + int ret = 0;
> +
> + ret = smu_v11_0_set_default_od_settings(smu, initialize,
> sizeof(OverDriveTable_t));
> + if (ret)
> + return ret;
> +
> + if (initialize) {
> + ret = navi10_setup_od_limits(smu);
> + if (ret) {
> + pr_err("Failed to retrieve board OD limits\n");
> + return ret;
> + }
> +
> + }
> +
> + od_table = (OverDriveTable_t *)smu->smu_table.overdrive_table;
> + if (od_table) {
> + navi10_dump_od_table(od_table);
> + }
> +
> + return ret;
> +}
> +
> +static int navi10_od_edit_dpm_table(struct smu_context *smu, enum
> PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) {
> + int i;
> + int ret = 0;
> + struct smu_table_context *table_context = &smu->smu_table;
> + OverDriveTable_t *od_table;
> + struct smu_11_0_overdrive_table *od_settings;
> + od_table = (OverDriveTable_t *)table_context->overdrive_table;
> +
> + if (!smu->od_enabled) {
> + pr_warn("OverDrive is not enabled!\n");
> + return -EINVAL;
> + }
> +
> + if (!smu->od_settings) {
> + pr_err("OD board limits are not set!\n");
> + return -ENOENT;
> + }
> +
> + od_settings = smu->od_settings;
> +
> + switch (type) {
> + case PP_OD_EDIT_SCLK_VDDC_TABLE:
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_LIMITS)) {
> + pr_warn("GFXCLK_LIMITS not supported!\n");
> + return -ENOTSUPP;
> + }
> + if (!table_context->overdrive_table) {
> + pr_err("Overdrive is not initialized\n");
> + return -EINVAL;
> + }
> + if (input[0] > input[1]) {
> + pr_info("GfxclkFmin must be less than GfxclkFmax\n");
> + return -EINVAL;
> + }
[Quan, Evan] This judgement is a little weird. As input[0] is feature id while input[1] is the actual requested frequency.
> + for (i = 0; i < size; i += 2) {
> + if (i + 2 > size) {
> + pr_info("invalid number of input
> parameters %d\n", size);
> + return -EINVAL;
> + }
> + switch (input[i]) {
> + case 0:
> + freq_setting =
> SMU_11_0_ODSETTING_GFXCLKFMIN;
> + freq_ptr = &od_table->GfxclkFmin;
> + if (input[i + 1] > od_table->GfxclkFmax) {
> + pr_info("GfxclkFmin (%ld) must be <=
> GfxclkFmax (%u)!\n",
> + input[i + 1],
> + od_table->GfxclkFmin);
> + return -EINVAL;
> + }
> + break;
> + case 1:
> + freq_setting =
> SMU_11_0_ODSETTING_GFXCLKFMAX;
> + freq_ptr = &od_table->GfxclkFmax;
> + if (input[i + 1] < od_table->GfxclkFmin) {
> + pr_info("GfxclkFmax (%ld) must be >=
> GfxclkFmin (%u)!\n",
> + input[i + 1],
> + od_table->GfxclkFmax);
> + return -EINVAL;
> + }
> + break;
> + default:
> + pr_info("Invalid SCLK_VDDC_TABLE
> index: %ld\n", input[i]);
> + pr_info("Supported indices: [0:min,1:max]\n");
> + return -EINVAL;
> + }
> + ret = navi10_od_setting_check_range(od_settings,
> freq_setting, input[i + 1]);
> + if (ret)
> + return ret;
> + *freq_ptr = input[i + 1];
> + }
> + break;
> + case PP_OD_EDIT_MCLK_VDDC_TABLE:
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_UCLK_MAX)) {
> + pr_warn("UCLK_MAX not supported!\n");
> + return -ENOTSUPP;
> + }
> + if (size < 2) {
> + pr_info("invalid number of parameters: %d\n", size);
> + return -EINVAL;
> + }
> + if (input[0] != 1) {
> + pr_info("Invalid MCLK_VDDC_TABLE index: %ld\n",
> input[0]);
> + pr_info("Supported indices: [1:max]\n");
> + return -EINVAL;
> + }
> + ret = navi10_od_setting_check_range(od_settings,
> SMU_11_0_ODSETTING_UCLKFMAX, input[1]);
> + if (ret)
> + return ret;
> + od_table->UclkFmax = input[1];
> + break;
> + case PP_OD_COMMIT_DPM_TABLE:
> + navi10_dump_od_table(od_table);
> + ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0,
> (void *)od_table, true);
> + if (ret) {
> + pr_err("Failed to import overdrive table!\n");
> + return ret;
> + }
> + mutex_lock(&(smu->mutex));
> + ret = smu_handle_task(smu, smu->smu_dpm.dpm_level,
> AMD_PP_TASK_READJUST_POWER_STATE);
> + mutex_unlock(&(smu->mutex));
[Quan, Evan] This may be not based on the latest source code. As with the latest source code, there is already lock protection in smu_od_edit_dpm_table().
Then trying to get the lock again will dead lock.
> + if (ret) {
> + return ret;
> + }
> + break;
> + case PP_OD_EDIT_VDDC_CURVE:
> + // TODO: implement
> + return -ENOSYS;
> + default:
> + return -ENOSYS;
> + }
> + return ret;
> +}
> +
> static const struct pptable_funcs navi10_ppt_funcs = {
> .tables_init = navi10_tables_init,
> .alloc_dpm_context = navi10_allocate_dpm_context, @@ -1629,6
> +1812,8 @@ static const struct pptable_funcs navi10_ppt_funcs = {
> .get_thermal_temperature_range =
> navi10_get_thermal_temperature_range,
> .display_disable_memory_clock_switch =
> navi10_display_disable_memory_clock_switch,
> .get_power_limit = navi10_get_power_limit,
> + .set_default_od_settings = navi10_set_default_od_settings,
> + .od_edit_dpm_table = navi10_od_edit_dpm_table,
> };
>
> void navi10_set_ppt_funcs(struct smu_context *smu) diff --git
> a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
> b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
> index c5257ae3188a..029f0896146a 100644
> --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
> +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
> @@ -1828,3 +1828,30 @@ void smu_v11_0_set_smu_funcs(struct smu_context
> *smu)
> pr_warn("Unknown asic for smu11\n");
> }
> }
> +
> +int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool
> +initialize, size_t overdrive_table_size) {
> + struct smu_table_context *table_context = &smu->smu_table;
> + int ret = 0;
> +
> + if (initialize) {
> + if (table_context->overdrive_table) {
> + return -EINVAL;
> + }
> + table_context->overdrive_table = kzalloc(overdrive_table_size,
> GFP_KERNEL);
> + if (!table_context->overdrive_table) {
> + return -ENOMEM;
> + }
> + ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0,
> table_context->overdrive_table, false);
> + if (ret) {
> + pr_err("Failed to export overdrive table!\n");
> + return ret;
> + }
> + }
> + ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0,
> table_context->overdrive_table, true);
> + if (ret) {
> + pr_err("Failed to import overdrive table!\n");
> + return ret;
> + }
> + return ret;
> +}
> --
> 2.23.0
>
>
> From 7bc07e0b053381ce7409d8251be18380fb6b3c43 Mon Sep 17 00:00:00
> 2001
> Message-Id:
> <7bc07e0b053381ce7409d8251be18380fb6b3c43.1573151434.git.mcoffin13@g
> mail.com>
> In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
> References: <cover.1573151434.git.mcoffin13@gmail.com>
> From: Matt Coffin <mcoffin13@gmail.com>
> Date: Tue, 5 Nov 2019 12:39:27 -0700
> Subject: [PATCH 2/3] drm/amdgpu/navi10: implement GFXCLK_CURVE
> overdrive
> To: amd-gfx@lists.freedesktop.org
>
> [Why]
> Before this patch, there was no way to set the gfxclk voltage curve in
> the overdrive settings for navi10 through pp_od_clk_voltage
>
> [How]
> Add the required implementation to navi10's ppt dpm table editing
> implementation, similar to the vega20 implementation and interface.
> ---
> drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 55 +++++++++++++++++++++-
> drivers/gpu/drm/amd/powerplay/navi10_ppt.h | 2 +
> 2 files changed, 55 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> index 6d0e511ad093..e717328f93ce 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> @@ -1667,6 +1667,8 @@ static int navi10_od_edit_dpm_table(struct
> smu_context *smu, enum PP_OD_DPM_TABL
> struct smu_table_context *table_context = &smu->smu_table;
> OverDriveTable_t *od_table;
> struct smu_11_0_overdrive_table *od_settings;
> + enum SMU_11_0_ODSETTING_ID freq_setting, voltage_setting;
> + uint16_t *freq_ptr, *voltage_ptr;
> od_table = (OverDriveTable_t *)table_context->overdrive_table;
>
> if (!smu->od_enabled) {
> @@ -1766,8 +1768,57 @@ static int navi10_od_edit_dpm_table(struct
> smu_context *smu, enum PP_OD_DPM_TABL
> }
> break;
> case PP_OD_EDIT_VDDC_CURVE:
> - // TODO: implement
> - return -ENOSYS;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_CURVE)) {
> + pr_warn("GFXCLK_CURVE not supported!\n");
> + return -ENOTSUPP;
> + }
> + if (size < 3) {
> + pr_info("invalid number of parameters: %d\n", size);
> + return -EINVAL;
> + }
> + if (!od_table) {
> + pr_info("Overdrive is not initialized\n");
> + return -EINVAL;
> + }
> +
> + switch (input[0]) {
> + case 0:
> + freq_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1;
> + voltage_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1;
> + freq_ptr = &od_table->GfxclkFreq1;
> + voltage_ptr = &od_table->GfxclkVolt1;
> + break;
> + case 1:
> + freq_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2;
> + voltage_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2;
> + freq_ptr = &od_table->GfxclkFreq2;
> + voltage_ptr = &od_table->GfxclkVolt2;
> + break;
> + case 2:
> + freq_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3;
> + voltage_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3;
> + freq_ptr = &od_table->GfxclkFreq3;
> + voltage_ptr = &od_table->GfxclkVolt3;
> + break;
> + default:
> + pr_info("Invalid VDDC_CURVE index: %ld\n", input[0]);
> + pr_info("Supported indices: [0, 1, 2]\n");
> + return -EINVAL;
> + }
> + ret = navi10_od_setting_check_range(od_settings, freq_setting,
> input[1]);
> + if (ret)
> + return ret;
> + // Allow setting zero to disable the OverDrive VDDC curve
> + if (input[2] != 0) {
> + ret = navi10_od_setting_check_range(od_settings,
> voltage_setting, input[2]);
> + if (ret)
> + return ret;
> + }
> + *freq_ptr = input[1];
> + *voltage_ptr = ((uint16_t)input[2]) * NAVI10_VOLTAGE_SCALE;
> + pr_debug("OD: set curve %ld: (%d, %d)\n", input[0], *freq_ptr,
> *voltage_ptr);
> + navi10_dump_od_table(od_table);
> + break;
> default:
> return -ENOSYS;
> }
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> index 620ff17c2fef..484d2c58fc06 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> @@ -27,6 +27,8 @@
> #define NAVI10_PEAK_SCLK_XT (1755)
> #define NAVI10_PEAK_SCLK_XL (1625)
>
> +#define NAVI10_VOLTAGE_SCALE (4)
> +
> extern void navi10_set_ppt_funcs(struct smu_context *smu);
>
> #endif
> --
> 2.23.0
>
>
> From e091c4085ecc669ea907fe5d8515f14586863f9b Mon Sep 17 00:00:00
> 2001
> Message-Id:
> <e091c4085ecc669ea907fe5d8515f14586863f9b.1573151434.git.mcoffin13@g
> mail.com>
> In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
> References: <cover.1573151434.git.mcoffin13@gmail.com>
> From: Matt Coffin <mcoffin13@gmail.com>
> Date: Wed, 6 Nov 2019 12:05:28 -0700
> Subject: [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
> To: amd-gfx@lists.freedesktop.org
>
> [Why]
> Before this patch, navi10 overdrive settings could not be printed via
> pp_od_clk_voltage
>
> [How]
> Implement printing for the overdrive settings for the following clocks
> in navi10's ppt print_clk_levels implementation:
>
> * SMU_OD_SCLK
> * SMU_OD_MCLK
> * SMU_OD_VDDC_CURVE
> ---
> drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 ++++++++++++++++++++--
> 1 file changed, 51 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> index e717328f93ce..506af59ff45f 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> @@ -677,13 +677,25 @@ static bool
> navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu
> return dpm_desc->SnapToDiscrete == 0 ? true : false;
> }
>
> +static inline bool navi10_od_feature_is_supported(struct
> smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID
> feature)
> +{
> + return od_table->cap[feature];
> +}
> +
> +
> static int navi10_print_clk_levels(struct smu_context *smu,
> enum smu_clk_type clk_type, char *buf)
> {
> + OverDriveTable_t *od_table;
> + struct smu_11_0_overdrive_table *od_settings;
> + uint16_t *curve_settings;
> int i, size = 0, ret = 0;
> uint32_t cur_value = 0, value = 0, count = 0;
> uint32_t freq_values[3] = {0};
> uint32_t mark_index = 0;
> + struct smu_table_context *table_context = &smu->smu_table;
> + od_table = (OverDriveTable_t *)table_context->overdrive_table;
> + od_settings = smu->od_settings;
>
> switch (clk_type) {
> case SMU_GFXCLK:
> @@ -734,6 +746,45 @@ static int navi10_print_clk_levels(struct smu_context
> *smu,
>
> }
> break;
> + case SMU_OD_SCLK:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_LIMITS))
> + break;
> + size += sprintf(buf + size, "OD_SCLK:\n");
> + size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table-
> >GfxclkFmin, od_table->GfxclkFmax);
> + break;
> + case SMU_OD_MCLK:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_UCLK_MAX))
> + break;
> + size += sprintf(buf + size, "OD_MCLK:\n");
> + size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
> + break;
> + case SMU_OD_VDDC_CURVE:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_CURVE))
> + break;
> + size += sprintf(buf + size, "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;
> + }
> + size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i,
> curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
> + }
> + break;
> default:
> break;
> }
> @@ -1600,11 +1651,6 @@ static inline void
> navi10_dump_od_table(OverDriveTable_t *od_table) {
> pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
> }
>
> -static inline bool navi10_od_feature_is_supported(struct
> smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID
> feature)
> -{
> - return od_table->cap[feature];
> -}
> -
> static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table
> *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
> {
> if (value < od_table->min[setting]) {
> --
> 2.23.0
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH 2/3] drm/amdgpu/navi10: implement GFXCLK_CURVE overdrive
@ 2019-11-08 5:50 ` Quan, Evan
0 siblings, 0 replies; 14+ messages in thread
From: Quan, Evan @ 2019-11-08 5:50 UTC (permalink / raw)
To: Matt Coffin, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Deucher, Alexander
Comment inline
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Matt
> Coffin
> Sent: Friday, November 8, 2019 2:35 AM
> To: amd-gfx@lists.freedesktop.org
> Cc: Matt Coffin <mcoffin13@gmail.com>
> Subject: [PATCH 2/3] drm/amdgpu/navi10: implement GFXCLK_CURVE
> overdrive
>
> [Why]
> Before this patch, there was no way to set the gfxclk voltage curve in the
> overdrive settings for navi10 through pp_od_clk_voltage
>
> [How]
> Add the required implementation to navi10's ppt dpm table editing
> implementation, similar to the vega20 implementation and interface.
> ---
> drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 55 +++++++++++++++++++++-
> drivers/gpu/drm/amd/powerplay/navi10_ppt.h | 2 +
> 2 files changed, 55 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> index 6d0e511ad093..e717328f93ce 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> @@ -1667,6 +1667,8 @@ static int navi10_od_edit_dpm_table(struct
> smu_context *smu, enum PP_OD_DPM_TABL
> struct smu_table_context *table_context = &smu->smu_table;
> OverDriveTable_t *od_table;
> struct smu_11_0_overdrive_table *od_settings;
> + enum SMU_11_0_ODSETTING_ID freq_setting, voltage_setting;
> + uint16_t *freq_ptr, *voltage_ptr;
> od_table = (OverDriveTable_t *)table_context->overdrive_table;
>
> if (!smu->od_enabled) {
> @@ -1766,8 +1768,57 @@ static int navi10_od_edit_dpm_table(struct
> smu_context *smu, enum PP_OD_DPM_TABL
> }
> break;
> case PP_OD_EDIT_VDDC_CURVE:
> - // TODO: implement
> - return -ENOSYS;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_CURVE)) {
> + pr_warn("GFXCLK_CURVE not supported!\n");
> + return -ENOTSUPP;
> + }
> + if (size < 3) {
> + pr_info("invalid number of parameters: %d\n", size);
> + return -EINVAL;
> + }
> + if (!od_table) {
> + pr_info("Overdrive is not initialized\n");
> + return -EINVAL;
> + }
> +
> + switch (input[0]) {
> + case 0:
> + freq_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1;
> + voltage_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1;
> + freq_ptr = &od_table->GfxclkFreq1;
> + voltage_ptr = &od_table->GfxclkVolt1;
> + break;
> + case 1:
> + freq_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2;
> + voltage_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2;
> + freq_ptr = &od_table->GfxclkFreq2;
> + voltage_ptr = &od_table->GfxclkVolt2;
> + break;
> + case 2:
> + freq_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3;
> + voltage_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3;
> + freq_ptr = &od_table->GfxclkFreq3;
> + voltage_ptr = &od_table->GfxclkVolt3;
> + break;
> + default:
> + pr_info("Invalid VDDC_CURVE index: %ld\n", input[0]);
> + pr_info("Supported indices: [0, 1, 2]\n");
> + return -EINVAL;
> + }
> + ret = navi10_od_setting_check_range(od_settings, freq_setting,
> input[1]);
> + if (ret)
> + return ret;
> + // Allow setting zero to disable the OverDrive VDDC curve
> + if (input[2] != 0) {
> + ret = navi10_od_setting_check_range(od_settings,
> voltage_setting, input[2]);
> + if (ret)
> + return ret;
> + }
> + *freq_ptr = input[1];
> + *voltage_ptr = ((uint16_t)input[2]) * NAVI10_VOLTAGE_SCALE;
[Quan, Evan] Need to move this under "if (input[2] != 0)" protection also I think.
> + pr_debug("OD: set curve %ld: (%d, %d)\n", input[0], *freq_ptr,
> *voltage_ptr);
> + navi10_dump_od_table(od_table);
> + break;
> default:
> return -ENOSYS;
> }
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> index 620ff17c2fef..484d2c58fc06 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> @@ -27,6 +27,8 @@
> #define NAVI10_PEAK_SCLK_XT (1755)
> #define NAVI10_PEAK_SCLK_XL (1625)
>
> +#define NAVI10_VOLTAGE_SCALE (4)
> +
> extern void navi10_set_ppt_funcs(struct smu_context *smu);
>
> #endif
> --
> 2.23.0
>
>
> From e091c4085ecc669ea907fe5d8515f14586863f9b Mon Sep 17 00:00:00
> 2001
> Message-Id:
> <e091c4085ecc669ea907fe5d8515f14586863f9b.1573151434.git.mcoffin13@g
> mail.com>
> In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
> References: <cover.1573151434.git.mcoffin13@gmail.com>
> From: Matt Coffin <mcoffin13@gmail.com>
> Date: Wed, 6 Nov 2019 12:05:28 -0700
> Subject: [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
> To: amd-gfx@lists.freedesktop.org
>
> [Why]
> Before this patch, navi10 overdrive settings could not be printed via
> pp_od_clk_voltage
>
> [How]
> Implement printing for the overdrive settings for the following clocks
> in navi10's ppt print_clk_levels implementation:
>
> * SMU_OD_SCLK
> * SMU_OD_MCLK
> * SMU_OD_VDDC_CURVE
> ---
> drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 ++++++++++++++++++++--
> 1 file changed, 51 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> index e717328f93ce..506af59ff45f 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> @@ -677,13 +677,25 @@ static bool
> navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu
> return dpm_desc->SnapToDiscrete == 0 ? true : false;
> }
>
> +static inline bool navi10_od_feature_is_supported(struct
> smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID
> feature)
> +{
> + return od_table->cap[feature];
> +}
> +
> +
> static int navi10_print_clk_levels(struct smu_context *smu,
> enum smu_clk_type clk_type, char *buf)
> {
> + OverDriveTable_t *od_table;
> + struct smu_11_0_overdrive_table *od_settings;
> + uint16_t *curve_settings;
> int i, size = 0, ret = 0;
> uint32_t cur_value = 0, value = 0, count = 0;
> uint32_t freq_values[3] = {0};
> uint32_t mark_index = 0;
> + struct smu_table_context *table_context = &smu->smu_table;
> + od_table = (OverDriveTable_t *)table_context->overdrive_table;
> + od_settings = smu->od_settings;
>
> switch (clk_type) {
> case SMU_GFXCLK:
> @@ -734,6 +746,45 @@ static int navi10_print_clk_levels(struct smu_context
> *smu,
>
> }
> break;
> + case SMU_OD_SCLK:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_LIMITS))
> + break;
> + size += sprintf(buf + size, "OD_SCLK:\n");
> + size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table-
> >GfxclkFmin, od_table->GfxclkFmax);
> + break;
> + case SMU_OD_MCLK:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_UCLK_MAX))
> + break;
> + size += sprintf(buf + size, "OD_MCLK:\n");
> + size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
> + break;
> + case SMU_OD_VDDC_CURVE:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_CURVE))
> + break;
> + size += sprintf(buf + size, "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;
> + }
> + size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i,
> curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
> + }
> + break;
> default:
> break;
> }
> @@ -1600,11 +1651,6 @@ static inline void
> navi10_dump_od_table(OverDriveTable_t *od_table) {
> pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
> }
>
> -static inline bool navi10_od_feature_is_supported(struct
> smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID
> feature)
> -{
> - return od_table->cap[feature];
> -}
> -
> static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table
> *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
> {
> if (value < od_table->min[setting]) {
> --
> 2.23.0
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH 2/3] drm/amdgpu/navi10: implement GFXCLK_CURVE overdrive
@ 2019-11-08 5:50 ` Quan, Evan
0 siblings, 0 replies; 14+ messages in thread
From: Quan, Evan @ 2019-11-08 5:50 UTC (permalink / raw)
To: Matt Coffin, amd-gfx; +Cc: Deucher, Alexander
Comment inline
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Matt
> Coffin
> Sent: Friday, November 8, 2019 2:35 AM
> To: amd-gfx@lists.freedesktop.org
> Cc: Matt Coffin <mcoffin13@gmail.com>
> Subject: [PATCH 2/3] drm/amdgpu/navi10: implement GFXCLK_CURVE
> overdrive
>
> [Why]
> Before this patch, there was no way to set the gfxclk voltage curve in the
> overdrive settings for navi10 through pp_od_clk_voltage
>
> [How]
> Add the required implementation to navi10's ppt dpm table editing
> implementation, similar to the vega20 implementation and interface.
> ---
> drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 55 +++++++++++++++++++++-
> drivers/gpu/drm/amd/powerplay/navi10_ppt.h | 2 +
> 2 files changed, 55 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> index 6d0e511ad093..e717328f93ce 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> @@ -1667,6 +1667,8 @@ static int navi10_od_edit_dpm_table(struct
> smu_context *smu, enum PP_OD_DPM_TABL
> struct smu_table_context *table_context = &smu->smu_table;
> OverDriveTable_t *od_table;
> struct smu_11_0_overdrive_table *od_settings;
> + enum SMU_11_0_ODSETTING_ID freq_setting, voltage_setting;
> + uint16_t *freq_ptr, *voltage_ptr;
> od_table = (OverDriveTable_t *)table_context->overdrive_table;
>
> if (!smu->od_enabled) {
> @@ -1766,8 +1768,57 @@ static int navi10_od_edit_dpm_table(struct
> smu_context *smu, enum PP_OD_DPM_TABL
> }
> break;
> case PP_OD_EDIT_VDDC_CURVE:
> - // TODO: implement
> - return -ENOSYS;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_CURVE)) {
> + pr_warn("GFXCLK_CURVE not supported!\n");
> + return -ENOTSUPP;
> + }
> + if (size < 3) {
> + pr_info("invalid number of parameters: %d\n", size);
> + return -EINVAL;
> + }
> + if (!od_table) {
> + pr_info("Overdrive is not initialized\n");
> + return -EINVAL;
> + }
> +
> + switch (input[0]) {
> + case 0:
> + freq_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1;
> + voltage_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1;
> + freq_ptr = &od_table->GfxclkFreq1;
> + voltage_ptr = &od_table->GfxclkVolt1;
> + break;
> + case 1:
> + freq_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2;
> + voltage_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2;
> + freq_ptr = &od_table->GfxclkFreq2;
> + voltage_ptr = &od_table->GfxclkVolt2;
> + break;
> + case 2:
> + freq_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3;
> + voltage_setting =
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3;
> + freq_ptr = &od_table->GfxclkFreq3;
> + voltage_ptr = &od_table->GfxclkVolt3;
> + break;
> + default:
> + pr_info("Invalid VDDC_CURVE index: %ld\n", input[0]);
> + pr_info("Supported indices: [0, 1, 2]\n");
> + return -EINVAL;
> + }
> + ret = navi10_od_setting_check_range(od_settings, freq_setting,
> input[1]);
> + if (ret)
> + return ret;
> + // Allow setting zero to disable the OverDrive VDDC curve
> + if (input[2] != 0) {
> + ret = navi10_od_setting_check_range(od_settings,
> voltage_setting, input[2]);
> + if (ret)
> + return ret;
> + }
> + *freq_ptr = input[1];
> + *voltage_ptr = ((uint16_t)input[2]) * NAVI10_VOLTAGE_SCALE;
[Quan, Evan] Need to move this under "if (input[2] != 0)" protection also I think.
> + pr_debug("OD: set curve %ld: (%d, %d)\n", input[0], *freq_ptr,
> *voltage_ptr);
> + navi10_dump_od_table(od_table);
> + break;
> default:
> return -ENOSYS;
> }
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> index 620ff17c2fef..484d2c58fc06 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h
> @@ -27,6 +27,8 @@
> #define NAVI10_PEAK_SCLK_XT (1755)
> #define NAVI10_PEAK_SCLK_XL (1625)
>
> +#define NAVI10_VOLTAGE_SCALE (4)
> +
> extern void navi10_set_ppt_funcs(struct smu_context *smu);
>
> #endif
> --
> 2.23.0
>
>
> From e091c4085ecc669ea907fe5d8515f14586863f9b Mon Sep 17 00:00:00
> 2001
> Message-Id:
> <e091c4085ecc669ea907fe5d8515f14586863f9b.1573151434.git.mcoffin13@g
> mail.com>
> In-Reply-To: <cover.1573151434.git.mcoffin13@gmail.com>
> References: <cover.1573151434.git.mcoffin13@gmail.com>
> From: Matt Coffin <mcoffin13@gmail.com>
> Date: Wed, 6 Nov 2019 12:05:28 -0700
> Subject: [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
> To: amd-gfx@lists.freedesktop.org
>
> [Why]
> Before this patch, navi10 overdrive settings could not be printed via
> pp_od_clk_voltage
>
> [How]
> Implement printing for the overdrive settings for the following clocks
> in navi10's ppt print_clk_levels implementation:
>
> * SMU_OD_SCLK
> * SMU_OD_MCLK
> * SMU_OD_VDDC_CURVE
> ---
> drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 ++++++++++++++++++++--
> 1 file changed, 51 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> index e717328f93ce..506af59ff45f 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> @@ -677,13 +677,25 @@ static bool
> navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu
> return dpm_desc->SnapToDiscrete == 0 ? true : false;
> }
>
> +static inline bool navi10_od_feature_is_supported(struct
> smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID
> feature)
> +{
> + return od_table->cap[feature];
> +}
> +
> +
> static int navi10_print_clk_levels(struct smu_context *smu,
> enum smu_clk_type clk_type, char *buf)
> {
> + OverDriveTable_t *od_table;
> + struct smu_11_0_overdrive_table *od_settings;
> + uint16_t *curve_settings;
> int i, size = 0, ret = 0;
> uint32_t cur_value = 0, value = 0, count = 0;
> uint32_t freq_values[3] = {0};
> uint32_t mark_index = 0;
> + struct smu_table_context *table_context = &smu->smu_table;
> + od_table = (OverDriveTable_t *)table_context->overdrive_table;
> + od_settings = smu->od_settings;
>
> switch (clk_type) {
> case SMU_GFXCLK:
> @@ -734,6 +746,45 @@ static int navi10_print_clk_levels(struct smu_context
> *smu,
>
> }
> break;
> + case SMU_OD_SCLK:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_LIMITS))
> + break;
> + size += sprintf(buf + size, "OD_SCLK:\n");
> + size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table-
> >GfxclkFmin, od_table->GfxclkFmax);
> + break;
> + case SMU_OD_MCLK:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_UCLK_MAX))
> + break;
> + size += sprintf(buf + size, "OD_MCLK:\n");
> + size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
> + break;
> + case SMU_OD_VDDC_CURVE:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_CURVE))
> + break;
> + size += sprintf(buf + size, "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;
> + }
> + size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i,
> curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
> + }
> + break;
> default:
> break;
> }
> @@ -1600,11 +1651,6 @@ static inline void
> navi10_dump_od_table(OverDriveTable_t *od_table) {
> pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct);
> }
>
> -static inline bool navi10_od_feature_is_supported(struct
> smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID
> feature)
> -{
> - return od_table->cap[feature];
> -}
> -
> static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table
> *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value)
> {
> if (value < od_table->min[setting]) {
> --
> 2.23.0
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
@ 2019-11-08 5:50 ` Quan, Evan
0 siblings, 0 replies; 14+ messages in thread
From: Quan, Evan @ 2019-11-08 5:50 UTC (permalink / raw)
To: Matt Coffin, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
Reviewed-by: Evan Quan <evan.quan@amd.com>
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Matt
> Coffin
> Sent: Friday, November 8, 2019 2:36 AM
> To: amd-gfx@lists.freedesktop.org
> Cc: Matt Coffin <mcoffin13@gmail.com>
> Subject: [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
>
> [Why]
> Before this patch, navi10 overdrive settings could not be printed via
> pp_od_clk_voltage
>
> [How]
> Implement printing for the overdrive settings for the following clocks in
> navi10's ppt print_clk_levels implementation:
>
> * SMU_OD_SCLK
> * SMU_OD_MCLK
> * SMU_OD_VDDC_CURVE
> ---
> drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 ++++++++++++++++++++--
> 1 file changed, 51 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> index e717328f93ce..506af59ff45f 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> @@ -677,13 +677,25 @@ static bool
> navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu
> return dpm_desc->SnapToDiscrete == 0 ? true : false; }
>
> +static inline bool navi10_od_feature_is_supported(struct
> +smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID
> feature) {
> + return od_table->cap[feature];
> +}
> +
> +
> static int navi10_print_clk_levels(struct smu_context *smu,
> enum smu_clk_type clk_type, char *buf) {
> + OverDriveTable_t *od_table;
> + struct smu_11_0_overdrive_table *od_settings;
> + uint16_t *curve_settings;
> int i, size = 0, ret = 0;
> uint32_t cur_value = 0, value = 0, count = 0;
> uint32_t freq_values[3] = {0};
> uint32_t mark_index = 0;
> + struct smu_table_context *table_context = &smu->smu_table;
> + od_table = (OverDriveTable_t *)table_context->overdrive_table;
> + od_settings = smu->od_settings;
>
> switch (clk_type) {
> case SMU_GFXCLK:
> @@ -734,6 +746,45 @@ static int navi10_print_clk_levels(struct smu_context
> *smu,
>
> }
> break;
> + case SMU_OD_SCLK:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_LIMITS))
> + break;
> + size += sprintf(buf + size, "OD_SCLK:\n");
> + size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table-
> >GfxclkFmin, od_table->GfxclkFmax);
> + break;
> + case SMU_OD_MCLK:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_UCLK_MAX))
> + break;
> + size += sprintf(buf + size, "OD_MCLK:\n");
> + size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
> + break;
> + case SMU_OD_VDDC_CURVE:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_CURVE))
> + break;
> + size += sprintf(buf + size, "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;
> + }
> + size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i,
> curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
> + }
> + break;
> default:
> break;
> }
> @@ -1600,11 +1651,6 @@ static inline void
> navi10_dump_od_table(OverDriveTable_t *od_table) {
> pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct); }
>
> -static inline bool navi10_od_feature_is_supported(struct
> smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID
> feature) -{
> - return od_table->cap[feature];
> -}
> -
> static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table
> *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value) {
> if (value < od_table->min[setting]) {
> --
> 2.23.0
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
@ 2019-11-08 5:50 ` Quan, Evan
0 siblings, 0 replies; 14+ messages in thread
From: Quan, Evan @ 2019-11-08 5:50 UTC (permalink / raw)
To: Matt Coffin, amd-gfx
Reviewed-by: Evan Quan <evan.quan@amd.com>
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Matt
> Coffin
> Sent: Friday, November 8, 2019 2:36 AM
> To: amd-gfx@lists.freedesktop.org
> Cc: Matt Coffin <mcoffin13@gmail.com>
> Subject: [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing
>
> [Why]
> Before this patch, navi10 overdrive settings could not be printed via
> pp_od_clk_voltage
>
> [How]
> Implement printing for the overdrive settings for the following clocks in
> navi10's ppt print_clk_levels implementation:
>
> * SMU_OD_SCLK
> * SMU_OD_MCLK
> * SMU_OD_VDDC_CURVE
> ---
> drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 ++++++++++++++++++++--
> 1 file changed, 51 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> index e717328f93ce..506af59ff45f 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> @@ -677,13 +677,25 @@ static bool
> navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu
> return dpm_desc->SnapToDiscrete == 0 ? true : false; }
>
> +static inline bool navi10_od_feature_is_supported(struct
> +smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID
> feature) {
> + return od_table->cap[feature];
> +}
> +
> +
> static int navi10_print_clk_levels(struct smu_context *smu,
> enum smu_clk_type clk_type, char *buf) {
> + OverDriveTable_t *od_table;
> + struct smu_11_0_overdrive_table *od_settings;
> + uint16_t *curve_settings;
> int i, size = 0, ret = 0;
> uint32_t cur_value = 0, value = 0, count = 0;
> uint32_t freq_values[3] = {0};
> uint32_t mark_index = 0;
> + struct smu_table_context *table_context = &smu->smu_table;
> + od_table = (OverDriveTable_t *)table_context->overdrive_table;
> + od_settings = smu->od_settings;
>
> switch (clk_type) {
> case SMU_GFXCLK:
> @@ -734,6 +746,45 @@ static int navi10_print_clk_levels(struct smu_context
> *smu,
>
> }
> break;
> + case SMU_OD_SCLK:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_LIMITS))
> + break;
> + size += sprintf(buf + size, "OD_SCLK:\n");
> + size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table-
> >GfxclkFmin, od_table->GfxclkFmax);
> + break;
> + case SMU_OD_MCLK:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_UCLK_MAX))
> + break;
> + size += sprintf(buf + size, "OD_MCLK:\n");
> + size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
> + break;
> + case SMU_OD_VDDC_CURVE:
> + if (!smu->od_enabled || !od_table || !od_settings)
> + break;
> + if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODFEATURE_GFXCLK_CURVE))
> + break;
> + size += sprintf(buf + size, "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;
> + }
> + size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i,
> curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
> + }
> + break;
> default:
> break;
> }
> @@ -1600,11 +1651,6 @@ static inline void
> navi10_dump_od_table(OverDriveTable_t *od_table) {
> pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct); }
>
> -static inline bool navi10_od_feature_is_supported(struct
> smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID
> feature) -{
> - return od_table->cap[feature];
> -}
> -
> static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table
> *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value) {
> if (value < od_table->min[setting]) {
> --
> 2.23.0
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2019-11-08 5:50 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-07 18:32 [PATCH 0/3] navi10: Implement overdrive pp_od_clk_voltage Matt Coffin
2019-11-07 18:32 ` Matt Coffin
[not found] ` <cover.1573151434.git.mcoffin13-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2019-11-07 18:34 ` [PATCH 1/3] drm/amdgpu/navi10: implement sclk/mclk OD via pp_od_clk_voltage Matt Coffin
2019-11-07 18:34 ` Matt Coffin
[not found] ` <8573e9199daf592f6e6e5a807b69b37bb80f156a.1573151434.git.mcoffin13-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2019-11-08 5:48 ` Quan, Evan
2019-11-08 5:48 ` Quan, Evan
2019-11-07 18:34 ` [PATCH 2/3] drm/amdgpu/navi10: implement GFXCLK_CURVE overdrive Matt Coffin
2019-11-07 18:34 ` Matt Coffin
[not found] ` <7bc07e0b053381ce7409d8251be18380fb6b3c43.1573151434.git.mcoffin13-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2019-11-08 5:50 ` Quan, Evan
2019-11-08 5:50 ` Quan, Evan
2019-11-07 18:35 ` [PATCH 3/3] drm/amdgpu/navi10: Implement od clk printing Matt Coffin
2019-11-07 18:35 ` Matt Coffin
[not found] ` <e091c4085ecc669ea907fe5d8515f14586863f9b.1573151434.git.mcoffin13-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2019-11-08 5:50 ` Quan, Evan
2019-11-08 5:50 ` Quan, Evan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.