mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'thermal-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull thermal control updates from Rafael Wysocki:
"These are mostly thermal driver updates, including new thermal drivers
for Renesas RZ/G3S and Renesas RZ/G3E SoCs, a new power slider
platform feature support in the Intel int340x thermal driver, a new
Tegra114- specific SOCTHERM driver and more.
There is also a Step-wise thermal governor update allowing it to start
reducing cooling somewhat earlier if the temperature of the given
thermal zone is falling down and a thermal testing code cleanup.
Specifics:
- Add new thermal driver for the Renesas RZ/G3S SoC (Claudiu Beznea)
- Add new thermal driver for the Renesas RZ/G3E SoC (John Madieu)
- Add support for new platform power slider feature to the Intel
int340x driver (Srinivas Pandruvada).
- Add new Tegra114-specific SOCTHERM driver and document Tegra114
SOCTHERM Thermal Management System in DT bindings (Svyatoslav
Ryhel)
- Add temperature sensor channel to thermal-generic-adc (Svyatoslav
Ryhel)
- Add support for per-SoC default trim values to the Renesas
rcar_gen3 thermal driver, use it for adding R-Car V4H default trim
values, fix a comment typo in that driver and document Gen4 support
in its Kconfig entry (Marek Vasut)
- Fix mapping SoCs to generic Gen4 entry in the Renesas rcar_gen3
thermal driver (Wolfram Sang)
- Document the TSU unit in the r9a08g045-tsu and r9a09g047-tsu DT
bindings (Claudiu Beznea, John Madieu)
- Make LMH select QCOM_SCM and add missing IRQ includes to the
qcom/lmh thermal driver (Dmitry Baryshkov)
- Fix incorrect error message in the qcom/lmh thermal driver (Sumeet
Pawnikar)
- Add QCS615 compatible to tsens thermal DT bindings (Gaurav Kohli)
- Document the Glymur temperature sensor in qcom-tsens thermal DT
bindings (Manaf Meethalavalappu Pallikunhi)
- Make k3_j72xx_bandgap thermal driver register the thermal sensor
with hwmon (Michael Walle)
- Tighten GRF requirements in the rockchip thermal DT bindings,
silence a GRF warning in the rockchip thermal driver and unify
struct rockchip_tsadc_chip format in it (Sebastian Reichel)
- Update the Step-wise thermal governor to allow it to reduce the
cooling level earlier if thermal zone temperature is dropping and
clean it up (Rafael Wysocki)
- Clean up the thermal testing code (Rafael Wysocki)
- Assorted cleanups of thermal drivers (Jiapeng Chong, Salah Triki,
Osama Abdelkader)"
* tag 'thermal-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (37 commits)
thermal/drivers/renesas/rzg3e: Fix add thermal driver for the Renesas RZ/G3E SoC
dt-bindings: thermal: qcom-tsens: Document the Glymur temperature Sensor
thermal/drivers/renesas/rzg3e: Add thermal driver for the Renesas RZ/G3E SoC
dt-bindings: thermal: r9a09g047-tsu: Document the TSU unit
thermal/drivers/thermal-generic-adc: Add temperature sensor channel
dt-bindings: thermal: rockchip: Tighten grf requirements
thermal/drivers/rockchip: Shut up GRF warning
thermal/drivers/rockchip: Unify struct rockchip_tsadc_chip format
thermal/drivers/renesas/rzg3s: Add thermal driver for the Renesas RZ/G3S SoC
dt-bindings: thermal: r9a08g045-tsu: Document the TSU unit
thermal/drivers/k3_j72xx_bandgap: Register sensors with hwmon
thermal/drivers/rcar_gen3: Fix mapping SoCs to generic Gen4 entry
thermal/drivers/tegra: Add Tegra114 specific SOCTHERM driver
dt-bindings: thermal: add Tegra114 soctherm header
thermal/drivers/tegra/soctherm-fuse: Prepare calibration for Tegra114 support
dt-bindings: thermal: Document Tegra114 SOCTHERM Thermal Management System
thermal/drivers/rcar_gen3: Document Gen4 support in Kconfig entry
thermal/drivers/rcar_gen3: Fix comment typo
drivers/thermal/qcom/lmh: Fix incorrect error message
thermal/drivers/qcom/lmh: Add missing IRQ includes
...
This commit is contained in:
@@ -18,6 +18,7 @@ description: The SOCTHERM IP block contains thermal sensors, support for
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra114-soctherm
|
||||
- nvidia,tegra124-soctherm
|
||||
- nvidia,tegra132-soctherm
|
||||
- nvidia,tegra210-soctherm
|
||||
@@ -206,6 +207,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- nvidia,tegra114-soctherm
|
||||
- nvidia,tegra124-soctherm
|
||||
- nvidia,tegra210-soctherm
|
||||
- nvidia,tegra210b01-soctherm
|
||||
|
||||
@@ -49,11 +49,13 @@ properties:
|
||||
- description: v2 of TSENS
|
||||
items:
|
||||
- enum:
|
||||
- qcom,glymur-tsens
|
||||
- qcom,milos-tsens
|
||||
- qcom,msm8953-tsens
|
||||
- qcom,msm8996-tsens
|
||||
- qcom,msm8998-tsens
|
||||
- qcom,qcm2290-tsens
|
||||
- qcom,qcs615-tsens
|
||||
- qcom,sa8255p-tsens
|
||||
- qcom,sa8775p-tsens
|
||||
- qcom,sar2130p-tsens
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/thermal/renesas,r9a08g045-tsu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas RZ/G3S Thermal Sensor Unit
|
||||
|
||||
description:
|
||||
The thermal sensor unit (TSU) measures the temperature(Tj) inside
|
||||
the LSI.
|
||||
|
||||
maintainers:
|
||||
- Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
|
||||
|
||||
$ref: thermal-sensor.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: renesas,r9a08g045-tsu
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: TSU module clock
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: TSU module reset
|
||||
|
||||
io-channels:
|
||||
items:
|
||||
- description: ADC channel which reports the TSU temperature
|
||||
|
||||
io-channel-names:
|
||||
items:
|
||||
- const: tsu
|
||||
|
||||
"#thermal-sensor-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- power-domains
|
||||
- resets
|
||||
- io-channels
|
||||
- io-channel-names
|
||||
- '#thermal-sensor-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/r9a08g045-cpg.h>
|
||||
|
||||
tsu: thermal@10059000 {
|
||||
compatible = "renesas,r9a08g045-tsu";
|
||||
reg = <0x10059000 0x1000>;
|
||||
clocks = <&cpg CPG_MOD R9A08G045_TSU_PCLK>;
|
||||
resets = <&cpg R9A08G045_TSU_PRESETN>;
|
||||
power-domains = <&cpg>;
|
||||
#thermal-sensor-cells = <0>;
|
||||
io-channels = <&adc 8>;
|
||||
io-channel-names = "tsu";
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
cpu-thermal {
|
||||
polling-delay-passive = <250>;
|
||||
polling-delay = <1000>;
|
||||
thermal-sensors = <&tsu>;
|
||||
|
||||
trips {
|
||||
sensor_crit: sensor-crit {
|
||||
temperature = <125000>;
|
||||
hysteresis = <1000>;
|
||||
type = "critical";
|
||||
};
|
||||
target: trip-point {
|
||||
temperature = <100000>;
|
||||
hysteresis = <1000>;
|
||||
type = "passive";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/thermal/renesas,r9a09g047-tsu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas RZ/G3E Temperature Sensor Unit (TSU)
|
||||
|
||||
maintainers:
|
||||
- John Madieu <john.madieu.xa@bp.renesas.com>
|
||||
|
||||
description:
|
||||
The Temperature Sensor Unit (TSU) is an integrated thermal sensor that
|
||||
monitors the chip temperature on the Renesas RZ/G3E SoC. The TSU provides
|
||||
real-time temperature measurements for thermal management.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: renesas,r9a09g047-tsu
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: Conversion complete interrupt signal (pulse)
|
||||
- description: Comparison result interrupt signal (level)
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: adi
|
||||
- const: adcmpi
|
||||
|
||||
"#thermal-sensor-cells":
|
||||
const: 0
|
||||
|
||||
renesas,tsu-trim:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
items:
|
||||
- items:
|
||||
- description: phandle to system controller
|
||||
- description: offset of trim registers
|
||||
description:
|
||||
Phandle and offset to the system controller containing the TSU
|
||||
calibration trim values. The offset points to the first trim register
|
||||
(OTPTSU1TRMVAL0), with the second trim register (OTPTSU1TRMVAL1) located
|
||||
at offset + 4.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- resets
|
||||
- power-domains
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- "#thermal-sensor-cells"
|
||||
- renesas,tsu-trim
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/renesas,r9a09g047-cpg.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
thermal-sensor@14002000 {
|
||||
compatible = "renesas,r9a09g047-tsu";
|
||||
reg = <0x14002000 0x1000>;
|
||||
clocks = <&cpg CPG_MOD 0x10a>;
|
||||
resets = <&cpg 0xf8>;
|
||||
power-domains = <&cpg>;
|
||||
interrupts = <GIC_SPI 250 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "adi", "adcmpi";
|
||||
#thermal-sensor-cells = <0>;
|
||||
renesas,tsu-trim = <&sys 0x330>;
|
||||
};
|
||||
@@ -119,6 +119,21 @@ required:
|
||||
- resets
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- rockchip,px30-tsadc
|
||||
- rockchip,rk3366-tsadc
|
||||
- rockchip,rk3399-tsadc
|
||||
- rockchip,rk3568-tsadc
|
||||
then:
|
||||
required:
|
||||
- rockchip,grf
|
||||
else:
|
||||
properties:
|
||||
rockchip,grf: false
|
||||
- if:
|
||||
not:
|
||||
properties:
|
||||
|
||||
+14
@@ -21701,6 +21701,20 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/iio/potentiometer/renesas,x9250.yaml
|
||||
F: drivers/iio/potentiometer/x9250.c
|
||||
|
||||
RENESAS RZ/G3S THERMAL SENSOR UNIT DRIVER
|
||||
M: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/thermal/renesas,r9a08g045-tsu.yaml
|
||||
F: drivers/thermal/renesas/rzg3s_thermal.c
|
||||
|
||||
RENESAS RZ/G3E THERMAL SENSOR UNIT DRIVER
|
||||
M: John Madieu <john.madieu.xa@bp.renesas.com>
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/thermal/renesas,r9a09g047-tsu.yaml
|
||||
F: drivers/thermal/renesas/rzg3e_thermal.c
|
||||
|
||||
RESET CONTROLLER FRAMEWORK
|
||||
M: Philipp Zabel <p.zabel@pengutronix.de>
|
||||
S: Maintained
|
||||
|
||||
@@ -20,11 +20,13 @@
|
||||
* If the temperature is higher than a trip point,
|
||||
* a. if the trend is THERMAL_TREND_RAISING, use higher cooling
|
||||
* state for this trip point
|
||||
* b. if the trend is THERMAL_TREND_DROPPING, do nothing
|
||||
* b. if the trend is THERMAL_TREND_DROPPING, use a lower cooling state
|
||||
* for this trip point, but keep the cooling state above the applicable
|
||||
* minimum
|
||||
* If the temperature is lower than a trip point,
|
||||
* a. if the trend is THERMAL_TREND_RAISING, do nothing
|
||||
* b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
|
||||
* state for this trip point, if the cooling state already
|
||||
* b. if the trend is THERMAL_TREND_DROPPING, use the minimum applicable
|
||||
* cooling state for this trip point, or if the cooling state already
|
||||
* equals lower limit, deactivate the thermal instance
|
||||
*/
|
||||
static unsigned long get_target_state(struct thermal_instance *instance,
|
||||
@@ -51,6 +53,17 @@ static unsigned long get_target_state(struct thermal_instance *instance,
|
||||
if (throttle) {
|
||||
if (trend == THERMAL_TREND_RAISING)
|
||||
return clamp(cur_state + 1, instance->lower, instance->upper);
|
||||
|
||||
/*
|
||||
* If the zone temperature is falling, the cooling level can
|
||||
* be reduced, but it should still be above the lower state of
|
||||
* the given thermal instance to pull the temperature further
|
||||
* down.
|
||||
*/
|
||||
if (trend == THERMAL_TREND_DROPPING)
|
||||
return clamp(cur_state - 1,
|
||||
min(instance->lower + 1, instance->upper),
|
||||
instance->upper);
|
||||
} else if (trend == THERMAL_TREND_DROPPING) {
|
||||
if (cur_state <= instance->lower)
|
||||
return THERMAL_NO_TARGET;
|
||||
@@ -69,16 +82,14 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip_desc *td,
|
||||
int trip_threshold)
|
||||
{
|
||||
bool throttle = tz->temperature >= trip_threshold;
|
||||
const struct thermal_trip *trip = &td->trip;
|
||||
enum thermal_trend trend = get_tz_trend(tz, trip);
|
||||
int trip_id = thermal_zone_trip_id(tz, trip);
|
||||
struct thermal_instance *instance;
|
||||
bool throttle = false;
|
||||
|
||||
if (tz->temperature >= trip_threshold) {
|
||||
throttle = true;
|
||||
if (throttle)
|
||||
trace_thermal_zone_trip(tz, trip_id, trip->type);
|
||||
}
|
||||
|
||||
dev_dbg(&tz->device, "Trip%d[type=%d,temp=%d]:trend=%d,throttle=%d\n",
|
||||
trip_id, trip->type, trip_threshold, trend, throttle);
|
||||
|
||||
@@ -12,6 +12,7 @@ config INT340X_THERMAL
|
||||
select ACPI_THERMAL_LIB
|
||||
select INTEL_SOC_DTS_IOSF_CORE
|
||||
select INTEL_TCC
|
||||
select ACPI_PLATFORM_PROFILE
|
||||
select PROC_THERMAL_MMIO_RAPL if POWERCAP
|
||||
help
|
||||
Newer laptops and tablets that use ACPI may have thermal sensors and
|
||||
|
||||
@@ -14,5 +14,6 @@ obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_mbox.o
|
||||
obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_wt_req.o
|
||||
obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_wt_hint.o
|
||||
obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_power_floor.o
|
||||
obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_soc_slider.o
|
||||
obj-$(CONFIG_INT3406_THERMAL) += int3406_thermal.o
|
||||
obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o
|
||||
|
||||
@@ -220,9 +220,6 @@ static int acpi_parse_psvt(acpi_handle handle, int *psvt_count, struct psvt **ps
|
||||
int i, result = 0;
|
||||
struct psvt *psvts;
|
||||
|
||||
if (!acpi_has_method(handle, "PSVT"))
|
||||
return -ENODEV;
|
||||
|
||||
status = acpi_evaluate_object(handle, "PSVT", NULL, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
@@ -338,10 +338,17 @@ static int tcc_offset_save = -1;
|
||||
|
||||
int proc_thermal_suspend(struct device *dev)
|
||||
{
|
||||
struct proc_thermal_device *proc_dev;
|
||||
|
||||
tcc_offset_save = intel_tcc_get_offset(-1);
|
||||
if (tcc_offset_save < 0)
|
||||
dev_warn(dev, "failed to save offset (%d)\n", tcc_offset_save);
|
||||
|
||||
proc_dev = dev_get_drvdata(dev);
|
||||
|
||||
if (proc_dev->mmio_feature_mask & PROC_THERMAL_FEATURE_SOC_POWER_SLIDER)
|
||||
proc_thermal_soc_power_slider_suspend(proc_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(proc_thermal_suspend);
|
||||
@@ -357,6 +364,9 @@ int proc_thermal_resume(struct device *dev)
|
||||
if (tcc_offset_save >= 0)
|
||||
intel_tcc_set_offset(-1, tcc_offset_save);
|
||||
|
||||
if (proc_dev->mmio_feature_mask & PROC_THERMAL_FEATURE_SOC_POWER_SLIDER)
|
||||
proc_thermal_soc_power_slider_resume(proc_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(proc_thermal_resume);
|
||||
@@ -432,8 +442,18 @@ int proc_thermal_mmio_add(struct pci_dev *pdev,
|
||||
}
|
||||
}
|
||||
|
||||
if (feature_mask & PROC_THERMAL_FEATURE_SOC_POWER_SLIDER) {
|
||||
ret = proc_thermal_soc_power_slider_add(pdev, proc_priv);
|
||||
if (ret) {
|
||||
dev_info(&pdev->dev, "failed to add soc power efficiency slider\n");
|
||||
goto err_rem_wlt;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_rem_wlt:
|
||||
proc_thermal_wt_hint_remove(pdev);
|
||||
err_rem_rfim:
|
||||
proc_thermal_rfim_remove(pdev);
|
||||
err_rem_ptc:
|
||||
|
||||
@@ -69,6 +69,7 @@ struct rapl_mmio_regs {
|
||||
#define PROC_THERMAL_FEATURE_POWER_FLOOR 0x40
|
||||
#define PROC_THERMAL_FEATURE_MSI_SUPPORT 0x80
|
||||
#define PROC_THERMAL_FEATURE_PTC 0x100
|
||||
#define PROC_THERMAL_FEATURE_SOC_POWER_SLIDER 0x200
|
||||
|
||||
#if IS_ENABLED(CONFIG_PROC_THERMAL_MMIO_RAPL)
|
||||
int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
|
||||
@@ -127,4 +128,9 @@ int proc_thermal_mmio_add(struct pci_dev *pdev,
|
||||
void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
|
||||
int proc_thermal_ptc_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
|
||||
void proc_thermal_ptc_remove(struct pci_dev *pdev);
|
||||
|
||||
int proc_thermal_soc_power_slider_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
|
||||
void proc_thermal_soc_power_slider_suspend(struct proc_thermal_device *proc_priv);
|
||||
void proc_thermal_soc_power_slider_resume(struct proc_thermal_device *proc_priv);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -498,7 +498,8 @@ static const struct pci_device_id proc_thermal_pci_ids[] = {
|
||||
{ PCI_DEVICE_DATA(INTEL, PTL_THERMAL, PROC_THERMAL_FEATURE_RAPL |
|
||||
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) },
|
||||
PROC_THERMAL_FEATURE_POWER_FLOOR | PROC_THERMAL_FEATURE_PTC |
|
||||
PROC_THERMAL_FEATURE_SOC_POWER_SLIDER) },
|
||||
{ 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 |
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Processor Thermal Device Interface for Reading and Writing
|
||||
* SoC Power Slider Values from User Space.
|
||||
*
|
||||
* Operation:
|
||||
* The SOC_EFFICIENCY_SLIDER_0_0_0_MCHBAR register is accessed
|
||||
* using the MMIO (Memory-Mapped I/O) interface with an MMIO offset of 0x5B38.
|
||||
* Although this register is 64 bits wide, only bits 7:0 are used,
|
||||
* and the other bits remain unchanged.
|
||||
*
|
||||
* Bit definitions
|
||||
*
|
||||
* Bits 2:0 (Slider value):
|
||||
* The SoC optimizer slider value indicates the system wide energy performance
|
||||
* hint. The slider has no specific units and ranges from 0 (highest
|
||||
* performance) to 6 (highest energy efficiency). Value of 7 is reserved.
|
||||
* Bits 3 : Reserved
|
||||
* Bits 6:4 (Offset)
|
||||
* Offset allows the SoC to automatically switch slider position in range
|
||||
* [slider value (bits 2:0) + offset] to improve power efficiency based on
|
||||
* internal SoC algorithms.
|
||||
* Bit 7 (Enable):
|
||||
* If this bit is set, the SoC Optimization sliders will be processed by the
|
||||
* SoC firmware.
|
||||
*
|
||||
* Copyright (c) 2025, Intel Corporation.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_profile.h>
|
||||
#include "processor_thermal_device.h"
|
||||
|
||||
#define SOC_POWER_SLIDER_OFFSET 0x5B38
|
||||
|
||||
enum power_slider_preference {
|
||||
SOC_POWER_SLIDER_PERFORMANCE,
|
||||
SOC_POWER_SLIDER_BALANCE,
|
||||
SOC_POWER_SLIDER_POWERSAVE,
|
||||
};
|
||||
|
||||
#define SOC_SLIDER_VALUE_MINIMUM 0x00
|
||||
#define SOC_SLIDER_VALUE_BALANCE 0x03
|
||||
#define SOC_SLIDER_VALUE_MAXIMUM 0x06
|
||||
|
||||
#define SLIDER_MASK GENMASK_ULL(2, 0)
|
||||
#define SLIDER_ENABLE_BIT 7
|
||||
|
||||
static u8 slider_values[] = {
|
||||
[SOC_POWER_SLIDER_PERFORMANCE] = SOC_SLIDER_VALUE_MINIMUM,
|
||||
[SOC_POWER_SLIDER_BALANCE] = SOC_SLIDER_VALUE_BALANCE,
|
||||
[SOC_POWER_SLIDER_POWERSAVE] = SOC_SLIDER_VALUE_MAXIMUM,
|
||||
};
|
||||
|
||||
/* Lock to protect module param updates */
|
||||
static DEFINE_MUTEX(slider_param_lock);
|
||||
|
||||
static int slider_balanced_param = SOC_SLIDER_VALUE_BALANCE;
|
||||
|
||||
static int slider_def_balance_set(const char *arg, const struct kernel_param *kp)
|
||||
{
|
||||
u8 slider_val;
|
||||
int ret;
|
||||
|
||||
guard(mutex)(&slider_param_lock);
|
||||
|
||||
ret = kstrtou8(arg, 16, &slider_val);
|
||||
if (!ret) {
|
||||
if (slider_val <= slider_values[SOC_POWER_SLIDER_PERFORMANCE] ||
|
||||
slider_val >= slider_values[SOC_POWER_SLIDER_POWERSAVE])
|
||||
return -EINVAL;
|
||||
|
||||
slider_balanced_param = slider_val;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int slider_def_balance_get(char *buf, const struct kernel_param *kp)
|
||||
{
|
||||
guard(mutex)(&slider_param_lock);
|
||||
return sysfs_emit(buf, "%02x\n", slider_values[SOC_POWER_SLIDER_BALANCE]);
|
||||
}
|
||||
|
||||
static const struct kernel_param_ops slider_def_balance_ops = {
|
||||
.set = slider_def_balance_set,
|
||||
.get = slider_def_balance_get,
|
||||
};
|
||||
|
||||
module_param_cb(slider_balance, &slider_def_balance_ops, NULL, 0644);
|
||||
MODULE_PARM_DESC(slider_balance, "Set slider default value for balance");
|
||||
|
||||
static u8 slider_offset;
|
||||
|
||||
static int slider_def_offset_set(const char *arg, const struct kernel_param *kp)
|
||||
{
|
||||
u8 offset;
|
||||
int ret;
|
||||
|
||||
guard(mutex)(&slider_param_lock);
|
||||
|
||||
ret = kstrtou8(arg, 16, &offset);
|
||||
if (!ret) {
|
||||
if (offset > SOC_SLIDER_VALUE_MAXIMUM)
|
||||
return -EINVAL;
|
||||
|
||||
slider_offset = offset;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int slider_def_offset_get(char *buf, const struct kernel_param *kp)
|
||||
{
|
||||
guard(mutex)(&slider_param_lock);
|
||||
return sysfs_emit(buf, "%02x\n", slider_offset);
|
||||
}
|
||||
|
||||
static const struct kernel_param_ops slider_offset_ops = {
|
||||
.set = slider_def_offset_set,
|
||||
.get = slider_def_offset_get,
|
||||
};
|
||||
|
||||
/*
|
||||
* To enhance power efficiency dynamically, the firmware can optionally
|
||||
* auto-adjust the slider value based on the current workload. This
|
||||
* adjustment is controlled by the "slider_offset" module parameter.
|
||||
* This offset permits the firmware to increase the slider value
|
||||
* up to and including "SoC slider + slider offset,".
|
||||
*/
|
||||
module_param_cb(slider_offset, &slider_offset_ops, NULL, 0644);
|
||||
MODULE_PARM_DESC(slider_offset, "Set slider offset");
|
||||
|
||||
/* Convert from platform power profile option to SoC slider value */
|
||||
static int convert_profile_to_power_slider(enum platform_profile_option profile)
|
||||
{
|
||||
switch (profile) {
|
||||
case PLATFORM_PROFILE_LOW_POWER:
|
||||
return slider_values[SOC_POWER_SLIDER_POWERSAVE];
|
||||
case PLATFORM_PROFILE_BALANCED:
|
||||
return slider_values[SOC_POWER_SLIDER_BALANCE];
|
||||
case PLATFORM_PROFILE_PERFORMANCE:
|
||||
return slider_values[SOC_POWER_SLIDER_PERFORMANCE];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* Convert to platform power profile option from SoC slider values */
|
||||
static int convert_power_slider_to_profile(u8 slider)
|
||||
{
|
||||
if (slider == slider_values[SOC_POWER_SLIDER_PERFORMANCE])
|
||||
return PLATFORM_PROFILE_PERFORMANCE;
|
||||
if (slider == slider_values[SOC_POWER_SLIDER_BALANCE])
|
||||
return PLATFORM_PROFILE_BALANCED;
|
||||
if (slider == slider_values[SOC_POWER_SLIDER_POWERSAVE])
|
||||
return PLATFORM_PROFILE_LOW_POWER;
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline u64 read_soc_slider(struct proc_thermal_device *proc_priv)
|
||||
{
|
||||
return readq(proc_priv->mmio_base + SOC_POWER_SLIDER_OFFSET);
|
||||
}
|
||||
|
||||
static inline void write_soc_slider(struct proc_thermal_device *proc_priv, u64 val)
|
||||
{
|
||||
writeq(val, proc_priv->mmio_base + SOC_POWER_SLIDER_OFFSET);
|
||||
}
|
||||
|
||||
#define SLIDER_OFFSET_MASK GENMASK_ULL(6, 4)
|
||||
|
||||
static void set_soc_power_profile(struct proc_thermal_device *proc_priv, int slider)
|
||||
{
|
||||
u64 val;
|
||||
|
||||
val = read_soc_slider(proc_priv);
|
||||
val &= ~SLIDER_MASK;
|
||||
val |= FIELD_PREP(SLIDER_MASK, slider) | BIT(SLIDER_ENABLE_BIT);
|
||||
|
||||
/* Set the slider offset from module params */
|
||||
val &= ~SLIDER_OFFSET_MASK;
|
||||
val |= FIELD_PREP(SLIDER_OFFSET_MASK, slider_offset);
|
||||
|
||||
write_soc_slider(proc_priv, val);
|
||||
}
|
||||
|
||||
/* profile get/set callbacks are called with a profile lock, so no need for local locks */
|
||||
|
||||
static int power_slider_platform_profile_set(struct device *dev,
|
||||
enum platform_profile_option profile)
|
||||
{
|
||||
struct proc_thermal_device *proc_priv;
|
||||
int slider;
|
||||
|
||||
proc_priv = dev_get_drvdata(dev);
|
||||
if (!proc_priv)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
guard(mutex)(&slider_param_lock);
|
||||
|
||||
slider_values[SOC_POWER_SLIDER_BALANCE] = slider_balanced_param;
|
||||
|
||||
slider = convert_profile_to_power_slider(profile);
|
||||
if (slider < 0)
|
||||
return slider;
|
||||
|
||||
set_soc_power_profile(proc_priv, slider);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int power_slider_platform_profile_get(struct device *dev,
|
||||
enum platform_profile_option *profile)
|
||||
{
|
||||
struct proc_thermal_device *proc_priv;
|
||||
int slider, ret;
|
||||
u64 val;
|
||||
|
||||
proc_priv = dev_get_drvdata(dev);
|
||||
if (!proc_priv)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
val = read_soc_slider(proc_priv);
|
||||
slider = FIELD_GET(SLIDER_MASK, val);
|
||||
|
||||
ret = convert_power_slider_to_profile(slider);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*profile = ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int power_slider_platform_profile_probe(void *drvdata, unsigned long *choices)
|
||||
{
|
||||
set_bit(PLATFORM_PROFILE_LOW_POWER, choices);
|
||||
set_bit(PLATFORM_PROFILE_BALANCED, choices);
|
||||
set_bit(PLATFORM_PROFILE_PERFORMANCE, choices);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_profile_ops power_slider_platform_profile_ops = {
|
||||
.probe = power_slider_platform_profile_probe,
|
||||
.profile_get = power_slider_platform_profile_get,
|
||||
.profile_set = power_slider_platform_profile_set,
|
||||
};
|
||||
|
||||
int proc_thermal_soc_power_slider_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv)
|
||||
{
|
||||
struct device *ppdev;
|
||||
|
||||
set_soc_power_profile(proc_priv, slider_values[SOC_POWER_SLIDER_BALANCE]);
|
||||
|
||||
ppdev = devm_platform_profile_register(&pdev->dev, "SoC Power Slider", proc_priv,
|
||||
&power_slider_platform_profile_ops);
|
||||
|
||||
return PTR_ERR_OR_ZERO(ppdev);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(proc_thermal_soc_power_slider_add, "INT340X_THERMAL");
|
||||
|
||||
static u64 soc_slider_save;
|
||||
|
||||
void proc_thermal_soc_power_slider_suspend(struct proc_thermal_device *proc_priv)
|
||||
{
|
||||
soc_slider_save = read_soc_slider(proc_priv);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(proc_thermal_soc_power_slider_suspend, "INT340X_THERMAL");
|
||||
|
||||
void proc_thermal_soc_power_slider_resume(struct proc_thermal_device *proc_priv)
|
||||
{
|
||||
write_soc_slider(proc_priv, soc_slider_save);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(proc_thermal_soc_power_slider_resume, "INT340X_THERMAL");
|
||||
|
||||
MODULE_IMPORT_NS("INT340X_THERMAL");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Processor Thermal Power Slider Interface");
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "thermal_hwmon.h"
|
||||
|
||||
#define K3_VTM_DEVINFO_PWR0_OFFSET 0x4
|
||||
#define K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK 0xf0
|
||||
#define K3_VTM_TMPSENS0_CTRL_OFFSET 0x300
|
||||
@@ -513,6 +515,8 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev)
|
||||
ret = PTR_ERR(ti_thermal);
|
||||
goto err_free_ref_table;
|
||||
}
|
||||
|
||||
devm_thermal_add_hwmon_sysfs(bgp->dev, ti_thermal);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, bgp);
|
||||
|
||||
@@ -639,7 +639,7 @@ static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
|
||||
|
||||
lvts_sensor[i].low_thresh = INT_MIN;
|
||||
lvts_sensor[i].high_thresh = INT_MIN;
|
||||
};
|
||||
}
|
||||
|
||||
lvts_ctrl->valid_sensor_mask = lvts_ctrl_data->valid_sensor_mask;
|
||||
|
||||
|
||||
@@ -34,7 +34,8 @@ config QCOM_SPMI_TEMP_ALARM
|
||||
|
||||
config QCOM_LMH
|
||||
tristate "Qualcomm Limits Management Hardware"
|
||||
depends on ARCH_QCOM && QCOM_SCM
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
select QCOM_SCM
|
||||
help
|
||||
This enables initialization of Qualcomm limits management
|
||||
hardware(LMh). LMh allows for hardware-enforced mitigation for cpus based on
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqdesc.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
@@ -204,7 +206,7 @@ static int lmh_probe(struct platform_device *pdev)
|
||||
ret = qcom_scm_lmh_dcvsh(LMH_SUB_FN_THERMAL, LMH_TH_LOW_THRESHOLD, temp_low,
|
||||
LMH_NODE_DCVS, node_id, 0);
|
||||
if (ret) {
|
||||
dev_err(dev, "Error setting thermal ARM threshold%d\n", ret);
|
||||
dev_err(dev, "Error setting thermal LOW threshold%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,13 +10,13 @@ config RCAR_THERMAL
|
||||
thermal framework.
|
||||
|
||||
config RCAR_GEN3_THERMAL
|
||||
tristate "Renesas R-Car Gen3 and RZ/G2 thermal driver"
|
||||
tristate "Renesas R-Car Gen3/Gen4 and RZ/G2 thermal driver"
|
||||
depends on ARCH_RENESAS || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
depends on OF
|
||||
help
|
||||
Enable this to plug the R-Car Gen3 or RZ/G2 thermal sensor driver into
|
||||
the Linux thermal framework.
|
||||
Enable this to plug the R-Car Gen3/Gen4 or RZ/G2 thermal sensor
|
||||
driver into the Linux thermal framework.
|
||||
|
||||
config RZG2L_THERMAL
|
||||
tristate "Renesas RZ/G2L thermal driver"
|
||||
@@ -26,3 +26,18 @@ config RZG2L_THERMAL
|
||||
help
|
||||
Enable this to plug the RZ/G2L thermal sensor driver into the Linux
|
||||
thermal framework.
|
||||
|
||||
config RZG3S_THERMAL
|
||||
tristate "Renesas RZ/G3S thermal driver"
|
||||
depends on ARCH_R9A08G045 || COMPILE_TEST
|
||||
depends on OF && IIO && RZG2L_ADC
|
||||
help
|
||||
Enable this to plug the RZ/G3S thermal sensor driver into the Linux
|
||||
thermal framework.
|
||||
|
||||
config RZG3E_THERMAL
|
||||
tristate "Renesas RZ/G3E thermal driver"
|
||||
depends on ARCH_RENESAS || COMPILE_TEST
|
||||
help
|
||||
Enable this to plug the RZ/G3E thermal sensor driver into the Linux
|
||||
thermal framework.
|
||||
|
||||
@@ -3,3 +3,6 @@
|
||||
obj-$(CONFIG_RCAR_GEN3_THERMAL) += rcar_gen3_thermal.o
|
||||
obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o
|
||||
obj-$(CONFIG_RZG2L_THERMAL) += rzg2l_thermal.o
|
||||
obj-$(CONFIG_RZG3E_THERMAL) += rzg3e_thermal.o
|
||||
obj-$(CONFIG_RZG3S_THERMAL) += rzg3s_thermal.o
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user