summaryrefslogtreecommitdiff
path: root/drivers/thermal/mediatek/lvts_thermal.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thermal/mediatek/lvts_thermal.c')
-rw-r--r--drivers/thermal/mediatek/lvts_thermal.c580
1 files changed, 420 insertions, 160 deletions
diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
index fd4bd650c77a..985925147ac0 100644
--- a/drivers/thermal/mediatek/lvts_thermal.c
+++ b/drivers/thermal/mediatek/lvts_thermal.c
@@ -65,12 +65,15 @@
#define LVTS_HW_FILTER 0x0
#define LVTS_TSSEL_CONF 0x13121110
#define LVTS_CALSCALE_CONF 0x300
-#define LVTS_MONINT_CONF 0x8300318C
-#define LVTS_MONINT_OFFSET_SENSOR0 0xC
-#define LVTS_MONINT_OFFSET_SENSOR1 0x180
-#define LVTS_MONINT_OFFSET_SENSOR2 0x3000
-#define LVTS_MONINT_OFFSET_SENSOR3 0x3000000
+#define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR0 BIT(3)
+#define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR1 BIT(8)
+#define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR2 BIT(13)
+#define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR3 BIT(25)
+#define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR0 BIT(2)
+#define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR1 BIT(7)
+#define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR2 BIT(12)
+#define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR3 BIT(24)
#define LVTS_INT_SENSOR0 0x0009001F
#define LVTS_INT_SENSOR1 0x001203E0
@@ -91,10 +94,6 @@
#define LVTS_MSR_READ_TIMEOUT_US 400
#define LVTS_MSR_READ_WAIT_US (LVTS_MSR_READ_TIMEOUT_US / 2)
-#define LVTS_HW_SHUTDOWN_MT7988 105000
-#define LVTS_HW_SHUTDOWN_MT8192 105000
-#define LVTS_HW_SHUTDOWN_MT8195 105000
-
#define LVTS_MINIMUM_THRESHOLD 20000
static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
@@ -102,22 +101,35 @@ static int golden_temp_offset;
struct lvts_sensor_data {
int dt_id;
+ u8 cal_offsets[3];
};
struct lvts_ctrl_data {
struct lvts_sensor_data lvts_sensor[LVTS_SENSOR_MAX];
- int cal_offset[LVTS_SENSOR_MAX];
- int hw_tshut_temp;
- int num_lvts_sensor;
+ u8 valid_sensor_mask;
int offset;
int mode;
};
+#define VALID_SENSOR_MAP(s0, s1, s2, s3) \
+ .valid_sensor_mask = (((s0) ? BIT(0) : 0) | \
+ ((s1) ? BIT(1) : 0) | \
+ ((s2) ? BIT(2) : 0) | \
+ ((s3) ? BIT(3) : 0))
+
+#define lvts_for_each_valid_sensor(i, lvts_ctrl) \
+ for ((i) = 0; (i) < LVTS_SENSOR_MAX; (i)++) \
+ if (!((lvts_ctrl)->valid_sensor_mask & BIT(i))) \
+ continue; \
+ else
+
struct lvts_data {
const struct lvts_ctrl_data *lvts_ctrl;
int num_lvts_ctrl;
int temp_factor;
int temp_offset;
+ int gt_calib_bit_offset;
+ unsigned int def_calibration;
};
struct lvts_sensor {
@@ -134,8 +146,7 @@ struct lvts_ctrl {
struct lvts_sensor sensors[LVTS_SENSOR_MAX];
const struct lvts_data *lvts_data;
u32 calibration[LVTS_SENSOR_MAX];
- u32 hw_tshut_raw_temp;
- int num_lvts_sensor;
+ u8 valid_sensor_mask;
int mode;
void __iomem *base;
int low_thresh;
@@ -202,6 +213,13 @@ static const struct debugfs_reg32 lvts_regs[] = {
LVTS_DEBUG_FS_REGS(LVTS_CLKEN),
};
+static void lvts_debugfs_exit(void *data)
+{
+ struct lvts_domain *lvts_td = data;
+
+ debugfs_remove_recursive(lvts_td->dom_dentry);
+}
+
static int lvts_debugfs_init(struct device *dev, struct lvts_domain *lvts_td)
{
struct debugfs_regset32 *regset;
@@ -234,12 +252,7 @@ static int lvts_debugfs_init(struct device *dev, struct lvts_domain *lvts_td)
debugfs_create_regset32("registers", 0400, dentry, regset);
}
- return 0;
-}
-
-static void lvts_debugfs_exit(struct lvts_domain *lvts_td)
-{
- debugfs_remove_recursive(lvts_td->dom_dentry);
+ return devm_add_action_or_reset(dev, lvts_debugfs_exit, lvts_td);
}
#else
@@ -250,8 +263,6 @@ static inline int lvts_debugfs_init(struct device *dev,
return 0;
}
-static void lvts_debugfs_exit(struct lvts_domain *lvts_td) { }
-
#endif
static int lvts_raw_to_temp(u32 raw_temp, int temp_factor)
@@ -318,23 +329,41 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
static void lvts_update_irq_mask(struct lvts_ctrl *lvts_ctrl)
{
- u32 masks[] = {
- LVTS_MONINT_OFFSET_SENSOR0,
- LVTS_MONINT_OFFSET_SENSOR1,
- LVTS_MONINT_OFFSET_SENSOR2,
- LVTS_MONINT_OFFSET_SENSOR3,
+ static const u32 high_offset_inten_masks[] = {
+ LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR0,
+ LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR1,
+ LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR2,
+ LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR3,
+ };
+ static const u32 low_offset_inten_masks[] = {
+ LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR0,
+ LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR1,
+ LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR2,
+ LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR3,
};
u32 value = 0;
int i;
value = readl(LVTS_MONINT(lvts_ctrl->base));
- for (i = 0; i < ARRAY_SIZE(masks); i++) {
+ lvts_for_each_valid_sensor(i, lvts_ctrl) {
if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
- && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)
- value |= masks[i];
- else
- value &= ~masks[i];
+ && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh) {
+ /*
+ * The minimum threshold needs to be configured in the
+ * OFFSETL register to get working interrupts, but we
+ * don't actually want to generate interrupts when
+ * crossing it.
+ */
+ if (lvts_ctrl->low_thresh == -INT_MAX) {
+ value &= ~low_offset_inten_masks[i];
+ value |= high_offset_inten_masks[i];
+ } else {
+ value |= low_offset_inten_masks[i] | high_offset_inten_masks[i];
+ }
+ } else {
+ value &= ~(low_offset_inten_masks[i] | high_offset_inten_masks[i]);
+ }
}
writel(value, LVTS_MONINT(lvts_ctrl->base));
@@ -347,7 +376,7 @@ static bool lvts_should_update_thresh(struct lvts_ctrl *lvts_ctrl, int high)
if (high > lvts_ctrl->high_thresh)
return true;
- for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++)
+ lvts_for_each_valid_sensor(i, lvts_ctrl)
if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
&& lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)
return false;
@@ -413,7 +442,7 @@ static irqreturn_t lvts_ctrl_irq_handler(struct lvts_ctrl *lvts_ctrl)
{
irqreturn_t iret = IRQ_NONE;
u32 value;
- u32 masks[] = {
+ static const u32 masks[] = {
LVTS_INT_SENSOR0,
LVTS_INT_SENSOR1,
LVTS_INT_SENSOR2,
@@ -551,6 +580,7 @@ static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
const struct lvts_ctrl_data *lvts_ctrl_data)
{
struct lvts_sensor *lvts_sensor = lvts_ctrl->sensors;
+
void __iomem *msr_regs[] = {
LVTS_MSR0(lvts_ctrl->base),
LVTS_MSR1(lvts_ctrl->base),
@@ -567,7 +597,7 @@ static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
int i;
- for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++) {
+ lvts_for_each_valid_sensor(i, lvts_ctrl_data) {
int dt_id = lvts_ctrl_data->lvts_sensor[i].dt_id;
@@ -607,7 +637,7 @@ static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
lvts_sensor[i].high_thresh = INT_MIN;
};
- lvts_ctrl->num_lvts_sensor = lvts_ctrl_data->num_lvts_sensor;
+ lvts_ctrl->valid_sensor_mask = lvts_ctrl_data->valid_sensor_mask;
return 0;
}
@@ -668,18 +698,42 @@ 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
*
- * The data description gives the offset of the calibration data in
- * this bytes stream for each sensor.
+ * 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.
*/
static int lvts_calibration_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
const struct lvts_ctrl_data *lvts_ctrl_data,
- u8 *efuse_calibration)
+ u8 *efuse_calibration,
+ size_t calib_len)
{
int i;
+ u32 gt;
- for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++)
- memcpy(&lvts_ctrl->calibration[i],
- efuse_calibration + lvts_ctrl_data->cal_offset[i], 2);
+ /* 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;
+
+ lvts_for_each_valid_sensor(i, lvts_ctrl_data) {
+ const struct lvts_sensor_data *sensor =
+ &lvts_ctrl_data->lvts_sensor[i];
+
+ if (sensor->cal_offsets[0] >= calib_len ||
+ sensor->cal_offsets[1] >= calib_len ||
+ sensor->cal_offsets[2] >= calib_len)
+ return -EINVAL;
+
+ 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);
+ } else if (lvts_ctrl->lvts_data->def_calibration) {
+ lvts_ctrl->calibration[i] = lvts_ctrl->lvts_data->def_calibration;
+ } else {
+ dev_err(dev, "efuse contains invalid calibration data and no default given.\n");
+ return -ENODATA;
+ }
+ }
return 0;
}
@@ -734,16 +788,24 @@ static int lvts_calibration_read(struct device *dev, struct lvts_domain *lvts_td
return 0;
}
-static int lvts_golden_temp_init(struct device *dev, u32 *value, int temp_offset)
+static int lvts_golden_temp_init(struct device *dev, u8 *calib,
+ const struct lvts_data *lvts_data)
{
u32 gt;
- gt = (*value) >> 24;
+ /*
+ * The golden temp information is contained in the first 32-bit
+ * word of efuse data at a specific bit offset.
+ */
+ 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)
golden_temp = gt;
- golden_temp_offset = golden_temp * 500 + temp_offset;
+ golden_temp_offset = golden_temp * 500 + lvts_data->temp_offset;
+
+ dev_info(dev, "%sgolden temp=%d\n", gt ? "" : "fake ", golden_temp);
return 0;
}
@@ -762,11 +824,7 @@ static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td,
if (ret)
return ret;
- /*
- * The golden temp information is contained in the first chunk
- * of efuse data.
- */
- ret = lvts_golden_temp_init(dev, (u32 *)lvts_td->calib, lvts_data->temp_offset);
+ ret = lvts_golden_temp_init(dev, lvts_td->calib, lvts_data);
if (ret)
return ret;
@@ -786,7 +844,8 @@ static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td,
ret = lvts_calibration_init(dev, &lvts_ctrl[i],
&lvts_data->lvts_ctrl[i],
- lvts_td->calib);
+ lvts_td->calib,
+ lvts_td->calib_len);
if (ret)
return ret;
@@ -796,14 +855,6 @@ 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_tshut_raw_temp =
- lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp,
- lvts_data->temp_factor);
-
lvts_ctrl[i].low_thresh = INT_MIN;
lvts_ctrl[i].high_thresh = INT_MIN;
}
@@ -819,6 +870,32 @@ static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td,
return 0;
}
+static void lvts_ctrl_monitor_enable(struct device *dev, struct lvts_ctrl *lvts_ctrl, bool enable)
+{
+ /*
+ * Bitmaps to enable each sensor on filtered mode in the MONCTL0
+ * register.
+ */
+ static const u8 sensor_filt_bitmap[] = { BIT(0), BIT(1), BIT(2), BIT(3) };
+ u32 sensor_map = 0;
+ int i;
+
+ if (lvts_ctrl->mode != LVTS_MSR_FILTERED_MODE)
+ return;
+
+ if (enable) {
+ lvts_for_each_valid_sensor(i, lvts_ctrl)
+ sensor_map |= sensor_filt_bitmap[i];
+ }
+
+ /*
+ * Bits:
+ * 9: Single point access flow
+ * 0-3: Enable sensing point 0-3
+ */
+ writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
+}
+
/*
* At this point the configuration register is the only place in the
* driver where we write multiple values. Per hardware constraint,
@@ -852,7 +929,6 @@ static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
* 10 : Selected sensor with bits 19-18
* 11 : Reserved
*/
- writel(BIT(16), LVTS_PROTCTL(lvts_ctrl->base));
/*
* LVTS_PROTTA : Stage 1 temperature threshold
@@ -865,8 +941,8 @@ static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
*
* writel(0x0, LVTS_PROTTA(lvts_ctrl->base));
* writel(0x0, LVTS_PROTTB(lvts_ctrl->base));
+ * writel(0x0, LVTS_PROTTC(lvts_ctrl->base));
*/
- writel(lvts_ctrl->hw_tshut_raw_temp, LVTS_PROTTC(lvts_ctrl->base));
/*
* LVTS_MONINT : Interrupt configuration register
@@ -874,7 +950,7 @@ 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(LVTS_MONINT_CONF, LVTS_MONINT(lvts_ctrl->base));
+ writel(0, LVTS_MONINT(lvts_ctrl->base));
return 0;
}
@@ -1089,7 +1165,7 @@ static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl)
u32 *sensor_bitmap = lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE ?
sensor_imm_bitmap : sensor_filt_bitmap;
- for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++) {
+ lvts_for_each_valid_sensor(i, lvts_ctrl) {
int dt_id = lvts_sensors[i].dt_id;
@@ -1246,6 +1322,8 @@ static int lvts_probe(struct platform_device *pdev)
return -ENOMEM;
lvts_data = of_device_get_match_data(dev);
+ if (!lvts_data)
+ return -ENODEV;
lvts_td->clk = devm_clk_get_enabled(dev, NULL);
if (IS_ERR(lvts_td->clk))
@@ -1296,34 +1374,36 @@ static void lvts_remove(struct platform_device *pdev)
for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
-
- lvts_debugfs_exit(lvts_td);
}
static const struct lvts_ctrl_data mt7988_lvts_ap_data_ctrl[] = {
{
- .cal_offset = { 0x00, 0x04, 0x08, 0x0c },
.lvts_sensor = {
- { .dt_id = MT7988_CPU_0 },
- { .dt_id = MT7988_CPU_1 },
- { .dt_id = MT7988_ETH2P5G_0 },
- { .dt_id = MT7988_ETH2P5G_1 }
+ { .dt_id = MT7988_CPU_0,
+ .cal_offsets = { 0x00, 0x01, 0x02 } },
+ { .dt_id = MT7988_CPU_1,
+ .cal_offsets = { 0x04, 0x05, 0x06 } },
+ { .dt_id = MT7988_ETH2P5G_0,
+ .cal_offsets = { 0x08, 0x09, 0x0a } },
+ { .dt_id = MT7988_ETH2P5G_1,
+ .cal_offsets = { 0x0c, 0x0d, 0x0e } }
},
- .num_lvts_sensor = 4,
+ VALID_SENSOR_MAP(1, 1, 1, 1),
.offset = 0x0,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT7988,
},
{
- .cal_offset = { 0x14, 0x18, 0x1c, 0x20 },
.lvts_sensor = {
- { .dt_id = MT7988_TOPS_0},
- { .dt_id = MT7988_TOPS_1},
- { .dt_id = MT7988_ETHWARP_0},
- { .dt_id = MT7988_ETHWARP_1}
+ { .dt_id = MT7988_TOPS_0,
+ .cal_offsets = { 0x14, 0x15, 0x16 } },
+ { .dt_id = MT7988_TOPS_1,
+ .cal_offsets = { 0x18, 0x19, 0x1a } },
+ { .dt_id = MT7988_ETHWARP_0,
+ .cal_offsets = { 0x1c, 0x1d, 0x1e } },
+ { .dt_id = MT7988_ETHWARP_1,
+ .cal_offsets = { 0x20, 0x21, 0x22 } }
},
- .num_lvts_sensor = 4,
+ VALID_SENSOR_MAP(1, 1, 1, 1),
.offset = 0x100,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT7988,
}
};
@@ -1334,8 +1414,11 @@ static int lvts_suspend(struct device *dev)
lvts_td = dev_get_drvdata(dev);
- for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
+ for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
+ lvts_ctrl_monitor_enable(dev, &lvts_td->lvts_ctrl[i], false);
+ usleep_range(100, 200);
lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
+ }
clk_disable_unprepare(lvts_td->clk);
@@ -1353,170 +1436,304 @@ static int lvts_resume(struct device *dev)
if (ret)
return ret;
- for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
+ for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], true);
+ usleep_range(100, 200);
+ lvts_ctrl_monitor_enable(dev, &lvts_td->lvts_ctrl[i], true);
+ }
return 0;
}
+/*
+ * The MT8186 calibration data is stored as packed 3-byte little-endian
+ * values using a weird layout that makes sense only when viewed as a 32-bit
+ * hexadecimal word dump. Let's suppose SxBy where x = sensor number and
+ * y = byte number where the LSB is y=0. We then have:
+ *
+ * [S0B2-S0B1-S0B0-S1B2] [S1B1-S1B0-S2B2-S2B1] [S2B0-S3B2-S3B1-S3B0]
+ *
+ * However, when considering a byte stream, those appear as follows:
+ *
+ * [S1B2] [S0B0[ [S0B1] [S0B2] [S2B1] [S2B2] [S1B0] [S1B1] [S3B0] [S3B1] [S3B2] [S2B0]
+ *
+ * Hence the rather confusing offsets provided below.
+ */
+static const struct lvts_ctrl_data mt8186_lvts_data_ctrl[] = {
+ {
+ .lvts_sensor = {
+ { .dt_id = MT8186_LITTLE_CPU0,
+ .cal_offsets = { 5, 6, 7 } },
+ { .dt_id = MT8186_LITTLE_CPU1,
+ .cal_offsets = { 10, 11, 4 } },
+ { .dt_id = MT8186_LITTLE_CPU2,
+ .cal_offsets = { 15, 8, 9 } },
+ { .dt_id = MT8186_CAM,
+ .cal_offsets = { 12, 13, 14 } }
+ },
+ VALID_SENSOR_MAP(1, 1, 1, 1),
+ .offset = 0x0,
+ },
+ {
+ .lvts_sensor = {
+ { .dt_id = MT8186_BIG_CPU0,
+ .cal_offsets = { 22, 23, 16 } },
+ { .dt_id = MT8186_BIG_CPU1,
+ .cal_offsets = { 27, 20, 21 } }
+ },
+ VALID_SENSOR_MAP(1, 1, 0, 0),
+ .offset = 0x100,
+ },
+ {
+ .lvts_sensor = {
+ { .dt_id = MT8186_NNA,
+ .cal_offsets = { 29, 30, 31 } },
+ { .dt_id = MT8186_ADSP,
+ .cal_offsets = { 34, 35, 28 } },
+ { .dt_id = MT8186_GPU,
+ .cal_offsets = { 39, 32, 33 } }
+ },
+ VALID_SENSOR_MAP(1, 1, 1, 0),
+ .offset = 0x200,
+ }
+};
+
+static const struct lvts_ctrl_data mt8188_lvts_mcu_data_ctrl[] = {
+ {
+ .lvts_sensor = {
+ { .dt_id = MT8188_MCU_LITTLE_CPU0,
+ .cal_offsets = { 22, 23, 24 } },
+ { .dt_id = MT8188_MCU_LITTLE_CPU1,
+ .cal_offsets = { 25, 26, 27 } },
+ { .dt_id = MT8188_MCU_LITTLE_CPU2,
+ .cal_offsets = { 28, 29, 30 } },
+ { .dt_id = MT8188_MCU_LITTLE_CPU3,
+ .cal_offsets = { 31, 32, 33 } },
+ },
+ VALID_SENSOR_MAP(1, 1, 1, 1),
+ .offset = 0x0,
+ },
+ {
+ .lvts_sensor = {
+ { .dt_id = MT8188_MCU_BIG_CPU0,
+ .cal_offsets = { 34, 35, 36 } },
+ { .dt_id = MT8188_MCU_BIG_CPU1,
+ .cal_offsets = { 37, 38, 39 } },
+ },
+ VALID_SENSOR_MAP(1, 1, 0, 0),
+ .offset = 0x100,
+ }
+};
+
+static const struct lvts_ctrl_data mt8188_lvts_ap_data_ctrl[] = {
+ {
+ .lvts_sensor = {
+
+ { /* unused */ },
+ { .dt_id = MT8188_AP_APU,
+ .cal_offsets = { 40, 41, 42 } },
+ },
+ VALID_SENSOR_MAP(0, 1, 0, 0),
+ .offset = 0x0,
+ },
+ {
+ .lvts_sensor = {
+ { .dt_id = MT8188_AP_GPU0,
+ .cal_offsets = { 43, 44, 45 } },
+ { .dt_id = MT8188_AP_GPU1,
+ .cal_offsets = { 46, 47, 48 } },
+ { .dt_id = MT8188_AP_ADSP,
+ .cal_offsets = { 49, 50, 51 } },
+ },
+ VALID_SENSOR_MAP(1, 1, 1, 0),
+ .offset = 0x100,
+ },
+ {
+ .lvts_sensor = {
+ { .dt_id = MT8188_AP_VDO,
+ .cal_offsets = { 52, 53, 54 } },
+ { .dt_id = MT8188_AP_INFRA,
+ .cal_offsets = { 55, 56, 57 } },
+ },
+ VALID_SENSOR_MAP(1, 1, 0, 0),
+ .offset = 0x200,
+ },
+ {
+ .lvts_sensor = {
+ { .dt_id = MT8188_AP_CAM1,
+ .cal_offsets = { 58, 59, 60 } },
+ { .dt_id = MT8188_AP_CAM2,
+ .cal_offsets = { 61, 62, 63 } },
+ },
+ VALID_SENSOR_MAP(1, 1, 0, 0),
+ .offset = 0x300,
+ }
+};
+
static const struct lvts_ctrl_data mt8192_lvts_mcu_data_ctrl[] = {
{
- .cal_offset = { 0x04, 0x08 },
.lvts_sensor = {
- { .dt_id = MT8192_MCU_BIG_CPU0 },
- { .dt_id = MT8192_MCU_BIG_CPU1 }
+ { .dt_id = MT8192_MCU_BIG_CPU0,
+ .cal_offsets = { 0x04, 0x05, 0x06 } },
+ { .dt_id = MT8192_MCU_BIG_CPU1,
+ .cal_offsets = { 0x08, 0x09, 0x0a } }
},
- .num_lvts_sensor = 2,
+ VALID_SENSOR_MAP(1, 1, 0, 0),
.offset = 0x0,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
.mode = LVTS_MSR_FILTERED_MODE,
},
{
- .cal_offset = { 0x0c, 0x10 },
.lvts_sensor = {
- { .dt_id = MT8192_MCU_BIG_CPU2 },
- { .dt_id = MT8192_MCU_BIG_CPU3 }
+ { .dt_id = MT8192_MCU_BIG_CPU2,
+ .cal_offsets = { 0x0c, 0x0d, 0x0e } },
+ { .dt_id = MT8192_MCU_BIG_CPU3,
+ .cal_offsets = { 0x10, 0x11, 0x12 } }
},
- .num_lvts_sensor = 2,
+ VALID_SENSOR_MAP(1, 1, 0, 0),
.offset = 0x100,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
.mode = LVTS_MSR_FILTERED_MODE,
},
{
- .cal_offset = { 0x14, 0x18, 0x1c, 0x20 },
.lvts_sensor = {
- { .dt_id = MT8192_MCU_LITTLE_CPU0 },
- { .dt_id = MT8192_MCU_LITTLE_CPU1 },
- { .dt_id = MT8192_MCU_LITTLE_CPU2 },
- { .dt_id = MT8192_MCU_LITTLE_CPU3 }
+ { .dt_id = MT8192_MCU_LITTLE_CPU0,
+ .cal_offsets = { 0x14, 0x15, 0x16 } },
+ { .dt_id = MT8192_MCU_LITTLE_CPU1,
+ .cal_offsets = { 0x18, 0x19, 0x1a } },
+ { .dt_id = MT8192_MCU_LITTLE_CPU2,
+ .cal_offsets = { 0x1c, 0x1d, 0x1e } },
+ { .dt_id = MT8192_MCU_LITTLE_CPU3,
+ .cal_offsets = { 0x20, 0x21, 0x22 } }
},
- .num_lvts_sensor = 4,
+ VALID_SENSOR_MAP(1, 1, 1, 1),
.offset = 0x200,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
.mode = LVTS_MSR_FILTERED_MODE,
}
};
static const struct lvts_ctrl_data mt8192_lvts_ap_data_ctrl[] = {
- {
- .cal_offset = { 0x24, 0x28 },
+ {
.lvts_sensor = {
- { .dt_id = MT8192_AP_VPU0 },
- { .dt_id = MT8192_AP_VPU1 }
+ { .dt_id = MT8192_AP_VPU0,
+ .cal_offsets = { 0x24, 0x25, 0x26 } },
+ { .dt_id = MT8192_AP_VPU1,
+ .cal_offsets = { 0x28, 0x29, 0x2a } }
},
- .num_lvts_sensor = 2,
+ VALID_SENSOR_MAP(1, 1, 0, 0),
.offset = 0x0,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
},
{
- .cal_offset = { 0x2c, 0x30 },
.lvts_sensor = {
- { .dt_id = MT8192_AP_GPU0 },
- { .dt_id = MT8192_AP_GPU1 }
+ { .dt_id = MT8192_AP_GPU0,
+ .cal_offsets = { 0x2c, 0x2d, 0x2e } },
+ { .dt_id = MT8192_AP_GPU1,
+ .cal_offsets = { 0x30, 0x31, 0x32 } }
},
- .num_lvts_sensor = 2,
+ VALID_SENSOR_MAP(1, 1, 0, 0),
.offset = 0x100,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
},
{
- .cal_offset = { 0x34, 0x38 },
.lvts_sensor = {
- { .dt_id = MT8192_AP_INFRA },
- { .dt_id = MT8192_AP_CAM },
+ { .dt_id = MT8192_AP_INFRA,
+ .cal_offsets = { 0x34, 0x35, 0x36 } },
+ { .dt_id = MT8192_AP_CAM,
+ .cal_offsets = { 0x38, 0x39, 0x3a } },
},
- .num_lvts_sensor = 2,
+ VALID_SENSOR_MAP(1, 1, 0, 0),
.offset = 0x200,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
},
{
- .cal_offset = { 0x3c, 0x40, 0x44 },
.lvts_sensor = {
- { .dt_id = MT8192_AP_MD0 },
- { .dt_id = MT8192_AP_MD1 },
- { .dt_id = MT8192_AP_MD2 }
+ { .dt_id = MT8192_AP_MD0,
+ .cal_offsets = { 0x3c, 0x3d, 0x3e } },
+ { .dt_id = MT8192_AP_MD1,
+ .cal_offsets = { 0x40, 0x41, 0x42 } },
+ { .dt_id = MT8192_AP_MD2,
+ .cal_offsets = { 0x44, 0x45, 0x46 } }
},
- .num_lvts_sensor = 3,
+ VALID_SENSOR_MAP(1, 1, 1, 0),
.offset = 0x300,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
}
};
static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
{
- .cal_offset = { 0x04, 0x07 },
.lvts_sensor = {
- { .dt_id = MT8195_MCU_BIG_CPU0 },
- { .dt_id = MT8195_MCU_BIG_CPU1 }
+ { .dt_id = MT8195_MCU_BIG_CPU0,
+ .cal_offsets = { 0x04, 0x05, 0x06 } },
+ { .dt_id = MT8195_MCU_BIG_CPU1,
+ .cal_offsets = { 0x07, 0x08, 0x09 } }
},
- .num_lvts_sensor = 2,
+ VALID_SENSOR_MAP(1, 1, 0, 0),
.offset = 0x0,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
},
{
- .cal_offset = { 0x0d, 0x10 },
.lvts_sensor = {
- { .dt_id = MT8195_MCU_BIG_CPU2 },
- { .dt_id = MT8195_MCU_BIG_CPU3 }
+ { .dt_id = MT8195_MCU_BIG_CPU2,
+ .cal_offsets = { 0x0d, 0x0e, 0x0f } },
+ { .dt_id = MT8195_MCU_BIG_CPU3,
+ .cal_offsets = { 0x10, 0x11, 0x12 } }
},
- .num_lvts_sensor = 2,
+ VALID_SENSOR_MAP(1, 1, 0, 0),
.offset = 0x100,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
},
{
- .cal_offset = { 0x16, 0x19, 0x1c, 0x1f },
.lvts_sensor = {
- { .dt_id = MT8195_MCU_LITTLE_CPU0 },
- { .dt_id = MT8195_MCU_LITTLE_CPU1 },
- { .dt_id = MT8195_MCU_LITTLE_CPU2 },
- { .dt_id = MT8195_MCU_LITTLE_CPU3 }
+ { .dt_id = MT8195_MCU_LITTLE_CPU0,
+ .cal_offsets = { 0x16, 0x17, 0x18 } },
+ { .dt_id = MT8195_MCU_LITTLE_CPU1,
+ .cal_offsets = { 0x19, 0x1a, 0x1b } },
+ { .dt_id = MT8195_MCU_LITTLE_CPU2,
+ .cal_offsets = { 0x1c, 0x1d, 0x1e } },
+ { .dt_id = MT8195_MCU_LITTLE_CPU3,
+ .cal_offsets = { 0x1f, 0x20, 0x21 } }
},
- .num_lvts_sensor = 4,
+ VALID_SENSOR_MAP(1, 1, 1, 1),
.offset = 0x200,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
}
};
static const struct lvts_ctrl_data mt8195_lvts_ap_data_ctrl[] = {
- {
- .cal_offset = { 0x25, 0x28 },
+ {
.lvts_sensor = {
- { .dt_id = MT8195_AP_VPU0 },
- { .dt_id = MT8195_AP_VPU1 }
+ { .dt_id = MT8195_AP_VPU0,
+ .cal_offsets = { 0x25, 0x26, 0x27 } },
+ { .dt_id = MT8195_AP_VPU1,
+ .cal_offsets = { 0x28, 0x29, 0x2a } }
},
- .num_lvts_sensor = 2,
+ VALID_SENSOR_MAP(1, 1, 0, 0),
.offset = 0x0,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
},
{
- .cal_offset = { 0x2e, 0x31 },
.lvts_sensor = {
- { .dt_id = MT8195_AP_GPU0 },
- { .dt_id = MT8195_AP_GPU1 }
+ { .dt_id = MT8195_AP_GPU0,
+ .cal_offsets = { 0x2e, 0x2f, 0x30 } },
+ { .dt_id = MT8195_AP_GPU1,
+ .cal_offsets = { 0x31, 0x32, 0x33 } }
},
- .num_lvts_sensor = 2,
+ VALID_SENSOR_MAP(1, 1, 0, 0),
.offset = 0x100,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
},
{
- .cal_offset = { 0x37, 0x3a, 0x3d },
.lvts_sensor = {
- { .dt_id = MT8195_AP_VDEC },
- { .dt_id = MT8195_AP_IMG },
- { .dt_id = MT8195_AP_INFRA },
+ { .dt_id = MT8195_AP_VDEC,
+ .cal_offsets = { 0x37, 0x38, 0x39 } },
+ { .dt_id = MT8195_AP_IMG,
+ .cal_offsets = { 0x3a, 0x3b, 0x3c } },
+ { .dt_id = MT8195_AP_INFRA,
+ .cal_offsets = { 0x3d, 0x3e, 0x3f } }
},
- .num_lvts_sensor = 3,
+ VALID_SENSOR_MAP(1, 1, 1, 0),
.offset = 0x200,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
},
{
- .cal_offset = { 0x43, 0x46 },
.lvts_sensor = {
- { .dt_id = MT8195_AP_CAM0 },
- { .dt_id = MT8195_AP_CAM1 }
+ { .dt_id = MT8195_AP_CAM0,
+ .cal_offsets = { 0x43, 0x44, 0x45 } },
+ { .dt_id = MT8195_AP_CAM1,
+ .cal_offsets = { 0x46, 0x47, 0x48 } }
},
- .num_lvts_sensor = 2,
+ VALID_SENSOR_MAP(1, 1, 0, 0),
.offset = 0x300,
- .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
}
};
@@ -1525,16 +1742,52 @@ static const struct lvts_data mt7988_lvts_ap_data = {
.num_lvts_ctrl = ARRAY_SIZE(mt7988_lvts_ap_data_ctrl),
.temp_factor = LVTS_COEFF_A_MT7988,
.temp_offset = LVTS_COEFF_B_MT7988,
+ .gt_calib_bit_offset = 24,
+};
+
+static const struct lvts_data mt8186_lvts_data = {
+ .lvts_ctrl = mt8186_lvts_data_ctrl,
+ .num_lvts_ctrl = ARRAY_SIZE(mt8186_lvts_data_ctrl),
+ .temp_factor = LVTS_COEFF_A_MT7988,
+ .temp_offset = LVTS_COEFF_B_MT7988,
+ .gt_calib_bit_offset = 24,
+ .def_calibration = 19000,
+};
+
+static const struct lvts_data mt8188_lvts_mcu_data = {
+ .lvts_ctrl = mt8188_lvts_mcu_data_ctrl,
+ .num_lvts_ctrl = ARRAY_SIZE(mt8188_lvts_mcu_data_ctrl),
+ .temp_factor = LVTS_COEFF_A_MT8195,
+ .temp_offset = LVTS_COEFF_B_MT8195,
+ .gt_calib_bit_offset = 20,
+ .def_calibration = 35000,
+};
+
+static const struct lvts_data mt8188_lvts_ap_data = {
+ .lvts_ctrl = mt8188_lvts_ap_data_ctrl,
+ .num_lvts_ctrl = ARRAY_SIZE(mt8188_lvts_ap_data_ctrl),
+ .temp_factor = LVTS_COEFF_A_MT8195,
+ .temp_offset = LVTS_COEFF_B_MT8195,
+ .gt_calib_bit_offset = 20,
+ .def_calibration = 35000,
};
static const struct lvts_data mt8192_lvts_mcu_data = {
.lvts_ctrl = mt8192_lvts_mcu_data_ctrl,
.num_lvts_ctrl = ARRAY_SIZE(mt8192_lvts_mcu_data_ctrl),
+ .temp_factor = LVTS_COEFF_A_MT8195,
+ .temp_offset = LVTS_COEFF_B_MT8195,
+ .gt_calib_bit_offset = 24,
+ .def_calibration = 35000,
};
static const struct lvts_data mt8192_lvts_ap_data = {
.lvts_ctrl = mt8192_lvts_ap_data_ctrl,
.num_lvts_ctrl = ARRAY_SIZE(mt8192_lvts_ap_data_ctrl),
+ .temp_factor = LVTS_COEFF_A_MT8195,
+ .temp_offset = LVTS_COEFF_B_MT8195,
+ .gt_calib_bit_offset = 24,
+ .def_calibration = 35000,
};
static const struct lvts_data mt8195_lvts_mcu_data = {
@@ -1542,6 +1795,8 @@ static const struct lvts_data mt8195_lvts_mcu_data = {
.num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_mcu_data_ctrl),
.temp_factor = LVTS_COEFF_A_MT8195,
.temp_offset = LVTS_COEFF_B_MT8195,
+ .gt_calib_bit_offset = 24,
+ .def_calibration = 35000,
};
static const struct lvts_data mt8195_lvts_ap_data = {
@@ -1549,10 +1804,15 @@ static const struct lvts_data mt8195_lvts_ap_data = {
.num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_ap_data_ctrl),
.temp_factor = LVTS_COEFF_A_MT8195,
.temp_offset = LVTS_COEFF_B_MT8195,
+ .gt_calib_bit_offset = 24,
+ .def_calibration = 35000,
};
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 },
+ { .compatible = "mediatek,mt8188-lvts-mcu", .data = &mt8188_lvts_mcu_data },
+ { .compatible = "mediatek,mt8188-lvts-ap", .data = &mt8188_lvts_ap_data },
{ .compatible = "mediatek,mt8192-lvts-mcu", .data = &mt8192_lvts_mcu_data },
{ .compatible = "mediatek,mt8192-lvts-ap", .data = &mt8192_lvts_ap_data },
{ .compatible = "mediatek,mt8195-lvts-mcu", .data = &mt8195_lvts_mcu_data },
@@ -1567,7 +1827,7 @@ static const struct dev_pm_ops lvts_pm_ops = {
static struct platform_driver lvts_driver = {
.probe = lvts_probe,
- .remove_new = lvts_remove,
+ .remove = lvts_remove,
.driver = {
.name = "mtk-lvts-thermal",
.of_match_table = lvts_of_match,