Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

thermal: int340x: processor_thermal: Enable slow workload type hints

On processors starting from Panther Lake, additional workload type hints
are provided.

The hardware analyzes workload residencies over an extended period to
determine whether the workload classification tends toward idle/battery
life states or sustained/performance states. Based on this long-term
analysis, it classifies:

Power Classification: If the workload exhibits more idle or battery
life residencies, it is classified as "power". This is indicated by
setting bit 4 of the current workload type.

Performance Classification: If the workload exhibits more sustained
or performance residencies, it is classified as "performance". This
is indicated by clearing bit 4 of the current workload type.

This approach enables applications to ignore short-term workload
fluctuations and instead respond to longer-term power vs. performance
trends. Hints of this type are called slow workload hints.

To get notifications for slow workload hints, bit 22 in the thermal
mailbox can be used for configuring workload interrupts. It is possible
to exclusively enable slow workload hints or enable them in addition to
the current workload hints.

To enable slow workload hints, a new sysfs attribute is added to the
existing workload hint attributes:

workload_slow_hint_enable (RW): Write 1 to enable, 0 to disable.

Reading this attribute shows the current state.

This attribute is not present on any previous generation of processors.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
[ rjw: Dropped redundant local variables, changelog edits ]
Link: https://patch.msgid.link/20251218222559.4110027-2-srinivas.pandruvada@linux.intel.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Srinivas Pandruvada and committed by
Rafael J. Wysocki
a499c24c 3e087352

+52 -8
+3
Documentation/driver-api/thermal/intel_dptf.rst
··· 375 375 ``workload_hint_enable`` (RW) 376 376 Enable firmware to send workload type hints to user space. 377 377 378 + ``workload_slow_hint_enable`` (RW) 379 + Enable firmware to send slow workload type hints to user space. 380 + 378 381 ``notification_delay_ms`` (RW) 379 382 Minimum delay in milliseconds before firmware will notify OS. This is 380 383 for the rate control of notifications. This delay is between changing
+49 -8
drivers/thermal/intel/int340x_thermal/processor_thermal_wt_hint.c
··· 34 34 35 35 #define SOC_WT GENMASK_ULL(47, 40) 36 36 37 + #define SOC_WT_SLOW_PREDICTION_INT_ENABLE_BIT 22 37 38 #define SOC_WT_PREDICTION_INT_ENABLE_BIT 23 38 39 39 40 #define SOC_WT_PREDICTION_INT_ACTIVE BIT(2) ··· 48 47 49 48 static DEFINE_MUTEX(wt_lock); 50 49 static u8 wt_enable; 50 + static u8 wt_slow_enable; 51 51 52 52 /* Show current predicted workload type index */ 53 53 static ssize_t workload_type_index_show(struct device *dev, ··· 61 59 int wt; 62 60 63 61 mutex_lock(&wt_lock); 64 - if (!wt_enable) { 62 + if (!wt_enable && !wt_slow_enable) { 65 63 mutex_unlock(&wt_lock); 66 64 return -ENODATA; 67 65 } ··· 86 84 return sysfs_emit(buf, "%d\n", wt_enable); 87 85 } 88 86 89 - static ssize_t workload_hint_enable_store(struct device *dev, 90 - struct device_attribute *attr, 91 - const char *buf, size_t size) 87 + static ssize_t workload_hint_enable(struct device *dev, u8 enable_bit, u8 *status, 88 + struct device_attribute *attr, 89 + const char *buf, size_t size) 92 90 { 93 91 struct pci_dev *pdev = to_pci_dev(dev); 94 92 u8 mode; ··· 101 99 102 100 if (mode) 103 101 ret = processor_thermal_mbox_interrupt_config(pdev, true, 104 - SOC_WT_PREDICTION_INT_ENABLE_BIT, 102 + enable_bit, 105 103 notify_delay); 106 104 else 107 105 ret = processor_thermal_mbox_interrupt_config(pdev, false, 108 - SOC_WT_PREDICTION_INT_ENABLE_BIT, 0); 106 + enable_bit, 0); 109 107 110 108 if (ret) 111 109 goto ret_enable_store; 112 110 113 111 ret = size; 114 - wt_enable = mode; 112 + *status = mode; 115 113 116 114 ret_enable_store: 117 115 mutex_unlock(&wt_lock); ··· 119 117 return ret; 120 118 } 121 119 120 + static ssize_t workload_hint_enable_store(struct device *dev, struct device_attribute *attr, 121 + const char *buf, size_t size) 122 + { 123 + return workload_hint_enable(dev, SOC_WT_PREDICTION_INT_ENABLE_BIT, &wt_enable, 124 + attr, buf, size); 125 + } 122 126 static DEVICE_ATTR_RW(workload_hint_enable); 127 + 128 + static ssize_t workload_slow_hint_enable_show(struct device *dev, struct device_attribute *attr, 129 + char *buf) 130 + { 131 + return sysfs_emit(buf, "%d\n", wt_slow_enable); 132 + } 133 + 134 + static ssize_t workload_slow_hint_enable_store(struct device *dev, struct device_attribute *attr, 135 + const char *buf, size_t size) 136 + { 137 + return workload_hint_enable(dev, SOC_WT_SLOW_PREDICTION_INT_ENABLE_BIT, &wt_slow_enable, 138 + attr, buf, size); 139 + } 140 + static DEVICE_ATTR_RW(workload_slow_hint_enable); 123 141 124 142 static ssize_t notification_delay_ms_show(struct device *dev, 125 143 struct device_attribute *attr, ··· 200 178 201 179 static DEVICE_ATTR_RW(notification_delay_ms); 202 180 181 + static umode_t workload_hint_attr_visible(struct kobject *kobj, struct attribute *attr, int unused) 182 + { 183 + if (attr != &dev_attr_workload_slow_hint_enable.attr) 184 + return attr->mode; 185 + 186 + switch (to_pci_dev(kobj_to_dev(kobj))->device) { 187 + case PCI_DEVICE_ID_INTEL_LNLM_THERMAL: 188 + case PCI_DEVICE_ID_INTEL_MTLP_THERMAL: 189 + case PCI_DEVICE_ID_INTEL_ARL_S_THERMAL: 190 + return 0; 191 + default: 192 + break; 193 + } 194 + 195 + return attr->mode; 196 + } 197 + 203 198 static struct attribute *workload_hint_attrs[] = { 204 199 &dev_attr_workload_type_index.attr, 205 200 &dev_attr_workload_hint_enable.attr, 201 + &dev_attr_workload_slow_hint_enable.attr, 206 202 &dev_attr_notification_delay_ms.attr, 207 203 NULL 208 204 }; 209 205 210 206 static const struct attribute_group workload_hint_attribute_group = { 211 207 .attrs = workload_hint_attrs, 212 - .name = "workload_hint" 208 + .name = "workload_hint", 209 + .is_visible = workload_hint_attr_visible 213 210 }; 214 211 215 212 /*