linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] drivers: thermal: processor_thermal_device: Export sysfs inteface for TCC offset
@ 2019-07-23  1:03 Srinivas Pandruvada
  2019-07-24 19:52 ` Benjamin Berg
  0 siblings, 1 reply; 2+ messages in thread
From: Srinivas Pandruvada @ 2019-07-23  1:03 UTC (permalink / raw)
  To: rui.zhang, edubezval; +Cc: linux-pm, linux-kernel, Srinivas Pandruvada

This change exports an interface to read tcc offset and allow writing if
the platform is not locked.

Refer to Intel SDM for details on the MSR: MSR_TEMPERATURE_TARGET.
Here TCC Activation Offset (R/W) bits allow temperature offset in degrees
in relation to TjMAX.

This change will be useful for improving performance from user space for
some platforms, if the current offset is not optimal.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 .../processor_thermal_device.c                | 91 ++++++++++++++++++-
 1 file changed, 87 insertions(+), 4 deletions(-)

diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
index 213ab3cc6b80..a35635129fed 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
@@ -137,6 +137,72 @@ static const struct attribute_group power_limit_attribute_group = {
 	.name = "power_limits"
 };
 
+static ssize_t tcc_offset_degree_celsius_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	u64 val;
+	int err;
+
+	err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
+	if (err)
+		return err;
+
+	val = (val >> 24) & 0xff;
+	return sprintf(buf, "%d\n", (int)val);
+}
+
+static int tcc_offset_update(int tcc)
+{
+	u64 val;
+	int err;
+
+	if (!tcc)
+		return -EINVAL;
+
+	err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
+	if (err)
+		return err;
+
+	val = ~GENMASK_ULL(31, 24);
+	val = (tcc & 0xff) << 24;
+
+	err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int tcc_offset_save;
+
+static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
+				struct device_attribute *attr, const char *buf,
+				size_t count)
+{
+	u64 val;
+	int tcc, err;
+
+	err = rdmsrl_safe(MSR_PLATFORM_INFO, &val);
+	if (err)
+		return err;
+
+	if (!(val & BIT(30)))
+		return -EACCES;
+
+	if (kstrtoint(buf, 0, &tcc))
+		return -EINVAL;
+
+	err = tcc_offset_update(tcc);
+	if (err)
+		return err;
+
+	tcc_offset_save = tcc;
+
+	return count;
+}
+
+static DEVICE_ATTR_RW(tcc_offset_degree_celsius);
+
 static int stored_tjmax; /* since it is fixed, we can have local storage */
 
 static int get_tjmax(void)
@@ -332,6 +398,7 @@ static void proc_thermal_remove(struct proc_thermal_device *proc_priv)
 	acpi_remove_notify_handler(proc_priv->adev->handle,
 				   ACPI_DEVICE_NOTIFY, proc_thermal_notify);
 	int340x_thermal_zone_remove(proc_priv->int340x_zone);
+	sysfs_remove_file(&proc_priv->dev->kobj, &dev_attr_tcc_offset_degree_celsius.attr);
 	sysfs_remove_group(&proc_priv->dev->kobj,
 			   &power_limit_attribute_group);
 }
@@ -355,8 +422,15 @@ static int int3401_add(struct platform_device *pdev)
 
 	dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PLATFORM_DEV\n");
 
-	return sysfs_create_group(&pdev->dev.kobj,
-					 &power_limit_attribute_group);
+	ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
+	if (ret)
+		return ret;
+
+	ret = sysfs_create_group(&pdev->dev.kobj, &power_limit_attribute_group);
+	if (ret)
+		sysfs_remove_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
+
+	return ret;
 }
 
 static int int3401_remove(struct platform_device *pdev)
@@ -584,8 +658,15 @@ static int  proc_thermal_pci_probe(struct pci_dev *pdev,
 
 	dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PCI\n");
 
-	return sysfs_create_group(&pdev->dev.kobj,
-					 &power_limit_attribute_group);
+	ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
+	if (ret)
+		return ret;
+
+	ret = sysfs_create_group(&pdev->dev.kobj, &power_limit_attribute_group);
+	if (ret)
+		sysfs_remove_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
+
+	return ret;
 }
 
 static void  proc_thermal_pci_remove(struct pci_dev *pdev)
@@ -611,6 +692,8 @@ static int proc_thermal_resume(struct device *dev)
 	proc_dev = dev_get_drvdata(dev);
 	proc_thermal_read_ppcc(proc_dev);
 
+	tcc_offset_update(tcc_offset_save);
+
 	return 0;
 }
 #else
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] drivers: thermal: processor_thermal_device: Export sysfs inteface for TCC offset
  2019-07-23  1:03 [PATCH] drivers: thermal: processor_thermal_device: Export sysfs inteface for TCC offset Srinivas Pandruvada
@ 2019-07-24 19:52 ` Benjamin Berg
  0 siblings, 0 replies; 2+ messages in thread
From: Benjamin Berg @ 2019-07-24 19:52 UTC (permalink / raw)
  To: Srinivas Pandruvada, rui.zhang, edubezval; +Cc: linux-pm, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 4902 bytes --]

Tested-by: Benjamin Berg <bberg@redhat.com>

Hi,

this patch allows performance improvements of some machines. It would
be nice if this could still make 5.3.

Benjamin

