Skip to content

Commit 2cbe1a3

Browse files
committed
Merge earlier changes in Intel thermal drivers for v6.7.
2 parents a56cc0a + 1ced5dc commit 2cbe1a3

File tree

12 files changed

+764
-157
lines changed

12 files changed

+764
-157
lines changed

Documentation/driver-api/thermal/intel_dptf.rst

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,57 @@ DPTF Fan Control
315315
----------------------------------------
316316

317317
Refer to Documentation/admin-guide/acpi/fan_performance_states.rst
318+
319+
Workload Type Hints
320+
----------------------------------------
321+
322+
The firmware in Meteor Lake processor generation is capable of identifying
323+
workload type and passing hints regarding it to the OS. A special sysfs
324+
interface is provided to allow user space to obtain workload type hints from
325+
the firmware and control the rate at which they are provided.
326+
327+
User space can poll attribute "workload_type_index" for the current hint or
328+
can receive a notification whenever the value of this attribute is updated.
329+
330+
file:`/sys/bus/pci/devices/0000:00:04.0/workload_hint/`
331+
Segment 0, bus 0, device 4, function 0 is reserved for the processor thermal
332+
device on all Intel client processors. So, the above path doesn't change
333+
based on the processor generation.
334+
335+
``workload_hint_enable`` (RW)
336+
Enable firmware to send workload type hints to user space.
337+
338+
``notification_delay_ms`` (RW)
339+
Minimum delay in milliseconds before firmware will notify OS. This is
340+
for the rate control of notifications. This delay is between changing
341+
the workload type prediction in the firmware and notifying the OS about
342+
the change. The default delay is 1024 ms. The delay of 0 is invalid.
343+
The delay is rounded up to the nearest power of 2 to simplify firmware
344+
programming of the delay value. The read of notification_delay_ms
345+
attribute shows the effective value used.
346+
347+
``workload_type_index`` (RO)
348+
Predicted workload type index. User space can get notification of
349+
change via existing sysfs attribute change notification mechanism.
350+
351+
The supported index values and their meaning for the Meteor Lake
352+
processor generation are as follows:
353+
354+
0 - Idle: System performs no tasks, power and idle residency are
355+
consistently low for long periods of time.
356+
357+
1 – Battery Life: Power is relatively low, but the processor may
358+
still be actively performing a task, such as video playback for
359+
a long period of time.
360+
361+
2 – Sustained: Power level that is relatively high for a long period
362+
of time, with very few to no periods of idleness, which will
363+
eventually exhaust RAPL Power Limit 1 and 2.
364+
365+
3 – Bursty: Consumes a relatively constant average amount of power, but
366+
periods of relative idleness are interrupted by bursts of
367+
activity. The bursts are relatively short and the periods of
368+
relative idleness between them typically prevent RAPL Power
369+
Limit 1 from being exhausted.
370+
371+
4 – Unknown: Can't classify.

drivers/thermal/intel/int340x_thermal/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_device_pci.o
1010
obj-$(CONFIG_PROC_THERMAL_MMIO_RAPL) += processor_thermal_rapl.o
1111
obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_rfim.o
1212
obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_mbox.o
13+
obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_wt_req.o
14+
obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_wt_hint.o
1315
obj-$(CONFIG_INT3406_THERMAL) += int3406_thermal.o
1416
obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o

drivers/thermal/intel/int340x_thermal/processor_thermal_device.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -346,12 +346,18 @@ int proc_thermal_mmio_add(struct pci_dev *pdev,
346346
}
347347
}
348348

349-
if (feature_mask & PROC_THERMAL_FEATURE_MBOX) {
350-
ret = proc_thermal_mbox_add(pdev, proc_priv);
349+
if (feature_mask & PROC_THERMAL_FEATURE_WT_REQ) {
350+
ret = proc_thermal_wt_req_add(pdev, proc_priv);
351351
if (ret) {
352352
dev_err(&pdev->dev, "failed to add MBOX interface\n");
353353
goto err_rem_rfim;
354354
}
355+
} else if (feature_mask & PROC_THERMAL_FEATURE_WT_HINT) {
356+
ret = proc_thermal_wt_hint_add(pdev, proc_priv);
357+
if (ret) {
358+
dev_err(&pdev->dev, "failed to add WT Hint\n");
359+
goto err_rem_rfim;
360+
}
355361
}
356362

357363
return 0;
@@ -374,12 +380,15 @@ void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device *
374380
proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DVFS)
375381
proc_thermal_rfim_remove(pdev);
376382

377-
if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_MBOX)
378-
proc_thermal_mbox_remove(pdev);
383+
if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_WT_REQ)
384+
proc_thermal_wt_req_remove(pdev);
385+
else if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_WT_HINT)
386+
proc_thermal_wt_hint_remove(pdev);
379387
}
380388
EXPORT_SYMBOL_GPL(proc_thermal_mmio_remove);
381389

