mvebu: improve thermal management of IEI Puzzle devices
authorDaniel Golle <daniel@makrotopia.org>
Thu, 2 May 2024 12:21:09 +0000 (13:21 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Sat, 1 Jun 2024 15:40:10 +0000 (16:40 +0100)
 - 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>
target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/cn9131-puzzle-m901.dts
target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/cn9132-puzzle-m902.dts
target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/puzzle-thermal.dtsi
target/linux/mvebu/patches-6.6/350-drivers-thermal-step_wise-add-support-for-hysteresis.patch [new file with mode: 0644]
target/linux/mvebu/patches-6.6/912-drivers-hwmon-wt61p803-puzzle-thermal-zone.patch [new file with mode: 0644]

index d214853f1be1167c2d1ea60cdc5f105a14ef696a..b3e3d0a1e00eaad0f4619a19f5624a5085206dce 100644 (file)
                        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 {
                        };
                };
 
-               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>;
        };
 };
 
-&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";
        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>;
        };
 };
 
        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>;
        };
 };
 
        };
 };
 
-&cp1_thermal_ic {
-       PUZZLE_FAN_THERMAL(cp1, &chassis_fan_group0);
-};
-
 &cp1_usb3_1 {
        status = "okay";
        phys = <&cp1_comphy3 1>;
index 8c775e4a4f9a983792bc8bb22945d6eac2625b4f..f1cae8e5e426316a1b06fbca0e82c3ee6fbcdc57 100644 (file)
                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 {
                        };
                };
 
-               hwmon {
+               puzzle_hwmon: hwmon {
                        compatible = "iei,wt61p803-puzzle-hwmon";
                        #address-cells = <1>;
                        #size-cells = <0>;
        };
 };
 
-&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";
 
 &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>;
        };
 };
 
 
 &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>;
        };
 };
 
        };
 };
 
-&cp1_thermal_ic {
-       PUZZLE_FAN_THERMAL(cp1, &chassis_fan_group0);
-};
-
 /*
  * Instantiate the second connected CP115
  */
 
 &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>;
        };
 };
 
                };
        };
 };
-
-&cp2_thermal_ic {
-       PUZZLE_FAN_THERMAL(cp2, &chassis_fan_group0);
-};
index ea79ab224e4af885935969c3139777938670a299..d347a429ae23a12e20b14ec4d6249212b3533abc 100644 (file)
@@ -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>;                    \
+               };                                                      \
        }
diff --git a/target/linux/mvebu/patches-6.6/350-drivers-thermal-step_wise-add-support-for-hysteresis.patch b/target/linux/mvebu/patches-6.6/350-drivers-thermal-step_wise-add-support-for-hysteresis.patch
new file mode 100644 (file)
index 0000000..e7332b6
--- /dev/null
@@ -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);
diff --git a/target/linux/mvebu/patches-6.6/912-drivers-hwmon-wt61p803-puzzle-thermal-zone.patch b/target/linux/mvebu/patches-6.6/912-drivers-hwmon-wt61p803-puzzle-thermal-zone.patch
new file mode 100644 (file)
index 0000000..4633c03
--- /dev/null
@@ -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),