Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e60f2d35 authored by zhaohui yu's avatar zhaohui yu Committed by yanjie.jiang
Browse files

[ALPS08827026] ccci: change wdt event record and add epon flg



[Description]
1.Change wdt event record to struct.
2.Add epon check before md off, in case lost wdt event with epon flg.

[Test]
1.MD EE test pass.
2.specific test: reset md -> wdt irq with epon, md reset pass.

MTK-Commit-Id: ff30d7174497900ea793dbecd206ea3ff4fcecdb

Signed-off-by: default avatarzhaohui yu <zhaohui.yu@mediatek.com>
CR-Id: ALPS08827026
Feature: CCCI_HIF_CONTROL
Change-Id: Iba2323403a792e10dae922051533fa19df126bfa
parent 8239958d
Loading
Loading
Loading
Loading
+49 −34
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "modem_secure_base.h"

struct ccci_fsm_ctl *ccci_fsm_entries;
struct md_wdt_record md_wdt_rec;

static int needforcestop;
static int hs2_done;
@@ -821,8 +822,6 @@ static void *ccci_md_get_time_info(struct ccci_runtime_feature *rt_feature,
	return rt_element;
}



static int ccci_md_prepare_runtime_data(unsigned char *data, int length)
{
	struct ccci_modem *md = ccci_get_modem();
@@ -1317,6 +1316,29 @@ static int ccci_md_prepare_runtime_data(unsigned char *data, int length)
	return 0;
}

static int ccci_md_epon_set(void)
{
	struct ccci_modem *md = ccci_get_modem();
	struct ccci_smem_region *mdss_dbg
			= ccci_md_get_smem_by_user_id(SMEM_USER_RAW_MDSS_DBG);
	int ret = 0, in_md_l2sram = 0;

	if (md->hw_info->md_l2sram_base) {
		md_cd_lock_modem_clock_src(1);
		ret = *((int *)(md->hw_info->md_l2sram_base
			+ md->hw_info->md_epon_offset)) == 0xBAEBAE10;
		md_cd_lock_modem_clock_src(0);
		in_md_l2sram = 1;
	} else if (mdss_dbg && mdss_dbg->base_ap_view_vir)
		ret = *((int *)(mdss_dbg->base_ap_view_vir
			+ md->hw_info->md_epon_offset)) == 0xBAEBAE10;

	CCCI_NORMAL_LOG(0, FSM, "%s, 0x%x\n",
		(in_md_l2sram?"l2sram":"mdssdbg"), ret);

	return ret;
}

