1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | |
3 | /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. |
4 | * Copyright (C) 2018-2023 Linaro Ltd. |
5 | */ |
6 | #ifndef _GSI_REG_H_ |
7 | #define _GSI_REG_H_ |
8 | |
9 | /* === Only "gsi.c" and "gsi_reg.c" should include this file === */ |
10 | |
11 | #include <linux/bits.h> |
12 | |
13 | struct platform_device; |
14 | |
15 | struct gsi; |
16 | |
17 | /** |
18 | * DOC: GSI Registers |
19 | * |
20 | * GSI registers are located within the "gsi" address space defined by Device |
21 | * Tree. The offset of each register within that space is specified by |
22 | * symbols defined below. The GSI address space is mapped to virtual memory |
23 | * space in gsi_init(). All GSI registers are 32 bits wide. |
24 | * |
25 | * Each register type is duplicated for a number of instances of something. |
26 | * For example, each GSI channel has its own set of registers defining its |
27 | * configuration. The offset to a channel's set of registers is computed |
28 | * based on a "base" offset plus an additional "stride" amount computed |
29 | * from the channel's ID. For such registers, the offset is computed by a |
30 | * function-like macro that takes a parameter used in the computation. |
31 | * |
32 | * The offset of a register dependent on execution environment is computed |
33 | * by a macro that is supplied a parameter "ee". The "ee" value is a member |
34 | * of the gsi_ee_id enumerated type. |
35 | * |
36 | * The offset of a channel register is computed by a macro that is supplied a |
37 | * parameter "ch". The "ch" value is a channel id whose maximum value is 30 |
38 | * (though the actual limit is hardware-dependent). |
39 | * |
40 | * The offset of an event register is computed by a macro that is supplied a |
41 | * parameter "ev". The "ev" value is an event id whose maximum value is 15 |
42 | * (though the actual limit is hardware-dependent). |
43 | */ |
44 | |
45 | /* enum gsi_reg_id - GSI register IDs */ |
46 | enum gsi_reg_id { |
47 | INTER_EE_SRC_CH_IRQ_MSK, /* IPA v3.5+ */ |
48 | INTER_EE_SRC_EV_CH_IRQ_MSK, /* IPA v3.5+ */ |
49 | CH_C_CNTXT_0, |
50 | CH_C_CNTXT_1, |
51 | CH_C_CNTXT_2, |
52 | CH_C_CNTXT_3, |
53 | CH_C_QOS, |
54 | CH_C_SCRATCH_0, |
55 | CH_C_SCRATCH_1, |
56 | CH_C_SCRATCH_2, |
57 | CH_C_SCRATCH_3, |
58 | EV_CH_E_CNTXT_0, |
59 | EV_CH_E_CNTXT_1, |
60 | EV_CH_E_CNTXT_2, |
61 | EV_CH_E_CNTXT_3, |
62 | EV_CH_E_CNTXT_4, |
63 | EV_CH_E_CNTXT_8, |
64 | EV_CH_E_CNTXT_9, |
65 | EV_CH_E_CNTXT_10, |
66 | EV_CH_E_CNTXT_11, |
67 | EV_CH_E_CNTXT_12, |
68 | EV_CH_E_CNTXT_13, |
69 | EV_CH_E_SCRATCH_0, |
70 | EV_CH_E_SCRATCH_1, |
71 | CH_C_DOORBELL_0, |
72 | EV_CH_E_DOORBELL_0, |
73 | GSI_STATUS, |
74 | CH_CMD, |
75 | EV_CH_CMD, |
76 | GENERIC_CMD, |
77 | HW_PARAM_2, /* IPA v3.5.1+ */ |
78 | HW_PARAM_4, /* IPA v5.0+ */ |
79 | CNTXT_TYPE_IRQ, |
80 | CNTXT_TYPE_IRQ_MSK, |
81 | CNTXT_SRC_CH_IRQ, |
82 | CNTXT_SRC_CH_IRQ_MSK, |
83 | CNTXT_SRC_CH_IRQ_CLR, |
84 | CNTXT_SRC_EV_CH_IRQ, |
85 | CNTXT_SRC_EV_CH_IRQ_MSK, |
86 | CNTXT_SRC_EV_CH_IRQ_CLR, |
87 | CNTXT_SRC_IEOB_IRQ, |
88 | CNTXT_SRC_IEOB_IRQ_MSK, |
89 | CNTXT_SRC_IEOB_IRQ_CLR, |
90 | CNTXT_GLOB_IRQ_STTS, |
91 | CNTXT_GLOB_IRQ_EN, |
92 | CNTXT_GLOB_IRQ_CLR, |
93 | CNTXT_GSI_IRQ_STTS, |
94 | CNTXT_GSI_IRQ_EN, |
95 | CNTXT_GSI_IRQ_CLR, |
96 | CNTXT_INTSET, |
97 | ERROR_LOG, |
98 | ERROR_LOG_CLR, |
99 | CNTXT_SCRATCH_0, |
100 | GSI_REG_ID_COUNT, /* Last; not an ID */ |
101 | }; |
102 | |
103 | /* CH_C_CNTXT_0 register */ |
104 | enum gsi_reg_ch_c_cntxt_0_field_id { |
105 | CHTYPE_PROTOCOL, |
106 | CHTYPE_DIR, |
107 | CH_EE, |
108 | CHID, |
109 | CHTYPE_PROTOCOL_MSB, /* IPA v4.5-4.11 */ |
110 | ERINDEX, /* Not IPA v5.0+ */ |
111 | CHSTATE, |
112 | ELEMENT_SIZE, |
113 | }; |
114 | |
115 | /** enum gsi_channel_type - CHTYPE_PROTOCOL field values in CH_C_CNTXT_0 */ |
116 | enum gsi_channel_type { |
117 | GSI_CHANNEL_TYPE_MHI = 0x0, |
118 | GSI_CHANNEL_TYPE_XHCI = 0x1, |
119 | GSI_CHANNEL_TYPE_GPI = 0x2, |
120 | GSI_CHANNEL_TYPE_XDCI = 0x3, |
121 | GSI_CHANNEL_TYPE_WDI2 = 0x4, |
122 | GSI_CHANNEL_TYPE_GCI = 0x5, |
123 | GSI_CHANNEL_TYPE_WDI3 = 0x6, |
124 | GSI_CHANNEL_TYPE_MHIP = 0x7, |
125 | GSI_CHANNEL_TYPE_AQC = 0x8, |
126 | GSI_CHANNEL_TYPE_11AD = 0x9, |
127 | }; |
128 | |
129 | /* CH_C_CNTXT_1 register */ |
130 | enum gsi_reg_ch_c_cntxt_1_field_id { |
131 | CH_R_LENGTH, |
132 | CH_ERINDEX, /* IPA v5.0+ */ |
133 | }; |
134 | |
135 | /* CH_C_QOS register */ |
136 | enum gsi_reg_ch_c_qos_field_id { |
137 | WRR_WEIGHT, |
138 | MAX_PREFETCH, |
139 | USE_DB_ENG, |
140 | USE_ESCAPE_BUF_ONLY, /* IPA v4.0-4.2 */ |
141 | PREFETCH_MODE, /* IPA v4.5+ */ |
142 | EMPTY_LVL_THRSHOLD, /* IPA v4.5+ */ |
143 | DB_IN_BYTES, /* IPA v4.9+ */ |
144 | LOW_LATENCY_EN, /* IPA v5.0+ */ |
145 | }; |
146 | |
147 | /** enum gsi_prefetch_mode - PREFETCH_MODE field in CH_C_QOS */ |
148 | enum gsi_prefetch_mode { |
149 | USE_PREFETCH_BUFS = 0, |
150 | ESCAPE_BUF_ONLY = 1, |
151 | SMART_PREFETCH = 2, |
152 | FREE_PREFETCH = 3, |
153 | }; |
154 | |
155 | /* EV_CH_E_CNTXT_0 register */ |
156 | enum gsi_reg_ch_c_ev_ch_e_cntxt_0_field_id { |
157 | EV_CHTYPE, /* enum gsi_channel_type */ |
158 | EV_EE, /* enum gsi_ee_id; always GSI_EE_AP for us */ |
159 | EV_EVCHID, |
160 | EV_INTYPE, |
161 | EV_CHSTATE, |
162 | EV_ELEMENT_SIZE, |
163 | }; |
164 | |
165 | /* EV_CH_E_CNTXT_1 register */ |
166 | enum gsi_reg_ev_ch_c_cntxt_1_field_id { |
167 | R_LENGTH, |
168 | }; |
169 | |
170 | /* EV_CH_E_CNTXT_8 register */ |
171 | enum gsi_reg_ch_c_ev_ch_e_cntxt_8_field_id { |
172 | EV_MODT, |
173 | EV_MODC, |
174 | EV_MOD_CNT, |
175 | }; |
176 | |
177 | /* GSI_STATUS register */ |
178 | enum gsi_reg_gsi_status_field_id { |
179 | ENABLED, |
180 | }; |
181 | |
182 | /* CH_CMD register */ |
183 | enum gsi_reg_gsi_ch_cmd_field_id { |
184 | CH_CHID, |
185 | CH_OPCODE, |
186 | }; |
187 | |
188 | /** enum gsi_ch_cmd_opcode - CH_OPCODE field values in CH_CMD */ |
189 | enum gsi_ch_cmd_opcode { |
190 | GSI_CH_ALLOCATE = 0x0, |
191 | GSI_CH_START = 0x1, |
192 | GSI_CH_STOP = 0x2, |
193 | GSI_CH_RESET = 0x9, |
194 | GSI_CH_DE_ALLOC = 0xa, |
195 | GSI_CH_DB_STOP = 0xb, |
196 | }; |
197 | |
198 | /* EV_CH_CMD register */ |
199 | enum gsi_ev_ch_cmd_field_id { |
200 | EV_CHID, |
201 | EV_OPCODE, |
202 | }; |
203 | |
204 | /** enum gsi_evt_cmd_opcode - EV_OPCODE field values in EV_CH_CMD */ |
205 | enum gsi_evt_cmd_opcode { |
206 | GSI_EVT_ALLOCATE = 0x0, |
207 | GSI_EVT_RESET = 0x9, |
208 | GSI_EVT_DE_ALLOC = 0xa, |
209 | }; |
210 | |
211 | /* GENERIC_CMD register */ |
212 | enum gsi_generic_cmd_field_id { |
213 | GENERIC_OPCODE, |
214 | GENERIC_CHID, |
215 | GENERIC_EE, |
216 | GENERIC_PARAMS, /* IPA v4.11+ */ |
217 | }; |
218 | |
219 | /** enum gsi_generic_cmd_opcode - GENERIC_OPCODE field values in GENERIC_CMD */ |
220 | enum gsi_generic_cmd_opcode { |
221 | GSI_GENERIC_HALT_CHANNEL = 0x1, |
222 | GSI_GENERIC_ALLOCATE_CHANNEL = 0x2, |
223 | GSI_GENERIC_ENABLE_FLOW_CONTROL = 0x3, /* IPA v4.2+ */ |
224 | GSI_GENERIC_DISABLE_FLOW_CONTROL = 0x4, /* IPA v4.2+ */ |
225 | GSI_GENERIC_QUERY_FLOW_CONTROL = 0x5, /* IPA v4.11+ */ |
226 | }; |
227 | |
228 | /* HW_PARAM_2 register */ /* IPA v3.5.1+ */ |
229 | enum gsi_hw_param_2_field_id { |
230 | IRAM_SIZE, |
231 | NUM_CH_PER_EE, |
232 | NUM_EV_PER_EE, /* Not IPA v5.0+ */ |
233 | GSI_CH_PEND_TRANSLATE, |
234 | GSI_CH_FULL_LOGIC, |
235 | GSI_USE_SDMA, /* IPA v4.0+ */ |
236 | GSI_SDMA_N_INT, /* IPA v4.0+ */ |
237 | GSI_SDMA_MAX_BURST, /* IPA v4.0+ */ |
238 | GSI_SDMA_N_IOVEC, /* IPA v4.0+ */ |
239 | GSI_USE_RD_WR_ENG, /* IPA v4.2+ */ |
240 | GSI_USE_INTER_EE, /* IPA v4.2+ */ |
241 | }; |
242 | |
243 | /** enum gsi_iram_size - IRAM_SIZE field values in HW_PARAM_2 */ |
244 | enum gsi_iram_size { |
245 | IRAM_SIZE_ONE_KB = 0x0, |
246 | IRAM_SIZE_TWO_KB = 0x1, |
247 | /* The next two values are available for IPA v4.0 and above */ |
248 | IRAM_SIZE_TWO_N_HALF_KB = 0x2, |
249 | IRAM_SIZE_THREE_KB = 0x3, |
250 | /* The next two values are available for IPA v4.5 and above */ |
251 | IRAM_SIZE_THREE_N_HALF_KB = 0x4, |
252 | IRAM_SIZE_FOUR_KB = 0x5, |
253 | }; |
254 | |
255 | /* HW_PARAM_4 register */ /* IPA v5.0+ */ |
256 | enum gsi_hw_param_4_field_id { |
257 | EV_PER_EE, |
258 | IRAM_PROTOCOL_COUNT, |
259 | }; |
260 | |
261 | /** |
262 | * enum gsi_irq_type_id: GSI IRQ types |
263 | * @GSI_CH_CTRL: Channel allocation, deallocation, etc. |
264 | * @GSI_EV_CTRL: Event ring allocation, deallocation, etc. |
265 | * @GSI_GLOB_EE: Global/general event |
266 | * @GSI_IEOB: Transfer (TRE) completion |
267 | * @GSI_INTER_EE_CH_CTRL: Remote-issued stop/reset (unused) |
268 | * @GSI_INTER_EE_EV_CTRL: Remote-issued event reset (unused) |
269 | * @GSI_GENERAL: General hardware event (bus error, etc.) |
270 | */ |
271 | enum gsi_irq_type_id { |
272 | GSI_CH_CTRL = BIT(0), |
273 | GSI_EV_CTRL = BIT(1), |
274 | GSI_GLOB_EE = BIT(2), |
275 | GSI_IEOB = BIT(3), |
276 | GSI_INTER_EE_CH_CTRL = BIT(4), |
277 | GSI_INTER_EE_EV_CTRL = BIT(5), |
278 | GSI_GENERAL = BIT(6), |
279 | /* IRQ types 7-31 (and their bit values) are reserved */ |
280 | }; |
281 | |
282 | /** enum gsi_global_irq_id: Global GSI interrupt events */ |
283 | enum gsi_global_irq_id { |
284 | ERROR_INT = BIT(0), |
285 | GP_INT1 = BIT(1), |
286 | GP_INT2 = BIT(2), |
287 | GP_INT3 = BIT(3), |
288 | /* Global IRQ types 4-31 (and their bit values) are reserved */ |
289 | }; |
290 | |
291 | /** enum gsi_general_irq_id: GSI general IRQ conditions */ |
292 | enum gsi_general_irq_id { |
293 | BREAK_POINT = BIT(0), |
294 | BUS_ERROR = BIT(1), |
295 | CMD_FIFO_OVRFLOW = BIT(2), |
296 | MCS_STACK_OVRFLOW = BIT(3), |
297 | /* General IRQ types 4-31 (and their bit values) are reserved */ |
298 | }; |
299 | |
300 | /* CNTXT_INTSET register */ |
301 | enum gsi_cntxt_intset_field_id { |
302 | INTYPE, |
303 | }; |
304 | |
305 | /* ERROR_LOG register */ |
306 | enum gsi_error_log_field_id { |
307 | ERR_ARG3, |
308 | ERR_ARG2, |
309 | ERR_ARG1, |
310 | ERR_CODE, |
311 | ERR_VIRT_IDX, |
312 | ERR_TYPE, |
313 | ERR_EE, |
314 | }; |
315 | |
316 | /** enum gsi_err_code - ERR_CODE field values in EE_ERR_LOG */ |
317 | enum gsi_err_code { |
318 | GSI_INVALID_TRE = 0x1, |
319 | GSI_OUT_OF_BUFFERS = 0x2, |
320 | GSI_OUT_OF_RESOURCES = 0x3, |
321 | GSI_UNSUPPORTED_INTER_EE_OP = 0x4, |
322 | GSI_EVT_RING_EMPTY = 0x5, |
323 | GSI_NON_ALLOCATED_EVT_ACCESS = 0x6, |
324 | /* 7 is not assigned */ |
325 | GSI_HWO_1 = 0x8, |
326 | }; |
327 | |
328 | /** enum gsi_err_type - ERR_TYPE field values in EE_ERR_LOG */ |
329 | enum gsi_err_type { |
330 | GSI_ERR_TYPE_GLOB = 0x1, |
331 | GSI_ERR_TYPE_CHAN = 0x2, |
332 | GSI_ERR_TYPE_EVT = 0x3, |
333 | }; |
334 | |
335 | /* CNTXT_SCRATCH_0 register */ |
336 | enum gsi_cntxt_scratch_0_field_id { |
337 | INTER_EE_RESULT, |
338 | GENERIC_EE_RESULT, |
339 | }; |
340 | |
341 | /** enum gsi_generic_ee_result - GENERIC_EE_RESULT field values in SCRATCH_0 */ |
342 | enum gsi_generic_ee_result { |
343 | GENERIC_EE_SUCCESS = 0x1, |
344 | GENERIC_EE_INCORRECT_CHANNEL_STATE = 0x2, |
345 | GENERIC_EE_INCORRECT_DIRECTION = 0x3, |
346 | GENERIC_EE_INCORRECT_CHANNEL_TYPE = 0x4, |
347 | GENERIC_EE_INCORRECT_CHANNEL = 0x5, |
348 | GENERIC_EE_RETRY = 0x6, |
349 | GENERIC_EE_NO_RESOURCES = 0x7, |
350 | }; |
351 | |
352 | extern const struct regs gsi_regs_v3_1; |
353 | extern const struct regs gsi_regs_v3_5_1; |
354 | extern const struct regs gsi_regs_v4_0; |
355 | extern const struct regs gsi_regs_v4_5; |
356 | extern const struct regs gsi_regs_v4_9; |
357 | extern const struct regs gsi_regs_v4_11; |
358 | extern const struct regs gsi_regs_v5_0; |
359 | |
360 | /** |
361 | * gsi_reg() - Return the structure describing a GSI register |
362 | * @gsi: GSI pointer |
363 | * @reg_id: GSI register ID |
364 | */ |
365 | const struct reg *gsi_reg(struct gsi *gsi, enum gsi_reg_id reg_id); |
366 | |
367 | /** |
368 | * gsi_reg_init() - Perform GSI register initialization |
369 | * @gsi: GSI pointer |
370 | * @pdev: GSI (IPA) platform device |
371 | * |
372 | * Initialize GSI registers, including looking up and I/O mapping |
373 | * the "gsi" memory space. |
374 | */ |
375 | int gsi_reg_init(struct gsi *gsi, struct platform_device *pdev); |
376 | |
377 | /** |
378 | * gsi_reg_exit() - Inverse of gsi_reg_init() |
379 | * @gsi: GSI pointer |
380 | */ |
381 | void gsi_reg_exit(struct gsi *gsi); |
382 | |
383 | #endif /* _GSI_REG_H_ */ |
384 | |