Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
[linux-2.6-microblaze.git] / drivers / dma / idxd / registers.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright(c) 2019 Intel Corporation. All rights rsvd. */
3 #ifndef _IDXD_REGISTERS_H_
4 #define _IDXD_REGISTERS_H_
5
6 /* PCI Config */
7 #define PCI_DEVICE_ID_INTEL_DSA_SPR0    0x0b25
8 #define PCI_DEVICE_ID_INTEL_IAX_SPR0    0x0cfe
9
10 #define IDXD_MMIO_BAR           0
11 #define IDXD_WQ_BAR             2
12 #define IDXD_PORTAL_SIZE        PAGE_SIZE
13
14 /* MMIO Device BAR0 Registers */
15 #define IDXD_VER_OFFSET                 0x00
16 #define IDXD_VER_MAJOR_MASK             0xf0
17 #define IDXD_VER_MINOR_MASK             0x0f
18 #define GET_IDXD_VER_MAJOR(x)           (((x) & IDXD_VER_MAJOR_MASK) >> 4)
19 #define GET_IDXD_VER_MINOR(x)           ((x) & IDXD_VER_MINOR_MASK)
20
21 union gen_cap_reg {
22         struct {
23                 u64 block_on_fault:1;
24                 u64 overlap_copy:1;
25                 u64 cache_control_mem:1;
26                 u64 cache_control_cache:1;
27                 u64 rsvd:3;
28                 u64 int_handle_req:1;
29                 u64 dest_readback:1;
30                 u64 drain_readback:1;
31                 u64 rsvd2:6;
32                 u64 max_xfer_shift:5;
33                 u64 max_batch_shift:4;
34                 u64 max_ims_mult:6;
35                 u64 config_en:1;
36                 u64 max_descs_per_engine:8;
37                 u64 rsvd3:24;
38         };
39         u64 bits;
40 } __packed;
41 #define IDXD_GENCAP_OFFSET              0x10
42
43 union wq_cap_reg {
44         struct {
45                 u64 total_wq_size:16;
46                 u64 num_wqs:8;
47                 u64 wqcfg_size:4;
48                 u64 rsvd:20;
49                 u64 shared_mode:1;
50                 u64 dedicated_mode:1;
51                 u64 wq_ats_support:1;
52                 u64 priority:1;
53                 u64 occupancy:1;
54                 u64 occupancy_int:1;
55                 u64 rsvd3:10;
56         };
57         u64 bits;
58 } __packed;
59 #define IDXD_WQCAP_OFFSET               0x20
60 #define IDXD_WQCFG_MIN                  5
61
62 union group_cap_reg {
63         struct {
64                 u64 num_groups:8;
65                 u64 total_tokens:8;
66                 u64 token_en:1;
67                 u64 token_limit:1;
68                 u64 rsvd:46;
69         };
70         u64 bits;
71 } __packed;
72 #define IDXD_GRPCAP_OFFSET              0x30
73
74 union engine_cap_reg {
75         struct {
76                 u64 num_engines:8;
77                 u64 rsvd:56;
78         };
79         u64 bits;
80 } __packed;
81
82 #define IDXD_ENGCAP_OFFSET              0x38
83
84 #define IDXD_OPCAP_NOOP                 0x0001
85 #define IDXD_OPCAP_BATCH                        0x0002
86 #define IDXD_OPCAP_MEMMOVE              0x0008
87 struct opcap {
88         u64 bits[4];
89 };
90
91 #define IDXD_OPCAP_OFFSET               0x40
92
93 #define IDXD_TABLE_OFFSET               0x60
94 union offsets_reg {
95         struct {
96                 u64 grpcfg:16;
97                 u64 wqcfg:16;
98                 u64 msix_perm:16;
99                 u64 ims:16;
100                 u64 perfmon:16;
101                 u64 rsvd:48;
102         };
103         u64 bits[2];
104 } __packed;
105
106 #define IDXD_TABLE_MULT                 0x100
107
108 #define IDXD_GENCFG_OFFSET              0x80
109 union gencfg_reg {
110         struct {
111                 u32 token_limit:8;
112                 u32 rsvd:4;
113                 u32 user_int_en:1;
114                 u32 rsvd2:19;
115         };
116         u32 bits;
117 } __packed;
118
119 #define IDXD_GENCTRL_OFFSET             0x88
120 union genctrl_reg {
121         struct {
122                 u32 softerr_int_en:1;
123                 u32 rsvd:31;
124         };
125         u32 bits;
126 } __packed;
127
128 #define IDXD_GENSTATS_OFFSET            0x90
129 union gensts_reg {
130         struct {
131                 u32 state:2;
132                 u32 reset_type:2;
133                 u32 rsvd:28;
134         };
135         u32 bits;
136 } __packed;
137
138 enum idxd_device_status_state {
139         IDXD_DEVICE_STATE_DISABLED = 0,
140         IDXD_DEVICE_STATE_ENABLED,
141         IDXD_DEVICE_STATE_DRAIN,
142         IDXD_DEVICE_STATE_HALT,
143 };
144
145 enum idxd_device_reset_type {
146         IDXD_DEVICE_RESET_SOFTWARE = 0,
147         IDXD_DEVICE_RESET_FLR,
148         IDXD_DEVICE_RESET_WARM,
149         IDXD_DEVICE_RESET_COLD,
150 };
151
152 #define IDXD_INTCAUSE_OFFSET            0x98
153 #define IDXD_INTC_ERR                   0x01
154 #define IDXD_INTC_CMD                   0x02
155 #define IDXD_INTC_OCCUPY                        0x04
156 #define IDXD_INTC_PERFMON_OVFL          0x08
157
158 #define IDXD_CMD_OFFSET                 0xa0
159 union idxd_command_reg {
160         struct {
161                 u32 operand:20;
162                 u32 cmd:5;
163                 u32 rsvd:6;
164                 u32 int_req:1;
165         };
166         u32 bits;
167 } __packed;
168
169 enum idxd_cmd {
170         IDXD_CMD_ENABLE_DEVICE = 1,
171         IDXD_CMD_DISABLE_DEVICE,
172         IDXD_CMD_DRAIN_ALL,
173         IDXD_CMD_ABORT_ALL,
174         IDXD_CMD_RESET_DEVICE,
175         IDXD_CMD_ENABLE_WQ,
176         IDXD_CMD_DISABLE_WQ,
177         IDXD_CMD_DRAIN_WQ,
178         IDXD_CMD_ABORT_WQ,
179         IDXD_CMD_RESET_WQ,
180         IDXD_CMD_DRAIN_PASID,
181         IDXD_CMD_ABORT_PASID,
182         IDXD_CMD_REQUEST_INT_HANDLE,
183 };
184
185 #define IDXD_CMDSTS_OFFSET              0xa8
186 union cmdsts_reg {
187         struct {
188                 u8 err;
189                 u16 result;
190                 u8 rsvd:7;
191                 u8 active:1;
192         };
193         u32 bits;
194 } __packed;
195 #define IDXD_CMDSTS_ACTIVE              0x80000000
196
197 enum idxd_cmdsts_err {
198         IDXD_CMDSTS_SUCCESS = 0,
199         IDXD_CMDSTS_INVAL_CMD,
200         IDXD_CMDSTS_INVAL_WQIDX,
201         IDXD_CMDSTS_HW_ERR,
202         /* enable device errors */
203         IDXD_CMDSTS_ERR_DEV_ENABLED = 0x10,
204         IDXD_CMDSTS_ERR_CONFIG,
205         IDXD_CMDSTS_ERR_BUSMASTER_EN,
206         IDXD_CMDSTS_ERR_PASID_INVAL,
207         IDXD_CMDSTS_ERR_WQ_SIZE_ERANGE,
208         IDXD_CMDSTS_ERR_GRP_CONFIG,
209         IDXD_CMDSTS_ERR_GRP_CONFIG2,
210         IDXD_CMDSTS_ERR_GRP_CONFIG3,
211         IDXD_CMDSTS_ERR_GRP_CONFIG4,
212         /* enable wq errors */
213         IDXD_CMDSTS_ERR_DEV_NOTEN = 0x20,
214         IDXD_CMDSTS_ERR_WQ_ENABLED,
215         IDXD_CMDSTS_ERR_WQ_SIZE,
216         IDXD_CMDSTS_ERR_WQ_PRIOR,
217         IDXD_CMDSTS_ERR_WQ_MODE,
218         IDXD_CMDSTS_ERR_BOF_EN,
219         IDXD_CMDSTS_ERR_PASID_EN,
220         IDXD_CMDSTS_ERR_MAX_BATCH_SIZE,
221         IDXD_CMDSTS_ERR_MAX_XFER_SIZE,
222         /* disable device errors */
223         IDXD_CMDSTS_ERR_DIS_DEV_EN = 0x31,
224         /* disable WQ, drain WQ, abort WQ, reset WQ */
225         IDXD_CMDSTS_ERR_DEV_NOT_EN,
226         /* request interrupt handle */
227         IDXD_CMDSTS_ERR_INVAL_INT_IDX = 0x41,
228         IDXD_CMDSTS_ERR_NO_HANDLE,
229 };
230
231 #define IDXD_SWERR_OFFSET               0xc0
232 #define IDXD_SWERR_VALID                0x00000001
233 #define IDXD_SWERR_OVERFLOW             0x00000002
234 #define IDXD_SWERR_ACK                  (IDXD_SWERR_VALID | IDXD_SWERR_OVERFLOW)
235 union sw_err_reg {
236         struct {
237                 u64 valid:1;
238                 u64 overflow:1;
239                 u64 desc_valid:1;
240                 u64 wq_idx_valid:1;
241                 u64 batch:1;
242                 u64 fault_rw:1;
243                 u64 priv:1;
244                 u64 rsvd:1;
245                 u64 error:8;
246                 u64 wq_idx:8;
247                 u64 rsvd2:8;
248                 u64 operation:8;
249                 u64 pasid:20;
250                 u64 rsvd3:4;
251
252                 u64 batch_idx:16;
253                 u64 rsvd4:16;
254                 u64 invalid_flags:32;
255
256                 u64 fault_addr;
257
258                 u64 rsvd5;
259         };
260         u64 bits[4];
261 } __packed;
262
263 union msix_perm {
264         struct {
265                 u32 rsvd:2;
266                 u32 ignore:1;
267                 u32 pasid_en:1;
268                 u32 rsvd2:8;
269                 u32 pasid:20;
270         };
271         u32 bits;
272 } __packed;
273
274 union group_flags {
275         struct {
276                 u32 tc_a:3;
277                 u32 tc_b:3;
278                 u32 rsvd:1;
279                 u32 use_token_limit:1;
280                 u32 tokens_reserved:8;
281                 u32 rsvd2:4;
282                 u32 tokens_allowed:8;
283                 u32 rsvd3:4;
284         };
285         u32 bits;
286 } __packed;
287
288 struct grpcfg {
289         u64 wqs[4];
290         u64 engines;
291         union group_flags flags;
292 } __packed;
293
294 union wqcfg {
295         struct {
296                 /* bytes 0-3 */
297                 u16 wq_size;
298                 u16 rsvd;
299
300                 /* bytes 4-7 */
301                 u16 wq_thresh;
302                 u16 rsvd1;
303
304                 /* bytes 8-11 */
305                 u32 mode:1;     /* shared or dedicated */
306                 u32 bof:1;      /* block on fault */
307                 u32 wq_ats_disable:1;
308                 u32 rsvd2:1;
309                 u32 priority:4;
310                 u32 pasid:20;
311                 u32 pasid_en:1;
312                 u32 priv:1;
313                 u32 rsvd3:2;
314
315                 /* bytes 12-15 */
316                 u32 max_xfer_shift:5;
317                 u32 max_batch_shift:4;
318                 u32 rsvd4:23;
319
320                 /* bytes 16-19 */
321                 u16 occupancy_inth;
322                 u16 occupancy_table_sel:1;
323                 u16 rsvd5:15;
324
325                 /* bytes 20-23 */
326                 u16 occupancy_limit;
327                 u16 occupancy_int_en:1;
328                 u16 rsvd6:15;
329
330                 /* bytes 24-27 */
331                 u16 occupancy;
332                 u16 occupancy_int:1;
333                 u16 rsvd7:12;
334                 u16 mode_support:1;
335                 u16 wq_state:2;
336
337                 /* bytes 28-31 */
338                 u32 rsvd8;
339         };
340         u32 bits[8];
341 } __packed;
342
343 #define WQCFG_PASID_IDX                2
344
345 /*
346  * This macro calculates the offset into the WQCFG register
347  * idxd - struct idxd *
348  * n - wq id
349  * ofs - the index of the 32b dword for the config register
350  *
351  * The WQCFG register block is divided into groups per each wq. The n index
352  * allows us to move to the register group that's for that particular wq.
353  * Each register is 32bits. The ofs gives us the number of register to access.
354  */
355 #define WQCFG_OFFSET(_idxd_dev, n, ofs) \
356 ({\
357         typeof(_idxd_dev) __idxd_dev = (_idxd_dev);     \
358         (__idxd_dev)->wqcfg_offset + (n) * (__idxd_dev)->wqcfg_size + sizeof(u32) * (ofs);      \
359 })
360
361 #define WQCFG_STRIDES(_idxd_dev) ((_idxd_dev)->wqcfg_size / sizeof(u32))
362
363 #define GRPCFG_SIZE             64
364 #define GRPWQCFG_STRIDES        4
365
366 /*
367  * This macro calculates the offset into the GRPCFG register
368  * idxd - struct idxd *
369  * n - wq id
370  * ofs - the index of the 32b dword for the config register
371  *
372  * The WQCFG register block is divided into groups per each wq. The n index
373  * allows us to move to the register group that's for that particular wq.
374  * Each register is 32bits. The ofs gives us the number of register to access.
375  */
376 #define GRPWQCFG_OFFSET(idxd_dev, n, ofs) ((idxd_dev)->grpcfg_offset +\
377                                            (n) * GRPCFG_SIZE + sizeof(u64) * (ofs))
378 #define GRPENGCFG_OFFSET(idxd_dev, n) ((idxd_dev)->grpcfg_offset + (n) * GRPCFG_SIZE + 32)
379 #define GRPFLGCFG_OFFSET(idxd_dev, n) ((idxd_dev)->grpcfg_offset + (n) * GRPCFG_SIZE + 40)
380
381 #endif