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