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