On Mon, 2019-07-22 at 18:03 -0700, Srinivas Pandruvada wrote:
> This change exports an interface to read tcc offset and allow writing if
> the platform is not locked.
> 
> Refer to Intel SDM for details on the MSR: MSR_TEMPERATURE_TARGET.
> Here TCC Activation Offset (R/W) bits allow temperature offset in degrees
> in relation to TjMAX.
> 
> This change will be useful for improving performance from user space for
> some platforms, if the current offset is not optimal.
> 
> Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
> ---
>  .../processor_thermal_device.c                | 91
> ++++++++++++++++++-
>  1 file changed, 87 insertions(+), 4 deletions(-)
> 
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
> index 213ab3cc6b80..a35635129fed 100644
> ---
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
> +++
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
> @@ -137,6 +137,72 @@ static const struct attribute_group
> power_limit_attribute_group = {
>  	.name = "power_limits"
>  };
>  
> +static ssize_t tcc_offset_degree_celsius_show(struct device *dev,
> +			       struct device_attribute *attr, char
> *buf)
> +{
> +	u64 val;
> +	int err;
> +
> +	err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
> +	if (err)
> +		return err;
> +
> +	val = (val >> 24) & 0xff;
> +	return sprintf(buf, "%d\n", (int)val);
> +}
> +
> +static int tcc_offset_update(int tcc)
> +{
> +	u64 val;
> +	int err;
> +
> +	if (!tcc)
> +		return -EINVAL;
> +
> +	err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
> +	if (err)
> +		return err;
> +
> +	val = ~GENMASK_ULL(31, 24);
> +	val = (tcc & 0xff) << 24;
> +
> +	err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val);
> +	if (err)
> +		return err;
> +
> +	return 0;
> +}
> +
> +static int tcc_offset_save;
> +
> +static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
> +				struct device_attribute *attr, const
> char *buf,
> +				size_t count)
> +{
> +	u64 val;
> +	int tcc, err;
> +
> +	err = rdmsrl_safe(MSR_PLATFORM_INFO, &val);
> +	if (err)
> +		return err;
> +
> +	if (!(val & BIT(30)))
> +		return -EACCES;
> +
> +	if (kstrtoint(buf, 0, &tcc))
> +		return -EINVAL;
> +
> +	err = tcc_offset_update(tcc);
> +	if (err)
> +		return err;
> +
> +	tcc_offset_save = tcc;
> +
> +	return count;
> +}
> +
> +static DEVICE_ATTR_RW(tcc_offset_degree_celsius);
> +
>  static int stored_tjmax; /* since it is fixed, we can have local
> storage */
>  
>  static int get_tjmax(void)
> @@ -332,6 +398,7 @@ static void proc_thermal_remove(struct
> proc_thermal_device *proc_priv)
>  	acpi_remove_notify_handler(proc_priv->adev->handle,
>  				   ACPI_DEVICE_NOTIFY,
> proc_thermal_notify);
>  	int340x_thermal_zone_remove(proc_priv->int340x_zone);
> +	sysfs_remove_file(&proc_priv->dev->kobj,
> &dev_attr_tcc_offset_degree_celsius.attr);
>  	sysfs_remove_group(&proc_priv->dev->kobj,
>  			   &power_limit_attribute_group);
>  }
> @@ -355,8 +422,15 @@ static int int3401_add(struct platform_device
> *pdev)
>  
>  	dev_info(&pdev->dev, "Creating sysfs group for
> PROC_THERMAL_PLATFORM_DEV\n");
>  
> -	return sysfs_create_group(&pdev->dev.kobj,
> -					 &power_limit_attribute_group);
> +	ret = sysfs_create_file(&pdev->dev.kobj,
> &dev_attr_tcc_offset_degree_celsius.attr);
> +	if (ret)
> +		return ret;
> +
> +	ret = sysfs_create_group(&pdev->dev.kobj,
> &power_limit_attribute_group);
> +	if (ret)
> +		sysfs_remove_file(&pdev->dev.kobj,
> &dev_attr_tcc_offset_degree_celsius.attr);
> +
> +	return ret;
>  }
>  
>  static int int3401_remove(struct platform_device *pdev)
> @@ -584,8 +658,15 @@ static int  proc_thermal_pci_probe(struct
> pci_dev *pdev,
>  
>  	dev_info(&pdev->dev, "Creating sysfs group for
> PROC_THERMAL_PCI\n");
>  
> -	return sysfs_create_group(&pdev->dev.kobj,
> -					 &power_limit_attribute_group);
> +	ret = sysfs_create_file(&pdev->dev.kobj,
> &dev_attr_tcc_offset_degree_celsius.attr);
> +	if (ret)
> +		return ret;
> +
> +	ret = sysfs_create_group(&pdev->dev.kobj,
> &power_limit_attribute_group);
> +	if (ret)
> +		sysfs_remove_file(&pdev->dev.kobj,
> &dev_attr_tcc_offset_degree_celsius.attr);
> +
> +	return ret;
>  }
>  
>  static void  proc_thermal_pci_remove(struct pci_dev *pdev)
> @@ -611,6 +692,8 @@ static int proc_thermal_resume(struct device
> *dev)
>  	proc_dev = dev_get_drvdata(dev);
>  	proc_thermal_read_ppcc(proc_dev);
>  
> +	tcc_offset_update(tcc_offset_save);
> +
>  	return 0;
>  }
>  #else

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-07-24 19:52 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-23  1:03 [PATCH] drivers: thermal: processor_thermal_device: Export sysfs inteface for TCC offset Srinivas Pandruvada
2019-07-24 19:52 ` Benjamin Berg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).