1
0
mirror of https://git.openwrt.org/openwrt/openwrt.git synced 2024-10-18 21:48:23 +02:00

mvebu: improve thermal management of IEI Puzzle devices

- Make step_wise thermal governor respect hysteresis
   This is done by importing a downstream patch, backporting the same feature
   now present in Linux v6.10+ would be too messy.
 - Introduce thermal zone for the WT61P803 uC (chassis and board sensors)
 - Introduce thermal zones for AQR NBase-T PHYs
 - No longer modify existing SoC thermal zones (which are now only in charge
   for emergency shutdown, and can be interrupt driven instead of polled)

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
This commit is contained in:
Daniel Golle 2024-05-02 13:21:09 +01:00
parent dbc9596c7e
commit ac783b419b
5 changed files with 337 additions and 106 deletions

@ -54,6 +54,91 @@
gpios = <&cp0_gpio2 4 GPIO_ACTIVE_LOW>;
};
};
thermal-zones {
chassis-thermal {
polling-delay = <5000>;
thermal-sensors = <&puzzle_hwmon 0>, <&puzzle_hwmon 1>;
trips {
chassis_very_hot: trip-point3 {
temperature = <55000>;
hysteresis = <5000>;
type = "active";
};
chassis_hot: trip-point2 {
temperature = <50000>;
hysteresis = <5000>;
type = "active";
};
chassis_warm: trip-point1 {
temperature = <45000>;
hysteresis = <5000>;
type = "active";
};
chassis_cold: trip-point0 {
temperature = <40000>;
hysteresis = <5000>;
type = "active";
};
};
cooling-maps {
map3 {
trip = <&chassis_very_hot>;
cooling-device = <&chassis_fan_group0 6 6>;
};
map2 {
trip = <&chassis_hot>;
cooling-device = <&chassis_fan_group0 3 3>;
};
map1 {
trip = <&chassis_warm>;
cooling-device = <&chassis_fan_group0 1 1>;
};
map0 {
trip = <&chassis_cold>;
cooling-device = <&chassis_fan_group0 0 0>;
};
};
};
cp0-phy0-thermal {
thermal-sensors = <&cp0_nbaset_phy0>;
PUZZLE_FAN_THERMAL(cp0_phy0, &chassis_fan_group0);
};
cp0-phy1-thermal {
thermal-sensors = <&cp0_nbaset_phy1>;
PUZZLE_FAN_THERMAL(cp0_phy1, &chassis_fan_group0);
};
cp0-phy2-thermal {
thermal-sensors = <&cp0_nbaset_phy2>;
PUZZLE_FAN_THERMAL(cp0_phy2, &chassis_fan_group0);
};
cp1-phy0-thermal {
thermal-sensors = <&cp1_nbaset_phy0>;
PUZZLE_FAN_THERMAL(cp1_phy0, &chassis_fan_group0);
};
cp1-phy1-thermal {
thermal-sensors = <&cp1_nbaset_phy1>;
PUZZLE_FAN_THERMAL(cp1_phy1, &chassis_fan_group0);
};
cp1-phy2-thermal {
thermal-sensors = <&cp1_nbaset_phy2>;
PUZZLE_FAN_THERMAL(cp1_phy2, &chassis_fan_group0);
};
};
};
&uart0 {
@ -104,10 +189,11 @@
};
};
hwmon {
puzzle_hwmon: hwmon {
compatible = "iei,wt61p803-puzzle-hwmon";
#address-cells = <1>;
#size-cells = <0>;
#thermal-sensor-cells = <1>;
chassis_fan_group0: fan-group@0 {
#cooling-cells = <2>;
@ -118,14 +204,6 @@
};
};
&ap_thermal_ic {
PUZZLE_FAN_THERMAL(ic, &chassis_fan_group0);
};
&cp0_thermal_ic {
PUZZLE_FAN_THERMAL(cp0, &chassis_fan_group0);
};
/* on-board eMMC - U9 */
&ap_sdhci0 {
pinctrl-names = "default";
@ -144,14 +222,17 @@
cp0_nbaset_phy0: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <2>;
#thermal-sensor-cells = <0>;
};
cp0_nbaset_phy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <0>;
#thermal-sensor-cells = <0>;
};
cp0_nbaset_phy2: ethernet-phy@2 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <8>;
#thermal-sensor-cells = <0>;
};
};
@ -313,14 +394,17 @@
cp1_nbaset_phy0: ethernet-phy@3 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <2>;
#thermal-sensor-cells = <0>;
};
cp1_nbaset_phy1: ethernet-phy@4 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <0>;
#thermal-sensor-cells = <0>;
};
cp1_nbaset_phy2: ethernet-phy@5 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <8>;
#thermal-sensor-cells = <0>;
};
};
@ -399,10 +483,6 @@
};
};
&cp1_thermal_ic {
PUZZLE_FAN_THERMAL(cp1, &chassis_fan_group0);
};
&cp1_usb3_1 {
status = "okay";
phys = <&cp1_comphy3 1>;

@ -99,6 +99,96 @@
tx-fault-gpio = <&cp2_module_expander1 8 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
thermal-zones {
chassis-thermal {
polling-delay = <5000>;
thermal-sensors = <&puzzle_hwmon 0>, <&puzzle_hwmon 1>;
trips {
chassis_very_hot: trip-point2 {
temperature = <55000>;
hysteresis = <5000>;
type = "active";
};
chassis_hot: trip-point1 {
temperature = <50000>;
hysteresis = <5000>;
type = "active";
};
chassis_warm: trip-point0 {
temperature = <45000>;
hysteresis = <5000>;
type = "active";
};
};
cooling-maps {
map2 {
trip = <&chassis_very_hot>;
cooling-device = <&chassis_fan_group0 6 6>;
};
map1 {
trip = <&chassis_hot>;
cooling-device = <&chassis_fan_group0 3 3>;
};
map0 {
trip = <&chassis_warm>;
cooling-device = <&chassis_fan_group0 1 1>;
};
};
};
cp0-phy0-thermal {
thermal-sensors = <&cp0_nbaset_phy0>;
PUZZLE_FAN_THERMAL(cp0_phy0, &chassis_fan_group0);
};
cp0-phy1-thermal {
thermal-sensors = <&cp0_nbaset_phy1>;
PUZZLE_FAN_THERMAL(cp0_phy1, &chassis_fan_group0);
};
cp0-phy2-thermal {
thermal-sensors = <&cp0_nbaset_phy2>;
PUZZLE_FAN_THERMAL(cp0_phy2, &chassis_fan_group0);
};
cp1-phy0-thermal {
thermal-sensors = <&cp1_nbaset_phy0>;
PUZZLE_FAN_THERMAL(cp1_phy0, &chassis_fan_group0);
};
cp1-phy1-thermal {
thermal-sensors = <&cp1_nbaset_phy1>;
PUZZLE_FAN_THERMAL(cp1_phy1, &chassis_fan_group0);
};
cp1-phy2-thermal {
thermal-sensors = <&cp1_nbaset_phy2>;
PUZZLE_FAN_THERMAL(cp1_phy2, &chassis_fan_group0);
};
cp2-phy0-thermal {
thermal-sensors = <&cp2_nbaset_phy0>;
PUZZLE_FAN_THERMAL(cp2_phy0, &chassis_fan_group0);
};
cp2-phy1-thermal {
thermal-sensors = <&cp2_nbaset_phy1>;
PUZZLE_FAN_THERMAL(cp2_phy1, &chassis_fan_group0);
};
cp2-phy2-thermal {
thermal-sensors = <&cp2_nbaset_phy2>;
PUZZLE_FAN_THERMAL(cp2_phy2, &chassis_fan_group0);
};
};
};
&uart0 {
@ -149,7 +239,7 @@
};
};
hwmon {
puzzle_hwmon: hwmon {
compatible = "iei,wt61p803-puzzle-hwmon";
#address-cells = <1>;
#size-cells = <0>;
@ -163,15 +253,6 @@
};
};
&ap_thermal_ic {
PUZZLE_FAN_THERMAL(ic, &chassis_fan_group0);
};
&cp0_thermal_ic {
PUZZLE_FAN_THERMAL(cp0, &chassis_fan_group0);
};
/* on-board eMMC - U9 */
&ap_sdhci0 {
pinctrl-names = "default";
@ -187,17 +268,20 @@
&cp0_xmdio {
status = "okay";
cp0_nbaset_phy0: ethernet-phy@0 {
cp0_nbaset_phy0: ethernet-phy@2 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <2>;
#thermal-sensor-cells = <0>;
};
cp0_nbaset_phy1: ethernet-phy@1 {
cp0_nbaset_phy1: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <0>;
#thermal-sensor-cells = <0>;
};
cp0_nbaset_phy2: ethernet-phy@2 {
cp0_nbaset_phy2: ethernet-phy@8 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <8>;
#thermal-sensor-cells = <0>;
};
};
@ -374,17 +458,20 @@
&cp1_xmdio {
status = "okay";
cp1_nbaset_phy0: ethernet-phy@3 {
cp1_nbaset_phy0: ethernet-phy@2 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <2>;
#thermal-sensor-cells = <0>;
};
cp1_nbaset_phy1: ethernet-phy@4 {
cp1_nbaset_phy1: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <0>;
#thermal-sensor-cells = <0>;
};
cp1_nbaset_phy2: ethernet-phy@5 {
cp1_nbaset_phy2: ethernet-phy@8 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <8>;
#thermal-sensor-cells = <0>;
};
};
@ -451,10 +538,6 @@
};
};
&cp1_thermal_ic {
PUZZLE_FAN_THERMAL(cp1, &chassis_fan_group0);
};
/*
* Instantiate the second connected CP115
*/
@ -487,17 +570,20 @@
&cp2_xmdio {
status = "okay";
cp2_nbaset_phy0: ethernet-phy@6 {
cp2_nbaset_phy0: ethernet-phy@2 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <2>;
#thermal-sensor-cells = <0>;
};
cp2_nbaset_phy1: ethernet-phy@7 {
cp2_nbaset_phy1: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <0>;
#thermal-sensor-cells = <0>;
};
cp2_nbaset_phy2: ethernet-phy@8 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <8>;
#thermal-sensor-cells = <0>;
};
};
@ -574,7 +660,3 @@
};
};
};
&cp2_thermal_ic {
PUZZLE_FAN_THERMAL(cp2, &chassis_fan_group0);
};

