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
28enum 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
38enum 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
50enum 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
58enum t7xx_ex_reason {
59	EXCEPTION_HS_TIMEOUT,
60	EXCEPTION_EVENT,
61};
62
63enum t7xx_md_irq_type {
64	MD_IRQ_WDT,
65	MD_IRQ_CCIF_EX,
66	MD_IRQ_PORT_ENUM,
67};
68
69enum 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
84struct 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
102struct 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
109struct 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
117struct t7xx_fsm_notifier {
118	struct list_head	entry;
119	int (*notifier_fn)(enum md_state state, void *data);
120	void			*data;
121};
122
123int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id,
124			unsigned int flag);
125int t7xx_fsm_append_event(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_event_state event_id,
126			  unsigned char *data, unsigned int length);
127void t7xx_fsm_clr_event(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_event_state event_id);
128void t7xx_fsm_broadcast_state(struct t7xx_fsm_ctl *ctl, enum md_state state);
129void t7xx_fsm_reset(struct t7xx_modem *md);
130int t7xx_fsm_init(struct t7xx_modem *md);
131void t7xx_fsm_uninit(struct t7xx_modem *md);
132int t7xx_fsm_recv_md_intr(struct t7xx_fsm_ctl *ctl, enum t7xx_md_irq_type type);
133enum md_state t7xx_fsm_get_md_state(struct t7xx_fsm_ctl *ctl);
134unsigned int t7xx_fsm_get_ctl_state(struct t7xx_fsm_ctl *ctl);
135void t7xx_fsm_notifier_register(struct t7xx_modem *md, struct t7xx_fsm_notifier *notifier);
136void t7xx_fsm_notifier_unregister(struct t7xx_modem *md, struct t7xx_fsm_notifier *notifier);
137
138#endif /* __T7XX_MONITOR_H__ */
139