From: Alex Deucher <alexander.deucher@amd.com>
To: <amd-gfx@lists.freedesktop.org>
Cc: Yang Wang <kevinyang.wang@amd.com>,
Asad Kamal <asad.kamal@amd.com>,
"Lijo Lazar" <lijo.lazar@amd.com>,
Alex Deucher <alexander.deucher@amd.com>
Subject: [PATCH 07/25] drm/amd/pm: Setup driver pptable for smu 15.0.8
Date: Tue, 17 Mar 2026 16:12:23 -0400 [thread overview]
Message-ID: <20260317201242.3808136-7-alexander.deucher@amd.com> (raw)
In-Reply-To: <20260317201242.3808136-1-alexander.deucher@amd.com>
From: Yang Wang <kevinyang.wang@amd.com>
Setup driver pptable and initialize data from static metrics table for
smu_v15_0_8
v2: Remove unrelated changes and update description (Lijo)
v3: Use ARRAY_SIZE (Lijo)
v4: Move structure to header file
Signed-off-by: Yang Wang <kevinyang.wang@amd.com>
Signed-off-by: Asad Kamal <asad.kamal@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 +
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h | 1 +
.../drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c | 210 +++++++++++++++++-
.../drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.h | 30 +++
4 files changed, 237 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 892c90b8d063b..49e7881750fa7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -690,6 +690,7 @@ enum amdgpu_uid_type {
AMDGPU_UID_TYPE_XCD,
AMDGPU_UID_TYPE_AID,
AMDGPU_UID_TYPE_SOC,
+ AMDGPU_UID_TYPE_MID,
AMDGPU_UID_TYPE_MAX
};
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h
index 95c77e926e1fe..06842d38c92bd 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h
@@ -109,6 +109,7 @@ struct smu_15_0_dpm_context {
uint32_t workload_policy_mask;
uint32_t dcef_min_ds_clk;
uint64_t caps;
+ uint32_t board_volt;
};
enum smu_15_0_power_state {
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c
index ae2e0d44b1da1..82b09fe7fccd5 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c
@@ -35,6 +35,7 @@
#include "mp/mp_15_0_8_offset.h"
#include "mp/mp_15_0_8_sh_mask.h"
#include "smu_v15_0.h"
+#include "amdgpu_fru_eeprom.h"
#undef MP1_Public
@@ -51,6 +52,10 @@
#undef pr_info
#undef pr_debug
+#define SMUQ10_TO_UINT(x) ((x) >> 10)
+#define SMUQ10_FRAC(x) ((x) & 0x3ff)
+#define SMUQ10_ROUND(x) ((SMUQ10_TO_UINT(x)) + ((SMUQ10_FRAC(x)) >= 0x200))
+
#define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c))
#define SMU_15_0_8_FEA_MAP(smu_feature, smu_15_0_8_feature) \
@@ -161,6 +166,35 @@ static const struct cmn2asic_mapping smu_v15_0_8_table_map[SMU_TABLE_COUNT] = {
static int smu_v15_0_8_tables_init(struct smu_context *smu)
{
+ struct smu_table_context *smu_table = &smu->smu_table;
+ struct smu_table *tables = smu_table->tables;
+ int gpu_metrcs_size = sizeof(MetricsTable_t);
+ void *driver_pptable __free(kfree) = NULL;
+ void *metrics_table __free(kfree) = NULL;
+
+ SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU15_TOOL_SIZE,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
+
+ SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS,
+ gpu_metrcs_size,
+ PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT);
+
+ metrics_table = kzalloc(gpu_metrcs_size, GFP_KERNEL);
+ if (!metrics_table)
+ return -ENOMEM;
+
+ smu_table->metrics_time = 0;
+
+ driver_pptable = kzalloc(sizeof(PPTable_t), GFP_KERNEL);
+ if (!driver_pptable)
+ return -ENOMEM;
+
+ smu_table->metrics_table = no_free_ptr(metrics_table);
+ smu_table->driver_pptable = no_free_ptr(driver_pptable);
+
+ mutex_init(&smu_table->metrics_lock);
+
return 0;
}
@@ -197,16 +231,35 @@ static int smu_v15_0_8_init_smc_tables(struct smu_context *smu)
return ret;
}
-static int smu_v15_0_8_init_allowed_features(struct smu_context *smu)
+static int smu_v15_0_8_tables_fini(struct smu_context *smu)
{
- /* pptable will handle the features to enable */
- smu_feature_list_set_all(smu, SMU_FEATURE_LIST_ALLOWED);
+ struct smu_table_context *smu_table = &smu->smu_table;
+
+ mutex_destroy(&smu_table->metrics_lock);
return 0;
}
-static int smu_v15_0_8_set_default_dpm_table(struct smu_context *smu)
+static int smu_v15_0_8_fini_smc_tables(struct smu_context *smu)
{
+ int ret;
+
+ ret = smu_v15_0_8_tables_fini(smu);
+ if (ret)
+ return ret;
+
+ ret = smu_v15_0_fini_smc_tables(smu);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int smu_v15_0_8_init_allowed_features(struct smu_context *smu)
+{
+ /* pptable will handle the features to enable */
+ smu_feature_list_set_all(smu, SMU_FEATURE_LIST_ALLOWED);
+
return 0;
}
@@ -258,6 +311,153 @@ static int smu_v15_0_8_get_static_metrics_table(struct smu_context *smu)
return 0;
}
+static int smu_v15_0_8_fru_get_product_info(struct smu_context *smu,
+ StaticMetricsTable_t *static_metrics)
+{
+ struct amdgpu_fru_info *fru_info;
+ struct amdgpu_device *adev = smu->adev;
+
+ if (!adev->fru_info) {
+ adev->fru_info = kzalloc(sizeof(*adev->fru_info), GFP_KERNEL);
+ if (!adev->fru_info)
+ return -ENOMEM;
+ }
+
+ fru_info = adev->fru_info;
+ strscpy(fru_info->product_number, static_metrics->ProductInfo.ModelNumber,
+ sizeof(fru_info->product_number));
+ strscpy(fru_info->product_name, static_metrics->ProductInfo.Name,
+ sizeof(fru_info->product_name));
+ strscpy(fru_info->serial, static_metrics->ProductInfo.Serial,
+ sizeof(fru_info->serial));
+ strscpy(fru_info->manufacturer_name, static_metrics->ProductInfo.ManufacturerName,
+ sizeof(fru_info->manufacturer_name));
+ strscpy(fru_info->fru_id, static_metrics->ProductInfo.FruId,
+ sizeof(fru_info->fru_id));
+
+ return 0;
+}
+
+static void smu_v15_0_8_init_xgmi_data(struct smu_context *smu,
+ StaticMetricsTable_t *static_metrics)
+{
+ uint16_t max_speed;
+ uint8_t max_width;
+
+ max_width = (uint8_t)static_metrics->MaxXgmiWidth;
+ max_speed = (uint16_t)static_metrics->MaxXgmiBitrate;
+ amgpu_xgmi_set_max_speed_width(smu->adev, max_speed, max_width);
+}
+
+static int smu_v15_0_8_set_driver_pptable(struct smu_context *smu)
+{
+ struct smu_15_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
+ struct smu_table_context *smu_table = &smu->smu_table;
+ StaticMetricsTable_t *static_metrics = (StaticMetricsTable_t *)smu_table->metrics_table;
+ PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable;
+ int ret, i, n;
+ uint32_t table_version;
+
+ if (!pptable->init) {
+ ret = smu_v15_0_8_get_static_metrics_table(smu);
+ if (ret)
+ return ret;
+
+ ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetMetricsVersion,
+ &table_version);
+ if (ret)
+ return ret;
+ smu_table->tables[SMU_TABLE_SMU_METRICS].version =
+ table_version;
+
+ pptable->MaxSocketPowerLimit =
+ SMUQ10_ROUND(static_metrics->MaxSocketPowerLimit);
+ pptable->MaxGfxclkFrequency =
+ SMUQ10_ROUND(static_metrics->MaxGfxclkFrequency);
+ pptable->MinGfxclkFrequency =
+ SMUQ10_ROUND(static_metrics->MinGfxclkFrequency);
+ pptable->MaxFclkFrequency =
+ SMUQ10_ROUND(static_metrics->MaxFclkFrequency);
+ pptable->MinFclkFrequency =
+ SMUQ10_ROUND(static_metrics->MinFclkFrequency);
+ pptable->MaxGl2clkFrequency =
+ SMUQ10_ROUND(static_metrics->MaxGl2clkFrequency);
+ pptable->MinGl2clkFrequency =
+ SMUQ10_ROUND(static_metrics->MinGl2clkFrequency);
+
+ for (i = 0; i < ARRAY_SIZE(static_metrics->UclkFrequencyTable); ++i)
+ pptable->UclkFrequencyTable[i] =
+ SMUQ10_ROUND(static_metrics->UclkFrequencyTable[i]);
+
+ pptable->SocclkFrequency = SMUQ10_ROUND(static_metrics->SocclkFrequency);
+ pptable->LclkFrequency = SMUQ10_ROUND(static_metrics->LclkFrequency);
+ pptable->VclkFrequency = SMUQ10_ROUND(static_metrics->VclkFrequency);
+ pptable->DclkFrequency = SMUQ10_ROUND(static_metrics->DclkFrequency);
+
+ pptable->CTFLimitMID = SMUQ10_ROUND(static_metrics->CTFLimit_MID);
+ pptable->CTFLimitAID = SMUQ10_ROUND(static_metrics->CTFLimit_AID);
+ pptable->CTFLimitXCD = SMUQ10_ROUND(static_metrics->CTFLimit_XCD);
+ pptable->CTFLimitHBM = SMUQ10_ROUND(static_metrics->CTFLimit_HBM);
+ pptable->ThermalLimitMID = SMUQ10_ROUND(static_metrics->ThermalLimit_MID);
+ pptable->ThermalLimitAID = SMUQ10_ROUND(static_metrics->ThermalLimit_AID);
+ pptable->ThermalLimitXCD = SMUQ10_ROUND(static_metrics->ThermalLimit_XCD);
+ pptable->ThermalLimitHBM = SMUQ10_ROUND(static_metrics->ThermalLimit_HBM);
+
+ /* use MID0 serial number by default */
+ pptable->PublicSerialNumberMID =
+ static_metrics->PublicSerialNumber_MID[0];
+
+ amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_SOC,
+ 0, pptable->PublicSerialNumberMID);
+ pptable->PublicSerialNumberAID =
+ static_metrics->PublicSerialNumber_AID[0];
+ pptable->PublicSerialNumberXCD =
+ static_metrics->PublicSerialNumber_XCD[0];
+ n = ARRAY_SIZE(static_metrics->PublicSerialNumber_MID);
+ for (i = 0; i < n; i++) {
+ amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_MID, i,
+ static_metrics->PublicSerialNumber_MID[i]);
+ }
+ n = ARRAY_SIZE(static_metrics->PublicSerialNumber_AID);
+ for (i = 0; i < n; i++) {
+ amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_AID, i,
+ static_metrics->PublicSerialNumber_AID[i]);
+ }
+ n = ARRAY_SIZE(static_metrics->PublicSerialNumber_XCD);
+ for (i = 0; i < n; i++) {
+ amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_XCD, i,
+ static_metrics->PublicSerialNumber_XCD[i]);
+ }
+
+ ret = smu_v15_0_8_fru_get_product_info(smu, static_metrics);
+ if (ret)
+ return ret;
+ pptable->PPT1Max = static_metrics->PPT1Max;
+ pptable->PPT1Min = static_metrics->PPT1Min;
+ pptable->PPT1Default = static_metrics->PPT1Default;
+
+ if (static_metrics->pldmVersion[0] != 0xFFFFFFFF)
+ smu->adev->firmware.pldm_version =
+ static_metrics->pldmVersion[0];
+ dpm_context->board_volt = static_metrics->InputTelemetryVoltageInmV;
+ smu_v15_0_8_init_xgmi_data(smu, static_metrics);
+ pptable->init = true;
+ }
+
+ return 0;
+}
+
+static int smu_v15_0_8_set_default_dpm_table(struct smu_context *smu)
+{
+ int ret;
+
+ ret = smu_v15_0_8_set_driver_pptable(smu);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static int smu_v15_0_8_irq_process(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry)
@@ -498,7 +698,7 @@ static const struct pptable_funcs smu_v15_0_8_ppt_funcs = {
.set_default_dpm_table = smu_v15_0_8_set_default_dpm_table,
.is_dpm_running = smu_v15_0_8_is_dpm_running,
.init_smc_tables = smu_v15_0_8_init_smc_tables,
- .fini_smc_tables = smu_v15_0_fini_smc_tables,
+ .fini_smc_tables = smu_v15_0_8_fini_smc_tables,
.init_power = smu_v15_0_init_power,
.fini_power = smu_v15_0_fini_power,
.check_fw_status = smu_v15_0_8_check_fw_status,
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.h b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.h
index 40c410928c966..6c85f23d31116 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.h
@@ -25,4 +25,34 @@
extern void smu_v15_0_8_set_ppt_funcs(struct smu_context *smu);
+typedef struct {
+ uint32_t MaxSocketPowerLimit;
+ uint32_t MaxGfxclkFrequency;
+ uint32_t MinGfxclkFrequency;
+ uint32_t MaxFclkFrequency;
+ uint32_t MinFclkFrequency;
+ uint32_t MaxGl2clkFrequency;
+ uint32_t MinGl2clkFrequency;
+ uint32_t UclkFrequencyTable[4];
+ uint32_t SocclkFrequency;
+ uint32_t LclkFrequency;
+ uint32_t VclkFrequency;
+ uint32_t DclkFrequency;
+ uint32_t CTFLimitMID;
+ uint32_t CTFLimitAID;
+ uint32_t CTFLimitXCD;
+ uint32_t CTFLimitHBM;
+ uint32_t ThermalLimitMID;
+ uint32_t ThermalLimitAID;
+ uint32_t ThermalLimitXCD;
+ uint32_t ThermalLimitHBM;
+ uint64_t PublicSerialNumberMID;
+ uint64_t PublicSerialNumberAID;
+ uint64_t PublicSerialNumberXCD;
+ uint32_t PPT1Max;
+ uint32_t PPT1Min;
+ uint32_t PPT1Default;
+ bool init;
+} PPTable_t;
+
#endif
--
2.53.0
next prev parent reply other threads:[~2026-03-17 20:13 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-17 20:12 [PATCH 01/25] drm/amd/pm: Add smu v15_0_8 driver interface header Alex Deucher
2026-03-17 20:12 ` [PATCH 02/25] drm/amd/pm: Add smu v15_0_8 message header Alex Deucher
2026-03-17 20:12 ` [PATCH 03/25] drm/amd/pm: Add smu v15_0_8 pmfw header Alex Deucher
2026-03-17 20:12 ` [PATCH 04/25] drm/amd/pm: Add initial support for smu v15_0_8 Alex Deucher
2026-03-17 20:12 ` [PATCH 05/25] drm/amd/pm: Add mode2 support for smu_v15_0_8 Alex Deucher
2026-03-17 20:12 ` [PATCH 06/25] drm/amd/pm: Add static metrics support Alex Deucher
2026-03-17 20:12 ` Alex Deucher [this message]
2026-03-17 20:12 ` [PATCH 08/25] drm/amd/pm: Update dpm table structs for smu_v15_0 Alex Deucher
2026-03-17 20:12 ` [PATCH 09/25] drm/amd/pm: Add default dpm table support for smu 15.0.8 Alex Deucher
2026-03-17 20:12 ` [PATCH 10/25] drm/amd/pm: Add get_pm_metrics " Alex Deucher
2026-03-17 20:12 ` [PATCH 11/25] drm/amd/pm: add get_gpu_metrics support for 15.0.8 Alex Deucher
2026-03-17 20:12 ` [PATCH 12/25] drm/amd/pm: add get_unique_id support for smu 15.0.8 Alex Deucher
2026-03-17 20:12 ` [PATCH 13/25] drm/amd/pm: add set{get}_power_limit " Alex Deucher
2026-03-17 20:12 ` [PATCH 14/25] drm/amd/pm: Add emit clock support Alex Deucher
2026-03-17 20:12 ` [PATCH 15/25] drm/amd/pm: add populate_umd_state_clk support Alex Deucher
2026-03-17 20:12 ` [PATCH 16/25] drm/amd/pm: Add set_performance_support Alex Deucher
2026-03-17 20:12 ` [PATCH 17/25] drm/amd/pm: Add od_edit_dpm_table support Alex Deucher
2026-03-17 20:12 ` [PATCH 18/25] drm/amd/pm: Add get_thermal_temperature_range support Alex Deucher
2026-03-17 20:12 ` [PATCH 19/25] drm/amd/pm: Add ppt1 support Alex Deucher
2026-03-17 20:12 ` [PATCH 20/25] drm/amd/pm: Add read sensor support Alex Deucher
2026-03-17 20:12 ` [PATCH 21/25] drm/amd/pm: Add gpuboard temperature metrics support Alex Deucher
2026-03-17 20:12 ` [PATCH 22/25] drm/amd/pm: Add baseboard " Alex Deucher
2026-03-17 20:12 ` [PATCH 23/25] drm/amd/pm: Add NPM support for smu_v15_0_8 Alex Deucher
2026-03-17 20:12 ` [PATCH 24/25] drm/amdgpu: Add smu v15_0_8 ip block Alex Deucher
2026-03-17 20:12 ` [PATCH 25/25] drm/amd/pm: Enable user specified gfx clock ranges Alex Deucher
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260317201242.3808136-7-alexander.deucher@amd.com \
--to=alexander.deucher@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=asad.kamal@amd.com \
--cc=kevinyang.wang@amd.com \
--cc=lijo.lazar@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox