瑞芯微Rockchip开发者社区
直播中

飞毛腿452

9年用户 915经验值
擅长:电源/新能源
私信 关注
[问答]

如何对Android7.1 RK3288 Thermal进行控制呢

如何对Android7.1 RK3288 Thermal进行控制呢?

回帖(1)

王璐

2022-3-4 16:21:54
【平台信息】

平台:RK3288
Android:5.1
Linux:4.4

【代码梳理】

1、Dts配置

1)tsadc配置,文件:kernelarcharmbootdtsrk3288.dtsi
        tsadc: tsadc@ff280000 {
                compatible = "rockchip,rk3288-tsadc"; //设备名,和驱动匹配
                reg = <0x0 0xff280000 0x0 0x100>;
                interrupts = ;
                clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>;
                clock-names = "tsadc", "apb_pclk";
                assigned-clocks = <&cru SCLK_TSADC>; //工作时钟,5KHz
                assigned-clock-rates = <5000>;
                resets = <&cru SRST_TSADC>; //reset对应的cru
                reset-names = "tsadc-apb";
                pinctrl-names = "init", "default", "sleep"; // tsadc输出引脚配置,支持gpio和otpout模式
                pinctrl-0 = <&otp_gpio>;
                pinctrl-1 = <&otp_gpio>;
                pinctrl-2 = <&otp_gpio>;
                #thermal-sensor-cells = <1>; //表示tsadc可以作为一个thermal sensor,并制定引用tsadc节点的时候需要带几个参数,如果SOC只有一个tsadc,可以设置为0,超过一个必须设置为1
                rockchip,hw-tshut-temp = <120000>;   //设置的关机温度
                rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */
                status = "disabled";
        };
2)pinctrl配置,文件:kernelarcharmbootdtsrk3288.dtsi
        pinctrl: pinctrl {
                ...
                tsadc {
                        otp_gpio: otp-gpio {
                                rockchip,pins = <0 10 RK_FUNC_GPIO &pcfg_pull_none>;
                        };

                        otp_out: otp-out {
                                rockchip,pins = <0 10 RK_FUNC_1 &pcfg_pull_none>; //配置为Over Temp Protect模式
                        };
                };
                ...
3)文件kernelarcharmbootdtsrk3288-remoter.dts
&tsadc {
        status = "okay";
        rockchip,hw-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */   //关机模式,设置为通过gpio方式
        rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */  //对应关机极性
        pinctrl-1 = <&otp_out>;
};
4)thermal配置,        文件:kernelarcharmbootdtsrk3288.dtsi
参考文档:
        thermal_zones: thermal-zones {
                soc_thermal: soc-thermal {
                        polling-delay-passive = <200>; /* milliseconds */
                        polling-delay = <1000>; /* milliseconds */
                        sustainable-power = <1200>; /* milliwatts */

                        thermal-sensors = <&tsadc 1>;  //当前thermal-sensor通过tsadc1获取温度
                        trips {
                                threshold: trip-point@0 {
                                        temperature = <75000>; /* millicelsius */
                                        hysteresis = <2000>; /* millicelsius */
                                        type = "passive";
                                };
                                target: trip-point@1 {
                                        temperature = <85000>; /* millicelsius */
                                        hysteresis = <2000>; /* millicelsius */
                                        type = "passive";
                                };
                                soc_crit: soc-crit {
                                        temperature = <115000>; /* millicelsius */
                                        hysteresis = <2000>; /* millicelsius */
                                        type = "critical";
                                };
                        };

                        cooling-maps {
                                map0 {
                                        trip = <&target>;
                                        cooling-device =
                                        <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
                                        contribution = <1024>;
                                };
                                map1 {
                                        trip = <&target>;
                                        cooling-device =
                                        <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
                                        contribution = <1024>;
                                };
                        };
                };

                gpu_thermal: gpu-thermal {
                        polling-delay-passive = <200>; /* milliseconds */
                        polling-delay = <1000>; /* milliseconds */
                        thermal-sensors = <&tsadc 2>;
                };
        };

参考文档:Documentation/devicetree/bindings/thermal/thermal.txt
Documentation/devicetree/bindings/thermal/rockchip-thermal.txt
Documentation/devicetree/bindings/thermal/power_allocator.txt

2、驱动代码
kerneldrivershwmonrockchip-hwmon.c
kerneldrivershwmonrockchip_tsadc.c

