Merge tag 'sched-urgent-2022-06-05' of git://git.kernel.org/pub/scm/linux/kernel...
[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 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
24 union 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
45 union 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
64 union 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
76 union 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
89 struct opcap {
90         u64 bits[4];
91 };
92
93 #define IDXD_OPCAP_OFFSET               0x40
94
95 #define IDXD_TABLE_OFFSET               0x60
96 union 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
111 union 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
122 union 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
132 union gensts_reg {
133         struct {
134                 u32 state:2;
135                 u32 reset_type:2;
136                 u32 rsvd:28;
137         };
138         u32 bits;
139 } __packed;
140
141 enum 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
148 enum 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
164 union 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
174 enum 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
194 union 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
207 enum 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)
247 union 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
275 union 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
286 union 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
300 struct grpcfg {
301         u64 wqs[4];
302         u64 engines;
303         union group_flags flags;
304 } __packed;
305
306 union 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
399 union 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
418 union idxd_evntcap {
419         struct {
420                 u64 events:28;
421                 u64 rsvd:36;
422         };
423         u64 bits;
424 } __packed;
425
426 struct 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
437 struct 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
450 union 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
462 union 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
479 union idxd_cntrdata {
480         struct {
481                 u64 event_count_value;
482         };
483         u64 val;
484 } __packed;
485
486 union event_cfg {
487         struct {
488                 u64 event_cat:4;
489                 u64 event_enc:28;
490         };
491         u64 val;
492 } __packed;
493
494 union 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