* [PATCH V1 0/2] Get real time power input via AMD PMF
@ 2025-12-11 17:58 Lizhi Hou
2025-12-11 17:58 ` [PATCH V1 1/2] platform/x86/amd/pmf: Introduce new interface to export NPU metrics Lizhi Hou
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Lizhi Hou @ 2025-12-11 17:58 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, ogabbay, quic_jhugo, maciej.falkowski
Cc: Lizhi Hou, linux-kernel, max.zhen, sonal.santan,
mario.limonciello, platform-driver-x86, dri-devel,
Shyam-sundar.S-k, VinitKumar.Shukla
Adding new NPU metrics API to AMD PMF driver is pending because of
lacking real case.
https://lore.kernel.org/all/d344b850-f68d-f9a5-f0dc-55af4b48b714@linux.intel.com/
Create xdna driver patch to fetch real time power input via PMF API.
Here is an example output with xrt-smi(1) tool.
# xrt-smi examine -r all | grep Power
Power Mode : Default
Estimated Power : 0.563 Watts
Lizhi Hou (1):
accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate
Shyam Sundar S K (1):
platform/x86/amd/pmf: Introduce new interface to export NPU metrics
drivers/accel/amdxdna/aie2_pci.c | 29 ++++++++++
drivers/accel/amdxdna/aie2_pci.h | 18 ++++++
drivers/accel/amdxdna/amdxdna_pci_drv.c | 3 +-
drivers/platform/x86/amd/pmf/core.c | 75 +++++++++++++++++++++++++
drivers/platform/x86/amd/pmf/pmf.h | 2 +
include/linux/amd-pmf-io.h | 21 +++++++
6 files changed, 147 insertions(+), 1 deletion(-)
--
2.34.1
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH V1 1/2] platform/x86/amd/pmf: Introduce new interface to export NPU metrics 2025-12-11 17:58 [PATCH V1 0/2] Get real time power input via AMD PMF Lizhi Hou @ 2025-12-11 17:58 ` Lizhi Hou 2025-12-11 18:28 ` Ilpo Järvinen 2025-12-11 17:58 ` [PATCH V2 2/2] accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate Lizhi Hou 2025-12-11 18:22 ` [PATCH V1 0/2] Get real time power input via AMD PMF Mario Limonciello 2 siblings, 1 reply; 13+ messages in thread From: Lizhi Hou @ 2025-12-11 17:58 UTC (permalink / raw) To: ilpo.jarvinen, hansg, ogabbay, quic_jhugo, maciej.falkowski Cc: Shyam Sundar S K, linux-kernel, max.zhen, sonal.santan, mario.limonciello, platform-driver-x86, dri-devel, VinitKumar.Shukla, Patil Rajesh Reddy, Lizhi Hou From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> The PMF driver retrieves NPU metrics data from the PMFW. Introduce a new interface to make NPU metrics accessible to other drivers like AMDXDNA driver, which can access and utilize this information as needed. Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> Co-developed-by: Patil Rajesh Reddy <Patil.Reddy@amd.com> Signed-off-by: Patil Rajesh Reddy <Patil.Reddy@amd.com> Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> --- drivers/platform/x86/amd/pmf/core.c | 75 +++++++++++++++++++++++++++++ drivers/platform/x86/amd/pmf/pmf.h | 2 + include/linux/amd-pmf-io.h | 21 ++++++++ 3 files changed, 98 insertions(+) diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c index a6a5d416edf9..8e4ce91b3527 100644 --- a/drivers/platform/x86/amd/pmf/core.c +++ b/drivers/platform/x86/amd/pmf/core.c @@ -8,12 +8,15 @@ * Author: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> */ +#include <linux/array_size.h> +#include <linux/cleanup.h> #include <linux/debugfs.h> #include <linux/iopoll.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/platform_device.h> #include <linux/power_supply.h> +#include <linux/string.h> #include <asm/amd/node.h> #include "pmf.h" @@ -53,6 +56,8 @@ static bool force_load; module_param(force_load, bool, 0444); MODULE_PARM_DESC(force_load, "Force load this driver on supported older platforms (experimental)"); +static struct device *pmf_device; + static int amd_pmf_pwr_src_notify_call(struct notifier_block *nb, unsigned long event, void *data) { struct amd_pmf_dev *pmf = container_of(nb, struct amd_pmf_dev, pwr_src_notifier); @@ -314,6 +319,70 @@ int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev) return 0; } +static int is_npu_metrics_supported(struct amd_pmf_dev *pdev) +{ + switch (pdev->cpu_id) { + case PCI_DEVICE_ID_AMD_1AH_M20H_ROOT: + case PCI_DEVICE_ID_AMD_1AH_M60H_ROOT: + return 0; + default: + return -EOPNOTSUPP; + } +} + +static int amd_pmf_get_smu_metrics(struct amd_pmf_dev *dev, struct amd_pmf_npu_metrics *data) +{ + int ret, i; + + guard(mutex)(&dev->metrics_mutex); + + if (is_npu_metrics_supported(dev)) + return -EOPNOTSUPP; + + ret = amd_pmf_set_dram_addr(dev, true); + if (ret) + return ret; + + memset(dev->buf, 0, dev->mtable_size); + + /* Send SMU command to get NPU metrics */ + ret = amd_pmf_send_cmd(dev, SET_TRANSFER_TABLE, SET_CMD, METRICS_TABLE_ID, NULL); + if (ret) { + dev_err(dev->dev, "SMU command failed to get NPU metrics: %d\n", ret); + return ret; + } + + memcpy(&dev->m_table_v2, dev->buf, dev->mtable_size); + + data->npuclk_freq = dev->m_table_v2.npuclk_freq; + for (i = 0; i < ARRAY_SIZE(data->npu_busy); i++) + data->npu_busy[i] = dev->m_table_v2.npu_busy[i]; + data->npu_power = dev->m_table_v2.npu_power; + data->mpnpuclk_freq = dev->m_table_v2.mpnpuclk_freq; + data->npu_reads = dev->m_table_v2.npu_reads; + data->npu_writes = dev->m_table_v2.npu_writes; + + return 0; +} + +int amd_pmf_get_npu_data(struct amd_pmf_npu_metrics *info) +{ + struct amd_pmf_dev *pdev; + + if (!info) + return -EINVAL; + + if (!pmf_device) + return -ENODEV; + + pdev = dev_get_drvdata(pmf_device); + if (!pdev) + return -ENODEV; + + return amd_pmf_get_smu_metrics(pdev, info); +} +EXPORT_SYMBOL_GPL(amd_pmf_get_npu_data); + static int amd_pmf_suspend_handler(struct device *dev) { struct amd_pmf_dev *pdev = dev_get_drvdata(dev); @@ -469,6 +538,10 @@ static int amd_pmf_probe(struct platform_device *pdev) mutex_init(&dev->update_mutex); mutex_init(&dev->cb_mutex); + err = devm_mutex_init(dev->dev, &dev->metrics_mutex); + if (err) + return err; + apmf_acpi_init(dev); platform_set_drvdata(pdev, dev); amd_pmf_dbgfs_register(dev); @@ -477,6 +550,8 @@ static int amd_pmf_probe(struct platform_device *pdev) if (is_apmf_func_supported(dev, APMF_FUNC_SBIOS_HEARTBEAT_V2)) amd_pmf_notify_sbios_heartbeat_event_v2(dev, ON_LOAD); + pmf_device = dev->dev; + dev_info(dev->dev, "registered PMF device successfully\n"); return 0; diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h index f07e9f4c660a..0354cc5dc79e 100644 --- a/drivers/platform/x86/amd/pmf/pmf.h +++ b/drivers/platform/x86/amd/pmf/pmf.h @@ -12,6 +12,7 @@ #define PMF_H #include <linux/acpi.h> +#include <linux/amd-pmf-io.h> #include <linux/input.h> #include <linux/platform_device.h> #include <linux/platform_profile.h> @@ -412,6 +413,7 @@ struct amd_pmf_dev { struct apmf_sbios_req_v1 req1; struct pmf_bios_inputs_prev cb_prev; /* To preserve custom BIOS inputs */ bool cb_flag; /* To handle first custom BIOS input */ + struct mutex metrics_mutex; }; struct apmf_sps_prop_granular_v2 { diff --git a/include/linux/amd-pmf-io.h b/include/linux/amd-pmf-io.h index 6fa510f419c0..55198d2875cc 100644 --- a/include/linux/amd-pmf-io.h +++ b/include/linux/amd-pmf-io.h @@ -61,5 +61,26 @@ enum laptop_placement { LP_UNDEFINED, }; +/** + * struct amd_pmf_npu_metrics: Get NPU metrics data from PMF driver + * @npuclk_freq: NPU clock frequency [MHz] + * @npu_busy: NPU busy % [0-100] + * @npu_power: NPU power [mW] + * @mpnpuclk_freq: MPNPU [MHz] + * @npu_reads: NPU read bandwidth [MB/sec] + * @npu_writes: NPU write bandwidth [MB/sec] + */ +struct amd_pmf_npu_metrics { + u16 npuclk_freq; + u16 npu_busy[8]; + u16 npu_power; + u16 mpnpuclk_freq; + u16 npu_reads; + u16 npu_writes; +}; + int amd_get_sfh_info(struct amd_sfh_info *sfh_info, enum sfh_message_type op); + +/* AMD PMF and NPU interface */ +int amd_pmf_get_npu_data(struct amd_pmf_npu_metrics *info); #endif -- 2.34.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH V1 1/2] platform/x86/amd/pmf: Introduce new interface to export NPU metrics 2025-12-11 17:58 ` [PATCH V1 1/2] platform/x86/amd/pmf: Introduce new interface to export NPU metrics Lizhi Hou @ 2025-12-11 18:28 ` Ilpo Järvinen 2025-12-11 19:07 ` Lizhi Hou 2025-12-12 6:00 ` Shyam Sundar S K 0 siblings, 2 replies; 13+ messages in thread From: Ilpo Järvinen @ 2025-12-11 18:28 UTC (permalink / raw) To: Lizhi Hou Cc: Hans de Goede, ogabbay, quic_jhugo, maciej.falkowski, Shyam Sundar S K, LKML, max.zhen, sonal.santan, mario.limonciello, platform-driver-x86, dri-devel, VinitKumar.Shukla, Patil Rajesh Reddy On Thu, 11 Dec 2025, Lizhi Hou wrote: > From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> > > The PMF driver retrieves NPU metrics data from the PMFW. Introduce a new > interface to make NPU metrics accessible to other drivers like AMDXDNA > driver, which can access and utilize this information as needed. > > Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> > Co-developed-by: Patil Rajesh Reddy <Patil.Reddy@amd.com> > Signed-off-by: Patil Rajesh Reddy <Patil.Reddy@amd.com> > Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> > Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> > --- > drivers/platform/x86/amd/pmf/core.c | 75 +++++++++++++++++++++++++++++ > drivers/platform/x86/amd/pmf/pmf.h | 2 + > include/linux/amd-pmf-io.h | 21 ++++++++ > 3 files changed, 98 insertions(+) > > diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c > index a6a5d416edf9..8e4ce91b3527 100644 > --- a/drivers/platform/x86/amd/pmf/core.c > +++ b/drivers/platform/x86/amd/pmf/core.c > @@ -8,12 +8,15 @@ > * Author: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> > */ > > +#include <linux/array_size.h> > +#include <linux/cleanup.h> > #include <linux/debugfs.h> > #include <linux/iopoll.h> > #include <linux/module.h> > #include <linux/pci.h> > #include <linux/platform_device.h> > #include <linux/power_supply.h> > +#include <linux/string.h> > #include <asm/amd/node.h> > #include "pmf.h" > > @@ -53,6 +56,8 @@ static bool force_load; > module_param(force_load, bool, 0444); > MODULE_PARM_DESC(force_load, "Force load this driver on supported older platforms (experimental)"); > > +static struct device *pmf_device; > + > static int amd_pmf_pwr_src_notify_call(struct notifier_block *nb, unsigned long event, void *data) > { > struct amd_pmf_dev *pmf = container_of(nb, struct amd_pmf_dev, pwr_src_notifier); > @@ -314,6 +319,70 @@ int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev) > return 0; > } > > +static int is_npu_metrics_supported(struct amd_pmf_dev *pdev) > +{ > + switch (pdev->cpu_id) { > + case PCI_DEVICE_ID_AMD_1AH_M20H_ROOT: > + case PCI_DEVICE_ID_AMD_1AH_M60H_ROOT: > + return 0; > + default: > + return -EOPNOTSUPP; > + } > +} > + > +static int amd_pmf_get_smu_metrics(struct amd_pmf_dev *dev, struct amd_pmf_npu_metrics *data) > +{ > + int ret, i; > + > + guard(mutex)(&dev->metrics_mutex); > + > + if (is_npu_metrics_supported(dev)) > + return -EOPNOTSUPP; > + > + ret = amd_pmf_set_dram_addr(dev, true); > + if (ret) > + return ret; > + > + memset(dev->buf, 0, dev->mtable_size); > + > + /* Send SMU command to get NPU metrics */ > + ret = amd_pmf_send_cmd(dev, SET_TRANSFER_TABLE, SET_CMD, METRICS_TABLE_ID, NULL); > + if (ret) { > + dev_err(dev->dev, "SMU command failed to get NPU metrics: %d\n", ret); > + return ret; > + } > + > + memcpy(&dev->m_table_v2, dev->buf, dev->mtable_size); > + > + data->npuclk_freq = dev->m_table_v2.npuclk_freq; > + for (i = 0; i < ARRAY_SIZE(data->npu_busy); i++) > + data->npu_busy[i] = dev->m_table_v2.npu_busy[i]; > + data->npu_power = dev->m_table_v2.npu_power; > + data->mpnpuclk_freq = dev->m_table_v2.mpnpuclk_freq; > + data->npu_reads = dev->m_table_v2.npu_reads; > + data->npu_writes = dev->m_table_v2.npu_writes; > + > + return 0; > +} > + > +int amd_pmf_get_npu_data(struct amd_pmf_npu_metrics *info) > +{ > + struct amd_pmf_dev *pdev; > + > + if (!info) > + return -EINVAL; > + > + if (!pmf_device) > + return -ENODEV; > + > + pdev = dev_get_drvdata(pmf_device); > + if (!pdev) > + return -ENODEV; > + > + return amd_pmf_get_smu_metrics(pdev, info); > +} > +EXPORT_SYMBOL_GPL(amd_pmf_get_npu_data); > + > static int amd_pmf_suspend_handler(struct device *dev) > { > struct amd_pmf_dev *pdev = dev_get_drvdata(dev); > @@ -469,6 +538,10 @@ static int amd_pmf_probe(struct platform_device *pdev) > mutex_init(&dev->update_mutex); > mutex_init(&dev->cb_mutex); > > + err = devm_mutex_init(dev->dev, &dev->metrics_mutex); > + if (err) > + return err; > + > apmf_acpi_init(dev); > platform_set_drvdata(pdev, dev); > amd_pmf_dbgfs_register(dev); > @@ -477,6 +550,8 @@ static int amd_pmf_probe(struct platform_device *pdev) > if (is_apmf_func_supported(dev, APMF_FUNC_SBIOS_HEARTBEAT_V2)) > amd_pmf_notify_sbios_heartbeat_event_v2(dev, ON_LOAD); > > + pmf_device = dev->dev; > + > dev_info(dev->dev, "registered PMF device successfully\n"); > > return 0; > diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h > index f07e9f4c660a..0354cc5dc79e 100644 > --- a/drivers/platform/x86/amd/pmf/pmf.h > +++ b/drivers/platform/x86/amd/pmf/pmf.h > @@ -12,6 +12,7 @@ > #define PMF_H > > #include <linux/acpi.h> > +#include <linux/amd-pmf-io.h> > #include <linux/input.h> > #include <linux/platform_device.h> > #include <linux/platform_profile.h> > @@ -412,6 +413,7 @@ struct amd_pmf_dev { > struct apmf_sbios_req_v1 req1; > struct pmf_bios_inputs_prev cb_prev; /* To preserve custom BIOS inputs */ > bool cb_flag; /* To handle first custom BIOS input */ > + struct mutex metrics_mutex; This files seems to lack include for struct mutex (despite using them already so please add it finally there :-)). > }; > > struct apmf_sps_prop_granular_v2 { > diff --git a/include/linux/amd-pmf-io.h b/include/linux/amd-pmf-io.h > index 6fa510f419c0..55198d2875cc 100644 > --- a/include/linux/amd-pmf-io.h > +++ b/include/linux/amd-pmf-io.h > @@ -61,5 +61,26 @@ enum laptop_placement { > LP_UNDEFINED, > }; > > +/** > + * struct amd_pmf_npu_metrics: Get NPU metrics data from PMF driver > + * @npuclk_freq: NPU clock frequency [MHz] > + * @npu_busy: NPU busy % [0-100] > + * @npu_power: NPU power [mW] > + * @mpnpuclk_freq: MPNPU [MHz] > + * @npu_reads: NPU read bandwidth [MB/sec] > + * @npu_writes: NPU write bandwidth [MB/sec] > + */ > +struct amd_pmf_npu_metrics { > + u16 npuclk_freq; > + u16 npu_busy[8]; > + u16 npu_power; > + u16 mpnpuclk_freq; > + u16 npu_reads; > + u16 npu_writes; > +}; > + > int amd_get_sfh_info(struct amd_sfh_info *sfh_info, enum sfh_message_type op); > + > +/* AMD PMF and NPU interface */ > +int amd_pmf_get_npu_data(struct amd_pmf_npu_metrics *info); > #endif > -- i. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V1 1/2] platform/x86/amd/pmf: Introduce new interface to export NPU metrics 2025-12-11 18:28 ` Ilpo Järvinen @ 2025-12-11 19:07 ` Lizhi Hou 2025-12-12 6:00 ` Shyam Sundar S K 1 sibling, 0 replies; 13+ messages in thread From: Lizhi Hou @ 2025-12-11 19:07 UTC (permalink / raw) To: Ilpo Järvinen Cc: Hans de Goede, ogabbay, quic_jhugo, maciej.falkowski, Shyam Sundar S K, LKML, max.zhen, sonal.santan, mario.limonciello, platform-driver-x86, dri-devel, VinitKumar.Shukla, Patil Rajesh Reddy On 12/11/25 10:28, Ilpo Järvinen wrote: > On Thu, 11 Dec 2025, Lizhi Hou wrote: > >> From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> >> >> The PMF driver retrieves NPU metrics data from the PMFW. Introduce a new >> interface to make NPU metrics accessible to other drivers like AMDXDNA >> driver, which can access and utilize this information as needed. >> >> Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> >> Co-developed-by: Patil Rajesh Reddy <Patil.Reddy@amd.com> >> Signed-off-by: Patil Rajesh Reddy <Patil.Reddy@amd.com> >> Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> >> Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> >> --- >> drivers/platform/x86/amd/pmf/core.c | 75 +++++++++++++++++++++++++++++ >> drivers/platform/x86/amd/pmf/pmf.h | 2 + >> include/linux/amd-pmf-io.h | 21 ++++++++ >> 3 files changed, 98 insertions(+) >> >> diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c >> index a6a5d416edf9..8e4ce91b3527 100644 >> --- a/drivers/platform/x86/amd/pmf/core.c >> +++ b/drivers/platform/x86/amd/pmf/core.c >> @@ -8,12 +8,15 @@ >> * Author: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> >> */ >> >> +#include <linux/array_size.h> >> +#include <linux/cleanup.h> >> #include <linux/debugfs.h> >> #include <linux/iopoll.h> >> #include <linux/module.h> >> #include <linux/pci.h> >> #include <linux/platform_device.h> >> #include <linux/power_supply.h> >> +#include <linux/string.h> >> #include <asm/amd/node.h> >> #include "pmf.h" >> >> @@ -53,6 +56,8 @@ static bool force_load; >> module_param(force_load, bool, 0444); >> MODULE_PARM_DESC(force_load, "Force load this driver on supported older platforms (experimental)"); >> >> +static struct device *pmf_device; >> + >> static int amd_pmf_pwr_src_notify_call(struct notifier_block *nb, unsigned long event, void *data) >> { >> struct amd_pmf_dev *pmf = container_of(nb, struct amd_pmf_dev, pwr_src_notifier); >> @@ -314,6 +319,70 @@ int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev) >> return 0; >> } >> >> +static int is_npu_metrics_supported(struct amd_pmf_dev *pdev) >> +{ >> + switch (pdev->cpu_id) { >> + case PCI_DEVICE_ID_AMD_1AH_M20H_ROOT: >> + case PCI_DEVICE_ID_AMD_1AH_M60H_ROOT: >> + return 0; >> + default: >> + return -EOPNOTSUPP; >> + } >> +} >> + >> +static int amd_pmf_get_smu_metrics(struct amd_pmf_dev *dev, struct amd_pmf_npu_metrics *data) >> +{ >> + int ret, i; >> + >> + guard(mutex)(&dev->metrics_mutex); >> + >> + if (is_npu_metrics_supported(dev)) >> + return -EOPNOTSUPP; >> + >> + ret = amd_pmf_set_dram_addr(dev, true); >> + if (ret) >> + return ret; >> + >> + memset(dev->buf, 0, dev->mtable_size); >> + >> + /* Send SMU command to get NPU metrics */ >> + ret = amd_pmf_send_cmd(dev, SET_TRANSFER_TABLE, SET_CMD, METRICS_TABLE_ID, NULL); >> + if (ret) { >> + dev_err(dev->dev, "SMU command failed to get NPU metrics: %d\n", ret); >> + return ret; >> + } >> + >> + memcpy(&dev->m_table_v2, dev->buf, dev->mtable_size); >> + >> + data->npuclk_freq = dev->m_table_v2.npuclk_freq; >> + for (i = 0; i < ARRAY_SIZE(data->npu_busy); i++) >> + data->npu_busy[i] = dev->m_table_v2.npu_busy[i]; >> + data->npu_power = dev->m_table_v2.npu_power; >> + data->mpnpuclk_freq = dev->m_table_v2.mpnpuclk_freq; >> + data->npu_reads = dev->m_table_v2.npu_reads; >> + data->npu_writes = dev->m_table_v2.npu_writes; >> + >> + return 0; >> +} >> + >> +int amd_pmf_get_npu_data(struct amd_pmf_npu_metrics *info) >> +{ >> + struct amd_pmf_dev *pdev; >> + >> + if (!info) >> + return -EINVAL; >> + >> + if (!pmf_device) >> + return -ENODEV; >> + >> + pdev = dev_get_drvdata(pmf_device); >> + if (!pdev) >> + return -ENODEV; >> + >> + return amd_pmf_get_smu_metrics(pdev, info); >> +} >> +EXPORT_SYMBOL_GPL(amd_pmf_get_npu_data); >> + >> static int amd_pmf_suspend_handler(struct device *dev) >> { >> struct amd_pmf_dev *pdev = dev_get_drvdata(dev); >> @@ -469,6 +538,10 @@ static int amd_pmf_probe(struct platform_device *pdev) >> mutex_init(&dev->update_mutex); >> mutex_init(&dev->cb_mutex); >> >> + err = devm_mutex_init(dev->dev, &dev->metrics_mutex); >> + if (err) >> + return err; >> + >> apmf_acpi_init(dev); >> platform_set_drvdata(pdev, dev); >> amd_pmf_dbgfs_register(dev); >> @@ -477,6 +550,8 @@ static int amd_pmf_probe(struct platform_device *pdev) >> if (is_apmf_func_supported(dev, APMF_FUNC_SBIOS_HEARTBEAT_V2)) >> amd_pmf_notify_sbios_heartbeat_event_v2(dev, ON_LOAD); >> >> + pmf_device = dev->dev; >> + >> dev_info(dev->dev, "registered PMF device successfully\n"); >> >> return 0; >> diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h >> index f07e9f4c660a..0354cc5dc79e 100644 >> --- a/drivers/platform/x86/amd/pmf/pmf.h >> +++ b/drivers/platform/x86/amd/pmf/pmf.h >> @@ -12,6 +12,7 @@ >> #define PMF_H >> >> #include <linux/acpi.h> >> +#include <linux/amd-pmf-io.h> >> #include <linux/input.h> >> #include <linux/platform_device.h> >> #include <linux/platform_profile.h> >> @@ -412,6 +413,7 @@ struct amd_pmf_dev { >> struct apmf_sbios_req_v1 req1; >> struct pmf_bios_inputs_prev cb_prev; /* To preserve custom BIOS inputs */ >> bool cb_flag; /* To handle first custom BIOS input */ >> + struct mutex metrics_mutex; > This files seems to lack include for struct mutex (despite using them > already so please add it finally there :-)). Sure, I will add it. Thanks, Lizhi > >> }; >> >> struct apmf_sps_prop_granular_v2 { >> diff --git a/include/linux/amd-pmf-io.h b/include/linux/amd-pmf-io.h >> index 6fa510f419c0..55198d2875cc 100644 >> --- a/include/linux/amd-pmf-io.h >> +++ b/include/linux/amd-pmf-io.h >> @@ -61,5 +61,26 @@ enum laptop_placement { >> LP_UNDEFINED, >> }; >> >> +/** >> + * struct amd_pmf_npu_metrics: Get NPU metrics data from PMF driver >> + * @npuclk_freq: NPU clock frequency [MHz] >> + * @npu_busy: NPU busy % [0-100] >> + * @npu_power: NPU power [mW] >> + * @mpnpuclk_freq: MPNPU [MHz] >> + * @npu_reads: NPU read bandwidth [MB/sec] >> + * @npu_writes: NPU write bandwidth [MB/sec] >> + */ >> +struct amd_pmf_npu_metrics { >> + u16 npuclk_freq; >> + u16 npu_busy[8]; >> + u16 npu_power; >> + u16 mpnpuclk_freq; >> + u16 npu_reads; >> + u16 npu_writes; >> +}; >> + >> int amd_get_sfh_info(struct amd_sfh_info *sfh_info, enum sfh_message_type op); >> + >> +/* AMD PMF and NPU interface */ >> +int amd_pmf_get_npu_data(struct amd_pmf_npu_metrics *info); >> #endif >> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V1 1/2] platform/x86/amd/pmf: Introduce new interface to export NPU metrics 2025-12-11 18:28 ` Ilpo Järvinen 2025-12-11 19:07 ` Lizhi Hou @ 2025-12-12 6:00 ` Shyam Sundar S K 1 sibling, 0 replies; 13+ messages in thread From: Shyam Sundar S K @ 2025-12-12 6:00 UTC (permalink / raw) To: Ilpo Järvinen, Lizhi Hou Cc: Hans de Goede, ogabbay, quic_jhugo, maciej.falkowski, LKML, max.zhen, sonal.santan, mario.limonciello, platform-driver-x86, dri-devel, VinitKumar.Shukla, Patil Rajesh Reddy On 12/11/2025 23:58, Ilpo Järvinen wrote: > On Thu, 11 Dec 2025, Lizhi Hou wrote: > >> From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> >> >> The PMF driver retrieves NPU metrics data from the PMFW. Introduce a new >> interface to make NPU metrics accessible to other drivers like AMDXDNA >> driver, which can access and utilize this information as needed. >> >> Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> >> Co-developed-by: Patil Rajesh Reddy <Patil.Reddy@amd.com> >> Signed-off-by: Patil Rajesh Reddy <Patil.Reddy@amd.com> >> Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> >> Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> >> --- >> drivers/platform/x86/amd/pmf/core.c | 75 +++++++++++++++++++++++++++++ >> drivers/platform/x86/amd/pmf/pmf.h | 2 + >> include/linux/amd-pmf-io.h | 21 ++++++++ >> 3 files changed, 98 insertions(+) >> >> diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c >> index a6a5d416edf9..8e4ce91b3527 100644 >> --- a/drivers/platform/x86/amd/pmf/core.c >> +++ b/drivers/platform/x86/amd/pmf/core.c >> @@ -8,12 +8,15 @@ >> * Author: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> >> */ >> >> +#include <linux/array_size.h> >> +#include <linux/cleanup.h> >> #include <linux/debugfs.h> >> #include <linux/iopoll.h> >> #include <linux/module.h> >> #include <linux/pci.h> >> #include <linux/platform_device.h> >> #include <linux/power_supply.h> >> +#include <linux/string.h> >> #include <asm/amd/node.h> >> #include "pmf.h" >> >> @@ -53,6 +56,8 @@ static bool force_load; >> module_param(force_load, bool, 0444); >> MODULE_PARM_DESC(force_load, "Force load this driver on supported older platforms (experimental)"); >> >> +static struct device *pmf_device; >> + >> static int amd_pmf_pwr_src_notify_call(struct notifier_block *nb, unsigned long event, void *data) >> { >> struct amd_pmf_dev *pmf = container_of(nb, struct amd_pmf_dev, pwr_src_notifier); >> @@ -314,6 +319,70 @@ int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev) >> return 0; >> } >> >> +static int is_npu_metrics_supported(struct amd_pmf_dev *pdev) >> +{ >> + switch (pdev->cpu_id) { >> + case PCI_DEVICE_ID_AMD_1AH_M20H_ROOT: >> + case PCI_DEVICE_ID_AMD_1AH_M60H_ROOT: >> + return 0; >> + default: >> + return -EOPNOTSUPP; >> + } >> +} >> + >> +static int amd_pmf_get_smu_metrics(struct amd_pmf_dev *dev, struct amd_pmf_npu_metrics *data) >> +{ >> + int ret, i; >> + >> + guard(mutex)(&dev->metrics_mutex); >> + >> + if (is_npu_metrics_supported(dev)) >> + return -EOPNOTSUPP; >> + >> + ret = amd_pmf_set_dram_addr(dev, true); >> + if (ret) >> + return ret; >> + >> + memset(dev->buf, 0, dev->mtable_size); >> + >> + /* Send SMU command to get NPU metrics */ >> + ret = amd_pmf_send_cmd(dev, SET_TRANSFER_TABLE, SET_CMD, METRICS_TABLE_ID, NULL); >> + if (ret) { >> + dev_err(dev->dev, "SMU command failed to get NPU metrics: %d\n", ret); >> + return ret; >> + } >> + >> + memcpy(&dev->m_table_v2, dev->buf, dev->mtable_size); >> + >> + data->npuclk_freq = dev->m_table_v2.npuclk_freq; >> + for (i = 0; i < ARRAY_SIZE(data->npu_busy); i++) >> + data->npu_busy[i] = dev->m_table_v2.npu_busy[i]; >> + data->npu_power = dev->m_table_v2.npu_power; >> + data->mpnpuclk_freq = dev->m_table_v2.mpnpuclk_freq; >> + data->npu_reads = dev->m_table_v2.npu_reads; >> + data->npu_writes = dev->m_table_v2.npu_writes; >> + >> + return 0; >> +} >> + >> +int amd_pmf_get_npu_data(struct amd_pmf_npu_metrics *info) >> +{ >> + struct amd_pmf_dev *pdev; >> + >> + if (!info) >> + return -EINVAL; >> + >> + if (!pmf_device) >> + return -ENODEV; >> + >> + pdev = dev_get_drvdata(pmf_device); >> + if (!pdev) >> + return -ENODEV; >> + >> + return amd_pmf_get_smu_metrics(pdev, info); >> +} >> +EXPORT_SYMBOL_GPL(amd_pmf_get_npu_data); >> + >> static int amd_pmf_suspend_handler(struct device *dev) >> { >> struct amd_pmf_dev *pdev = dev_get_drvdata(dev); >> @@ -469,6 +538,10 @@ static int amd_pmf_probe(struct platform_device *pdev) >> mutex_init(&dev->update_mutex); >> mutex_init(&dev->cb_mutex); >> >> + err = devm_mutex_init(dev->dev, &dev->metrics_mutex); >> + if (err) >> + return err; >> + >> apmf_acpi_init(dev); >> platform_set_drvdata(pdev, dev); >> amd_pmf_dbgfs_register(dev); >> @@ -477,6 +550,8 @@ static int amd_pmf_probe(struct platform_device *pdev) >> if (is_apmf_func_supported(dev, APMF_FUNC_SBIOS_HEARTBEAT_V2)) >> amd_pmf_notify_sbios_heartbeat_event_v2(dev, ON_LOAD); >> >> + pmf_device = dev->dev; >> + >> dev_info(dev->dev, "registered PMF device successfully\n"); >> >> return 0; >> diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h >> index f07e9f4c660a..0354cc5dc79e 100644 >> --- a/drivers/platform/x86/amd/pmf/pmf.h >> +++ b/drivers/platform/x86/amd/pmf/pmf.h >> @@ -12,6 +12,7 @@ >> #define PMF_H >> >> #include <linux/acpi.h> >> +#include <linux/amd-pmf-io.h> >> #include <linux/input.h> >> #include <linux/platform_device.h> >> #include <linux/platform_profile.h> >> @@ -412,6 +413,7 @@ struct amd_pmf_dev { >> struct apmf_sbios_req_v1 req1; >> struct pmf_bios_inputs_prev cb_prev; /* To preserve custom BIOS inputs */ >> bool cb_flag; /* To handle first custom BIOS input */ >> + struct mutex metrics_mutex; > > This files seems to lack include for struct mutex (despite using them > already so please add it finally there :-)). This is already taken care in one of the patch already in queue. https://patchwork.kernel.org/project/platform-driver-x86/patch/20251202042219.245173-1-Shyam-sundar.S-k@amd.com/ Thanks, Shyam ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V2 2/2] accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate 2025-12-11 17:58 [PATCH V1 0/2] Get real time power input via AMD PMF Lizhi Hou 2025-12-11 17:58 ` [PATCH V1 1/2] platform/x86/amd/pmf: Introduce new interface to export NPU metrics Lizhi Hou @ 2025-12-11 17:58 ` Lizhi Hou 2025-12-11 18:20 ` Mario Limonciello ` (2 more replies) 2025-12-11 18:22 ` [PATCH V1 0/2] Get real time power input via AMD PMF Mario Limonciello 2 siblings, 3 replies; 13+ messages in thread From: Lizhi Hou @ 2025-12-11 17:58 UTC (permalink / raw) To: ilpo.jarvinen, hansg, ogabbay, quic_jhugo, maciej.falkowski Cc: Lizhi Hou, linux-kernel, max.zhen, sonal.santan, mario.limonciello, platform-driver-x86, dri-devel, Shyam-sundar.S-k, VinitKumar.Shukla The AMD PMF driver provides an interface to obtain realtime power estimates for the NPU. Expose this information to userspace through a new DRM_IOCTL_AMDXDNA_GET_INFO parameter, allowing applications to query the current NPU power level. Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> --- drivers/accel/amdxdna/aie2_pci.c | 29 +++++++++++++++++++++++++ drivers/accel/amdxdna/aie2_pci.h | 18 +++++++++++++++ drivers/accel/amdxdna/amdxdna_pci_drv.c | 3 ++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_pci.c index 81a8e4137bfd..4a2c7addcd79 100644 --- a/drivers/accel/amdxdna/aie2_pci.c +++ b/drivers/accel/amdxdna/aie2_pci.c @@ -10,6 +10,7 @@ #include <drm/drm_managed.h> #include <drm/drm_print.h> #include <drm/gpu_scheduler.h> +#include <linux/amd-pmf-io.h> #include <linux/cleanup.h> #include <linux/errno.h> #include <linux/firmware.h> @@ -777,6 +778,31 @@ static int aie2_get_clock_metadata(struct amdxdna_client *client, return ret; } +static int aie2_get_sensors(struct amdxdna_client *client, + struct amdxdna_drm_get_info *args) +{ + struct amdxdna_drm_query_sensor sensor = { 0 }; + int ret; + + if (args->buffer_size < sizeof(sensor)) + return -EINVAL; + + ret = AIE2_GET_PMF_NPU_DATA(npu_power, sensor.input); + if (ret) + return ret; + sensor.type = AMDXDNA_SENSOR_TYPE_POWER; + sensor.unitm = -3; + snprintf(sensor.label, sizeof(sensor.label), "Total Power"); + snprintf(sensor.units, sizeof(sensor.units), "mW"); + + if (copy_to_user(u64_to_user_ptr(args->buffer), &sensor, sizeof(sensor))) + return -EFAULT; + + args->buffer_size = sizeof(sensor); + + return 0; +} + static int aie2_hwctx_status_cb(struct amdxdna_hwctx *hwctx, void *arg) { struct amdxdna_drm_hwctx_entry *tmp __free(kfree) = NULL; @@ -980,6 +1006,9 @@ static int aie2_get_info(struct amdxdna_client *client, struct amdxdna_drm_get_i case DRM_AMDXDNA_QUERY_CLOCK_METADATA: ret = aie2_get_clock_metadata(client, args); break; + case DRM_AMDXDNA_QUERY_SENSORS: + ret = aie2_get_sensors(client, args); + break; case DRM_AMDXDNA_QUERY_HW_CONTEXTS: ret = aie2_get_hwctx_status(client, args); break; diff --git a/drivers/accel/amdxdna/aie2_pci.h b/drivers/accel/amdxdna/aie2_pci.h index c6b5cf4ae5c4..edf6f2e00dea 100644 --- a/drivers/accel/amdxdna/aie2_pci.h +++ b/drivers/accel/amdxdna/aie2_pci.h @@ -46,6 +46,24 @@ pci_resource_len(NDEV2PDEV(_ndev), (_ndev)->xdna->dev_info->mbox_bar); \ }) +#if IS_ENABLED(CONFIG_AMD_PMF) +#define AIE2_GET_PMF_NPU_DATA(field, val) \ +({ \ + struct amd_pmf_npu_metrics _npu_metrics; \ + int _ret; \ + _ret = amd_pmf_get_npu_data(&_npu_metrics); \ + val = _ret ? U32_MAX : _npu_metrics.field; \ + (_ret); \ +}) +#else +#define SENSOR_DEFAULT_npu_power U32_MAX +#define AIE2_GET_PMF_NPU_DATA(field, val) \ +({ \ + val = SENSOR_DEFAULT_##field; \ + (-EOPNOTSUPP); \ +}) +#endif + enum aie2_smu_reg_idx { SMU_CMD_REG = 0, SMU_ARG_REG, diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c index 1973ab67721b..643ebd387074 100644 --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c @@ -32,9 +32,10 @@ MODULE_FIRMWARE("amdnpu/17f0_20/npu.sbin"); * 0.4: Support getting resource information * 0.5: Support getting telemetry data * 0.6: Support preemption + * 0.7: Support getting power data */ #define AMDXDNA_DRIVER_MAJOR 0 -#define AMDXDNA_DRIVER_MINOR 6 +#define AMDXDNA_DRIVER_MINOR 7 /* * Bind the driver base on (vendor_id, device_id) pair and later use the -- 2.34.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH V2 2/2] accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate 2025-12-11 17:58 ` [PATCH V2 2/2] accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate Lizhi Hou @ 2025-12-11 18:20 ` Mario Limonciello 2025-12-11 18:24 ` Ilpo Järvinen 2025-12-12 6:01 ` Shyam Sundar S K 2 siblings, 0 replies; 13+ messages in thread From: Mario Limonciello @ 2025-12-11 18:20 UTC (permalink / raw) To: Lizhi Hou, ilpo.jarvinen, hansg, ogabbay, quic_jhugo, maciej.falkowski Cc: linux-kernel, max.zhen, sonal.santan, platform-driver-x86, dri-devel, Shyam-sundar.S-k, VinitKumar.Shukla On 12/11/25 11:58 AM, Lizhi Hou wrote: > The AMD PMF driver provides an interface to obtain realtime power > estimates for the NPU. Expose this information to userspace through a > new DRM_IOCTL_AMDXDNA_GET_INFO parameter, allowing applications to query > the current NPU power level. > > Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>> --- > drivers/accel/amdxdna/aie2_pci.c | 29 +++++++++++++++++++++++++ > drivers/accel/amdxdna/aie2_pci.h | 18 +++++++++++++++ > drivers/accel/amdxdna/amdxdna_pci_drv.c | 3 ++- > 3 files changed, 49 insertions(+), 1 deletion(-) > > diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_pci.c > index 81a8e4137bfd..4a2c7addcd79 100644 > --- a/drivers/accel/amdxdna/aie2_pci.c > +++ b/drivers/accel/amdxdna/aie2_pci.c > @@ -10,6 +10,7 @@ > #include <drm/drm_managed.h> > #include <drm/drm_print.h> > #include <drm/gpu_scheduler.h> > +#include <linux/amd-pmf-io.h> > #include <linux/cleanup.h> > #include <linux/errno.h> > #include <linux/firmware.h> > @@ -777,6 +778,31 @@ static int aie2_get_clock_metadata(struct amdxdna_client *client, > return ret; > } > > +static int aie2_get_sensors(struct amdxdna_client *client, > + struct amdxdna_drm_get_info *args) > +{ > + struct amdxdna_drm_query_sensor sensor = { 0 }; > + int ret; > + > + if (args->buffer_size < sizeof(sensor)) > + return -EINVAL; > + > + ret = AIE2_GET_PMF_NPU_DATA(npu_power, sensor.input); > + if (ret) > + return ret; > + sensor.type = AMDXDNA_SENSOR_TYPE_POWER; > + sensor.unitm = -3; > + snprintf(sensor.label, sizeof(sensor.label), "Total Power"); > + snprintf(sensor.units, sizeof(sensor.units), "mW"); > + > + if (copy_to_user(u64_to_user_ptr(args->buffer), &sensor, sizeof(sensor))) > + return -EFAULT; > + > + args->buffer_size = sizeof(sensor); > + > + return 0; > +} > + > static int aie2_hwctx_status_cb(struct amdxdna_hwctx *hwctx, void *arg) > { > struct amdxdna_drm_hwctx_entry *tmp __free(kfree) = NULL; > @@ -980,6 +1006,9 @@ static int aie2_get_info(struct amdxdna_client *client, struct amdxdna_drm_get_i > case DRM_AMDXDNA_QUERY_CLOCK_METADATA: > ret = aie2_get_clock_metadata(client, args); > break; > + case DRM_AMDXDNA_QUERY_SENSORS: > + ret = aie2_get_sensors(client, args); > + break; > case DRM_AMDXDNA_QUERY_HW_CONTEXTS: > ret = aie2_get_hwctx_status(client, args); > break; > diff --git a/drivers/accel/amdxdna/aie2_pci.h b/drivers/accel/amdxdna/aie2_pci.h > index c6b5cf4ae5c4..edf6f2e00dea 100644 > --- a/drivers/accel/amdxdna/aie2_pci.h > +++ b/drivers/accel/amdxdna/aie2_pci.h > @@ -46,6 +46,24 @@ > pci_resource_len(NDEV2PDEV(_ndev), (_ndev)->xdna->dev_info->mbox_bar); \ > }) > > +#if IS_ENABLED(CONFIG_AMD_PMF) > +#define AIE2_GET_PMF_NPU_DATA(field, val) \ > +({ \ > + struct amd_pmf_npu_metrics _npu_metrics; \ > + int _ret; \ > + _ret = amd_pmf_get_npu_data(&_npu_metrics); \ > + val = _ret ? U32_MAX : _npu_metrics.field; \ > + (_ret); \ > +}) > +#else > +#define SENSOR_DEFAULT_npu_power U32_MAX > +#define AIE2_GET_PMF_NPU_DATA(field, val) \ > +({ \ > + val = SENSOR_DEFAULT_##field; \ > + (-EOPNOTSUPP); \ > +}) > +#endif > + > enum aie2_smu_reg_idx { > SMU_CMD_REG = 0, > SMU_ARG_REG, > diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c > index 1973ab67721b..643ebd387074 100644 > --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c > +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c > @@ -32,9 +32,10 @@ MODULE_FIRMWARE("amdnpu/17f0_20/npu.sbin"); > * 0.4: Support getting resource information > * 0.5: Support getting telemetry data > * 0.6: Support preemption > + * 0.7: Support getting power data > */ > #define AMDXDNA_DRIVER_MAJOR 0 > -#define AMDXDNA_DRIVER_MINOR 6 > +#define AMDXDNA_DRIVER_MINOR 7 > > /* > * Bind the driver base on (vendor_id, device_id) pair and later use the ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V2 2/2] accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate 2025-12-11 17:58 ` [PATCH V2 2/2] accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate Lizhi Hou 2025-12-11 18:20 ` Mario Limonciello @ 2025-12-11 18:24 ` Ilpo Järvinen 2025-12-11 19:06 ` Lizhi Hou 2025-12-12 6:01 ` Shyam Sundar S K 2 siblings, 1 reply; 13+ messages in thread From: Ilpo Järvinen @ 2025-12-11 18:24 UTC (permalink / raw) To: Lizhi Hou Cc: Hans de Goede, ogabbay, quic_jhugo, maciej.falkowski, LKML, max.zhen, sonal.santan, mario.limonciello, platform-driver-x86, dri-devel, Shyam-sundar.S-k, VinitKumar.Shukla On Thu, 11 Dec 2025, Lizhi Hou wrote: > The AMD PMF driver provides an interface to obtain realtime power > estimates for the NPU. Expose this information to userspace through a > new DRM_IOCTL_AMDXDNA_GET_INFO parameter, allowing applications to query > the current NPU power level. > > Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> > --- > drivers/accel/amdxdna/aie2_pci.c | 29 +++++++++++++++++++++++++ > drivers/accel/amdxdna/aie2_pci.h | 18 +++++++++++++++ > drivers/accel/amdxdna/amdxdna_pci_drv.c | 3 ++- > 3 files changed, 49 insertions(+), 1 deletion(-) > > diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_pci.c > index 81a8e4137bfd..4a2c7addcd79 100644 > --- a/drivers/accel/amdxdna/aie2_pci.c > +++ b/drivers/accel/amdxdna/aie2_pci.c > @@ -10,6 +10,7 @@ > #include <drm/drm_managed.h> > #include <drm/drm_print.h> > #include <drm/gpu_scheduler.h> > +#include <linux/amd-pmf-io.h> > #include <linux/cleanup.h> > #include <linux/errno.h> > #include <linux/firmware.h> > @@ -777,6 +778,31 @@ static int aie2_get_clock_metadata(struct amdxdna_client *client, > return ret; > } > > +static int aie2_get_sensors(struct amdxdna_client *client, > + struct amdxdna_drm_get_info *args) > +{ > + struct amdxdna_drm_query_sensor sensor = { 0 }; = {} is enough to initialize to defaults. > + int ret; > + > + if (args->buffer_size < sizeof(sensor)) > + return -EINVAL; > + > + ret = AIE2_GET_PMF_NPU_DATA(npu_power, sensor.input); > + if (ret) > + return ret; > + sensor.type = AMDXDNA_SENSOR_TYPE_POWER; > + sensor.unitm = -3; > + snprintf(sensor.label, sizeof(sensor.label), "Total Power"); > + snprintf(sensor.units, sizeof(sensor.units), "mW"); scnprintf() x2 > + > + if (copy_to_user(u64_to_user_ptr(args->buffer), &sensor, sizeof(sensor))) > + return -EFAULT; > + > + args->buffer_size = sizeof(sensor); > + > + return 0; > +} > + > static int aie2_hwctx_status_cb(struct amdxdna_hwctx *hwctx, void *arg) > { > struct amdxdna_drm_hwctx_entry *tmp __free(kfree) = NULL; > @@ -980,6 +1006,9 @@ static int aie2_get_info(struct amdxdna_client *client, struct amdxdna_drm_get_i > case DRM_AMDXDNA_QUERY_CLOCK_METADATA: > ret = aie2_get_clock_metadata(client, args); > break; > + case DRM_AMDXDNA_QUERY_SENSORS: > + ret = aie2_get_sensors(client, args); > + break; > case DRM_AMDXDNA_QUERY_HW_CONTEXTS: > ret = aie2_get_hwctx_status(client, args); > break; > diff --git a/drivers/accel/amdxdna/aie2_pci.h b/drivers/accel/amdxdna/aie2_pci.h > index c6b5cf4ae5c4..edf6f2e00dea 100644 > --- a/drivers/accel/amdxdna/aie2_pci.h > +++ b/drivers/accel/amdxdna/aie2_pci.h > @@ -46,6 +46,24 @@ > pci_resource_len(NDEV2PDEV(_ndev), (_ndev)->xdna->dev_info->mbox_bar); \ > }) > > +#if IS_ENABLED(CONFIG_AMD_PMF) > +#define AIE2_GET_PMF_NPU_DATA(field, val) \ > +({ \ > + struct amd_pmf_npu_metrics _npu_metrics; \ > + int _ret; \ > + _ret = amd_pmf_get_npu_data(&_npu_metrics); \ > + val = _ret ? U32_MAX : _npu_metrics.field; \ #include needed for U32_MAX. Unrelated to this patch, this files is also missing include for at least SZ_* (so likely works by chance) and types.h. > + (_ret); \ > +}) Please try to align the backslashed to right so that they don't mix up with the code. Add an empty lines after variables declaration (with the backslash in the end obviously) so these almost looks like "normal" coding style. > +#else > +#define SENSOR_DEFAULT_npu_power U32_MAX > +#define AIE2_GET_PMF_NPU_DATA(field, val) \ > +({ \ > + val = SENSOR_DEFAULT_##field; \ > + (-EOPNOTSUPP); \ > +}) > +#endif > + > enum aie2_smu_reg_idx { > SMU_CMD_REG = 0, > SMU_ARG_REG, > diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c > index 1973ab67721b..643ebd387074 100644 > --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c > +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c > @@ -32,9 +32,10 @@ MODULE_FIRMWARE("amdnpu/17f0_20/npu.sbin"); > * 0.4: Support getting resource information > * 0.5: Support getting telemetry data > * 0.6: Support preemption > + * 0.7: Support getting power data > */ > #define AMDXDNA_DRIVER_MAJOR 0 > -#define AMDXDNA_DRIVER_MINOR 6 > +#define AMDXDNA_DRIVER_MINOR 7 > > /* > * Bind the driver base on (vendor_id, device_id) pair and later use the > -- i. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V2 2/2] accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate 2025-12-11 18:24 ` Ilpo Järvinen @ 2025-12-11 19:06 ` Lizhi Hou 0 siblings, 0 replies; 13+ messages in thread From: Lizhi Hou @ 2025-12-11 19:06 UTC (permalink / raw) To: Ilpo Järvinen Cc: Hans de Goede, ogabbay, quic_jhugo, maciej.falkowski, LKML, max.zhen, sonal.santan, mario.limonciello, platform-driver-x86, dri-devel, Shyam-sundar.S-k, VinitKumar.Shukla On 12/11/25 10:24, Ilpo Järvinen wrote: > On Thu, 11 Dec 2025, Lizhi Hou wrote: > >> The AMD PMF driver provides an interface to obtain realtime power >> estimates for the NPU. Expose this information to userspace through a >> new DRM_IOCTL_AMDXDNA_GET_INFO parameter, allowing applications to query >> the current NPU power level. >> >> Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> >> --- >> drivers/accel/amdxdna/aie2_pci.c | 29 +++++++++++++++++++++++++ >> drivers/accel/amdxdna/aie2_pci.h | 18 +++++++++++++++ >> drivers/accel/amdxdna/amdxdna_pci_drv.c | 3 ++- >> 3 files changed, 49 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_pci.c >> index 81a8e4137bfd..4a2c7addcd79 100644 >> --- a/drivers/accel/amdxdna/aie2_pci.c >> +++ b/drivers/accel/amdxdna/aie2_pci.c >> @@ -10,6 +10,7 @@ >> #include <drm/drm_managed.h> >> #include <drm/drm_print.h> >> #include <drm/gpu_scheduler.h> >> +#include <linux/amd-pmf-io.h> >> #include <linux/cleanup.h> >> #include <linux/errno.h> >> #include <linux/firmware.h> >> @@ -777,6 +778,31 @@ static int aie2_get_clock_metadata(struct amdxdna_client *client, >> return ret; >> } >> >> +static int aie2_get_sensors(struct amdxdna_client *client, >> + struct amdxdna_drm_get_info *args) >> +{ >> + struct amdxdna_drm_query_sensor sensor = { 0 }; > = {} is enough to initialize to defaults. Will fix. > >> + int ret; >> + >> + if (args->buffer_size < sizeof(sensor)) >> + return -EINVAL; >> + >> + ret = AIE2_GET_PMF_NPU_DATA(npu_power, sensor.input); >> + if (ret) >> + return ret; >> + sensor.type = AMDXDNA_SENSOR_TYPE_POWER; >> + sensor.unitm = -3; >> + snprintf(sensor.label, sizeof(sensor.label), "Total Power"); >> + snprintf(sensor.units, sizeof(sensor.units), "mW"); > scnprintf() x2 Will fix. >> + >> + if (copy_to_user(u64_to_user_ptr(args->buffer), &sensor, sizeof(sensor))) >> + return -EFAULT; >> + >> + args->buffer_size = sizeof(sensor); >> + >> + return 0; >> +} >> + >> static int aie2_hwctx_status_cb(struct amdxdna_hwctx *hwctx, void *arg) >> { >> struct amdxdna_drm_hwctx_entry *tmp __free(kfree) = NULL; >> @@ -980,6 +1006,9 @@ static int aie2_get_info(struct amdxdna_client *client, struct amdxdna_drm_get_i >> case DRM_AMDXDNA_QUERY_CLOCK_METADATA: >> ret = aie2_get_clock_metadata(client, args); >> break; >> + case DRM_AMDXDNA_QUERY_SENSORS: >> + ret = aie2_get_sensors(client, args); >> + break; >> case DRM_AMDXDNA_QUERY_HW_CONTEXTS: >> ret = aie2_get_hwctx_status(client, args); >> break; >> diff --git a/drivers/accel/amdxdna/aie2_pci.h b/drivers/accel/amdxdna/aie2_pci.h >> index c6b5cf4ae5c4..edf6f2e00dea 100644 >> --- a/drivers/accel/amdxdna/aie2_pci.h >> +++ b/drivers/accel/amdxdna/aie2_pci.h >> @@ -46,6 +46,24 @@ >> pci_resource_len(NDEV2PDEV(_ndev), (_ndev)->xdna->dev_info->mbox_bar); \ >> }) >> >> +#if IS_ENABLED(CONFIG_AMD_PMF) >> +#define AIE2_GET_PMF_NPU_DATA(field, val) \ >> +({ \ >> + struct amd_pmf_npu_metrics _npu_metrics; \ >> + int _ret; \ >> + _ret = amd_pmf_get_npu_data(&_npu_metrics); \ >> + val = _ret ? U32_MAX : _npu_metrics.field; \ > #include needed for U32_MAX. Will fix. > > Unrelated to this patch, this files is also missing include for at least > SZ_* (so likely works by chance) and types.h. Thanks for pointing this out. I will fix it in future patch. > >> + (_ret); \ >> +}) > Please try to align the backslashed to right so that they don't mix up > with the code. > > Add an empty lines after variables declaration (with the backslash in > the end obviously) so these almost looks like "normal" coding style. Will fix. Thanks, Lizhi > >> +#else >> +#define SENSOR_DEFAULT_npu_power U32_MAX >> +#define AIE2_GET_PMF_NPU_DATA(field, val) \ >> +({ \ >> + val = SENSOR_DEFAULT_##field; \ >> + (-EOPNOTSUPP); \ >> +}) >> +#endif >> + >> enum aie2_smu_reg_idx { >> SMU_CMD_REG = 0, >> SMU_ARG_REG, >> diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c >> index 1973ab67721b..643ebd387074 100644 >> --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c >> +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c >> @@ -32,9 +32,10 @@ MODULE_FIRMWARE("amdnpu/17f0_20/npu.sbin"); >> * 0.4: Support getting resource information >> * 0.5: Support getting telemetry data >> * 0.6: Support preemption >> + * 0.7: Support getting power data >> */ >> #define AMDXDNA_DRIVER_MAJOR 0 >> -#define AMDXDNA_DRIVER_MINOR 6 >> +#define AMDXDNA_DRIVER_MINOR 7 >> >> /* >> * Bind the driver base on (vendor_id, device_id) pair and later use the >> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V2 2/2] accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate 2025-12-11 17:58 ` [PATCH V2 2/2] accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate Lizhi Hou 2025-12-11 18:20 ` Mario Limonciello 2025-12-11 18:24 ` Ilpo Järvinen @ 2025-12-12 6:01 ` Shyam Sundar S K 2 siblings, 0 replies; 13+ messages in thread From: Shyam Sundar S K @ 2025-12-12 6:01 UTC (permalink / raw) To: Lizhi Hou, ilpo.jarvinen, hansg, ogabbay, quic_jhugo, maciej.falkowski Cc: linux-kernel, max.zhen, sonal.santan, mario.limonciello, platform-driver-x86, dri-devel, VinitKumar.Shukla On 12/11/2025 23:28, Lizhi Hou wrote: > The AMD PMF driver provides an interface to obtain realtime power > estimates for the NPU. Expose this information to userspace through a > new DRM_IOCTL_AMDXDNA_GET_INFO parameter, allowing applications to query > the current NPU power level. > > Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> Reviewed-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> Thanks, Shyam > --- > drivers/accel/amdxdna/aie2_pci.c | 29 +++++++++++++++++++++++++ > drivers/accel/amdxdna/aie2_pci.h | 18 +++++++++++++++ > drivers/accel/amdxdna/amdxdna_pci_drv.c | 3 ++- > 3 files changed, 49 insertions(+), 1 deletion(-) > > diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_pci.c > index 81a8e4137bfd..4a2c7addcd79 100644 > --- a/drivers/accel/amdxdna/aie2_pci.c > +++ b/drivers/accel/amdxdna/aie2_pci.c > @@ -10,6 +10,7 @@ > #include <drm/drm_managed.h> > #include <drm/drm_print.h> > #include <drm/gpu_scheduler.h> > +#include <linux/amd-pmf-io.h> > #include <linux/cleanup.h> > #include <linux/errno.h> > #include <linux/firmware.h> > @@ -777,6 +778,31 @@ static int aie2_get_clock_metadata(struct amdxdna_client *client, > return ret; > } > > +static int aie2_get_sensors(struct amdxdna_client *client, > + struct amdxdna_drm_get_info *args) > +{ > + struct amdxdna_drm_query_sensor sensor = { 0 }; > + int ret; > + > + if (args->buffer_size < sizeof(sensor)) > + return -EINVAL; > + > + ret = AIE2_GET_PMF_NPU_DATA(npu_power, sensor.input); > + if (ret) > + return ret; > + sensor.type = AMDXDNA_SENSOR_TYPE_POWER; > + sensor.unitm = -3; > + snprintf(sensor.label, sizeof(sensor.label), "Total Power"); > + snprintf(sensor.units, sizeof(sensor.units), "mW"); > + > + if (copy_to_user(u64_to_user_ptr(args->buffer), &sensor, sizeof(sensor))) > + return -EFAULT; > + > + args->buffer_size = sizeof(sensor); > + > + return 0; > +} > + > static int aie2_hwctx_status_cb(struct amdxdna_hwctx *hwctx, void *arg) > { > struct amdxdna_drm_hwctx_entry *tmp __free(kfree) = NULL; > @@ -980,6 +1006,9 @@ static int aie2_get_info(struct amdxdna_client *client, struct amdxdna_drm_get_i > case DRM_AMDXDNA_QUERY_CLOCK_METADATA: > ret = aie2_get_clock_metadata(client, args); > break; > + case DRM_AMDXDNA_QUERY_SENSORS: > + ret = aie2_get_sensors(client, args); > + break; > case DRM_AMDXDNA_QUERY_HW_CONTEXTS: > ret = aie2_get_hwctx_status(client, args); > break; > diff --git a/drivers/accel/amdxdna/aie2_pci.h b/drivers/accel/amdxdna/aie2_pci.h > index c6b5cf4ae5c4..edf6f2e00dea 100644 > --- a/drivers/accel/amdxdna/aie2_pci.h > +++ b/drivers/accel/amdxdna/aie2_pci.h > @@ -46,6 +46,24 @@ > pci_resource_len(NDEV2PDEV(_ndev), (_ndev)->xdna->dev_info->mbox_bar); \ > }) > > +#if IS_ENABLED(CONFIG_AMD_PMF) > +#define AIE2_GET_PMF_NPU_DATA(field, val) \ > +({ \ > + struct amd_pmf_npu_metrics _npu_metrics; \ > + int _ret; \ > + _ret = amd_pmf_get_npu_data(&_npu_metrics); \ > + val = _ret ? U32_MAX : _npu_metrics.field; \ > + (_ret); \ > +}) > +#else > +#define SENSOR_DEFAULT_npu_power U32_MAX > +#define AIE2_GET_PMF_NPU_DATA(field, val) \ > +({ \ > + val = SENSOR_DEFAULT_##field; \ > + (-EOPNOTSUPP); \ > +}) > +#endif > + > enum aie2_smu_reg_idx { > SMU_CMD_REG = 0, > SMU_ARG_REG, > diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c > index 1973ab67721b..643ebd387074 100644 > --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c > +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c > @@ -32,9 +32,10 @@ MODULE_FIRMWARE("amdnpu/17f0_20/npu.sbin"); > * 0.4: Support getting resource information > * 0.5: Support getting telemetry data > * 0.6: Support preemption > + * 0.7: Support getting power data > */ > #define AMDXDNA_DRIVER_MAJOR 0 > -#define AMDXDNA_DRIVER_MINOR 6 > +#define AMDXDNA_DRIVER_MINOR 7 > > /* > * Bind the driver base on (vendor_id, device_id) pair and later use the ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V1 0/2] Get real time power input via AMD PMF 2025-12-11 17:58 [PATCH V1 0/2] Get real time power input via AMD PMF Lizhi Hou 2025-12-11 17:58 ` [PATCH V1 1/2] platform/x86/amd/pmf: Introduce new interface to export NPU metrics Lizhi Hou 2025-12-11 17:58 ` [PATCH V2 2/2] accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate Lizhi Hou @ 2025-12-11 18:22 ` Mario Limonciello 2025-12-11 19:16 ` Lizhi Hou 2 siblings, 1 reply; 13+ messages in thread From: Mario Limonciello @ 2025-12-11 18:22 UTC (permalink / raw) To: Lizhi Hou, ilpo.jarvinen, hansg, ogabbay, quic_jhugo, maciej.falkowski Cc: linux-kernel, max.zhen, sonal.santan, platform-driver-x86, dri-devel, Shyam-sundar.S-k, VinitKumar.Shukla On 12/11/25 11:58 AM, Lizhi Hou wrote: > Adding new NPU metrics API to AMD PMF driver is pending because of > lacking real case. > https://lore.kernel.org/all/d344b850-f68d-f9a5-f0dc-55af4b48b714@linux.intel.com/ > > Create xdna driver patch to fetch real time power input via PMF API. > Here is an example output with xrt-smi(1) tool. > > # xrt-smi examine -r all | grep Power > Power Mode : Default > Estimated Power : 0.563 Watts > > Lizhi Hou (1): > accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate > > Shyam Sundar S K (1): > platform/x86/amd/pmf: Introduce new interface to export NPU metrics > > drivers/accel/amdxdna/aie2_pci.c | 29 ++++++++++ > drivers/accel/amdxdna/aie2_pci.h | 18 ++++++ > drivers/accel/amdxdna/amdxdna_pci_drv.c | 3 +- > drivers/platform/x86/amd/pmf/core.c | 75 +++++++++++++++++++++++++ > drivers/platform/x86/amd/pmf/pmf.h | 2 + > include/linux/amd-pmf-io.h | 21 +++++++ > 6 files changed, 147 insertions(+), 1 deletion(-) > Do you have a preference on how this gets merged ? Should it go through drm-next or platform-x86-next? I suppose whoever is going to have more development layering on top the next cycle it would be preferable to put in that tree. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V1 0/2] Get real time power input via AMD PMF 2025-12-11 18:22 ` [PATCH V1 0/2] Get real time power input via AMD PMF Mario Limonciello @ 2025-12-11 19:16 ` Lizhi Hou 0 siblings, 0 replies; 13+ messages in thread From: Lizhi Hou @ 2025-12-11 19:16 UTC (permalink / raw) To: Mario Limonciello, ilpo.jarvinen, hansg, ogabbay, quic_jhugo, maciej.falkowski Cc: linux-kernel, max.zhen, sonal.santan, platform-driver-x86, dri-devel, Shyam-sundar.S-k, VinitKumar.Shukla On 12/11/25 10:22, Mario Limonciello wrote: > On 12/11/25 11:58 AM, Lizhi Hou wrote: >> Adding new NPU metrics API to AMD PMF driver is pending because of >> lacking real case. >> https://lore.kernel.org/all/d344b850-f68d-f9a5-f0dc-55af4b48b714@linux.intel.com/ >> >> Create xdna driver patch to fetch real time power input via PMF API. >> Here is an example output with xrt-smi(1) tool. >> >> # xrt-smi examine -r all | grep Power >> Power Mode : Default >> Estimated Power : 0.563 Watts >> >> Lizhi Hou (1): >> accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate >> >> Shyam Sundar S K (1): >> platform/x86/amd/pmf: Introduce new interface to export NPU metrics >> >> drivers/accel/amdxdna/aie2_pci.c | 29 ++++++++++ >> drivers/accel/amdxdna/aie2_pci.h | 18 ++++++ >> drivers/accel/amdxdna/amdxdna_pci_drv.c | 3 +- >> drivers/platform/x86/amd/pmf/core.c | 75 +++++++++++++++++++++++++ >> drivers/platform/x86/amd/pmf/pmf.h | 2 + >> include/linux/amd-pmf-io.h | 21 +++++++ >> 6 files changed, 147 insertions(+), 1 deletion(-) >> > > Do you have a preference on how this gets merged ? Should it go > through drm-next or platform-x86-next? > > I suppose whoever is going to have more development layering on top > the next cycle it would be preferable to put in that tree. I do not have preference. :) And this depends on Shyam's previous patch which is not in drm-next yet? Thanks, Lizhi ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V2 0/2] Get real time power input via AMD PMF
@ 2025-12-12 18:18 Lizhi Hou
2025-12-12 18:18 ` [PATCH V2 2/2] accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate Lizhi Hou
0 siblings, 1 reply; 13+ messages in thread
From: Lizhi Hou @ 2025-12-12 18:18 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, ogabbay, quic_jhugo, maciej.falkowski
Cc: Lizhi Hou, linux-kernel, max.zhen, sonal.santan,
mario.limonciello, dri-devel, platform-driver-x86,
Shyam-sundar.S-k, VinitKumar.Shukla
Adding new NPU metrics API to AMD PMF driver is pending because of
lacking real case.
https://lore.kernel.org/all/d344b850-f68d-f9a5-f0dc-55af4b48b714@linux.intel.com/
Create xdna driver patch to fetch real time power input via PMF API.
Here is an example output with xrt-smi(1) tool.
# xrt-smi examine -r all | grep Power
Power Mode : Default
Estimated Power : 0.563 Watts
V2:
Including header file for struct mutex will be added by
https://patchwork.kernel.org/project/platform-driver-x86/patch/20251202042219.245173-1-Shyam-sundar.S-k@amd.com/
Add include for U32_MAX
Replace snprintf by scnprintf
Fix coding style
Lizhi Hou (1):
accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate
Shyam Sundar S K (1):
platform/x86/amd/pmf: Introduce new interface to export NPU metrics
drivers/accel/amdxdna/aie2_pci.c | 29 ++++++++++
drivers/accel/amdxdna/aie2_pci.h | 20 +++++++
drivers/accel/amdxdna/amdxdna_pci_drv.c | 3 +-
drivers/platform/x86/amd/pmf/core.c | 75 +++++++++++++++++++++++++
drivers/platform/x86/amd/pmf/pmf.h | 2 +
include/linux/amd-pmf-io.h | 21 +++++++
6 files changed, 149 insertions(+), 1 deletion(-)
--
2.34.1
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH V2 2/2] accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate 2025-12-12 18:18 [PATCH V2 " Lizhi Hou @ 2025-12-12 18:18 ` Lizhi Hou 0 siblings, 0 replies; 13+ messages in thread From: Lizhi Hou @ 2025-12-12 18:18 UTC (permalink / raw) To: ilpo.jarvinen, hansg, ogabbay, quic_jhugo, maciej.falkowski Cc: Lizhi Hou, linux-kernel, max.zhen, sonal.santan, mario.limonciello, dri-devel, platform-driver-x86, Shyam-sundar.S-k, VinitKumar.Shukla, Mario Limonciello The AMD PMF driver provides an interface to obtain realtime power estimates for the NPU. Expose this information to userspace through a new DRM_IOCTL_AMDXDNA_GET_INFO parameter, allowing applications to query the current NPU power level. Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org> Reviewed-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> --- drivers/accel/amdxdna/aie2_pci.c | 29 +++++++++++++++++++++++++ drivers/accel/amdxdna/aie2_pci.h | 20 +++++++++++++++++ drivers/accel/amdxdna/amdxdna_pci_drv.c | 3 ++- 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_pci.c index 81a8e4137bfd..55fbc8f0f455 100644 --- a/drivers/accel/amdxdna/aie2_pci.c +++ b/drivers/accel/amdxdna/aie2_pci.c @@ -10,6 +10,7 @@ #include <drm/drm_managed.h> #include <drm/drm_print.h> #include <drm/gpu_scheduler.h> +#include <linux/amd-pmf-io.h> #include <linux/cleanup.h> #include <linux/errno.h> #include <linux/firmware.h> @@ -777,6 +778,31 @@ static int aie2_get_clock_metadata(struct amdxdna_client *client, return ret; } +static int aie2_get_sensors(struct amdxdna_client *client, + struct amdxdna_drm_get_info *args) +{ + struct amdxdna_drm_query_sensor sensor = {}; + int ret; + + if (args->buffer_size < sizeof(sensor)) + return -EINVAL; + + ret = AIE2_GET_PMF_NPU_DATA(npu_power, sensor.input); + if (ret) + return ret; + sensor.type = AMDXDNA_SENSOR_TYPE_POWER; + sensor.unitm = -3; + scnprintf(sensor.label, sizeof(sensor.label), "Total Power"); + scnprintf(sensor.units, sizeof(sensor.units), "mW"); + + if (copy_to_user(u64_to_user_ptr(args->buffer), &sensor, sizeof(sensor))) + return -EFAULT; + + args->buffer_size = sizeof(sensor); + + return 0; +} + static int aie2_hwctx_status_cb(struct amdxdna_hwctx *hwctx, void *arg) { struct amdxdna_drm_hwctx_entry *tmp __free(kfree) = NULL; @@ -980,6 +1006,9 @@ static int aie2_get_info(struct amdxdna_client *client, struct amdxdna_drm_get_i case DRM_AMDXDNA_QUERY_CLOCK_METADATA: ret = aie2_get_clock_metadata(client, args); break; + case DRM_AMDXDNA_QUERY_SENSORS: + ret = aie2_get_sensors(client, args); + break; case DRM_AMDXDNA_QUERY_HW_CONTEXTS: ret = aie2_get_hwctx_status(client, args); break; diff --git a/drivers/accel/amdxdna/aie2_pci.h b/drivers/accel/amdxdna/aie2_pci.h index c6b5cf4ae5c4..7f588ad99240 100644 --- a/drivers/accel/amdxdna/aie2_pci.h +++ b/drivers/accel/amdxdna/aie2_pci.h @@ -7,6 +7,7 @@ #define _AIE2_PCI_H_ #include <drm/amdxdna_accel.h> +#include <linux/limits.h> #include <linux/semaphore.h> #include "amdxdna_mailbox.h" @@ -46,6 +47,25 @@ pci_resource_len(NDEV2PDEV(_ndev), (_ndev)->xdna->dev_info->mbox_bar); \ }) +#if IS_ENABLED(CONFIG_AMD_PMF) +#define AIE2_GET_PMF_NPU_DATA(field, val) \ +({ \ + struct amd_pmf_npu_metrics _npu_metrics; \ + int _ret; \ + \ + _ret = amd_pmf_get_npu_data(&_npu_metrics); \ + val = _ret ? U32_MAX : _npu_metrics.field; \ + (_ret); \ +}) +#else +#define SENSOR_DEFAULT_npu_power U32_MAX +#define AIE2_GET_PMF_NPU_DATA(field, val) \ +({ \ + val = SENSOR_DEFAULT_##field; \ + (-EOPNOTSUPP); \ +}) +#endif + enum aie2_smu_reg_idx { SMU_CMD_REG = 0, SMU_ARG_REG, diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c index 1973ab67721b..643ebd387074 100644 --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c @@ -32,9 +32,10 @@ MODULE_FIRMWARE("amdnpu/17f0_20/npu.sbin"); * 0.4: Support getting resource information * 0.5: Support getting telemetry data * 0.6: Support preemption + * 0.7: Support getting power data */ #define AMDXDNA_DRIVER_MAJOR 0 -#define AMDXDNA_DRIVER_MINOR 6 +#define AMDXDNA_DRIVER_MINOR 7 /* * Bind the driver base on (vendor_id, device_id) pair and later use the -- 2.34.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-12-12 18:19 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-12-11 17:58 [PATCH V1 0/2] Get real time power input via AMD PMF Lizhi Hou 2025-12-11 17:58 ` [PATCH V1 1/2] platform/x86/amd/pmf: Introduce new interface to export NPU metrics Lizhi Hou 2025-12-11 18:28 ` Ilpo Järvinen 2025-12-11 19:07 ` Lizhi Hou 2025-12-12 6:00 ` Shyam Sundar S K 2025-12-11 17:58 ` [PATCH V2 2/2] accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate Lizhi Hou 2025-12-11 18:20 ` Mario Limonciello 2025-12-11 18:24 ` Ilpo Järvinen 2025-12-11 19:06 ` Lizhi Hou 2025-12-12 6:01 ` Shyam Sundar S K 2025-12-11 18:22 ` [PATCH V1 0/2] Get real time power input via AMD PMF Mario Limonciello 2025-12-11 19:16 ` Lizhi Hou -- strict thread matches above, loose matches on Subject: below -- 2025-12-12 18:18 [PATCH V2 " Lizhi Hou 2025-12-12 18:18 ` [PATCH V2 2/2] accel/amdxdna: Add IOCTL to retrieve realtime NPU power estimate Lizhi Hou
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox