1 /* 2 * Copyright (c) 2025, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <errno.h> 8 #include <stdint.h> 9 #include <stdio.h> 10 #include <common/debug.h> 11 #include <drivers/delay_timer.h> 12 #include <lib/mmio.h> 13 #include <lib/mmio_poll.h> 14 #include <lib/utils_def.h> 15 16 #include <lib/mtk_init/mtk_init.h> 17 #include <lpm/mt_lp_api.h> 18 #include <mtk_mmap_pool.h> 19 #include <soc_temp_lvts_interface.h> 20 #include <thermal_lvts.h> 21 22 static void lvts_write_device_nodelay(struct lvts_data *lvts_data, 23 uint32_t data, unsigned int tc_id) 24 { 25 uintptr_t base; 26 27 base = GET_BASE_ADDR(lvts_data, tc_id); 28 29 mmio_write_32(LVTS_CONFIG_0 + base, data); 30 } 31 32 static void lvts_write_data_check(struct lvts_data *lvts_data, uint32_t data, 33 unsigned int tc_id) 34 { 35 uintptr_t base; 36 int ret; 37 uint32_t temp; 38 39 base = GET_BASE_ADDR(lvts_data, tc_id); 40 41 ret = mmio_read_32_poll_timeout( 42 LVTS_CONFIG_0 + base, 43 temp, 44 ((temp & (0x1 << DEVICE_ACCESS_START_BIT)) == 0), 45 20); 46 47 if (ret) 48 INFO("write device err: LVTS %d didn't ready, data 0x%x\n", 49 tc_id, data); 50 } 51 52 void lvts_write_all_device(struct lvts_data *lvts_data, uint32_t data) 53 { 54 unsigned int tc_id; 55 struct tc_settings *tc = lvts_data->tc; 56 57 for (tc_id = 0; tc_id < lvts_data->num_tc; tc_id++) { 58 if (tc[tc_id].ctrl_on_off == CTRL_OFF) 59 continue; 60 61 lvts_write_device_nodelay(lvts_data, data, tc_id); 62 } 63 dmbsy(); 64 for (tc_id = 0; tc_id < lvts_data->num_tc; tc_id++) { 65 if (tc[tc_id].ctrl_on_off == CTRL_OFF) 66 continue; 67 68 lvts_write_data_check(lvts_data, data, tc_id); 69 } 70 } 71 72 void lvts_write_device(struct lvts_data *lvts_data, uint32_t data, 73 unsigned int tc_id) 74 { 75 uintptr_t base; 76 int ret; 77 uint32_t temp; 78 79 base = GET_BASE_ADDR(lvts_data, tc_id); 80 81 mmio_write_32(LVTS_CONFIG_0 + base, data); 82 dmbsy(); 83 84 udelay(5); 85 86 ret = mmio_read_32_poll_timeout( 87 LVTS_CONFIG_0 + base, 88 temp, 89 ((temp & (0x1 << DEVICE_ACCESS_START_BIT)) == 0), 90 20); 91 92 if (ret) 93 INFO("write device err: LVTS %d didn't ready, data 0x%x\n", 94 tc_id, data); 95 96 } 97 98 uint32_t lvts_read_device(struct lvts_data *lvts_data, uint32_t reg_idx, 99 unsigned int tc_id) 100 { 101 uintptr_t base; 102 uint32_t temp, data; 103 uint32_t write_val = READ_DEVICE_REG(reg_idx); 104 int ret; 105 106 base = GET_BASE_ADDR(lvts_data, tc_id); 107 mmio_write_32(LVTS_CONFIG_0 + base, write_val); 108 dmbsy(); 109 110 ret = mmio_read_32_poll_timeout( 111 LVTS_CONFIG_0 + base, 112 temp, 113 ((temp & (0x1 << DEVICE_ACCESS_START_BIT)) == 0), 114 20); 115 if (ret) 116 INFO("read device err: LVTS %d didn't ready, reg_idx 0x%x\n", 117 tc_id, reg_idx); 118 119 data = mmio_read_32(LVTSRDATA0_0 + base); 120 121 return data; 122 } 123 124 #define THERMAL_SENSOR_IDLE_MASK (BIT(10) | BIT(7) | BIT(0)) 125 #define HALF_WORD (16) 126 #define IDLE_CHECK_BIT1_MASK (BIT(10)) 127 #define IDLE_CHECK_BIT2_MASK (BIT(7)) 128 #define IDLE_CHECK_BIT3_MASK (BIT(0)) 129 #define SHIFT_8 (8) 130 #define SHIFT_6 (6) 131 132 static uint32_t lvts_thermal_check_all_sensing_point_idle( 133 struct lvts_data *lvts_data) 134 { 135 unsigned int i; 136 uintptr_t base; 137 uint32_t temp, mask, error_code; 138 struct tc_settings *tc = lvts_data->tc; 139 140 mask = THERMAL_SENSOR_IDLE_MASK; 141 142 for (i = 0; i < lvts_data->num_tc; i++) { 143 if (tc[i].ctrl_on_off == CTRL_OFF) 144 continue; 145 146 base = GET_BASE_ADDR(lvts_data, i); 147 temp = mmio_read_32(base + LVTSMSRCTL1_0); 148 /* Check if bit10=bit7=bit0=0 */ 149 if ((temp & mask) != 0) { 150 error_code = (i << HALF_WORD) 151 + ((temp & IDLE_CHECK_BIT1_MASK) >> SHIFT_8) 152 + ((temp & IDLE_CHECK_BIT2_MASK) >> SHIFT_6) 153 + (temp & IDLE_CHECK_BIT3_MASK); 154 155 return error_code; 156 } 157 } 158 159 return 0; 160 } 161 162 #define ITERATION_TIME (80) 163 #define DELAY_US (2) 164 165 static void wait_all_tc_sensing_point_idle(struct lvts_data *lvts_data) 166 { 167 unsigned int i; 168 uintptr_t base; 169 uint32_t temp, mask, error_code; 170 int cnt = 0; 171 struct tc_settings *tc = lvts_data->tc; 172 static unsigned int no_idle_count; 173 174 mask = THERMAL_SENSOR_IDLE_MASK; 175 176 while (cnt < ITERATION_TIME) { 177 temp = lvts_thermal_check_all_sensing_point_idle(lvts_data); 178 if (temp == 0) 179 goto TAIL; 180 181 udelay(DELAY_US); 182 cnt++; 183 184 } 185 no_idle_count++; 186 mmio_write_32(THERMAL_CSRAM_BASE + NO_IDLE_COUNT_ADDR_OFFSET, 187 no_idle_count); 188 189 for (i = 0; i < lvts_data->num_tc; i++) { 190 if (tc[i].ctrl_on_off == CTRL_OFF) 191 continue; 192 193 base = GET_BASE_ADDR(lvts_data, i); 194 temp = mmio_read_32(LVTSMSRCTL1_0 + base); 195 /* 196 * Error code 197 * 000: IDLE 198 * 001: Write transaction 199 * 010: Waiting for read after Write 200 * 011: Disable Continue fetching on Device 201 * 100: Read transaction 202 * 101: Set Device special Register for Voltage threshold 203 * 111: Set TSMCU number for Fetch 204 */ 205 if ((temp & mask) != 0) { 206 error_code = ((temp & IDLE_CHECK_BIT1_MASK) >> SHIFT_8) 207 + ((temp & IDLE_CHECK_BIT2_MASK) >> SHIFT_6) 208 + (temp & IDLE_CHECK_BIT3_MASK); 209 210 INFO("LVTS %d sensing points not idle, error_code %d\n", 211 i, error_code); 212 } 213 } 214 TAIL: 215 return; 216 } 217 218 static void disable_all_sensing_points(struct lvts_data *lvts_data) 219 { 220 unsigned int i; 221 uintptr_t base; 222 struct tc_settings *tc = lvts_data->tc; 223 224 for (i = 0; i < lvts_data->num_tc; i++) { 225 if (tc[i].ctrl_on_off == CTRL_OFF) 226 continue; 227 228 base = GET_BASE_ADDR(lvts_data, i); 229 mmio_write_32(LVTSMONCTL0_0 + base, DISABLE_SENSING_POINT); 230 } 231 dmbsy(); 232 } 233 234 static void enable_all_sensing_points(struct lvts_data *lvts_data) 235 { 236 struct tc_settings *tc = lvts_data->tc; 237 unsigned int i, j, num; 238 uintptr_t base; 239 uint32_t flag; 240 241 for (i = 0; i < lvts_data->num_tc; i++) { 242 if (tc[i].ctrl_on_off == CTRL_OFF) 243 continue; 244 245 base = GET_BASE_ADDR(lvts_data, i); 246 num = tc[i].num_sensor; 247 248 if (num > ALL_SENSING_POINTS) { 249 INFO("%s, LVTS%d, illegal number of sensors: %d\n", 250 __func__, i, tc[i].num_sensor); 251 continue; 252 } 253 254 flag = LVTS_SINGLE_SENSE; 255 for (j = 0; j < tc[i].num_sensor; j++) { 256 if (tc[i].sensor_on_off[j] != SEN_ON) 257 continue; 258 259 flag = flag | (0x1 << j); 260 } 261 mmio_write_32(LVTSMONCTL0_0 + base, flag); 262 } 263 dmbsy(); 264 } 265 266 void set_polling_speed(struct lvts_data *lvts_data, unsigned int tc_id) 267 { 268 struct tc_settings *tc = lvts_data->tc; 269 uint32_t lvts_mon_ctrl1, lvts_mon_ctrl2; 270 uintptr_t base; 271 272 base = GET_BASE_ADDR(lvts_data, tc_id); 273 274 lvts_mon_ctrl1 = (((tc[tc_id].tc_speed.group_interval_delay 275 << 20) & GENMASK(29, 20)) | 276 (tc[tc_id].tc_speed.period_unit & 277 GENMASK(9, 0))); 278 lvts_mon_ctrl2 = (((tc[tc_id].tc_speed.filter_interval_delay 279 << 16) & GENMASK(25, 16)) | 280 (tc[tc_id].tc_speed.sensor_interval_delay 281 & GENMASK(9, 0))); 282 /* 283 * Clock source of LVTS thermal controller is 26MHz. 284 * Period unit is a base for all interval delays 285 * All interval delays must multiply it to convert a setting to time. 286 * Filter interval delay is a delay between two samples of the same 287 * sensor 288 * Sensor interval delay is a delay between two samples of differnet 289 * sensors 290 * Group interval delay is a delay between different rounds. 291 * For example: 292 * If Period unit = C, filter delay = 1, sensor delay = 2, group 293 * delay = 1, 294 * and two sensors, TS1 and TS2, are in a LVTS thermal controller 295 * and then 296 * Period unit = C * 1/26M * 256 = 12 * 38.46ns * 256 = 118.149us 297 * Filter interval delay = 1 * Period unit = 118.149us 298 * Sensor interval delay = 2 * Period unit = 236.298us 299 * Group interval delay = 1 * Period unit = 118.149us 300 * 301 * TS1 TS1 ... TS1 TS2 TS2 ... TS2 TS1... 302 * <--> Filter interval delay 303 * <--> Sensor interval delay 304 * <--> Group interval delay 305 */ 306 mmio_write_32(LVTSMONCTL1_0 + base, lvts_mon_ctrl1); 307 mmio_write_32(LVTSMONCTL2_0 + base, lvts_mon_ctrl2); 308 dmbsy(); 309 } 310 311 void set_hw_filter(struct lvts_data *lvts_data, unsigned int tc_id) 312 { 313 struct tc_settings *tc = lvts_data->tc; 314 uint32_t option; 315 uintptr_t base; 316 317 base = GET_BASE_ADDR(lvts_data, tc_id); 318 option = tc[tc_id].hw_filter & 0x7; 319 /* hw filter 320 * 000: Get one sample 321 * 001: Get 2 samples and average them 322 * 010: Get 4 samples, drop max&min and average the rest of 2 samples 323 * 011: Get 6 samples, drop max&min and average the rest of 4 samples 324 * 100: Get 10 samples, drop max&min and average the rest of 8 samples 325 * 101: Get 18 samples, drop max&min and average the rest of 16 samples 326 */ 327 option = (option << 9) | (option << 6) | (option << 3) | option; 328 329 mmio_write_32(LVTSMSRCTL0_0 + base, option); 330 dmbsy(); 331 } 332 333 unsigned int get_dominator_index(struct lvts_data *lvts_data, 334 unsigned int tc_id) 335 { 336 struct tc_settings *tc = lvts_data->tc; 337 unsigned int d_index; 338 339 if (tc[tc_id].dominator_sensing_point == ALL_SENSING_POINTS) { 340 d_index = ALL_SENSING_POINTS; 341 } else if (tc[tc_id].dominator_sensing_point < 342 tc[tc_id].num_sensor){ 343 d_index = tc[tc_id].dominator_sensing_point; 344 } else { 345 INFO("Error: LVTS%d, dominator_sensing_point= %d over %d\n", 346 tc_id, tc[tc_id].dominator_sensing_point, 347 tc[tc_id].num_sensor); 348 349 INFO("Use the sensing point 0 as the dominated sensor\n"); 350 d_index = SENSING_POINT0; 351 } 352 353 return d_index; 354 } 355 356 static void set_all_tc_hw_reboot(struct lvts_data *lvts_data) 357 { 358 struct tc_settings *tc = lvts_data->tc; 359 int trip_point; 360 unsigned int i; 361 362 for (i = 0; i < lvts_data->num_tc; i++) { 363 if (tc[i].ctrl_on_off == CTRL_OFF) 364 continue; 365 366 trip_point = tc[i].hw_reboot_trip_point; 367 368 if (tc[i].num_sensor == 0) 369 continue; 370 371 if (trip_point == DISABLE_THERMAL_HW_REBOOT) { 372 disable_hw_reboot_interrupt(lvts_data, i); 373 continue; 374 } 375 376 set_tc_hw_reboot_threshold(lvts_data, trip_point, i); 377 } 378 } 379 380 static bool lvts_lk_init_check(struct lvts_data *lvts_data) 381 { 382 unsigned int i; 383 uint32_t data; 384 uintptr_t base; 385 bool ret = false; 386 struct tc_settings *tc = lvts_data->tc; 387 388 for (i = 0; i < lvts_data->num_tc; i++) { 389 if (tc[i].ctrl_on_off == CTRL_OFF) 390 continue; 391 392 base = GET_BASE_ADDR(lvts_data, i); 393 394 /* Check LVTS device ID */ 395 data = mmio_read_32(LVTSSPARE0_0 + base) & GENMASK(11, 0); 396 397 if (data == LK_LVTS_MAGIC) { 398 mmio_write_32(LVTSSPARE0_0 + base, 0x0); 399 ret = true; 400 } else { 401 ret = false; 402 break; 403 } 404 } 405 dmbsy(); 406 return ret; 407 } 408 409 static void lvts_set_init_flag_tfa(struct lvts_data *lvts_data) 410 { 411 uintptr_t base; 412 unsigned int i; 413 struct tc_settings *tc = lvts_data->tc; 414 415 /* write TFA init done flag to inform kernel */ 416 417 for (i = 0; i < lvts_data->num_tc; i++) { 418 if (tc[i].ctrl_on_off == CTRL_OFF) 419 continue; 420 421 base = GET_BASE_ADDR(lvts_data, i); 422 423 /* enable sensing point 0 */ 424 mmio_write_32(base + LVTSSPARE0_0, TFA_LVTS_MAGIC); 425 } 426 dmbsy(); 427 } 428 429 static void lvts_clear_init_flag_tfa(struct lvts_data *lvts_data) 430 { 431 uintptr_t base; 432 unsigned int i; 433 struct tc_settings *tc = lvts_data->tc; 434 435 for (i = 0; i < lvts_data->num_tc; i++) { 436 if (tc[i].ctrl_on_off == CTRL_OFF) 437 continue; 438 439 base = GET_BASE_ADDR(lvts_data, i); 440 mmio_write_32(LVTSSPARE0_0 + base, 0); 441 } 442 dmbsy(); 443 } 444 445 static int read_calibration_data(struct lvts_data *lvts_data) 446 { 447 struct tc_settings *tc = lvts_data->tc; 448 unsigned int i, j, s_index; 449 uintptr_t base; 450 struct sensor_cal_data *cal_data = &lvts_data->cal_data; 451 452 for (i = 0; i < lvts_data->num_tc; i++) { 453 if (tc[i].ctrl_on_off == CTRL_OFF) 454 continue; 455 456 base = GET_BASE_ADDR(lvts_data, i); 457 458 for (j = 0; j < tc[i].num_sensor; j++) { 459 if (tc[i].sensor_on_off[j] != SEN_ON) 460 continue; 461 462 s_index = tc[i].sensor_map[j]; 463 464 cal_data->efuse_data[s_index] = 465 mmio_read_32(LVTSEDATA00_0 + base + 0x4 * j); 466 467 } 468 } 469 470 return 0; 471 } 472 473 static int lvts_init(struct lvts_data *lvts_data) 474 { 475 struct platform_ops *ops = &lvts_data->ops; 476 int ret; 477 bool lk_init = false; 478 479 mmio_write_32(THERMAL_CSRAM_BASE + CLOSE_FOOTPRINT_ADDR_OFFSET, 0x0); 480 481 thermal_clock_open(); 482 483 lk_init = lvts_lk_init_check(lvts_data); 484 if (lk_init == true) { 485 ret = read_calibration_data(lvts_data); 486 487 lvts_set_init_flag_tfa(lvts_data); 488 lvts_data->init_done = true; 489 INFO("%s, LK init LVTS\n", __func__); 490 491 return ret; 492 } 493 494 ops->lvts_reset(lvts_data); 495 496 if (ops->device_identification) 497 ops->device_identification(lvts_data); 498 499 if (ops->device_enable_and_init) 500 ops->device_enable_and_init(lvts_data); 501 502 if (IS_ENABLE(lvts_data, (int)FEATURE_DEVICE_AUTO_RCK)) { 503 if (ops->device_enable_auto_rck) 504 ops->device_enable_auto_rck(lvts_data); 505 } else { 506 if (ops->device_read_count_rc_n) 507 ops->device_read_count_rc_n(lvts_data); 508 } 509 510 if (ops->set_cal_data) 511 ops->set_cal_data(lvts_data); 512 513 disable_all_sensing_points(lvts_data); 514 wait_all_tc_sensing_point_idle(lvts_data); 515 if (ops->init_controller) 516 ops->init_controller(lvts_data); 517 518 set_all_tc_hw_reboot(lvts_data); 519 enable_all_sensing_points(lvts_data); 520 lvts_set_init_flag_tfa(lvts_data); 521 lvts_data->init_done = true; 522 523 return 0; 524 } 525 526 static int update_lvts_data_from_efuse(struct lvts_data *lvts_data) 527 { 528 struct platform_ops *ops = &lvts_data->ops; 529 530 if (ops->get_calibration_data) 531 ops->get_calibration_data(lvts_data); 532 533 if (ops->efuse_to_cal_data) 534 ops->efuse_to_cal_data(lvts_data); 535 536 if (ops->check_cal_data) 537 ops->check_cal_data(lvts_data); 538 539 if (ops->update_coef_data) 540 ops->update_coef_data(lvts_data); 541 542 return 0; 543 } 544 545 static void lvts_close(struct lvts_data *lvts_data) 546 { 547 mmio_write_32(THERMAL_CSRAM_BASE + INIT_FOOTPRINT_ADDR_OFFSET, 0x0); 548 549 lvts_data->ops.lvts_reset(lvts_data); 550 551 lvts_clear_init_flag_tfa(lvts_data); 552 553 thermal_clock_close(); 554 } 555 556 void set_calibration_data_v1(struct lvts_data *lvts_data) 557 { 558 struct tc_settings *tc = lvts_data->tc; 559 struct sensor_cal_data *cal_data = &lvts_data->cal_data; 560 unsigned int i, j, s_index; 561 uint32_t e_data; 562 uintptr_t base; 563 564 for (i = 0; i < lvts_data->num_tc; i++) { 565 if (tc[i].ctrl_on_off == CTRL_OFF) 566 continue; 567 568 base = GET_BASE_ADDR(lvts_data, i); 569 570 for (j = 0; j < tc[i].num_sensor; j++) { 571 if (tc[i].sensor_on_off[j] != SEN_ON) 572 continue; 573 574 s_index = tc[i].sensor_map[j]; 575 if (IS_ENABLE(lvts_data, (int)FEATURE_DEVICE_AUTO_RCK)) 576 e_data = cal_data->count_r[s_index]; 577 else 578 e_data = cal_data->efuse_data[s_index]; 579 580 mmio_write_32(LVTSEDATA00_0 + base + 0x4 * j, e_data); 581 } 582 } 583 dmbsy(); 584 } 585 586 static int lvts_thermal_init(void) 587 { 588 struct lvts_data *lvts_data; 589 int ret; 590 591 lvts_data = &lvts_data_instance; 592 593 ret = update_lvts_data_from_efuse(lvts_data); 594 if (ret) 595 return ret; 596 597 ret = lvts_init(lvts_data); 598 if (ret) 599 return ret; 600 601 return 0; 602 } 603 604 /* suspend/resume */ 605 static int lvts_suspend_callback(struct lvts_data *lvts_data) 606 { 607 lvts_close(lvts_data); 608 609 return 0; 610 } 611 612 static int lvts_resume_callback(struct lvts_data *lvts_data) 613 { 614 return lvts_init(lvts_data); 615 } 616 617 static void *lvts_pm_suspend_event_handler(const void *arg) 618 { 619 struct mt_lp_publish_event const *event = 620 (struct mt_lp_publish_event const *) arg; 621 struct lvts_data *lvts_data = &lvts_data_instance; 622 int ret; 623 624 if (!event) { 625 return NULL; 626 } 627 628 if (event->id == MT_LPM_PUBEVENTS_SYS_POWER_OFF) { 629 ret = lvts_suspend_callback(lvts_data); 630 if (ret) { 631 INFO("%s, %d, ret = %d\n", __func__, __LINE__, ret); 632 } 633 return (void *)arg; 634 635 } else if (event->id == MT_LPM_PUBEVENTS_SYS_POWER_ON) { 636 ret = lvts_resume_callback(lvts_data); 637 if (ret) { 638 INFO("%s, %d, ret = %d\n", __func__, __LINE__, ret); 639 } 640 return (void *)arg; 641 } 642 643 return NULL; 644 } 645 MT_LP_SUBSCRIBE_SUSPEND(lvts_pm_suspend_event_handler); 646 647 MTK_PLAT_RUNTIME_INIT(lvts_thermal_init); 648