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_tokens:8; 68 u64 token_en:1; 69 u64 token_limit:1; 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 token_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 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 504