mirror of
https://github.com/torvalds/linux.git
synced 2026-06-05 13:06:59 +02:00
Merge branch 'thermal-intel'
Merge Intel thermal drivers updates for 6.17: - Add Wildcat Lake PCI ID to the int340x processor_thermal driver (Srinivas Pandruvada). - Add debugfs interface to override the temperature set by the firmware in the platform temperature control (PTC) interface and add a new sysfs control attribute called thermal_tolerance to it (Srinivas Pandruvada). * thermal-intel: thermal: int340x: processor_thermal: Add Wildcat Lake PCI ID thermal: intel: int340x: Allow temperature override thermal: intel: int340x: Add throttling control interface to PTC
This commit is contained in:
commit
866032d562
|
|
@ -206,6 +206,15 @@ All these controls needs admin privilege to update.
|
|||
Update a new temperature target in milli degree celsius for hardware to
|
||||
use for the temperature control.
|
||||
|
||||
``thermal_tolerance`` (RW)
|
||||
This attribute ranges from 0 to 7, where 0 represents
|
||||
the most aggressive control to avoid any temperature overshoots, and
|
||||
7 represents a more graceful approach, favoring performance even at
|
||||
the expense of temperature overshoots.
|
||||
Note: This level may not scale linearly. For example, a value of 3 does
|
||||
not necessarily imply a 50% improvement in performance compared to a
|
||||
value of 0.
|
||||
|
||||
Given that this is platform temperature control, it is expected that a
|
||||
single user-level manager owns and manages the controls. If multiple
|
||||
user-level software applications attempt to write different targets, it
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/pci.h>
|
||||
#include "processor_thermal_device.h"
|
||||
|
||||
|
|
@ -49,14 +50,16 @@ struct mmio_reg {
|
|||
};
|
||||
|
||||
#define MAX_ATTR_GROUP_NAME_LEN 32
|
||||
#define PTC_MAX_ATTRS 3
|
||||
#define PTC_MAX_ATTRS 4
|
||||
|
||||
struct ptc_data {
|
||||
u32 offset;
|
||||
struct pci_dev *pdev;
|
||||
struct attribute_group ptc_attr_group;
|
||||
struct attribute *ptc_attrs[PTC_MAX_ATTRS];
|
||||
struct device_attribute temperature_target_attr;
|
||||
struct device_attribute enable_attr;
|
||||
struct device_attribute thermal_tolerance_attr;
|
||||
char group_name[MAX_ATTR_GROUP_NAME_LEN];
|
||||
};
|
||||
|
||||
|
|
@ -78,6 +81,7 @@ static u32 ptc_offsets[PTC_MAX_INSTANCES] = {0x5B20, 0x5B28, 0x5B30};
|
|||
static const char * const ptc_strings[] = {
|
||||
"temperature_target",
|
||||
"enable",
|
||||
"thermal_tolerance",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -177,6 +181,8 @@ PTC_SHOW(temperature_target);
|
|||
PTC_STORE(temperature_target);
|
||||
PTC_SHOW(enable);
|
||||
PTC_STORE(enable);
|
||||
PTC_SHOW(thermal_tolerance);
|
||||
PTC_STORE(thermal_tolerance);
|
||||
|
||||
#define ptc_init_attribute(_name)\
|
||||
do {\
|
||||
|
|
@ -193,9 +199,11 @@ static int ptc_create_groups(struct pci_dev *pdev, int instance, struct ptc_data
|
|||
|
||||
ptc_init_attribute(temperature_target);
|
||||
ptc_init_attribute(enable);
|
||||
ptc_init_attribute(thermal_tolerance);
|
||||
|
||||
data->ptc_attrs[index++] = &data->temperature_target_attr.attr;
|
||||
data->ptc_attrs[index++] = &data->enable_attr.attr;
|
||||
data->ptc_attrs[index++] = &data->thermal_tolerance_attr.attr;
|
||||
data->ptc_attrs[index] = NULL;
|
||||
|
||||
snprintf(data->group_name, MAX_ATTR_GROUP_NAME_LEN,
|
||||
|
|
@ -209,6 +217,63 @@ static int ptc_create_groups(struct pci_dev *pdev, int instance, struct ptc_data
|
|||
}
|
||||
|
||||
static struct ptc_data ptc_instance[PTC_MAX_INSTANCES];
|
||||
static struct dentry *ptc_debugfs;
|
||||
|
||||
#define PTC_TEMP_OVERRIDE_ENABLE_INDEX 4
|
||||
#define PTC_TEMP_OVERRIDE_INDEX 5
|
||||
|
||||
static ssize_t ptc_temperature_write(struct file *file, const char __user *data,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ptc_data *ptc_instance = file->private_data;
|
||||
struct pci_dev *pdev = ptc_instance->pdev;
|
||||
char buf[32];
|
||||
ssize_t len;
|
||||
u32 value;
|
||||
|
||||
len = min(count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, data, len))
|
||||
return -EFAULT;
|
||||
|
||||
buf[len] = '\0';
|
||||
if (kstrtouint(buf, 0, &value))
|
||||
return -EINVAL;
|
||||
|
||||
if (ptc_mmio_regs[PTC_TEMP_OVERRIDE_INDEX].units)
|
||||
value /= ptc_mmio_regs[PTC_TEMP_OVERRIDE_INDEX].units;
|
||||
|
||||
if (value > ptc_mmio_regs[PTC_TEMP_OVERRIDE_INDEX].mask)
|
||||
return -EINVAL;
|
||||
|
||||
if (!value) {
|
||||
ptc_mmio_write(pdev, ptc_instance->offset, PTC_TEMP_OVERRIDE_ENABLE_INDEX, 0);
|
||||
} else {
|
||||
ptc_mmio_write(pdev, ptc_instance->offset, PTC_TEMP_OVERRIDE_INDEX, value);
|
||||
ptc_mmio_write(pdev, ptc_instance->offset, PTC_TEMP_OVERRIDE_ENABLE_INDEX, 1);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations ptc_fops = {
|
||||
.open = simple_open,
|
||||
.write = ptc_temperature_write,
|
||||
.llseek = generic_file_llseek,
|
||||
};
|
||||
|
||||
static void ptc_create_debugfs(void)
|
||||
{
|
||||
ptc_debugfs = debugfs_create_dir("platform_temperature_control", NULL);
|
||||
|
||||
debugfs_create_file("temperature_0", 0200, ptc_debugfs, &ptc_instance[0], &ptc_fops);
|
||||
debugfs_create_file("temperature_1", 0200, ptc_debugfs, &ptc_instance[1], &ptc_fops);
|
||||
debugfs_create_file("temperature_2", 0200, ptc_debugfs, &ptc_instance[2], &ptc_fops);
|
||||
}
|
||||
|
||||
static void ptc_delete_debugfs(void)
|
||||
{
|
||||
debugfs_remove_recursive(ptc_debugfs);
|
||||
}
|
||||
|
||||
int proc_thermal_ptc_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv)
|
||||
{
|
||||
|
|
@ -217,8 +282,11 @@ int proc_thermal_ptc_add(struct pci_dev *pdev, struct proc_thermal_device *proc_
|
|||
|
||||
for (i = 0; i < PTC_MAX_INSTANCES; i++) {
|
||||
ptc_instance[i].offset = ptc_offsets[i];
|
||||
ptc_instance[i].pdev = pdev;
|
||||
ptc_create_groups(pdev, i, &ptc_instance[i]);
|
||||
}
|
||||
|
||||
ptc_create_debugfs();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -234,6 +302,8 @@ void proc_thermal_ptc_remove(struct pci_dev *pdev)
|
|||
|
||||
for (i = 0; i < PTC_MAX_INSTANCES; i++)
|
||||
sysfs_remove_group(&pdev->dev.kobj, &ptc_instance[i].ptc_attr_group);
|
||||
|
||||
ptc_delete_debugfs();
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(proc_thermal_ptc_remove);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#define PCI_DEVICE_ID_INTEL_SKL_THERMAL 0x1903
|
||||
#define PCI_DEVICE_ID_INTEL_TGL_THERMAL 0x9A03
|
||||
#define PCI_DEVICE_ID_INTEL_PTL_THERMAL 0xB01D
|
||||
#define PCI_DEVICE_ID_INTEL_WCL_THERMAL 0xFD1D
|
||||
|
||||
struct power_config {
|
||||
u32 index;
|
||||
|
|
|
|||
|
|
@ -499,6 +499,10 @@ static const struct pci_device_id proc_thermal_pci_ids[] = {
|
|||
PROC_THERMAL_FEATURE_DLVR | PROC_THERMAL_FEATURE_DVFS |
|
||||
PROC_THERMAL_FEATURE_MSI_SUPPORT | PROC_THERMAL_FEATURE_WT_HINT |
|
||||
PROC_THERMAL_FEATURE_POWER_FLOOR | PROC_THERMAL_FEATURE_PTC) },
|
||||
{ PCI_DEVICE_DATA(INTEL, WCL_THERMAL, PROC_THERMAL_FEATURE_MSI_SUPPORT |
|
||||
PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_DLVR |
|
||||
PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WT_HINT |
|
||||
PROC_THERMAL_FEATURE_POWER_FLOOR | PROC_THERMAL_FEATURE_PTC) },
|
||||
{ },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -442,6 +442,7 @@ int proc_thermal_rfim_add(struct pci_dev *pdev, struct proc_thermal_device *proc
|
|||
switch (pdev->device) {
|
||||
case PCI_DEVICE_ID_INTEL_LNLM_THERMAL:
|
||||
case PCI_DEVICE_ID_INTEL_PTL_THERMAL:
|
||||
case PCI_DEVICE_ID_INTEL_WCL_THERMAL:
|
||||
dlvr_mmio_regs_table = lnl_dlvr_mmio_regs;
|
||||
dlvr_mapping = lnl_dlvr_mapping;
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user