Commit 74dd4d1f authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files
Pull thermal control updates for 6.20/7.0 from Daniel Lezcano:

"- Fix CFLAGS and LDFLAGS in the pkg-config template fir the libthermal
   (Romain Gantois)

 - Support multiple temp to raw conversion functions for the Mediatek
   LVTS thermal driver and add the MT8196 and MT6991 support (Laura
   Nao)

 - Add support for the Mediatek LVTS driver for MT7987 (Frank
   Wunderlich)

 - Use the existing HZ_PER_MHZ macro on STM32 (Andy Shevchenko)

 - Use the existing clamp() macro in BCM2835 (Thorsten Blum)

 - Make the reset line optional in order to support new Renesas Soc
   where it is not available. Add the RZ/T2H and RZ/N2H suppport
   (Cosmin Tanislav)"

* tag 'thermal-v7.0' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/thermal/linux:
  thermal: renesas: rzg3e: add support for RZ/T2H and RZ/N2H
  dt-bindings: thermal: r9a09g047-tsu: document RZ/T2H and RZ/N2H
  thermal: renesas: rzg3e: make calibration value retrieval per-chip
  thermal: renesas: rzg3e: make min and max temperature per-chip
  thermal: renesas: rzg3e: make reset optional
  dt-bindings: thermal: r9a09g047-tsu: Document RZ/V2N TSU
  thermal/drivers/broadcom: Use clamp to simplify bcm2835_thermal_temp2adc
  thermal/drivers/stm32: Use predefined HZ_PER_MHZ instead of a custom one
  thermal/drivers/mediatek/lvts_thermal: Add mt7987 support
  dt-bindings: thermal: mediatek: Add LVTS thermal controller definition for MT7987
  dt-bindings: nvmem: mediatek: efuse: Add support for MT8196
  thermal/drivers/mediatek/lvts_thermal: Add MT8196 support
  thermal/drivers/mediatek/lvts: Support MSR offset for 16-bit calibration data
  thermal/drivers/mediatek/lvts: Add support for ATP mode
  thermal/drivers/mediatek/lvts: Add lvts_temp_to_raw variant
  thermal/drivers/mediatek/lvts: Add platform ops to support alternative conversion logic
  thermal/drivers/mediatek/lvts: Make number of calibration offsets configurable
  dt-bindings: thermal: mediatek: Add LVTS thermal controller support for MT8196
  tools: lib: thermal: Correct CFLAGS and LDFLAGS in pkg-config template
parents a1fe789a 00610309
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ properties:
          - enum:
              - mediatek,mt8188-efuse
              - mediatek,mt8189-efuse
              - mediatek,mt8196-efuse
          - const: mediatek,mt8186-efuse
      - const: mediatek,mt8186-efuse

+3 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ description: |
properties:
  compatible:
    enum:
      - mediatek,mt7987-lvts-ap
      - mediatek,mt7988-lvts-ap
      - mediatek,mt8186-lvts
      - mediatek,mt8188-lvts-ap
@@ -26,6 +27,8 @@ properties:
      - mediatek,mt8192-lvts-mcu
      - mediatek,mt8195-lvts-ap
      - mediatek,mt8195-lvts-mcu
      - mediatek,mt8196-lvts-ap
      - mediatek,mt8196-lvts-mcu

  reg:
    maxItems: 1
+30 −4
Original line number Diff line number Diff line
@@ -17,10 +17,17 @@ description:
properties:
  compatible:
    oneOf:
      - const: renesas,r9a09g047-tsu # RZ/G3E
      - enum:
          - renesas,r9a09g047-tsu # RZ/G3E
          - renesas,r9a09g077-tsu # RZ/T2H
      - items:
          - const: renesas,r9a09g057-tsu # RZ/V2H
          - enum:
              - renesas,r9a09g056-tsu # RZ/V2N
              - renesas,r9a09g057-tsu # RZ/V2H
          - const: renesas,r9a09g047-tsu # RZ/G3E
      - items:
          - const: renesas,r9a09g087-tsu # RZ/N2H
          - const: renesas,r9a09g077-tsu # RZ/T2H

  reg:
    maxItems: 1
