]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
thermal/drivers/mediatek/lvts_thermal: Add MT8196 support
authorLaura Nao <laura.nao@collabora.com>
Tue, 25 Nov 2025 16:16:57 +0000 (17:16 +0100)
committerDaniel Lezcano <daniel.lezcano@linaro.org>
Tue, 20 Jan 2026 19:41:49 +0000 (20:41 +0100)
Add LVTS driver support for MT8196.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Tested-by: Frank Wunderlich <frank-w@public-files.de>
Signed-off-by: Laura Nao <laura.nao@collabora.com>
Link: https://patch.msgid.link/20251125-mt8196-lvts-v4-v5-7-6db7eb903fb7@collabora.com
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
drivers/thermal/mediatek/lvts_thermal.c

index 93eb62cae5120a733458e83698cdf2fcb6bef0db..cb68494f086ce0420d01977e4da715289de159f9 100644 (file)
 #define LVTS_COEFF_B_MT8195                    250460
 #define LVTS_COEFF_A_MT7988                    -204650
 #define LVTS_COEFF_B_MT7988                    204650
+#define LVTS_COEFF_A_MT8196                    391460
+#define LVTS_COEFF_B_MT8196                    -391460
+
+#define LVTS_MSR_OFFSET_MT8196         -984
 
 #define LVTS_MSR_READ_TIMEOUT_US       400
 #define LVTS_MSR_READ_WAIT_US          (LVTS_MSR_READ_TIMEOUT_US / 2)
 
 #define LVTS_MAX_CAL_OFFSETS           3
 #define LVTS_NUM_CAL_OFFSETS_MT7988    3
+#define LVTS_NUM_CAL_OFFSETS_MT8196    2
 
 static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
 static int golden_temp_offset;
@@ -784,6 +789,39 @@ static int lvts_decode_sensor_calibration(const struct lvts_sensor_data *sensor,
  * <-----ap--tc#3-----> <-----sensor#7-----> <-----sensor#8----->
  *  0x40 | 0x41 | 0x42 | 0x43 | 0x44 | 0x45 | 0x46 | 0x47 | 0x48
  *
+ * MT8196 :
+ * Stream index map for MCU Domain mt8196 :
+ *
+ * <-sensor#1--> <-sensor#0--> <-sensor#3--> <-sensor#2-->
+ *  0x04 | 0x05 | 0x06 | 0x07 | 0x08 | 0x09 | 0x0A | 0x0B
+ *
+ * <-sensor#5--> <-sensor#4--> <-sensor#7--> <-sensor#6-->
+ *  0x0C | 0x0D | 0x0E | 0x0F | 0x10 | 0x11 | 0x12 | 0x13
+ *
+ * <-sensor#9--> <-sensor#8--> <-sensor#11-> <-sensor#10->
+ *  0x14 | 0x15 | 0x16 | 0x17 | 0x18 | 0x19 | 0x1A | 0X1B
+ *
+ * <-sensor#13-> <-sensor#12-> <-sensor#15-> <-sensor#14->
+ *  0x1C | 0x1D | 0x1E | 0x1F | 0x20 | 0x21 | 0x22 | 0x23
+ *
+ * Stream index map for APU Domain mt8196 :
+ *
+ * <-sensor#1--> <-sensor#0--> <-sensor#3--> <-sensor#2-->
+ *  0x24 | 0x25 | 0x26 | 0x27 | 0x28 | 0x29 | 0x2A | 0x2B
+ *
+ * Stream index map for GPU Domain mt8196 :
+ *
+ * <-sensor#1--> <-sensor#0-->
+ *  0x2C | 0x2D | 0x2E | 0x2F
+ *
+ * Stream index map for AP Domain mt8196 :
+ *
+ * <-sensor#1--> <-sensor#0--> <-sensor#3--> <-sensor#2-->
+ *  0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37
+ *
+ * <-sensor#5--> <-sensor#4--> <-sensor#6--> <-sensor#7-->
+ *  0x38 | 0x39 | 0x3A | 0x3B | 0x3C | 0x3D | 0x3E | 0x3F
+ *
  * Note: In some cases, values don't strictly follow a little endian ordering.
  * The data description gives byte offsets constituting each calibration value
  * for each sensor.
@@ -1849,11 +1887,112 @@ static const struct lvts_ctrl_data mt8195_lvts_ap_data_ctrl[] = {
        }
 };
 
