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