@@ -63,13 +70,32 @@ required:
  - compatible
  - reg
  - clocks
  - resets
  - power-domains
  - interrupts
  - interrupt-names
  - "#thermal-sensor-cells"

allOf:
  - if:
      properties:
        compatible:
          contains:
            const: renesas,r9a09g047-tsu
    then:
      required:
        - resets
        - renesas,tsu-trim

  - if:
      properties:
        compatible:
          contains:
            const: renesas,r9a09g077-tsu
    then:
      properties:
        resets: false
        renesas,tsu-trim: false

additionalProperties: false

examples:
+2 −6
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
@@ -80,12 +81,7 @@ static int bcm2835_thermal_temp2adc(int temp, int offset, int slope)
	temp -= offset;
	temp /= slope;

	if (temp < 0)
		temp = 0;
	if (temp >= BIT(BCM2835_TS_TSENSSTAT_DATA_BITS))
		temp = BIT(BCM2835_TS_TSENSSTAT_DATA_BITS) - 1;

	return temp;
	return clamp(temp, 0, (int)BIT(BCM2835_TS_TSENSSTAT_DATA_BITS) - 1);
}

static int bcm2835_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
+340 −22
Original line number Diff line number Diff line
@@ -44,6 +44,11 @@
#define LVTS_EDATA01(__base)	(__base + 0x0058)
#define LVTS_EDATA02(__base)	(__base + 0x005C)
#define LVTS_EDATA03(__base)	(__base + 0x0060)
#define LVTS_MSROFT(__base)		(__base + 0x006C)
#define LVTS_ATP0(__base)		(__base + 0x0070)
#define LVTS_ATP1(__base)		(__base + 0x0074)
#define LVTS_ATP2(__base)		(__base + 0x0078)
#define LVTS_ATP3(__base)		(__base + 0x007C)
#define LVTS_MSR0(__base)		(__base + 0x0090)
#define LVTS_MSR1(__base)		(__base + 0x0094)
#define LVTS_MSR2(__base)		(__base + 0x0098)
@@ -85,30 +90,43 @@
#define LVTS_GOLDEN_TEMP_DEFAULT	50
#define LVTS_COEFF_A_MT8195			-250460
#define LVTS_COEFF_B_MT8195			250460
#define LVTS_COEFF_A_MT7987			-204650
#define LVTS_COEFF_B_MT7987			204650
#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_IMMEDIATE_MODE		0
#define LVTS_MSR_FILTERED_MODE		1
#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_MINIMUM_THRESHOLD		20000

#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;

enum lvts_msr_mode {
	LVTS_MSR_IMMEDIATE_MODE,
	LVTS_MSR_FILTERED_MODE,
	LVTS_MSR_ATP_MODE,
};

struct lvts_sensor_data {
	int dt_id;
	u8 cal_offsets[3];
	u8 cal_offsets[LVTS_MAX_CAL_OFFSETS];
};

struct lvts_ctrl_data {
	struct lvts_sensor_data lvts_sensor[LVTS_SENSOR_MAX];
	u8 valid_sensor_mask;
	int offset;
	int mode;
	enum lvts_msr_mode mode;
};