+static const struct lvts_ctrl_data mt8196_lvts_mcu_data_ctrl[] = {
+       {
+               .lvts_sensor = {
+                       { .dt_id = MT8196_MCU_MEDIUM_CPU6_0,
+                         .cal_offsets = { 0x06, 0x07 } },
+                       { .dt_id = MT8196_MCU_MEDIUM_CPU6_1,
+                         .cal_offsets = { 0x04, 0x05 } },
+                       { .dt_id = MT8196_MCU_DSU2,
+                         .cal_offsets = { 0x0A, 0x0B } },
+                       { .dt_id = MT8196_MCU_DSU3,
+                         .cal_offsets = { 0x08, 0x09 } }
+               },
+               VALID_SENSOR_MAP(1, 1, 1, 1),
+               .offset = 0x0,
+               .mode = LVTS_MSR_ATP_MODE,
+       },
+       {
+               .lvts_sensor = {
+                       { .dt_id = MT8196_MCU_LITTLE_CPU3,
+                         .cal_offsets = { 0x0E, 0x0F } },
+                       { .dt_id = MT8196_MCU_LITTLE_CPU0,
+                         .cal_offsets = { 0x0C, 0x0D } },
+                       { .dt_id = MT8196_MCU_LITTLE_CPU1,
+                         .cal_offsets = { 0x12, 0x13 } },
+                       { .dt_id = MT8196_MCU_LITTLE_CPU2,
+                         .cal_offsets = { 0x10, 0x11 } }
+               },
+               VALID_SENSOR_MAP(1, 1, 1, 1),
+               .offset = 0x100,
+               .mode = LVTS_MSR_ATP_MODE,
+       },
+       {
+               .lvts_sensor = {
+                       { .dt_id = MT8196_MCU_MEDIUM_CPU4_0,
+                         .cal_offsets = { 0x16, 0x17 } },
+                       { .dt_id = MT8196_MCU_MEDIUM_CPU4_1,
+                         .cal_offsets = { 0x14, 0x15 } },
+                       { .dt_id = MT8196_MCU_MEDIUM_CPU5_0,
+                         .cal_offsets = { 0x1A, 0x1B } },
+                       { .dt_id = MT8196_MCU_MEDIUM_CPU5_1,
+                         .cal_offsets = { 0x18, 0x19 } }
+               },
+               VALID_SENSOR_MAP(1, 1, 1, 1),
+               .offset = 0x200,
+               .mode = LVTS_MSR_ATP_MODE,
+       },
+       {
+               .lvts_sensor = {
+                       { .dt_id = MT8196_MCU_DSU0,
+                         .cal_offsets = { 0x1E, 0x1F } },
+                       { .dt_id = MT8196_MCU_DSU1,
+                         .cal_offsets = { 0x1C, 0x1D } },
+                       { .dt_id = MT8196_MCU_BIG_CPU7_0,
+                         .cal_offsets = { 0x22, 0x23 } },
+                       { .dt_id = MT8196_MCU_BIG_CPU7_1,
+                         .cal_offsets = { 0x20, 0x21 } }
+               },
+               VALID_SENSOR_MAP(1, 1, 1, 1),
+               .offset = 0x300,
+               .mode = LVTS_MSR_ATP_MODE,
+       }
+};
+
+static const struct lvts_ctrl_data mt8196_lvts_ap_data_ctrl[] = {
+       {
+               .lvts_sensor = {
+                       { .dt_id = MT8196_AP_TOP0,
+                         .cal_offsets = { 0x32, 0x33 } },
+                       { .dt_id = MT8196_AP_TOP1,
+                         .cal_offsets = { 0x30, 0x31 } },
+                       { .dt_id = MT8196_AP_TOP2,
+                         .cal_offsets = { 0x36, 0x37 } },
+                       { .dt_id = MT8196_AP_TOP3,
+                         .cal_offsets = { 0x34, 0x35 } }
+               },
+               VALID_SENSOR_MAP(1, 1, 1, 1),
+               .offset = 0x0,
+               .mode = LVTS_MSR_ATP_MODE,
+       },
+       {
+               .lvts_sensor = {
+                       { .dt_id = MT8196_AP_BOT0,
+                         .cal_offsets = { 0x3A, 0x3B } },
+                       { .dt_id = MT8196_AP_BOT1,
+                         .cal_offsets = { 0x38, 0x39 } },
+                       { .dt_id = MT8196_AP_BOT2,
+                         .cal_offsets = { 0x3E, 0x3F } },
+                       { .dt_id = MT8196_AP_BOT3,
+                         .cal_offsets = { 0x3C, 0x3D } }
+               },
+               VALID_SENSOR_MAP(1, 1, 1, 1),
+               .offset = 0x100,
+               .mode = LVTS_MSR_ATP_MODE,
+       }
+};
+
 static const struct lvts_platform_ops lvts_platform_ops_mt7988 = {
        .lvts_raw_to_temp = lvts_raw_to_temp_mt7988,
        .lvts_temp_to_raw = lvts_temp_to_raw_mt7988,
 };
 
