]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
mediatek: port MT7987 thermal support
authorDaniel Golle <daniel@makrotopia.org>
Sun, 5 Oct 2025 02:40:27 +0000 (03:40 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Wed, 5 Nov 2025 14:19:40 +0000 (14:19 +0000)
The MT7987 has two LVTS thermal sensors, one covering all CPU cores,
and one for the built-in 2.5GE PHY.
Add support for MT7987 to the LVTS thermal driver.
Thanks to Chad Monroe of Adtran for providing cleaned up patches for
Linux 6.6 which have been ported to Linux 6.12.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
target/linux/mediatek/patches-6.12/830-thermal-drivers-mediatek-lvts_thermal-Add-irq_enable-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/831-thermal-drivers-mediatek-lvts_thermal-Add-MT7987-support.patch [new file with mode: 0644]

diff --git a/target/linux/mediatek/patches-6.12/830-thermal-drivers-mediatek-lvts_thermal-Add-irq_enable-support.patch b/target/linux/mediatek/patches-6.12/830-thermal-drivers-mediatek-lvts_thermal-Add-irq_enable-support.patch
new file mode 100644 (file)
index 0000000..ff1fd3e
--- /dev/null
@@ -0,0 +1,148 @@
+From: Chad Monroe <chad@monroe.io>
+Date: Mon, 01 Sep 2025 06:42:10 -0700
+Subject: [PATCH] thermal/drivers/mediatek/lvts_thermal: Add irq_enable
+ support.
+
+Allow interrupt support to be disabled as some SoCs don't support it.
+
+Signed-off-by: Chad Monroe <chad@monroe.io>
+---
+ drivers/thermal/mediatek/lvts_thermal.c |   33 ++++++++++++++++------
+ 1 file changed, 25 insertions(+), 8 deletions(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -127,6 +127,7 @@ struct lvts_data {
+       const struct lvts_ctrl_data *lvts_ctrl;
+       const u32 *conn_cmd;
+       const u32 *init_cmd;
++      bool irq_enable;
+       int num_lvts_ctrl;
+       int num_conn_cmd;
+       int num_init_cmd;
+@@ -408,6 +409,10 @@ static int lvts_set_trips(struct thermal
+               lvts_ctrl->high_thresh = high;
+               lvts_ctrl->low_thresh = low;
+       }
++
++      if (!lvts_data->irq_enable)
++              return 0;
++
+       lvts_update_irq_mask(lvts_ctrl);
+       if (!should_update_thresh)
+@@ -921,6 +926,8 @@ static void lvts_write_config(struct lvt
+ 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,7 +961,8 @@ static int lvts_irq_init(struct lvts_ctr
+        * 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));
+       return 0;
+ }
+@@ -1338,9 +1346,11 @@ static int lvts_probe(struct platform_de
+       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 +1362,12 @@ static int lvts_probe(struct platform_de
+        * 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);
+@@ -1754,6 +1766,7 @@ static const struct lvts_ctrl_data mt819
+ };
+ static const struct lvts_data mt7988_lvts_ap_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt7988_lvts_ap_data_ctrl,
+       .conn_cmd       = mt7988_conn_cmds,
+       .init_cmd       = mt7988_init_cmds,
+@@ -1766,6 +1779,7 @@ static const struct lvts_data mt7988_lvt
+ };
+ static const struct lvts_data mt8186_lvts_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt8186_lvts_data_ctrl,
+       .conn_cmd       = default_conn_cmds,
+       .init_cmd       = default_init_cmds,
+@@ -1779,6 +1793,7 @@ static const struct lvts_data mt8186_lvt
+ };
+ static const struct lvts_data mt8188_lvts_mcu_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt8188_lvts_mcu_data_ctrl,
+       .conn_cmd       = default_conn_cmds,
+       .init_cmd       = default_init_cmds,
+@@ -1792,6 +1807,7 @@ static const struct lvts_data mt8188_lvt
+ };
+ static const struct lvts_data mt8188_lvts_ap_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt8188_lvts_ap_data_ctrl,
+       .conn_cmd       = default_conn_cmds,
+       .init_cmd       = default_init_cmds,
+@@ -1805,6 +1821,7 @@ static const struct lvts_data mt8188_lvt
+ };
+ static const struct lvts_data mt8192_lvts_mcu_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt8192_lvts_mcu_data_ctrl,
+       .conn_cmd       = default_conn_cmds,
+       .init_cmd       = default_init_cmds,
+@@ -1818,6 +1835,7 @@ static const struct lvts_data mt8192_lvt
+ };
+ static const struct lvts_data mt8192_lvts_ap_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt8192_lvts_ap_data_ctrl,
+       .conn_cmd       = default_conn_cmds,
+       .init_cmd       = default_init_cmds,
+@@ -1831,6 +1849,7 @@ static const struct lvts_data mt8192_lvt
+ };
+ static const struct lvts_data mt8195_lvts_mcu_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt8195_lvts_mcu_data_ctrl,
+       .conn_cmd       = default_conn_cmds,
+       .init_cmd       = default_init_cmds,
+@@ -1844,6 +1863,7 @@ static const struct lvts_data mt8195_lvt
+ };
+ static const struct lvts_data mt8195_lvts_ap_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt8195_lvts_ap_data_ctrl,
+       .conn_cmd       = default_conn_cmds,
+       .init_cmd       = default_init_cmds,
diff --git a/target/linux/mediatek/patches-6.12/831-thermal-drivers-mediatek-lvts_thermal-Add-MT7987-support.patch b/target/linux/mediatek/patches-6.12/831-thermal-drivers-mediatek-lvts_thermal-Add-MT7987-support.patch
new file mode 100644 (file)
index 0000000..7cd4aff
--- /dev/null
@@ -0,0 +1,106 @@
+From: Chad Monroe <chad@monroe.io>
+Date: Mon, 01 Sep 2025 06:44:04 -0700
+Subject: [PATCH] thermal/drivers/mediatek/lvts_thermal: Add MT7987 support 
+
+Add support for Mediatek MT7987 LVTS. Based patch[1] from vendor  SDK.
+
+1: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/742007e189ffcc95783924cea1150f574b6eb71e
+
+Signed-off-by: Chad Monroe <chad@monroe.io>
+---
+ drivers/thermal/mediatek/lvts_thermal.c             |   36 ++++++++++
+ include/dt-bindings/thermal/mediatek,lvts-thermal.h |    3 
+ 2 files changed, 39 insertions(+)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -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
+@@ -1385,6 +1387,19 @@ static void lvts_remove(struct platform_
+               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,
++      },
++};
++
+ static const struct lvts_ctrl_data mt7988_lvts_ap_data_ctrl[] = {
+       {
+               .lvts_sensor = {
+@@ -1455,6 +1470,7 @@ static int lvts_resume(struct device *de
+ }
+ static const u32 default_conn_cmds[] = { 0xC103FFFF, 0xC502FF55 };
++static const u32 mt7987_conn_cmds[] = { 0xC103FFFF, 0xC502FC55 };
+ static const u32 mt7988_conn_cmds[] = { 0xC103FFFF, 0xC502FC55 };
+ /*
+@@ -1467,6 +1483,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,
+@@ -1765,6 +1787,19 @@ static const struct lvts_ctrl_data mt819
+       }
+ };
++static const struct lvts_data mt7987_lvts_ap_data = {
++      .irq_enable     = false,
++      .lvts_ctrl      = mt7987_lvts_ap_data_ctrl,
++      .conn_cmd       = mt7987_conn_cmds,
++      .init_cmd       = mt7987_init_cmds,
++      .num_lvts_ctrl  = ARRAY_SIZE(mt7987_lvts_ap_data_ctrl),
++      .num_conn_cmd   = ARRAY_SIZE(mt7987_conn_cmds),
++      .num_init_cmd   = ARRAY_SIZE(mt7987_init_cmds),
++      .temp_factor    = LVTS_COEFF_A_MT7987,
++      .temp_offset    = LVTS_COEFF_B_MT7987,
++      .gt_calib_bit_offset = 24,
++};
++
+ static const struct lvts_data mt7988_lvts_ap_data = {
+       .irq_enable     = true,
+       .lvts_ctrl      = mt7988_lvts_ap_data_ctrl,
+@@ -1877,6 +1912,7 @@ static const struct lvts_data mt8195_lvt
+ };
+ 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 },
+--- a/include/dt-bindings/thermal/mediatek,lvts-thermal.h
++++ b/include/dt-bindings/thermal/mediatek,lvts-thermal.h
+@@ -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