@ -1,68 +1,62 @@
#define PUZZLE_FAN_THERMAL(_cname, _fan) \
polling-delay-passive = <500>; \
polling-delay = <1000>; \
\
trips { \
cpu-hot { \
temperature = <75000>; \
hysteresis = <5000>; \
type = "hot"; \
}; \
_cname##_active_full: cpu-active-full { \
temperature = <70000>; \
hysteresis = <5000>; \
type = "active"; \
}; \
_cname##_active_high: cpu-active-high { \
temperature = <65000>; \
hysteresis = <5000>; \
type = "active"; \
}; \
_cname##_active_med: cpu-active-med { \
temperature = <62500>; \
hysteresis = <3000>; \
type = "active"; \
}; \
_cname##_active_low: cpu-active-low { \
temperature = <60000>; \
hysteresis = <3000>; \
type = "active"; \
}; \
_cname##_active_min: cpu-active-min { \
temperature = <55000>; \
hysteresis = <5000>; \
type = "active"; \
}; \
_cname##_active_idle: cpu-active-idle { \
temperature = <50000>; \
hysteresis = <5000>; \
type = "active"; \
}; \
}; \
cooling-maps { \
cpu-active-full { \
trip = <&_cname##_active_full>; \
cooling-device = <_fan THERMAL_NO_LIMIT \
THERMAL_NO_LIMIT>; \
}; \
cpu-active-high { \
trip = <&_cname##_active_high>; \
cooling-device = <_fan 4 5>; \
}; \
cpu-active-med { \
trip = <&_cname##_active_med>; \
cooling-device = <_fan 3 4>; \
}; \
cpu-active-low { \
trip = <&_cname##_active_low>; \
cooling-device = <_fan 2 3>; \
}; \
cpu-active-min { \
trip = <&_cname##_active_min>; \
cooling-device = <_fan 1 2>; \
}; \
cpu-active-idle { \
trip = <&_cname##_active_idle>; \
cooling-device = <_fan 0 0>; \
}; \
#define PUZZLE_FAN_THERMAL(_cname, _fan) \
polling-delay-passive = <500>; \
polling-delay = <1000>; \
\
trips { \
_cname##_active_full: trip-point5 { \
temperature = <70000>; \
hysteresis = <3000>; \
type = "active"; \
}; \
_cname##_active_very_high: trip-point4 { \
temperature = <67500>; \
hysteresis = <3000>; \
type = "active"; \
}; \
_cname##_active_high: trip-point3 { \
temperature = <65000>; \
hysteresis = <5000>; \
type = "active"; \
}; \
_cname##_active_med: trip-point2 { \
temperature = <62500>; \
hysteresis = <3000>; \
type = "active"; \
}; \
_cname##_active_low: trip-point1 { \
temperature = <60000>; \
hysteresis = <3000>; \
type = "active"; \
}; \
_cname##_active_min: trip-point0 { \
temperature = <55000>; \
hysteresis = <5000>; \
type = "active"; \
}; \
}; \
cooling-maps { \
map5 { \
trip = <&_cname##_active_full>; \
cooling-device = <_fan 6 6>; \
}; \
map4 { \
trip = <&_cname##_active_very_high>; \
cooling-device = <_fan 5 5>; \
}; \
map3 { \
trip = <&_cname##_active_high>; \
cooling-device = <_fan 4 4>; \
}; \
map2 { \
trip = <&_cname##_active_med>; \
cooling-device = <_fan 3 3>; \
}; \
map1 { \
trip = <&_cname##_active_low>; \
cooling-device = <_fan 2 2>; \
}; \
map0 { \
trip = <&_cname##_active_min>; \
cooling-device = <_fan 1 1>; \
}; \
}