+static const struct lvts_platform_ops lvts_platform_ops_mt8196 = {
+       .lvts_raw_to_temp = lvts_raw_to_temp_mt7988,
+       .lvts_temp_to_raw = lvts_temp_to_raw_mt8196,
+};
+
 static const struct lvts_data mt7988_lvts_ap_data = {
        .lvts_ctrl      = mt7988_lvts_ap_data_ctrl,
        .conn_cmd       = mt7988_conn_cmds,
@@ -1973,6 +2112,30 @@ static const struct lvts_data mt8195_lvts_ap_data = {
        .ops = &lvts_platform_ops_mt7988,
 };
 
+static const struct lvts_data mt8196_lvts_mcu_data = {
+       .lvts_ctrl      = mt8196_lvts_mcu_data_ctrl,
+       .num_lvts_ctrl  = ARRAY_SIZE(mt8196_lvts_mcu_data_ctrl),
+       .temp_factor    = LVTS_COEFF_A_MT8196,
+       .temp_offset    = LVTS_COEFF_B_MT8196,
+       .gt_calib_bit_offset = 0,
+       .def_calibration = 14437,
+       .num_cal_offsets = LVTS_NUM_CAL_OFFSETS_MT8196,
+       .msr_offset = LVTS_MSR_OFFSET_MT8196,
+       .ops = &lvts_platform_ops_mt8196,
+};
+
+static const struct lvts_data mt8196_lvts_ap_data = {
+       .lvts_ctrl      = mt8196_lvts_ap_data_ctrl,
+       .num_lvts_ctrl  = ARRAY_SIZE(mt8196_lvts_ap_data_ctrl),
+       .temp_factor    = LVTS_COEFF_A_MT8196,
+       .temp_offset    = LVTS_COEFF_B_MT8196,
+       .gt_calib_bit_offset = 0,
+       .def_calibration = 14437,
+       .num_cal_offsets = LVTS_NUM_CAL_OFFSETS_MT8196,
+       .msr_offset = LVTS_MSR_OFFSET_MT8196,
+       .ops = &lvts_platform_ops_mt8196,
+};
+
 static const struct of_device_id lvts_of_match[] = {
        { .compatible = "mediatek,mt7988-lvts-ap", .data = &mt7988_lvts_ap_data },
        { .compatible = "mediatek,mt8186-lvts", .data = &mt8186_lvts_data },
@@ -1982,6 +2145,8 @@ static const struct of_device_id lvts_of_match[] = {
        { .compatible = "mediatek,mt8192-lvts-ap", .data = &mt8192_lvts_ap_data },
        { .compatible = "mediatek,mt8195-lvts-mcu", .data = &mt8195_lvts_mcu_data },
        { .compatible = "mediatek,mt8195-lvts-ap", .data = &mt8195_lvts_ap_data },
+       { .compatible = "mediatek,mt8196-lvts-mcu", .data = &mt8196_lvts_mcu_data },
+       { .compatible = "mediatek,mt8196-lvts-ap", .data = &mt8196_lvts_ap_data },
        {},
 };
 MODULE_DEVICE_TABLE(of, lvts_of_match);