382390
MODULE_IMPORT_NS(INTEL_TCC);
391+
MODULE_IMPORT_NS(INT340X_THERMAL);
383392
MODULE_AUTHOR("Srinivas Pandruvada <[email protected]>");
384393
MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver");
385394
MODULE_LICENSE("GPL v2");

drivers/thermal/intel/int340x_thermal/processor_thermal_device.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/intel_rapl.h>
1111

1212
#define PCI_DEVICE_ID_INTEL_ADL_THERMAL 0x461d
13+
#define PCI_DEVICE_ID_INTEL_ARL_S_THERMAL 0xAD03
1314
#define PCI_DEVICE_ID_INTEL_BDW_THERMAL 0x1603
1415
#define PCI_DEVICE_ID_INTEL_BSW_THERMAL 0x22DC
1516

@@ -59,8 +60,9 @@ struct rapl_mmio_regs {
5960
#define PROC_THERMAL_FEATURE_RAPL 0x01
6061
#define PROC_THERMAL_FEATURE_FIVR 0x02
6162
#define PROC_THERMAL_FEATURE_DVFS 0x04
62-
#define PROC_THERMAL_FEATURE_MBOX 0x08
63+
#define PROC_THERMAL_FEATURE_WT_REQ 0x08
6364
#define PROC_THERMAL_FEATURE_DLVR 0x10
65+
#define PROC_THERMAL_FEATURE_WT_HINT 0x20
6466

6567
#if IS_ENABLED(CONFIG_PROC_THERMAL_MMIO_RAPL)
6668
int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
@@ -80,13 +82,27 @@ static void __maybe_unused proc_thermal_rapl_remove(void)
8082
int proc_thermal_rfim_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
8183
void proc_thermal_rfim_remove(struct pci_dev *pdev);
8284

83-
int proc_thermal_mbox_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
84-
void proc_thermal_mbox_remove(struct pci_dev *pdev);
85+
int proc_thermal_wt_req_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
86+
void proc_thermal_wt_req_remove(struct pci_dev *pdev);
87+
88+
#define MBOX_CMD_WORKLOAD_TYPE_READ 0x0E
89+
#define MBOX_CMD_WORKLOAD_TYPE_WRITE 0x0F
90+
91+
#define MBOX_DATA_BIT_AC_DC 30
92+
#define MBOX_DATA_BIT_VALID 31
8593

8694
int processor_thermal_send_mbox_read_cmd(struct pci_dev *pdev, u16 id, u64 *resp);
8795
int processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev, u16 id, u32 data);
96+
int processor_thermal_mbox_interrupt_config(struct pci_dev *pdev, bool enable, int enable_bit,
97+
int time_window);
8898
int proc_thermal_add(struct device *dev, struct proc_thermal_device *priv);
8999
void proc_thermal_remove(struct proc_thermal_device *proc_priv);
100+
101+
int proc_thermal_wt_hint_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
102+
void proc_thermal_wt_hint_remove(struct pci_dev *pdev);
103+
void proc_thermal_wt_intr_callback(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
104+
bool proc_thermal_check_wt_intr(struct proc_thermal_device *proc_priv);
105+
90106
int proc_thermal_suspend(struct device *dev);
91107
int proc_thermal_resume(struct device *dev);
92108
int proc_thermal_mmio_add(struct pci_dev *pdev,

drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515

1616
#define DRV_NAME "proc_thermal_pci"
1717

18+
static bool use_msi;
19+
module_param(use_msi, bool, 0644);
20+
MODULE_PARM_DESC(use_msi,
21+
"Use PCI MSI based interrupts for processor thermal device.");
22+
1823
struct proc_thermal_pci {
1924
struct pci_dev *pdev;
2025
struct proc_thermal_device *proc_priv;
@@ -117,20 +122,44 @@ static void pkg_thermal_schedule_work(struct delayed_work *work)
117122
schedule_delayed_work(work, ms);
118123
}
119124

125+
static irqreturn_t proc_thermal_irq_thread_handler(int irq, void *devid)
126+
{
127+
struct proc_thermal_pci *pci_info = devid;
128+
129+
proc_thermal_wt_intr_callback(pci_info->pdev, pci_info->proc_priv);
130+
131+
return IRQ_HANDLED;
132+
}
133+
120134
static irqreturn_t proc_thermal_irq_handler(int irq, void *devid)
121135
{
122136
struct proc_thermal_pci *pci_info = devid;
137+
struct proc_thermal_device *proc_priv;
138+
int ret = IRQ_HANDLED;
123139
u32 status;
124140

141+
proc_priv = pci_info->proc_priv;
142+
143+
if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_WT_HINT) {
144+
if (proc_thermal_check_wt_intr(pci_info->proc_priv))
145+
ret = IRQ_WAKE_THREAD;
146+
}
147+
148+
/*
149+
* Since now there are two sources of interrupts: one from thermal threshold
150+
* and another from workload hint, add a check if there was really a threshold
151+
* interrupt before scheduling work function for thermal threshold.
152+
*/
125153
proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_INT_STATUS_0, &status);
154+
if (status) {
155+
/* Disable enable interrupt flag */
156+
proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0);
157+
pkg_thermal_schedule_work(&pci_info->work);
158+
}
126159

