Skip to contentSkip to conversation

Add MT7987 Thermal support

PATCH Superseded Frank Wunderlich 4 participants 11 messages Oct 26, 2025 – Nov 14, 2025

Subsystems (3)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover Add MT7987 Thermal support

From: Frank Wunderlich <[email protected]>

This series adds Thermal support for MT7987.

Frank Wunderlich (5):
dt-bindings: thermal: mediatek: make interrupt only required for
current SoCs
dt-bindings: thermal: mediatek: Add LVTS thermal controller definition

    for MT7987

thermal/drivers/mediatek/lvts_thermal: Add no-irq-mode for mt7987 thermal/drivers/mediatek/lvts_thermal: Add SoC based golden Temp thermal/drivers/mediatek/lvts_thermal: Add mt7987 support

 .../thermal/mediatek,lvts-thermal.yaml        |  18 +++-
 drivers/thermal/mediatek/lvts_thermal.c       | 102 ++++++++++++++++--
 .../thermal/mediatek,lvts-thermal.h           |   3 +
 3 files changed, 111 insertions(+), 12 deletions(-)
Signature · 1 line
2.43.0
#1 lore raw

PATCH 1/5 dt-bindings: thermal: mediatek: make interrupt only required for current SoCs

From: Frank Wunderlich <[email protected]>

Upcoming MT7987 does not have a IRQ we have to make interrupt-property only required for current supported SoCs.

---
 .../bindings/thermal/mediatek,lvts-thermal.yaml | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml +16 -1
index 0259cd3ce9c5..7ec9c46eef22 100644
@@ -58,6 +58,16 @@ properties:
 allOf:
   - $ref: thermal-sensor.yaml#
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt7988-lvts-ap
+    then:
+      required:
+        - interrupts
+
   - if:
       properties:
         compatible:
@@ -75,6 +85,9 @@ allOf:
         nvmem-cell-names:
           maxItems: 1
 
+      required:
+        - interrupts
+
   - if:
       properties:
         compatible:
@@ -91,10 +104,12 @@ allOf:
         nvmem-cell-names:
           minItems: 2
 
+      required:
+        - interrupts
+
 required:
   - compatible
   - reg
-  - interrupts
   - clocks
   - resets
   - nvmem-cells
Signature · 1 line
2.43.0
#2 lore raw

Re: [PATCH v1 1/5] dt-bindings: thermal: mediatek: make interrupt only required for current SoCs

Il 26/10/25 13:21, Frank Wunderlich ha scritto:

Quoted 4 lines

From: Frank Wunderlich <[email protected]>

Upcoming MT7987 does not have a IRQ we have to make interrupt-property only required for current supported SoCs.

Hmm. Thermal sensor IP with no interrupt? Looks really strange.

This is odd, because LVTS always has multiple interrupts, and if this doesn't actually feature any, it really feels like the hardware is broken somehow.

MediaTek, can you please confirm whether the LVTS IP in MT7987 is really like that, or can you please give the right interrupt number to Frank?

Thanks,
Angelo

Quoted 51 lines
---
  .../bindings/thermal/mediatek,lvts-thermal.yaml | 17 ++++++++++++++++-
  1 file changed, 16 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml +16 -1
index 0259cd3ce9c5..7ec9c46eef22 100644
@@ -58,6 +58,16 @@ properties:
  allOf:
    - $ref: thermal-sensor.yaml#
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt7988-lvts-ap
+    then:
+      required:
+        - interrupts
+
    - if:
        properties:
          compatible:
@@ -75,6 +85,9 @@ allOf:
          nvmem-cell-names:
            maxItems: 1
 
+      required:
+        - interrupts
+
    - if:
        properties:
          compatible:
@@ -91,10 +104,12 @@ allOf:
          nvmem-cell-names:
            minItems: 2
 
+      required:
+        - interrupts
+
  required:
    - compatible
    - reg
-  - interrupts
    - clocks
    - resets
    - nvmem-cells
#3 lore raw

Re: [PATCH v1 1/5] dt-bindings: thermal: mediatek: make interrupt only required for current SoCs

Hi,

i got respoonse from MTK...

Am 2025-10-27 11:43, schrieb AngeloGioacchino Del Regno:

