Only supported for particular Intel Xe graphics platforms.
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp5_crit
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. GPU PCIe critical temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp5_emergency
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. GPU PCIe shutdown temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp5_input
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. GPU PCIe temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/fan1_input
Date: March 2025
KernelVersion: 6.16
CHANNEL_PKG,
CHANNEL_VRAM,
CHANNEL_MCTRL,
+ CHANNEL_PCIE,
CHANNEL_MAX,
};
HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL |
HWMON_T_MAX,
HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL),
HWMON_CHANNEL_INFO(power, HWMON_P_MAX | HWMON_P_RATED_MAX | HWMON_P_LABEL | HWMON_P_CRIT |
HWMON_P_CAP,
return 0;
}
+static int get_pcie_temp(struct xe_hwmon *hwmon, long *val)
+{
+ struct xe_tile *root_tile = xe_device_get_root_tile(hwmon->xe);
+ u32 data = 0;
+ int ret;
+
+ ret = xe_pcode_read(root_tile, PCODE_MBOX(PCODE_THERMAL_INFO, READ_THERMAL_DATA,
+ PCIE_SENSOR_GROUP_ID), &data, NULL);
+ if (ret)
+ return ret;
+
+ /* Sensor offset is different for G21 */
+ if (hwmon->xe->info.subplatform != XE_SUBPLATFORM_BATTLEMAGE_G21)
+ data = REG_FIELD_GET(PCIE_SENSOR_MASK, data);
+
+ data = REG_FIELD_GET(TEMP_MASK, data);
+ *val = (s8)data * MILLIDEGREE_PER_DEGREE;
+
+ return 0;
+}
+
/* I1 is exposed as power_crit or as curr_crit depending on bit 31 */
static int xe_hwmon_pcode_read_i1(const struct xe_hwmon *hwmon, u32 *uval)
{
case CHANNEL_VRAM:
return hwmon->temp.limit[TEMP_LIMIT_MEM_SHUTDOWN] ? 0444 : 0;
case CHANNEL_MCTRL:
+ case CHANNEL_PCIE:
return hwmon->temp.count ? 0444 : 0;
default:
return 0;
case CHANNEL_VRAM:
return hwmon->temp.limit[TEMP_LIMIT_MEM_CRIT] ? 0444 : 0;
case CHANNEL_MCTRL:
+ case CHANNEL_PCIE:
return hwmon->temp.count ? 0444 : 0;
default:
return 0;
return xe_reg_is_valid(xe_hwmon_get_reg(hwmon, REG_TEMP,
channel)) ? 0444 : 0;
case CHANNEL_MCTRL:
+ case CHANNEL_PCIE:
return hwmon->temp.count ? 0444 : 0;
default:
return 0;
return 0;
case CHANNEL_MCTRL:
return get_mc_temp(hwmon, val);
+ case CHANNEL_PCIE:
+ return get_pcie_temp(hwmon, val);
default:
return -EOPNOTSUPP;
}
switch (channel) {
case CHANNEL_PKG:
case CHANNEL_MCTRL:
+ case CHANNEL_PCIE:
*val = hwmon->temp.limit[TEMP_LIMIT_PKG_SHUTDOWN] * MILLIDEGREE_PER_DEGREE;
return 0;
case CHANNEL_VRAM:
switch (channel) {
case CHANNEL_PKG:
case CHANNEL_MCTRL:
+ case CHANNEL_PCIE:
*val = hwmon->temp.limit[TEMP_LIMIT_PKG_CRIT] * MILLIDEGREE_PER_DEGREE;
return 0;
case CHANNEL_VRAM:
*str = "vram";
else if (channel == CHANNEL_MCTRL)
*str = "mctrl";
+ else if (channel == CHANNEL_PCIE)
+ *str = "pcie";
return 0;
case hwmon_power:
case hwmon_energy: