Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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 DEVICE_VERSION_1 0x100
11#define DEVICE_VERSION_2 0x200
12
13#define IDXD_MMIO_BAR 0
14#define IDXD_WQ_BAR 2
15#define IDXD_PORTAL_SIZE PAGE_SIZE
16
17/* MMIO Device BAR0 Registers */
18#define IDXD_VER_OFFSET 0x00
19#define IDXD_VER_MAJOR_MASK 0xf0
20#define IDXD_VER_MINOR_MASK 0x0f
21#define GET_IDXD_VER_MAJOR(x) (((x) & IDXD_VER_MAJOR_MASK) >> 4)
22#define GET_IDXD_VER_MINOR(x) ((x) & IDXD_VER_MINOR_MASK)
23
24union gen_cap_reg {
25 struct {
26 u64 block_on_fault:1;
27 u64 overlap_copy:1;
28 u64 cache_control_mem:1;
29 u64 cache_control_cache:1;
30 u64 cmd_cap:1;
31 u64 rsvd:3;
32 u64 dest_readback:1;
33 u64 drain_readback:1;
34 u64 rsvd2:6;
35 u64 max_xfer_shift:5;
36 u64 max_batch_shift:4;
37 u64 max_ims_mult:6;
38 u64 config_en:1;
39 u64 rsvd3:32;
40 };
41 u64 bits;
42} __packed;
43#define IDXD_GENCAP_OFFSET 0x10
44
45union wq_cap_reg {
46 struct {
47 u64 total_wq_size:16;
48 u64 num_wqs:8;
49 u64 wqcfg_size:4;
50 u64 rsvd:20;
51 u64 shared_mode:1;
52 u64 dedicated_mode:1;
53 u64 wq_ats_support:1;
54 u64 priority:1;
55 u64 occupancy:1;
56 u64 occupancy_int:1;
57 u64 rsvd3:10;
58 };
59 u64 bits;
60} __packed;
61#define IDXD_WQCAP_OFFSET 0x20
62#define IDXD_WQCFG_MIN 5
63
64union group_cap_reg {
65 struct {
66 u64 num_groups:8;
67 u64 total_rdbufs:8; /* formerly total_tokens */
68 u64 rdbuf_ctrl:1; /* formerly token_en */
69 u64 rdbuf_limit:1; /* formerly token_limit */
70 u64 rsvd:46;
71 };
72 u64 bits;
73} __packed;
74#define IDXD_GRPCAP_OFFSET 0x30
75
76union engine_cap_reg {
77 struct {
78 u64 num_engines:8;
79 u64 rsvd:56;
80 };
81 u64 bits;
82} __packed;
83
84#define IDXD_ENGCAP_OFFSET 0x38
85
86#define IDXD_OPCAP_NOOP 0x0001
87#define IDXD_OPCAP_BATCH 0x0002
88#define IDXD_OPCAP_MEMMOVE 0x0008
89struct opcap {
90 u64 bits[4];
91};
92
93#define IDXD_OPCAP_OFFSET 0x40
94
95#define IDXD_TABLE_OFFSET 0x60
96union offsets_reg {
97 struct {
98 u64 grpcfg:16;
99 u64 wqcfg:16;
100 u64 msix_perm:16;
101 u64 ims:16;
102 u64 perfmon:16;
103 u64 rsvd:48;
104 };
105 u64 bits[2];
106} __packed;
107
108#define IDXD_TABLE_MULT 0x100
109
110#define IDXD_GENCFG_OFFSET 0x80
111union gencfg_reg {
112 struct {
113 u32 rdbuf_limit:8;
114 u32 rsvd:4;
115 u32 user_int_en:1;
116 u32 rsvd2:19;
117 };
118 u32 bits;
119} __packed;
120
121#define IDXD_GENCTRL_OFFSET 0x88
122union genctrl_reg {
123 struct {
124 u32 softerr_int_en:1;
125 u32 halt_int_en:1;
126 u32 rsvd:30;
127 };
128 u32 bits;
129} __packed;
130
131#define IDXD_GENSTATS_OFFSET 0x90
132union gensts_reg {
133 struct {
134 u32 state:2;
135 u32 reset_type:2;
136 u32 rsvd:28;
137 };
138 u32 bits;
139} __packed;
140
141enum idxd_device_status_state {
142 IDXD_DEVICE_STATE_DISABLED = 0,
143 IDXD_DEVICE_STATE_ENABLED,
144 IDXD_DEVICE_STATE_DRAIN,
145 IDXD_DEVICE_STATE_HALT,
146};
147
148enum idxd_device_reset_type {
149 IDXD_DEVICE_RESET_SOFTWARE = 0,
150 IDXD_DEVICE_RESET_FLR,
151 IDXD_DEVICE_RESET_WARM,
152 IDXD_DEVICE_RESET_COLD,
153};
154
155#define IDXD_INTCAUSE_OFFSET 0x98
156#define IDXD_INTC_ERR 0x01
157#define IDXD_INTC_CMD 0x02
158#define IDXD_INTC_OCCUPY 0x04
159#define IDXD_INTC_PERFMON_OVFL 0x08
160#define IDXD_INTC_HALT_STATE 0x10
161#define IDXD_INTC_INT_HANDLE_REVOKED 0x80000000
162
163#define IDXD_CMD_OFFSET 0xa0
164union idxd_command_reg {
165 struct {
166 u32 operand:20;
167 u32 cmd:5;
168 u32 rsvd:6;
169 u32 int_req:1;
170 };
171 u32 bits;
172} __packed;
173
174enum idxd_cmd {
175 IDXD_CMD_ENABLE_DEVICE = 1,
176 IDXD_CMD_DISABLE_DEVICE,
177 IDXD_CMD_DRAIN_ALL,
178 IDXD_CMD_ABORT_ALL,
179 IDXD_CMD_RESET_DEVICE,
180 IDXD_CMD_ENABLE_WQ,
181 IDXD_CMD_DISABLE_WQ,
182 IDXD_CMD_DRAIN_WQ,
183 IDXD_CMD_ABORT_WQ,
184 IDXD_CMD_RESET_WQ,
185 IDXD_CMD_DRAIN_PASID,
186 IDXD_CMD_ABORT_PASID,
187 IDXD_CMD_REQUEST_INT_HANDLE,
188 IDXD_CMD_RELEASE_INT_HANDLE,
189};
190
191#define CMD_INT_HANDLE_IMS 0x10000
192
193#define IDXD_CMDSTS_OFFSET 0xa8
194union cmdsts_reg {
195 struct {
196 u8 err;
197 u16 result;
198 u8 rsvd:7;
199 u8 active:1;
200 };
201 u32 bits;
202} __packed;
203#define IDXD_CMDSTS_ACTIVE 0x80000000
204#define IDXD_CMDSTS_ERR_MASK 0xff
205#define IDXD_CMDSTS_RES_SHIFT 8
206
207enum idxd_cmdsts_err {
208 IDXD_CMDSTS_SUCCESS = 0,
209 IDXD_CMDSTS_INVAL_CMD,
210 IDXD_CMDSTS_INVAL_WQIDX,
211 IDXD_CMDSTS_HW_ERR,
212 /* enable device errors */
213 IDXD_CMDSTS_ERR_DEV_ENABLED = 0x10,
214 IDXD_CMDSTS_ERR_CONFIG,
215 IDXD_CMDSTS_ERR_BUSMASTER_EN,
216 IDXD_CMDSTS_ERR_PASID_INVAL,
217 IDXD_CMDSTS_ERR_WQ_SIZE_ERANGE,
218 IDXD_CMDSTS_ERR_GRP_CONFIG,
219 IDXD_CMDSTS_ERR_GRP_CONFIG2,
220 IDXD_CMDSTS_ERR_GRP_CONFIG3,
221 IDXD_CMDSTS_ERR_GRP_CONFIG4,
222 /* enable wq errors */
223 IDXD_CMDSTS_ERR_DEV_NOTEN = 0x20,
224 IDXD_CMDSTS_ERR_WQ_ENABLED,
225 IDXD_CMDSTS_ERR_WQ_SIZE,
226 IDXD_CMDSTS_ERR_WQ_PRIOR,
227 IDXD_CMDSTS_ERR_WQ_MODE,
228 IDXD_CMDSTS_ERR_BOF_EN,
229 IDXD_CMDSTS_ERR_PASID_EN,
230 IDXD_CMDSTS_ERR_MAX_BATCH_SIZE,
231 IDXD_CMDSTS_ERR_MAX_XFER_SIZE,
232 /* disable device errors */
233 IDXD_CMDSTS_ERR_DIS_DEV_EN = 0x31,
234 /* disable WQ, drain WQ, abort WQ, reset WQ */
235 IDXD_CMDSTS_ERR_DEV_NOT_EN,
236 /* request interrupt handle */
237 IDXD_CMDSTS_ERR_INVAL_INT_IDX = 0x41,
238 IDXD_CMDSTS_ERR_NO_HANDLE,
239};
240
241#define IDXD_CMDCAP_OFFSET 0xb0
242
243#define IDXD_SWERR_OFFSET 0xc0
244#define IDXD_SWERR_VALID 0x00000001
245#define IDXD_SWERR_OVERFLOW 0x00000002
246#define IDXD_SWERR_ACK (IDXD_SWERR_VALID | IDXD_SWERR_OVERFLOW)
247union sw_err_reg {
248 struct {
249 u64 valid:1;
250 u64 overflow:1;
251 u64 desc_valid:1;
252 u64 wq_idx_valid:1;
253 u64 batch:1;
254 u64 fault_rw:1;
255 u64 priv:1;
256 u64 rsvd:1;
257 u64 error:8;
258 u64 wq_idx:8;
259 u64 rsvd2:8;
260 u64 operation:8;
261 u64 pasid:20;
262 u64 rsvd3:4;
263
264 u64 batch_idx:16;
265 u64 rsvd4:16;
266 u64 invalid_flags:32;
267
268 u64 fault_addr;
269
270 u64 rsvd5;
271 };
272 u64 bits[4];
273} __packed;
274
275union msix_perm {
276 struct {
277 u32 rsvd:2;
278 u32 ignore:1;
279 u32 pasid_en:1;
280 u32 rsvd2:8;
281 u32 pasid:20;
282 };
283 u32 bits;
284} __packed;
285
286union group_flags {
287 struct {
288 u32 tc_a:3;
289 u32 tc_b:3;
290 u32 rsvd:1;
291 u32 use_rdbuf_limit:1;
292 u32 rdbufs_reserved:8;
293 u32 rsvd2:4;
294 u32 rdbufs_allowed:8;
295 u32 rsvd3:4;
296 };
297 u32 bits;
298} __packed;
299
300struct grpcfg {
301 u64 wqs[4];
302 u64 engines;
303 union group_flags flags;
304} __packed;
305
306union wqcfg {
307 struct {
308 /* bytes 0-3 */
309 u16 wq_size;
310 u16 rsvd;
311
312 /* bytes 4-7 */
313 u16 wq_thresh;
314 u16 rsvd1;
315
316 /* bytes 8-11 */
317 u32 mode:1; /* shared or dedicated */
318 u32 bof:1; /* block on fault */
319 u32 wq_ats_disable:1;
320 u32 rsvd2:1;
321 u32 priority:4;
322 u32 pasid:20;
323 u32 pasid_en:1;
324 u32 priv:1;
325 u32 rsvd3:2;
326
327 /* bytes 12-15 */
328 u32 max_xfer_shift:5;
329 u32 max_batch_shift:4;
330 u32 rsvd4:23;
331
332 /* bytes 16-19 */
333 u16 occupancy_inth;
334 u16 occupancy_table_sel:1;
335 u16 rsvd5:15;
336
337 /* bytes 20-23 */
338 u16 occupancy_limit;
339 u16 occupancy_int_en:1;
340 u16 rsvd6:15;
341
342 /* bytes 24-27 */
343 u16 occupancy;
344 u16 occupancy_int:1;
345 u16 rsvd7:12;
346 u16 mode_support:1;
347 u16 wq_state:2;
348
349 /* bytes 28-31 */
350 u32 rsvd8;
351 };
352 u32 bits[8];
353} __packed;
354
355#define WQCFG_PASID_IDX 2
356#define WQCFG_PRIVL_IDX 2
357#define WQCFG_OCCUP_IDX 6
358
359#define WQCFG_OCCUP_MASK 0xffff
360
361/*
362 * This macro calculates the offset into the WQCFG register
363 * idxd - struct idxd *
364 * n - wq id
365 * ofs - the index of the 32b dword for the config register
366 *
367 * The WQCFG register block is divided into groups per each wq. The n index
368 * allows us to move to the register group that's for that particular wq.
369 * Each register is 32bits. The ofs gives us the number of register to access.
370 */
371#define WQCFG_OFFSET(_idxd_dev, n, ofs) \
372({\
373 typeof(_idxd_dev) __idxd_dev = (_idxd_dev); \
374 (__idxd_dev)->wqcfg_offset + (n) * (__idxd_dev)->wqcfg_size + sizeof(u32) * (ofs); \
375})
376
377#define WQCFG_STRIDES(_idxd_dev) ((_idxd_dev)->wqcfg_size / sizeof(u32))
378
379#define GRPCFG_SIZE 64
380#define GRPWQCFG_STRIDES 4
381
382/*
383 * This macro calculates the offset into the GRPCFG register
384 * idxd - struct idxd *
385 * n - wq id
386 * ofs - the index of the 32b dword for the config register
387 *
388 * The WQCFG register block is divided into groups per each wq. The n index
389 * allows us to move to the register group that's for that particular wq.
390 * Each register is 32bits. The ofs gives us the number of register to access.
391 */
392#define GRPWQCFG_OFFSET(idxd_dev, n, ofs) ((idxd_dev)->grpcfg_offset +\
393 (n) * GRPCFG_SIZE + sizeof(u64) * (ofs))
394#define GRPENGCFG_OFFSET(idxd_dev, n) ((idxd_dev)->grpcfg_offset + (n) * GRPCFG_SIZE + 32)
395#define GRPFLGCFG_OFFSET(idxd_dev, n) ((idxd_dev)->grpcfg_offset + (n) * GRPCFG_SIZE + 40)
396
397/* Following is performance monitor registers */
398#define IDXD_PERFCAP_OFFSET 0x0
399union idxd_perfcap {
400 struct {
401 u64 num_perf_counter:6;
402 u64 rsvd1:2;
403 u64 counter_width:8;
404 u64 num_event_category:4;
405 u64 global_event_category:16;
406 u64 filter:8;
407 u64 rsvd2:8;
408 u64 cap_per_counter:1;
409 u64 writeable_counter:1;
410 u64 counter_freeze:1;
411 u64 overflow_interrupt:1;
412 u64 rsvd3:8;
413 };
414 u64 bits;
415} __packed;
416
417#define IDXD_EVNTCAP_OFFSET 0x80
418union idxd_evntcap {
419 struct {
420 u64 events:28;
421 u64 rsvd:36;
422 };
423 u64 bits;
424} __packed;
425
426struct idxd_event {
427 union {
428 struct {
429 u32 event_category:4;
430 u32 events:28;
431 };
432 u32 val;
433 };
434} __packed;
435
436#define IDXD_CNTRCAP_OFFSET 0x800
437struct idxd_cntrcap {
438 union {
439 struct {
440 u32 counter_width:8;
441 u32 rsvd:20;
442 u32 num_events:4;
443 };
444 u32 val;
445 };
446 struct idxd_event events[];
447} __packed;
448
449#define IDXD_PERFRST_OFFSET 0x10
450union idxd_perfrst {
451 struct {
452 u32 perfrst_config:1;
453 u32 perfrst_counter:1;
454 u32 rsvd:30;
455 };
456 u32 val;
457} __packed;
458
459#define IDXD_OVFSTATUS_OFFSET 0x30
460#define IDXD_PERFFRZ_OFFSET 0x20
461#define IDXD_CNTRCFG_OFFSET 0x100
462union idxd_cntrcfg {
463 struct {
464 u64 enable:1;
465 u64 interrupt_ovf:1;
466 u64 global_freeze_ovf:1;
467 u64 rsvd1:5;
468 u64 event_category:4;
469 u64 rsvd2:20;
470 u64 events:28;
471 u64 rsvd3:4;
472 };
473 u64 val;
474} __packed;
475
476#define IDXD_FLTCFG_OFFSET 0x300
477
478#define IDXD_CNTRDATA_OFFSET 0x200
479union idxd_cntrdata {
480 struct {
481 u64 event_count_value;
482 };
483 u64 val;
484} __packed;
485
486union event_cfg {
487 struct {
488 u64 event_cat:4;
489 u64 event_enc:28;
490 };
491 u64 val;
492} __packed;
493
494union filter_cfg {
495 struct {
496 u64 wq:32;
497 u64 tc:8;
498 u64 pg_sz:4;
499 u64 xfer_sz:8;
500 u64 eng:8;
501 };
502 u64 val;
503} __packed;
504
505#endif