linux/drivers/dma/idxd/registers.h
<<
>>
Prefs
   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
  24union 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 max_descs_per_engine:8;
  40                u64 rsvd3:24;
  41        };
  42        u64 bits;
  43} __packed;
  44#define IDXD_GENCAP_OFFSET              0x10
  45
  46union wq_cap_reg {
  47        struct {
  48                u64 total_wq_size:16;
  49                u64 num_wqs:8;
  50                u64 wqcfg_size:4;
  51                u64 rsvd:20;
  52                u64 shared_mode:1;
  53                u64 dedicated_mode:1;
  54                u64 wq_ats_support:1;
  55                u64 priority:1;
  56                u64 occupancy:1;
  57                u64 occupancy_int:1;
  58                u64 rsvd3:10;
  59        };
  60        u64 bits;
  61} __packed;
  62#define IDXD_WQCAP_OFFSET               0x20
  63#define IDXD_WQCFG_MIN                  5
  64
  65union group_cap_reg {
  66        struct {
  67                u64 num_groups:8;
  68                u64 total_tokens:8;
  69                u64 token_en:1;
  70                u64 token_limit:1;
  71                u64 rsvd:46;
  72        };
  73        u64 bits;
  74} __packed;
  75#define IDXD_GRPCAP_OFFSET              0x30
  76
  77union engine_cap_reg {
  78        struct {
  79                u64 num_engines:8;
  80                u64 rsvd:56;
  81        };
  82        u64 bits;
  83} __packed;
  84
  85#define IDXD_ENGCAP_OFFSET              0x38
  86
  87#define IDXD_OPCAP_NOOP                 0x0001
  88#define IDXD_OPCAP_BATCH                        0x0002
  89#define IDXD_OPCAP_MEMMOVE              0x0008
  90struct opcap {
  91        u64 bits[4];
  92};
  93
  94#define IDXD_OPCAP_OFFSET               0x40
  95
  96#define IDXD_TABLE_OFFSET               0x60
  97union offsets_reg {
  98        struct {
  99                u64 grpcfg:16;
 100                u64 wqcfg:16;
 101                u64 msix_perm:16;
 102                u64 ims:16;
 103                u64 perfmon:16;
 104                u64 rsvd:48;
 105        };
 106        u64 bits[2];
 107} __packed;
 108
 109#define IDXD_TABLE_MULT                 0x100
 110
 111#define IDXD_GENCFG_OFFSET              0x80
 112union gencfg_reg {
 113        struct {
 114                u32 token_limit:8;
 115                u32 rsvd:4;
 116                u32 user_int_en:1;
 117                u32 rsvd2:19;
 118        };
 119        u32 bits;
 120} __packed;
 121
 122#define IDXD_GENCTRL_OFFSET             0x88
 123union genctrl_reg {
 124        struct {
 125                u32 softerr_int_en:1;
 126                u32 halt_int_en:1;
 127                u32 rsvd:30;
 128        };
 129        u32 bits;
 130} __packed;
 131
 132#define IDXD_GENSTATS_OFFSET            0x90
 133union gensts_reg {
 134        struct {
 135                u32 state:2;
 136                u32 reset_type:2;
 137                u32 rsvd:28;
 138        };
 139        u32 bits;
 140} __packed;
 141
 142enum idxd_device_status_state {
 143        IDXD_DEVICE_STATE_DISABLED = 0,
 144        IDXD_DEVICE_STATE_ENABLED,
 145        IDXD_DEVICE_STATE_DRAIN,
 146        IDXD_DEVICE_STATE_HALT,
 147};
 148
 149enum idxd_device_reset_type {
 150        IDXD_DEVICE_RESET_SOFTWARE = 0,
 151        IDXD_DEVICE_RESET_FLR,
 152        IDXD_DEVICE_RESET_WARM,
 153        IDXD_DEVICE_RESET_COLD,
 154};
 155
 156#define IDXD_INTCAUSE_OFFSET            0x98
 157#define IDXD_INTC_ERR                   0x01
 158#define IDXD_INTC_CMD                   0x02
 159#define IDXD_INTC_OCCUPY                        0x04
 160#define IDXD_INTC_PERFMON_OVFL          0x08
 161
 162#define IDXD_CMD_OFFSET                 0xa0
 163union 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
 173enum 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
 193union 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
 206enum 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)
 246union 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
 274union 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
 285union 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
 299struct grpcfg {
 300        u64 wqs[4];
 301        u64 engines;
 302        union group_flags flags;
 303} __packed;
 304
 305union 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
 397union 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
 416union idxd_evntcap {
 417        struct {
 418                u64 events:28;
 419                u64 rsvd:36;
 420        };
 421        u64 bits;
 422} __packed;
 423
 424struct 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
 435struct 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
 448union 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
 460union 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
 477union idxd_cntrdata {
 478        struct {
 479                u64 event_count_value;
 480        };
 481        u64 val;
 482} __packed;
 483
 484union event_cfg {
 485        struct {
 486                u64 event_cat:4;
 487                u64 event_enc:28;
 488        };
 489        u64 val;
 490} __packed;
 491
 492union 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