1  /* SPDX-License-Identifier: GPL-2.0 */
2  /*
3   * Copyright (c) 2022, Linaro Ltd.
4   *
5   */
6  
7  #ifndef _MHI_COMMON_H
8  #define _MHI_COMMON_H
9  
10  #include <linux/bitfield.h>
11  #include <linux/mhi.h>
12  
13  /* MHI registers */
14  #define MHIREGLEN			0x00
15  #define MHIVER				0x08
16  #define MHICFG				0x10
17  #define CHDBOFF				0x18
18  #define ERDBOFF				0x20
19  #define BHIOFF				0x28
20  #define BHIEOFF				0x2c
21  #define DEBUGOFF			0x30
22  #define MHICTRL				0x38
23  #define MHISTATUS			0x48
24  #define CCABAP_LOWER			0x58
25  #define CCABAP_HIGHER			0x5c
26  #define ECABAP_LOWER			0x60
27  #define ECABAP_HIGHER			0x64
28  #define CRCBAP_LOWER			0x68
29  #define CRCBAP_HIGHER			0x6c
30  #define CRDB_LOWER			0x70
31  #define CRDB_HIGHER			0x74
32  #define MHICTRLBASE_LOWER		0x80
33  #define MHICTRLBASE_HIGHER		0x84
34  #define MHICTRLLIMIT_LOWER		0x88
35  #define MHICTRLLIMIT_HIGHER		0x8c
36  #define MHIDATABASE_LOWER		0x98
37  #define MHIDATABASE_HIGHER		0x9c
38  #define MHIDATALIMIT_LOWER		0xa0
39  #define MHIDATALIMIT_HIGHER		0xa4
40  
41  /* MHI BHI registers */
42  #define BHI_BHIVERSION_MINOR		0x00
43  #define BHI_BHIVERSION_MAJOR		0x04
44  #define BHI_IMGADDR_LOW			0x08
45  #define BHI_IMGADDR_HIGH		0x0c
46  #define BHI_IMGSIZE			0x10
47  #define BHI_RSVD1			0x14
48  #define BHI_IMGTXDB			0x18
49  #define BHI_RSVD2			0x1c
50  #define BHI_INTVEC			0x20
51  #define BHI_RSVD3			0x24
52  #define BHI_EXECENV			0x28
53  #define BHI_STATUS			0x2c
54  #define BHI_ERRCODE			0x30
55  #define BHI_ERRDBG1			0x34
56  #define BHI_ERRDBG2			0x38
57  #define BHI_ERRDBG3			0x3c
58  #define BHI_SERIALNU			0x40
59  #define BHI_SBLANTIROLLVER		0x44
60  #define BHI_NUMSEG			0x48
61  #define BHI_MSMHWID(n)			(0x4c + (0x4 * (n)))
62  #define BHI_OEMPKHASH(n)		(0x64 + (0x4 * (n)))
63  #define BHI_RSVD5			0xc4
64  
65  /* BHI register bits */
66  #define BHI_TXDB_SEQNUM_BMSK		GENMASK(29, 0)
67  #define BHI_TXDB_SEQNUM_SHFT		0
68  #define BHI_STATUS_MASK			GENMASK(31, 30)
69  #define BHI_STATUS_ERROR		0x03
70  #define BHI_STATUS_SUCCESS		0x02
71  #define BHI_STATUS_RESET		0x00
72  
73  /* MHI BHIE registers */
74  #define BHIE_MSMSOCID_OFFS		0x00
75  #define BHIE_TXVECADDR_LOW_OFFS		0x2c
76  #define BHIE_TXVECADDR_HIGH_OFFS	0x30
77  #define BHIE_TXVECSIZE_OFFS		0x34
78  #define BHIE_TXVECDB_OFFS		0x3c
79  #define BHIE_TXVECSTATUS_OFFS		0x44
80  #define BHIE_RXVECADDR_LOW_OFFS		0x60
81  #define BHIE_RXVECADDR_HIGH_OFFS	0x64
82  #define BHIE_RXVECSIZE_OFFS		0x68
83  #define BHIE_RXVECDB_OFFS		0x70
84  #define BHIE_RXVECSTATUS_OFFS		0x78
85  
86  /* BHIE register bits */
87  #define BHIE_TXVECDB_SEQNUM_BMSK	GENMASK(29, 0)
88  #define BHIE_TXVECDB_SEQNUM_SHFT	0
89  #define BHIE_TXVECSTATUS_SEQNUM_BMSK	GENMASK(29, 0)
90  #define BHIE_TXVECSTATUS_SEQNUM_SHFT	0
91  #define BHIE_TXVECSTATUS_STATUS_BMSK	GENMASK(31, 30)
92  #define BHIE_TXVECSTATUS_STATUS_SHFT	30
93  #define BHIE_TXVECSTATUS_STATUS_RESET	0x00
94  #define BHIE_TXVECSTATUS_STATUS_XFER_COMPL	0x02
95  #define BHIE_TXVECSTATUS_STATUS_ERROR	0x03
96  #define BHIE_RXVECDB_SEQNUM_BMSK	GENMASK(29, 0)
97  #define BHIE_RXVECDB_SEQNUM_SHFT	0
98  #define BHIE_RXVECSTATUS_SEQNUM_BMSK	GENMASK(29, 0)
99  #define BHIE_RXVECSTATUS_SEQNUM_SHFT	0
100  #define BHIE_RXVECSTATUS_STATUS_BMSK	GENMASK(31, 30)
101  #define BHIE_RXVECSTATUS_STATUS_SHFT	30
102  #define BHIE_RXVECSTATUS_STATUS_RESET	0x00
103  #define BHIE_RXVECSTATUS_STATUS_XFER_COMPL	0x02
104  #define BHIE_RXVECSTATUS_STATUS_ERROR	0x03
105  
106  /* MHI register bits */
107  #define MHICFG_NHWER_MASK		GENMASK(31, 24)
108  #define MHICFG_NER_MASK			GENMASK(23, 16)
109  #define MHICFG_NHWCH_MASK		GENMASK(15, 8)
110  #define MHICFG_NCH_MASK			GENMASK(7, 0)
111  #define MHICTRL_MHISTATE_MASK		GENMASK(15, 8)
112  #define MHICTRL_RESET_MASK		BIT(1)
113  #define MHISTATUS_MHISTATE_MASK		GENMASK(15, 8)
114  #define MHISTATUS_SYSERR_MASK		BIT(2)
115  #define MHISTATUS_READY_MASK		BIT(0)
116  
117  /* Command Ring Element macros */
118  /* No operation command */
119  #define MHI_TRE_CMD_NOOP_PTR		0
120  #define MHI_TRE_CMD_NOOP_DWORD0		0
121  #define MHI_TRE_CMD_NOOP_DWORD1		cpu_to_le32(FIELD_PREP(GENMASK(23, 16), MHI_CMD_NOP))
122  
123  /* Channel reset command */
124  #define MHI_TRE_CMD_RESET_PTR		0
125  #define MHI_TRE_CMD_RESET_DWORD0	0
126  #define MHI_TRE_CMD_RESET_DWORD1(chid)	cpu_to_le32(FIELD_PREP(GENMASK(31, 24), chid) | \
127  						    FIELD_PREP(GENMASK(23, 16),         \
128  							       MHI_CMD_RESET_CHAN))
129  
130  /* Channel stop command */
131  #define MHI_TRE_CMD_STOP_PTR		0
132  #define MHI_TRE_CMD_STOP_DWORD0		0
133  #define MHI_TRE_CMD_STOP_DWORD1(chid)	cpu_to_le32(FIELD_PREP(GENMASK(31, 24), chid) | \
134  						    FIELD_PREP(GENMASK(23, 16),         \
135  							       MHI_CMD_STOP_CHAN))
136  
137  /* Channel start command */
138  #define MHI_TRE_CMD_START_PTR		0
139  #define MHI_TRE_CMD_START_DWORD0	0
140  #define MHI_TRE_CMD_START_DWORD1(chid)	cpu_to_le32(FIELD_PREP(GENMASK(31, 24), chid) | \
141  						    FIELD_PREP(GENMASK(23, 16),         \
142  							       MHI_CMD_START_CHAN))
143  
144  #define MHI_TRE_GET_DWORD(tre, word)	le32_to_cpu((tre)->dword[(word)])
145  #define MHI_TRE_GET_CMD_CHID(tre)	FIELD_GET(GENMASK(31, 24), MHI_TRE_GET_DWORD(tre, 1))
146  #define MHI_TRE_GET_CMD_TYPE(tre)	FIELD_GET(GENMASK(23, 16), MHI_TRE_GET_DWORD(tre, 1))
147  
148  /* Event descriptor macros */
149  #define MHI_TRE_EV_PTR(ptr)		cpu_to_le64(ptr)
150  #define MHI_TRE_EV_DWORD0(code, len)	cpu_to_le32(FIELD_PREP(GENMASK(31, 24), code) | \
151  						    FIELD_PREP(GENMASK(15, 0), len))
152  #define MHI_TRE_EV_DWORD1(chid, type)	cpu_to_le32(FIELD_PREP(GENMASK(31, 24), chid) | \
153  						    FIELD_PREP(GENMASK(23, 16), type))
154  #define MHI_TRE_GET_EV_PTR(tre)		le64_to_cpu((tre)->ptr)
155  #define MHI_TRE_GET_EV_CODE(tre)	FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_DWORD(tre, 0)))
156  #define MHI_TRE_GET_EV_LEN(tre)		FIELD_GET(GENMASK(15, 0), (MHI_TRE_GET_DWORD(tre, 0)))
157  #define MHI_TRE_GET_EV_CHID(tre)	FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_DWORD(tre, 1)))
158  #define MHI_TRE_GET_EV_TYPE(tre)	FIELD_GET(GENMASK(23, 16), (MHI_TRE_GET_DWORD(tre, 1)))
159  #define MHI_TRE_GET_EV_STATE(tre)	FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_DWORD(tre, 0)))
160  #define MHI_TRE_GET_EV_EXECENV(tre)	FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_DWORD(tre, 0)))
161  #define MHI_TRE_GET_EV_SEQ(tre)		MHI_TRE_GET_DWORD(tre, 0)
162  #define MHI_TRE_GET_EV_TIME(tre)	MHI_TRE_GET_EV_PTR(tre)
163  #define MHI_TRE_GET_EV_COOKIE(tre)	lower_32_bits(MHI_TRE_GET_EV_PTR(tre))
164  #define MHI_TRE_GET_EV_VEID(tre)	FIELD_GET(GENMASK(23, 16), (MHI_TRE_GET_DWORD(tre, 0)))
165  #define MHI_TRE_GET_EV_LINKSPEED(tre)	FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_DWORD(tre, 1)))
166  #define MHI_TRE_GET_EV_LINKWIDTH(tre)	FIELD_GET(GENMASK(7, 0), (MHI_TRE_GET_DWORD(tre, 0)))
167  
168  /* State change event */
169  #define MHI_SC_EV_PTR			0
170  #define MHI_SC_EV_DWORD0(state)		cpu_to_le32(FIELD_PREP(GENMASK(31, 24), state))
171  #define MHI_SC_EV_DWORD1(type)		cpu_to_le32(FIELD_PREP(GENMASK(23, 16), type))
172  
173  /* EE event */
174  #define MHI_EE_EV_PTR			0
175  #define MHI_EE_EV_DWORD0(ee)		cpu_to_le32(FIELD_PREP(GENMASK(31, 24), ee))
176  #define MHI_EE_EV_DWORD1(type)		cpu_to_le32(FIELD_PREP(GENMASK(23, 16), type))
177  
178  
179  /* Command Completion event */
180  #define MHI_CC_EV_PTR(ptr)		cpu_to_le64(ptr)
181  #define MHI_CC_EV_DWORD0(code)		cpu_to_le32(FIELD_PREP(GENMASK(31, 24), code))
182  #define MHI_CC_EV_DWORD1(type)		cpu_to_le32(FIELD_PREP(GENMASK(23, 16), type))
183  
184  /* Transfer descriptor macros */
185  #define MHI_TRE_DATA_PTR(ptr)		cpu_to_le64(ptr)
186  #define MHI_TRE_DATA_DWORD0(len)	cpu_to_le32(FIELD_PREP(GENMASK(15, 0), len))
187  #define MHI_TRE_TYPE_TRANSFER		2
188  #define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) cpu_to_le32(FIELD_PREP(GENMASK(23, 16), \
189  								MHI_TRE_TYPE_TRANSFER) |    \
190  								FIELD_PREP(BIT(10), bei) |  \
191  								FIELD_PREP(BIT(9), ieot) |  \
192  								FIELD_PREP(BIT(8), ieob) |  \
193  								FIELD_PREP(BIT(0), chain))
194  #define MHI_TRE_DATA_GET_PTR(tre)	le64_to_cpu((tre)->ptr)
195  #define MHI_TRE_DATA_GET_LEN(tre)	FIELD_GET(GENMASK(15, 0), MHI_TRE_GET_DWORD(tre, 0))
196  #define MHI_TRE_DATA_GET_CHAIN(tre)	(!!(FIELD_GET(BIT(0), MHI_TRE_GET_DWORD(tre, 1))))
197  #define MHI_TRE_DATA_GET_IEOB(tre)	(!!(FIELD_GET(BIT(8), MHI_TRE_GET_DWORD(tre, 1))))
198  #define MHI_TRE_DATA_GET_IEOT(tre)	(!!(FIELD_GET(BIT(9), MHI_TRE_GET_DWORD(tre, 1))))
199  #define MHI_TRE_DATA_GET_BEI(tre)	(!!(FIELD_GET(BIT(10), MHI_TRE_GET_DWORD(tre, 1))))
200  
201  /* RSC transfer descriptor macros */
202  #define MHI_RSCTRE_DATA_PTR(ptr, len)	cpu_to_le64(FIELD_PREP(GENMASK(64, 48), len) | ptr)
203  #define MHI_RSCTRE_DATA_DWORD0(cookie)	cpu_to_le32(cookie)
204  #define MHI_RSCTRE_DATA_DWORD1		cpu_to_le32(FIELD_PREP(GENMASK(23, 16), \
205  							       MHI_PKT_TYPE_COALESCING))
206  
207  enum mhi_pkt_type {
208  	MHI_PKT_TYPE_INVALID = 0x0,
209  	MHI_PKT_TYPE_NOOP_CMD = 0x1,
210  	MHI_PKT_TYPE_TRANSFER = 0x2,
211  	MHI_PKT_TYPE_COALESCING = 0x8,
212  	MHI_PKT_TYPE_RESET_CHAN_CMD = 0x10,
213  	MHI_PKT_TYPE_STOP_CHAN_CMD = 0x11,
214  	MHI_PKT_TYPE_START_CHAN_CMD = 0x12,
215  	MHI_PKT_TYPE_STATE_CHANGE_EVENT = 0x20,
216  	MHI_PKT_TYPE_CMD_COMPLETION_EVENT = 0x21,
217  	MHI_PKT_TYPE_TX_EVENT = 0x22,
218  	MHI_PKT_TYPE_RSC_TX_EVENT = 0x28,
219  	MHI_PKT_TYPE_EE_EVENT = 0x40,
220  	MHI_PKT_TYPE_TSYNC_EVENT = 0x48,
221  	MHI_PKT_TYPE_BW_REQ_EVENT = 0x50,
222  	MHI_PKT_TYPE_STALE_EVENT, /* internal event */
223  };
224  
225  /* MHI transfer completion events */
226  enum mhi_ev_ccs {
227  	MHI_EV_CC_INVALID = 0x0,
228  	MHI_EV_CC_SUCCESS = 0x1,
229  	MHI_EV_CC_EOT = 0x2, /* End of transfer event */
230  	MHI_EV_CC_OVERFLOW = 0x3,
231  	MHI_EV_CC_EOB = 0x4, /* End of block event */
232  	MHI_EV_CC_OOB = 0x5, /* Out of block event */
233  	MHI_EV_CC_DB_MODE = 0x6,
234  	MHI_EV_CC_UNDEFINED_ERR = 0x10,
235  	MHI_EV_CC_BAD_TRE = 0x11,
236  };
237  
238  /* Channel state */
239  enum mhi_ch_state {
240  	MHI_CH_STATE_DISABLED,
241  	MHI_CH_STATE_ENABLED,
242  	MHI_CH_STATE_RUNNING,
243  	MHI_CH_STATE_SUSPENDED,
244  	MHI_CH_STATE_STOP,
245  	MHI_CH_STATE_ERROR,
246  };
247  
248  enum mhi_cmd_type {
249  	MHI_CMD_NOP = 1,
250  	MHI_CMD_RESET_CHAN = 16,
251  	MHI_CMD_STOP_CHAN = 17,
252  	MHI_CMD_START_CHAN = 18,
253  };
254  
255  #define EV_CTX_RESERVED_MASK		GENMASK(7, 0)
256  #define EV_CTX_INTMODC_MASK		GENMASK(15, 8)
257  #define EV_CTX_INTMODT_MASK		GENMASK(31, 16)
258  struct mhi_event_ctxt {
259  	__le32 intmod;
260  	__le32 ertype;
261  	__le32 msivec;
262  
263  	__le64 rbase __packed __aligned(4);
264  	__le64 rlen __packed __aligned(4);
265  	__le64 rp __packed __aligned(4);
266  	__le64 wp __packed __aligned(4);
267  };
268  
269  #define CHAN_CTX_CHSTATE_MASK		GENMASK(7, 0)
270  #define CHAN_CTX_BRSTMODE_MASK		GENMASK(9, 8)
271  #define CHAN_CTX_POLLCFG_MASK		GENMASK(15, 10)
272  #define CHAN_CTX_RESERVED_MASK		GENMASK(31, 16)
273  struct mhi_chan_ctxt {
274  	__le32 chcfg;
275  	__le32 chtype;
276  	__le32 erindex;
277  
278  	__le64 rbase __packed __aligned(4);
279  	__le64 rlen __packed __aligned(4);
280  	__le64 rp __packed __aligned(4);
281  	__le64 wp __packed __aligned(4);
282  };
283  
284  struct mhi_cmd_ctxt {
285  	__le32 reserved0;
286  	__le32 reserved1;
287  	__le32 reserved2;
288  
289  	__le64 rbase __packed __aligned(4);
290  	__le64 rlen __packed __aligned(4);
291  	__le64 rp __packed __aligned(4);
292  	__le64 wp __packed __aligned(4);
293  };
294  
295  struct mhi_ring_element {
296  	__le64 ptr;
297  	__le32 dword[2];
298  };
299  
300  #define MHI_STATE_LIST				\
301  	mhi_state(RESET,	"RESET")	\
302  	mhi_state(READY,	"READY")	\
303  	mhi_state(M0,		"M0")		\
304  	mhi_state(M1,		"M1")		\
305  	mhi_state(M2,		"M2")		\
306  	mhi_state(M3,		"M3")		\
307  	mhi_state(M3_FAST,	"M3_FAST")	\
308  	mhi_state(BHI,		"BHI")		\
309  	mhi_state_end(SYS_ERR,	"SYS ERROR")
310  
311  #undef mhi_state
312  #undef mhi_state_end
313  
314  #define mhi_state(a, b)		case MHI_STATE_##a: return b;
315  #define mhi_state_end(a, b)	case MHI_STATE_##a: return b;
316  
mhi_state_str(enum mhi_state state)317  static inline const char *mhi_state_str(enum mhi_state state)
318  {
319  	switch (state) {
320  	MHI_STATE_LIST
321  	default:
322  		return "Unknown state";
323  	}
324  }
325  
326  #endif /* _MHI_COMMON_H */
327