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