mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
drm/xe/hwmon: Read energy status from PMT
Read card and package energy status using pmt apis instead of xe_mmio for supported platforms. Enable Battlemage to read energy from PMT. v2: - Remove unused has_pmt_energy field. (Badal) - Use GENMASK to extract energy data. (Badal) v3: - Move PMT energy register offset and GENMASK to xe_pmt.h - Address review comments. (Jani) v4: - Remove unnecessary debug print. (Badal) v5: - Resolve an unused variable warning. - Add a return value check. Signed-off-by: Karthik Poosa <karthik.poosa@intel.com> Reviewed-by: Badal Nilawar <badal.nilawar@intel.com> Link: https://lore.kernel.org/r/20250529163458.2354509-6-karthik.poosa@intel.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
This commit is contained in:
committed by
Rodrigo Vivi
parent
719d8a5959
commit
0c5405d3aa
@@ -18,12 +18,10 @@
|
||||
#define PVC_GT0_PLATFORM_ENERGY_STATUS XE_REG(0x28106c)
|
||||
#define PVC_GT0_PACKAGE_POWER_SKU XE_REG(0x281080)
|
||||
|
||||
#define BMG_PACKAGE_ENERGY_STATUS XE_REG(0x138120)
|
||||
#define BMG_FAN_1_SPEED XE_REG(0x138140)
|
||||
#define BMG_FAN_2_SPEED XE_REG(0x138170)
|
||||
#define BMG_FAN_3_SPEED XE_REG(0x1381a0)
|
||||
#define BMG_VRAM_TEMPERATURE XE_REG(0x1382c0)
|
||||
#define BMG_PACKAGE_TEMPERATURE XE_REG(0x138434)
|
||||
#define BMG_PLATFORM_ENERGY_STATUS XE_REG(0x138458)
|
||||
|
||||
#endif /* _XE_PCODE_REGS_H_ */
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
#define BMG_PMT_BASE_OFFSET 0xDB000
|
||||
#define BMG_DISCOVERY_OFFSET (SOC_BASE + BMG_PMT_BASE_OFFSET)
|
||||
|
||||
#define PUNIT_TELEMETRY_GUID XE_REG(BMG_DISCOVERY_OFFSET + 0x4)
|
||||
#define BMG_ENERGY_STATUS_PMT_OFFSET (0x30)
|
||||
#define ENERGY_PKG REG_GENMASK64(31, 0)
|
||||
#define ENERGY_CARD REG_GENMASK64(63, 32)
|
||||
|
||||
#define BMG_TELEMETRY_BASE_OFFSET 0xE0000
|
||||
#define BMG_TELEMETRY_OFFSET (SOC_BASE + BMG_TELEMETRY_BASE_OFFSET)
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "xe_pcode_api.h"
|
||||
#include "xe_sriov.h"
|
||||
#include "xe_pm.h"
|
||||
#include "xe_vsec.h"
|
||||
#include "regs/xe_pmt.h"
|
||||
|
||||
enum xe_hwmon_reg {
|
||||
REG_TEMP,
|
||||
@@ -252,12 +254,7 @@ static struct xe_reg xe_hwmon_get_reg(struct xe_hwmon *hwmon, enum xe_hwmon_reg
|
||||
return GT_PERF_STATUS;
|
||||
break;
|
||||
case REG_PKG_ENERGY_STATUS:
|
||||
if (xe->info.platform == XE_BATTLEMAGE) {
|
||||
if (channel == CHANNEL_PKG)
|
||||
return BMG_PACKAGE_ENERGY_STATUS;
|
||||
else
|
||||
return BMG_PLATFORM_ENERGY_STATUS;
|
||||
} else if (xe->info.platform == XE_PVC && channel == CHANNEL_PKG) {
|
||||
if (xe->info.platform == XE_PVC && channel == CHANNEL_PKG) {
|
||||
return PVC_GT0_PLATFORM_ENERGY_STATUS;
|
||||
} else if ((xe->info.platform == XE_DG2) && (channel == CHANNEL_PKG)) {
|
||||
return PCU_CR_PACKAGE_ENERGY_STATUS;
|
||||
@@ -450,9 +447,32 @@ xe_hwmon_energy_get(struct xe_hwmon *hwmon, int channel, long *energy)
|
||||
struct xe_mmio *mmio = xe_root_tile_mmio(hwmon->xe);
|
||||
struct xe_hwmon_energy_info *ei = &hwmon->ei[channel];
|
||||
u64 reg_val;
|
||||
int ret = 0;
|
||||
|
||||
reg_val = xe_mmio_read32(mmio, xe_hwmon_get_reg(hwmon, REG_PKG_ENERGY_STATUS,
|
||||
channel));
|
||||
/* Energy is supported only for card and pkg */
|
||||
if (channel > CHANNEL_PKG) {
|
||||
*energy = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (hwmon->xe->info.platform == XE_BATTLEMAGE) {
|
||||
ret = xe_pmt_telem_read(to_pci_dev(hwmon->xe->drm.dev),
|
||||
xe_mmio_read32(mmio, PUNIT_TELEMETRY_GUID),
|
||||
®_val, BMG_ENERGY_STATUS_PMT_OFFSET, sizeof(reg_val));
|
||||
if (ret != sizeof(reg_val)) {
|
||||
drm_warn(&hwmon->xe->drm, "energy read from pmt failed, ret %d\n", ret);
|
||||
*energy = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (channel == CHANNEL_PKG)
|
||||
reg_val = REG_FIELD_GET64(ENERGY_PKG, reg_val);
|
||||
else
|
||||
reg_val = REG_FIELD_GET64(ENERGY_CARD, reg_val);
|
||||
} else {
|
||||
reg_val = xe_mmio_read32(mmio, xe_hwmon_get_reg(hwmon, REG_PKG_ENERGY_STATUS,
|
||||
channel));
|
||||
}
|
||||
|
||||
if (reg_val >= ei->reg_val_prev)
|
||||
ei->accum_energy += reg_val - ei->reg_val_prev;
|
||||
@@ -934,11 +954,18 @@ xe_hwmon_in_read(struct xe_hwmon *hwmon, u32 attr, int channel, long *val)
|
||||
static umode_t
|
||||
xe_hwmon_energy_is_visible(struct xe_hwmon *hwmon, u32 attr, int channel)
|
||||
{
|
||||
long energy = 0;
|
||||
|
||||
switch (attr) {
|
||||
case hwmon_energy_input:
|
||||
case hwmon_energy_label:
|
||||
return xe_reg_is_valid(xe_hwmon_get_reg(hwmon, REG_PKG_ENERGY_STATUS,
|
||||
channel)) ? 0444 : 0;
|
||||
if (hwmon->xe->info.platform == XE_BATTLEMAGE) {
|
||||
xe_hwmon_energy_get(hwmon, channel, &energy);
|
||||
return energy ? 0444 : 0;
|
||||
} else {
|
||||
return xe_reg_is_valid(xe_hwmon_get_reg(hwmon, REG_PKG_ENERGY_STATUS,
|
||||
channel)) ? 0444 : 0;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -1283,4 +1310,4 @@ int xe_hwmon_register(struct xe_device *xe)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_IMPORT_NS("INTEL_PMT_TELEMETRY");
|
||||
|
||||
@@ -149,8 +149,8 @@ static int xe_guid_decode(u32 guid, int *index, u32 *offset)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xe_pmt_telem_read(struct pci_dev *pdev, u32 guid, u64 *data, loff_t user_offset,
|
||||
u32 count)
|
||||
int xe_pmt_telem_read(struct pci_dev *pdev, u32 guid, u64 *data, loff_t user_offset,
|
||||
u32 count)
|
||||
{
|
||||
struct xe_device *xe = pdev_to_xe_device(pdev);
|
||||
void __iomem *telem_addr = xe->mmio.regs + BMG_TELEMETRY_OFFSET;
|
||||
|
||||
@@ -4,8 +4,12 @@
|
||||
#ifndef _XE_VSEC_H_
|
||||
#define _XE_VSEC_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct pci_dev;
|
||||
struct xe_device;
|
||||
|
||||
void xe_vsec_init(struct xe_device *xe);
|
||||
int xe_pmt_telem_read(struct pci_dev *pdev, u32 guid, u64 *data, loff_t user_offset, u32 count);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user