Loading Documentation/driver-api/thermal/intel_dptf.rst +9 −0 Original line number Diff line number Diff line Loading @@ -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 Loading drivers/thermal/intel/int340x_thermal/platform_temperature_control.c +71 −1 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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]; }; Loading @@ -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 }; Loading Loading @@ -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 {\ Loading @@ -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, Loading @@ -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) { Loading @@ -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; Loading @@ -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); Loading drivers/thermal/intel/int340x_thermal/processor_thermal_device.h +1 −0 Original line number Diff line number Diff line Loading @@ -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; Loading drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c +4 −0 Original line number Diff line number Diff line Loading @@ -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) }, { }, }; Loading drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
Documentation/driver-api/thermal/intel_dptf.rst +9 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
drivers/thermal/intel/int340x_thermal/platform_temperature_control.c +71 −1 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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]; }; Loading @@ -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 }; Loading Loading @@ -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 {\ Loading @@ -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, Loading @@ -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) { Loading @@ -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; Loading @@ -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); Loading
drivers/thermal/intel/int340x_thermal/processor_thermal_device.h +1 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c +4 −0 Original line number Diff line number Diff line Loading @@ -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) }, { }, }; Loading
drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c +1 −0 Original line number Diff line number Diff line Loading @@ -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