dt-bindings: thermal: tsens: Add ipq8074 compatible
Subsystems (5)
PATCH v3 1/5 dt-bindings: thermal: tsens: Add ipq8074 compatible
Qualcomm IPQ8074 has tsens v2.3.0 block, though unlike existing v2 IP it only uses one IRQ, so tsens v2 compatible cannot be used as the fallback.
We also have to make sure that correct interrupts are set according to compatibles, so populate interrupt information per compatibles.
---
Changes in v3:
* Remove implied min/maxItem properties as pointed by Rob
Changes in v2:
* No need for a list in compatible check
* Specify minItems and maxItems for interrupt and interrupt-names
--- .../bindings/thermal/qcom-tsens.yaml | 76 ++++++++++++++++--- 1 file changed, 65 insertions(+), 11 deletions(-)
Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +65 -11
@@ -56,6 +56,10 @@ properties: - qcom,sm8350-tsens - const: qcom,tsens-v2 + - description: v2 of TSENS with combined interrupt + enum: + - qcom,ipq8074-tsens + reg: items: - description: TM registers
@@ -63,15 +67,11 @@ properties: interrupts: minItems: 1 - items: - - description: Combined interrupt if upper or lower threshold crossed - - description: Interrupt if critical threshold crossed + maxItems: 2 interrupt-names: minItems: 1 - items: - - const: uplow - - const: critical + maxItems: 2 nvmem-cells: minItems: 1
@@ -124,22 +124,61 @@ allOf: then: properties: interrupts: - maxItems: 1 + items: + - description: Combined interrupt if upper or lower threshold crossed interrupt-names: - maxItems: 1 + items: + - const: uplow - else: + - if: + properties: + compatible: + contains: + enum: + - qcom,msm8953-tsens + - qcom,msm8996-tsens + - qcom,msm8998-tsens + - qcom,sc7180-tsens + - qcom,sc7280-tsens + - qcom,sc8180x-tsens + - qcom,sdm630-tsens + - qcom,sdm845-tsens + - qcom,sm8150-tsens + - qcom,sm8250-tsens + - qcom,sm8350-tsens + - qcom,tsens-v2 + then: + properties: + interrupts: + items: + - description: Combined interrupt if upper or lower threshold crossed + - description: Interrupt if critical threshold crossed + interrupt-names: + items: + - const: uplow + - const: critical + + - if: + properties: + compatible: + contains: + enum: + - qcom,ipq8074-tsens + then: properties: interrupts: - minItems: 2 + items: + - description: Combined interrupt if upper, lower or critical thresholds crossed interrupt-names: - minItems: 2 + items: + - const: combined - if: properties: compatible: contains: enum: + - qcom,ipq8074-tsens - qcom,tsens-v0_1 - qcom,tsens-v1 - qcom,tsens-v2
@@ -222,4 +261,19 @@ examples: #qcom,sensors = <13>; #thermal-sensor-cells = <1>; }; + + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + // Example 4 (for any IPQ8074 based SoC-s): + tsens4: thermal-sensor@4a9000 { + compatible = "qcom,ipq8074-tsens"; + reg = <0x4a9000 0x1000>, + <0x4a8000 0x1000>; + + interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "combined"; + + #qcom,sensors = <16>; + #thermal-sensor-cells = <1>; + }; ...
Signature · 1 line
2.35.1
PATCH v3 2/5 drivers: thermal: tsens: Add support for combined interrupt
Despite using tsens v2.3 IP, IPQ8074 and IPQ6018 only have one IRQ for signaling both up/low and critical trips.
--- drivers/thermal/qcom/tsens-8960.c | 1 + drivers/thermal/qcom/tsens-v0_1.c | 1 + drivers/thermal/qcom/tsens-v1.c | 1 + drivers/thermal/qcom/tsens-v2.c | 1 + drivers/thermal/qcom/tsens.c | 37 ++++++++++++++++++++++++++----- drivers/thermal/qcom/tsens.h | 2 ++ 6 files changed, 37 insertions(+), 6 deletions(-)
drivers/thermal/qcom/tsens-8960.c +1 -0
@@ -269,6 +269,7 @@ static const struct tsens_ops ops_8960 = {static struct tsens_features tsens_8960_feat = { .ver_major =VER_0 , .crit_int =0 , + .combo_int =0 , .adc =1 , .srot_split =0 , .max_sensors =11 ,
drivers/thermal/qcom/tsens-v0_1.c +1 -0
@@ -539,6 +539,7 @@ static int calibrate_9607(struct tsens_priv *priv)static struct tsens_features tsens_v0_1_feat = { .ver_major =VER_0_1 , .crit_int =0 , + .combo_int =0 , .adc =1 , .srot_split =1 , .max_sensors =11 ,
drivers/thermal/qcom/tsens-v1.c +1 -0
@@ -302,6 +302,7 @@ static int calibrate_8976(struct tsens_priv *priv)static struct tsens_features tsens_v1_feat = { .ver_major =VER_1_X , .crit_int =0 , + .combo_int =0 , .adc =1 , .srot_split =1 , .max_sensors =11 ,
drivers/thermal/qcom/tsens-v2.c +1 -0
@@ -31,6 +31,7 @@static struct tsens_features tsens_v2_feat = { .ver_major =VER_2_X , .crit_int =1 , + .combo_int =0 , .adc =0 , .srot_split =1 , .max_sensors =16 ,
drivers/thermal/qcom/tsens.c +31 -6
@@ -532,6 +532,26 @@ static irqreturn_t tsens_irq_thread(int irq, void *data)return IRQ_HANDLED ; } +/** +* tsens_combined_irq_thread - Threaded interrupt handler for combined interrupts +* @irq: irq number +* @data: tsens controller private data +* +* Handle the combined interrupt as if it were 2 separate interrupts, so call the +* critical handler first and then the up/low one. +* +* Return: IRQ_HANDLED +*/ +static irqreturn_t tsens_combined_irq_thread (int irq,void *data) +{ +irqreturn_t ret; + + ret =tsens_critical_irq_thread (irq, data); + ret =tsens_irq_thread (irq, data); + +return ret; +} +static int tsens_set_trips (void *_sensor,int low,int high) {struct tsens_sensor *s = _sensor;
@@ -1080,13 +1100,18 @@ static int tsens_register(struct tsens_priv *priv) tsens_mC_to_hw(priv->sensor, 0)); } - ret =tsens_register_irq (priv,"uplow" , tsens_irq_thread); -if (ret <0 ) -return ret; +if (priv->feat->combo_int) { + ret =tsens_register_irq (priv,"combined" , + tsens_combined_irq_thread); + }else { + ret =tsens_register_irq (priv,"uplow" , tsens_irq_thread); +if (ret <0 ) +return ret; -if (priv->feat->crit_int) - ret =tsens_register_irq (priv,"critical" , - tsens_critical_irq_thread); +if (priv->feat->crit_int) + ret =tsens_register_irq (priv,"critical" , + tsens_critical_irq_thread); + }return ret; }
drivers/thermal/qcom/tsens.h +2 -0
@@ -495,6 +495,7 @@ enum regfield_ids {* struct tsens_features - Features supported by the IP * @ver_major: Major number of IP version * @crit_int: does the IP support critical interrupts? +* @combo_int: does the IP use one IRQ for up, low and critical thresholds? * @adc: do the sensors only output adc code (instead of temperature)? * @srot_split: does the IP neatly splits the register space into SROT and TM, * with SROT only being available to secure boot firmware?
@@ -504,6 +505,7 @@ enum regfield_ids {struct tsens_features {unsigned int ver_major;unsigned int crit_int:1 ; +unsigned int combo_int:1 ;unsigned int adc:1 ;unsigned int srot_split:1 ;unsigned int has_watchdog:1 ;
Signature · 1 line
2.35.1
PATCH v3 3/5 drivers: thermal: tsens: allow configuring min and max trips
In reply to Robert MarkoIPQ8074 and IPQ6018 dont support negative trip temperatures and support up to 204 degrees C as the max trip temperature.
So, instead of always setting the -40 as min and 120 degrees C as max allow it to be configured as part of the features.
--- drivers/thermal/qcom/tsens-8960.c | 2 ++ drivers/thermal/qcom/tsens-v0_1.c | 2 ++ drivers/thermal/qcom/tsens-v1.c | 2 ++ drivers/thermal/qcom/tsens-v2.c | 2 ++ drivers/thermal/qcom/tsens.c | 4 ++-- drivers/thermal/qcom/tsens.h | 4 ++++ 6 files changed, 14 insertions(+), 2 deletions(-)
drivers/thermal/qcom/tsens-8960.c +2 -0
@@ -273,6 +273,8 @@ static struct tsens_features tsens_8960_feat = { .adc = 1, .srot_split = 0, .max_sensors = 11, + .trip_min_temp = -40000, + .trip_max_temp = 120000, };struct tsens_plat_data data_8960 = {
drivers/thermal/qcom/tsens-v0_1.c +2 -0
@@ -543,6 +543,8 @@ static struct tsens_features tsens_v0_1_feat = { .adc = 1, .srot_split = 1, .max_sensors = 11, + .trip_min_temp = -40000, + .trip_max_temp = 120000, };static const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS ] = {
drivers/thermal/qcom/tsens-v1.c +2 -0
@@ -306,6 +306,8 @@ static struct tsens_features tsens_v1_feat = { .adc = 1, .srot_split = 1, .max_sensors = 11, + .trip_min_temp = -40000, + .trip_max_temp = 120000, };static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS ] = {
drivers/thermal/qcom/tsens-v2.c +2 -0
@@ -35,6 +35,8 @@ static struct tsens_features tsens_v2_feat = { .adc = 0, .srot_split = 1, .max_sensors = 16, + .trip_min_temp = -40000, + .trip_max_temp = 120000, };static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS ] = {
drivers/thermal/qcom/tsens.c +2 -2
@@ -572,8 +572,8 @@ static int tsens_set_trips(void *_sensor, int low, int high)dev_dbg (dev,"[%u] %s: proposed thresholds: (%d:%d)\n" , hw_id, __func__, low, high); - cl_high =clamp_val (high,-40000 ,120000 ); - cl_low =clamp_val (low,-40000 ,120000 ); + cl_high =clamp_val (high, priv->feat->trip_min_temp, priv->feat->trip_max_temp); + cl_low =clamp_val (low, priv->feat->trip_min_temp, priv->feat->trip_max_temp); high_val =tsens_mC_to_hw (s, cl_high); low_val =tsens_mC_to_hw (s, cl_low);
drivers/thermal/qcom/tsens.h +4 -0
@@ -501,6 +501,8 @@ enum regfield_ids {* with SROT only being available to secure boot firmware? * @has_watchdog: does this IP support watchdog functionality? * @max_sensors: maximum sensors supported by this version of the IP +* @trip_min_temp: minimum trip temperature supported by this version of the IP +* @trip_max_temp: maximum trip temperature supported by this version of the IP */ struct tsens_features {unsigned int ver_major;
@@ -510,6 +512,8 @@ struct tsens_features { unsigned int srot_split:1; unsigned int has_watchdog:1;unsigned int max_sensors; +int trip_min_temp; +int trip_max_temp; };/**
Signature · 1 line
2.35.1
PATCH v3 4/5 drivers: thermal: tsens: add IPQ8074 support
In reply to Robert MarkoQualcomm IPQ8074 uses tsens v2.3 IP, however unlike other tsens v2 IP it only has one IRQ, that is used for up/low as well as critical. It also does not support negative trip temperatures.
--- drivers/thermal/qcom/tsens-v2.c | 17 +++++++++++++++++ drivers/thermal/qcom/tsens.c | 3 +++ drivers/thermal/qcom/tsens.h | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-)
drivers/thermal/qcom/tsens-v2.c +17 -0
@@ -39,6 +39,17 @@ static struct tsens_features tsens_v2_feat = { .trip_max_temp = 120000, }; +static struct tsens_features ipq8074_feat = { + .ver_major =VER_2_X , + .crit_int =1 , + .combo_int =1 , + .adc =0 , + .srot_split =1 , + .max_sensors =16 , + .trip_min_temp =0 , + .trip_max_temp =204000 , +}; +static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS ] = {/* ----- SROT ------ */ /* VERSION */
@@ -104,6 +115,12 @@ struct tsens_plat_data data_tsens_v2 = { .fields = tsens_v2_regfields, }; +struct tsens_plat_data data_ipq8074 = { + .ops = &ops_generic_v2, + .feat = &ipq8074_feat, + .fields = tsens_v2_regfields, +}; +/* Kept around for backward compatibility with old msm8996.dtsi */ struct tsens_plat_data data_8996 = { .num_sensors =13 ,
drivers/thermal/qcom/tsens.c +3 -0
@@ -990,6 +990,9 @@ static const struct of_device_id tsens_table[] = { { .compatible = "qcom,ipq8064-tsens", .data = &data_8960, + }, { + .compatible = "qcom,ipq8074-tsens", + .data = &data_ipq8074, }, { .compatible = "qcom,mdm9607-tsens", .data = &data_9607,
drivers/thermal/qcom/tsens.h +1 -1
@@ -599,6 +599,6 @@ extern struct tsens_plat_data data_8916, data_8939, data_8974, data_9607;extern struct tsens_plat_data data_tsens_v1, data_8976;/* TSENS v2 targets */ -extern struct tsens_plat_data data_8996, data_tsens_v2; +extern struct tsens_plat_data data_8996, data_ipq8074, data_tsens_v2;#endif /* __QCOM_TSENS_H__ */
Signature · 1 line
2.35.1
PATCH v3 5/5 arm64: dts: ipq8074: add thermal nodes
In reply to Robert MarkoIPQ8074 has a tsens v2.3.0 peripheral which monitors temperatures around the various subsystems on the die.
So lets add the tsens and thermal zone nodes, passive CPU cooling will come in later patches after CPU frequency scaling is supported.
--- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 96 +++++++++++++++++++++++++++ 1 file changed, 96 insertions(+)
arch/arm64/boot/dts/qcom/ipq8074.dtsi +96 -0
@@ -332,6 +332,16 @@ prng: rng@e3000 { status = "disabled"; }; + tsens: thermal-sensor@4a9000 { + compatible = "qcom,ipq8074-tsens"; + reg = <0x4a9000 0x1000>, /* TM */ + <0x4a8000 0x1000>; /* SROT */ + interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "combined"; + #qcom,sensors = <16>; + #thermal-sensor-cells = <1>; + }; + cryptobam: dma-controller@704000 { compatible = "qcom,bam-v1.7.0"; reg = <0x00704000 0x20000>;
@@ -1092,4 +1102,90 @@ wifi: wifi@c0000000 { status = "disabled"; }; }; + + thermal-zones { + nss-top-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 4>; + }; + + nss0-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 5>; + }; + + nss1-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 6>; + }; + + wcss-phya0-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 7>; + }; + + wcss-phya1-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 8>; + }; + + cpu0_thermal: cpu0-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 9>; + }; + + cpu1_thermal: cpu1-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 10>; + }; + + cpu2_thermal: cpu2-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 11>; + }; + + cpu3_thermal: cpu3-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 12>; + }; + + cluster_thermal: cluster-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 13>; + }; + + wcss-phyb0-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 14>; + }; + + wcss-phyb1-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 15>; + }; + }; };
Signature · 1 line
2.35.1