1 /* SPDX-License-Identifier: GPL-2.0-only
2  *
3  * Copyright (c) 2021, MediaTek Inc.
4  * Copyright (c) 2021-2022, Intel Corporation.
5  *
6  * Authors:
7  *  Amir Hanania <amir.hanania@intel.com>
8  *  Haijun Liu <haijun.liu@mediatek.com>
9  *  Moises Veleta <moises.veleta@intel.com>
10  *
11  * Contributors:
12  *  Eliot Lee <eliot.lee@intel.com>
13  *  Ricardo Martinez <ricardo.martinez@linux.intel.com>
14  *  Sreehari Kancharla <sreehari.kancharla@intel.com>
15  */
16 
17 #ifndef __T7XX_MONITOR_H__
18 #define __T7XX_MONITOR_H__
19 
20 #include <linux/bits.h>
21 #include <linux/sched.h>
22 #include <linux/spinlock.h>
23 #include <linux/types.h>
24 #include <linux/wait.h>
25 
26 #include "t7xx_modem_ops.h"
27 
28 enum t7xx_fsm_state {
29 	FSM_STATE_INIT,
30 	FSM_STATE_PRE_START,
31 	FSM_STATE_STARTING,
32 	FSM_STATE_READY,
33 	FSM_STATE_EXCEPTION,
34 	FSM_STATE_STOPPING,
35 	FSM_STATE_STOPPED,
36 };
37 
38 enum t7xx_fsm_event_state {
39 	FSM_EVENT_INVALID,
40 	FSM_EVENT_MD_HS2,
41 	FSM_EVENT_AP_HS2,
42 	FSM_EVENT_MD_EX,
43 	FSM_EVENT_MD_EX_REC_OK,
44 	FSM_EVENT_MD_EX_PASS,
45 	FSM_EVENT_MD_HS2_EXIT,
46 	FSM_EVENT_AP_HS2_EXIT,
47 	FSM_EVENT_MAX
48 };
49 
50 enum t7xx_fsm_cmd_state {
51 	FSM_CMD_INVALID,
52 	FSM_CMD_START,
53 	FSM_CMD_EXCEPTION,
54 	FSM_CMD_PRE_STOP,
55 	FSM_CMD_STOP,
56 };
57 
58 enum t7xx_ex_reason {
59 	EXCEPTION_HS_TIMEOUT,
60 	EXCEPTION_EVENT,
61 };
62 
63 enum t7xx_md_irq_type {
64 	MD_IRQ_WDT,
65 	MD_IRQ_CCIF_EX,
66 	MD_IRQ_PORT_ENUM,
67 };
68 
69 enum md_state {
70 	MD_STATE_INVALID,
71 	MD_STATE_WAITING_FOR_HS1,
72 	MD_STATE_WAITING_FOR_HS2,
73 	MD_STATE_READY,
74 	MD_STATE_EXCEPTION,
75 	MD_STATE_WAITING_TO_STOP,
76 	MD_STATE_STOPPED,
77 };
78 
79 #define FSM_CMD_FLAG_WAIT_FOR_COMPLETION	BIT(0)
80 #define FSM_CMD_FLAG_FLIGHT_MODE		BIT(1)
81 #define FSM_CMD_FLAG_IN_INTERRUPT		BIT(2)
82 #define FSM_CMD_EX_REASON			GENMASK(23, 16)
83 
84 struct t7xx_fsm_ctl {
85 	struct t7xx_modem	*md;
86 	enum md_state		md_state;
87 	unsigned int		curr_state;
88 	struct list_head	command_queue;
89 	struct list_head	event_queue;
90 	wait_queue_head_t	command_wq;
91 	wait_queue_head_t	event_wq;
92 	wait_queue_head_t	async_hk_wq;
93 	spinlock_t		event_lock;		/* Protects event queue */
94 	spinlock_t		command_lock;		/* Protects command queue */
95 	struct task_struct	*fsm_thread;
96 	bool			exp_flg;
97 	spinlock_t		notifier_lock;		/* Protects notifier list */
98 	struct list_head	notifier_list;
99 	u32			status;			/* Device boot stage */
100 };
101 
102 struct t7xx_fsm_event {
103 	struct list_head	entry;
104 	enum t7xx_fsm_event_state event_id;
105 	unsigned int		length;
106 	unsigned char		data[] __counted_by(length);
107 };
108 
109 struct t7xx_fsm_command {
110 	struct list_head	entry;
111 	enum t7xx_fsm_cmd_state	cmd_id;
112 	unsigned int		flag;
113 	struct completion	*done;
114 	int			*ret;
115 };
116 
117 struct t7xx_fsm_notifier {
118 	struct list_head	entry;
119 	int (*notifier_fn)(enum md_state state, void *data);
120 	void			*data;
121 };
122 
123 int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id,
124 			unsigned int flag);
125 int t7xx_fsm_append_event(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_event_state event_id,
126 			  unsigned char *data, unsigned int length);
127 void t7xx_fsm_clr_event(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_event_state event_id);
128 void t7xx_fsm_broadcast_state(struct t7xx_fsm_ctl *ctl, enum md_state state);
129 void t7xx_fsm_reset(struct t7xx_modem *md);
130 int t7xx_fsm_init(struct t7xx_modem *md);
131 void t7xx_fsm_uninit(struct t7xx_modem *md);
132 int t7xx_fsm_recv_md_intr(struct t7xx_fsm_ctl *ctl, enum t7xx_md_irq_type type);
133 enum md_state t7xx_fsm_get_md_state(struct t7xx_fsm_ctl *ctl);
134 unsigned int t7xx_fsm_get_ctl_state(struct t7xx_fsm_ctl *ctl);
135 void t7xx_fsm_notifier_register(struct t7xx_modem *md, struct t7xx_fsm_notifier *notifier);
136 void t7xx_fsm_notifier_unregister(struct t7xx_modem *md, struct t7xx_fsm_notifier *notifier);
137 
138 #endif /* __T7XX_MONITOR_H__ */
139