blob: 61256cad575c55d15ef6015fa13c1cd426377a0c [file] [log] [blame]
yu.dongc33b3072024-08-21 23:14:49 -07001/*****************************************************************************
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
88static 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};
94static kal_uint32 tia_sensor_hwShutdownTemp[TIA_SENSOR_NUM] = {9999, 9999, 9999, 9999};
95const 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
113enum { // 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};
121static const kal_char *tia_thr_typ_str[TIA_THR_TYP_MAX] = {"hw", "sw", "wrn", "al0", "al1"};
122enum { // alarm type
123 TIA_ALM_TYP_RISING = 0,
124 TIA_ALM_TYP_FALLING,
125 TIA_ALM_TYP_DISABLE
126};
127static tfwk_thermal_cfg_t tia_thr_cfgs[TIA_SENSOR_NUM][TIA_THR_PP_NUM][TIA_THR_ALM_NUM];
128static 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];
133static kal_uint32 tia_thr_ppi[TIA_SENSOR_NUM]; // current ppi, update to ~ppi
134static 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
141static kal_timerid tia_tmr_id;
142static kal_spinlockid tia_tmr_sl;
143static 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
152static 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
161static 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
180static 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
195static 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
204static 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
241static 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
266static 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
371static 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
407static 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
421static 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
431kal_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
551kal_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
564kal_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
580void 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
635void 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
651void 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
670void 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
692void tia_dbg_fake_en(kal_bool en)
693{
694 #ifdef __MTK_INTERNAL__
695 tia_sensor_fake_en = en;
696 #endif
697}
698
699void 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
713void 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
742void* 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}