Quoted 6 lines

Il 26/10/25 13:21, Frank Wunderlich ha scritto:

Quoted 4 lines

From: Frank Wunderlich <[email protected]>

Upcoming MT7987 does not have a IRQ we have to make interrupt-property only required for current supported SoCs.

Quoted 8 lines

Hmm. Thermal sensor IP with no interrupt? Looks really strange.

This is odd, because LVTS always has multiple interrupts, and if this doesn't actually feature any, it really feels like the hardware is broken somehow.

MediaTek, can you please confirm whether the LVTS IP in MT7987 is really like that, or can you please give the right interrupt number to Frank?

the reason why the interrupt is disabled on MT7988/87 is because the original designer only intended for customers to use HW reset, and did not plan for customers to use high/low offset interrupts. However, in theory, this function can work.

see this part of driver-patch (3/5 "Add no-irq-mode for mt7987")

handling is divided into two cases: one is high/low offset, and the other is HW reset.

- writel(0, LVTS_MONINT(lvts_ctrl->base));
-
+ if (lvts_data->irq_enable) {
+ writel(0, LVTS_MONINT(lvts_ctrl->base));
+ } else {
+ writel(BIT(16), LVTS_PROTCTL(lvts_ctrl->base));
+ writel(lvts_ctrl->hw_reset_raw_temp, LVTS_PROTTC(lvts_ctrl->base));
+ }

HW Reset:
In BL2, we set the thermal_ctl_en (bit 16) of WDT_REQ_MODE (0x1001C030) to 1 so that the WDT can receive the HW reset signal from LVTS.
We also set thermal_ctl_irq (bit 16) of WDT_REQ_IRQ_EN (0x1001C034) to 1 so that when the WDT receives the LVTS HW reset signal, it will directly reset the IC.
LVTSMONCTRL, LVTSPROTCTL, and LVTSPROTTC are used to control the HW reset strategy and temperature.

High/Low Offset:
Since multiple sensors share the high/low offset settings, the high/low offset temperature will be set when we echo the temperature to thermal_zoneX/trip_point_X (call lvts_set_trips function). Whenever any sensor's temperature is higher or lower than the high/low offset, it will trigger an IRQ (call lvts_irq_handle).

Currently we are discussing a way to verify this function works in hardware and then we can add IRQ for mt7987 (which is same as on mt7988 where i did not know till now that IRQ is not known as working - just ported driver + dts and checked temperature output and thermal-trip handling regarding to fan). And if it works we could drop patches for no-irq-mode.

Quoted 2 lines

Thanks,
Angelo

regards Frank

#4 lore raw

PATCH 2/5 dt-bindings: thermal: mediatek: Add LVTS thermal controller definition for MT7987

In reply to Frank Wunderlich

From: Frank Wunderlich <[email protected]>

Add thermal controller definition for MT7987.

---
 .../devicetree/bindings/thermal/mediatek,lvts-thermal.yaml     | 1 +
 include/dt-bindings/thermal/mediatek,lvts-thermal.h            | 3 +++
 2 files changed, 4 insertions(+)
Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml +1 -0
index 7ec9c46eef22..13e948a2a909 100644
@@ -18,6 +18,7 @@ description: |
 properties:
   compatible:
     enum:
+      - mediatek,mt7987-lvts-ap
       - mediatek,mt7988-lvts-ap
       - mediatek,mt8186-lvts
       - mediatek,mt8188-lvts-ap
include/dt-bindings/thermal/mediatek,lvts-thermal.h +3 -0
index ddc7302a510a..e9780edcd26c 100644
@@ -7,6 +7,9 @@
 #ifndef __MEDIATEK_LVTS_DT_H
 #define __MEDIATEK_LVTS_DT_H
 
+#define MT7987_CPU		0
+#define MT7987_ETH2P5G		1
+
 #define MT7988_CPU_0		0
 #define MT7988_CPU_1		1
 #define MT7988_ETH2P5G_0	2
Signature · 1 line
2.43.0
maintainer Acked-by on v1 2/5
#5 lore raw

Re: [PATCH v1 2/5] dt-bindings: thermal: mediatek: Add LVTS thermal controller definition for MT7987

Quoted 10 lines · Frank Wunderlich

