lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <34f414e2dd4512a96a74f4748dca79b31ed1cb8b.camel@linux.intel.com>
Date:   Wed, 09 Dec 2020 08:15:28 -0800
From:   Srinivas Pandruvada <srinivas.pandruvada@...ux.intel.com>
To:     rui.zhang@...el.com, daniel.lezcano@...aro.org, amitk@...nel.org
Cc:     linux-kernel@...r.kernel.org, linux-pm@...r.kernel.org
Subject: Re: [PATCH 1/4] thermal: int340x: processor_thermal: Refactor MMIO
 interface

On Thu, 2020-11-26 at 09:18 -0800, Srinivas Pandruvada wrote:
> The Processor Thermal PCI device supports multiple features.
> Currently
> we export only RAPL. But we need more features from this device
> exposed
> for Tiger Lake and Alder Lake based platforms. So re-structure the
> current MMIO interface, so that more features can be added cleanly.
> 
> No functional changes are expected with this change.
> 
Any objection for this series for 5.11?

Thanks,
Srinivas

> Changes done in this patch:
> - Using PCI_DEVICE_DATA(), hence names of defines changed
> - Move RAPL MMIO code to its own module
> - Move the RAPL MMIO offsets to RAPL MMIO module
> - Adjust Kconfig dependency of PROC_THERMAL_MMIO_RAPL
> - Per processor driver data now contains the supported features
> - Moved all the common data structures and defines to a common header
>   file
> - This new header file contains all the processor_thermal_*
> interfaces
> - Based on the features supported the module interface is called
> - Each module atleast provides one add and one remove function
> 
> Signed-off-by: Srinivas Pandruvada <
> srinivas.pandruvada@...ux.intel.com>
> ---
>  drivers/thermal/intel/int340x_thermal/Kconfig |   6 +-
>  .../thermal/intel/int340x_thermal/Makefile    |   1 +
>  .../processor_thermal_device.c                | 261 ++++----------
> ----
>  .../processor_thermal_device.h                |  72 +++++
>  .../int340x_thermal/processor_thermal_rapl.c  | 134 +++++++++
>  5 files changed, 263 insertions(+), 211 deletions(-)
>  create mode 100644
> drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
>  create mode 100644
> drivers/thermal/intel/int340x_thermal/processor_thermal_rapl.c
> 
> diff --git a/drivers/thermal/intel/int340x_thermal/Kconfig
> b/drivers/thermal/intel/int340x_thermal/Kconfig
> index 797907542e43..45c31f3d6054 100644
> --- a/drivers/thermal/intel/int340x_thermal/Kconfig
> +++ b/drivers/thermal/intel/int340x_thermal/Kconfig
> @@ -10,6 +10,7 @@ config INT340X_THERMAL
>  	select ACPI_THERMAL_REL
>  	select ACPI_FAN
>  	select INTEL_SOC_DTS_IOSF_CORE
> +	select PROC_THERMAL_MMIO_RAPL if X86_64 && POWERCAP
>  	help
>  	  Newer laptops and tablets that use ACPI may have thermal
> sensors and
>  	  other devices with thermal control capabilities outside the
> core
> @@ -41,9 +42,6 @@ config INT3406_THERMAL
>  	  power consumed by display device.
>  
>  config PROC_THERMAL_MMIO_RAPL
> -	bool
> -	depends on 64BIT
> -	depends on POWERCAP
> +	tristate
>  	select INTEL_RAPL_CORE
> -	default y
>  endif
> diff --git a/drivers/thermal/intel/int340x_thermal/Makefile
> b/drivers/thermal/intel/int340x_thermal/Makefile
> index 287eb0a1476d..86e8d3c87df7 100644
> --- a/drivers/thermal/intel/int340x_thermal/Makefile
> +++ b/drivers/thermal/intel/int340x_thermal/Makefile
> @@ -4,5 +4,6 @@ obj-$(CONFIG_INT340X_THERMAL)	+=
> int340x_thermal_zone.o
>  obj-$(CONFIG_INT340X_THERMAL)	+= int3402_thermal.o
>  obj-$(CONFIG_INT340X_THERMAL)	+= int3403_thermal.o
>  obj-$(CONFIG_INT340X_THERMAL)	+= processor_thermal_device.o
> +obj-$(CONFIG_PROC_THERMAL_MMIO_RAPL) += processor_thermal_rapl.o
>  obj-$(CONFIG_INT3406_THERMAL)	+= int3406_thermal.o
>  obj-$(CONFIG_ACPI_THERMAL_REL)	+= acpi_thermal_rel.o
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
> index 81e8b15ef405..5b8dc5e9ec86 100644
> ---
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
> +++
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
> @@ -12,74 +12,18 @@
>  #include <linux/acpi.h>
>  #include <linux/thermal.h>
>  #include <linux/cpuhotplug.h>
> -#include <linux/intel_rapl.h>
>  #include "int340x_thermal_zone.h"
> +#include "processor_thermal_device.h"
>  #include "../intel_soc_dts_iosf.h"
>  
> -/* Broadwell-U/HSB thermal reporting device */
> -#define PCI_DEVICE_ID_PROC_BDW_THERMAL	0x1603
> -#define PCI_DEVICE_ID_PROC_HSB_THERMAL	0x0A03
> -
> -/* Skylake thermal reporting device */
> -#define PCI_DEVICE_ID_PROC_SKL_THERMAL	0x1903
> -
> -/* CannonLake thermal reporting device */
> -#define PCI_DEVICE_ID_PROC_CNL_THERMAL	0x5a03
> -#define PCI_DEVICE_ID_PROC_CFL_THERMAL	0x3E83
> -
> -/* Braswell thermal reporting device */
> -#define PCI_DEVICE_ID_PROC_BSW_THERMAL	0x22DC
> -
> -/* Broxton thermal reporting device */
> -#define PCI_DEVICE_ID_PROC_BXT0_THERMAL  0x0A8C
> -#define PCI_DEVICE_ID_PROC_BXT1_THERMAL  0x1A8C
> -#define PCI_DEVICE_ID_PROC_BXTX_THERMAL  0x4A8C
> -#define PCI_DEVICE_ID_PROC_BXTP_THERMAL  0x5A8C
> -
> -/* GeminiLake thermal reporting device */
> -#define PCI_DEVICE_ID_PROC_GLK_THERMAL	0x318C
> -
> -/* IceLake thermal reporting device */
> -#define PCI_DEVICE_ID_PROC_ICL_THERMAL	0x8a03
> -
> -/* JasperLake thermal reporting device */
> -#define PCI_DEVICE_ID_PROC_JSL_THERMAL	0x4E03
> -
> -/* TigerLake thermal reporting device */
> -#define PCI_DEVICE_ID_PROC_TGL_THERMAL	0x9A03
> -
>  #define DRV_NAME "proc_thermal"
>  
> -struct power_config {
> -	u32	index;
> -	u32	min_uw;
> -	u32	max_uw;
> -	u32	tmin_us;
> -	u32	tmax_us;
> -	u32	step_uw;
> -};
> -
> -struct proc_thermal_device {
> -	struct device *dev;
> -	struct acpi_device *adev;
> -	struct power_config power_limits[2];
> -	struct int34x_thermal_zone *int340x_zone;
> -	struct intel_soc_dts_sensors *soc_dts;
> -	void __iomem *mmio_base;
> -};
> -
>  enum proc_thermal_emum_mode_type {
>  	PROC_THERMAL_NONE,
>  	PROC_THERMAL_PCI,
>  	PROC_THERMAL_PLATFORM_DEV
>  };
>  
> -struct rapl_mmio_regs {
> -	u64 reg_unit;
> -	u64 regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX];
> -	int limits[RAPL_DOMAIN_MAX];
> -};
> -
>  /*
>   * We can have only one type of enumeration, PCI or Platform,
>   * not both. So we don't need instance specific data.
> @@ -461,84 +405,13 @@ static irqreturn_t proc_thermal_pci_msi_irq(int
> irq, void *devid)
>  	return IRQ_HANDLED;
>  }
>  
> -#ifdef CONFIG_PROC_THERMAL_MMIO_RAPL
> -
>  #define MCHBAR 0
>  
> -/* RAPL Support via MMIO interface */
> -static struct rapl_if_priv rapl_mmio_priv;
> -
> -static int rapl_mmio_cpu_online(unsigned int cpu)
> -{
> -	struct rapl_package *rp;
> -
> -	/* mmio rapl supports package 0 only for now */
> -	if (topology_physical_package_id(cpu))
> -		return 0;
> -
> -	rp = rapl_find_package_domain(cpu, &rapl_mmio_priv);
> -	if (!rp) {
> -		rp = rapl_add_package(cpu, &rapl_mmio_priv);
> -		if (IS_ERR(rp))
> -			return PTR_ERR(rp);
> -	}
> -	cpumask_set_cpu(cpu, &rp->cpumask);
> -	return 0;
> -}
> -
> -static int rapl_mmio_cpu_down_prep(unsigned int cpu)
> +static int proc_thermal_set_mmio_base(struct pci_dev *pdev,
> +				      struct proc_thermal_device
> *proc_priv)
>  {
> -	struct rapl_package *rp;
> -	int lead_cpu;
> -
> -	rp = rapl_find_package_domain(cpu, &rapl_mmio_priv);
> -	if (!rp)
> -		return 0;
> -
> -	cpumask_clear_cpu(cpu, &rp->cpumask);
> -	lead_cpu = cpumask_first(&rp->cpumask);
> -	if (lead_cpu >= nr_cpu_ids)
> -		rapl_remove_package(rp);
> -	else if (rp->lead_cpu == cpu)
> -		rp->lead_cpu = lead_cpu;
> -	return 0;
> -}
> -
> -static int rapl_mmio_read_raw(int cpu, struct reg_action *ra)
> -{
> -	if (!ra->reg)
> -		return -EINVAL;
> -
> -	ra->value = readq((void __iomem *)ra->reg);
> -	ra->value &= ra->mask;
> -	return 0;
> -}
> -
> -static int rapl_mmio_write_raw(int cpu, struct reg_action *ra)
> -{
> -	u64 val;
> -
> -	if (!ra->reg)
> -		return -EINVAL;
> -
> -	val = readq((void __iomem *)ra->reg);
> -	val &= ~ra->mask;
> -	val |= ra->value;
> -	writeq(val, (void __iomem *)ra->reg);
> -	return 0;
> -}
> -
> -static int proc_thermal_rapl_add(struct pci_dev *pdev,
> -				 struct proc_thermal_device *proc_priv,
> -				 struct rapl_mmio_regs *rapl_regs)
> -{
> -	enum rapl_domain_reg_id reg;
> -	enum rapl_domain_type domain;
>  	int ret;
>  
> -	if (!rapl_regs)
> -		return 0;
> -
>  	ret = pcim_iomap_regions(pdev, 1 << MCHBAR, DRV_NAME);
>  	if (ret) {
>  		dev_err(&pdev->dev, "cannot reserve PCI memory
> region\n");
> @@ -547,66 +420,42 @@ static int proc_thermal_rapl_add(struct pci_dev
> *pdev,
>  
>  	proc_priv->mmio_base = pcim_iomap_table(pdev)[MCHBAR];
>  
> -	for (domain = RAPL_DOMAIN_PACKAGE; domain < RAPL_DOMAIN_MAX;
> domain++) {
> -		for (reg = RAPL_DOMAIN_REG_LIMIT; reg <
> RAPL_DOMAIN_REG_MAX; reg++)
> -			if (rapl_regs->regs[domain][reg])
> -				rapl_mmio_priv.regs[domain][reg] =
> -						(u64)proc_priv-
> >mmio_base +
> -						rapl_regs-
> >regs[domain][reg];
> -		rapl_mmio_priv.limits[domain] = rapl_regs-
> >limits[domain];
> -	}
> -	rapl_mmio_priv.reg_unit = (u64)proc_priv->mmio_base +
> rapl_regs->reg_unit;
> +	return 0;
> +}
>  
> -	rapl_mmio_priv.read_raw = rapl_mmio_read_raw;
> -	rapl_mmio_priv.write_raw = rapl_mmio_write_raw;
> +static int proc_thermal_mmio_add(struct pci_dev *pdev,
> +				 struct proc_thermal_device *proc_priv,
> +				 kernel_ulong_t feature_mask)
> +{
> +	int ret;
>  
> -	rapl_mmio_priv.control_type =
> powercap_register_control_type(NULL, "intel-rapl-mmio", NULL);
> -	if (IS_ERR(rapl_mmio_priv.control_type)) {
> -		pr_debug("failed to register powercap
> control_type.\n");
> -		return PTR_ERR(rapl_mmio_priv.control_type);
> +	if (feature_mask) {
> +		ret = proc_thermal_set_mmio_base(pdev, proc_priv);
> +		if (ret)
> +			return ret;
>  	}
>  
> -	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
> "powercap/rapl:online",
> -				rapl_mmio_cpu_online,
> rapl_mmio_cpu_down_prep);
> -	if (ret < 0) {
> -		powercap_unregister_control_type(rapl_mmio_priv.control
> _type);
> -		rapl_mmio_priv.control_type = NULL;
> -		return ret;
> +	if (feature_mask & PROC_THERMAL_FEATURE_RAPL) {
> +		ret = proc_thermal_rapl_add(pdev, proc_priv);
> +		if (ret) {
> +			dev_err(&pdev->dev, "failed to add RAPL MMIO
> interface\n");
> +			return ret;
> +		}
>  	}
> -	rapl_mmio_priv.pcap_rapl_online = ret;
> +
> +	proc_priv->mmio_feature_mask = feature_mask;
>  
>  	return 0;
>  }
>  
> -static void proc_thermal_rapl_remove(void)
> +static void proc_thermal_mmio_remove(struct pci_dev *pdev)
>  {
> -	if (IS_ERR_OR_NULL(rapl_mmio_priv.control_type))
> -		return;
> -
> -	cpuhp_remove_state(rapl_mmio_priv.pcap_rapl_online);
> -	powercap_unregister_control_type(rapl_mmio_priv.control_type);
> -}
> +	struct proc_thermal_device *proc_priv = pci_get_drvdata(pdev);
>  
> -static const struct rapl_mmio_regs rapl_mmio_hsw = {
> -	.reg_unit = 0x5938,
> -	.regs[RAPL_DOMAIN_PACKAGE] = { 0x59a0, 0x593c, 0x58f0, 0,
> 0x5930},
> -	.regs[RAPL_DOMAIN_DRAM] = { 0x58e0, 0x58e8, 0x58ec, 0, 0},
> -	.limits[RAPL_DOMAIN_PACKAGE] = 2,
> -	.limits[RAPL_DOMAIN_DRAM] = 2,
> -};
> +	if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_RAPL)
> +		proc_thermal_rapl_remove();
>  
> -#else
> -
> -static int proc_thermal_rapl_add(struct pci_dev *pdev,
> -				 struct proc_thermal_device *proc_priv,
> -				 struct rapl_mmio_regs *rapl_regs)
> -{
> -	return 0;
>  }
> -static void proc_thermal_rapl_remove(void) {}
> -static const struct rapl_mmio_regs rapl_mmio_hsw;
> -
> -#endif /* CONFIG_MMIO_RAPL */
>  
>  static int  proc_thermal_pci_probe(struct pci_dev *pdev,
>  				   const struct pci_device_id *id)
> @@ -629,18 +478,10 @@ static int  proc_thermal_pci_probe(struct
> pci_dev *pdev,
>  	if (ret)
>  		return ret;
>  
> -	ret = proc_thermal_rapl_add(pdev, proc_priv,
> -				(struct rapl_mmio_regs *)id-
> >driver_data);
> -	if (ret) {
> -		dev_err(&pdev->dev, "failed to add RAPL MMIO
> interface\n");
> -		proc_thermal_remove(proc_priv);
> -		return ret;
> -	}
> -
>  	pci_set_drvdata(pdev, proc_priv);
>  	proc_thermal_emum_mode = PROC_THERMAL_PCI;
>  
> -	if (pdev->device == PCI_DEVICE_ID_PROC_BSW_THERMAL) {
> +	if (pdev->device == PCI_DEVICE_ID_INTEL_BSW_THERMAL) {
>  		/*
>  		 * Enumerate additional DTS sensors available via IOSF.
>  		 * But we are not treating as a failure condition, if
> @@ -676,10 +517,18 @@ static int  proc_thermal_pci_probe(struct
> pci_dev *pdev,
>  		return ret;
>  
>  	ret = sysfs_create_group(&pdev->dev.kobj,
> &power_limit_attribute_group);
> -	if (ret)
> +	if (ret) {
>  		sysfs_remove_file(&pdev->dev.kobj,
> &dev_attr_tcc_offset_degree_celsius.attr);
> +		return ret;
> +	}
>  
> -	return ret;
> +	ret = proc_thermal_mmio_add(pdev, proc_priv, id->driver_data);
> +	if (ret) {
> +		proc_thermal_remove(proc_priv);
> +		return ret;
> +	}
> +
> +	return 0;
>  }
>  
>  static void  proc_thermal_pci_remove(struct pci_dev *pdev)
> @@ -693,7 +542,8 @@ static void  proc_thermal_pci_remove(struct
> pci_dev *pdev)
>  			pci_disable_msi(pdev);
>  		}
>  	}
> -	proc_thermal_rapl_remove();
> +
> +	proc_thermal_mmio_remove(pdev);
>  	proc_thermal_remove(proc_priv);
>  }
>  
> @@ -716,24 +566,21 @@ static int proc_thermal_resume(struct device
> *dev)
>  static SIMPLE_DEV_PM_OPS(proc_thermal_pm, NULL,
> proc_thermal_resume);
>  
>  static const struct pci_device_id proc_thermal_pci_ids[] = {
> -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_PROC_BDW_THERMAL)},
> -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_PROC_HSB_THERMAL)},
> -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_PROC_SKL_THERMAL),
> -		.driver_data = (kernel_ulong_t)&rapl_mmio_hsw, },
> -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_PROC_BSW_THERMAL)},
> -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_PROC_BXT0_THERMAL)},
> -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_PROC_BXT1_THERMAL)},
> -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_PROC_BXTX_THERMAL)},
> -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_PROC_BXTP_THERMAL)},
> -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_PROC_CNL_THERMAL)},
> -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_PROC_CFL_THERMAL)},
> -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_PROC_GLK_THERMAL)},
> -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_PROC_ICL_THERMAL),
> -		.driver_data = (kernel_ulong_t)&rapl_mmio_hsw, },
> -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_PROC_JSL_THERMAL)},
> -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_PROC_TGL_THERMAL),
> -		.driver_data = (kernel_ulong_t)&rapl_mmio_hsw, },
> -	{ 0, },
> +	{ PCI_DEVICE_DATA(INTEL, BDW_THERMAL, 0) },
> +	{ PCI_DEVICE_DATA(INTEL, BSW_THERMAL, 0) },
> +	{ PCI_DEVICE_DATA(INTEL, BXT0_THERMAL, 0) },
> +	{ PCI_DEVICE_DATA(INTEL, BXT1_THERMAL, 0) },
> +	{ PCI_DEVICE_DATA(INTEL, BXTX_THERMAL, 0) },
> +	{ PCI_DEVICE_DATA(INTEL, BXTP_THERMAL, 0) },
> +	{ PCI_DEVICE_DATA(INTEL, CNL_THERMAL, 0) },
> +	{ PCI_DEVICE_DATA(INTEL, CFL_THERMAL, 0) },
> +	{ PCI_DEVICE_DATA(INTEL, GLK_THERMAL, 0) },
> +	{ PCI_DEVICE_DATA(INTEL, HSB_THERMAL, 0) },
> +	{ PCI_DEVICE_DATA(INTEL, ICL_THERMAL,
> PROC_THERMAL_FEATURE_RAPL) },
> +	{ PCI_DEVICE_DATA(INTEL, JSL_THERMAL, 0) },
> +	{ PCI_DEVICE_DATA(INTEL, SKL_THERMAL,
> PROC_THERMAL_FEATURE_RAPL) },
> +	{ PCI_DEVICE_DATA(INTEL, TGL_THERMAL,
> PROC_THERMAL_FEATURE_RAPL) },
> +	{ },
>  };
>  
>  MODULE_DEVICE_TABLE(pci, proc_thermal_pci_ids);
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> new file mode 100644
> index 000000000000..e20d142a55b4
> --- /dev/null
> +++
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> @@ -0,0 +1,72 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * processor_thermal_device.h
> + * Copyright (c) 2020, Intel Corporation.
> + */
> +
> +#ifndef __PROCESSOR_THERMAL_DEVICE_H__
> +#define __PROCESSOR_THERMAL_DEVICE_H__
> +
> +#include <linux/intel_rapl.h>
> +
> +#define PCI_DEVICE_ID_INTEL_BDW_THERMAL	0x1603
> +#define PCI_DEVICE_ID_INTEL_BSW_THERMAL	0x22DC
> +
> +#define PCI_DEVICE_ID_INTEL_BXT0_THERMAL	0x0A8C
> +#define PCI_DEVICE_ID_INTEL_BXT1_THERMAL	0x1A8C
> +#define PCI_DEVICE_ID_INTEL_BXTX_THERMAL	0x4A8C
> +#define PCI_DEVICE_ID_INTEL_BXTP_THERMAL	0x5A8C
> +
> +#define PCI_DEVICE_ID_INTEL_CNL_THERMAL	0x5a03
> +#define PCI_DEVICE_ID_INTEL_CFL_THERMAL	0x3E83
> +#define PCI_DEVICE_ID_INTEL_GLK_THERMAL	0x318C
> +#define PCI_DEVICE_ID_INTEL_HSB_THERMAL	0x0A03
> +#define PCI_DEVICE_ID_INTEL_ICL_THERMAL	0x8a03
> +#define PCI_DEVICE_ID_INTEL_JSL_THERMAL	0x4E03
> +#define PCI_DEVICE_ID_INTEL_SKL_THERMAL	0x1903
> +#define PCI_DEVICE_ID_INTEL_TGL_THERMAL	0x9A03
> +
> +struct power_config {
> +	u32	index;
> +	u32	min_uw;
> +	u32	max_uw;
> +	u32	tmin_us;
> +	u32	tmax_us;
> +	u32	step_uw;
> +};
> +
> +struct proc_thermal_device {
> +	struct device *dev;
> +	struct acpi_device *adev;
> +	struct power_config power_limits[2];
> +	struct int34x_thermal_zone *int340x_zone;
> +	struct intel_soc_dts_sensors *soc_dts;
> +	u32 mmio_feature_mask;
> +	void __iomem *mmio_base;
> +};
> +
> +struct rapl_mmio_regs {
> +	u64 reg_unit;
> +	u64 regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX];
> +	int limits[RAPL_DOMAIN_MAX];
> +};
> +
> +#define PROC_THERMAL_FEATURE_NONE	0x00
> +#define PROC_THERMAL_FEATURE_RAPL	0x01
> +
> +#if IS_ENABLED(CONFIG_PROC_THERMAL_MMIO_RAPL)
> +int proc_thermal_rapl_add(struct pci_dev *pdev, struct
> proc_thermal_device *proc_priv);
> +void proc_thermal_rapl_remove(void);
> +#else
> +static int __maybe_unused proc_thermal_rapl_add(struct pci_dev
> *pdev,
> +						struct
> proc_thermal_device *proc_priv)
> +{
> +	return 0;
> +}
> +
> +static void __maybe_unused proc_thermal_rapl_remove(void)
> +{
> +}
> +#endif
> +
> +#endif
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_rapl.c
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_rapl.c
> new file mode 100644
> index 000000000000..a205221ec8df
> --- /dev/null
> +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_rapl.c
> @@ -0,0 +1,134 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * processor thermal device RFIM control
> + * Copyright (c) 2020, Intel Corporation.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/pci.h>
> +#include "processor_thermal_device.h"
> +
> +static struct rapl_if_priv rapl_mmio_priv;
> +
> +static const struct rapl_mmio_regs rapl_mmio_default = {
> +	.reg_unit = 0x5938,
> +	.regs[RAPL_DOMAIN_PACKAGE] = { 0x59a0, 0x593c, 0x58f0, 0,
> 0x5930},
> +	.regs[RAPL_DOMAIN_DRAM] = { 0x58e0, 0x58e8, 0x58ec, 0, 0},
> +	.limits[RAPL_DOMAIN_PACKAGE] = 2,
> +	.limits[RAPL_DOMAIN_DRAM] = 2,
> +};
> +
> +static int rapl_mmio_cpu_online(unsigned int cpu)
> +{
> +	struct rapl_package *rp;
> +
> +	/* mmio rapl supports package 0 only for now */
> +	if (topology_physical_package_id(cpu))
> +		return 0;
> +
> +	rp = rapl_find_package_domain(cpu, &rapl_mmio_priv);
> +	if (!rp) {
> +		rp = rapl_add_package(cpu, &rapl_mmio_priv);
> +		if (IS_ERR(rp))
> +			return PTR_ERR(rp);
> +	}
> +	cpumask_set_cpu(cpu, &rp->cpumask);
> +	return 0;
> +}
> +
> +static int rapl_mmio_cpu_down_prep(unsigned int cpu)
> +{
> +	struct rapl_package *rp;
> +	int lead_cpu;
> +
> +	rp = rapl_find_package_domain(cpu, &rapl_mmio_priv);
> +	if (!rp)
> +		return 0;
> +
> +	cpumask_clear_cpu(cpu, &rp->cpumask);
> +	lead_cpu = cpumask_first(&rp->cpumask);
> +	if (lead_cpu >= nr_cpu_ids)
> +		rapl_remove_package(rp);
> +	else if (rp->lead_cpu == cpu)
> +		rp->lead_cpu = lead_cpu;
> +	return 0;
> +}
> +
> +static int rapl_mmio_read_raw(int cpu, struct reg_action *ra)
> +{
> +	if (!ra->reg)
> +		return -EINVAL;
> +
> +	ra->value = readq((void __iomem *)ra->reg);
> +	ra->value &= ra->mask;
> +	return 0;
> +}
> +
> +static int rapl_mmio_write_raw(int cpu, struct reg_action *ra)
> +{
> +	u64 val;
> +
> +	if (!ra->reg)
> +		return -EINVAL;
> +
> +	val = readq((void __iomem *)ra->reg);
> +	val &= ~ra->mask;
> +	val |= ra->value;
> +	writeq(val, (void __iomem *)ra->reg);
> +	return 0;
> +}
> +
> +int proc_thermal_rapl_add(struct pci_dev *pdev, struct
> proc_thermal_device *proc_priv)
> +{
> +	const struct rapl_mmio_regs *rapl_regs = &rapl_mmio_default;
> +	enum rapl_domain_reg_id reg;
> +	enum rapl_domain_type domain;
> +	int ret;
> +
> +	if (!rapl_regs)
> +		return 0;
> +
> +	for (domain = RAPL_DOMAIN_PACKAGE; domain < RAPL_DOMAIN_MAX;
> domain++) {
> +		for (reg = RAPL_DOMAIN_REG_LIMIT; reg <
> RAPL_DOMAIN_REG_MAX; reg++)
> +			if (rapl_regs->regs[domain][reg])
> +				rapl_mmio_priv.regs[domain][reg] =
> +						(u64)proc_priv-
> >mmio_base +
> +						rapl_regs-
> >regs[domain][reg];
> +		rapl_mmio_priv.limits[domain] = rapl_regs-
> >limits[domain];
> +	}
> +	rapl_mmio_priv.reg_unit = (u64)proc_priv->mmio_base +
> rapl_regs->reg_unit;
> +
> +	rapl_mmio_priv.read_raw = rapl_mmio_read_raw;
> +	rapl_mmio_priv.write_raw = rapl_mmio_write_raw;
> +
> +	rapl_mmio_priv.control_type =
> powercap_register_control_type(NULL, "intel-rapl-mmio", NULL);
> +	if (IS_ERR(rapl_mmio_priv.control_type)) {
> +		pr_debug("failed to register powercap
> control_type.\n");
> +		return PTR_ERR(rapl_mmio_priv.control_type);
> +	}
> +
> +	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
> "powercap/rapl:online",
> +				rapl_mmio_cpu_online,
> rapl_mmio_cpu_down_prep);
> +	if (ret < 0) {
> +		powercap_unregister_control_type(rapl_mmio_priv.control
> _type);
> +		rapl_mmio_priv.control_type = NULL;
> +		return ret;
> +	}
> +	rapl_mmio_priv.pcap_rapl_online = ret;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(proc_thermal_rapl_add);
> +
> +void proc_thermal_rapl_remove(void)
> +{
> +	if (IS_ERR_OR_NULL(rapl_mmio_priv.control_type))
> +		return;
> +
> +	cpuhp_remove_state(rapl_mmio_priv.pcap_rapl_online);
> +	powercap_unregister_control_type(rapl_mmio_priv.control_type);
> +}
> +EXPORT_SYMBOL_GPL(proc_thermal_rapl_remove);
> +
> +MODULE_LICENSE("GPL v2");

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