127-
/* Disable enable interrupt flag */
128-
proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0);
129160
pci_write_config_byte(pci_info->pdev, 0xdc, 0x01);
130161

131-
pkg_thermal_schedule_work(&pci_info->work);
132-
133-
return IRQ_HANDLED;
162+
return ret;
134163
}
135164

136165
static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
@@ -203,6 +232,7 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
203232
struct proc_thermal_device *proc_priv;
204233
struct proc_thermal_pci *pci_info;
205234
int irq_flag = 0, irq, ret;
235+
bool msi_irq = false;
206236

207237
proc_priv = devm_kzalloc(&pdev->dev, sizeof(*proc_priv), GFP_KERNEL);
208238
if (!proc_priv)
@@ -248,18 +278,23 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
248278
goto err_ret_mmio;
249279
}
250280

251-
/* request and enable interrupt */
252-
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
253-
if (ret < 0) {
254-
dev_err(&pdev->dev, "Failed to allocate vectors!\n");
255-
goto err_ret_tzone;
256-
}
257-
if (!pdev->msi_enabled && !pdev->msix_enabled)
281+
if (use_msi && (pdev->msi_enabled || pdev->msix_enabled)) {
282+
/* request and enable interrupt */
283+
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
284+
if (ret < 0) {
285+
dev_err(&pdev->dev, "Failed to allocate vectors!\n");
286+
goto err_ret_tzone;
287+
}
288+
289+
irq = pci_irq_vector(pdev, 0);
290+
msi_irq = true;
291+
} else {
258292
irq_flag = IRQF_SHARED;
293+
irq = pdev->irq;
294+
}
259295

260-
irq = pci_irq_vector(pdev, 0);
261296
ret = devm_request_threaded_irq(&pdev->dev, irq,
262-
proc_thermal_irq_handler, NULL,
297+
proc_thermal_irq_handler, proc_thermal_irq_thread_handler,
263298
irq_flag, KBUILD_MODNAME, pci_info);
264299
if (ret) {
265300
dev_err(&pdev->dev, "Request IRQ %d failed\n", pdev->irq);
@@ -273,7 +308,8 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
273308
return 0;
274309

275310
err_free_vectors:
276-
pci_free_irq_vectors(pdev);
311+
if (msi_irq)
312+
pci_free_irq_vectors(pdev);
277313
err_ret_tzone:
278314
thermal_zone_device_unregister(pci_info->tzone);
279315
err_ret_mmio:
@@ -350,9 +386,15 @@ static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, proc_thermal_pci_suspend,
350386
proc_thermal_pci_resume);
351387

352388
static const struct pci_device_id proc_thermal_pci_ids[] = {
353-
{ PCI_DEVICE_DATA(INTEL, ADL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) },
354-
{ PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX | PROC_THERMAL_FEATURE_DLVR) },
355-
{ PCI_DEVICE_DATA(INTEL, RPL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) },
389+
{ PCI_DEVICE_DATA(INTEL, ADL_THERMAL, PROC_THERMAL_FEATURE_RAPL |
390+
PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WT_REQ) },
391+
{ PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL |
392+
PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR |
393+
PROC_THERMAL_FEATURE_WT_HINT) },
394+
{ PCI_DEVICE_DATA(INTEL, ARL_S_THERMAL, PROC_THERMAL_FEATURE_RAPL |
395+
PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR | PROC_THERMAL_FEATURE_WT_HINT) },
396+
{ PCI_DEVICE_DATA(INTEL, RPL_THERMAL, PROC_THERMAL_FEATURE_RAPL |
397+
PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WT_REQ) },
356398
{ },
357399
};
358400

@@ -368,6 +410,8 @@ static struct pci_driver proc_thermal_pci_driver = {
368410

369411
module_pci_driver(proc_thermal_pci_driver);
370412

413+
MODULE_IMPORT_NS(INT340X_THERMAL);
414+
371415
MODULE_AUTHOR("Srinivas Pandruvada <[email protected]>");
372416
MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver");
373417
MODULE_LICENSE("GPL v2");

drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ static const struct pci_device_id proc_thermal_pci_ids[] = {
137137
{ PCI_DEVICE_DATA(INTEL, ICL_THERMAL, PROC_THERMAL_FEATURE_RAPL) },
138138
{ PCI_DEVICE_DATA(INTEL, JSL_THERMAL, 0) },
139139
{ PCI_DEVICE_DATA(INTEL, SKL_THERMAL, PROC_THERMAL_FEATURE_RAPL) },
140-
{ PCI_DEVICE_DATA(INTEL, TGL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_MBOX) },
140+
{ PCI_DEVICE_DATA(INTEL, TGL_THERMAL, PROC_THERMAL_FEATURE_RAPL |
141+
PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_WT_REQ) },
141142
{ },
142143
};
143144

0 commit comments

Comments
 (0)