@ -0,0 +1,65 @@
From 9685ce100f0d302501117113ef0a526ad1acca1d Mon Sep 17 00:00:00 2001
From: Ram Chandrasekar <rkumbako@codeaurora.org>
Date: Mon, 7 May 2018 11:54:08 -0600
Subject: [PATCH] drivers: thermal: step_wise: add support for hysteresis
Step wise governor increases the mitigation level when the temperature
goes above a threshold and will decrease the mitigation when the
temperature falls below the threshold. If it were a case, where the
temperature hovers around a threshold, the mitigation will be applied
and removed at every iteration. This reaction to the temperature is
inefficient for performance.
The use of hysteresis temperature could avoid this ping-pong of
mitigation by relaxing the mitigation to happen only when the
temperature goes below this lower hysteresis value.
Signed-off-by: Ram Chandrasekar <rkumbako@codeaurora.org>
Signed-off-by: Lina Iyer <ilina@codeaurora.org>
[forward-ported for Linux 6.6, as stop-gap downstream solution]
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/thermal/gov_step_wise.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
--- a/drivers/thermal/gov_step_wise.c
+++ b/drivers/thermal/gov_step_wise.c
@@ -86,22 +86,31 @@ static void thermal_zone_trip_update(str
struct thermal_instance *instance;
bool throttle = false;
int old_target;
+ int hyst_temp;
trend = get_tz_trend(tz, trip_id);
- if (tz->temperature >= trip->temperature) {
- throttle = true;
- 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->temperature, trend, throttle);
+ hyst_temp = trip->temperature - trip->hysteresis;
+ dev_dbg(&tz->device, "Trip%d[type=%d,temp=%d,hyst=%d]:trend=%d,throttle=%d\n",
+ trip_id, trip->type, trip->temperature, hyst_temp, trend, throttle);
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
if (instance->trip != trip)
continue;
old_target = instance->target;
+ throttle = false;
+ /*
+ * Lower the mitigation only if the temperature
+ * goes below the hysteresis temperature.
+ */
+ if (tz->temperature >= trip->temperature ||
+ (tz->temperature >= hyst_temp &&
+ old_target != THERMAL_NO_TARGET)) {
+ throttle = true;
+ trace_thermal_zone_trip(tz, trip_id, trip->type);
+ }
+
instance->target = get_target_state(instance, trend, throttle);
dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
old_target, (int)instance->target);

@ -0,0 +1,10 @@
--- a/drivers/hwmon/iei-wt61p803-puzzle-hwmon.c
+++ b/drivers/hwmon/iei-wt61p803-puzzle-hwmon.c
@@ -251,6 +251,7 @@ static const struct hwmon_ops iei_wt61p8
};
static const struct hwmon_channel_info *iei_wt61p803_puzzle_info[] = {
+ HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
HWMON_CHANNEL_INFO(pwm,
HWMON_PWM_INPUT,
HWMON_PWM_INPUT),