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

Reply via email to