rockchip_temp_probe ->     rockchip-hwmon.c
    rockchip_hwmon_init -> rockchip_tsadc.c
        request_threaded_irq    //申请一个中断线程,对应函数是rockchip_tsadc_auto_ht_interrupt()
        create_singlethread_workqueue    //创建workqueue thread,对应函数是rockchip_tsadc_auto_ht_work
        of_property_read_u32    //读取dts中的tsadc-ht-temp, tsadc-ht-reset-cru,tsadc-ht-pull-gpio
        rockchip_tsadc_set_auto_temp    //设置为自动温度探测模式,参数channel表示只针对此channel设置,rk3288 cpu对应是channel 1.
            rockchip_tsadc_auto_mode_set   ->  //设置中断和关机的温度, 分别对应的是80和120度
        data->ops.read_sensor = rockchip_rk3288_tsadc_get_temp;    //读取温度函数接口定义.
        INIT_DEFERRABLE_WORK(&data->work, tsadc_monitor);    //温度变化时更新sysfs中的alarm node信息.
        sysfs_create_group    //在tsadc device下创建sysfs,attr为rockchip_temp_group, 按照SENSOR_DEVICE_ATTR格式来定义,不过最终用的都是sysfs文件创建那一套.
        hwmon_device_register    //hwmon device注册, 会在/sys/class/hwmon下看到.
        
        当达到80°的时候,中断被触发:
rockchip_tsadc_auto_ht_interrupt ->
    queue_work(dev->workqueue, &dev->auto_ht_irq_work) ->     //给workqueue执行
        rockchip_tsadc_auto_ht_work ->
            tsadc_readl        //读取中断状态
            pm_power_off    //过温就执行关机

【用户态接口】

用户态接口在/sys/class/thermal/⽬录,具体内容和DTSI中thermal zone节点的配置对应。有的平台thermal
zone节点下只有⼀个⼦节点,对应/sys/class/thermal/⽬录下也只有thermal_zone0⼦⽬录;有的平台有两个⼦节
点,对应/sys/class/thermal/⽬录下就会有thermal_zone0和thermal_zone1⼦⽬录。通过⽤⼾态接口可以切换温
控策略,查看当前温度等。
以RK3288为例⼦,/sys/class/thermal/thermal_zone0/⽬录下包含如下常⽤的信息:

temp /* 当前温度 */
available_policies /* ⽀持的温控策略 */
policy /* 当前使⽤的温控策略 */
sustainable_power /* 期望的最⾼温度下对应的power值 */
integral_cutoff /* PID算法中I的触发条件:当前温度-期望的最⾼温度
k_d /* PID算法中计算D的时候⽤的参数 */
k_i /* PID算法中计算I的时候⽤的参数 */
k_po /* PID算法中计算P的时候⽤的参数 */
k_pu /* PID算法中计算P的时候⽤的参数 */
mode /* enabled:⾃带定时获取温度,判断是否需要降频。disabled关闭该功能 */
type /* 当前thermal zone的类型 */
/* 不同的温度阀值,对应trips节点的配置 */
trip_point_0_hyst
trip_point_0_temp
trip_point_0_type
trip_point_1_hyst
trip_point_1_temp
trip_point_1_type
trip_point_2_hyst
trip_point_2_temp
trip_point_2_type
/* 不同cooling devic的状态,对应cooling-maps节点的配置 */
cdev0 /* 代表⼀个cooling devic,有的平台还有cdev1、cdev2等 */
cur_state /* 该cooling device当前频率的档位 */
max_state /* 该cooling device最多有⼏个档位 */
type /* 该cooling device的类型 */
cdev0_weight /* 该cooling devic在计算power时扩⼤的倍数 */

参考文档:Documentation/thermal/sysfs-api.txt

【调试总结】


1、查看thermal类型
rk3288:/ # cat /sys/class/thermal/thermal_zone0/type
soc-thermal
rk3288:/ # cat /sys/class/thermal/thermal_zone1/type
gpu-thermal
rk3288:/ # cat /sys/class/thermal/thermal_zone2/type
rk-bat

2、获取温度值
rk3288:/ # cat /sys/class/thermal/thermal_zone0/temp
36999
rk3288:/ # cat /sys/class/thermal/thermal_zone1/temp
37198
rk3288:/ # cat /sys/class/thermal/thermal_zone2/temp
18800
举报

更多回帖

×
20
完善资料,
赚取积分