From: Frank Wunderlich <[email protected]>

Add thermal controller definition for MT7987.

---
 .../devicetree/bindings/thermal/mediatek,lvts-thermal.yaml     | 1 +
 include/dt-bindings/thermal/mediatek,lvts-thermal.h            | 3 +++
 2 files changed, 4 insertions(+)
#6 lore raw

PATCH 3/5 thermal/drivers/mediatek/lvts_thermal: Add no-irq-mode for mt7987

In reply to Frank Wunderlich

From: Frank Wunderlich <[email protected]>

Upcoming MT7987 does not have IRQ for thermal. Add a field in lvts_data to configure this based on SoC.

---
 drivers/thermal/mediatek/lvts_thermal.c | 51 ++++++++++++++++++++-----
 1 file changed, 41 insertions(+), 10 deletions(-)
drivers/thermal/mediatek/lvts_thermal.c +41 -10
index ab55b20cda47..9413b30f7b69 100644
@@ -94,6 +94,8 @@
 #define LVTS_MSR_READ_TIMEOUT_US	400
 #define LVTS_MSR_READ_WAIT_US		(LVTS_MSR_READ_TIMEOUT_US / 2)
 
+#define LVTS_HW_RESET_TEMP		125000
+
 #define LVTS_MINIMUM_THRESHOLD		20000
 
 static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
@@ -134,6 +136,7 @@ struct lvts_data {
 	int temp_offset;
 	int gt_calib_bit_offset;
 	unsigned int def_calibration;
+	bool irq_enable;
 };
 
 struct lvts_sensor {
@@ -151,6 +154,7 @@ struct lvts_ctrl {
 	const struct lvts_data *lvts_data;
 	u32 calibration[LVTS_SENSOR_MAX];
 	u8 valid_sensor_mask;
+	u32 hw_reset_raw_temp;
 	int mode;
 	void __iomem *base;
 	int low_thresh;
@@ -410,6 +414,9 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
 	}
 	lvts_update_irq_mask(lvts_ctrl);
 
+	if (!lvts_data->irq_enable)
+		return 0;
+
 	if (!should_update_thresh)
 		return 0;
 
@@ -859,6 +866,14 @@ static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td,
 		 */
 		lvts_ctrl[i].mode = lvts_data->lvts_ctrl[i].mode;
 
+		/*
+		 * The temperature to raw temperature must be done
+		 * after initializing the calibration.
+		 */
+		lvts_ctrl[i].hw_reset_raw_temp =
+			lvts_temp_to_raw(LVTS_HW_RESET_TEMP,
+					 lvts_data->temp_factor);
+
 		lvts_ctrl[i].low_thresh = INT_MIN;
 		lvts_ctrl[i].high_thresh = INT_MIN;
 	}
@@ -915,12 +930,13 @@ static void lvts_write_config(struct lvts_ctrl *lvts_ctrl, const u32 *cmds, int
 	 */
 	for (i = 0; i < nr_cmds; i++) {
 		writel(cmds[i], LVTS_CONFIG(lvts_ctrl->base));
-		usleep_range(2, 4);
+		usleep_range(5, 15);
 	}
 }
 
 static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
 {
+	const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
 	/*
 	 * LVTS_PROTCTL : Thermal Protection Sensor Selection
 	 *
@@ -954,8 +970,12 @@ static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
 	 * The LVTS_MONINT register layout is the same as the LVTS_MONINTSTS
 	 * register, except we set the bits to enable the interrupt.
 	 */
-	writel(0, LVTS_MONINT(lvts_ctrl->base));
-
+	if (lvts_data->irq_enable) {
+		writel(0, LVTS_MONINT(lvts_ctrl->base));
+	} else {
+		writel(BIT(16), LVTS_PROTCTL(lvts_ctrl->base));
+		writel(lvts_ctrl->hw_reset_raw_temp, LVTS_PROTTC(lvts_ctrl->base));
+	}
 	return 0;
 }
 
@@ -1338,9 +1358,11 @@ static int lvts_probe(struct platform_device *pdev)
 	if (IS_ERR(lvts_td->reset))
 		return dev_err_probe(dev, PTR_ERR(lvts_td->reset), "Failed to get reset control\n");
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
+	if (lvts_data->irq_enable) {
+		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return irq;
+	}
 
 	golden_temp_offset = lvts_data->temp_offset;
 
