视壮BBS

   登录   |   注册   |

VS-RK3399 Android7.1 TSADC驱动流程小结

117

主题

128

帖子

591

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
591
发表于 2018-5-7 14:51:35     
VS-RK3399 Android7.1 TSADC驱动流程小结
前言:和RK3288一样,RK3399上有两路TSADC通道分别用于监测CPU和GPU的温度。 不同的是RK3399结合kernel thermal core框架来管控,而RK3288直接是写了一个独立驱动控制硬件。

TSADC两种模式:
1.用户自定义模式。 所以信号都通过是user写到寄存器中控制。
2.自动模式。 控制器自动查询TSADC输出,如果温度过高就会产生中断,如果再高就会发信号给CRU模块复位整个芯片或者通过gpio通知PMU做处理。

TSADC控制器特性:
1. 支持用户自定义和自动模式
2. 支持两路通道
3. 系统复位的温度点可被配置
4. 可设置范围:~40-125°, 精度是5°
5. ADC精度10bit,采样率50kb/s
6. 温度探测和周期值可配置

控制器配置:
rk3399.dtsi:

tsadc: tsadc@ff260000 {    compatible = "rockchip,rk3399-tsadc"; //设备名,和驱动匹配    reg = <0x0 0xff260000 0x0 0x100>;    interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH 0>;    rockchip,grf = <&grf>;    clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>;    clock-names = "tsadc", "apb_pclk";    assigned-clocks = <&cru SCLK_TSADC>;    assigned-clock-rates = <750000>;    resets = <&cru SRST_TSADC>;//reset对应的cru    reset-names = "tsadc-apb";    pinctrl-names = "init", "default", "sleep";    pinctrl-0 = <&otp_gpio>;    pinctrl-1 = <&otp_out>;    pinctrl-2 = <&otp_gpio>;    #thermal-sensor-cells = <1>;    rockchip,hw-tshut-temp = <95000>;  //设置的关机温度    status = "disabled";};
另一部分配置是在rk3399-core.c中:
&tsadc {    /* tshut mode 0:CRU 1:GPIO */    rockchip,hw-tshut-mode = <1>;  //关机模式,设置为通过gpio方式    /* tshut polarity 0OW 1:HIGH */    rockchip,hw-tshut-polarity = <1>;  //对应关机极性    status = "okay";};


除了tsadc之外,我们也需要了解thermal zone的配置:


thermal_zones: thermal-zones {    soc_thermal: soc-thermal {  //对应cpu thermal        polling-delay-passive = <20>; /* milliseconds */    //当超过阀值时,每隔20ms查询一次。        polling-delay = <1000>; /* milliseconds */      //未超过阀值时,每隔1000ms查询一次。        sustainable-power = <1000>; /* milliwatts */    //当前温度到达预设的最高值时,系统能分配给 cooling 设备的能量。                                                        //用于power allocator策略。        thermal-sensors = <&tsadc 0>;   //使用tsadc的channel 0.        trips { //控制温度触发范围值配置            threshold: trip-point@0 {                temperature = <70000>; /* millicelsius */   //温度超过70°温控策略开始工作,但不一定马上限制频率。                hysteresis = <2000>; /* millicelsius */     //迟滞值,允许一定时间缓冲后才开始执行控制策略。                type = "passive";                           //要设置成"passive"            };            target: trip-point@1 {  //                temperature = <85000>; /* millicelsius */                hysteresis = <2000>; /* millicelsius */                type = "passive";            };            soc_crit: soc-crit {    //系统温度的临界值,超过就要关机了。                temperature = <95000>; /* millicelsius */                hysteresis = <2000>; /* millicelsius */                type = "critical";  //要设置成critical才会起作用。            };        };        cooling-maps {  //降温策略配置,有三个要被降温的设备,分别是小核A53(cpu_l0), 大核A72(cpu_b0)以及GPU                map0 {                trip = <&target>;  //power_allocater策略子节点的trip属性都设置target。                cooling-device =                    <&cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;    //允许被限制最低和最高频率。                contribution = <4096>;  //注释是 the percentage (from 0 to 100) of cooling contribution,还未研究其意义。            };            map1 {                trip = <&target>;                cooling-device =                    <&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;                contribution = <1024>;            };            map2 {                trip = <&target>;                cooling-device =                    <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;                contribution = <4096>;            };        };    };    gpu_thermal: gpu-thermal {        polling-delay-passive = <100>; /* milliseconds */        polling-delay = <1000>; /* milliseconds */        thermal-sensors = <&tsadc 1>;    };};




驱动文件: rockchip_thermal.c: rk3399 thermal controller驱动。 of-thermal.c: thermal core device tree接口。 thermal_core.c: linux thermal core核心框架。


重要数据结构:
如下这个数据结构,里面基本上包含了驱动所有信息和功能,其中有些对应的值比如关机模式,关机温度等可以在dts中修改(前面dts已经提及过)
rockchip_thermal.c:

static const struct rockchip_tsadc_chip rk3399_tsadc_data = {    .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */    .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */    .chn_num = 2, /* two channels for tsadc */    .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */    .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */    .tshut_temp = 95000,    //操作函数集    .initialize = rk_tsadcv3_initialize,    .irq_ack = rk_tsadcv3_irq_ack,    .control = rk_tsadcv3_control,    .get_temp = rk_tsadcv2_get_temp,    .set_alarm_temp = rk_tsadcv2_alarm_temp,    .set_tshut_temp = rk_tsadcv2_tshut_temp,    .set_tshut_mode = rk_tsadcv2_tshut_mode,    //表格就是读到的ADC和温度的关系。    .table = {        .id = rk3399_code_table,        .length = ARRAY_SIZE(rk3399_code_table),        .data_mask = TSADCV3_DATA_MASK,        .mode = ADC_INCREMENT,    },};

代码调用流程:

TSADC驱动初始化:

rockchip_thermal_probe ->  rockchip-thermal.c 用struct rockchip_thermal_data结构体表示thermal信息。  thermal->chip = (const struct rockchip_tsadc_chip *)match->data;  //data就是rk3399_tsadc_data变量  rockchip_thermal_reset_controller //先复位控制器  rockchip_configure_from_dt //解析dts中的"rockchip,hw-tshut-temp","rockchip,hw-tshut-mode"以及"rockchip,hw-tshut-polarity"  thermal->chip->initialize ->    rk_tsadcv3_initialize //初始化TSADC控制器  rockchip_thermal_register_sensor -> //注册控制器    tsadc->set_tshut_mode -> //设置关机模式      rk_tsadcv2_tshut_mode    tsadc->set_tshut_temp -> //设置关机温度    devm_thermal_zone_of_sensor_register -> of-thermal.c //注册thermal zone到系统中,留意其中的ops: rockchip_of_thermal_ops      thermal_zone_of_sensor_register ->   //返回的struct thermal_zone_device是thermal框架中标准结构        of_find_node_by_name(NULL, "thermal-zones"); //rk3399.dtsi中有此节点        thermal_zone_of_add_sensor  -> //有soc_thermal和gpu_thermal两个zone,rockchip定义的ops会和                                       //struct rockchip_thermal_sensor被放到struct __thermal_zone中                                       //可以看到,thermal_zone_device包含__thermal_zone和ops, __thermal_zone包含                                       //rk自己定义的rockchip_thermal_sensor和ops,注意两者ops的区别,不要混淆了,下面的                                       //set_mode调用过程可以看到ops的一级级调用,最终控制到rk的tsadc控制器。          thermal_zone_get_zone_by_name //thermal zone在thermal_core.c中注册过了。        tzd->ops->set_mode ->          of_thermal_set_mode -> of-thermal.c            thermal_zone_device_update ->              update_temperature -> //更新温度                thermal_zone_get_temp ->                  tz->ops->get_temp ->                    of_thermal_get_temp ->                      data->ops->get_temp ->    //对应ops是rockchip_of_thermal_ops                        rockchip_thermal_get_temp ->                          tsadc->get_temp ->                            rk_tsadcv2_get_temp ->  //调用控制器的get temp接口                              rk_tsadcv2_code_to_temp //code转换成temperature              thermal_zone_set_trips ->                tz->ops->get_trip_temp ->   //获取各个trip对应的温度,trip有三个,配置在thermal_zones节点中定义。                  of_thermal_get_trip_temp ->                    *temp = data->trips[trip].temperature    //根据trip number获取对应的温度                tz->ops->get_trip_hyst ->   //获取迟滞值,此值会和上面的temperature结合,比如原本是75°触发,迟滞值是5°,那么80°才会真的触发thermal core做策略调整                  of_thermal_get_trip_hyst                tz->ops->set_trips ->                  of_thermal_set_trips ->                    data->ops->set_trips ->                       rockchip_thermal_set_trips ->                        tsadc->set_alarm_temp ->                          rk_tsadcv2_alarm_temp ->  //设置触发alarm的温度,对应中断处理在下面注册               handle_thermal_trip ->                 tz->ops->get_trip_type -> //获取trip type                   of_thermal_get_trip_type                 handle_critical_trips -> //如果type是critical就走此流程                   tz->ops->get_trip_temp  //获取此trip对应设置的温度(dts中配置),如果没达到此温度就不做处理                   orderly_poweroff //执行关机动作                 handle_non_critical_trips -> //非critical的情况                   tz->governor->throttle //执行thermal core cooling策略                 monitor_thermal_zone   //继续定时监测温度   devm_request_threaded_irq //创建一个thermal thread,处理函数是rockchip_thermal_alarm_irq_thread()   thermal->chip->control -> //使能tsadc控制器     rk_tsadcv3_control    rockchip_thermal_toggle_sensor ->         tzd->ops->set_mode //又重新调用了一次   atomic_notifier_chain_register //系统panic的时候会发送回调,对应的处理函数是rockchip_thermal_panic(),打

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

友情链接 : 易百讯      粤ICP备14022046号-2
快速回复 返回顶部 返回列表