static void fsm_routine_start(struct ccci_fsm_ctl *ctl,
	struct ccci_fsm_command *cmd)
{
@@ -1501,6 +1523,7 @@ static void fsm_routine_stop(struct ccci_fsm_ctl *ctl,
	unsigned long flags;
	int ret;
	unsigned long long ns_0, ns_1, ns_2;
	unsigned long long time_0, time_1, time_2;
	char buf[128] = {0};

	/* 1. state sanity check */
@@ -1530,6 +1553,12 @@ static void fsm_routine_stop(struct ccci_fsm_ctl *ctl,
	/*reset fsm poller*/
	ctl->poller_ctl.poller_state = FSM_POLLER_RECEIVED_RESPONSE;
	wake_up(&ctl->poller_ctl.status_rx_wq);

	if (md_wdt_rec.isr_cnt != md_wdt_rec.routine_cnt && ccci_md_epon_set()) {
		md_wdt_rec.reset_flg = 1;
		CCCI_ERROR_LOG(0, FSM, "wdt routine cnt(%d) is diff isr cnt(%d)\n",
			md_wdt_rec.routine_cnt, md_wdt_rec.isr_cnt);
	}
	/* 4. hardware stop */
	ccci_md_stop(cmd->flag & FSM_CMD_FLAG_FLIGHT_MODE ?
		MD_FLIGHT_MODE_ENTER : MD_FLIGHT_MODE_NONE);
@@ -1549,12 +1578,16 @@ static void fsm_routine_stop(struct ccci_fsm_ctl *ctl,
	/* Cleare MD WDT pending bit */
	ret = irq_set_irqchip_state(md->md_wdt_irq_id,
			IRQCHIP_STATE_PENDING, false);
	ns_0 = do_div(wdt_time[0], NSEC_PER_SEC);
	ns_1 = do_div(wdt_time[1], NSEC_PER_SEC);
	ns_2 = do_div(wdt_time[2], NSEC_PER_SEC);

	time_0 = md_wdt_rec.time[0];
	time_1 = md_wdt_rec.time[1];
	time_2 = md_wdt_rec.time[2];
	ns_0 = do_div(time_0, NSEC_PER_SEC);
	ns_1 = do_div(time_1, NSEC_PER_SEC);
	ns_2 = do_div(time_2, NSEC_PER_SEC);
	scnprintf(buf, sizeof(buf),
		"last md wdt isr: %llu.%06llu, disable time: %llu.%06llu, enable time: %llu.%06llu",
		wdt_time[0], ns_0/1000, wdt_time[1], ns_1/1000, wdt_time[2], ns_2/1000);
		time_0, ns_0/1000, time_1, ns_1/1000, time_2, ns_2/1000);
	CCCI_NORMAL_LOG(0, FSM, "clear md wdt irq(%d) ret: %d, %s\n",
		md->md_wdt_irq_id, ret, buf);

@@ -1569,52 +1602,34 @@ static void fsm_routine_stop(struct ccci_fsm_ctl *ctl,
	fsm_finish_command(ctl, cmd, 1);
}

static int ccci_md_epon_set(void)
{
	struct ccci_modem *md = ccci_get_modem();
	struct ccci_smem_region *mdss_dbg
			= ccci_md_get_smem_by_user_id(SMEM_USER_RAW_MDSS_DBG);
	int ret = 0, in_md_l2sram = 0;

	if (md->hw_info->md_l2sram_base) {
		md_cd_lock_modem_clock_src(1);
		ret = *((int *)(md->hw_info->md_l2sram_base
			+ md->hw_info->md_epon_offset)) == 0xBAEBAE10;
		md_cd_lock_modem_clock_src(0);
		in_md_l2sram = 1;
	} else if (mdss_dbg && mdss_dbg->base_ap_view_vir)
		ret = *((int *)(mdss_dbg->base_ap_view_vir
			+ md->hw_info->md_epon_offset)) == 0xBAEBAE10;

	CCCI_NORMAL_LOG(0, FSM, "reset MD after WDT, %s, 0x%x\n",
		(in_md_l2sram?"l2sram":"mdssdbg"), ret);

	return ret;
}

static void fsm_routine_wdt(struct ccci_fsm_ctl *ctl,
	struct ccci_fsm_command *cmd)
{
	int reset_md = 0;
	int is_epon_set = 0;
	unsigned long long ns_0, time_0;

	is_epon_set = ccci_md_epon_set();

	if (is_epon_set)
	if (is_epon_set || md_wdt_rec.reset_flg)
		reset_md = 1;
	else {
		if (ccci_port_get_critical_user(
				CRIT_USR_MDLOG) == 0) {
			CCCI_NORMAL_LOG(0, FSM,
				"mdlogger closed, reset MD after WDT\n");
		if (ccci_port_get_critical_user(CRIT_USR_MDLOG) == 0) {
			CCCI_NORMAL_LOG(0, FSM, "mdlogger closed, reset MD after WDT\n");
			reset_md = 1;
		} else {
			fsm_routine_exception(ctl, NULL, EXCEPTION_WDT);
		}
	}

	time_0 = md_wdt_rec.time[0];
	ns_0 = do_div(time_0, NSEC_PER_SEC);
	CCCI_NORMAL_LOG(0, FSM, "reset MD after WDT[reset_md: %d], wdt isr: %llu.%06llu\n",
		reset_md, time_0, ns_0/1000);
	if (reset_md)
		fsm_monitor_send_message(CCCI_MD_MSG_RESET_REQUEST, 0);

	md_wdt_rec.routine_cnt++;
	fsm_finish_command(ctl, cmd, 1);
}

+6 −11
Original line number Diff line number Diff line
@@ -51,14 +51,6 @@

struct ccci_modem *modem_sys;

/* used to save wdt key time
 * id setting:
 * 0: wdt isr time
 * 1: disable wdt irq time
 * 2: enable wdt irq time
 */
unsigned long long wdt_time[3];

#ifdef CCCI_KMODULE_ENABLE
bool spm_is_md1_sleep(void)
{
@@ -82,7 +74,7 @@ void wdt_enable_irq(struct ccci_modem *md)
{
	if (atomic_cmpxchg(&md->wdt_enabled, 0, 1) == 0) {
		enable_irq(md->md_wdt_irq_id);
		wdt_time[2] = local_clock();
		md_wdt_rec.time[2] = local_clock();
		CCCI_NORMAL_LOG(0, TAG, "enable wdt irq\n");
	}
}
@@ -95,7 +87,7 @@ void wdt_disable_irq(struct ccci_modem *md)
		 * if use disable_irq in isr, system will hang
		 */
		disable_irq_nosync(md->md_wdt_irq_id);
		wdt_time[1] = local_clock();
		md_wdt_rec.time[1] = local_clock();
		/*CCCI_NORMAL_LOG(0, TAG, "disable wdt irq\n");*/
	}
}
@@ -104,7 +96,10 @@ static irqreturn_t md_cd_wdt_isr(int irq, void *data)
{
	struct ccci_modem *md = (struct ccci_modem *)data;

	wdt_time[0] = local_clock();
	md_wdt_rec.time[0] = local_clock();
	md_wdt_rec.isr_cnt++;
	md_wdt_rec.reset_flg = 0;

	//CCCI_ERROR_LOG(0, TAG, "MD WDT IRQ\n");
	//ccci_event_log("md: MD WDT IRQ\n");
	ccci_hif_md_exception((1<<CCIF_HIF_ID), HIF_EX_STOP_EE_NOTIFY);
+0 −1
Original line number Diff line number Diff line
@@ -10,7 +10,6 @@ enum MD_IRQ_TYPE {
	MD_IRQ_WDT,
	MD_IRQ_CCIF_EX,
};
extern unsigned long long wdt_time[3];

int ccci_fsm_init(void);
int ccci_fsm_recv_control_packet(struct sk_buff *skb);
+19 −0
Original line number Diff line number Diff line
@@ -153,6 +153,25 @@ struct ccci_modem {
	void *ioremap_buff_src;
};

struct md_wdt_record {
	unsigned int isr_cnt;
	unsigned int routine_cnt;
	/* When FSM receives a reset event followed by a WDT event
	 * with an EPON flag, and the reset event precedes the WDT
	 * event, md will reset and lost the EPON flag. so need a
	 * reset_flg to record this scenario.
	 */
	unsigned int reset_flg;
	/* used to save wdt key time
	 * id setting:
	 * 0: wdt isr time
	 * 1: disable wdt irq time
	 * 2: enable wdt irq time
	 */
	unsigned long long time[3];
};

extern struct md_wdt_record md_wdt_rec;
extern struct ccci_modem *modem_sys;

/****************************************************************************/