#define VALID_SENSOR_MAP(s0, s1, s2, s3) \
@@ -123,10 +141,17 @@ struct lvts_ctrl_data {
			continue; \
		else

struct lvts_platform_ops {
	int (*lvts_raw_to_temp)(u32 raw_temp, int temp_factor);
	u32 (*lvts_temp_to_raw)(int temperature, int temp_factor);
};

struct lvts_data {
	const struct lvts_ctrl_data *lvts_ctrl;
	const struct lvts_platform_ops *ops;
	const u32 *conn_cmd;
	const u32 *init_cmd;
	int num_cal_offsets;
	int num_lvts_ctrl;
	int num_conn_cmd;
	int num_init_cmd;
@@ -134,6 +159,7 @@ struct lvts_data {
	int temp_offset;
	int gt_calib_bit_offset;
	unsigned int def_calibration;
	u16 msr_offset;
};

struct lvts_sensor {
@@ -202,6 +228,11 @@ static const struct debugfs_reg32 lvts_regs[] = {
	LVTS_DEBUG_FS_REGS(LVTS_EDATA01),
	LVTS_DEBUG_FS_REGS(LVTS_EDATA02),
	LVTS_DEBUG_FS_REGS(LVTS_EDATA03),
	LVTS_DEBUG_FS_REGS(LVTS_MSROFT),
	LVTS_DEBUG_FS_REGS(LVTS_ATP0),
	LVTS_DEBUG_FS_REGS(LVTS_ATP1),
	LVTS_DEBUG_FS_REGS(LVTS_ATP2),
	LVTS_DEBUG_FS_REGS(LVTS_ATP3),
	LVTS_DEBUG_FS_REGS(LVTS_MSR0),
	LVTS_DEBUG_FS_REGS(LVTS_MSR1),
	LVTS_DEBUG_FS_REGS(LVTS_MSR2),
@@ -269,7 +300,17 @@ static inline int lvts_debugfs_init(struct device *dev,

#endif

static int lvts_raw_to_temp(u32 raw_temp, int temp_factor)
static int lvts_raw_to_temp(u32 raw_temp, const struct lvts_data *lvts_data)
{
	return lvts_data->ops->lvts_raw_to_temp(raw_temp & 0xFFFF, lvts_data->temp_factor);
}

static u32 lvts_temp_to_raw(int temperature, const struct lvts_data *lvts_data)
{
	return lvts_data->ops->lvts_temp_to_raw(temperature, lvts_data->temp_factor);
}

static int lvts_raw_to_temp_mt7988(u32 raw_temp, int temp_factor)
{
	int temperature;

@@ -279,7 +320,7 @@ static int lvts_raw_to_temp(u32 raw_temp, int temp_factor)
	return temperature;
}

static u32 lvts_temp_to_raw(int temperature, int temp_factor)
static u32 lvts_temp_to_raw_mt7988(int temperature, int temp_factor)
{
	u32 raw_temp = ((s64)(golden_temp_offset - temperature)) << 14;

@@ -288,6 +329,15 @@ static u32 lvts_temp_to_raw(int temperature, int temp_factor)
	return raw_temp;
}

static u32 lvts_temp_to_raw_mt8196(int temperature, int temp_factor)
{
	u32 raw_temp;

	raw_temp = temperature - golden_temp_offset;

	return div_s64((s64)temp_factor << 14, raw_temp);
}

static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
{
	struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
@@ -326,7 +376,7 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
	if (rc)
		return -EAGAIN;

	*temp = lvts_raw_to_temp(value & 0xFFFF, lvts_data->temp_factor);
	*temp = lvts_raw_to_temp(value, lvts_data);

	return 0;
}
@@ -396,8 +446,8 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
	const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
	void __iomem *base = lvts_sensor->base;
	u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD,
				       lvts_data->temp_factor);
	u32 raw_high = lvts_temp_to_raw(high, lvts_data->temp_factor);
				       lvts_data);
	u32 raw_high = lvts_temp_to_raw(high, lvts_data);
	bool should_update_thresh;

	lvts_sensor->low_thresh = low;
@@ -599,6 +649,13 @@ static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
		LVTS_IMMD3(lvts_ctrl->base)
	};

	void __iomem *atp_regs[] = {
		LVTS_ATP0(lvts_ctrl->base),
		LVTS_ATP1(lvts_ctrl->base),
		LVTS_ATP2(lvts_ctrl->base),
		LVTS_ATP3(lvts_ctrl->base)
	};

	int i;

	lvts_for_each_valid_sensor(i, lvts_ctrl_data) {
@@ -634,8 +691,20 @@ static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
		/*
		 * Each sensor has its own register address to read from.
		 */
		lvts_sensor[i].msr = lvts_ctrl_data->mode == LVTS_MSR_IMMEDIATE_MODE ?
			imm_regs[i] : msr_regs[i];
		switch (lvts_ctrl_data->mode) {
		case LVTS_MSR_IMMEDIATE_MODE:
			lvts_sensor[i].msr = imm_regs[i];
			break;
		case LVTS_MSR_FILTERED_MODE:
			lvts_sensor[i].msr = msr_regs[i];
			break;
		case LVTS_MSR_ATP_MODE:
			lvts_sensor[i].msr = atp_regs[i];
			break;
		default:
			lvts_sensor[i].msr = imm_regs[i];
			break;
		}

		lvts_sensor[i].low_thresh = INT_MIN;
		lvts_sensor[i].high_thresh = INT_MIN;
@@ -646,6 +715,26 @@ static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
	return 0;
}

static int lvts_decode_sensor_calibration(const struct lvts_sensor_data *sensor,
					const u8 *efuse_calibration, u32 calib_len,
					u8 num_offsets, u32 *calib)
{
	int i;
	u32 calib_val = 0;

	for (i = 0; i < num_offsets; i++) {
		u8 offset = sensor->cal_offsets[i];

		if (offset >= calib_len)
			return -EINVAL;
		// Pack each calibration byte into the correct position
		calib_val |= efuse_calibration[offset] << (8 * i);
	}

	*calib = calib_val;
	return 0;
}

/*
 * The efuse blob values follows the sensor enumeration per thermal
 * controller. The decoding of the stream is as follow:
@@ -702,6 +791,39 @@ static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
 * <-----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.
@@ -711,26 +833,29 @@ static int lvts_calibration_init(struct device *dev, struct lvts_ctrl *lvts_ctrl
					u8 *efuse_calibration,
					size_t calib_len)
{
	int i;
	const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
	int i, ret;
	u32 gt;

	/* A zero value for gt means that device has invalid efuse data */
	gt = (((u32 *)efuse_calibration)[0] >> lvts_ctrl->lvts_data->gt_calib_bit_offset) & 0xff;
	gt = (((u32 *)efuse_calibration)[0] >> lvts_data->gt_calib_bit_offset) & 0xff;

	lvts_for_each_valid_sensor(i, lvts_ctrl_data) {
		const struct lvts_sensor_data *sensor =
					&lvts_ctrl_data->lvts_sensor[i];
		u32 calib = 0;

		if (sensor->cal_offsets[0] >= calib_len ||
		    sensor->cal_offsets[1] >= calib_len ||
		    sensor->cal_offsets[2] >= calib_len)
			return -EINVAL;
		ret = lvts_decode_sensor_calibration(sensor, efuse_calibration,
						     calib_len,
						     lvts_data->num_cal_offsets,
						     &calib);
		if (ret)
			return ret;

		if (gt) {
			lvts_ctrl->calibration[i] =
				(efuse_calibration[sensor->cal_offsets[0]] << 0) +
				(efuse_calibration[sensor->cal_offsets[1]] << 8) +
				(efuse_calibration[sensor->cal_offsets[2]] << 16);
			lvts_ctrl->calibration[i] = calib;
			if (lvts_ctrl->lvts_data->msr_offset)
				lvts_ctrl->calibration[i] += lvts_ctrl->lvts_data->msr_offset;
		} else if (lvts_ctrl->lvts_data->def_calibration) {
			lvts_ctrl->calibration[i] = lvts_ctrl->lvts_data->def_calibration;
		} else {
@@ -884,7 +1009,7 @@ static void lvts_ctrl_monitor_enable(struct device *dev, struct lvts_ctrl *lvts_
	u32 sensor_map = 0;
	int i;

	if (lvts_ctrl->mode != LVTS_MSR_FILTERED_MODE)
	if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE)
		return;

	if (enable) {
@@ -1038,6 +1163,17 @@ static int lvts_ctrl_calibrate(struct device *dev, struct lvts_ctrl *lvts_ctrl)
	for (i = 0; i < LVTS_SENSOR_MAX; i++)
		writel(lvts_ctrl->calibration[i], lvts_edata[i]);

	/* LVTS_MSROFT : Constant offset applied to MSR values
	 * for post-processing
	 *
	 * Bits:
	 *
	 * 20-0 : Constant data added to MSR values
	 */
	if (lvts_ctrl->lvts_data->msr_offset)
		writel(lvts_ctrl->lvts_data->msr_offset,
		       LVTS_MSROFT(lvts_ctrl->base));

	return 0;
}

@@ -1373,6 +1509,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 = {
@@ -1455,6 +1605,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,
@@ -1753,6 +1909,125 @@ 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 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,
	.gt_calib_bit_offset = 32,
	.def_calibration = 19380,
};

static const struct lvts_data mt7988_lvts_ap_data = {
	.lvts_ctrl	= mt7988_lvts_ap_data_ctrl,
	.conn_cmd	= mt7988_conn_cmds,
@@ -1763,6 +2038,8 @@ 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,
	.num_cal_offsets = LVTS_NUM_CAL_OFFSETS_MT7988,
	.ops = &lvts_platform_ops_mt7988,
};

static const struct lvts_data mt8186_lvts_data = {
@@ -1776,6 +2053,8 @@ static const struct lvts_data mt8186_lvts_data = {
	.temp_offset	= LVTS_COEFF_B_MT7988,
	.gt_calib_bit_offset = 24,
	.def_calibration = 19000,
	.num_cal_offsets = LVTS_NUM_CAL_OFFSETS_MT7988,
	.ops = &lvts_platform_ops_mt7988,
};

static const struct lvts_data mt8188_lvts_mcu_data = {
@@ -1789,6 +2068,8 @@ static const struct lvts_data mt8188_lvts_mcu_data = {
	.temp_offset	= LVTS_COEFF_B_MT8195,
	.gt_calib_bit_offset = 20,
	.def_calibration = 35000,
	.num_cal_offsets = LVTS_NUM_CAL_OFFSETS_MT7988,
	.ops = &lvts_platform_ops_mt7988,
};

static const struct lvts_data mt8188_lvts_ap_data = {
@@ -1802,6 +2083,8 @@ static const struct lvts_data mt8188_lvts_ap_data = {
	.temp_offset	= LVTS_COEFF_B_MT8195,
	.gt_calib_bit_offset = 20,
	.def_calibration = 35000,
	.num_cal_offsets = LVTS_NUM_CAL_OFFSETS_MT7988,
	.ops = &lvts_platform_ops_mt7988,
};

static const struct lvts_data mt8192_lvts_mcu_data = {
@@ -1815,6 +2098,8 @@ static const struct lvts_data mt8192_lvts_mcu_data = {
	.temp_offset	= LVTS_COEFF_B_MT8195,
	.gt_calib_bit_offset = 24,
	.def_calibration = 35000,
	.num_cal_offsets = LVTS_NUM_CAL_OFFSETS_MT7988,
	.ops = &lvts_platform_ops_mt7988,
};

static const struct lvts_data mt8192_lvts_ap_data = {
@@ -1828,6 +2113,8 @@ static const struct lvts_data mt8192_lvts_ap_data = {
	.temp_offset	= LVTS_COEFF_B_MT8195,
	.gt_calib_bit_offset = 24,
	.def_calibration = 35000,
	.num_cal_offsets = LVTS_NUM_CAL_OFFSETS_MT7988,
	.ops = &lvts_platform_ops_mt7988,
};

static const struct lvts_data mt8195_lvts_mcu_data = {
@@ -1841,6 +2128,8 @@ static const struct lvts_data mt8195_lvts_mcu_data = {
	.temp_offset	= LVTS_COEFF_B_MT8195,
	.gt_calib_bit_offset = 24,
	.def_calibration = 35000,
	.num_cal_offsets = LVTS_NUM_CAL_OFFSETS_MT7988,
	.ops = &lvts_platform_ops_mt7988,
};

static const struct lvts_data mt8195_lvts_ap_data = {
@@ -1854,9 +2143,36 @@ static const struct lvts_data mt8195_lvts_ap_data = {
	.temp_offset	= LVTS_COEFF_B_MT8195,
	.gt_calib_bit_offset = 24,
	.def_calibration = 35000,
	.num_cal_offsets = LVTS_NUM_CAL_OFFSETS_MT7988,
	.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,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 },
@@ -1865,6 +2181,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);
Loading