@@ -1352,10 +1374,12 @@ static int lvts_probe(struct platform_device *pdev)
 	 * At this point the LVTS is initialized and enabled. We can
 	 * safely enable the interrupt.
 	 */
-	ret = devm_request_threaded_irq(dev, irq, NULL, lvts_irq_handler,
-					IRQF_ONESHOT, dev_name(dev), lvts_td);
-	if (ret)
-		return dev_err_probe(dev, ret, "Failed to request interrupt\n");
+	if (lvts_data->irq_enable) {
+		ret = devm_request_threaded_irq(dev, irq, NULL, lvts_irq_handler,
+						IRQF_ONESHOT, dev_name(dev), lvts_td);
+		if (ret)
+			return dev_err_probe(dev, ret, "Failed to request interrupt\n");
+	}
 
 	platform_set_drvdata(pdev, lvts_td);
 
@@ -1763,6 +1787,7 @@ static const struct lvts_data mt7988_lvts_ap_data = {
 	.temp_factor	= LVTS_COEFF_A_MT7988,
 	.temp_offset	= LVTS_COEFF_B_MT7988,
 	.gt_calib_bit_offset = 24,
+	.irq_enable = true, //SDK false
 };
 
 static const struct lvts_data mt8186_lvts_data = {
@@ -1776,6 +1801,7 @@ static const struct lvts_data mt8186_lvts_data = {
 	.temp_offset	= LVTS_COEFF_B_MT7988,
 	.gt_calib_bit_offset = 24,
 	.def_calibration = 19000,
+	.irq_enable = true,
 };
 
 static const struct lvts_data mt8188_lvts_mcu_data = {
@@ -1789,6 +1815,7 @@ static const struct lvts_data mt8188_lvts_mcu_data = {
 	.temp_offset	= LVTS_COEFF_B_MT8195,
 	.gt_calib_bit_offset = 20,
 	.def_calibration = 35000,
+	.irq_enable = true,
 };
 
 static const struct lvts_data mt8188_lvts_ap_data = {
@@ -1802,6 +1829,7 @@ static const struct lvts_data mt8188_lvts_ap_data = {
 	.temp_offset	= LVTS_COEFF_B_MT8195,
 	.gt_calib_bit_offset = 20,
 	.def_calibration = 35000,
+	.irq_enable = true,
 };
 
 static const struct lvts_data mt8192_lvts_mcu_data = {
@@ -1815,6 +1843,7 @@ static const struct lvts_data mt8192_lvts_mcu_data = {
 	.temp_offset	= LVTS_COEFF_B_MT8195,
 	.gt_calib_bit_offset = 24,
 	.def_calibration = 35000,
+	.irq_enable = true,
 };
 
 static const struct lvts_data mt8192_lvts_ap_data = {
@@ -1828,6 +1857,7 @@ static const struct lvts_data mt8192_lvts_ap_data = {
 	.temp_offset	= LVTS_COEFF_B_MT8195,
 	.gt_calib_bit_offset = 24,
 	.def_calibration = 35000,
+	.irq_enable = true,
 };
 
 static const struct lvts_data mt8195_lvts_mcu_data = {
@@ -1841,6 +1871,7 @@ static const struct lvts_data mt8195_lvts_mcu_data = {
 	.temp_offset	= LVTS_COEFF_B_MT8195,
 	.gt_calib_bit_offset = 24,
 	.def_calibration = 35000,
+	.irq_enable = true,
 };
 
 static const struct lvts_data mt8195_lvts_ap_data = {
Signature · 1 line
2.43.0
#7 lore raw

PATCH 4/5 thermal/drivers/mediatek/lvts_thermal: Add SoC based golden Temp

In reply to Frank Wunderlich

From: Frank Wunderlich <[email protected]>

Add SoC based golden temp for invalid efuse data.

This is a preliminary patch for mt7987 support where goldentemp is slightly higher than other SOCs.

---
 drivers/thermal/mediatek/lvts_thermal.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/thermal/mediatek/lvts_thermal.c +12 -1
index 9413b30f7b69..544941e8219a 100644
@@ -134,6 +134,7 @@ struct lvts_data {
 	int num_init_cmd;
 	int temp_factor;
 	int temp_offset;
+	int golden_temp;
 	int gt_calib_bit_offset;
 	unsigned int def_calibration;
 	bool irq_enable;
@@ -811,8 +812,10 @@ static int lvts_golden_temp_init(struct device *dev, u8 *calib,
 	gt = (((u32 *)calib)[0] >> lvts_data->gt_calib_bit_offset) & 0xff;
 
 	/* A zero value for gt means that device has invalid efuse data */
-	if (gt && gt < LVTS_GOLDEN_TEMP_MAX)
+	if (gt && gt <= LVTS_GOLDEN_TEMP_MAX)
 		golden_temp = gt;
+	else
+		golden_temp = lvts_data->golden_temp;
 
 	golden_temp_offset = golden_temp * 500 + lvts_data->temp_offset;
 
@@ -1786,6 +1789,7 @@ static const struct lvts_data mt7988_lvts_ap_data = {
 	.num_init_cmd	= ARRAY_SIZE(mt7988_init_cmds),
 	.temp_factor	= LVTS_COEFF_A_MT7988,
 	.temp_offset	= LVTS_COEFF_B_MT7988,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
 	.gt_calib_bit_offset = 24,
 	.irq_enable = true, //SDK false
 };
@@ -1799,6 +1803,7 @@ static const struct lvts_data mt8186_lvts_data = {
 	.num_init_cmd	= ARRAY_SIZE(default_init_cmds),
 	.temp_factor	= LVTS_COEFF_A_MT7988,
 	.temp_offset	= LVTS_COEFF_B_MT7988,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
 	.gt_calib_bit_offset = 24,
 	.def_calibration = 19000,
 	.irq_enable = true,
@@ -1813,6 +1818,7 @@ static const struct lvts_data mt8188_lvts_mcu_data = {
 	.num_init_cmd	= ARRAY_SIZE(default_init_cmds),
 	.temp_factor	= LVTS_COEFF_A_MT8195,
 	.temp_offset	= LVTS_COEFF_B_MT8195,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
 	.gt_calib_bit_offset = 20,
 	.def_calibration = 35000,
 	.irq_enable = true,
@@ -1827,6 +1833,7 @@ static const struct lvts_data mt8188_lvts_ap_data = {
 	.num_init_cmd	= ARRAY_SIZE(default_init_cmds),
 	.temp_factor	= LVTS_COEFF_A_MT8195,
 	.temp_offset	= LVTS_COEFF_B_MT8195,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
 	.gt_calib_bit_offset = 20,
 	.def_calibration = 35000,
 	.irq_enable = true,
@@ -1841,6 +1848,7 @@ static const struct lvts_data mt8192_lvts_mcu_data = {
 	.num_init_cmd	= ARRAY_SIZE(default_init_cmds),
 	.temp_factor	= LVTS_COEFF_A_MT8195,
 	.temp_offset	= LVTS_COEFF_B_MT8195,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
 	.gt_calib_bit_offset = 24,
 	.def_calibration = 35000,
 	.irq_enable = true,
@@ -1855,6 +1863,7 @@ static const struct lvts_data mt8192_lvts_ap_data = {
 	.num_init_cmd	= ARRAY_SIZE(default_init_cmds),
 	.temp_factor	= LVTS_COEFF_A_MT8195,
 	.temp_offset	= LVTS_COEFF_B_MT8195,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
 	.gt_calib_bit_offset = 24,
 	.def_calibration = 35000,
 	.irq_enable = true,
@@ -1869,6 +1878,7 @@ static const struct lvts_data mt8195_lvts_mcu_data = {
 	.num_init_cmd	= ARRAY_SIZE(default_init_cmds),
 	.temp_factor	= LVTS_COEFF_A_MT8195,
 	.temp_offset	= LVTS_COEFF_B_MT8195,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
 	.gt_calib_bit_offset = 24,
 	.def_calibration = 35000,
 	.irq_enable = true,
@@ -1883,6 +1893,7 @@ static const struct lvts_data mt8195_lvts_ap_data = {
 	.num_init_cmd	= ARRAY_SIZE(default_init_cmds),
 	.temp_factor	= LVTS_COEFF_A_MT8195,
 	.temp_offset	= LVTS_COEFF_B_MT8195,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
 	.gt_calib_bit_offset = 24,
 	.def_calibration = 35000,
 };
Signature · 1 line
2.43.0
#8 lore raw

Re: [PATCH v1 4/5] thermal/drivers/mediatek/lvts_thermal: Add SoC based golden Temp

Il 26/10/25 13:21, Frank Wunderlich ha scritto:

Quoted 7 lines

From: Frank Wunderlich <[email protected]>

Add SoC based golden temp for invalid efuse data.

This is a preliminary patch for mt7987 support where goldentemp is slightly higher than other SOCs.

I've found this "hack" required for all of the preproduction SoCs, as those are usually unfused and/or missing at least some calibration parameters.

Are you using an early/preproduction/whatever SoC, or are you testing on a retail board?

Regards,
Angelo

Quoted 93 lines
---
  drivers/thermal/mediatek/lvts_thermal.c | 13 ++++++++++++-
  1 file changed, 12 insertions(+), 1 deletion(-)
drivers/thermal/mediatek/lvts_thermal.c +12 -1
index 9413b30f7b69..544941e8219a 100644
@@ -134,6 +134,7 @@ struct lvts_data {
  	int num_init_cmd;
  	int temp_factor;
  	int temp_offset;
+	int golden_temp;
  	int gt_calib_bit_offset;
  	unsigned int def_calibration;
  	bool irq_enable;
@@ -811,8 +812,10 @@ static int lvts_golden_temp_init(struct device *dev, u8 *calib,
  	gt = (((u32 *)calib)[0] >> lvts_data->gt_calib_bit_offset) & 0xff;
 
  	/* A zero value for gt means that device has invalid efuse data */
-	if (gt && gt < LVTS_GOLDEN_TEMP_MAX)
+	if (gt && gt <= LVTS_GOLDEN_TEMP_MAX)
  		golden_temp = gt;
+	else
+		golden_temp = lvts_data->golden_temp;
 
  	golden_temp_offset = golden_temp * 500 + lvts_data->temp_offset;
 
@@ -1786,6 +1789,7 @@ static const struct lvts_data mt7988_lvts_ap_data = {
  	.num_init_cmd	= ARRAY_SIZE(mt7988_init_cmds),
  	.temp_factor	= LVTS_COEFF_A_MT7988,
  	.temp_offset	= LVTS_COEFF_B_MT7988,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
  	.gt_calib_bit_offset = 24,
  	.irq_enable = true, //SDK false
  };
@@ -1799,6 +1803,7 @@ static const struct lvts_data mt8186_lvts_data = {
  	.num_init_cmd	= ARRAY_SIZE(default_init_cmds),
  	.temp_factor	= LVTS_COEFF_A_MT7988,
  	.temp_offset	= LVTS_COEFF_B_MT7988,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
  	.gt_calib_bit_offset = 24,
  	.def_calibration = 19000,
  	.irq_enable = true,
@@ -1813,6 +1818,7 @@ static const struct lvts_data mt8188_lvts_mcu_data = {
  	.num_init_cmd	= ARRAY_SIZE(default_init_cmds),
  	.temp_factor	= LVTS_COEFF_A_MT8195,
  	.temp_offset	= LVTS_COEFF_B_MT8195,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
  	.gt_calib_bit_offset = 20,
  	.def_calibration = 35000,
  	.irq_enable = true,
@@ -1827,6 +1833,7 @@ static const struct lvts_data mt8188_lvts_ap_data = {
  	.num_init_cmd	= ARRAY_SIZE(default_init_cmds),
  	.temp_factor	= LVTS_COEFF_A_MT8195,
  	.temp_offset	= LVTS_COEFF_B_MT8195,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
  	.gt_calib_bit_offset = 20,
  	.def_calibration = 35000,
  	.irq_enable = true,
@@ -1841,6 +1848,7 @@ static const struct lvts_data mt8192_lvts_mcu_data = {
  	.num_init_cmd	= ARRAY_SIZE(default_init_cmds),
  	.temp_factor	= LVTS_COEFF_A_MT8195,
  	.temp_offset	= LVTS_COEFF_B_MT8195,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
  	.gt_calib_bit_offset = 24,
  	.def_calibration = 35000,
  	.irq_enable = true,
@@ -1855,6 +1863,7 @@ static const struct lvts_data mt8192_lvts_ap_data = {
  	.num_init_cmd	= ARRAY_SIZE(default_init_cmds),
  	.temp_factor	= LVTS_COEFF_A_MT8195,
  	.temp_offset	= LVTS_COEFF_B_MT8195,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
  	.gt_calib_bit_offset = 24,
  	.def_calibration = 35000,
  	.irq_enable = true,
@@ -1869,6 +1878,7 @@ static const struct lvts_data mt8195_lvts_mcu_data = {
  	.num_init_cmd	= ARRAY_SIZE(default_init_cmds),
  	.temp_factor	= LVTS_COEFF_A_MT8195,
  	.temp_offset	= LVTS_COEFF_B_MT8195,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
  	.gt_calib_bit_offset = 24,
  	.def_calibration = 35000,
  	.irq_enable = true,
@@ -1883,6 +1893,7 @@ static const struct lvts_data mt8195_lvts_ap_data = {
  	.num_init_cmd	= ARRAY_SIZE(default_init_cmds),
  	.temp_factor	= LVTS_COEFF_A_MT8195,
  	.temp_offset	= LVTS_COEFF_B_MT8195,
+	.golden_temp	= LVTS_GOLDEN_TEMP_DEFAULT,
  	.gt_calib_bit_offset = 24,
  	.def_calibration = 35000,
  };
#9 lore raw

Aw: Re: [PATCH v1 4/5] thermal/drivers/mediatek/lvts_thermal: Add SoC based golden Temp

Hi Angelo,

Quoted 13 lines

Gesendet: Montag, 27. Oktober 2025 um 11:45
Von: "AngeloGioacchino Del Regno" <[email protected]>
Betreff: Re: [PATCH v1 4/5] thermal/drivers/mediatek/lvts_thermal: Add SoC based golden Temp

Il 26/10/25 13:21, Frank Wunderlich ha scritto:

Quoted 7 lines

From: Frank Wunderlich <[email protected]>

Add SoC based golden temp for invalid efuse data.

This is a preliminary patch for mt7987 support where goldentemp is slightly higher than other SOCs.

Quoted 5 lines

I've found this "hack" required for all of the preproduction SoCs, as those are usually unfused and/or missing at least some calibration parameters.

Are you using an early/preproduction/whatever SoC, or are you testing on a retail board?

thanks for looking into it. I'm using a Bananapi R4 Lite v1.1 so not pre-production SoC afaik.

Not sure why i ported this patch from sdk (maybe due to patch compatibility and thinking this is needed). Tested without it and it seems to work as far as i can tell. Will drop it in next round.

For the no-irq part i also ported this from SDK where no irq is defined (i also wondered about missing irq-support as it would require polling to handle emergency shutdown which seems not done in sdk too):

https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/HEAD/autobuild/unified/filogic/24.10/files/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7987.dtsi#556

https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/HEAD/autobuild/unified/filogic/24.10/files/target/linux/mediatek/patches-6.6/999-2101-thermal-mediatek-add-mt7987-lvts-support.patch#160

the irq_enable part is squashed with the mt7988 lvts support:

https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/HEAD/autobuild/unified/filogic/24.10/files/target/linux/mediatek/patches-6.6/999-2100-thermal-mediatek-add-mt7988-lvts-support.patch#110

regards Frank

Quoted 7 lines

Regards,
Angelo

Quoted 4 lines
---
  drivers/thermal/mediatek/lvts_thermal.c | 13 ++++++++++++-
  1 file changed, 12 insertions(+), 1 deletion(-)
#10 lore raw

PATCH 5/5 thermal/drivers/mediatek/lvts_thermal: Add mt7987 support

In reply to Frank Wunderlich

From: Frank Wunderlich <[email protected]>

Add support for MT7987.

---
 drivers/thermal/mediatek/lvts_thermal.c | 38 +++++++++++++++++++++++++
 1 file changed, 38 insertions(+)
drivers/thermal/mediatek/lvts_thermal.c +38 -0
index 544941e8219a..1d800bdf4a24 100644
@@ -87,6 +87,8 @@
 #define LVTS_COEFF_B_MT8195			250460
 #define LVTS_COEFF_A_MT7988			-204650
 #define LVTS_COEFF_B_MT7988			204650
+#define LVTS_COEFF_A_MT7987			-204650
+#define LVTS_COEFF_B_MT7987			204650
 
 #define LVTS_MSR_IMMEDIATE_MODE		0
 #define LVTS_MSR_FILTERED_MODE		1
@@ -1400,6 +1402,20 @@ static void lvts_remove(struct platform_device *pdev)
 		lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
 }
 
+static const struct lvts_ctrl_data mt7987_lvts_ap_data_ctrl[] = {
+	{
+		.lvts_sensor = {
+			{ .dt_id = MT7987_CPU,
+			  .cal_offsets = { 0x04, 0x05, 0x06 } },
+			{ .dt_id = MT7987_ETH2P5G,
+			  .cal_offsets = { 0x08, 0x09, 0x0a } },
+		},
+		VALID_SENSOR_MAP(1, 1, 0, 0),
+		.offset = 0x0,
+		.mode = LVTS_MSR_FILTERED_MODE,
+	},
+};
+
 static const struct lvts_ctrl_data mt7988_lvts_ap_data_ctrl[] = {
 	{
 		.lvts_sensor = {
@@ -1482,6 +1498,12 @@ static const u32 default_init_cmds[] = {
 	0xC10300FC, 0xC103009D, 0xC10300F1, 0xC10300E1
 };
 
+static const u32 mt7987_init_cmds[] = {
+	0xC1030300, 0xC1030420, 0xC1030500, 0xC10307A6, 0xC10308C7,
+	0xC103098D, 0xC1030C7C, 0xC1030AA8, 0xC10308CE, 0xC10308C7,
+	0xC1030B04, 0xC1030E01, 0xC10306B8
+};
+
 static const u32 mt7988_init_cmds[] = {
 	0xC1030300, 0xC1030420, 0xC1030500, 0xC10307A6, 0xC1030CFC,
 	0xC1030A8C, 0xC103098D, 0xC10308F1, 0xC1030B04, 0xC1030E01,
@@ -1780,6 +1802,21 @@ static const struct lvts_ctrl_data mt8195_lvts_ap_data_ctrl[] = {
 	}
 };
 
+static const struct lvts_data mt7987_lvts_ap_data = {
+	.lvts_ctrl	= mt7987_lvts_ap_data_ctrl,
+	.num_lvts_ctrl	= ARRAY_SIZE(mt7987_lvts_ap_data_ctrl),
+	.conn_cmd	= mt7988_conn_cmds,
+	.init_cmd	= mt7987_init_cmds,
+	.num_conn_cmd	= ARRAY_SIZE(mt7988_conn_cmds),
+	.num_init_cmd	= ARRAY_SIZE(mt7987_init_cmds),
+	.temp_factor	= LVTS_COEFF_A_MT7987,
+	.temp_offset	= LVTS_COEFF_B_MT7987,
+	.golden_temp	= 60,
+	.gt_calib_bit_offset = 32,
+	.def_calibration = 19380,
+	.irq_enable	= false,
+};
+
 static const struct lvts_data mt7988_lvts_ap_data = {
 	.lvts_ctrl	= mt7988_lvts_ap_data_ctrl,
 	.conn_cmd	= mt7988_conn_cmds,
@@ -1899,6 +1936,7 @@ static const struct lvts_data mt8195_lvts_ap_data = {
 };
 
 static const struct of_device_id lvts_of_match[] = {
+	{ .compatible = "mediatek,mt7987-lvts-ap", .data = &mt7987_lvts_ap_data },
 	{ .compatible = "mediatek,mt7988-lvts-ap", .data = &mt7988_lvts_ap_data },
 	{ .compatible = "mediatek,mt8186-lvts", .data = &mt8186_lvts_data },
 	{ .compatible = "mediatek,mt8188-lvts-mcu", .data = &mt8188_lvts_mcu_data },
Signature · 1 line
2.43.0