Good evening Mark (and tech@),
thank you for thermal zones support.
I thought it would be nice to use it in A64 as well.
I tested it by running 'ubench -c' in a loop and checking clocks
and CPU temp. Clock went down when temperature rised limiting available
operating-points as expected (as far as I could tell).
I used following device tree entries:
(excerpt that should present the idea)
thermal-zones {
cpu-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
thermal-sensors = <&ths 0>;
trips {
cpu_warm: cpu_warm {
temperature = <65000000>;
hysteresis = <2000000>;
type = "passive";
};
cpu_hot_pre: cpu_hot_pre {
temperature = <70000000>;
hysteresis = <2000000>;
type = "passive";
};
cpu_hot: cpu_hot {
temperature = <75000000>;
hysteresis = <2000000>;
type = "passive";
};
cpu_very_hot: cpu_very_hot {
temperature = <90000000>;
hysteresis = <2000000>;
type = "passive";
};
};
cooling-maps {
cpu_warm_limit_cpu {
trip = <&cpu_warm>;
cooling-device = <&cpu0
THERMAL_NO_LIMIT 2>;
};
cpu_hot_pre_limit_cpu {
trip = <&cpu_hot_pre>;
cooling-device = <&cpu0 2 3>;
};
cpu_hot_limit_cpu {
trip = <&cpu_hot>;
cooling-device = <&cpu0 3 4>;
};
cpu_very_hot_pre_limit_cpu {
trip = <&cpu_very_hot>;
cooling-device = <&cpu0 5 6>;
};
cpu_very_hot_limit_cpu {
trip = <&cpu_very_hot>;
cooling-device = <&cpu0 7
THERMAL_NO_LIMIT>;
};
};
};
};
cpu0_opp_table: opp_table0 {
compatible = "operating-points-v2";
opp-shared;
opp-648000000 {
opp-hz = /bits/ 64 <648000000>;
opp-microvolt = <1040000>;
clock-latency-ns = <244144>; /* 8 32k periods */
};
opp-792000000 {
opp-hz = /bits/ 64 <792000000>;
opp-microvolt = <1100000>;
clock-latency-ns = <244144>; /* 8 32k periods */
};
opp-816000000 {
opp-hz = /bits/ 64 <816000000>;
opp-microvolt = <1100000>;
clock-latency-ns = <244144>; /* 8 32k periods */
};
opp-912000000 {
opp-hz = /bits/ 64 <912000000>;
opp-microvolt = <1120000>;
clock-latency-ns = <244144>; /* 8 32k periods */
};
opp-960000000 {
opp-hz = /bits/ 64 <960000000>;
opp-microvolt = <1160000>;
clock-latency-ns = <244144>; /* 8 32k periods */
};
opp-1008000000 {
opp-hz = /bits/ 64 <1008000000>;
opp-microvolt = <1200000>;
clock-latency-ns = <244144>; /* 8 32k periods */
};
opp-1056000000 {
opp-hz = /bits/ 64 <1056000000>;
opp-microvolt = <1240000>;
clock-latency-ns = <244144>; /* 8 32k periods */
};
opp-1104000000 {
opp-hz = /bits/ 64 <1104000000>;
opp-microvolt = <1260000>;
clock-latency-ns = <244144>; /* 8 32k periods */
};
opp-1152000000 {
opp-hz = /bits/ 64 <1152000000>;
opp-microvolt = <1300000>;
clock-latency-ns = <244144>; /* 8 32k periods */
};
};
--
Krystian
Index: sys/dev/fdt/sxitemp.c
===================================================================
RCS file: /cvs/src/sys/dev/fdt/sxitemp.c,v
retrieving revision 1.4
diff -u -p -r1.4 sxitemp.c
--- sys/dev/fdt/sxitemp.c 27 May 2018 21:59:26 -0000 1.4
+++ sys/dev/fdt/sxitemp.c 6 Sep 2019 19:25:27 -0000
@@ -28,6 +28,7 @@
#include <dev/ofw/ofw_clock.h>
#include <dev/ofw/ofw_misc.h>
#include <dev/ofw/ofw_pinctrl.h>
+#include <dev/ofw/ofw_thermal.h>
#include <dev/ofw/fdt.h>
/* Registers */
@@ -63,6 +64,8 @@ struct sxitemp_softc {
struct ksensor sc_sensors[3];
struct ksensordev sc_sensordev;
+
+ struct thermal_sensor sc_ts;
};
int sxitemp_match(struct device *, void *, void *);
@@ -82,6 +85,7 @@ uint64_t sxitemp_a64_calc_temp(int64_t);
uint64_t sxitemp_h5_calc_temp0(int64_t);
uint64_t sxitemp_h5_calc_temp1(int64_t);
void sxitemp_refresh_sensors(void *);
+int32_t sxitemp_get_temperature(void *, uint32_t *);
int
sxitemp_match(struct device *parent, void *match, void *aux)
@@ -172,6 +176,11 @@ sxitemp_attach(struct device *parent, st
}
sensordev_install(&sc->sc_sensordev);
sensor_task_register(sc, sxitemp_refresh_sensors, 5);
+
+ sc->sc_ts.ts_node = node;
+ sc->sc_ts.ts_cookie = sc;
+ sc->sc_ts.ts_get_temperature = sxitemp_get_temperature;
+ thermal_sensor_register(&sc->sc_ts);
}
uint64_t
@@ -236,4 +245,25 @@ sxitemp_refresh_sensors(void *arg)
sc->sc_sensors[2].value = sc->sc_calc_temp2(data) + 273150000;
sc->sc_sensors[2].flags &= ~SENSOR_FINVALID;
}
+}
+
+int32_t
+sxitemp_get_temperature(void *cookie, uint32_t *cells)
+{
+ struct sxitemp_softc *sc = cookie;
+ uint32_t idx = cells[0];
+ uint32_t data;
+
+ if (idx == 0 && sc->sc_calc_temp0) {
+ data = HREAD4(sc, THS0_DATA);
+ return sc->sc_calc_temp0(data);
+ } else if (idx == 1 && sc->sc_calc_temp1) {
+ data = HREAD4(sc, THS1_DATA);
+ return sc->sc_calc_temp1(data);
+ } else if (idx == 2 && sc->sc_calc_temp2) {
+ data = HREAD4(sc, THS2_DATA);
+ return sc->sc_calc_temp2(data);
+ }
+
+ return THERMAL_SENSOR_MAX;
}