thermal-zones - A64 support

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

thermal-zones - A64 support

Krystian Lewandowski-2
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;
 }

Reply | Threaded
Open this post in threaded view
|

Re: thermal-zones - A64 support

Mark Kettenis
> Date: Fri, 6 Sep 2019 21:55:43 +0200
> From: Krystian Lewandowski <[hidden email]>
>
> 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

It's a shame that mainline Linux still doesn't have this.  But it is
hard to imagine a way to do the binding for the thermal sensors
differently.

I have committed this now.  Sorry for the delay.

> 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;
>  }
>