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