1*3da2d29cSRaymond Sun /* 2*3da2d29cSRaymond Sun * Copyright (c) 2025, MediaTek Inc. All rights reserved. 3*3da2d29cSRaymond Sun * 4*3da2d29cSRaymond Sun * SPDX-License-Identifier: BSD-3-Clause 5*3da2d29cSRaymond Sun */ 6*3da2d29cSRaymond Sun 7*3da2d29cSRaymond Sun #ifndef THERMAL_LVTS_H 8*3da2d29cSRaymond Sun #define THERMAL_LVTS_H 9*3da2d29cSRaymond Sun 10*3da2d29cSRaymond Sun /* Definition or macro function */ 11*3da2d29cSRaymond Sun #define LK_LVTS_MAGIC (0x0000555) 12*3da2d29cSRaymond Sun #define TFA_LVTS_MAGIC (0x0000777) 13*3da2d29cSRaymond Sun 14*3da2d29cSRaymond Sun #define THERMAL_TEMP_INVALID (-274000) 15*3da2d29cSRaymond Sun 16*3da2d29cSRaymond Sun #define DEVICE_ACCESS_START_BIT (24) 17*3da2d29cSRaymond Sun 18*3da2d29cSRaymond Sun #define DISABLE_THERMAL_HW_REBOOT (-274000) 19*3da2d29cSRaymond Sun 20*3da2d29cSRaymond Sun #define CLOCK_26MHZ_CYCLE_NS (38) 21*3da2d29cSRaymond Sun 22*3da2d29cSRaymond Sun #define FEATURE_DEVICE_AUTO_RCK (BIT(0)) 23*3da2d29cSRaymond Sun 24*3da2d29cSRaymond Sun #define IS_ENABLE(lvts_data, feature) \ 25*3da2d29cSRaymond Sun (lvts_data->feature_bitmap & feature) 26*3da2d29cSRaymond Sun 27*3da2d29cSRaymond Sun #define GET_BASE_ADDR(lvts_data, tc_id) \ 28*3da2d29cSRaymond Sun (lvts_data->domain[lvts_data->tc[tc_id].domain_index].base \ 29*3da2d29cSRaymond Sun + lvts_data->tc[tc_id].addr_offset) 30*3da2d29cSRaymond Sun 31*3da2d29cSRaymond Sun #define SET_TC_SPEED_IN_US(pu, gd, fd, sd) \ 32*3da2d29cSRaymond Sun { \ 33*3da2d29cSRaymond Sun .period_unit = ((pu * 1000) / (256 * CLOCK_26MHZ_CYCLE_NS)), \ 34*3da2d29cSRaymond Sun .group_interval_delay = (gd / pu), \ 35*3da2d29cSRaymond Sun .filter_interval_delay = (fd / pu), \ 36*3da2d29cSRaymond Sun .sensor_interval_delay = (sd / pu), \ 37*3da2d29cSRaymond Sun } 38*3da2d29cSRaymond Sun 39*3da2d29cSRaymond Sun #define GET_CAL_BITMASK(lvts_data, index, h, l) \ 40*3da2d29cSRaymond Sun ((index < lvts_data->num_efuse_addr) \ 41*3da2d29cSRaymond Sun ? ((lvts_data->efuse[index] & GENMASK(h, l)) >> l) \ 42*3da2d29cSRaymond Sun : 0) 43*3da2d29cSRaymond Sun 44*3da2d29cSRaymond Sun 45*3da2d29cSRaymond Sun /* LVTS HW filter settings 46*3da2d29cSRaymond Sun * 000: Get one sample 47*3da2d29cSRaymond Sun * 001: Get 2 samples and average them 48*3da2d29cSRaymond Sun * 010: Get 4 samples, drop max and min, then average the rest of 2 samples 49*3da2d29cSRaymond Sun * 011: Get 6 samples, drop max and min, then average the rest of 4 samples 50*3da2d29cSRaymond Sun * 100: Get 10 samples, drop max and min, then average the rest of 8 samples 51*3da2d29cSRaymond Sun * 101: Get 18 samples, drop max and min, then average the rest of 16 samples 52*3da2d29cSRaymond Sun */ 53*3da2d29cSRaymond Sun enum lvts_hw_filter { 54*3da2d29cSRaymond Sun LVTS_FILTER_1, 55*3da2d29cSRaymond Sun LVTS_FILTER_2, 56*3da2d29cSRaymond Sun LVTS_FILTER_2_OF_4, 57*3da2d29cSRaymond Sun LVTS_FILTER_4_OF_6, 58*3da2d29cSRaymond Sun LVTS_FILTER_8_OF_10, 59*3da2d29cSRaymond Sun LVTS_FILTER_16_OF_18 60*3da2d29cSRaymond Sun }; 61*3da2d29cSRaymond Sun 62*3da2d29cSRaymond Sun enum lvts_sensing_point { 63*3da2d29cSRaymond Sun SENSING_POINT0, 64*3da2d29cSRaymond Sun SENSING_POINT1, 65*3da2d29cSRaymond Sun SENSING_POINT2, 66*3da2d29cSRaymond Sun SENSING_POINT3, 67*3da2d29cSRaymond Sun ALL_SENSING_POINTS 68*3da2d29cSRaymond Sun }; 69*3da2d29cSRaymond Sun 70*3da2d29cSRaymond Sun enum calibration_mode { 71*3da2d29cSRaymond Sun CALI_NT, 72*3da2d29cSRaymond Sun CALI_HT, 73*3da2d29cSRaymond Sun ALL_CALI_MODES 74*3da2d29cSRaymond Sun }; 75*3da2d29cSRaymond Sun 76*3da2d29cSRaymond Sun /* Data structure */ 77*3da2d29cSRaymond Sun struct lvts_data; 78*3da2d29cSRaymond Sun 79*3da2d29cSRaymond Sun struct speed_settings { 80*3da2d29cSRaymond Sun unsigned int period_unit; 81*3da2d29cSRaymond Sun unsigned int group_interval_delay; 82*3da2d29cSRaymond Sun unsigned int filter_interval_delay; 83*3da2d29cSRaymond Sun unsigned int sensor_interval_delay; 84*3da2d29cSRaymond Sun }; 85*3da2d29cSRaymond Sun 86*3da2d29cSRaymond Sun struct formula_coeff { 87*3da2d29cSRaymond Sun int a[ALL_SENSING_POINTS]; 88*3da2d29cSRaymond Sun unsigned int golden_temp; 89*3da2d29cSRaymond Sun enum calibration_mode cali_mode; 90*3da2d29cSRaymond Sun }; 91*3da2d29cSRaymond Sun 92*3da2d29cSRaymond Sun enum sensor_switch_status { 93*3da2d29cSRaymond Sun SEN_OFF, 94*3da2d29cSRaymond Sun SEN_ON 95*3da2d29cSRaymond Sun }; 96*3da2d29cSRaymond Sun 97*3da2d29cSRaymond Sun enum controller_switch_status { 98*3da2d29cSRaymond Sun CTRL_OFF, 99*3da2d29cSRaymond Sun CTRL_ON 100*3da2d29cSRaymond Sun }; 101*3da2d29cSRaymond Sun 102*3da2d29cSRaymond Sun struct tc_settings { 103*3da2d29cSRaymond Sun unsigned int domain_index; 104*3da2d29cSRaymond Sun uintptr_t addr_offset; 105*3da2d29cSRaymond Sun unsigned int num_sensor; 106*3da2d29cSRaymond Sun unsigned int sensor_map[ALL_SENSING_POINTS]; /* In sensor ID */ 107*3da2d29cSRaymond Sun enum controller_switch_status ctrl_on_off; 108*3da2d29cSRaymond Sun enum sensor_switch_status sensor_on_off[ALL_SENSING_POINTS]; 109*3da2d29cSRaymond Sun struct speed_settings tc_speed; 110*3da2d29cSRaymond Sun /* HW filter setting 111*3da2d29cSRaymond Sun * 000: Get one sample 112*3da2d29cSRaymond Sun * 001: Get 2 samples and average them 113*3da2d29cSRaymond Sun * 010: Get 4 samples, drop max&min and average the rest of 2 samples 114*3da2d29cSRaymond Sun * 011: Get 6 samples, drop max&min and average the rest of 4 samples 115*3da2d29cSRaymond Sun * 100: Get 10 samples, drop max&min and average the rest of 8 samples 116*3da2d29cSRaymond Sun * 101: Get 18 samples, drop max&min and average the rest of 16 samples 117*3da2d29cSRaymond Sun */ 118*3da2d29cSRaymond Sun uint32_t hw_filter; 119*3da2d29cSRaymond Sun /* Dominator_sensing point is used to select a sensing point 120*3da2d29cSRaymond Sun * and reference its temperature to trigger Thermal HW Reboot 121*3da2d29cSRaymond Sun * When it is ALL_SENSING_POINTS, it will select all sensing points 122*3da2d29cSRaymond Sun */ 123*3da2d29cSRaymond Sun enum lvts_sensing_point dominator_sensing_point; 124*3da2d29cSRaymond Sun int hw_reboot_trip_point; /* -274000: Disable HW reboot */ 125*3da2d29cSRaymond Sun uint32_t irq_bit; 126*3da2d29cSRaymond Sun struct formula_coeff coeff; 127*3da2d29cSRaymond Sun }; 128*3da2d29cSRaymond Sun 129*3da2d29cSRaymond Sun struct sensor_cal_data { 130*3da2d29cSRaymond Sun unsigned int golden_temp; 131*3da2d29cSRaymond Sun unsigned int golden_temp_ht; 132*3da2d29cSRaymond Sun uint32_t cali_mode; 133*3da2d29cSRaymond Sun uint32_t *count_r; 134*3da2d29cSRaymond Sun uint32_t *count_rc; 135*3da2d29cSRaymond Sun uint32_t *count_rc_now; 136*3da2d29cSRaymond Sun uint32_t *efuse_data; 137*3da2d29cSRaymond Sun 138*3da2d29cSRaymond Sun unsigned int default_golden_temp; 139*3da2d29cSRaymond Sun unsigned int default_golden_temp_ht; 140*3da2d29cSRaymond Sun uint32_t default_count_r; 141*3da2d29cSRaymond Sun uint32_t default_count_rc; 142*3da2d29cSRaymond Sun }; 143*3da2d29cSRaymond Sun 144*3da2d29cSRaymond Sun struct platform_ops { 145*3da2d29cSRaymond Sun void (*lvts_reset)(struct lvts_data *lvts_data); 146*3da2d29cSRaymond Sun void (*device_identification)(struct lvts_data *lvts_data); 147*3da2d29cSRaymond Sun void (*get_calibration_data)(struct lvts_data *lvts_data); 148*3da2d29cSRaymond Sun void (*efuse_to_cal_data)(struct lvts_data *lvts_data); 149*3da2d29cSRaymond Sun void (*device_enable_and_init)(struct lvts_data *lvts_data); 150*3da2d29cSRaymond Sun void (*device_enable_auto_rck)(struct lvts_data *lvts_data); 151*3da2d29cSRaymond Sun int (*device_read_count_rc_n)(struct lvts_data *lvts_data); 152*3da2d29cSRaymond Sun void (*set_cal_data)(struct lvts_data *lvts_data); 153*3da2d29cSRaymond Sun void (*init_controller)(struct lvts_data *lvts_data); 154*3da2d29cSRaymond Sun int (*lvts_raw_to_temp)(const struct formula_coeff *co, 155*3da2d29cSRaymond Sun unsigned int id, unsigned int msr_raw); 156*3da2d29cSRaymond Sun unsigned int (*lvts_temp_to_raw)(const struct formula_coeff *co, 157*3da2d29cSRaymond Sun unsigned int id, int temp); 158*3da2d29cSRaymond Sun void (*check_cal_data)(struct lvts_data *lvts_data); 159*3da2d29cSRaymond Sun void (*update_coef_data)(struct lvts_data *lvts_data); 160*3da2d29cSRaymond Sun }; 161*3da2d29cSRaymond Sun 162*3da2d29cSRaymond Sun struct power_domain { 163*3da2d29cSRaymond Sun uintptr_t base; /* LVTS base addresses */ 164*3da2d29cSRaymond Sun uintptr_t reset_base; 165*3da2d29cSRaymond Sun uintptr_t reset_set_offset; 166*3da2d29cSRaymond Sun uintptr_t reset_clr_offset; 167*3da2d29cSRaymond Sun uint32_t reset_set_bitnum; 168*3da2d29cSRaymond Sun uint32_t reset_clr_bitnum; 169*3da2d29cSRaymond Sun }; 170*3da2d29cSRaymond Sun 171*3da2d29cSRaymond Sun struct sensor_data { 172*3da2d29cSRaymond Sun int temp; /* Current temperature */ 173*3da2d29cSRaymond Sun unsigned int msr_raw; /* MSR raw data from LVTS */ 174*3da2d29cSRaymond Sun }; 175*3da2d29cSRaymond Sun 176*3da2d29cSRaymond Sun struct lvts_data { 177*3da2d29cSRaymond Sun unsigned int num_domain; 178*3da2d29cSRaymond Sun struct power_domain *domain; 179*3da2d29cSRaymond Sun 180*3da2d29cSRaymond Sun unsigned int num_tc; /* Number of LVTS thermal controllers */ 181*3da2d29cSRaymond Sun struct tc_settings *tc; 182*3da2d29cSRaymond Sun int counting_window_us; /* LVTS device counting window */ 183*3da2d29cSRaymond Sun 184*3da2d29cSRaymond Sun unsigned int num_sensor; /* Number of sensors in this platform */ 185*3da2d29cSRaymond Sun struct sensor_data *sen_data; 186*3da2d29cSRaymond Sun 187*3da2d29cSRaymond Sun struct platform_ops ops; 188*3da2d29cSRaymond Sun int feature_bitmap; /* Show what features are enabled */ 189*3da2d29cSRaymond Sun 190*3da2d29cSRaymond Sun unsigned int num_efuse_addr; 191*3da2d29cSRaymond Sun uint32_t *efuse; 192*3da2d29cSRaymond Sun 193*3da2d29cSRaymond Sun uint32_t *irq_bitmap; 194*3da2d29cSRaymond Sun 195*3da2d29cSRaymond Sun struct sensor_cal_data cal_data; 196*3da2d29cSRaymond Sun int enable_dump_log; 197*3da2d29cSRaymond Sun bool init_done; 198*3da2d29cSRaymond Sun }; 199*3da2d29cSRaymond Sun 200*3da2d29cSRaymond Sun /* LVTS device register */ 201*3da2d29cSRaymond Sun #define RG_TSFM_CTRL_0 0x03 202*3da2d29cSRaymond Sun #define RG_TSFM_CTRL_3 0x06 203*3da2d29cSRaymond Sun #define RG_TSV2F_CTRL_0 0x08 204*3da2d29cSRaymond Sun #define RG_TSV2F_CTRL_1 0x09 205*3da2d29cSRaymond Sun #define RG_TSV2F_CTRL_2 0x0A 206*3da2d29cSRaymond Sun #define RG_TSV2F_CTRL_3 0x0B 207*3da2d29cSRaymond Sun #define RG_TSV2F_CTRL_4 0x0C 208*3da2d29cSRaymond Sun #define RG_TSV2F_CTRL_5 0x0D 209*3da2d29cSRaymond Sun #define RG_TSV2F_CTRL_6 0x0E 210*3da2d29cSRaymond Sun #define RG_DID_LVTS 0xFC 211*3da2d29cSRaymond Sun #define RG_TSFM_RST 0xFF 212*3da2d29cSRaymond Sun 213*3da2d29cSRaymond Sun /* LVTS controller register */ 214*3da2d29cSRaymond Sun #define LVTSMONCTL0_0 0x000 215*3da2d29cSRaymond Sun #define LVTS_SINGLE_SENSE (1UL << 9) 216*3da2d29cSRaymond Sun #define DISABLE_SENSING_POINT (LVTS_SINGLE_SENSE | 0x0) 217*3da2d29cSRaymond Sun #define LVTSMONCTL1_0 0x004 218*3da2d29cSRaymond Sun #define LVTSMONCTL2_0 0x008 219*3da2d29cSRaymond Sun #define LVTSMONINT_0 0x00C 220*3da2d29cSRaymond Sun #define STAGE3_INT_EN (1UL << 31) 221*3da2d29cSRaymond Sun 222*3da2d29cSRaymond Sun #define HIGH_OFFSET3_INT_EN (1UL << 25) 223*3da2d29cSRaymond Sun #define HIGH_OFFSET2_INT_EN (1UL << 13) 224*3da2d29cSRaymond Sun #define HIGH_OFFSET1_INT_EN (1UL << 8) 225*3da2d29cSRaymond Sun #define HIGH_OFFSET0_INT_EN (1UL << 3) 226*3da2d29cSRaymond Sun 227*3da2d29cSRaymond Sun #define LOW_OFFSET3_INT_EN (1UL << 24) 228*3da2d29cSRaymond Sun #define LOW_OFFSET2_INT_EN (1UL << 12) 229*3da2d29cSRaymond Sun #define LOW_OFFSET1_INT_EN (1UL << 7) 230*3da2d29cSRaymond Sun #define LOW_OFFSET0_INT_EN (1UL << 2) 231*3da2d29cSRaymond Sun 232*3da2d29cSRaymond Sun #define LVTSOFFSETH_0 0x030 233*3da2d29cSRaymond Sun #define LVTSOFFSETL_0 0x034 234*3da2d29cSRaymond Sun #define LVTSMSRCTL0_0 0x038 235*3da2d29cSRaymond Sun #define LVTSMSRCTL1_0 0x03C 236*3da2d29cSRaymond Sun #define LVTSTSSEL_0 0x040 237*3da2d29cSRaymond Sun #define LVTSCALSCALE_0 0x048 238*3da2d29cSRaymond Sun #define SET_CALC_SCALE_RULES 0x00000300 239*3da2d29cSRaymond Sun #define LVTS_ID_0 0x04C 240*3da2d29cSRaymond Sun #define LVTS_CONFIG_0 0x050 241*3da2d29cSRaymond Sun #define LVTSEDATA00_0 0x054 242*3da2d29cSRaymond Sun #define MRS_RAW_MASK GENMASK(15, 0) 243*3da2d29cSRaymond Sun #define LVTSRDATA0_0 0x0B0 244*3da2d29cSRaymond Sun #define LVTSPROTCTL_0 0x0C0 245*3da2d29cSRaymond Sun #define PROTOFFSET GENMASK(15, 0) 246*3da2d29cSRaymond Sun #define LVTSPROTTC_0 0x0CC 247*3da2d29cSRaymond Sun #define LVTSCLKEN_0 0x0E4 248*3da2d29cSRaymond Sun #define ENABLE_LVTS_CTRL_CLK (1) 249*3da2d29cSRaymond Sun #define LVTSSPARE0_0 0x0F0 250*3da2d29cSRaymond Sun 251*3da2d29cSRaymond Sun #define BROADCAST_ID_UPDATE (1UL << 26) 252*3da2d29cSRaymond Sun #define DEVICE_SENSING_STATUS (1UL << 25) 253*3da2d29cSRaymond Sun #define DEVICE_ACCESS_STARTUS (1UL << 24) 254*3da2d29cSRaymond Sun #define WRITE_ACCESS (1UL << 16) 255*3da2d29cSRaymond Sun 256*3da2d29cSRaymond Sun #define DEVICE_WRITE (1UL << 31 | 1UL << 30 | DEVICE_ACCESS_STARTUS \ 257*3da2d29cSRaymond Sun | 1UL << 17 | WRITE_ACCESS) 258*3da2d29cSRaymond Sun 259*3da2d29cSRaymond Sun 260*3da2d29cSRaymond Sun #define DEVICE_READ (1UL << 31 | 1UL << 30 | DEVICE_ACCESS_STARTUS \ 261*3da2d29cSRaymond Sun | 1UL << 17) 262*3da2d29cSRaymond Sun #define RESET_ALL_DEVICES (DEVICE_WRITE | RG_TSFM_RST << 8 | 0xFF) 263*3da2d29cSRaymond Sun #define READ_BACK_DEVICE_ID (1UL << 31 | 1UL << 30 | BROADCAST_ID_UPDATE \ 264*3da2d29cSRaymond Sun | DEVICE_ACCESS_STARTUS | 1UL << 17 \ 265*3da2d29cSRaymond Sun | RG_DID_LVTS << 8) 266*3da2d29cSRaymond Sun 267*3da2d29cSRaymond Sun #define READ_DEVICE_REG(reg_idx) (DEVICE_READ | reg_idx << 8 | 0x00) 268*3da2d29cSRaymond Sun 269*3da2d29cSRaymond Sun /* LVTS register mask */ 270*3da2d29cSRaymond Sun #define INIT_FOOTPRINT_ADDR_OFFSET (0x1F8) 271*3da2d29cSRaymond Sun #define CLOSE_FOOTPRINT_ADDR_OFFSET (0x1FC) 272*3da2d29cSRaymond Sun #define NO_IDLE_COUNT_ADDR_OFFSET (0x1E4) 273*3da2d29cSRaymond Sun 274*3da2d29cSRaymond Sun void thermal_clock_open(void); 275*3da2d29cSRaymond Sun void thermal_clock_close(void); 276*3da2d29cSRaymond Sun void set_polling_speed(struct lvts_data *lvts_data, unsigned int tc_id); 277*3da2d29cSRaymond Sun void set_hw_filter(struct lvts_data *lvts_data, unsigned int tc_id); 278*3da2d29cSRaymond Sun void lvts_write_all_device(struct lvts_data *lvts_data, uint32_t data); 279*3da2d29cSRaymond Sun void lvts_write_device(struct lvts_data *lvts_data, uint32_t data, 280*3da2d29cSRaymond Sun unsigned int tc_id); 281*3da2d29cSRaymond Sun uint32_t lvts_read_device(struct lvts_data *lvts_data, uint32_t reg_idx, 282*3da2d29cSRaymond Sun unsigned int tc_id); 283*3da2d29cSRaymond Sun void set_calibration_data_v1(struct lvts_data *lvts_data); 284*3da2d29cSRaymond Sun unsigned int get_dominator_index(struct lvts_data *lvts_data, 285*3da2d29cSRaymond Sun unsigned int tc_id); 286*3da2d29cSRaymond Sun void disable_hw_reboot_interrupt(struct lvts_data *lvts_data, 287*3da2d29cSRaymond Sun unsigned int tc_id); 288*3da2d29cSRaymond Sun void enable_hw_reboot_interrupt(struct lvts_data *lvts_data, 289*3da2d29cSRaymond Sun unsigned int tc_id); 290*3da2d29cSRaymond Sun void set_tc_hw_reboot_threshold(struct lvts_data *lvts_data, int trip_point, 291*3da2d29cSRaymond Sun unsigned int tc_id); 292*3da2d29cSRaymond Sun 293*3da2d29cSRaymond Sun extern struct lvts_data lvts_data_instance; 294*3da2d29cSRaymond Sun 295*3da2d29cSRaymond Sun #endif /* THERMAL_LVTS_H */ 296