yu.dong | c33b307 | 2024-08-21 23:14:49 -0700 | [diff] [blame^] | 1 | /***************************************************************************** |
| 2 | * Copyright Statement: |
| 3 | * -------------------- |
| 4 | * This software is protected by Copyright and the information contained |
| 5 | * herein is confidential. The software may not be copied and the information |
| 6 | * contained herein may not be used or disclosed except with the written |
| 7 | * permission of MediaTek Inc. (C) 2017 |
| 8 | * |
| 9 | * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES |
| 10 | * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") |
| 11 | * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON |
| 12 | * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, |
| 13 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF |
| 14 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. |
| 15 | * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE |
| 16 | * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR |
| 17 | * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH |
| 18 | * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO |
| 19 | * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S |
| 20 | * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. |
| 21 | * |
| 22 | * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE |
| 23 | * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, |
| 24 | * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, |
| 25 | * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO |
| 26 | * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. |
| 27 | * |
| 28 | * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE |
| 29 | * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF |
| 30 | * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND |
| 31 | * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER |
| 32 | * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC). |
| 33 | * |
| 34 | *****************************************************************************/ |
| 35 | |
| 36 | /******************************************************************************* |
| 37 | * |
| 38 | * Filename: |
| 39 | * --------- |
| 40 | * tia.c |
| 41 | * |
| 42 | * Project: |
| 43 | * -------- |
| 44 | * VMOLY |
| 45 | * |
| 46 | * Description: |
| 47 | * ------------ |
| 48 | * TIA (Thermal Information Acquisition) driver for MD thermal |
| 49 | * |
| 50 | * Author: |
| 51 | * ------- |
| 52 | * ------- |
| 53 | * |
| 54 | *============================================================================ |
| 55 | * HISTORY |
| 56 | * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!! |
| 57 | *------------------------------------------------------------------------------ |
| 58 | * removed! |
| 59 | * removed! |
| 60 | * removed! |
| 61 | * |
| 62 | * removed! |
| 63 | * removed! |
| 64 | * removed! |
| 65 | * removed! |
| 66 | * removed! |
| 67 | * removed! |
| 68 | * removed! |
| 69 | * removed! |
| 70 | * |
| 71 | * removed! |
| 72 | * removed! |
| 73 | * removed! |
| 74 | *------------------------------------------------------------------------------ |
| 75 | * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!! |
| 76 | *============================================================================ |
| 77 | ****************************************************************************/ |
| 78 | |
| 79 | #include "kal_public_api.h" |
| 80 | #include "kal_ex_api.h" |
| 81 | #include "drv_comm.h" |
| 82 | #include "us_timer.h" |
| 83 | #include "cache_sw.h" |
| 84 | #include "tia_reg.h" |
| 85 | #include "tia.h" |
| 86 | |
| 87 | // sensor information |
| 88 | static tfwk_sensor_info_t tia_sensor_info[TIA_SENSOR_NUM] = { |
| 89 | {.sensor_id=1, .min_temperature=-200, .max_temperature=1150, .warning_temperature=9999, .accuracy=30, .resolution=10, .sensor_name="PA_Group_2_NTC"}, |
| 90 | {.sensor_id=2, .min_temperature=-200, .max_temperature=1150, .warning_temperature=9999, .accuracy=30, .resolution=10, .sensor_name="PA_Group_1_NTC"}, |
| 91 | {.sensor_id=3, .min_temperature=-200, .max_temperature=1150, .warning_temperature=9999, .accuracy=30, .resolution=10, .sensor_name="RF_IC_NTC"}, |
| 92 | {.sensor_id=4, .min_temperature=-200, .max_temperature=1150, .warning_temperature=9999, .accuracy=30, .resolution=10, .sensor_name="SOC_NTC"}, |
| 93 | }; |
| 94 | static kal_uint32 tia_sensor_hwShutdownTemp[TIA_SENSOR_NUM] = {9999, 9999, 9999, 9999}; |
| 95 | const kal_uint32 tia_sensor_map[TIA_SENSOR_NUM] = { |
| 96 | //PA_G2, PA_G1, RF_IC, SOC |
| 97 | 2, 1, 3, 0 |
| 98 | }; |
| 99 | #if defined(CHIP10992) |
| 100 | static kal_bool tia_sensor_fake_en = KAL_FALSE; |
| 101 | static kal_uint32 tia_sensor_fake_ohm[TIA_SENSOR_NUM]; |
| 102 | #else |
| 103 | static kal_bool tia_sensor_fake_en = KAL_TRUE; |
| 104 | static kal_uint32 tia_sensor_fake_ohm[TIA_SENSOR_NUM] = {0x000186A0, 0x000186A0, 0x000186A0, 0x000186A0}; |
| 105 | #endif |
| 106 | |
| 107 | // threshold monitor |
| 108 | #define TIA_THR_TMP_MAX (TIA_ADC_TMP_MAX * 10) // threshold temperature: valid max |
| 109 | #define TIA_THR_TMP_MIN (TIA_ADC_TMP_MIN * 10) // threshold temperature: valid max |
| 110 | #define TIA_THR_TMP_HW_NEAR (100) // threshold temperature, near HW shutdown (>= HW - this_DEF) |
| 111 | #define TIA_THR_PP_NUM 2 // ping-pong number |
| 112 | #define TIA_THR_ALM_NUM 2 // alarm number |
| 113 | enum { // threshold type |
| 114 | TIA_THR_TYP_HW = 0, |
| 115 | TIA_THR_TYP_SW, |
| 116 | TIA_THR_TYP_WRN, |
| 117 | TIA_THR_TYP_AL0, |
| 118 | TIA_THR_TYP_AL1, |
| 119 | TIA_THR_TYP_MAX |
| 120 | }; |
| 121 | static const kal_char *tia_thr_typ_str[TIA_THR_TYP_MAX] = {"hw", "sw", "wrn", "al0", "al1"}; |
| 122 | enum { // alarm type |
| 123 | TIA_ALM_TYP_RISING = 0, |
| 124 | TIA_ALM_TYP_FALLING, |
| 125 | TIA_ALM_TYP_DISABLE |
| 126 | }; |
| 127 | static tfwk_thermal_cfg_t tia_thr_cfgs[TIA_SENSOR_NUM][TIA_THR_PP_NUM][TIA_THR_ALM_NUM]; |
| 128 | static struct tia_thr_mon_s { |
| 129 | kal_bool vld; // valid or not |
| 130 | kal_int32 thr; // threshold value, order: hw > sw > fim > al0 > al1 |
| 131 | tfwk_thermal_cfg_t *cfg; // pointer to tia_thr_cfgs (for sw/fim/alarm, not hw) |
| 132 | } tia_thr_mons[TIA_SENSOR_NUM][TIA_THR_PP_NUM][TIA_THR_TYP_MAX]; |
| 133 | static kal_uint32 tia_thr_ppi[TIA_SENSOR_NUM]; // current ppi, update to ~ppi |
| 134 | static kal_uint32 tia_thr_hw; |
| 135 | #define TIA_HW_RESET_RECORD(tid) \ |
| 136 | DRV_WriteReg32(TOPRGU_WDT_NONRST_REG2, DRV_Reg32(TOPRGU_WDT_NONRST_REG2) | TOPRGU_TID_STATUS(tid)) |
| 137 | |
| 138 | #define TIA_TMR_MS_DFT 1000 // default polling period |
| 139 | #define TIA_TMR_MS_ITS 100 // intensive polling period |
| 140 | #define TIA_TMR_MS_MIN 64 // minimax polling period |
| 141 | static kal_timerid tia_tmr_id; |
| 142 | static kal_spinlockid tia_tmr_sl; |
| 143 | static void tia_tmr_set(kal_uint32 ms, kal_bool imm); |
| 144 | |
| 145 | //#define TIA_STACK_PRF |
| 146 | #ifdef TIA_STACK_PRF |
| 147 | #define STACK_SIZE_MAX 0x1000 |
| 148 | #define STACK_GUARD_PTN0 0x43415453 // STACKEND |
| 149 | #define STACK_GUARD_PTN1 0x444E454B |
| 150 | #define STACK_GUARD_TST 0xFEFEFEFE |
| 151 | |
| 152 | static struct { |
| 153 | kal_uint32 init_bas; |
| 154 | kal_uint32 init_cur; |
| 155 | kal_uint32 init_us; |
| 156 | kal_uint32 done_cur; |
| 157 | kal_uint32 done_use; |
| 158 | kal_uint32 done_us; |
| 159 | } tia_stack_prf; |
| 160 | |
| 161 | static void __attribute__((noinline)) tia_stack_prf_init(void) |
| 162 | { |
| 163 | void *sp_ptr = NULL; |
| 164 | register kal_uint32 adr; |
| 165 | |
| 166 | tia_stack_prf.init_cur = (kal_uint32) &sp_ptr; |
| 167 | for (adr = tia_stack_prf.init_cur & ~0x7; adr > tia_stack_prf.init_cur - STACK_SIZE_MAX; adr -= 8) { |
| 168 | if ((DRV_Reg32(adr) == STACK_GUARD_PTN0) && (DRV_Reg32(adr+4) == STACK_GUARD_PTN1)) { |
| 169 | adr = CPU_CACHE_LINE_ALIGN_ADDR(adr) + CPU_CACHE_LINE_ALIGN_LEN(adr, 8); |
| 170 | break; |
| 171 | } |
| 172 | } |
| 173 | tia_stack_prf.init_bas = adr; |
| 174 | for (; adr < tia_stack_prf.init_cur - 0x10; adr += 4) { |
| 175 | DRV_WriteReg32(adr, STACK_GUARD_TST); |
| 176 | } |
| 177 | tia_stack_prf.init_us = ust_get_current_time(); |
| 178 | } |
| 179 | |
| 180 | static void __attribute__((noinline)) tia_stack_prf_done(void) |
| 181 | { |
| 182 | void *sp_ptr = NULL; |
| 183 | register kal_uint32 adr; |
| 184 | |
| 185 | tia_stack_prf.done_us = ust_get_current_time(); |
| 186 | tia_stack_prf.done_cur = (kal_uint32) &sp_ptr; |
| 187 | for (adr = tia_stack_prf.init_bas; adr < tia_stack_prf.init_cur; adr += 4) { |
| 188 | if (DRV_Reg32(adr) != STACK_GUARD_TST) { |
| 189 | break; |
| 190 | } |
| 191 | } |
| 192 | tia_stack_prf.done_use = adr; |
| 193 | } |
| 194 | |
| 195 | static void __attribute__((noinline)) tia_stack_prf_result(void) |
| 196 | { |
| 197 | MD_TRC(TIA_MSG_STACK_INFO, |
| 198 | tia_stack_prf.init_cur, tia_stack_prf.init_bas, tia_stack_prf.init_cur - tia_stack_prf.init_bas, |
| 199 | tia_stack_prf.done_cur, tia_stack_prf.done_use, tia_stack_prf.done_cur - tia_stack_prf.done_use, |
| 200 | ust_us_duration(tia_stack_prf.init_us, tia_stack_prf.done_us)); |
| 201 | } |
| 202 | #endif |
| 203 | |
| 204 | static kal_int32 tia_temp(kal_uint32 tid) |
| 205 | { |
| 206 | static struct { |
| 207 | kal_uint32 frc; |
| 208 | kal_int32 tmp; |
| 209 | } tmps[TIA_SENSOR_NUM]; |
| 210 | kal_uint32 nid, reg, dbg, frc, rc, adc; |
| 211 | kal_int32 tmp; |
| 212 | |
| 213 | if (tia_sensor_fake_en) { |
| 214 | rc = TIA_ADC_RC_FAKE; |
| 215 | adc = tia_sensor_fake_ohm[tid]; |
| 216 | tmp = tia_adc_to_tmp(rc, adc); |
| 217 | MD_TRC(TIA_MSG_AUXADC_TMP, tid, TIA_ADC_RC2K(rc), adc, tmp, tia_sensor_fake_en); |
| 218 | } else { |
| 219 | nid = TIA_SENSOR_NID(tid); |
| 220 | reg = DRV_Reg32(TIA_HW_RC_ADC(nid)); |
| 221 | frc = ust_get_current_time(); |
| 222 | if (TIA_HW_ADC_VLD(reg)) { |
| 223 | rc = TIA_HW_RC_VAL(reg); |
| 224 | adc = TIA_HW_ADC_VAL(reg); |
| 225 | tmp = tia_adc_to_tmp(rc, adc); |
| 226 | EXT_ASSERT(tmp != TIA_ADC_TMP_ERR, rc, adc, (kal_uint32) tmp); |
| 227 | tmps[tid].frc = frc; |
| 228 | tmps[tid].tmp = tmp; |
| 229 | MD_TRC(TIA_MSG_AUXADC_TMP, tid, TIA_ADC_RC2K(rc), adc, tmp, tia_sensor_fake_en); |
| 230 | } else { |
| 231 | dbg = DRV_Reg32(TIA_TIA2_DEBUG); |
| 232 | EXT_ASSERT((tmps[tid].frc != 0) && (tmps[tid].tmp != 0), tid, reg, dbg); |
| 233 | tmp = tmps[tid].tmp; |
| 234 | MD_TRC(TIA_MSG_ERR_ADC_INVALID, __func__, tid, reg, dbg, tmp, ust_us_duration(tmps[tid].frc, frc)); |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | return tmp; |
| 239 | } |
| 240 | |
| 241 | static void tia_notify(kal_uint32 tid, kal_int32 tmp, tfwk_thermal_cfg_t* cfg) |
| 242 | { |
| 243 | static thermal_sta_info_t tia_thr_ntf; // declare "static" in global bss, dont use stack area (kal timer limitation) |
| 244 | kal_uint32 sid, idx; |
| 245 | |
| 246 | tia_thr_ntf.temp = tmp; |
| 247 | memcpy(&tia_thr_ntf.cfg, cfg, sizeof(thermal_cfg_t)); |
| 248 | |
| 249 | for (sid = THERMAL_LVTS_SENSOR_ID(0); sid < THERMAL_LVTS_SENSOR_ID(THERMAL_LVTS_SENSOR_NUM); sid++) { |
| 250 | tia_thr_ntf.others[sid].sensor_id = sid; |
| 251 | TIA_LVTS_GET_TEMP(sid, &tia_thr_ntf.others[sid].temp); |
| 252 | } |
| 253 | idx = sid; |
| 254 | for (sid = THERMAL_TIA_SENSOR_ID(0); sid < THERMAL_TIA_SENSOR_ID(TIA_SENSOR_NUM); sid++) { |
| 255 | if (TIA_SENSOR_TID(sid) == tid) { |
| 256 | continue; |
| 257 | } |
| 258 | tia_thr_ntf.others[idx].sensor_id = sid; |
| 259 | tia_thr_ntf.others[idx].temp = tia_temp(TIA_SENSOR_TID(sid)); |
| 260 | idx++; |
| 261 | } |
| 262 | |
| 263 | tfwk_sensor_notify(&tia_thr_ntf); |
| 264 | } |
| 265 | |
| 266 | static void tia_tmr_handler(void *param_ptr) |
| 267 | { |
| 268 | kal_uint32 tid, idx, tms = 0; |
| 269 | kal_int32 tmp; |
| 270 | kal_bool hit, ins = KAL_FALSE; |
| 271 | struct tia_thr_mon_s *mon; |
| 272 | |
| 273 | #ifdef TIA_STACK_PRF |
| 274 | tia_stack_prf_init(); |
| 275 | #endif |
| 276 | // check threshold |
| 277 | for (tid = 0; tid < TIA_SENSOR_NUM; tid++) { |
| 278 | tmp = tia_temp(tid); // always update temperature locally |
| 279 | mon = tia_thr_mons[tid][tia_thr_ppi[tid]]; |
| 280 | hit = KAL_FALSE; |
| 281 | for (idx = 0; idx < TIA_THR_TYP_MAX; idx++) { |
| 282 | if (mon[idx].vld) { hit = KAL_TRUE; break; } |
| 283 | } |
| 284 | if (!hit) { continue; } |
| 285 | // hw threshold |
| 286 | if (mon[TIA_THR_TYP_HW].vld) { |
| 287 | if (tmp >= mon[TIA_THR_TYP_HW].thr) { |
| 288 | MD_TRC(TIA_MSG_ERR_OVER_HW_THRESHOLD, __func__, tid, tmp, mon[TIA_THR_TYP_HW].thr); |
| 289 | TIA_HW_RESET_RECORD(tid); |
| 290 | TIA_LVTS_HW_RGU_RESET(); |
| 291 | break; |
| 292 | } else if (tmp >= (mon[TIA_THR_TYP_HW].thr - TIA_THR_TMP_HW_NEAR)) { |
| 293 | MD_TRC(TIA_MSG_NEAR_HW_THRESHOLD, tid, tmp, mon[TIA_THR_TYP_HW].thr); |
| 294 | } |
| 295 | } |
| 296 | // rising sw/fim/alarm threshold |
| 297 | hit = KAL_FALSE; |
| 298 | for (idx = TIA_THR_TYP_SW; idx < TIA_THR_TYP_MAX; idx++) { |
| 299 | if ((mon[idx].vld == KAL_FALSE) || (mon[idx].cfg->sensor_alarm_type != TIA_ALM_TYP_RISING)) { |
| 300 | continue; |
| 301 | } |
| 302 | if (hit) { // disable lower threhold |
| 303 | mon[idx].vld = KAL_FALSE; |
| 304 | continue; |
| 305 | } |
| 306 | if (tmp >= mon[idx].thr) { |
| 307 | tia_notify(tid, tmp, mon[idx].cfg); |
| 308 | mon[idx].vld = KAL_FALSE; |
| 309 | hit = KAL_TRUE; |
| 310 | MD_TRC(TIA_MSG_OVER_THRESHOLD, tid, tmp, tia_thr_typ_str[idx], mon[idx].thr); |
| 311 | MD_TRC(TIA_MSG_ALARM_INFO, mon[idx].cfg->enable, mon[idx].cfg->sensor_id, mon[idx].cfg->alarm_id, |
| 312 | mon[idx].cfg->threshold_value, mon[idx].cfg->hysteresis_value, mon[idx].cfg->sampling_period, |
| 313 | mon[idx].cfg->sensor_alarm_type); |
| 314 | } |
| 315 | } |
| 316 | // falling alarm threshold |
| 317 | hit = KAL_FALSE; |
| 318 | for (idx = TIA_THR_TYP_AL1; idx >= TIA_THR_TYP_AL0; idx--) { |
| 319 | if ((mon[idx].vld == KAL_FALSE) || (mon[idx].cfg->sensor_alarm_type != TIA_ALM_TYP_FALLING)) { |
| 320 | continue; |
| 321 | } |
| 322 | if (hit) { // disable higher threhold |
| 323 | mon[idx].vld = KAL_FALSE; |
| 324 | continue; |
| 325 | } |
| 326 | if (tmp <= mon[idx].thr) { |
| 327 | tia_notify(tid, tmp, mon[idx].cfg); |
| 328 | mon[idx].vld = KAL_FALSE; |
| 329 | hit = KAL_TRUE; |
| 330 | MD_TRC(TIA_MSG_UNDER_THRESHOLD, tid, tmp, tia_thr_typ_str[idx], mon[idx].thr); |
| 331 | MD_TRC(TIA_MSG_ALARM_INFO, mon[idx].cfg->enable, mon[idx].cfg->sensor_id, mon[idx].cfg->alarm_id, |
| 332 | mon[idx].cfg->threshold_value, mon[idx].cfg->hysteresis_value, mon[idx].cfg->sampling_period, |
| 333 | mon[idx].cfg->sensor_alarm_type); |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | // sample period (config and insensive) |
| 338 | for (idx = TIA_THR_TYP_SW; idx < TIA_THR_TYP_MAX; idx++) { |
| 339 | kal_uint32 t; |
| 340 | if (mon[idx].vld == KAL_FALSE) { |
| 341 | continue; |
| 342 | } |
| 343 | t = mon[idx].cfg->sampling_period; |
| 344 | if ((tms == 0) || (tms > t)) { |
| 345 | tms = (t < TIA_TMR_MS_MIN)? TIA_TMR_MS_MIN: t; |
| 346 | } |
| 347 | if ((mon[idx].cfg->sensor_alarm_type == TIA_ALM_TYP_RISING) && |
| 348 | (tmp >= (mon[idx].cfg->threshold_value - (kal_int32) mon[idx].cfg->hysteresis_value))) { |
| 349 | ins = KAL_TRUE; |
| 350 | continue; |
| 351 | } |
| 352 | if ((mon[idx].cfg->sensor_alarm_type == TIA_ALM_TYP_FALLING) && |
| 353 | (tmp <= (mon[idx].cfg->threshold_value + (kal_int32) mon[idx].cfg->hysteresis_value))) { |
| 354 | ins = KAL_TRUE; |
| 355 | continue; |
| 356 | } |
| 357 | } |
| 358 | } |
| 359 | |
| 360 | // update timer period |
| 361 | if ((ins) && (tms > TIA_TMR_MS_ITS)) { |
| 362 | tms = TIA_TMR_MS_ITS; |
| 363 | } |
| 364 | tia_tmr_set(tms, KAL_FALSE); |
| 365 | #ifdef TIA_STACK_PRF |
| 366 | tia_stack_prf_done(); |
| 367 | tia_stack_prf_result(); |
| 368 | #endif |
| 369 | } |
| 370 | |
| 371 | static void tia_tmr_set(kal_uint32 ms, kal_bool imm) |
| 372 | { |
| 373 | static kal_uint32 ms_cfg; |
| 374 | kal_bool ms_trc = KAL_FALSE; |
| 375 | kal_uint32 tck; |
| 376 | |
| 377 | if ((ms == 0) && tia_thr_hw) { |
| 378 | ms = TIA_TMR_MS_DFT; |
| 379 | } |
| 380 | tck = kal_milli_secs_to_ticks(ms); |
| 381 | |
| 382 | kal_take_spinlock(tia_tmr_sl, KAL_INFINITE_WAIT); |
| 383 | if (ms != ms_cfg) { |
| 384 | if (ms_cfg != 1) { |
| 385 | ms_trc = KAL_TRUE; |
| 386 | } |
| 387 | if (ms == 0) { |
| 388 | kal_cancel_timer(tia_tmr_id); |
| 389 | ms_cfg = 0; |
| 390 | } else if (imm) { |
| 391 | kal_disable_delayed_timer(tia_tmr_id); |
| 392 | kal_set_timer(tia_tmr_id, tia_tmr_handler, NULL, 1, tck); |
| 393 | ms_cfg = 1; |
| 394 | } else { |
| 395 | kal_enable_delayed_timer(tia_tmr_id, MAX_DELAY_UNLIMITED); |
| 396 | kal_set_timer(tia_tmr_id, tia_tmr_handler, NULL, tck, tck); |
| 397 | ms_cfg = ms; |
| 398 | } |
| 399 | } |
| 400 | kal_give_spinlock(tia_tmr_sl); |
| 401 | |
| 402 | if (ms_trc) { |
| 403 | MD_TRC(TIA_MSG_SAMPLING_PERIOD, ms); |
| 404 | } |
| 405 | } |
| 406 | |
| 407 | static kal_int32 thr_alarm_temp_max(kal_uint32 tid) |
| 408 | { |
| 409 | struct tia_thr_mon_s *mon; |
| 410 | kal_int32 idx, tmp = TIA_THR_TMP_MAX; |
| 411 | |
| 412 | mon = tia_thr_mons[tid][tia_thr_ppi[tid]]; |
| 413 | for (idx = 0; idx < TIA_THR_TYP_AL0; idx++) { |
| 414 | if (tmp > mon[idx].thr) { |
| 415 | tmp = mon[idx].thr; |
| 416 | } |
| 417 | } |
| 418 | return tmp; |
| 419 | } |
| 420 | |
| 421 | static kal_int32 thr_alarm_temp_min(kal_uint32 tid) |
| 422 | { |
| 423 | kal_int32 tmp = TIA_THR_TMP_MIN; |
| 424 | |
| 425 | if (tmp < tia_sensor_info[tid].min_temperature) { |
| 426 | tmp = tia_sensor_info[tid].min_temperature; |
| 427 | } |
| 428 | return tmp; |
| 429 | } |
| 430 | |
| 431 | kal_int32 tia_set_alarm(kal_uint32 ncfg, tfwk_thermal_cfg_t* tcfgs) |
| 432 | { |
| 433 | #define _upd_err_code(r,e) do {if ((r)==THERMAL_ERR_NONE) (r) = (e);} while (0) |
| 434 | kal_int32 ret = THERMAL_ERR_NONE, tmp; |
| 435 | kal_uint32 tid, ppi, idx, tms; |
| 436 | struct tia_thr_mon_s *mon; |
| 437 | tfwk_thermal_cfg_t *cfg; |
| 438 | tfwk_thermal_cfg_t *cfg_f[TIA_SENSOR_NUM][TIA_THR_ALM_NUM] = {NULL}; // filter cfg list |
| 439 | |
| 440 | EXT_ASSERT(ncfg && tcfgs, ncfg, (kal_uint32) tcfgs, 0); |
| 441 | |
| 442 | // filter cfg |
| 443 | for (idx = 0; idx < ncfg; idx++) { |
| 444 | cfg = &tcfgs[idx]; |
| 445 | if (!TIA_SENSOR_SID_VALID(cfg->sensor_id)) { |
| 446 | MD_TRC(TIA_MSG_ERR_SENSOR_ID, __func__, cfg->sensor_id); |
| 447 | _upd_err_code(ret, THERMAL_ERR_SENSOR_ID); |
| 448 | continue; |
| 449 | } |
| 450 | if (cfg->alarm_id >= TIA_THR_ALM_NUM) { |
| 451 | MD_TRC(TIA_MSG_ERR_ALARM_ID, __func__, cfg->alarm_id); |
| 452 | _upd_err_code(ret, THERMAL_ERR_ALARM_ID); |
| 453 | continue; |
| 454 | } |
| 455 | tid = TIA_SENSOR_TID(cfg->sensor_id); |
| 456 | tmp = thr_alarm_temp_max(tid); |
| 457 | if (cfg->threshold_value >= tmp) { |
| 458 | MD_TRC(TIA_MSG_ERR_THRESHOLD_RANGE_MAX, __func__, cfg->threshold_value, tmp); |
| 459 | _upd_err_code(ret, THERMAL_ERR_THRESHOLD_RANGE); |
| 460 | continue; |
| 461 | } |
| 462 | tmp = thr_alarm_temp_min(tid); |
| 463 | if (cfg->threshold_value <= tmp) { |
| 464 | MD_TRC(TIA_MSG_ERR_THRESHOLD_RANGE_MIN, __func__, cfg->threshold_value, tmp); |
| 465 | _upd_err_code(ret, THERMAL_ERR_THRESHOLD_RANGE); |
| 466 | continue; |
| 467 | } |
| 468 | cfg_f[tid][cfg->alarm_id] = cfg; |
| 469 | MD_TRC(TIA_MSG_ALARM_INFO,cfg->enable, cfg->sensor_id, cfg->alarm_id, cfg->threshold_value, |
| 470 | cfg->hysteresis_value, cfg->sampling_period, cfg->sensor_alarm_type); |
| 471 | } |
| 472 | |
| 473 | // update internal cfg |
| 474 | for (tid = 0; tid < TIA_SENSOR_NUM; tid++) { |
| 475 | if ((cfg_f[tid][0]==NULL) && (cfg_f[tid][1]==NULL)) { |
| 476 | continue; |
| 477 | } |
| 478 | // clean first |
| 479 | ppi = !tia_thr_ppi[tid]; |
| 480 | mon = tia_thr_mons[tid][ppi]; |
| 481 | mon[TIA_THR_TYP_SW].vld = KAL_FALSE; |
| 482 | mon[TIA_THR_TYP_SW].cfg = NULL; |
| 483 | mon[TIA_THR_TYP_WRN].vld = KAL_FALSE; |
| 484 | mon[TIA_THR_TYP_WRN].cfg = NULL; |
| 485 | memset(&mon[TIA_THR_TYP_AL0], 0x0, sizeof(struct tia_thr_mon_s)*TIA_THR_ALM_NUM); |
| 486 | // update alarm |
| 487 | if ((cfg_f[tid][0] == NULL) || (cfg_f[tid][1] == NULL)) { |
| 488 | idx = (cfg_f[tid][0] == NULL); |
| 489 | memcpy(&tia_thr_cfgs[tid][ppi][idx], cfg_f[tid][idx], sizeof(tfwk_thermal_cfg_t)); |
| 490 | if ((cfg_f[tid][idx]->enable != 0) && (cfg_f[tid][idx]->sensor_alarm_type < TIA_ALM_TYP_DISABLE)) { |
| 491 | mon[TIA_THR_TYP_AL0].vld = KAL_TRUE; |
| 492 | mon[TIA_THR_TYP_AL0].thr = cfg_f[tid][idx]->threshold_value; |
| 493 | mon[TIA_THR_TYP_AL0].cfg = &tia_thr_cfgs[tid][ppi][idx]; |
| 494 | } |
| 495 | idx = !idx; |
| 496 | memset(&tia_thr_cfgs[tid][ppi][idx], 0x0, sizeof(tfwk_thermal_cfg_t)); |
| 497 | } else { |
| 498 | memcpy(&tia_thr_cfgs[tid][ppi][0], cfg_f[tid][0], sizeof(tfwk_thermal_cfg_t)); |
| 499 | memcpy(&tia_thr_cfgs[tid][ppi][1], cfg_f[tid][1], sizeof(tfwk_thermal_cfg_t)); |
| 500 | idx = (cfg_f[tid][0]->threshold_value < cfg_f[tid][1]->threshold_value); |
| 501 | tmp = TIA_THR_TYP_AL0; |
| 502 | if ((cfg_f[tid][idx]->enable != 0) && (cfg_f[tid][idx]->sensor_alarm_type < TIA_ALM_TYP_DISABLE)) { |
| 503 | mon[tmp].vld = KAL_TRUE; |
| 504 | mon[tmp].thr = cfg_f[tid][idx]->threshold_value; |
| 505 | mon[tmp].cfg = &tia_thr_cfgs[tid][ppi][idx]; |
| 506 | tmp++; |
| 507 | } |
| 508 | idx = !idx; |
| 509 | if ((cfg_f[tid][idx]->enable != 0) && (cfg_f[tid][idx]->sensor_alarm_type < TIA_ALM_TYP_DISABLE)) { |
| 510 | mon[tmp].vld = KAL_TRUE; |
| 511 | mon[tmp].thr = cfg_f[tid][idx]->threshold_value; |
| 512 | mon[tmp].cfg = &tia_thr_cfgs[tid][ppi][idx]; |
| 513 | } |
| 514 | } |
| 515 | // update sw/fim threshold if one more rising alarm |
| 516 | for (idx = TIA_THR_TYP_AL0; idx <= TIA_THR_TYP_AL1; idx++) { |
| 517 | if (mon[idx].vld && (mon[idx].cfg->sensor_alarm_type == TIA_ALM_TYP_RISING)) { |
| 518 | mon[TIA_THR_TYP_SW].vld = (mon[TIA_THR_TYP_SW].thr <= TIA_THR_TMP_MAX); |
| 519 | mon[TIA_THR_TYP_SW].cfg = mon[TIA_THR_TYP_SW].vld? mon[idx].cfg: NULL; |
| 520 | mon[TIA_THR_TYP_WRN].vld = (mon[TIA_THR_TYP_WRN].thr <= TIA_THR_TMP_MAX); |
| 521 | mon[TIA_THR_TYP_WRN].cfg = mon[TIA_THR_TYP_WRN].vld? mon[idx].cfg: NULL; |
| 522 | break; |
| 523 | } |
| 524 | } |
| 525 | tia_thr_ppi[tid] = ppi; |
| 526 | } |
| 527 | |
| 528 | // update sampling period |
| 529 | tms = 0; |
| 530 | for (tid = 0; tid < TIA_SENSOR_NUM; tid++) { |
| 531 | mon = tia_thr_mons[tid][tia_thr_ppi[tid]]; |
| 532 | for (idx = TIA_THR_TYP_AL0; idx <= TIA_THR_TYP_AL1; idx++) { |
| 533 | kal_uint32 t; |
| 534 | if (mon[idx].vld == KAL_FALSE) { |
| 535 | continue; |
| 536 | } |
| 537 | t = mon[idx].cfg->sampling_period; |
| 538 | if ((tms == 0) || (tms > t)) { |
| 539 | tms = (t < TIA_TMR_MS_MIN)? TIA_TMR_MS_MIN: t; |
| 540 | } |
| 541 | } |
| 542 | } |
| 543 | tia_tmr_set(tms, KAL_TRUE); |
| 544 | |
| 545 | if (ret != THERMAL_ERR_NONE) { |
| 546 | MD_TRC(TIA_MSG_ERR_CODE, __func__, ret); |
| 547 | } |
| 548 | return ret; |
| 549 | } |
| 550 | |
| 551 | kal_int32 tia_get_temp(kal_uint32 sensor_id, kal_int32 *temp) |
| 552 | { |
| 553 | if (!TIA_SENSOR_SID_VALID(sensor_id)) { |
| 554 | MD_TRC(TIA_MSG_ERR_SENSOR_ID, __func__, sensor_id); |
| 555 | return THERMAL_ERR_SENSOR_ID; |
| 556 | } |
| 557 | EXT_ASSERT(temp!=NULL, sensor_id, (kal_uint32) temp, 0); |
| 558 | |
| 559 | *temp = tia_temp(TIA_SENSOR_TID(sensor_id)); |
| 560 | |
| 561 | return THERMAL_ERR_NONE; |
| 562 | } |
| 563 | |
| 564 | kal_int32 tia_get_temp_all(kal_uint32 ninfo, thermal_temp_info_t *infos) |
| 565 | { |
| 566 | kal_uint32 idx; |
| 567 | thermal_temp_info_t *inf; |
| 568 | |
| 569 | EXT_ASSERT((ninfo==TIA_SENSOR_NUM) && (infos!=NULL), ninfo, (kal_uint32) infos, 0); |
| 570 | |
| 571 | for (idx = 0; idx < TIA_SENSOR_NUM; idx++) { |
| 572 | inf = &infos[idx]; |
| 573 | inf->temp = tia_temp(idx); |
| 574 | inf->sensor_id = TIA_SENSOR_SID(idx); |
| 575 | } |
| 576 | |
| 577 | return THERMAL_ERR_NONE; |
| 578 | } |
| 579 | |
| 580 | void tia_init(void) |
| 581 | { |
| 582 | tfwk_sensor_if_t sif = {.get_temp_fp = tia_get_temp, .set_alarm_fp = tia_set_alarm}; |
| 583 | tfwk_sensor_info_t *sinfo_rt; |
| 584 | kal_uint32 tid, ppi; |
| 585 | struct tia_thr_mon_s *act; |
| 586 | |
| 587 | UNUSED_PARAMETER(tia_thr_typ_str); |
| 588 | |
| 589 | tia_adc_init(); |
| 590 | for (tid = 0; tid < TIA_SENSOR_NUM; tid++) { |
| 591 | tia_temp(tid); // update first record |
| 592 | } |
| 593 | |
| 594 | #ifndef NVRAM_NOT_PRESENT // update from nvram |
| 595 | for (tid = 0; tid < TIA_SENSOR_NUM; tid++) { |
| 596 | nvram_thermal_sensor_info_struct sinfo_nv; |
| 597 | if (tia_nvram_read_sensor_info(TIA_SENSOR_SID(tid), &sinfo_nv)) { |
| 598 | sinfo_rt = &tia_sensor_info[tid]; |
| 599 | sinfo_rt->sensor_id = sinfo_nv.sensor_id; |
| 600 | sinfo_rt->min_temperature = sinfo_nv.min_temp; |
| 601 | sinfo_rt->max_temperature = sinfo_nv.max_temp; |
| 602 | sinfo_rt->warning_temperature = sinfo_nv.warn_temp; |
| 603 | sinfo_rt->accuracy = sinfo_nv.accuracy; |
| 604 | sinfo_rt->resolution = sinfo_nv.resolution; |
| 605 | memcpy(sinfo_rt->sensor_name, sinfo_nv.sensor_name, sizeof(sinfo_rt->sensor_name)); |
| 606 | tia_sensor_hwShutdownTemp[tid] = sinfo_nv.hws_temp; |
| 607 | } |
| 608 | } |
| 609 | #endif |
| 610 | |
| 611 | // update to tia_thr_mons, tia_thr_hw |
| 612 | for (tid = 0; tid < TIA_SENSOR_NUM; tid++) { |
| 613 | kal_uint32 hws = tia_sensor_hwShutdownTemp[tid]; |
| 614 | kal_bool vld = (hws <= TIA_THR_TMP_MAX); |
| 615 | tia_thr_hw += vld; |
| 616 | sinfo_rt = &tia_sensor_info[tid]; |
| 617 | for (ppi = 0; ppi < TIA_THR_PP_NUM; ppi++) { |
| 618 | act = tia_thr_mons[tid][ppi]; |
| 619 | act[TIA_THR_TYP_HW].thr = hws; |
| 620 | act[TIA_THR_TYP_HW].vld = vld; |
| 621 | act[TIA_THR_TYP_SW].thr = sinfo_rt->max_temperature; |
| 622 | act[TIA_THR_TYP_WRN].thr = sinfo_rt->warning_temperature; |
| 623 | } |
| 624 | } |
| 625 | |
| 626 | // register to tfwk |
| 627 | tfwk_sensor_reg(TFWK_TIA, TIA_SENSOR_NUM, tia_sensor_info, &sif); |
| 628 | |
| 629 | // kal timer |
| 630 | tia_tmr_id = kal_create_timer("TIA"); |
| 631 | tia_tmr_sl = kal_create_spinlock("TIA"); |
| 632 | tia_tmr_set(0, KAL_TRUE); |
| 633 | } |
| 634 | |
| 635 | void tia_dbg_sns_infs(kal_uint32 tid) |
| 636 | { |
| 637 | kal_uint32 msk; |
| 638 | tfwk_sensor_info_t *inf; |
| 639 | |
| 640 | msk = (tid >= TIA_SENSOR_NUM)? ((1 << TIA_SENSOR_NUM) - 1): (1 << tid); |
| 641 | for (tid = 0; tid < TIA_SENSOR_NUM; tid++) { |
| 642 | if (msk & (1 << tid)) { |
| 643 | inf = &tia_sensor_info[tid]; UNUSED_PARAMETER(inf); |
| 644 | MD_TRC(TIA_MSG_SENSOR_INFO, inf->sensor_id, inf->min_temperature, inf->max_temperature, |
| 645 | inf->warning_temperature, tia_sensor_hwShutdownTemp[tid], inf->accuracy, |
| 646 | inf->resolution, TIA_SENSOR_NID(tid), inf->sensor_name); |
| 647 | } |
| 648 | } |
| 649 | } |
| 650 | |
| 651 | void tia_dbg_thr_cfgs(kal_uint32 tid) |
| 652 | { |
| 653 | kal_uint32 msk, idx; |
| 654 | tfwk_thermal_cfg_t *cfg; |
| 655 | |
| 656 | msk = (tid >= TIA_SENSOR_NUM)? ((1 << TIA_SENSOR_NUM) - 1): (1 << tid); |
| 657 | for (tid = 0; tid < TIA_SENSOR_NUM; tid++) { |
| 658 | if ((msk & (1 << tid)) == 0) { |
| 659 | continue; |
| 660 | } |
| 661 | for (idx = 0; idx < TIA_THR_ALM_NUM; idx++) { |
| 662 | cfg = &tia_thr_cfgs[tid][tia_thr_ppi[tid]][idx]; UNUSED_PARAMETER(cfg); |
| 663 | MD_TRC(TIA_MSG_ALARM_INFO, cfg->enable, cfg->sensor_id, cfg->alarm_id, |
| 664 | cfg->threshold_value, cfg->hysteresis_value, cfg->sampling_period, |
| 665 | cfg->sensor_alarm_type); |
| 666 | } |
| 667 | } |
| 668 | } |
| 669 | |
| 670 | void tia_dbg_thr_mons(kal_uint32 tid) |
| 671 | { |
| 672 | kal_uint32 msk, idx; |
| 673 | struct tia_thr_mon_s *mon; |
| 674 | |
| 675 | msk = (tid >= TIA_SENSOR_NUM)? ((1 << TIA_SENSOR_NUM) - 1): (1 << tid); |
| 676 | for (tid = 0; tid < TIA_SENSOR_NUM; tid++) { |
| 677 | if ((msk & (1 << tid)) == 0) { |
| 678 | continue; |
| 679 | } |
| 680 | for (idx = 0; idx < TIA_THR_TYP_MAX; idx++) { |
| 681 | mon = &tia_thr_mons[tid][tia_thr_ppi[tid]][idx]; |
| 682 | MD_TRC(TIA_MSG_MONITOR_INFO, tid, tia_thr_typ_str[idx], mon->vld, mon->thr); |
| 683 | if (mon->vld && mon->cfg) { |
| 684 | MD_TRC(TIA_MSG_ALARM_INFO, mon->cfg->enable, mon->cfg->sensor_id, mon->cfg->alarm_id, |
| 685 | mon->cfg->threshold_value, mon->cfg->hysteresis_value, mon->cfg->sampling_period, |
| 686 | mon->cfg->sensor_alarm_type); |
| 687 | } |
| 688 | } |
| 689 | } |
| 690 | } |
| 691 | |
| 692 | void tia_dbg_fake_en(kal_bool en) |
| 693 | { |
| 694 | #ifdef __MTK_INTERNAL__ |
| 695 | tia_sensor_fake_en = en; |
| 696 | #endif |
| 697 | } |
| 698 | |
| 699 | void tia_dbg_fake_ohm(kal_uint32 tid, kal_uint32 ohm) |
| 700 | { |
| 701 | #ifdef __MTK_INTERNAL__ |
| 702 | kal_uint32 msk; |
| 703 | |
| 704 | msk = (tid >= TIA_SENSOR_NUM)? ((1 << TIA_SENSOR_NUM) - 1): (1 << tid); |
| 705 | for (tid = 0; tid < TIA_SENSOR_NUM; tid++) { |
| 706 | if (msk & (1 << tid)) { |
| 707 | tia_sensor_fake_ohm[tid] = ohm; |
| 708 | } |
| 709 | } |
| 710 | #endif |
| 711 | } |
| 712 | |
| 713 | void tia_dbg_sw_reset(void) |
| 714 | { |
| 715 | #ifdef __MTK_INTERNAL__ |
| 716 | /// WDT_DEBUG_CTL3: [13] debugsys_thermal_req=0, [14] debugsys_req=0 |
| 717 | DRV_WriteReg32(0xC00070a8, 0x51000000); |
| 718 | // TOPRGU_CH_DEBUGSYS_EAP_SEL: [1] DEBUGSYS_HAND_SHAKE_REQ_EN=0 |
| 719 | DRV_WriteReg32(0xC0007718, 0x00000000); |
| 720 | // TOPRGU_CH_DEBUGSYS_EAP_MODE: [0] DEBUGSYS_EN=0 |
| 721 | DRV_WriteReg32(0xC0007714, 0x00000000); |
| 722 | // DRM_LATCH_CTL: [0] rg_latch_en=0, [6] rg_dramc_latch_en=0, |
| 723 | // [11] rg_dramc_rd_test_en=0, [12] rg_dramc_rdwt_test_en=0, |
| 724 | // [13] dvfsrc_latch_en=0, [14] emi_latch_en=0 |
| 725 | DRV_WriteReg32(0xC0010044, 0x95000000); |
| 726 | // DRM_DEBUG_CTL2: [9] dvfsrc_en=0, [8] emi_dcs_en=0 |
| 727 | DRV_WriteReg32(0xC00100a0, (DRV_Reg32(0xC00100a0) & ~0xff000300) | 0x55000000); |
| 728 | // DRM_MODE: [7] ddr_reserve_mode_wo=1 |
| 729 | DRV_WriteReg32(0xC0010000, 0x22000000); |
| 730 | |
| 731 | ust_us_busyloop(100); |
| 732 | |
| 733 | // TOPRGUWDT_RESTART |
| 734 | DRV_WriteReg32(0xC0007008, 0x00001971); |
| 735 | // TOPRGUWDT_MODE |
| 736 | DRV_WriteReg32(0xC0007000, (DRV_Reg32(0xC0007000) & ~0xff000048) | 0x22000000); |
| 737 | // TOPRGUWDT_SWRST |
| 738 | DRV_WriteReg32(0xC0007014, 0x00001209); |
| 739 | #endif |
| 740 | } |
| 741 | |
| 742 | void* tia_dbg_symbol(kal_char *sym) |
| 743 | { |
| 744 | #ifdef __MTK_INTERNAL__ |
| 745 | if (strcmp(sym, "tia_thr_mons") == 0) { |
| 746 | return (void *) tia_thr_mons; |
| 747 | } else if (strcmp(sym, "tia_thr_ppi") == 0) { |
| 748 | return (void *) tia_thr_ppi; |
| 749 | } else if (strcmp(sym, "tia_tmr_handler") == 0) { |
| 750 | return (void *) tia_tmr_handler; |
| 751 | } |
| 752 | #endif |
| 753 | return NULL; |
| 754 | } |