1803 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2023 MediaTek Inc.4 * Author: Balsam CHIHI <bchihi@baylibre.com>5 */6 7#include <linux/clk.h>8#include <linux/clk-provider.h>9#include <linux/delay.h>10#include <linux/debugfs.h>11#include <linux/init.h>12#include <linux/interrupt.h>13#include <linux/iopoll.h>14#include <linux/kernel.h>15#include <linux/nvmem-consumer.h>16#include <linux/of.h>17#include <linux/platform_device.h>18#include <linux/reset.h>19#include <linux/thermal.h>20#include <dt-bindings/thermal/mediatek,lvts-thermal.h>21 22#include "../thermal_hwmon.h"23 24#define LVTS_MONCTL0(__base) (__base + 0x0000)25#define LVTS_MONCTL1(__base) (__base + 0x0004)26#define LVTS_MONCTL2(__base) (__base + 0x0008)27#define LVTS_MONINT(__base) (__base + 0x000C)28#define LVTS_MONINTSTS(__base) (__base + 0x0010)29#define LVTS_MONIDET0(__base) (__base + 0x0014)30#define LVTS_MONIDET1(__base) (__base + 0x0018)31#define LVTS_MONIDET2(__base) (__base + 0x001C)32#define LVTS_MONIDET3(__base) (__base + 0x0020)33#define LVTS_H2NTHRE(__base) (__base + 0x0024)34#define LVTS_HTHRE(__base) (__base + 0x0028)35#define LVTS_OFFSETH(__base) (__base + 0x0030)36#define LVTS_OFFSETL(__base) (__base + 0x0034)37#define LVTS_MSRCTL0(__base) (__base + 0x0038)38#define LVTS_MSRCTL1(__base) (__base + 0x003C)39#define LVTS_TSSEL(__base) (__base + 0x0040)40#define LVTS_CALSCALE(__base) (__base + 0x0048)41#define LVTS_ID(__base) (__base + 0x004C)42#define LVTS_CONFIG(__base) (__base + 0x0050)43#define LVTS_EDATA00(__base) (__base + 0x0054)44#define LVTS_EDATA01(__base) (__base + 0x0058)45#define LVTS_EDATA02(__base) (__base + 0x005C)46#define LVTS_EDATA03(__base) (__base + 0x0060)47#define LVTS_MSR0(__base) (__base + 0x0090)48#define LVTS_MSR1(__base) (__base + 0x0094)49#define LVTS_MSR2(__base) (__base + 0x0098)50#define LVTS_MSR3(__base) (__base + 0x009C)51#define LVTS_IMMD0(__base) (__base + 0x00A0)52#define LVTS_IMMD1(__base) (__base + 0x00A4)53#define LVTS_IMMD2(__base) (__base + 0x00A8)54#define LVTS_IMMD3(__base) (__base + 0x00AC)55#define LVTS_PROTCTL(__base) (__base + 0x00C0)56#define LVTS_PROTTA(__base) (__base + 0x00C4)57#define LVTS_PROTTB(__base) (__base + 0x00C8)58#define LVTS_PROTTC(__base) (__base + 0x00CC)59#define LVTS_CLKEN(__base) (__base + 0x00E4)60 61#define LVTS_PERIOD_UNIT 062#define LVTS_GROUP_INTERVAL 063#define LVTS_FILTER_INTERVAL 064#define LVTS_SENSOR_INTERVAL 065#define LVTS_HW_FILTER 0x066#define LVTS_TSSEL_CONF 0x1312111067#define LVTS_CALSCALE_CONF 0x30068#define LVTS_MONINT_CONF 0x8300318C69 70#define LVTS_MONINT_OFFSET_SENSOR0 0xC71#define LVTS_MONINT_OFFSET_SENSOR1 0x18072#define LVTS_MONINT_OFFSET_SENSOR2 0x300073#define LVTS_MONINT_OFFSET_SENSOR3 0x300000074 75#define LVTS_INT_SENSOR0 0x0009001F76#define LVTS_INT_SENSOR1 0x001203E077#define LVTS_INT_SENSOR2 0x00247C0078#define LVTS_INT_SENSOR3 0x1FC0000079 80#define LVTS_SENSOR_MAX 481#define LVTS_GOLDEN_TEMP_MAX 6282#define LVTS_GOLDEN_TEMP_DEFAULT 5083#define LVTS_COEFF_A_MT8195 -25046084#define LVTS_COEFF_B_MT8195 25046085#define LVTS_COEFF_A_MT7988 -20465086#define LVTS_COEFF_B_MT7988 20465087 88#define LVTS_MSR_IMMEDIATE_MODE 089#define LVTS_MSR_FILTERED_MODE 190 91#define LVTS_MSR_READ_TIMEOUT_US 40092#define LVTS_MSR_READ_WAIT_US (LVTS_MSR_READ_TIMEOUT_US / 2)93 94#define LVTS_HW_TSHUT_TEMP 10500095 96#define LVTS_MINIMUM_THRESHOLD 2000097 98static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;99static int golden_temp_offset;100 101struct lvts_sensor_data {102 int dt_id;103 u8 cal_offsets[3];104};105 106struct lvts_ctrl_data {107 struct lvts_sensor_data lvts_sensor[LVTS_SENSOR_MAX];108 u8 valid_sensor_mask;109 int offset;110 int mode;111};112 113#define VALID_SENSOR_MAP(s0, s1, s2, s3) \114 .valid_sensor_mask = (((s0) ? BIT(0) : 0) | \115 ((s1) ? BIT(1) : 0) | \116 ((s2) ? BIT(2) : 0) | \117 ((s3) ? BIT(3) : 0))118 119#define lvts_for_each_valid_sensor(i, lvts_ctrl) \120 for ((i) = 0; (i) < LVTS_SENSOR_MAX; (i)++) \121 if (!((lvts_ctrl)->valid_sensor_mask & BIT(i))) \122 continue; \123 else124 125struct lvts_data {126 const struct lvts_ctrl_data *lvts_ctrl;127 int num_lvts_ctrl;128 int temp_factor;129 int temp_offset;130 int gt_calib_bit_offset;131 unsigned int def_calibration;132};133 134struct lvts_sensor {135 struct thermal_zone_device *tz;136 void __iomem *msr;137 void __iomem *base;138 int id;139 int dt_id;140 int low_thresh;141 int high_thresh;142};143 144struct lvts_ctrl {145 struct lvts_sensor sensors[LVTS_SENSOR_MAX];146 const struct lvts_data *lvts_data;147 u32 calibration[LVTS_SENSOR_MAX];148 u32 hw_tshut_raw_temp;149 u8 valid_sensor_mask;150 int mode;151 void __iomem *base;152 int low_thresh;153 int high_thresh;154};155 156struct lvts_domain {157 struct lvts_ctrl *lvts_ctrl;158 struct reset_control *reset;159 struct clk *clk;160 int num_lvts_ctrl;161 void __iomem *base;162 size_t calib_len;163 u8 *calib;164#ifdef CONFIG_DEBUG_FS165 struct dentry *dom_dentry;166#endif167};168 169#ifdef CONFIG_MTK_LVTS_THERMAL_DEBUGFS170 171#define LVTS_DEBUG_FS_REGS(__reg) \172{ \173 .name = __stringify(__reg), \174 .offset = __reg(0), \175}176 177static const struct debugfs_reg32 lvts_regs[] = {178 LVTS_DEBUG_FS_REGS(LVTS_MONCTL0),179 LVTS_DEBUG_FS_REGS(LVTS_MONCTL1),180 LVTS_DEBUG_FS_REGS(LVTS_MONCTL2),181 LVTS_DEBUG_FS_REGS(LVTS_MONINT),182 LVTS_DEBUG_FS_REGS(LVTS_MONINTSTS),183 LVTS_DEBUG_FS_REGS(LVTS_MONIDET0),184 LVTS_DEBUG_FS_REGS(LVTS_MONIDET1),185 LVTS_DEBUG_FS_REGS(LVTS_MONIDET2),186 LVTS_DEBUG_FS_REGS(LVTS_MONIDET3),187 LVTS_DEBUG_FS_REGS(LVTS_H2NTHRE),188 LVTS_DEBUG_FS_REGS(LVTS_HTHRE),189 LVTS_DEBUG_FS_REGS(LVTS_OFFSETH),190 LVTS_DEBUG_FS_REGS(LVTS_OFFSETL),191 LVTS_DEBUG_FS_REGS(LVTS_MSRCTL0),192 LVTS_DEBUG_FS_REGS(LVTS_MSRCTL1),193 LVTS_DEBUG_FS_REGS(LVTS_TSSEL),194 LVTS_DEBUG_FS_REGS(LVTS_CALSCALE),195 LVTS_DEBUG_FS_REGS(LVTS_ID),196 LVTS_DEBUG_FS_REGS(LVTS_CONFIG),197 LVTS_DEBUG_FS_REGS(LVTS_EDATA00),198 LVTS_DEBUG_FS_REGS(LVTS_EDATA01),199 LVTS_DEBUG_FS_REGS(LVTS_EDATA02),200 LVTS_DEBUG_FS_REGS(LVTS_EDATA03),201 LVTS_DEBUG_FS_REGS(LVTS_MSR0),202 LVTS_DEBUG_FS_REGS(LVTS_MSR1),203 LVTS_DEBUG_FS_REGS(LVTS_MSR2),204 LVTS_DEBUG_FS_REGS(LVTS_MSR3),205 LVTS_DEBUG_FS_REGS(LVTS_IMMD0),206 LVTS_DEBUG_FS_REGS(LVTS_IMMD1),207 LVTS_DEBUG_FS_REGS(LVTS_IMMD2),208 LVTS_DEBUG_FS_REGS(LVTS_IMMD3),209 LVTS_DEBUG_FS_REGS(LVTS_PROTCTL),210 LVTS_DEBUG_FS_REGS(LVTS_PROTTA),211 LVTS_DEBUG_FS_REGS(LVTS_PROTTB),212 LVTS_DEBUG_FS_REGS(LVTS_PROTTC),213 LVTS_DEBUG_FS_REGS(LVTS_CLKEN),214};215 216static int lvts_debugfs_init(struct device *dev, struct lvts_domain *lvts_td)217{218 struct debugfs_regset32 *regset;219 struct lvts_ctrl *lvts_ctrl;220 struct dentry *dentry;221 char name[64];222 int i;223 224 lvts_td->dom_dentry = debugfs_create_dir(dev_name(dev), NULL);225 if (IS_ERR(lvts_td->dom_dentry))226 return 0;227 228 for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {229 230 lvts_ctrl = &lvts_td->lvts_ctrl[i];231 232 sprintf(name, "controller%d", i);233 dentry = debugfs_create_dir(name, lvts_td->dom_dentry);234 if (IS_ERR(dentry))235 continue;236 237 regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL);238 if (!regset)239 continue;240 241 regset->base = lvts_ctrl->base;242 regset->regs = lvts_regs;243 regset->nregs = ARRAY_SIZE(lvts_regs);244 245 debugfs_create_regset32("registers", 0400, dentry, regset);246 }247 248 return 0;249}250 251static void lvts_debugfs_exit(struct lvts_domain *lvts_td)252{253 debugfs_remove_recursive(lvts_td->dom_dentry);254}255 256#else257 258static inline int lvts_debugfs_init(struct device *dev,259 struct lvts_domain *lvts_td)260{261 return 0;262}263 264static void lvts_debugfs_exit(struct lvts_domain *lvts_td) { }265 266#endif267 268static int lvts_raw_to_temp(u32 raw_temp, int temp_factor)269{270 int temperature;271 272 temperature = ((s64)(raw_temp & 0xFFFF) * temp_factor) >> 14;273 temperature += golden_temp_offset;274 275 return temperature;276}277 278static u32 lvts_temp_to_raw(int temperature, int temp_factor)279{280 u32 raw_temp = ((s64)(golden_temp_offset - temperature)) << 14;281 282 raw_temp = div_s64(raw_temp, -temp_factor);283 284 return raw_temp;285}286 287static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)288{289 struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);290 struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl,291 sensors[lvts_sensor->id]);292 const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;293 void __iomem *msr = lvts_sensor->msr;294 u32 value;295 int rc;296 297 /*298 * Measurement registers:299 *300 * LVTS_MSR[0-3] / LVTS_IMMD[0-3]301 *302 * Bits:303 *304 * 32-17: Unused305 * 16 : Valid temperature306 * 15-0 : Raw temperature307 */308 rc = readl_poll_timeout(msr, value, value & BIT(16),309 LVTS_MSR_READ_WAIT_US, LVTS_MSR_READ_TIMEOUT_US);310 311 /*312 * As the thermal zone temperature will read before the313 * hardware sensor is fully initialized, we have to check the314 * validity of the temperature returned when reading the315 * measurement register. The thermal controller will set the316 * valid bit temperature only when it is totally initialized.317 *318 * Otherwise, we may end up with garbage values out of the319 * functionning temperature and directly jump to a system320 * shutdown.321 */322 if (rc)323 return -EAGAIN;324 325 *temp = lvts_raw_to_temp(value & 0xFFFF, lvts_data->temp_factor);326 327 return 0;328}329 330static void lvts_update_irq_mask(struct lvts_ctrl *lvts_ctrl)331{332 u32 masks[] = {333 LVTS_MONINT_OFFSET_SENSOR0,334 LVTS_MONINT_OFFSET_SENSOR1,335 LVTS_MONINT_OFFSET_SENSOR2,336 LVTS_MONINT_OFFSET_SENSOR3,337 };338 u32 value = 0;339 int i;340 341 value = readl(LVTS_MONINT(lvts_ctrl->base));342 343 for (i = 0; i < ARRAY_SIZE(masks); i++) {344 if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh345 && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)346 value |= masks[i];347 else348 value &= ~masks[i];349 }350 351 writel(value, LVTS_MONINT(lvts_ctrl->base));352}353 354static bool lvts_should_update_thresh(struct lvts_ctrl *lvts_ctrl, int high)355{356 int i;357 358 if (high > lvts_ctrl->high_thresh)359 return true;360 361 lvts_for_each_valid_sensor(i, lvts_ctrl)362 if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh363 && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)364 return false;365 366 return true;367}368 369static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)370{371 struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);372 struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl,373 sensors[lvts_sensor->id]);374 const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;375 void __iomem *base = lvts_sensor->base;376 u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD,377 lvts_data->temp_factor);378 u32 raw_high = lvts_temp_to_raw(high, lvts_data->temp_factor);379 bool should_update_thresh;380 381 lvts_sensor->low_thresh = low;382 lvts_sensor->high_thresh = high;383 384 should_update_thresh = lvts_should_update_thresh(lvts_ctrl, high);385 if (should_update_thresh) {386 lvts_ctrl->high_thresh = high;387 lvts_ctrl->low_thresh = low;388 }389 lvts_update_irq_mask(lvts_ctrl);390 391 if (!should_update_thresh)392 return 0;393 394 /*395 * Low offset temperature threshold396 *397 * LVTS_OFFSETL398 *399 * Bits:400 *401 * 14-0 : Raw temperature for threshold402 */403 pr_debug("%s: Setting low limit temperature interrupt: %d\n",404 thermal_zone_device_type(tz), low);405 writel(raw_low, LVTS_OFFSETL(base));406 407 /*408 * High offset temperature threshold409 *410 * LVTS_OFFSETH411 *412 * Bits:413 *414 * 14-0 : Raw temperature for threshold415 */416 pr_debug("%s: Setting high limit temperature interrupt: %d\n",417 thermal_zone_device_type(tz), high);418 writel(raw_high, LVTS_OFFSETH(base));419 420 return 0;421}422 423static irqreturn_t lvts_ctrl_irq_handler(struct lvts_ctrl *lvts_ctrl)424{425 irqreturn_t iret = IRQ_NONE;426 u32 value;427 u32 masks[] = {428 LVTS_INT_SENSOR0,429 LVTS_INT_SENSOR1,430 LVTS_INT_SENSOR2,431 LVTS_INT_SENSOR3432 };433 int i;434 435 /*436 * Interrupt monitoring status437 *438 * LVTS_MONINTST439 *440 * Bits:441 *442 * 31 : Interrupt for stage 3443 * 30 : Interrupt for stage 2444 * 29 : Interrupt for state 1445 * 28 : Interrupt using filter on sensor 3446 *447 * 27 : Interrupt using immediate on sensor 3448 * 26 : Interrupt normal to hot on sensor 3449 * 25 : Interrupt high offset on sensor 3450 * 24 : Interrupt low offset on sensor 3451 *452 * 23 : Interrupt hot threshold on sensor 3453 * 22 : Interrupt cold threshold on sensor 3454 * 21 : Interrupt using filter on sensor 2455 * 20 : Interrupt using filter on sensor 1456 *457 * 19 : Interrupt using filter on sensor 0458 * 18 : Interrupt using immediate on sensor 2459 * 17 : Interrupt using immediate on sensor 1460 * 16 : Interrupt using immediate on sensor 0461 *462 * 15 : Interrupt device access timeout interrupt463 * 14 : Interrupt normal to hot on sensor 2464 * 13 : Interrupt high offset interrupt on sensor 2465 * 12 : Interrupt low offset interrupt on sensor 2466 *467 * 11 : Interrupt hot threshold on sensor 2468 * 10 : Interrupt cold threshold on sensor 2469 * 9 : Interrupt normal to hot on sensor 1470 * 8 : Interrupt high offset interrupt on sensor 1471 *472 * 7 : Interrupt low offset interrupt on sensor 1473 * 6 : Interrupt hot threshold on sensor 1474 * 5 : Interrupt cold threshold on sensor 1475 * 4 : Interrupt normal to hot on sensor 0476 *477 * 3 : Interrupt high offset interrupt on sensor 0478 * 2 : Interrupt low offset interrupt on sensor 0479 * 1 : Interrupt hot threshold on sensor 0480 * 0 : Interrupt cold threshold on sensor 0481 *482 * We are interested in the sensor(s) responsible of the483 * interrupt event. We update the thermal framework with the484 * thermal zone associated with the sensor. The framework will485 * take care of the rest whatever the kind of interrupt, we486 * are only interested in which sensor raised the interrupt.487 *488 * sensor 3 interrupt: 0001 1111 1100 0000 0000 0000 0000 0000489 * => 0x1FC00000490 * sensor 2 interrupt: 0000 0000 0010 0100 0111 1100 0000 0000491 * => 0x00247C00492 * sensor 1 interrupt: 0000 0000 0001 0010 0000 0011 1110 0000493 * => 0X001203E0494 * sensor 0 interrupt: 0000 0000 0000 1001 0000 0000 0001 1111495 * => 0x0009001F496 */497 value = readl(LVTS_MONINTSTS(lvts_ctrl->base));498 499 /*500 * Let's figure out which sensors raised the interrupt501 *502 * NOTE: the masks array must be ordered with the index503 * corresponding to the sensor id eg. index=0, mask for504 * sensor0.505 */506 for (i = 0; i < ARRAY_SIZE(masks); i++) {507 508 if (!(value & masks[i]))509 continue;510 511 thermal_zone_device_update(lvts_ctrl->sensors[i].tz,512 THERMAL_TRIP_VIOLATED);513 iret = IRQ_HANDLED;514 }515 516 /*517 * Write back to clear the interrupt status (W1C)518 */519 writel(value, LVTS_MONINTSTS(lvts_ctrl->base));520 521 return iret;522}523 524/*525 * Temperature interrupt handler. Even if the driver supports more526 * interrupt modes, we use the interrupt when the temperature crosses527 * the hot threshold the way up and the way down (modulo the528 * hysteresis).529 *530 * Each thermal domain has a couple of interrupts, one for hardware531 * reset and another one for all the thermal events happening on the532 * different sensors.533 *534 * The interrupt is configured for thermal events when crossing the535 * hot temperature limit. At each interrupt, we check in every536 * controller if there is an interrupt pending.537 */538static irqreturn_t lvts_irq_handler(int irq, void *data)539{540 struct lvts_domain *lvts_td = data;541 irqreturn_t aux, iret = IRQ_NONE;542 int i;543 544 for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {545 546 aux = lvts_ctrl_irq_handler(&lvts_td->lvts_ctrl[i]);547 if (aux != IRQ_HANDLED)548 continue;549 550 iret = IRQ_HANDLED;551 }552 553 return iret;554}555 556static struct thermal_zone_device_ops lvts_ops = {557 .get_temp = lvts_get_temp,558 .set_trips = lvts_set_trips,559};560 561static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,562 const struct lvts_ctrl_data *lvts_ctrl_data)563{564 struct lvts_sensor *lvts_sensor = lvts_ctrl->sensors;565 566 void __iomem *msr_regs[] = {567 LVTS_MSR0(lvts_ctrl->base),568 LVTS_MSR1(lvts_ctrl->base),569 LVTS_MSR2(lvts_ctrl->base),570 LVTS_MSR3(lvts_ctrl->base)571 };572 573 void __iomem *imm_regs[] = {574 LVTS_IMMD0(lvts_ctrl->base),575 LVTS_IMMD1(lvts_ctrl->base),576 LVTS_IMMD2(lvts_ctrl->base),577 LVTS_IMMD3(lvts_ctrl->base)578 };579 580 int i;581 582 lvts_for_each_valid_sensor(i, lvts_ctrl_data) {583 584 int dt_id = lvts_ctrl_data->lvts_sensor[i].dt_id;585 586 /*587 * At this point, we don't know which id matches which588 * sensor. Let's set arbitrally the id from the index.589 */590 lvts_sensor[i].id = i;591 592 /*593 * The thermal zone registration will set the trip594 * point interrupt in the thermal controller595 * register. But this one will be reset in the596 * initialization after. So we need to post pone the597 * thermal zone creation after the controller is598 * setup. For this reason, we store the device tree599 * node id from the data in the sensor structure600 */601 lvts_sensor[i].dt_id = dt_id;602 603 /*604 * We assign the base address of the thermal605 * controller as a back pointer. So it will be606 * accessible from the different thermal framework ops607 * as we pass the lvts_sensor pointer as thermal zone608 * private data.609 */610 lvts_sensor[i].base = lvts_ctrl->base;611 612 /*613 * Each sensor has its own register address to read from.614 */615 lvts_sensor[i].msr = lvts_ctrl_data->mode == LVTS_MSR_IMMEDIATE_MODE ?616 imm_regs[i] : msr_regs[i];617 618 lvts_sensor[i].low_thresh = INT_MIN;619 lvts_sensor[i].high_thresh = INT_MIN;620 };621 622 lvts_ctrl->valid_sensor_mask = lvts_ctrl_data->valid_sensor_mask;623 624 return 0;625}626 627/*628 * The efuse blob values follows the sensor enumeration per thermal629 * controller. The decoding of the stream is as follow:630 *631 * MT8192 :632 * Stream index map for MCU Domain mt8192 :633 *634 * <-----mcu-tc#0-----> <-----sensor#0-----> <-----sensor#1----->635 * 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 | 0x08 | 0x09 | 0x0A | 0x0B636 *637 * <-----sensor#2-----> <-----sensor#3----->638 * 0x0C | 0x0D | 0x0E | 0x0F | 0x10 | 0x11 | 0x12 | 0x13639 *640 * <-----sensor#4-----> <-----sensor#5-----> <-----sensor#6-----> <-----sensor#7----->641 * 0x14 | 0x15 | 0x16 | 0x17 | 0x18 | 0x19 | 0x1A | 0x1B | 0x1C | 0x1D | 0x1E | 0x1F | 0x20 | 0x21 | 0x22 | 0x23642 *643 * Stream index map for AP Domain mt8192 :644 *645 * <-----sensor#0-----> <-----sensor#1----->646 * 0x24 | 0x25 | 0x26 | 0x27 | 0x28 | 0x29 | 0x2A | 0x2B647 *648 * <-----sensor#2-----> <-----sensor#3----->649 * 0x2C | 0x2D | 0x2E | 0x2F | 0x30 | 0x31 | 0x32 | 0x33650 *651 * <-----sensor#4-----> <-----sensor#5----->652 * 0x34 | 0x35 | 0x36 | 0x37 | 0x38 | 0x39 | 0x3A | 0x3B653 *654 * <-----sensor#6-----> <-----sensor#7-----> <-----sensor#8----->655 * 0x3C | 0x3D | 0x3E | 0x3F | 0x40 | 0x41 | 0x42 | 0x43 | 0x44 | 0x45 | 0x46 | 0x47656 *657 * MT8195 :658 * Stream index map for MCU Domain mt8195 :659 *660 * <-----mcu-tc#0-----> <-----sensor#0-----> <-----sensor#1----->661 * 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 | 0x08 | 0x09662 *663 * <-----mcu-tc#1-----> <-----sensor#2-----> <-----sensor#3----->664 * 0x0A | 0x0B | 0x0C | 0x0D | 0x0E | 0x0F | 0x10 | 0x11 | 0x12665 *666 * <-----mcu-tc#2-----> <-----sensor#4-----> <-----sensor#5-----> <-----sensor#6-----> <-----sensor#7----->667 * 0x13 | 0x14 | 0x15 | 0x16 | 0x17 | 0x18 | 0x19 | 0x1A | 0x1B | 0x1C | 0x1D | 0x1E | 0x1F | 0x20 | 0x21668 *669 * Stream index map for AP Domain mt8195 :670 *671 * <-----ap--tc#0-----> <-----sensor#0-----> <-----sensor#1----->672 * 0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 | 0x28 | 0x29 | 0x2A673 *674 * <-----ap--tc#1-----> <-----sensor#2-----> <-----sensor#3----->675 * 0x2B | 0x2C | 0x2D | 0x2E | 0x2F | 0x30 | 0x31 | 0x32 | 0x33676 *677 * <-----ap--tc#2-----> <-----sensor#4-----> <-----sensor#5-----> <-----sensor#6----->678 * 0x34 | 0x35 | 0x36 | 0x37 | 0x38 | 0x39 | 0x3A | 0x3B | 0x3C | 0x3D | 0x3E | 0x3F679 *680 * <-----ap--tc#3-----> <-----sensor#7-----> <-----sensor#8----->681 * 0x40 | 0x41 | 0x42 | 0x43 | 0x44 | 0x45 | 0x46 | 0x47 | 0x48682 *683 * Note: In some cases, values don't strictly follow a little endian ordering.684 * The data description gives byte offsets constituting each calibration value685 * for each sensor.686 */687static int lvts_calibration_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,688 const struct lvts_ctrl_data *lvts_ctrl_data,689 u8 *efuse_calibration,690 size_t calib_len)691{692 int i;693 u32 gt;694 695 /* A zero value for gt means that device has invalid efuse data */696 gt = (((u32 *)efuse_calibration)[0] >> lvts_ctrl->lvts_data->gt_calib_bit_offset) & 0xff;697 698 lvts_for_each_valid_sensor(i, lvts_ctrl_data) {699 const struct lvts_sensor_data *sensor =700 &lvts_ctrl_data->lvts_sensor[i];701 702 if (sensor->cal_offsets[0] >= calib_len ||703 sensor->cal_offsets[1] >= calib_len ||704 sensor->cal_offsets[2] >= calib_len)705 return -EINVAL;706 707 if (gt) {708 lvts_ctrl->calibration[i] =709 (efuse_calibration[sensor->cal_offsets[0]] << 0) +710 (efuse_calibration[sensor->cal_offsets[1]] << 8) +711 (efuse_calibration[sensor->cal_offsets[2]] << 16);712 } else if (lvts_ctrl->lvts_data->def_calibration) {713 lvts_ctrl->calibration[i] = lvts_ctrl->lvts_data->def_calibration;714 } else {715 dev_err(dev, "efuse contains invalid calibration data and no default given.\n");716 return -ENODATA;717 }718 }719 720 return 0;721}722 723/*724 * The efuse bytes stream can be split into different chunk of725 * nvmems. This function reads and concatenate those into a single726 * buffer so it can be read sequentially when initializing the727 * calibration data.728 */729static int lvts_calibration_read(struct device *dev, struct lvts_domain *lvts_td,730 const struct lvts_data *lvts_data)731{732 struct device_node *np = dev_of_node(dev);733 struct nvmem_cell *cell;734 struct property *prop;735 const char *cell_name;736 737 of_property_for_each_string(np, "nvmem-cell-names", prop, cell_name) {738 size_t len;739 u8 *efuse;740 741 cell = of_nvmem_cell_get(np, cell_name);742 if (IS_ERR(cell)) {743 dev_err(dev, "Failed to get cell '%s'\n", cell_name);744 return PTR_ERR(cell);745 }746 747 efuse = nvmem_cell_read(cell, &len);748 749 nvmem_cell_put(cell);750 751 if (IS_ERR(efuse)) {752 dev_err(dev, "Failed to read cell '%s'\n", cell_name);753 return PTR_ERR(efuse);754 }755 756 lvts_td->calib = devm_krealloc(dev, lvts_td->calib,757 lvts_td->calib_len + len, GFP_KERNEL);758 if (!lvts_td->calib) {759 kfree(efuse);760 return -ENOMEM;761 }762 763 memcpy(lvts_td->calib + lvts_td->calib_len, efuse, len);764 765 lvts_td->calib_len += len;766 767 kfree(efuse);768 }769 770 return 0;771}772 773static int lvts_golden_temp_init(struct device *dev, u8 *calib,774 const struct lvts_data *lvts_data)775{776 u32 gt;777 778 /*779 * The golden temp information is contained in the first 32-bit780 * word of efuse data at a specific bit offset.781 */782 gt = (((u32 *)calib)[0] >> lvts_data->gt_calib_bit_offset) & 0xff;783 784 /* A zero value for gt means that device has invalid efuse data */785 if (gt && gt < LVTS_GOLDEN_TEMP_MAX)786 golden_temp = gt;787 788 golden_temp_offset = golden_temp * 500 + lvts_data->temp_offset;789 790 dev_info(dev, "%sgolden temp=%d\n", gt ? "" : "fake ", golden_temp);791 792 return 0;793}794 795static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td,796 const struct lvts_data *lvts_data)797{798 size_t size = sizeof(*lvts_td->lvts_ctrl) * lvts_data->num_lvts_ctrl;799 struct lvts_ctrl *lvts_ctrl;800 int i, ret;801 802 /*803 * Create the calibration bytes stream from efuse data804 */805 ret = lvts_calibration_read(dev, lvts_td, lvts_data);806 if (ret)807 return ret;808 809 ret = lvts_golden_temp_init(dev, lvts_td->calib, lvts_data);810 if (ret)811 return ret;812 813 lvts_ctrl = devm_kzalloc(dev, size, GFP_KERNEL);814 if (!lvts_ctrl)815 return -ENOMEM;816 817 for (i = 0; i < lvts_data->num_lvts_ctrl; i++) {818 819 lvts_ctrl[i].base = lvts_td->base + lvts_data->lvts_ctrl[i].offset;820 lvts_ctrl[i].lvts_data = lvts_data;821 822 ret = lvts_sensor_init(dev, &lvts_ctrl[i],823 &lvts_data->lvts_ctrl[i]);824 if (ret)825 return ret;826 827 ret = lvts_calibration_init(dev, &lvts_ctrl[i],828 &lvts_data->lvts_ctrl[i],829 lvts_td->calib,830 lvts_td->calib_len);831 if (ret)832 return ret;833 834 /*835 * The mode the ctrl will use to read the temperature836 * (filtered or immediate)837 */838 lvts_ctrl[i].mode = lvts_data->lvts_ctrl[i].mode;839 840 /*841 * The temperature to raw temperature must be done842 * after initializing the calibration.843 */844 lvts_ctrl[i].hw_tshut_raw_temp =845 lvts_temp_to_raw(LVTS_HW_TSHUT_TEMP,846 lvts_data->temp_factor);847 848 lvts_ctrl[i].low_thresh = INT_MIN;849 lvts_ctrl[i].high_thresh = INT_MIN;850 }851 852 /*853 * We no longer need the efuse bytes stream, let's free it854 */855 devm_kfree(dev, lvts_td->calib);856 857 lvts_td->lvts_ctrl = lvts_ctrl;858 lvts_td->num_lvts_ctrl = lvts_data->num_lvts_ctrl;859 860 return 0;861}862 863/*864 * At this point the configuration register is the only place in the865 * driver where we write multiple values. Per hardware constraint,866 * each write in the configuration register must be separated by a867 * delay of 2 us.868 */869static void lvts_write_config(struct lvts_ctrl *lvts_ctrl, u32 *cmds, int nr_cmds)870{871 int i;872 873 /*874 * Configuration register875 */876 for (i = 0; i < nr_cmds; i++) {877 writel(cmds[i], LVTS_CONFIG(lvts_ctrl->base));878 usleep_range(2, 4);879 }880}881 882static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)883{884 /*885 * LVTS_PROTCTL : Thermal Protection Sensor Selection886 *887 * Bits:888 *889 * 19-18 : Sensor to base the protection on890 * 17-16 : Strategy:891 * 00 : Average of 4 sensors892 * 01 : Max of 4 sensors893 * 10 : Selected sensor with bits 19-18894 * 11 : Reserved895 */896 writel(BIT(16), LVTS_PROTCTL(lvts_ctrl->base));897 898 /*899 * LVTS_PROTTA : Stage 1 temperature threshold900 * LVTS_PROTTB : Stage 2 temperature threshold901 * LVTS_PROTTC : Stage 3 temperature threshold902 *903 * Bits:904 *905 * 14-0: Raw temperature threshold906 *907 * writel(0x0, LVTS_PROTTA(lvts_ctrl->base));908 * writel(0x0, LVTS_PROTTB(lvts_ctrl->base));909 */910 writel(lvts_ctrl->hw_tshut_raw_temp, LVTS_PROTTC(lvts_ctrl->base));911 912 /*913 * LVTS_MONINT : Interrupt configuration register914 *915 * The LVTS_MONINT register layout is the same as the LVTS_MONINTSTS916 * register, except we set the bits to enable the interrupt.917 */918 writel(LVTS_MONINT_CONF, LVTS_MONINT(lvts_ctrl->base));919 920 return 0;921}922 923static int lvts_domain_reset(struct device *dev, struct reset_control *reset)924{925 int ret;926 927 ret = reset_control_assert(reset);928 if (ret)929 return ret;930 931 return reset_control_deassert(reset);932}933 934/*935 * Enable or disable the clocks of a specified thermal controller936 */937static int lvts_ctrl_set_enable(struct lvts_ctrl *lvts_ctrl, int enable)938{939 /*940 * LVTS_CLKEN : Internal LVTS clock941 *942 * Bits:943 *944 * 0 : enable / disable clock945 */946 writel(enable, LVTS_CLKEN(lvts_ctrl->base));947 948 return 0;949}950 951static int lvts_ctrl_connect(struct device *dev, struct lvts_ctrl *lvts_ctrl)952{953 u32 id, cmds[] = { 0xC103FFFF, 0xC502FF55 };954 955 lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));956 957 /*958 * LVTS_ID : Get ID and status of the thermal controller959 *960 * Bits:961 *962 * 0-5 : thermal controller id963 * 7 : thermal controller connection is valid964 */965 id = readl(LVTS_ID(lvts_ctrl->base));966 if (!(id & BIT(7)))967 return -EIO;968 969 return 0;970}971 972static int lvts_ctrl_initialize(struct device *dev, struct lvts_ctrl *lvts_ctrl)973{974 /*975 * Write device mask: 0xC1030000976 */977 u32 cmds[] = {978 0xC1030E01, 0xC1030CFC, 0xC1030A8C, 0xC103098D, 0xC10308F1,979 0xC10307A6, 0xC10306B8, 0xC1030500, 0xC1030420, 0xC1030300,980 0xC1030030, 0xC10300F6, 0xC1030050, 0xC1030060, 0xC10300AC,981 0xC10300FC, 0xC103009D, 0xC10300F1, 0xC10300E1982 };983 984 lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));985 986 return 0;987}988 989static int lvts_ctrl_calibrate(struct device *dev, struct lvts_ctrl *lvts_ctrl)990{991 int i;992 void __iomem *lvts_edata[] = {993 LVTS_EDATA00(lvts_ctrl->base),994 LVTS_EDATA01(lvts_ctrl->base),995 LVTS_EDATA02(lvts_ctrl->base),996 LVTS_EDATA03(lvts_ctrl->base)997 };998 999 /*1000 * LVTS_EDATA0X : Efuse calibration reference value for sensor X1001 *1002 * Bits:1003 *1004 * 20-0 : Efuse value for normalization data1005 */1006 for (i = 0; i < LVTS_SENSOR_MAX; i++)1007 writel(lvts_ctrl->calibration[i], lvts_edata[i]);1008 1009 return 0;1010}1011 1012static int lvts_ctrl_configure(struct device *dev, struct lvts_ctrl *lvts_ctrl)1013{1014 u32 value;1015 1016 /*1017 * LVTS_TSSEL : Sensing point index numbering1018 *1019 * Bits:1020 *1021 * 31-24: ADC Sense 31022 * 23-16: ADC Sense 21023 * 15-8 : ADC Sense 11024 * 7-0 : ADC Sense 01025 */1026 value = LVTS_TSSEL_CONF;1027 writel(value, LVTS_TSSEL(lvts_ctrl->base));1028 1029 /*1030 * LVTS_CALSCALE : ADC voltage round1031 */1032 value = 0x300;1033 value = LVTS_CALSCALE_CONF;1034 1035 /*1036 * LVTS_MSRCTL0 : Sensor filtering strategy1037 *1038 * Filters:1039 *1040 * 000 : One sample1041 * 001 : Avg 2 samples1042 * 010 : 4 samples, drop min and max, avg 2 samples1043 * 011 : 6 samples, drop min and max, avg 4 samples1044 * 100 : 10 samples, drop min and max, avg 8 samples1045 * 101 : 18 samples, drop min and max, avg 16 samples1046 *1047 * Bits:1048 *1049 * 0-2 : Sensor0 filter1050 * 3-5 : Sensor1 filter1051 * 6-8 : Sensor2 filter1052 * 9-11 : Sensor3 filter1053 */1054 value = LVTS_HW_FILTER << 9 | LVTS_HW_FILTER << 6 |1055 LVTS_HW_FILTER << 3 | LVTS_HW_FILTER;1056 writel(value, LVTS_MSRCTL0(lvts_ctrl->base));1057 1058 /*1059 * LVTS_MONCTL1 : Period unit and group interval configuration1060 *1061 * The clock source of LVTS thermal controller is 26MHz.1062 *1063 * The period unit is a time base for all the interval delays1064 * specified in the registers. By default we use 12. The time1065 * conversion is done by multiplying by 256 and 1/26.10^61066 *1067 * An interval delay multiplied by the period unit gives the1068 * duration in seconds.1069 *1070 * - Filter interval delay is a delay between two samples of1071 * the same sensor.1072 *1073 * - Sensor interval delay is a delay between two samples of1074 * different sensors.1075 *1076 * - Group interval delay is a delay between different rounds.1077 *1078 * For example:1079 * If Period unit = C, filter delay = 1, sensor delay = 2, group delay = 1,1080 * and two sensors, TS1 and TS2, are in a LVTS thermal controller1081 * and then1082 * Period unit time = C * 1/26M * 256 = 12 * 38.46ns * 256 = 118.149us1083 * Filter interval delay = 1 * Period unit = 118.149us1084 * Sensor interval delay = 2 * Period unit = 236.298us1085 * Group interval delay = 1 * Period unit = 118.149us1086 *1087 * TS1 TS1 ... TS1 TS2 TS2 ... TS2 TS1...1088 * <--> Filter interval delay1089 * <--> Sensor interval delay1090 * <--> Group interval delay1091 * Bits:1092 * 29 - 20 : Group interval1093 * 16 - 13 : Send a single interrupt when crossing the hot threshold (1)1094 * or an interrupt everytime the hot threshold is crossed (0)1095 * 9 - 0 : Period unit1096 *1097 */1098 value = LVTS_GROUP_INTERVAL << 20 | LVTS_PERIOD_UNIT;1099 writel(value, LVTS_MONCTL1(lvts_ctrl->base));1100 1101 /*1102 * LVTS_MONCTL2 : Filtering and sensor interval1103 *1104 * Bits:1105 *1106 * 25-16 : Interval unit in PERIOD_UNIT between sample on1107 * the same sensor, filter interval1108 * 9-0 : Interval unit in PERIOD_UNIT between each sensor1109 *1110 */1111 value = LVTS_FILTER_INTERVAL << 16 | LVTS_SENSOR_INTERVAL;1112 writel(value, LVTS_MONCTL2(lvts_ctrl->base));1113 1114 return lvts_irq_init(lvts_ctrl);1115}1116 1117static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl)1118{1119 struct lvts_sensor *lvts_sensors = lvts_ctrl->sensors;1120 struct thermal_zone_device *tz;1121 u32 sensor_map = 0;1122 int i;1123 /*1124 * Bitmaps to enable each sensor on immediate and filtered modes, as1125 * described in MSRCTL1 and MONCTL0 registers below, respectively.1126 */1127 u32 sensor_imm_bitmap[] = { BIT(4), BIT(5), BIT(6), BIT(9) };1128 u32 sensor_filt_bitmap[] = { BIT(0), BIT(1), BIT(2), BIT(3) };1129 1130 u32 *sensor_bitmap = lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE ?1131 sensor_imm_bitmap : sensor_filt_bitmap;1132 1133 lvts_for_each_valid_sensor(i, lvts_ctrl) {1134 1135 int dt_id = lvts_sensors[i].dt_id;1136 1137 tz = devm_thermal_of_zone_register(dev, dt_id, &lvts_sensors[i],1138 &lvts_ops);1139 if (IS_ERR(tz)) {1140 /*1141 * This thermal zone is not described in the1142 * device tree. It is not an error from the1143 * thermal OF code POV, we just continue.1144 */1145 if (PTR_ERR(tz) == -ENODEV)1146 continue;1147 1148 return PTR_ERR(tz);1149 }1150 1151 devm_thermal_add_hwmon_sysfs(dev, tz);1152 1153 /*1154 * The thermal zone pointer will be needed in the1155 * interrupt handler, we store it in the sensor1156 * structure. The thermal domain structure will be1157 * passed to the interrupt handler private data as the1158 * interrupt is shared for all the controller1159 * belonging to the thermal domain.1160 */1161 lvts_sensors[i].tz = tz;1162 1163 /*1164 * This sensor was correctly associated with a thermal1165 * zone, let's set the corresponding bit in the sensor1166 * map, so we can enable the temperature monitoring in1167 * the hardware thermal controller.1168 */1169 sensor_map |= sensor_bitmap[i];1170 }1171 1172 /*1173 * The initialization of the thermal zones give us1174 * which sensor point to enable. If any thermal zone1175 * was not described in the device tree, it won't be1176 * enabled here in the sensor map.1177 */1178 if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {1179 /*1180 * LVTS_MSRCTL1 : Measurement control1181 *1182 * Bits:1183 *1184 * 9: Ignore MSRCTL0 config and do immediate measurement on sensor31185 * 6: Ignore MSRCTL0 config and do immediate measurement on sensor21186 * 5: Ignore MSRCTL0 config and do immediate measurement on sensor11187 * 4: Ignore MSRCTL0 config and do immediate measurement on sensor01188 *1189 * That configuration will ignore the filtering and the delays1190 * introduced in MONCTL1 and MONCTL21191 */1192 writel(sensor_map, LVTS_MSRCTL1(lvts_ctrl->base));1193 } else {1194 /*1195 * Bits:1196 * 9: Single point access flow1197 * 0-3: Enable sensing point 0-31198 */1199 writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));1200 }1201 1202 return 0;1203}1204 1205static int lvts_domain_init(struct device *dev, struct lvts_domain *lvts_td,1206 const struct lvts_data *lvts_data)1207{1208 struct lvts_ctrl *lvts_ctrl;1209 int i, ret;1210 1211 ret = lvts_ctrl_init(dev, lvts_td, lvts_data);1212 if (ret)1213 return ret;1214 1215 ret = lvts_domain_reset(dev, lvts_td->reset);1216 if (ret) {1217 dev_dbg(dev, "Failed to reset domain");1218 return ret;1219 }1220 1221 for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {1222 1223 lvts_ctrl = &lvts_td->lvts_ctrl[i];1224 1225 /*1226 * Initialization steps:1227 *1228 * - Enable the clock1229 * - Connect to the LVTS1230 * - Initialize the LVTS1231 * - Prepare the calibration data1232 * - Select monitored sensors1233 * [ Configure sampling ]1234 * [ Configure the interrupt ]1235 * - Start measurement1236 */1237 ret = lvts_ctrl_set_enable(lvts_ctrl, true);1238 if (ret) {1239 dev_dbg(dev, "Failed to enable LVTS clock");1240 return ret;1241 }1242 1243 ret = lvts_ctrl_connect(dev, lvts_ctrl);1244 if (ret) {1245 dev_dbg(dev, "Failed to connect to LVTS controller");1246 return ret;1247 }1248 1249 ret = lvts_ctrl_initialize(dev, lvts_ctrl);1250 if (ret) {1251 dev_dbg(dev, "Failed to initialize controller");1252 return ret;1253 }1254 1255 ret = lvts_ctrl_calibrate(dev, lvts_ctrl);1256 if (ret) {1257 dev_dbg(dev, "Failed to calibrate controller");1258 return ret;1259 }1260 1261 ret = lvts_ctrl_configure(dev, lvts_ctrl);1262 if (ret) {1263 dev_dbg(dev, "Failed to configure controller");1264 return ret;1265 }1266 1267 ret = lvts_ctrl_start(dev, lvts_ctrl);1268 if (ret) {1269 dev_dbg(dev, "Failed to start controller");1270 return ret;1271 }1272 }1273 1274 return lvts_debugfs_init(dev, lvts_td);1275}1276 1277static int lvts_probe(struct platform_device *pdev)1278{1279 const struct lvts_data *lvts_data;1280 struct lvts_domain *lvts_td;1281 struct device *dev = &pdev->dev;1282 struct resource *res;1283 int irq, ret;1284 1285 lvts_td = devm_kzalloc(dev, sizeof(*lvts_td), GFP_KERNEL);1286 if (!lvts_td)1287 return -ENOMEM;1288 1289 lvts_data = of_device_get_match_data(dev);1290 if (!lvts_data)1291 return -ENODEV;1292 1293 lvts_td->clk = devm_clk_get_enabled(dev, NULL);1294 if (IS_ERR(lvts_td->clk))1295 return dev_err_probe(dev, PTR_ERR(lvts_td->clk), "Failed to retrieve clock\n");1296 1297 res = platform_get_mem_or_io(pdev, 0);1298 if (!res)1299 return dev_err_probe(dev, (-ENXIO), "No IO resource\n");1300 1301 lvts_td->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);1302 if (IS_ERR(lvts_td->base))1303 return dev_err_probe(dev, PTR_ERR(lvts_td->base), "Failed to map io resource\n");1304 1305 lvts_td->reset = devm_reset_control_get_by_index(dev, 0);1306 if (IS_ERR(lvts_td->reset))1307 return dev_err_probe(dev, PTR_ERR(lvts_td->reset), "Failed to get reset control\n");1308 1309 irq = platform_get_irq(pdev, 0);1310 if (irq < 0)1311 return irq;1312 1313 golden_temp_offset = lvts_data->temp_offset;1314 1315 ret = lvts_domain_init(dev, lvts_td, lvts_data);1316 if (ret)1317 return dev_err_probe(dev, ret, "Failed to initialize the lvts domain\n");1318 1319 /*1320 * At this point the LVTS is initialized and enabled. We can1321 * safely enable the interrupt.1322 */1323 ret = devm_request_threaded_irq(dev, irq, NULL, lvts_irq_handler,1324 IRQF_ONESHOT, dev_name(dev), lvts_td);1325 if (ret)1326 return dev_err_probe(dev, ret, "Failed to request interrupt\n");1327 1328 platform_set_drvdata(pdev, lvts_td);1329 1330 return 0;1331}1332 1333static void lvts_remove(struct platform_device *pdev)1334{1335 struct lvts_domain *lvts_td;1336 int i;1337 1338 lvts_td = platform_get_drvdata(pdev);1339 1340 for (i = 0; i < lvts_td->num_lvts_ctrl; i++)1341 lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);1342 1343 lvts_debugfs_exit(lvts_td);1344}1345 1346static const struct lvts_ctrl_data mt7988_lvts_ap_data_ctrl[] = {1347 {1348 .lvts_sensor = {1349 { .dt_id = MT7988_CPU_0,1350 .cal_offsets = { 0x00, 0x01, 0x02 } },1351 { .dt_id = MT7988_CPU_1,1352 .cal_offsets = { 0x04, 0x05, 0x06 } },1353 { .dt_id = MT7988_ETH2P5G_0,1354 .cal_offsets = { 0x08, 0x09, 0x0a } },1355 { .dt_id = MT7988_ETH2P5G_1,1356 .cal_offsets = { 0x0c, 0x0d, 0x0e } }1357 },1358 VALID_SENSOR_MAP(1, 1, 1, 1),1359 .offset = 0x0,1360 },1361 {1362 .lvts_sensor = {1363 { .dt_id = MT7988_TOPS_0,1364 .cal_offsets = { 0x14, 0x15, 0x16 } },1365 { .dt_id = MT7988_TOPS_1,1366 .cal_offsets = { 0x18, 0x19, 0x1a } },1367 { .dt_id = MT7988_ETHWARP_0,1368 .cal_offsets = { 0x1c, 0x1d, 0x1e } },1369 { .dt_id = MT7988_ETHWARP_1,1370 .cal_offsets = { 0x20, 0x21, 0x22 } }1371 },1372 VALID_SENSOR_MAP(1, 1, 1, 1),1373 .offset = 0x100,1374 }1375};1376 1377static int lvts_suspend(struct device *dev)1378{1379 struct lvts_domain *lvts_td;1380 int i;1381 1382 lvts_td = dev_get_drvdata(dev);1383 1384 for (i = 0; i < lvts_td->num_lvts_ctrl; i++)1385 lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);1386 1387 clk_disable_unprepare(lvts_td->clk);1388 1389 return 0;1390}1391 1392static int lvts_resume(struct device *dev)1393{1394 struct lvts_domain *lvts_td;1395 int i, ret;1396 1397 lvts_td = dev_get_drvdata(dev);1398 1399 ret = clk_prepare_enable(lvts_td->clk);1400 if (ret)1401 return ret;1402 1403 for (i = 0; i < lvts_td->num_lvts_ctrl; i++)1404 lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], true);1405 1406 return 0;1407}1408 1409/*1410 * The MT8186 calibration data is stored as packed 3-byte little-endian1411 * values using a weird layout that makes sense only when viewed as a 32-bit1412 * hexadecimal word dump. Let's suppose SxBy where x = sensor number and1413 * y = byte number where the LSB is y=0. We then have:1414 *1415 * [S0B2-S0B1-S0B0-S1B2] [S1B1-S1B0-S2B2-S2B1] [S2B0-S3B2-S3B1-S3B0]1416 *1417 * However, when considering a byte stream, those appear as follows:1418 *1419 * [S1B2] [S0B0[ [S0B1] [S0B2] [S2B1] [S2B2] [S1B0] [S1B1] [S3B0] [S3B1] [S3B2] [S2B0]1420 *1421 * Hence the rather confusing offsets provided below.1422 */1423static const struct lvts_ctrl_data mt8186_lvts_data_ctrl[] = {1424 {1425 .lvts_sensor = {1426 { .dt_id = MT8186_LITTLE_CPU0,1427 .cal_offsets = { 5, 6, 7 } },1428 { .dt_id = MT8186_LITTLE_CPU1,1429 .cal_offsets = { 10, 11, 4 } },1430 { .dt_id = MT8186_LITTLE_CPU2,1431 .cal_offsets = { 15, 8, 9 } },1432 { .dt_id = MT8186_CAM,1433 .cal_offsets = { 12, 13, 14 } }1434 },1435 VALID_SENSOR_MAP(1, 1, 1, 1),1436 .offset = 0x0,1437 },1438 {1439 .lvts_sensor = {1440 { .dt_id = MT8186_BIG_CPU0,1441 .cal_offsets = { 22, 23, 16 } },1442 { .dt_id = MT8186_BIG_CPU1,1443 .cal_offsets = { 27, 20, 21 } }1444 },1445 VALID_SENSOR_MAP(1, 1, 0, 0),1446 .offset = 0x100,1447 },1448 {1449 .lvts_sensor = {1450 { .dt_id = MT8186_NNA,1451 .cal_offsets = { 29, 30, 31 } },1452 { .dt_id = MT8186_ADSP,1453 .cal_offsets = { 34, 35, 28 } },1454 { .dt_id = MT8186_GPU,1455 .cal_offsets = { 39, 32, 33 } }1456 },1457 VALID_SENSOR_MAP(1, 1, 1, 0),1458 .offset = 0x200,1459 }1460};1461 1462static const struct lvts_ctrl_data mt8188_lvts_mcu_data_ctrl[] = {1463 {1464 .lvts_sensor = {1465 { .dt_id = MT8188_MCU_LITTLE_CPU0,1466 .cal_offsets = { 22, 23, 24 } },1467 { .dt_id = MT8188_MCU_LITTLE_CPU1,1468 .cal_offsets = { 25, 26, 27 } },1469 { .dt_id = MT8188_MCU_LITTLE_CPU2,1470 .cal_offsets = { 28, 29, 30 } },1471 { .dt_id = MT8188_MCU_LITTLE_CPU3,1472 .cal_offsets = { 31, 32, 33 } },1473 },1474 VALID_SENSOR_MAP(1, 1, 1, 1),1475 .offset = 0x0,1476 },1477 {1478 .lvts_sensor = {1479 { .dt_id = MT8188_MCU_BIG_CPU0,1480 .cal_offsets = { 34, 35, 36 } },1481 { .dt_id = MT8188_MCU_BIG_CPU1,1482 .cal_offsets = { 37, 38, 39 } },1483 },1484 VALID_SENSOR_MAP(1, 1, 0, 0),1485 .offset = 0x100,1486 }1487};1488 1489static const struct lvts_ctrl_data mt8188_lvts_ap_data_ctrl[] = {1490 {1491 .lvts_sensor = {1492 1493 { /* unused */ },1494 { .dt_id = MT8188_AP_APU,1495 .cal_offsets = { 40, 41, 42 } },1496 },1497 VALID_SENSOR_MAP(0, 1, 0, 0),1498 .offset = 0x0,1499 },1500 {1501 .lvts_sensor = {1502 { .dt_id = MT8188_AP_GPU0,1503 .cal_offsets = { 43, 44, 45 } },1504 { .dt_id = MT8188_AP_GPU1,1505 .cal_offsets = { 46, 47, 48 } },1506 { .dt_id = MT8188_AP_ADSP,1507 .cal_offsets = { 49, 50, 51 } },1508 },1509 VALID_SENSOR_MAP(1, 1, 1, 0),1510 .offset = 0x100,1511 },1512 {1513 .lvts_sensor = {1514 { .dt_id = MT8188_AP_VDO,1515 .cal_offsets = { 52, 53, 54 } },1516 { .dt_id = MT8188_AP_INFRA,1517 .cal_offsets = { 55, 56, 57 } },1518 },1519 VALID_SENSOR_MAP(1, 1, 0, 0),1520 .offset = 0x200,1521 },1522 {1523 .lvts_sensor = {1524 { .dt_id = MT8188_AP_CAM1,1525 .cal_offsets = { 58, 59, 60 } },1526 { .dt_id = MT8188_AP_CAM2,1527 .cal_offsets = { 61, 62, 63 } },1528 },1529 VALID_SENSOR_MAP(1, 1, 0, 0),1530 .offset = 0x300,1531 }1532};1533 1534static const struct lvts_ctrl_data mt8192_lvts_mcu_data_ctrl[] = {1535 {1536 .lvts_sensor = {1537 { .dt_id = MT8192_MCU_BIG_CPU0,1538 .cal_offsets = { 0x04, 0x05, 0x06 } },1539 { .dt_id = MT8192_MCU_BIG_CPU1,1540 .cal_offsets = { 0x08, 0x09, 0x0a } }1541 },1542 VALID_SENSOR_MAP(1, 1, 0, 0),1543 .offset = 0x0,1544 .mode = LVTS_MSR_FILTERED_MODE,1545 },1546 {1547 .lvts_sensor = {1548 { .dt_id = MT8192_MCU_BIG_CPU2,1549 .cal_offsets = { 0x0c, 0x0d, 0x0e } },1550 { .dt_id = MT8192_MCU_BIG_CPU3,1551 .cal_offsets = { 0x10, 0x11, 0x12 } }1552 },1553 VALID_SENSOR_MAP(1, 1, 0, 0),1554 .offset = 0x100,1555 .mode = LVTS_MSR_FILTERED_MODE,1556 },1557 {1558 .lvts_sensor = {1559 { .dt_id = MT8192_MCU_LITTLE_CPU0,1560 .cal_offsets = { 0x14, 0x15, 0x16 } },1561 { .dt_id = MT8192_MCU_LITTLE_CPU1,1562 .cal_offsets = { 0x18, 0x19, 0x1a } },1563 { .dt_id = MT8192_MCU_LITTLE_CPU2,1564 .cal_offsets = { 0x1c, 0x1d, 0x1e } },1565 { .dt_id = MT8192_MCU_LITTLE_CPU3,1566 .cal_offsets = { 0x20, 0x21, 0x22 } }1567 },1568 VALID_SENSOR_MAP(1, 1, 1, 1),1569 .offset = 0x200,1570 .mode = LVTS_MSR_FILTERED_MODE,1571 }1572};1573 1574static const struct lvts_ctrl_data mt8192_lvts_ap_data_ctrl[] = {1575 {1576 .lvts_sensor = {1577 { .dt_id = MT8192_AP_VPU0,1578 .cal_offsets = { 0x24, 0x25, 0x26 } },1579 { .dt_id = MT8192_AP_VPU1,1580 .cal_offsets = { 0x28, 0x29, 0x2a } }1581 },1582 VALID_SENSOR_MAP(1, 1, 0, 0),1583 .offset = 0x0,1584 },1585 {1586 .lvts_sensor = {1587 { .dt_id = MT8192_AP_GPU0,1588 .cal_offsets = { 0x2c, 0x2d, 0x2e } },1589 { .dt_id = MT8192_AP_GPU1,1590 .cal_offsets = { 0x30, 0x31, 0x32 } }1591 },1592 VALID_SENSOR_MAP(1, 1, 0, 0),1593 .offset = 0x100,1594 },1595 {1596 .lvts_sensor = {1597 { .dt_id = MT8192_AP_INFRA,1598 .cal_offsets = { 0x34, 0x35, 0x36 } },1599 { .dt_id = MT8192_AP_CAM,1600 .cal_offsets = { 0x38, 0x39, 0x3a } },1601 },1602 VALID_SENSOR_MAP(1, 1, 0, 0),1603 .offset = 0x200,1604 },1605 {1606 .lvts_sensor = {1607 { .dt_id = MT8192_AP_MD0,1608 .cal_offsets = { 0x3c, 0x3d, 0x3e } },1609 { .dt_id = MT8192_AP_MD1,1610 .cal_offsets = { 0x40, 0x41, 0x42 } },1611 { .dt_id = MT8192_AP_MD2,1612 .cal_offsets = { 0x44, 0x45, 0x46 } }1613 },1614 VALID_SENSOR_MAP(1, 1, 1, 0),1615 .offset = 0x300,1616 }1617};1618 1619static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {1620 {1621 .lvts_sensor = {1622 { .dt_id = MT8195_MCU_BIG_CPU0,1623 .cal_offsets = { 0x04, 0x05, 0x06 } },1624 { .dt_id = MT8195_MCU_BIG_CPU1,1625 .cal_offsets = { 0x07, 0x08, 0x09 } }1626 },1627 VALID_SENSOR_MAP(1, 1, 0, 0),1628 .offset = 0x0,1629 },1630 {1631 .lvts_sensor = {1632 { .dt_id = MT8195_MCU_BIG_CPU2,1633 .cal_offsets = { 0x0d, 0x0e, 0x0f } },1634 { .dt_id = MT8195_MCU_BIG_CPU3,1635 .cal_offsets = { 0x10, 0x11, 0x12 } }1636 },1637 VALID_SENSOR_MAP(1, 1, 0, 0),1638 .offset = 0x100,1639 },1640 {1641 .lvts_sensor = {1642 { .dt_id = MT8195_MCU_LITTLE_CPU0,1643 .cal_offsets = { 0x16, 0x17, 0x18 } },1644 { .dt_id = MT8195_MCU_LITTLE_CPU1,1645 .cal_offsets = { 0x19, 0x1a, 0x1b } },1646 { .dt_id = MT8195_MCU_LITTLE_CPU2,1647 .cal_offsets = { 0x1c, 0x1d, 0x1e } },1648 { .dt_id = MT8195_MCU_LITTLE_CPU3,1649 .cal_offsets = { 0x1f, 0x20, 0x21 } }1650 },1651 VALID_SENSOR_MAP(1, 1, 1, 1),1652 .offset = 0x200,1653 }1654};1655 1656static const struct lvts_ctrl_data mt8195_lvts_ap_data_ctrl[] = {1657 {1658 .lvts_sensor = {1659 { .dt_id = MT8195_AP_VPU0,1660 .cal_offsets = { 0x25, 0x26, 0x27 } },1661 { .dt_id = MT8195_AP_VPU1,1662 .cal_offsets = { 0x28, 0x29, 0x2a } }1663 },1664 VALID_SENSOR_MAP(1, 1, 0, 0),1665 .offset = 0x0,1666 },1667 {1668 .lvts_sensor = {1669 { .dt_id = MT8195_AP_GPU0,1670 .cal_offsets = { 0x2e, 0x2f, 0x30 } },1671 { .dt_id = MT8195_AP_GPU1,1672 .cal_offsets = { 0x31, 0x32, 0x33 } }1673 },1674 VALID_SENSOR_MAP(1, 1, 0, 0),1675 .offset = 0x100,1676 },1677 {1678 .lvts_sensor = {1679 { .dt_id = MT8195_AP_VDEC,1680 .cal_offsets = { 0x37, 0x38, 0x39 } },1681 { .dt_id = MT8195_AP_IMG,1682 .cal_offsets = { 0x3a, 0x3b, 0x3c } },1683 { .dt_id = MT8195_AP_INFRA,1684 .cal_offsets = { 0x3d, 0x3e, 0x3f } }1685 },1686 VALID_SENSOR_MAP(1, 1, 1, 0),1687 .offset = 0x200,1688 },1689 {1690 .lvts_sensor = {1691 { .dt_id = MT8195_AP_CAM0,1692 .cal_offsets = { 0x43, 0x44, 0x45 } },1693 { .dt_id = MT8195_AP_CAM1,1694 .cal_offsets = { 0x46, 0x47, 0x48 } }1695 },1696 VALID_SENSOR_MAP(1, 1, 0, 0),1697 .offset = 0x300,1698 }1699};1700 1701static const struct lvts_data mt7988_lvts_ap_data = {1702 .lvts_ctrl = mt7988_lvts_ap_data_ctrl,1703 .num_lvts_ctrl = ARRAY_SIZE(mt7988_lvts_ap_data_ctrl),1704 .temp_factor = LVTS_COEFF_A_MT7988,1705 .temp_offset = LVTS_COEFF_B_MT7988,1706 .gt_calib_bit_offset = 24,1707};1708 1709static const struct lvts_data mt8186_lvts_data = {1710 .lvts_ctrl = mt8186_lvts_data_ctrl,1711 .num_lvts_ctrl = ARRAY_SIZE(mt8186_lvts_data_ctrl),1712 .temp_factor = LVTS_COEFF_A_MT7988,1713 .temp_offset = LVTS_COEFF_B_MT7988,1714 .gt_calib_bit_offset = 24,1715 .def_calibration = 19000,1716};1717 1718static const struct lvts_data mt8188_lvts_mcu_data = {1719 .lvts_ctrl = mt8188_lvts_mcu_data_ctrl,1720 .num_lvts_ctrl = ARRAY_SIZE(mt8188_lvts_mcu_data_ctrl),1721 .temp_factor = LVTS_COEFF_A_MT8195,1722 .temp_offset = LVTS_COEFF_B_MT8195,1723 .gt_calib_bit_offset = 20,1724 .def_calibration = 35000,1725};1726 1727static const struct lvts_data mt8188_lvts_ap_data = {1728 .lvts_ctrl = mt8188_lvts_ap_data_ctrl,1729 .num_lvts_ctrl = ARRAY_SIZE(mt8188_lvts_ap_data_ctrl),1730 .temp_factor = LVTS_COEFF_A_MT8195,1731 .temp_offset = LVTS_COEFF_B_MT8195,1732 .gt_calib_bit_offset = 20,1733 .def_calibration = 35000,1734};1735 1736static const struct lvts_data mt8192_lvts_mcu_data = {1737 .lvts_ctrl = mt8192_lvts_mcu_data_ctrl,1738 .num_lvts_ctrl = ARRAY_SIZE(mt8192_lvts_mcu_data_ctrl),1739 .temp_factor = LVTS_COEFF_A_MT8195,1740 .temp_offset = LVTS_COEFF_B_MT8195,1741 .gt_calib_bit_offset = 24,1742 .def_calibration = 35000,1743};1744 1745static const struct lvts_data mt8192_lvts_ap_data = {1746 .lvts_ctrl = mt8192_lvts_ap_data_ctrl,1747 .num_lvts_ctrl = ARRAY_SIZE(mt8192_lvts_ap_data_ctrl),1748 .temp_factor = LVTS_COEFF_A_MT8195,1749 .temp_offset = LVTS_COEFF_B_MT8195,1750 .gt_calib_bit_offset = 24,1751 .def_calibration = 35000,1752};1753 1754static const struct lvts_data mt8195_lvts_mcu_data = {1755 .lvts_ctrl = mt8195_lvts_mcu_data_ctrl,1756 .num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_mcu_data_ctrl),1757 .temp_factor = LVTS_COEFF_A_MT8195,1758 .temp_offset = LVTS_COEFF_B_MT8195,1759 .gt_calib_bit_offset = 24,1760 .def_calibration = 35000,1761};1762 1763static const struct lvts_data mt8195_lvts_ap_data = {1764 .lvts_ctrl = mt8195_lvts_ap_data_ctrl,1765 .num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_ap_data_ctrl),1766 .temp_factor = LVTS_COEFF_A_MT8195,1767 .temp_offset = LVTS_COEFF_B_MT8195,1768 .gt_calib_bit_offset = 24,1769 .def_calibration = 35000,1770};1771 1772static const struct of_device_id lvts_of_match[] = {1773 { .compatible = "mediatek,mt7988-lvts-ap", .data = &mt7988_lvts_ap_data },1774 { .compatible = "mediatek,mt8186-lvts", .data = &mt8186_lvts_data },1775 { .compatible = "mediatek,mt8188-lvts-mcu", .data = &mt8188_lvts_mcu_data },1776 { .compatible = "mediatek,mt8188-lvts-ap", .data = &mt8188_lvts_ap_data },1777 { .compatible = "mediatek,mt8192-lvts-mcu", .data = &mt8192_lvts_mcu_data },1778 { .compatible = "mediatek,mt8192-lvts-ap", .data = &mt8192_lvts_ap_data },1779 { .compatible = "mediatek,mt8195-lvts-mcu", .data = &mt8195_lvts_mcu_data },1780 { .compatible = "mediatek,mt8195-lvts-ap", .data = &mt8195_lvts_ap_data },1781 {},1782};1783MODULE_DEVICE_TABLE(of, lvts_of_match);1784 1785static const struct dev_pm_ops lvts_pm_ops = {1786 NOIRQ_SYSTEM_SLEEP_PM_OPS(lvts_suspend, lvts_resume)1787};1788 1789static struct platform_driver lvts_driver = {1790 .probe = lvts_probe,1791 .remove_new = lvts_remove,1792 .driver = {1793 .name = "mtk-lvts-thermal",1794 .of_match_table = lvts_of_match,1795 .pm = &lvts_pm_ops,1796 },1797};1798module_platform_driver(lvts_driver);1799 1800MODULE_AUTHOR("Balsam CHIHI <bchihi@baylibre.com>");1801MODULE_DESCRIPTION("MediaTek LVTS Thermal Driver");1802MODULE_LICENSE("GPL");1803