[Feature][Modem]Update MTK MODEM V1.6 baseline version: MOLY.NR15.R3.MD700.IVT.MP1MR3.MP.V1.6
MTK modem version: MT2735_IVT_MOLY.NR15.R3.MD700.IVT.MP1MR3.MP.V1.6.tar.gz
RF modem version: NA
Change-Id: I45a4c2752fa9d1a618beacd5d40737fb39ab64fb
diff --git a/mcu/driver/devdrv/tia/src/tia.c b/mcu/driver/devdrv/tia/src/tia.c
new file mode 100644
index 0000000..61256ca
--- /dev/null
+++ b/mcu/driver/devdrv/tia/src/tia.c
@@ -0,0 +1,754 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2017
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ *
+ * Filename:
+ * ---------
+ * tia.c
+ *
+ * Project:
+ * --------
+ * VMOLY
+ *
+ * Description:
+ * ------------
+ * TIA (Thermal Information Acquisition) driver for MD thermal
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#include "kal_public_api.h"
+#include "kal_ex_api.h"
+#include "drv_comm.h"
+#include "us_timer.h"
+#include "cache_sw.h"
+#include "tia_reg.h"
+#include "tia.h"
+
+// sensor information
+static tfwk_sensor_info_t tia_sensor_info[TIA_SENSOR_NUM] = {
+ {.sensor_id=1, .min_temperature=-200, .max_temperature=1150, .warning_temperature=9999, .accuracy=30, .resolution=10, .sensor_name="PA_Group_2_NTC"},
+ {.sensor_id=2, .min_temperature=-200, .max_temperature=1150, .warning_temperature=9999, .accuracy=30, .resolution=10, .sensor_name="PA_Group_1_NTC"},
+ {.sensor_id=3, .min_temperature=-200, .max_temperature=1150, .warning_temperature=9999, .accuracy=30, .resolution=10, .sensor_name="RF_IC_NTC"},
+ {.sensor_id=4, .min_temperature=-200, .max_temperature=1150, .warning_temperature=9999, .accuracy=30, .resolution=10, .sensor_name="SOC_NTC"},
+};
+static kal_uint32 tia_sensor_hwShutdownTemp[TIA_SENSOR_NUM] = {9999, 9999, 9999, 9999};
+const kal_uint32 tia_sensor_map[TIA_SENSOR_NUM] = {
+ //PA_G2, PA_G1, RF_IC, SOC
+ 2, 1, 3, 0
+};
+#if defined(CHIP10992)
+ static kal_bool tia_sensor_fake_en = KAL_FALSE;
+ static kal_uint32 tia_sensor_fake_ohm[TIA_SENSOR_NUM];
+#else
+ static kal_bool tia_sensor_fake_en = KAL_TRUE;
+ static kal_uint32 tia_sensor_fake_ohm[TIA_SENSOR_NUM] = {0x000186A0, 0x000186A0, 0x000186A0, 0x000186A0};
+#endif
+
+// threshold monitor
+#define TIA_THR_TMP_MAX (TIA_ADC_TMP_MAX * 10) // threshold temperature: valid max
+#define TIA_THR_TMP_MIN (TIA_ADC_TMP_MIN * 10) // threshold temperature: valid max
+#define TIA_THR_TMP_HW_NEAR (100) // threshold temperature, near HW shutdown (>= HW - this_DEF)
+#define TIA_THR_PP_NUM 2 // ping-pong number
+#define TIA_THR_ALM_NUM 2 // alarm number
+enum { // threshold type
+ TIA_THR_TYP_HW = 0,
+ TIA_THR_TYP_SW,
+ TIA_THR_TYP_WRN,
+ TIA_THR_TYP_AL0,
+ TIA_THR_TYP_AL1,
+ TIA_THR_TYP_MAX
+};
+static const kal_char *tia_thr_typ_str[TIA_THR_TYP_MAX] = {"hw", "sw", "wrn", "al0", "al1"};
+enum { // alarm type
+ TIA_ALM_TYP_RISING = 0,
+ TIA_ALM_TYP_FALLING,
+ TIA_ALM_TYP_DISABLE
+};
+static tfwk_thermal_cfg_t tia_thr_cfgs[TIA_SENSOR_NUM][TIA_THR_PP_NUM][TIA_THR_ALM_NUM];
+static struct tia_thr_mon_s {
+ kal_bool vld; // valid or not
+ kal_int32 thr; // threshold value, order: hw > sw > fim > al0 > al1
+ tfwk_thermal_cfg_t *cfg; // pointer to tia_thr_cfgs (for sw/fim/alarm, not hw)
+} tia_thr_mons[TIA_SENSOR_NUM][TIA_THR_PP_NUM][TIA_THR_TYP_MAX];
+static kal_uint32 tia_thr_ppi[TIA_SENSOR_NUM]; // current ppi, update to ~ppi
+static kal_uint32 tia_thr_hw;
+#define TIA_HW_RESET_RECORD(tid) \
+ DRV_WriteReg32(TOPRGU_WDT_NONRST_REG2, DRV_Reg32(TOPRGU_WDT_NONRST_REG2) | TOPRGU_TID_STATUS(tid))
+
+#define TIA_TMR_MS_DFT 1000 // default polling period
+#define TIA_TMR_MS_ITS 100 // intensive polling period
+#define TIA_TMR_MS_MIN 64 // minimax polling period
+static kal_timerid tia_tmr_id;
+static kal_spinlockid tia_tmr_sl;
+static void tia_tmr_set(kal_uint32 ms, kal_bool imm);
+
+//#define TIA_STACK_PRF
+#ifdef TIA_STACK_PRF
+#define STACK_SIZE_MAX 0x1000
+#define STACK_GUARD_PTN0 0x43415453 // STACKEND
+#define STACK_GUARD_PTN1 0x444E454B
+#define STACK_GUARD_TST 0xFEFEFEFE
+
+static struct {
+ kal_uint32 init_bas;
+ kal_uint32 init_cur;
+ kal_uint32 init_us;
+ kal_uint32 done_cur;
+ kal_uint32 done_use;
+ kal_uint32 done_us;
+} tia_stack_prf;
+
+static void __attribute__((noinline)) tia_stack_prf_init(void)
+{
+ void *sp_ptr = NULL;
+ register kal_uint32 adr;
+
+ tia_stack_prf.init_cur = (kal_uint32) &sp_ptr;
+ for (adr = tia_stack_prf.init_cur & ~0x7; adr > tia_stack_prf.init_cur - STACK_SIZE_MAX; adr -= 8) {
+ if ((DRV_Reg32(adr) == STACK_GUARD_PTN0) && (DRV_Reg32(adr+4) == STACK_GUARD_PTN1)) {
+ adr = CPU_CACHE_LINE_ALIGN_ADDR(adr) + CPU_CACHE_LINE_ALIGN_LEN(adr, 8);
+ break;
+ }
+ }
+ tia_stack_prf.init_bas = adr;
+ for (; adr < tia_stack_prf.init_cur - 0x10; adr += 4) {
+ DRV_WriteReg32(adr, STACK_GUARD_TST);
+ }
+ tia_stack_prf.init_us = ust_get_current_time();
+}
+
+static void __attribute__((noinline)) tia_stack_prf_done(void)
+{
+ void *sp_ptr = NULL;
+ register kal_uint32 adr;
+
+ tia_stack_prf.done_us = ust_get_current_time();
+ tia_stack_prf.done_cur = (kal_uint32) &sp_ptr;
+ for (adr = tia_stack_prf.init_bas; adr < tia_stack_prf.init_cur; adr += 4) {
+ if (DRV_Reg32(adr) != STACK_GUARD_TST) {
+ break;
+ }
+ }
+ tia_stack_prf.done_use = adr;
+}
+
+static void __attribute__((noinline)) tia_stack_prf_result(void)
+{
+ MD_TRC(TIA_MSG_STACK_INFO,
+ tia_stack_prf.init_cur, tia_stack_prf.init_bas, tia_stack_prf.init_cur - tia_stack_prf.init_bas,
+ tia_stack_prf.done_cur, tia_stack_prf.done_use, tia_stack_prf.done_cur - tia_stack_prf.done_use,
+ ust_us_duration(tia_stack_prf.init_us, tia_stack_prf.done_us));
+}
+#endif
+
+static kal_int32 tia_temp(kal_uint32 tid)
+{
+ static struct {
+ kal_uint32 frc;
+ kal_int32 tmp;
+ } tmps[TIA_SENSOR_NUM];
+ kal_uint32 nid, reg, dbg, frc, rc, adc;
+ kal_int32 tmp;
+
+ if (tia_sensor_fake_en) {
+ rc = TIA_ADC_RC_FAKE;
+ adc = tia_sensor_fake_ohm[tid];
+ tmp = tia_adc_to_tmp(rc, adc);
+ MD_TRC(TIA_MSG_AUXADC_TMP, tid, TIA_ADC_RC2K(rc), adc, tmp, tia_sensor_fake_en);
+ } else {
+ nid = TIA_SENSOR_NID(tid);
+ reg = DRV_Reg32(TIA_HW_RC_ADC(nid));
+ frc = ust_get_current_time();
+ if (TIA_HW_ADC_VLD(reg)) {
+ rc = TIA_HW_RC_VAL(reg);
+ adc = TIA_HW_ADC_VAL(reg);
+ tmp = tia_adc_to_tmp(rc, adc);
+ EXT_ASSERT(tmp != TIA_ADC_TMP_ERR, rc, adc, (kal_uint32) tmp);
+ tmps[tid].frc = frc;
+ tmps[tid].tmp = tmp;
+ MD_TRC(TIA_MSG_AUXADC_TMP, tid, TIA_ADC_RC2K(rc), adc, tmp, tia_sensor_fake_en);
+ } else {
+ dbg = DRV_Reg32(TIA_TIA2_DEBUG);
+ EXT_ASSERT((tmps[tid].frc != 0) && (tmps[tid].tmp != 0), tid, reg, dbg);
+ tmp = tmps[tid].tmp;
+ MD_TRC(TIA_MSG_ERR_ADC_INVALID, __func__, tid, reg, dbg, tmp, ust_us_duration(tmps[tid].frc, frc));
+ }
+ }
+
+ return tmp;
+}
+
+static void tia_notify(kal_uint32 tid, kal_int32 tmp, tfwk_thermal_cfg_t* cfg)
+{
+ static thermal_sta_info_t tia_thr_ntf; // declare "static" in global bss, dont use stack area (kal timer limitation)
+ kal_uint32 sid, idx;
+
+ tia_thr_ntf.temp = tmp;
+ memcpy(&tia_thr_ntf.cfg, cfg, sizeof(thermal_cfg_t));
+
+ for (sid = THERMAL_LVTS_SENSOR_ID(0); sid < THERMAL_LVTS_SENSOR_ID(THERMAL_LVTS_SENSOR_NUM); sid++) {
+ tia_thr_ntf.others[sid].sensor_id = sid;
+ TIA_LVTS_GET_TEMP(sid, &tia_thr_ntf.others[sid].temp);
+ }
+ idx = sid;
+ for (sid = THERMAL_TIA_SENSOR_ID(0); sid < THERMAL_TIA_SENSOR_ID(TIA_SENSOR_NUM); sid++) {
+ if (TIA_SENSOR_TID(sid) == tid) {
+ continue;
+ }
+ tia_thr_ntf.others[idx].sensor_id = sid;
+ tia_thr_ntf.others[idx].temp = tia_temp(TIA_SENSOR_TID(sid));
+ idx++;
+ }
+
+ tfwk_sensor_notify(&tia_thr_ntf);
+}
+
+static void tia_tmr_handler(void *param_ptr)
+{
+ kal_uint32 tid, idx, tms = 0;
+ kal_int32 tmp;
+ kal_bool hit, ins = KAL_FALSE;
+ struct tia_thr_mon_s *mon;
+
+ #ifdef TIA_STACK_PRF
+ tia_stack_prf_init();
+ #endif
+ // check threshold
+ for (tid = 0; tid < TIA_SENSOR_NUM; tid++) {
+ tmp = tia_temp(tid); // always update temperature locally
+ mon = tia_thr_mons[tid][tia_thr_ppi[tid]];
+ hit = KAL_FALSE;
+ for (idx = 0; idx < TIA_THR_TYP_MAX; idx++) {
+ if (mon[idx].vld) { hit = KAL_TRUE; break; }
+ }
+ if (!hit) { continue; }
+ // hw threshold
+ if (mon[TIA_THR_TYP_HW].vld) {
+ if (tmp >= mon[TIA_THR_TYP_HW].thr) {
+ MD_TRC(TIA_MSG_ERR_OVER_HW_THRESHOLD, __func__, tid, tmp, mon[TIA_THR_TYP_HW].thr);
+ TIA_HW_RESET_RECORD(tid);
+ TIA_LVTS_HW_RGU_RESET();
+ break;
+ } else if (tmp >= (mon[TIA_THR_TYP_HW].thr - TIA_THR_TMP_HW_NEAR)) {
+ MD_TRC(TIA_MSG_NEAR_HW_THRESHOLD, tid, tmp, mon[TIA_THR_TYP_HW].thr);
+ }
+ }
+ // rising sw/fim/alarm threshold
+ hit = KAL_FALSE;
+ for (idx = TIA_THR_TYP_SW; idx < TIA_THR_TYP_MAX; idx++) {
+ if ((mon[idx].vld == KAL_FALSE) || (mon[idx].cfg->sensor_alarm_type != TIA_ALM_TYP_RISING)) {
+ continue;
+ }
+ if (hit) { // disable lower threhold
+ mon[idx].vld = KAL_FALSE;
+ continue;
+ }
+ if (tmp >= mon[idx].thr) {
+ tia_notify(tid, tmp, mon[idx].cfg);
+ mon[idx].vld = KAL_FALSE;
+ hit = KAL_TRUE;
+ MD_TRC(TIA_MSG_OVER_THRESHOLD, tid, tmp, tia_thr_typ_str[idx], mon[idx].thr);
+ MD_TRC(TIA_MSG_ALARM_INFO, mon[idx].cfg->enable, mon[idx].cfg->sensor_id, mon[idx].cfg->alarm_id,
+ mon[idx].cfg->threshold_value, mon[idx].cfg->hysteresis_value, mon[idx].cfg->sampling_period,
+ mon[idx].cfg->sensor_alarm_type);
+ }
+ }
+ // falling alarm threshold
+ hit = KAL_FALSE;
+ for (idx = TIA_THR_TYP_AL1; idx >= TIA_THR_TYP_AL0; idx--) {
+ if ((mon[idx].vld == KAL_FALSE) || (mon[idx].cfg->sensor_alarm_type != TIA_ALM_TYP_FALLING)) {
+ continue;
+ }
+ if (hit) { // disable higher threhold
+ mon[idx].vld = KAL_FALSE;
+ continue;
+ }
+ if (tmp <= mon[idx].thr) {
+ tia_notify(tid, tmp, mon[idx].cfg);
+ mon[idx].vld = KAL_FALSE;
+ hit = KAL_TRUE;
+ MD_TRC(TIA_MSG_UNDER_THRESHOLD, tid, tmp, tia_thr_typ_str[idx], mon[idx].thr);
+ MD_TRC(TIA_MSG_ALARM_INFO, mon[idx].cfg->enable, mon[idx].cfg->sensor_id, mon[idx].cfg->alarm_id,
+ mon[idx].cfg->threshold_value, mon[idx].cfg->hysteresis_value, mon[idx].cfg->sampling_period,
+ mon[idx].cfg->sensor_alarm_type);
+ }
+ }
+
+ // sample period (config and insensive)
+ for (idx = TIA_THR_TYP_SW; idx < TIA_THR_TYP_MAX; idx++) {
+ kal_uint32 t;
+ if (mon[idx].vld == KAL_FALSE) {
+ continue;
+ }
+ t = mon[idx].cfg->sampling_period;
+ if ((tms == 0) || (tms > t)) {
+ tms = (t < TIA_TMR_MS_MIN)? TIA_TMR_MS_MIN: t;
+ }
+ if ((mon[idx].cfg->sensor_alarm_type == TIA_ALM_TYP_RISING) &&
+ (tmp >= (mon[idx].cfg->threshold_value - (kal_int32) mon[idx].cfg->hysteresis_value))) {
+ ins = KAL_TRUE;
+ continue;
+ }
+ if ((mon[idx].cfg->sensor_alarm_type == TIA_ALM_TYP_FALLING) &&
+ (tmp <= (mon[idx].cfg->threshold_value + (kal_int32) mon[idx].cfg->hysteresis_value))) {
+ ins = KAL_TRUE;
+ continue;
+ }
+ }
+ }
+
+ // update timer period
+ if ((ins) && (tms > TIA_TMR_MS_ITS)) {
+ tms = TIA_TMR_MS_ITS;
+ }
+ tia_tmr_set(tms, KAL_FALSE);
+ #ifdef TIA_STACK_PRF
+ tia_stack_prf_done();
+ tia_stack_prf_result();
+ #endif
+}
+
+static void tia_tmr_set(kal_uint32 ms, kal_bool imm)
+{
+ static kal_uint32 ms_cfg;
+ kal_bool ms_trc = KAL_FALSE;
+ kal_uint32 tck;
+
+ if ((ms == 0) && tia_thr_hw) {
+ ms = TIA_TMR_MS_DFT;
+ }
+ tck = kal_milli_secs_to_ticks(ms);
+
+ kal_take_spinlock(tia_tmr_sl, KAL_INFINITE_WAIT);
+ if (ms != ms_cfg) {
+ if (ms_cfg != 1) {
+ ms_trc = KAL_TRUE;
+ }
+ if (ms == 0) {
+ kal_cancel_timer(tia_tmr_id);
+ ms_cfg = 0;
+ } else if (imm) {
+ kal_disable_delayed_timer(tia_tmr_id);
+ kal_set_timer(tia_tmr_id, tia_tmr_handler, NULL, 1, tck);
+ ms_cfg = 1;
+ } else {
+ kal_enable_delayed_timer(tia_tmr_id, MAX_DELAY_UNLIMITED);
+ kal_set_timer(tia_tmr_id, tia_tmr_handler, NULL, tck, tck);
+ ms_cfg = ms;
+ }
+ }
+ kal_give_spinlock(tia_tmr_sl);
+
+ if (ms_trc) {
+ MD_TRC(TIA_MSG_SAMPLING_PERIOD, ms);
+ }
+}
+
+static kal_int32 thr_alarm_temp_max(kal_uint32 tid)
+{
+ struct tia_thr_mon_s *mon;
+ kal_int32 idx, tmp = TIA_THR_TMP_MAX;
+
+ mon = tia_thr_mons[tid][tia_thr_ppi[tid]];
+ for (idx = 0; idx < TIA_THR_TYP_AL0; idx++) {
+ if (tmp > mon[idx].thr) {
+ tmp = mon[idx].thr;
+ }
+ }
+ return tmp;
+}
+
+static kal_int32 thr_alarm_temp_min(kal_uint32 tid)
+{
+ kal_int32 tmp = TIA_THR_TMP_MIN;
+
+ if (tmp < tia_sensor_info[tid].min_temperature) {
+ tmp = tia_sensor_info[tid].min_temperature;
+ }
+ return tmp;
+}
+
+kal_int32 tia_set_alarm(kal_uint32 ncfg, tfwk_thermal_cfg_t* tcfgs)
+{
+ #define _upd_err_code(r,e) do {if ((r)==THERMAL_ERR_NONE) (r) = (e);} while (0)
+ kal_int32 ret = THERMAL_ERR_NONE, tmp;
+ kal_uint32 tid, ppi, idx, tms;
+ struct tia_thr_mon_s *mon;
+ tfwk_thermal_cfg_t *cfg;
+ tfwk_thermal_cfg_t *cfg_f[TIA_SENSOR_NUM][TIA_THR_ALM_NUM] = {NULL}; // filter cfg list
+
+ EXT_ASSERT(ncfg && tcfgs, ncfg, (kal_uint32) tcfgs, 0);
+
+ // filter cfg
+ for (idx = 0; idx < ncfg; idx++) {
+ cfg = &tcfgs[idx];
+ if (!TIA_SENSOR_SID_VALID(cfg->sensor_id)) {
+ MD_TRC(TIA_MSG_ERR_SENSOR_ID, __func__, cfg->sensor_id);
+ _upd_err_code(ret, THERMAL_ERR_SENSOR_ID);
+ continue;
+ }
+ if (cfg->alarm_id >= TIA_THR_ALM_NUM) {
+ MD_TRC(TIA_MSG_ERR_ALARM_ID, __func__, cfg->alarm_id);
+ _upd_err_code(ret, THERMAL_ERR_ALARM_ID);
+ continue;
+ }
+ tid = TIA_SENSOR_TID(cfg->sensor_id);
+ tmp = thr_alarm_temp_max(tid);
+ if (cfg->threshold_value >= tmp) {
+ MD_TRC(TIA_MSG_ERR_THRESHOLD_RANGE_MAX, __func__, cfg->threshold_value, tmp);
+ _upd_err_code(ret, THERMAL_ERR_THRESHOLD_RANGE);
+ continue;
+ }
+ tmp = thr_alarm_temp_min(tid);
+ if (cfg->threshold_value <= tmp) {
+ MD_TRC(TIA_MSG_ERR_THRESHOLD_RANGE_MIN, __func__, cfg->threshold_value, tmp);
+ _upd_err_code(ret, THERMAL_ERR_THRESHOLD_RANGE);
+ continue;
+ }
+ cfg_f[tid][cfg->alarm_id] = cfg;
+ MD_TRC(TIA_MSG_ALARM_INFO,cfg->enable, cfg->sensor_id, cfg->alarm_id, cfg->threshold_value,
+ cfg->hysteresis_value, cfg->sampling_period, cfg->sensor_alarm_type);
+ }
+
+ // update internal cfg
+ for (tid = 0; tid < TIA_SENSOR_NUM; tid++) {
+ if ((cfg_f[tid][0]==NULL) && (cfg_f[tid][1]==NULL)) {
+ continue;
+ }
+ // clean first
+ ppi = !tia_thr_ppi[tid];
+ mon = tia_thr_mons[tid][ppi];
+ mon[TIA_THR_TYP_SW].vld = KAL_FALSE;
+ mon[TIA_THR_TYP_SW].cfg = NULL;
+ mon[TIA_THR_TYP_WRN].vld = KAL_FALSE;
+ mon[TIA_THR_TYP_WRN].cfg = NULL;
+ memset(&mon[TIA_THR_TYP_AL0], 0x0, sizeof(struct tia_thr_mon_s)*TIA_THR_ALM_NUM);
+ // update alarm
+ if ((cfg_f[tid][0] == NULL) || (cfg_f[tid][1] == NULL)) {
+ idx = (cfg_f[tid][0] == NULL);
+ memcpy(&tia_thr_cfgs[tid][ppi][idx], cfg_f[tid][idx], sizeof(tfwk_thermal_cfg_t));
+ if ((cfg_f[tid][idx]->enable != 0) && (cfg_f[tid][idx]->sensor_alarm_type < TIA_ALM_TYP_DISABLE)) {
+ mon[TIA_THR_TYP_AL0].vld = KAL_TRUE;
+ mon[TIA_THR_TYP_AL0].thr = cfg_f[tid][idx]->threshold_value;
+ mon[TIA_THR_TYP_AL0].cfg = &tia_thr_cfgs[tid][ppi][idx];
+ }
+ idx = !idx;
+ memset(&tia_thr_cfgs[tid][ppi][idx], 0x0, sizeof(tfwk_thermal_cfg_t));
+ } else {
+ memcpy(&tia_thr_cfgs[tid][ppi][0], cfg_f[tid][0], sizeof(tfwk_thermal_cfg_t));
+ memcpy(&tia_thr_cfgs[tid][ppi][1], cfg_f[tid][1], sizeof(tfwk_thermal_cfg_t));
+ idx = (cfg_f[tid][0]->threshold_value < cfg_f[tid][1]->threshold_value);
+ tmp = TIA_THR_TYP_AL0;
+ if ((cfg_f[tid][idx]->enable != 0) && (cfg_f[tid][idx]->sensor_alarm_type < TIA_ALM_TYP_DISABLE)) {
+ mon[tmp].vld = KAL_TRUE;
+ mon[tmp].thr = cfg_f[tid][idx]->threshold_value;
+ mon[tmp].cfg = &tia_thr_cfgs[tid][ppi][idx];
+ tmp++;
+ }
+ idx = !idx;
+ if ((cfg_f[tid][idx]->enable != 0) && (cfg_f[tid][idx]->sensor_alarm_type < TIA_ALM_TYP_DISABLE)) {
+ mon[tmp].vld = KAL_TRUE;
+ mon[tmp].thr = cfg_f[tid][idx]->threshold_value;
+ mon[tmp].cfg = &tia_thr_cfgs[tid][ppi][idx];
+ }
+ }
+ // update sw/fim threshold if one more rising alarm
+ for (idx = TIA_THR_TYP_AL0; idx <= TIA_THR_TYP_AL1; idx++) {
+ if (mon[idx].vld && (mon[idx].cfg->sensor_alarm_type == TIA_ALM_TYP_RISING)) {
+ mon[TIA_THR_TYP_SW].vld = (mon[TIA_THR_TYP_SW].thr <= TIA_THR_TMP_MAX);
+ mon[TIA_THR_TYP_SW].cfg = mon[TIA_THR_TYP_SW].vld? mon[idx].cfg: NULL;
+ mon[TIA_THR_TYP_WRN].vld = (mon[TIA_THR_TYP_WRN].thr <= TIA_THR_TMP_MAX);
+ mon[TIA_THR_TYP_WRN].cfg = mon[TIA_THR_TYP_WRN].vld? mon[idx].cfg: NULL;
+ break;
+ }
+ }
+ tia_thr_ppi[tid] = ppi;
+ }
+
+ // update sampling period
+ tms = 0;
+ for (tid = 0; tid < TIA_SENSOR_NUM; tid++) {
+ mon = tia_thr_mons[tid][tia_thr_ppi[tid]];
+ for (idx = TIA_THR_TYP_AL0; idx <= TIA_THR_TYP_AL1; idx++) {
+ kal_uint32 t;
+ if (mon[idx].vld == KAL_FALSE) {
+ continue;
+ }
+ t = mon[idx].cfg->sampling_period;
+ if ((tms == 0) || (tms > t)) {
+ tms = (t < TIA_TMR_MS_MIN)? TIA_TMR_MS_MIN: t;
+ }
+ }
+ }
+ tia_tmr_set(tms, KAL_TRUE);
+
+ if (ret != THERMAL_ERR_NONE) {
+ MD_TRC(TIA_MSG_ERR_CODE, __func__, ret);
+ }
+ return ret;
+}
+
+kal_int32 tia_get_temp(kal_uint32 sensor_id, kal_int32 *temp)
+{
+ if (!TIA_SENSOR_SID_VALID(sensor_id)) {
+ MD_TRC(TIA_MSG_ERR_SENSOR_ID, __func__, sensor_id);
+ return THERMAL_ERR_SENSOR_ID;
+ }
+ EXT_ASSERT(temp!=NULL, sensor_id, (kal_uint32) temp, 0);
+
+ *temp = tia_temp(TIA_SENSOR_TID(sensor_id));
+
+ return THERMAL_ERR_NONE;
+}
+
+kal_int32 tia_get_temp_all(kal_uint32 ninfo, thermal_temp_info_t *infos)
+{
+ kal_uint32 idx;
+ thermal_temp_info_t *inf;
+
+ EXT_ASSERT((ninfo==TIA_SENSOR_NUM) && (infos!=NULL), ninfo, (kal_uint32) infos, 0);
+
+ for (idx = 0; idx < TIA_SENSOR_NUM; idx++) {
+ inf = &infos[idx];
+ inf->temp = tia_temp(idx);
+ inf->sensor_id = TIA_SENSOR_SID(idx);
+ }
+
+ return THERMAL_ERR_NONE;
+}
+
+void tia_init(void)
+{
+ tfwk_sensor_if_t sif = {.get_temp_fp = tia_get_temp, .set_alarm_fp = tia_set_alarm};
+ tfwk_sensor_info_t *sinfo_rt;
+ kal_uint32 tid, ppi;
+ struct tia_thr_mon_s *act;
+
+ UNUSED_PARAMETER(tia_thr_typ_str);
+
+ tia_adc_init();
+ for (tid = 0; tid < TIA_SENSOR_NUM; tid++) {
+ tia_temp(tid); // update first record
+ }
+
+ #ifndef NVRAM_NOT_PRESENT // update from nvram
+ for (tid = 0; tid < TIA_SENSOR_NUM; tid++) {
+ nvram_thermal_sensor_info_struct sinfo_nv;
+ if (tia_nvram_read_sensor_info(TIA_SENSOR_SID(tid), &sinfo_nv)) {
+ sinfo_rt = &tia_sensor_info[tid];
+ sinfo_rt->sensor_id = sinfo_nv.sensor_id;
+ sinfo_rt->min_temperature = sinfo_nv.min_temp;
+ sinfo_rt->max_temperature = sinfo_nv.max_temp;
+ sinfo_rt->warning_temperature = sinfo_nv.warn_temp;
+ sinfo_rt->accuracy = sinfo_nv.accuracy;
+ sinfo_rt->resolution = sinfo_nv.resolution;
+ memcpy(sinfo_rt->sensor_name, sinfo_nv.sensor_name, sizeof(sinfo_rt->sensor_name));
+ tia_sensor_hwShutdownTemp[tid] = sinfo_nv.hws_temp;
+ }
+ }
+ #endif
+
+ // update to tia_thr_mons, tia_thr_hw
+ for (tid = 0; tid < TIA_SENSOR_NUM; tid++) {
+ kal_uint32 hws = tia_sensor_hwShutdownTemp[tid];
+ kal_bool vld = (hws <= TIA_THR_TMP_MAX);
+ tia_thr_hw += vld;
+ sinfo_rt = &tia_sensor_info[tid];
+ for (ppi = 0; ppi < TIA_THR_PP_NUM; ppi++) {
+ act = tia_thr_mons[tid][ppi];
+ act[TIA_THR_TYP_HW].thr = hws;
+ act[TIA_THR_TYP_HW].vld = vld;
+ act[TIA_THR_TYP_SW].thr = sinfo_rt->max_temperature;
+ act[TIA_THR_TYP_WRN].thr = sinfo_rt->warning_temperature;
+ }
+ }
+
+ // register to tfwk
+ tfwk_sensor_reg(TFWK_TIA, TIA_SENSOR_NUM, tia_sensor_info, &sif);
+
+ // kal timer
+ tia_tmr_id = kal_create_timer("TIA");
+ tia_tmr_sl = kal_create_spinlock("TIA");
+ tia_tmr_set(0, KAL_TRUE);
+}
+
+void tia_dbg_sns_infs(kal_uint32 tid)
+{
+ kal_uint32 msk;
+ tfwk_sensor_info_t *inf;
+
+ msk = (tid >= TIA_SENSOR_NUM)? ((1 << TIA_SENSOR_NUM) - 1): (1 << tid);
+ for (tid = 0; tid < TIA_SENSOR_NUM; tid++) {
+ if (msk & (1 << tid)) {
+ inf = &tia_sensor_info[tid]; UNUSED_PARAMETER(inf);
+ MD_TRC(TIA_MSG_SENSOR_INFO, inf->sensor_id, inf->min_temperature, inf->max_temperature,
+ inf->warning_temperature, tia_sensor_hwShutdownTemp[tid], inf->accuracy,
+ inf->resolution, TIA_SENSOR_NID(tid), inf->sensor_name);
+ }
+ }
+}
+
+void tia_dbg_thr_cfgs(kal_uint32 tid)
+{
+ kal_uint32 msk, idx;
+ tfwk_thermal_cfg_t *cfg;
+
+ msk = (tid >= TIA_SENSOR_NUM)? ((1 << TIA_SENSOR_NUM) - 1): (1 << tid);
+ for (tid = 0; tid < TIA_SENSOR_NUM; tid++) {
+ if ((msk & (1 << tid)) == 0) {
+ continue;
+ }
+ for (idx = 0; idx < TIA_THR_ALM_NUM; idx++) {
+ cfg = &tia_thr_cfgs[tid][tia_thr_ppi[tid]][idx]; UNUSED_PARAMETER(cfg);
+ MD_TRC(TIA_MSG_ALARM_INFO, cfg->enable, cfg->sensor_id, cfg->alarm_id,
+ cfg->threshold_value, cfg->hysteresis_value, cfg->sampling_period,
+ cfg->sensor_alarm_type);
+ }
+ }
+}
+
+void tia_dbg_thr_mons(kal_uint32 tid)
+{
+ kal_uint32 msk, idx;
+ struct tia_thr_mon_s *mon;
+
+ msk = (tid >= TIA_SENSOR_NUM)? ((1 << TIA_SENSOR_NUM) - 1): (1 << tid);
+ for (tid = 0; tid < TIA_SENSOR_NUM; tid++) {
+ if ((msk & (1 << tid)) == 0) {
+ continue;
+ }
+ for (idx = 0; idx < TIA_THR_TYP_MAX; idx++) {
+ mon = &tia_thr_mons[tid][tia_thr_ppi[tid]][idx];
+ MD_TRC(TIA_MSG_MONITOR_INFO, tid, tia_thr_typ_str[idx], mon->vld, mon->thr);
+ if (mon->vld && mon->cfg) {
+ MD_TRC(TIA_MSG_ALARM_INFO, mon->cfg->enable, mon->cfg->sensor_id, mon->cfg->alarm_id,
+ mon->cfg->threshold_value, mon->cfg->hysteresis_value, mon->cfg->sampling_period,
+ mon->cfg->sensor_alarm_type);
+ }
+ }
+ }
+}
+
+void tia_dbg_fake_en(kal_bool en)
+{
+ #ifdef __MTK_INTERNAL__
+ tia_sensor_fake_en = en;
+ #endif
+}
+
+void tia_dbg_fake_ohm(kal_uint32 tid, kal_uint32 ohm)
+{
+ #ifdef __MTK_INTERNAL__
+ kal_uint32 msk;
+
+ msk = (tid >= TIA_SENSOR_NUM)? ((1 << TIA_SENSOR_NUM) - 1): (1 << tid);
+ for (tid = 0; tid < TIA_SENSOR_NUM; tid++) {
+ if (msk & (1 << tid)) {
+ tia_sensor_fake_ohm[tid] = ohm;
+ }
+ }
+ #endif
+}
+
+void tia_dbg_sw_reset(void)
+{
+ #ifdef __MTK_INTERNAL__
+ /// WDT_DEBUG_CTL3: [13] debugsys_thermal_req=0, [14] debugsys_req=0
+ DRV_WriteReg32(0xC00070a8, 0x51000000);
+ // TOPRGU_CH_DEBUGSYS_EAP_SEL: [1] DEBUGSYS_HAND_SHAKE_REQ_EN=0
+ DRV_WriteReg32(0xC0007718, 0x00000000);
+ // TOPRGU_CH_DEBUGSYS_EAP_MODE: [0] DEBUGSYS_EN=0
+ DRV_WriteReg32(0xC0007714, 0x00000000);
+ // DRM_LATCH_CTL: [0] rg_latch_en=0, [6] rg_dramc_latch_en=0,
+ // [11] rg_dramc_rd_test_en=0, [12] rg_dramc_rdwt_test_en=0,
+ // [13] dvfsrc_latch_en=0, [14] emi_latch_en=0
+ DRV_WriteReg32(0xC0010044, 0x95000000);
+ // DRM_DEBUG_CTL2: [9] dvfsrc_en=0, [8] emi_dcs_en=0
+ DRV_WriteReg32(0xC00100a0, (DRV_Reg32(0xC00100a0) & ~0xff000300) | 0x55000000);
+ // DRM_MODE: [7] ddr_reserve_mode_wo=1
+ DRV_WriteReg32(0xC0010000, 0x22000000);
+
+ ust_us_busyloop(100);
+
+ // TOPRGUWDT_RESTART
+ DRV_WriteReg32(0xC0007008, 0x00001971);
+ // TOPRGUWDT_MODE
+ DRV_WriteReg32(0xC0007000, (DRV_Reg32(0xC0007000) & ~0xff000048) | 0x22000000);
+ // TOPRGUWDT_SWRST
+ DRV_WriteReg32(0xC0007014, 0x00001209);
+ #endif
+}
+
+void* tia_dbg_symbol(kal_char *sym)
+{
+ #ifdef __MTK_INTERNAL__
+ if (strcmp(sym, "tia_thr_mons") == 0) {
+ return (void *) tia_thr_mons;
+ } else if (strcmp(sym, "tia_thr_ppi") == 0) {
+ return (void *) tia_thr_ppi;
+ } else if (strcmp(sym, "tia_tmr_handler") == 0) {
+ return (void *) tia_tmr_handler;
+ }
+ #endif
+ return NULL;
+}