registers.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  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. /* PCI Config */
  6. #define PCI_DEVICE_ID_INTEL_DSA_SPR0 0x0b25
  7. #define IDXD_MMIO_BAR 0
  8. #define IDXD_WQ_BAR 2
  9. #define IDXD_PORTAL_SIZE PAGE_SIZE
  10. /* MMIO Device BAR0 Registers */
  11. #define IDXD_VER_OFFSET 0x00
  12. #define IDXD_VER_MAJOR_MASK 0xf0
  13. #define IDXD_VER_MINOR_MASK 0x0f
  14. #define GET_IDXD_VER_MAJOR(x) (((x) & IDXD_VER_MAJOR_MASK) >> 4)
  15. #define GET_IDXD_VER_MINOR(x) ((x) & IDXD_VER_MINOR_MASK)
  16. union gen_cap_reg {
  17. struct {
  18. u64 block_on_fault:1;
  19. u64 overlap_copy:1;
  20. u64 cache_control_mem:1;
  21. u64 cache_control_cache:1;
  22. u64 rsvd:3;
  23. u64 int_handle_req:1;
  24. u64 dest_readback:1;
  25. u64 drain_readback:1;
  26. u64 rsvd2:6;
  27. u64 max_xfer_shift:5;
  28. u64 max_batch_shift:4;
  29. u64 max_ims_mult:6;
  30. u64 config_en:1;
  31. u64 max_descs_per_engine:8;
  32. u64 rsvd3:24;
  33. };
  34. u64 bits;
  35. } __packed;
  36. #define IDXD_GENCAP_OFFSET 0x10
  37. union wq_cap_reg {
  38. struct {
  39. u64 total_wq_size:16;
  40. u64 num_wqs:8;
  41. u64 wqcfg_size:4;
  42. u64 rsvd:20;
  43. u64 shared_mode:1;
  44. u64 dedicated_mode:1;
  45. u64 rsvd2:1;
  46. u64 priority:1;
  47. u64 occupancy:1;
  48. u64 occupancy_int:1;
  49. u64 rsvd3:10;
  50. };
  51. u64 bits;
  52. } __packed;
  53. #define IDXD_WQCAP_OFFSET 0x20
  54. #define IDXD_WQCFG_MIN 5
  55. union group_cap_reg {
  56. struct {
  57. u64 num_groups:8;
  58. u64 total_tokens:8;
  59. u64 token_en:1;
  60. u64 token_limit:1;
  61. u64 rsvd:46;
  62. };
  63. u64 bits;
  64. } __packed;
  65. #define IDXD_GRPCAP_OFFSET 0x30
  66. union engine_cap_reg {
  67. struct {
  68. u64 num_engines:8;
  69. u64 rsvd:56;
  70. };
  71. u64 bits;
  72. } __packed;
  73. #define IDXD_ENGCAP_OFFSET 0x38
  74. #define IDXD_OPCAP_NOOP 0x0001
  75. #define IDXD_OPCAP_BATCH 0x0002
  76. #define IDXD_OPCAP_MEMMOVE 0x0008
  77. struct opcap {
  78. u64 bits[4];
  79. };
  80. #define IDXD_OPCAP_OFFSET 0x40
  81. #define IDXD_TABLE_OFFSET 0x60
  82. union offsets_reg {
  83. struct {
  84. u64 grpcfg:16;
  85. u64 wqcfg:16;
  86. u64 msix_perm:16;
  87. u64 ims:16;
  88. u64 perfmon:16;
  89. u64 rsvd:48;
  90. };
  91. u64 bits[2];
  92. } __packed;
  93. #define IDXD_GENCFG_OFFSET 0x80
  94. union gencfg_reg {
  95. struct {
  96. u32 token_limit:8;
  97. u32 rsvd:4;
  98. u32 user_int_en:1;
  99. u32 rsvd2:19;
  100. };
  101. u32 bits;
  102. } __packed;
  103. #define IDXD_GENCTRL_OFFSET 0x88
  104. union genctrl_reg {
  105. struct {
  106. u32 softerr_int_en:1;
  107. u32 rsvd:31;
  108. };
  109. u32 bits;
  110. } __packed;
  111. #define IDXD_GENSTATS_OFFSET 0x90
  112. union gensts_reg {
  113. struct {
  114. u32 state:2;
  115. u32 reset_type:2;
  116. u32 rsvd:28;
  117. };
  118. u32 bits;
  119. } __packed;
  120. enum idxd_device_status_state {
  121. IDXD_DEVICE_STATE_DISABLED = 0,
  122. IDXD_DEVICE_STATE_ENABLED,
  123. IDXD_DEVICE_STATE_DRAIN,
  124. IDXD_DEVICE_STATE_HALT,
  125. };
  126. enum idxd_device_reset_type {
  127. IDXD_DEVICE_RESET_SOFTWARE = 0,
  128. IDXD_DEVICE_RESET_FLR,
  129. IDXD_DEVICE_RESET_WARM,
  130. IDXD_DEVICE_RESET_COLD,
  131. };
  132. #define IDXD_INTCAUSE_OFFSET 0x98
  133. #define IDXD_INTC_ERR 0x01
  134. #define IDXD_INTC_CMD 0x02
  135. #define IDXD_INTC_OCCUPY 0x04
  136. #define IDXD_INTC_PERFMON_OVFL 0x08
  137. #define IDXD_CMD_OFFSET 0xa0
  138. union idxd_command_reg {
  139. struct {
  140. u32 operand:20;
  141. u32 cmd:5;
  142. u32 rsvd:6;
  143. u32 int_req:1;
  144. };
  145. u32 bits;
  146. } __packed;
  147. enum idxd_cmd {
  148. IDXD_CMD_ENABLE_DEVICE = 1,
  149. IDXD_CMD_DISABLE_DEVICE,
  150. IDXD_CMD_DRAIN_ALL,
  151. IDXD_CMD_ABORT_ALL,
  152. IDXD_CMD_RESET_DEVICE,
  153. IDXD_CMD_ENABLE_WQ,
  154. IDXD_CMD_DISABLE_WQ,
  155. IDXD_CMD_DRAIN_WQ,
  156. IDXD_CMD_ABORT_WQ,
  157. IDXD_CMD_RESET_WQ,
  158. IDXD_CMD_DRAIN_PASID,
  159. IDXD_CMD_ABORT_PASID,
  160. IDXD_CMD_REQUEST_INT_HANDLE,
  161. };
  162. #define IDXD_CMDSTS_OFFSET 0xa8
  163. union cmdsts_reg {
  164. struct {
  165. u8 err;
  166. u16 result;
  167. u8 rsvd:7;
  168. u8 active:1;
  169. };
  170. u32 bits;
  171. } __packed;
  172. #define IDXD_CMDSTS_ACTIVE 0x80000000
  173. enum idxd_cmdsts_err {
  174. IDXD_CMDSTS_SUCCESS = 0,
  175. IDXD_CMDSTS_INVAL_CMD,
  176. IDXD_CMDSTS_INVAL_WQIDX,
  177. IDXD_CMDSTS_HW_ERR,
  178. /* enable device errors */
  179. IDXD_CMDSTS_ERR_DEV_ENABLED = 0x10,
  180. IDXD_CMDSTS_ERR_CONFIG,
  181. IDXD_CMDSTS_ERR_BUSMASTER_EN,
  182. IDXD_CMDSTS_ERR_PASID_INVAL,
  183. IDXD_CMDSTS_ERR_WQ_SIZE_ERANGE,
  184. IDXD_CMDSTS_ERR_GRP_CONFIG,
  185. IDXD_CMDSTS_ERR_GRP_CONFIG2,
  186. IDXD_CMDSTS_ERR_GRP_CONFIG3,
  187. IDXD_CMDSTS_ERR_GRP_CONFIG4,
  188. /* enable wq errors */
  189. IDXD_CMDSTS_ERR_DEV_NOTEN = 0x20,
  190. IDXD_CMDSTS_ERR_WQ_ENABLED,
  191. IDXD_CMDSTS_ERR_WQ_SIZE,
  192. IDXD_CMDSTS_ERR_WQ_PRIOR,
  193. IDXD_CMDSTS_ERR_WQ_MODE,
  194. IDXD_CMDSTS_ERR_BOF_EN,
  195. IDXD_CMDSTS_ERR_PASID_EN,
  196. IDXD_CMDSTS_ERR_MAX_BATCH_SIZE,
  197. IDXD_CMDSTS_ERR_MAX_XFER_SIZE,
  198. /* disable device errors */
  199. IDXD_CMDSTS_ERR_DIS_DEV_EN = 0x31,
  200. /* disable WQ, drain WQ, abort WQ, reset WQ */
  201. IDXD_CMDSTS_ERR_DEV_NOT_EN,
  202. /* request interrupt handle */
  203. IDXD_CMDSTS_ERR_INVAL_INT_IDX = 0x41,
  204. IDXD_CMDSTS_ERR_NO_HANDLE,
  205. };
  206. #define IDXD_SWERR_OFFSET 0xc0
  207. #define IDXD_SWERR_VALID 0x00000001
  208. #define IDXD_SWERR_OVERFLOW 0x00000002
  209. #define IDXD_SWERR_ACK (IDXD_SWERR_VALID | IDXD_SWERR_OVERFLOW)
  210. union sw_err_reg {
  211. struct {
  212. u64 valid:1;
  213. u64 overflow:1;
  214. u64 desc_valid:1;
  215. u64 wq_idx_valid:1;
  216. u64 batch:1;
  217. u64 fault_rw:1;
  218. u64 priv:1;
  219. u64 rsvd:1;
  220. u64 error:8;
  221. u64 wq_idx:8;
  222. u64 rsvd2:8;
  223. u64 operation:8;
  224. u64 pasid:20;
  225. u64 rsvd3:4;
  226. u64 batch_idx:16;
  227. u64 rsvd4:16;
  228. u64 invalid_flags:32;
  229. u64 fault_addr;
  230. u64 rsvd5;
  231. };
  232. u64 bits[4];
  233. } __packed;
  234. union msix_perm {
  235. struct {
  236. u32 rsvd:2;
  237. u32 ignore:1;
  238. u32 pasid_en:1;
  239. u32 rsvd2:8;
  240. u32 pasid:20;
  241. };
  242. u32 bits;
  243. } __packed;
  244. union group_flags {
  245. struct {
  246. u32 tc_a:3;
  247. u32 tc_b:3;
  248. u32 rsvd:1;
  249. u32 use_token_limit:1;
  250. u32 tokens_reserved:8;
  251. u32 rsvd2:4;
  252. u32 tokens_allowed:8;
  253. u32 rsvd3:4;
  254. };
  255. u32 bits;
  256. } __packed;
  257. struct grpcfg {
  258. u64 wqs[4];
  259. u64 engines;
  260. union group_flags flags;
  261. } __packed;
  262. union wqcfg {
  263. struct {
  264. /* bytes 0-3 */
  265. u16 wq_size;
  266. u16 rsvd;
  267. /* bytes 4-7 */
  268. u16 wq_thresh;
  269. u16 rsvd1;
  270. /* bytes 8-11 */
  271. u32 mode:1; /* shared or dedicated */
  272. u32 bof:1; /* block on fault */
  273. u32 rsvd2:2;
  274. u32 priority:4;
  275. u32 pasid:20;
  276. u32 pasid_en:1;
  277. u32 priv:1;
  278. u32 rsvd3:2;
  279. /* bytes 12-15 */
  280. u32 max_xfer_shift:5;
  281. u32 max_batch_shift:4;
  282. u32 rsvd4:23;
  283. /* bytes 16-19 */
  284. u16 occupancy_inth;
  285. u16 occupancy_table_sel:1;
  286. u16 rsvd5:15;
  287. /* bytes 20-23 */
  288. u16 occupancy_limit;
  289. u16 occupancy_int_en:1;
  290. u16 rsvd6:15;
  291. /* bytes 24-27 */
  292. u16 occupancy;
  293. u16 occupancy_int:1;
  294. u16 rsvd7:12;
  295. u16 mode_support:1;
  296. u16 wq_state:2;
  297. /* bytes 28-31 */
  298. u32 rsvd8;
  299. };
  300. u32 bits[8];
  301. } __packed;
  302. /*
  303. * This macro calculates the offset into the WQCFG register
  304. * idxd - struct idxd *
  305. * n - wq id
  306. * ofs - the index of the 32b dword for the config register
  307. *
  308. * The WQCFG register block is divided into groups per each wq. The n index
  309. * allows us to move to the register group that's for that particular wq.
  310. * Each register is 32bits. The ofs gives us the number of register to access.
  311. */
  312. #define WQCFG_OFFSET(_idxd_dev, n, ofs) \
  313. ({\
  314. typeof(_idxd_dev) __idxd_dev = (_idxd_dev); \
  315. (__idxd_dev)->wqcfg_offset + (n) * (__idxd_dev)->wqcfg_size + sizeof(u32) * (ofs); \
  316. })
  317. #define WQCFG_STRIDES(_idxd_dev) ((_idxd_dev)->wqcfg_size / sizeof(u32))
  318. #endif