Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /* Copyright(c) 2019 Intel Corporation. All rights rsvd. */
0003 #ifndef _IDXD_REGISTERS_H_
0004 #define _IDXD_REGISTERS_H_
0005 
0006 /* PCI Config */
0007 #define PCI_DEVICE_ID_INTEL_DSA_SPR0    0x0b25
0008 #define PCI_DEVICE_ID_INTEL_IAX_SPR0    0x0cfe
0009 
0010 #define DEVICE_VERSION_1        0x100
0011 #define DEVICE_VERSION_2        0x200
0012 
0013 #define IDXD_MMIO_BAR       0
0014 #define IDXD_WQ_BAR     2
0015 #define IDXD_PORTAL_SIZE    PAGE_SIZE
0016 
0017 /* MMIO Device BAR0 Registers */
0018 #define IDXD_VER_OFFSET         0x00
0019 #define IDXD_VER_MAJOR_MASK     0xf0
0020 #define IDXD_VER_MINOR_MASK     0x0f
0021 #define GET_IDXD_VER_MAJOR(x)       (((x) & IDXD_VER_MAJOR_MASK) >> 4)
0022 #define GET_IDXD_VER_MINOR(x)       ((x) & IDXD_VER_MINOR_MASK)
0023 
0024 union gen_cap_reg {
0025     struct {
0026         u64 block_on_fault:1;
0027         u64 overlap_copy:1;
0028         u64 cache_control_mem:1;
0029         u64 cache_control_cache:1;
0030         u64 cmd_cap:1;
0031         u64 rsvd:3;
0032         u64 dest_readback:1;
0033         u64 drain_readback:1;
0034         u64 rsvd2:6;
0035         u64 max_xfer_shift:5;
0036         u64 max_batch_shift:4;
0037         u64 max_ims_mult:6;
0038         u64 config_en:1;
0039         u64 rsvd3:32;
0040     };
0041     u64 bits;
0042 } __packed;
0043 #define IDXD_GENCAP_OFFSET      0x10
0044 
0045 union wq_cap_reg {
0046     struct {
0047         u64 total_wq_size:16;
0048         u64 num_wqs:8;
0049         u64 wqcfg_size:4;
0050         u64 rsvd:20;
0051         u64 shared_mode:1;
0052         u64 dedicated_mode:1;
0053         u64 wq_ats_support:1;
0054         u64 priority:1;
0055         u64 occupancy:1;
0056         u64 occupancy_int:1;
0057         u64 rsvd3:10;
0058     };
0059     u64 bits;
0060 } __packed;
0061 #define IDXD_WQCAP_OFFSET       0x20
0062 #define IDXD_WQCFG_MIN          5
0063 
0064 union group_cap_reg {
0065     struct {
0066         u64 num_groups:8;
0067         u64 total_rdbufs:8; /* formerly total_tokens */
0068         u64 rdbuf_ctrl:1;   /* formerly token_en */
0069         u64 rdbuf_limit:1;  /* formerly token_limit */
0070         u64 rsvd:46;
0071     };
0072     u64 bits;
0073 } __packed;
0074 #define IDXD_GRPCAP_OFFSET      0x30
0075 
0076 union engine_cap_reg {
0077     struct {
0078         u64 num_engines:8;
0079         u64 rsvd:56;
0080     };
0081     u64 bits;
0082 } __packed;
0083 
0084 #define IDXD_ENGCAP_OFFSET      0x38
0085 
0086 #define IDXD_OPCAP_NOOP         0x0001
0087 #define IDXD_OPCAP_BATCH            0x0002
0088 #define IDXD_OPCAP_MEMMOVE      0x0008
0089 struct opcap {
0090     u64 bits[4];
0091 };
0092 
0093 #define IDXD_OPCAP_OFFSET       0x40
0094 
0095 #define IDXD_TABLE_OFFSET       0x60
0096 union offsets_reg {
0097     struct {
0098         u64 grpcfg:16;
0099         u64 wqcfg:16;
0100         u64 msix_perm:16;
0101         u64 ims:16;
0102         u64 perfmon:16;
0103         u64 rsvd:48;
0104     };
0105     u64 bits[2];
0106 } __packed;
0107 
0108 #define IDXD_TABLE_MULT         0x100
0109 
0110 #define IDXD_GENCFG_OFFSET      0x80
0111 union gencfg_reg {
0112     struct {
0113         u32 rdbuf_limit:8;
0114         u32 rsvd:4;
0115         u32 user_int_en:1;
0116         u32 rsvd2:19;
0117     };
0118     u32 bits;
0119 } __packed;
0120 
0121 #define IDXD_GENCTRL_OFFSET     0x88
0122 union genctrl_reg {
0123     struct {
0124         u32 softerr_int_en:1;
0125         u32 halt_int_en:1;
0126         u32 rsvd:30;
0127     };
0128     u32 bits;
0129 } __packed;
0130 
0131 #define IDXD_GENSTATS_OFFSET        0x90
0132 union gensts_reg {
0133     struct {
0134         u32 state:2;
0135         u32 reset_type:2;
0136         u32 rsvd:28;
0137     };
0138     u32 bits;
0139 } __packed;
0140 
0141 enum idxd_device_status_state {
0142     IDXD_DEVICE_STATE_DISABLED = 0,
0143     IDXD_DEVICE_STATE_ENABLED,
0144     IDXD_DEVICE_STATE_DRAIN,
0145     IDXD_DEVICE_STATE_HALT,
0146 };
0147 
0148 enum idxd_device_reset_type {
0149     IDXD_DEVICE_RESET_SOFTWARE = 0,
0150     IDXD_DEVICE_RESET_FLR,
0151     IDXD_DEVICE_RESET_WARM,
0152     IDXD_DEVICE_RESET_COLD,
0153 };
0154 
0155 #define IDXD_INTCAUSE_OFFSET        0x98
0156 #define IDXD_INTC_ERR           0x01
0157 #define IDXD_INTC_CMD           0x02
0158 #define IDXD_INTC_OCCUPY            0x04
0159 #define IDXD_INTC_PERFMON_OVFL      0x08
0160 #define IDXD_INTC_HALT_STATE        0x10
0161 #define IDXD_INTC_INT_HANDLE_REVOKED    0x80000000
0162 
0163 #define IDXD_CMD_OFFSET         0xa0
0164 union idxd_command_reg {
0165     struct {
0166         u32 operand:20;
0167         u32 cmd:5;
0168         u32 rsvd:6;
0169         u32 int_req:1;
0170     };
0171     u32 bits;
0172 } __packed;
0173 
0174 enum idxd_cmd {
0175     IDXD_CMD_ENABLE_DEVICE = 1,
0176     IDXD_CMD_DISABLE_DEVICE,
0177     IDXD_CMD_DRAIN_ALL,
0178     IDXD_CMD_ABORT_ALL,
0179     IDXD_CMD_RESET_DEVICE,
0180     IDXD_CMD_ENABLE_WQ,
0181     IDXD_CMD_DISABLE_WQ,
0182     IDXD_CMD_DRAIN_WQ,
0183     IDXD_CMD_ABORT_WQ,
0184     IDXD_CMD_RESET_WQ,
0185     IDXD_CMD_DRAIN_PASID,
0186     IDXD_CMD_ABORT_PASID,
0187     IDXD_CMD_REQUEST_INT_HANDLE,
0188     IDXD_CMD_RELEASE_INT_HANDLE,
0189 };
0190 
0191 #define CMD_INT_HANDLE_IMS      0x10000
0192 
0193 #define IDXD_CMDSTS_OFFSET      0xa8
0194 union cmdsts_reg {
0195     struct {
0196         u8 err;
0197         u16 result;
0198         u8 rsvd:7;
0199         u8 active:1;
0200     };
0201     u32 bits;
0202 } __packed;
0203 #define IDXD_CMDSTS_ACTIVE      0x80000000
0204 #define IDXD_CMDSTS_ERR_MASK        0xff
0205 #define IDXD_CMDSTS_RES_SHIFT       8
0206 
0207 enum idxd_cmdsts_err {
0208     IDXD_CMDSTS_SUCCESS = 0,
0209     IDXD_CMDSTS_INVAL_CMD,
0210     IDXD_CMDSTS_INVAL_WQIDX,
0211     IDXD_CMDSTS_HW_ERR,
0212     /* enable device errors */
0213     IDXD_CMDSTS_ERR_DEV_ENABLED = 0x10,
0214     IDXD_CMDSTS_ERR_CONFIG,
0215     IDXD_CMDSTS_ERR_BUSMASTER_EN,
0216     IDXD_CMDSTS_ERR_PASID_INVAL,
0217     IDXD_CMDSTS_ERR_WQ_SIZE_ERANGE,
0218     IDXD_CMDSTS_ERR_GRP_CONFIG,
0219     IDXD_CMDSTS_ERR_GRP_CONFIG2,
0220     IDXD_CMDSTS_ERR_GRP_CONFIG3,
0221     IDXD_CMDSTS_ERR_GRP_CONFIG4,
0222     /* enable wq errors */
0223     IDXD_CMDSTS_ERR_DEV_NOTEN = 0x20,
0224     IDXD_CMDSTS_ERR_WQ_ENABLED,
0225     IDXD_CMDSTS_ERR_WQ_SIZE,
0226     IDXD_CMDSTS_ERR_WQ_PRIOR,
0227     IDXD_CMDSTS_ERR_WQ_MODE,
0228     IDXD_CMDSTS_ERR_BOF_EN,
0229     IDXD_CMDSTS_ERR_PASID_EN,
0230     IDXD_CMDSTS_ERR_MAX_BATCH_SIZE,
0231     IDXD_CMDSTS_ERR_MAX_XFER_SIZE,
0232     /* disable device errors */
0233     IDXD_CMDSTS_ERR_DIS_DEV_EN = 0x31,
0234     /* disable WQ, drain WQ, abort WQ, reset WQ */
0235     IDXD_CMDSTS_ERR_DEV_NOT_EN,
0236     /* request interrupt handle */
0237     IDXD_CMDSTS_ERR_INVAL_INT_IDX = 0x41,
0238     IDXD_CMDSTS_ERR_NO_HANDLE,
0239 };
0240 
0241 #define IDXD_CMDCAP_OFFSET      0xb0
0242 
0243 #define IDXD_SWERR_OFFSET       0xc0
0244 #define IDXD_SWERR_VALID        0x00000001
0245 #define IDXD_SWERR_OVERFLOW     0x00000002
0246 #define IDXD_SWERR_ACK          (IDXD_SWERR_VALID | IDXD_SWERR_OVERFLOW)
0247 union sw_err_reg {
0248     struct {
0249         u64 valid:1;
0250         u64 overflow:1;
0251         u64 desc_valid:1;
0252         u64 wq_idx_valid:1;
0253         u64 batch:1;
0254         u64 fault_rw:1;
0255         u64 priv:1;
0256         u64 rsvd:1;
0257         u64 error:8;
0258         u64 wq_idx:8;
0259         u64 rsvd2:8;
0260         u64 operation:8;
0261         u64 pasid:20;
0262         u64 rsvd3:4;
0263 
0264         u64 batch_idx:16;
0265         u64 rsvd4:16;
0266         u64 invalid_flags:32;
0267 
0268         u64 fault_addr;
0269 
0270         u64 rsvd5;
0271     };
0272     u64 bits[4];
0273 } __packed;
0274 
0275 union msix_perm {
0276     struct {
0277         u32 rsvd:2;
0278         u32 ignore:1;
0279         u32 pasid_en:1;
0280         u32 rsvd2:8;
0281         u32 pasid:20;
0282     };
0283     u32 bits;
0284 } __packed;
0285 
0286 union group_flags {
0287     struct {
0288         u32 tc_a:3;
0289         u32 tc_b:3;
0290         u32 rsvd:1;
0291         u32 use_rdbuf_limit:1;
0292         u32 rdbufs_reserved:8;
0293         u32 rsvd2:4;
0294         u32 rdbufs_allowed:8;
0295         u32 rsvd3:4;
0296     };
0297     u32 bits;
0298 } __packed;
0299 
0300 struct grpcfg {
0301     u64 wqs[4];
0302     u64 engines;
0303     union group_flags flags;
0304 } __packed;
0305 
0306 union wqcfg {
0307     struct {
0308         /* bytes 0-3 */
0309         u16 wq_size;
0310         u16 rsvd;
0311 
0312         /* bytes 4-7 */
0313         u16 wq_thresh;
0314         u16 rsvd1;
0315 
0316         /* bytes 8-11 */
0317         u32 mode:1; /* shared or dedicated */
0318         u32 bof:1;  /* block on fault */
0319         u32 wq_ats_disable:1;
0320         u32 rsvd2:1;
0321         u32 priority:4;
0322         u32 pasid:20;
0323         u32 pasid_en:1;
0324         u32 priv:1;
0325         u32 rsvd3:2;
0326 
0327         /* bytes 12-15 */
0328         u32 max_xfer_shift:5;
0329         u32 max_batch_shift:4;
0330         u32 rsvd4:23;
0331 
0332         /* bytes 16-19 */
0333         u16 occupancy_inth;
0334         u16 occupancy_table_sel:1;
0335         u16 rsvd5:15;
0336 
0337         /* bytes 20-23 */
0338         u16 occupancy_limit;
0339         u16 occupancy_int_en:1;
0340         u16 rsvd6:15;
0341 
0342         /* bytes 24-27 */
0343         u16 occupancy;
0344         u16 occupancy_int:1;
0345         u16 rsvd7:12;
0346         u16 mode_support:1;
0347         u16 wq_state:2;
0348 
0349         /* bytes 28-31 */
0350         u32 rsvd8;
0351     };
0352     u32 bits[8];
0353 } __packed;
0354 
0355 #define WQCFG_PASID_IDX                2
0356 #define WQCFG_PRIVL_IDX     2
0357 #define WQCFG_OCCUP_IDX     6
0358 
0359 #define WQCFG_OCCUP_MASK    0xffff
0360 
0361 /*
0362  * This macro calculates the offset into the WQCFG register
0363  * idxd - struct idxd *
0364  * n - wq id
0365  * ofs - the index of the 32b dword for the config register
0366  *
0367  * The WQCFG register block is divided into groups per each wq. The n index
0368  * allows us to move to the register group that's for that particular wq.
0369  * Each register is 32bits. The ofs gives us the number of register to access.
0370  */
0371 #define WQCFG_OFFSET(_idxd_dev, n, ofs) \
0372 ({\
0373     typeof(_idxd_dev) __idxd_dev = (_idxd_dev); \
0374     (__idxd_dev)->wqcfg_offset + (n) * (__idxd_dev)->wqcfg_size + sizeof(u32) * (ofs);  \
0375 })
0376 
0377 #define WQCFG_STRIDES(_idxd_dev) ((_idxd_dev)->wqcfg_size / sizeof(u32))
0378 
0379 #define GRPCFG_SIZE     64
0380 #define GRPWQCFG_STRIDES    4
0381 
0382 /*
0383  * This macro calculates the offset into the GRPCFG register
0384  * idxd - struct idxd *
0385  * n - wq id
0386  * ofs - the index of the 32b dword for the config register
0387  *
0388  * The WQCFG register block is divided into groups per each wq. The n index
0389  * allows us to move to the register group that's for that particular wq.
0390  * Each register is 32bits. The ofs gives us the number of register to access.
0391  */
0392 #define GRPWQCFG_OFFSET(idxd_dev, n, ofs) ((idxd_dev)->grpcfg_offset +\
0393                        (n) * GRPCFG_SIZE + sizeof(u64) * (ofs))
0394 #define GRPENGCFG_OFFSET(idxd_dev, n) ((idxd_dev)->grpcfg_offset + (n) * GRPCFG_SIZE + 32)
0395 #define GRPFLGCFG_OFFSET(idxd_dev, n) ((idxd_dev)->grpcfg_offset + (n) * GRPCFG_SIZE + 40)
0396 
0397 /* Following is performance monitor registers */
0398 #define IDXD_PERFCAP_OFFSET     0x0
0399 union idxd_perfcap {
0400     struct {
0401         u64 num_perf_counter:6;
0402         u64 rsvd1:2;
0403         u64 counter_width:8;
0404         u64 num_event_category:4;
0405         u64 global_event_category:16;
0406         u64 filter:8;
0407         u64 rsvd2:8;
0408         u64 cap_per_counter:1;
0409         u64 writeable_counter:1;
0410         u64 counter_freeze:1;
0411         u64 overflow_interrupt:1;
0412         u64 rsvd3:8;
0413     };
0414     u64 bits;
0415 } __packed;
0416 
0417 #define IDXD_EVNTCAP_OFFSET     0x80
0418 union idxd_evntcap {
0419     struct {
0420         u64 events:28;
0421         u64 rsvd:36;
0422     };
0423     u64 bits;
0424 } __packed;
0425 
0426 struct idxd_event {
0427     union {
0428         struct {
0429             u32 event_category:4;
0430             u32 events:28;
0431         };
0432         u32 val;
0433     };
0434 } __packed;
0435 
0436 #define IDXD_CNTRCAP_OFFSET     0x800
0437 struct idxd_cntrcap {
0438     union {
0439         struct {
0440             u32 counter_width:8;
0441             u32 rsvd:20;
0442             u32 num_events:4;
0443         };
0444         u32 val;
0445     };
0446     struct idxd_event events[];
0447 } __packed;
0448 
0449 #define IDXD_PERFRST_OFFSET     0x10
0450 union idxd_perfrst {
0451     struct {
0452         u32 perfrst_config:1;
0453         u32 perfrst_counter:1;
0454         u32 rsvd:30;
0455     };
0456     u32 val;
0457 } __packed;
0458 
0459 #define IDXD_OVFSTATUS_OFFSET       0x30
0460 #define IDXD_PERFFRZ_OFFSET     0x20
0461 #define IDXD_CNTRCFG_OFFSET     0x100
0462 union idxd_cntrcfg {
0463     struct {
0464         u64 enable:1;
0465         u64 interrupt_ovf:1;
0466         u64 global_freeze_ovf:1;
0467         u64 rsvd1:5;
0468         u64 event_category:4;
0469         u64 rsvd2:20;
0470         u64 events:28;
0471         u64 rsvd3:4;
0472     };
0473     u64 val;
0474 } __packed;
0475 
0476 #define IDXD_FLTCFG_OFFSET      0x300
0477 
0478 #define IDXD_CNTRDATA_OFFSET        0x200
0479 union idxd_cntrdata {
0480     struct {
0481         u64 event_count_value;
0482     };
0483     u64 val;
0484 } __packed;
0485 
0486 union event_cfg {
0487     struct {
0488         u64 event_cat:4;
0489         u64 event_enc:28;
0490     };
0491     u64 val;
0492 } __packed;
0493 
0494 union filter_cfg {
0495     struct {
0496         u64 wq:32;
0497         u64 tc:8;
0498         u64 pg_sz:4;
0499         u64 xfer_sz:8;
0500         u64 eng:8;
0501     };
0502     u64 val;
0503 } __packed;
0504 
0505 #endif