xref: /linux/drivers/bus/mhi/common.h (revision 3f0a50f345f78183f6e9b39c2f45ca5dcaa511ca)
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 /* Transfer descriptor macros */
169 #define MHI_TRE_DATA_PTR(ptr)		cpu_to_le64(ptr)
170 #define MHI_TRE_DATA_DWORD0(len)	cpu_to_le32(FIELD_PREP(GENMASK(15, 0), len))
171 #define MHI_TRE_TYPE_TRANSFER		2
172 #define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) cpu_to_le32(FIELD_PREP(GENMASK(23, 16), \
173 								MHI_TRE_TYPE_TRANSFER) |    \
174 								FIELD_PREP(BIT(10), bei) |  \
175 								FIELD_PREP(BIT(9), ieot) |  \
176 								FIELD_PREP(BIT(8), ieob) |  \
177 								FIELD_PREP(BIT(0), chain))
178 
179 /* RSC transfer descriptor macros */
180 #define MHI_RSCTRE_DATA_PTR(ptr, len)	cpu_to_le64(FIELD_PREP(GENMASK(64, 48), len) | ptr)
181 #define MHI_RSCTRE_DATA_DWORD0(cookie)	cpu_to_le32(cookie)
182 #define MHI_RSCTRE_DATA_DWORD1		cpu_to_le32(FIELD_PREP(GENMASK(23, 16), \
183 							       MHI_PKT_TYPE_COALESCING))
184 
185 enum mhi_pkt_type {
186 	MHI_PKT_TYPE_INVALID = 0x0,
187 	MHI_PKT_TYPE_NOOP_CMD = 0x1,
188 	MHI_PKT_TYPE_TRANSFER = 0x2,
189 	MHI_PKT_TYPE_COALESCING = 0x8,
190 	MHI_PKT_TYPE_RESET_CHAN_CMD = 0x10,
191 	MHI_PKT_TYPE_STOP_CHAN_CMD = 0x11,
192 	MHI_PKT_TYPE_START_CHAN_CMD = 0x12,
193 	MHI_PKT_TYPE_STATE_CHANGE_EVENT = 0x20,
194 	MHI_PKT_TYPE_CMD_COMPLETION_EVENT = 0x21,
195 	MHI_PKT_TYPE_TX_EVENT = 0x22,
196 	MHI_PKT_TYPE_RSC_TX_EVENT = 0x28,
197 	MHI_PKT_TYPE_EE_EVENT = 0x40,
198 	MHI_PKT_TYPE_TSYNC_EVENT = 0x48,
199 	MHI_PKT_TYPE_BW_REQ_EVENT = 0x50,
200 	MHI_PKT_TYPE_STALE_EVENT, /* internal event */
201 };
202 
203 /* MHI transfer completion events */
204 enum mhi_ev_ccs {
205 	MHI_EV_CC_INVALID = 0x0,
206 	MHI_EV_CC_SUCCESS = 0x1,
207 	MHI_EV_CC_EOT = 0x2, /* End of transfer event */
208 	MHI_EV_CC_OVERFLOW = 0x3,
209 	MHI_EV_CC_EOB = 0x4, /* End of block event */
210 	MHI_EV_CC_OOB = 0x5, /* Out of block event */
211 	MHI_EV_CC_DB_MODE = 0x6,
212 	MHI_EV_CC_UNDEFINED_ERR = 0x10,
213 	MHI_EV_CC_BAD_TRE = 0x11,
214 };
215 
216 /* Channel state */
217 enum mhi_ch_state {
218 	MHI_CH_STATE_DISABLED,
219 	MHI_CH_STATE_ENABLED,
220 	MHI_CH_STATE_RUNNING,
221 	MHI_CH_STATE_SUSPENDED,
222 	MHI_CH_STATE_STOP,
223 	MHI_CH_STATE_ERROR,
224 };
225 
226 enum mhi_cmd_type {
227 	MHI_CMD_NOP = 1,
228 	MHI_CMD_RESET_CHAN = 16,
229 	MHI_CMD_STOP_CHAN = 17,
230 	MHI_CMD_START_CHAN = 18,
231 };
232 
233 #define EV_CTX_RESERVED_MASK		GENMASK(7, 0)
234 #define EV_CTX_INTMODC_MASK		GENMASK(15, 8)
235 #define EV_CTX_INTMODT_MASK		GENMASK(31, 16)
236 struct mhi_event_ctxt {
237 	__le32 intmod;
238 	__le32 ertype;
239 	__le32 msivec;
240 
241 	__le64 rbase __packed __aligned(4);
242 	__le64 rlen __packed __aligned(4);
243 	__le64 rp __packed __aligned(4);
244 	__le64 wp __packed __aligned(4);
245 };
246 
247 #define CHAN_CTX_CHSTATE_MASK		GENMASK(7, 0)
248 #define CHAN_CTX_BRSTMODE_MASK		GENMASK(9, 8)
249 #define CHAN_CTX_POLLCFG_MASK		GENMASK(15, 10)
250 #define CHAN_CTX_RESERVED_MASK		GENMASK(31, 16)
251 struct mhi_chan_ctxt {
252 	__le32 chcfg;
253 	__le32 chtype;
254 	__le32 erindex;
255 
256 	__le64 rbase __packed __aligned(4);
257 	__le64 rlen __packed __aligned(4);
258 	__le64 rp __packed __aligned(4);
259 	__le64 wp __packed __aligned(4);
260 };
261 
262 struct mhi_cmd_ctxt {
263 	__le32 reserved0;
264 	__le32 reserved1;
265 	__le32 reserved2;
266 
267 	__le64 rbase __packed __aligned(4);
268 	__le64 rlen __packed __aligned(4);
269 	__le64 rp __packed __aligned(4);
270 	__le64 wp __packed __aligned(4);
271 };
272 
273 struct mhi_ring_element {
274 	__le64 ptr;
275 	__le32 dword[2];
276 };
277 
278 static inline const char *mhi_state_str(enum mhi_state state)
279 {
280 	switch (state) {
281 	case MHI_STATE_RESET:
282 		return "RESET";
283 	case MHI_STATE_READY:
284 		return "READY";
285 	case MHI_STATE_M0:
286 		return "M0";
287 	case MHI_STATE_M1:
288 		return "M1";
289 	case MHI_STATE_M2:
290 		return "M2";
291 	case MHI_STATE_M3:
292 		return "M3";
293 	case MHI_STATE_M3_FAST:
294 		return "M3 FAST";
295 	case MHI_STATE_BHI:
296 		return "BHI";
297 	case MHI_STATE_SYS_ERR:
298 		return "SYS ERROR";
299 	default:
300 		return "Unknown state";
301 	}
302 };
303 
304 #endif /* _MHI_COMMON_H */
305