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 358