1 /* SPDX-License-Identifier: MIT */ 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #ifndef _XE_RTP_ 7 #define _XE_RTP_ 8 9 #include <linux/xarray.h> 10 #include <linux/types.h> 11 12 #include "xe_rtp_types.h" 13 14 #include "i915_reg_defs.h" 15 16 /* 17 * Register table poke infrastructure 18 */ 19 20 struct xe_hw_engine; 21 struct xe_gt; 22 struct xe_reg_sr; 23 24 /* 25 * Helper macros - not to be used outside this header. 26 */ 27 /* This counts to 12. Any more, it will return 13th argument. */ 28 #define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n 29 #define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) 30 31 #define __CONCAT(a, b) a ## b 32 #define CONCATENATE(a, b) __CONCAT(a, b) 33 34 #define __CALL_FOR_EACH_1(MACRO_, x, ...) MACRO_(x) 35 #define __CALL_FOR_EACH_2(MACRO_, x, ...) \ 36 MACRO_(x) __CALL_FOR_EACH_1(MACRO_, ##__VA_ARGS__) 37 #define __CALL_FOR_EACH_3(MACRO_, x, ...) \ 38 MACRO_(x) __CALL_FOR_EACH_2(MACRO_, ##__VA_ARGS__) 39 #define __CALL_FOR_EACH_4(MACRO_, x, ...) \ 40 MACRO_(x) __CALL_FOR_EACH_3(MACRO_, ##__VA_ARGS__) 41 42 #define _CALL_FOR_EACH(NARGS_, MACRO_, x, ...) \ 43 CONCATENATE(__CALL_FOR_EACH_, NARGS_)(MACRO_, x, ##__VA_ARGS__) 44 #define CALL_FOR_EACH(MACRO_, x, ...) \ 45 _CALL_FOR_EACH(COUNT_ARGS(x, ##__VA_ARGS__), MACRO_, x, ##__VA_ARGS__) 46 47 #define _XE_RTP_REG(x_) (x_), XE_RTP_REG_REGULAR 48 #define _XE_RTP_MCR_REG(x_) (x_), XE_RTP_REG_MCR 49 50 /* 51 * Helper macros for concatenating prefix - do not use them directly outside 52 * this header 53 */ 54 #define __ADD_XE_RTP_ENTRY_FLAG_PREFIX(x) CONCATENATE(XE_RTP_ENTRY_FLAG_, x) | 55 #define __ADD_XE_RTP_ACTION_FLAG_PREFIX(x) CONCATENATE(XE_RTP_ACTION_FLAG_, x) | 56 #define __ADD_XE_RTP_RULE_PREFIX(x) CONCATENATE(XE_RTP_RULE_, x) , 57 #define __ADD_XE_RTP_ACTION_PREFIX(x) CONCATENATE(XE_RTP_ACTION_, x) , 58 59 /* 60 * Macros to encode rules to match against platform, IP version, stepping, etc. 61 * Shouldn't be used directly - see XE_RTP_RULES() 62 */ 63 64 #define _XE_RTP_RULE_PLATFORM(plat__) \ 65 { .match_type = XE_RTP_MATCH_PLATFORM, .platform = plat__ } 66 67 #define _XE_RTP_RULE_SUBPLATFORM(plat__, sub__) \ 68 { .match_type = XE_RTP_MATCH_SUBPLATFORM, \ 69 .platform = plat__, .subplatform = sub__ } 70 71 #define _XE_RTP_RULE_STEP(start__, end__) \ 72 { .match_type = XE_RTP_MATCH_STEP, \ 73 .step_start = start__, .step_end = end__ } 74 75 #define _XE_RTP_RULE_ENGINE_CLASS(cls__) \ 76 { .match_type = XE_RTP_MATCH_ENGINE_CLASS, \ 77 .engine_class = (cls__) } 78 79 /** 80 * XE_RTP_RULE_PLATFORM - Create rule matching platform 81 * @plat_: platform to match 82 * 83 * Refer to XE_RTP_RULES() for expected usage. 84 */ 85 #define XE_RTP_RULE_PLATFORM(plat_) \ 86 _XE_RTP_RULE_PLATFORM(XE_##plat_) 87 88 /** 89 * XE_RTP_RULE_SUBPLATFORM - Create rule matching platform and sub-platform 90 * @plat_: platform to match 91 * @sub_: sub-platform to match 92 * 93 * Refer to XE_RTP_RULES() for expected usage. 94 */ 95 #define XE_RTP_RULE_SUBPLATFORM(plat_, sub_) \ 96 _XE_RTP_RULE_SUBPLATFORM(XE_##plat_, XE_SUBPLATFORM_##plat_##_##sub_) 97 98 /** 99 * XE_RTP_RULE_STEP - Create rule matching platform stepping 100 * @start_: First stepping matching the rule 101 * @end_: First stepping that does not match the rule 102 * 103 * Note that the range matching this rule [ @start_, @end_ ), i.e. inclusive on 104 * the left, exclusive on the right. 105 * 106 * Refer to XE_RTP_RULES() for expected usage. 107 */ 108 #define XE_RTP_RULE_STEP(start_, end_) \ 109 _XE_RTP_RULE_STEP(STEP_##start_, STEP_##end_) 110 111 /** 112 * XE_RTP_RULE_ENGINE_CLASS - Create rule matching an engine class 113 * @cls_: Engine class to match 114 * 115 * Refer to XE_RTP_RULES() for expected usage. 116 */ 117 #define XE_RTP_RULE_ENGINE_CLASS(cls_) \ 118 _XE_RTP_RULE_ENGINE_CLASS(XE_ENGINE_CLASS_##cls_) 119 120 /** 121 * XE_RTP_RULE_FUNC - Create rule using callback function for match 122 * @func__: Function to call to decide if rule matches 123 * 124 * This allows more complex checks to be performed. The ``XE_RTP`` 125 * infrastructure will simply call the function @func_ passed to decide if this 126 * rule matches the device. 127 * 128 * Refer to XE_RTP_RULES() for expected usage. 129 */ 130 #define XE_RTP_RULE_FUNC(func__) \ 131 { .match_type = XE_RTP_MATCH_FUNC, \ 132 .match_func = (func__) } 133 134 /** 135 * XE_RTP_RULE_GRAPHICS_VERSION - Create rule matching graphics version 136 * @ver__: Graphics IP version to match 137 * 138 * Refer to XE_RTP_RULES() for expected usage. 139 */ 140 #define XE_RTP_RULE_GRAPHICS_VERSION(ver__) \ 141 { .match_type = XE_RTP_MATCH_GRAPHICS_VERSION, \ 142 .ver_start = ver__, } 143 144 /** 145 * XE_RTP_RULE_GRAPHICS_VERSION_RANGE - Create rule matching a range of graphics version 146 * @ver_start__: First graphics IP version to match 147 * @ver_end__: Last graphics IP version to match 148 * 149 * Note that the range matching this rule is [ @ver_start__, @ver_end__ ], i.e. 150 * inclusive on boths sides 151 * 152 * Refer to XE_RTP_RULES() for expected usage. 153 */ 154 #define XE_RTP_RULE_GRAPHICS_VERSION_RANGE(ver_start__, ver_end__) \ 155 { .match_type = XE_RTP_MATCH_GRAPHICS_VERSION_RANGE, \ 156 .ver_start = ver_start__, .ver_end = ver_end__, } 157 158 /** 159 * XE_RTP_RULE_MEDIA_VERSION - Create rule matching media version 160 * @ver__: Graphics IP version to match 161 * 162 * Refer to XE_RTP_RULES() for expected usage. 163 */ 164 #define XE_RTP_RULE_MEDIA_VERSION(ver__) \ 165 { .match_type = XE_RTP_MATCH_MEDIA_VERSION, \ 166 .ver_start = ver__, } 167 168 /** 169 * XE_RTP_RULE_MEDIA_VERSION_RANGE - Create rule matching a range of media version 170 * @ver_start__: First media IP version to match 171 * @ver_end__: Last media IP version to match 172 * 173 * Note that the range matching this rule is [ @ver_start__, @ver_end__ ], i.e. 174 * inclusive on boths sides 175 * 176 * Refer to XE_RTP_RULES() for expected usage. 177 */ 178 #define XE_RTP_RULE_MEDIA_VERSION_RANGE(ver_start__, ver_end__) \ 179 { .match_type = XE_RTP_MATCH_MEDIA_VERSION_RANGE, \ 180 .ver_start = ver_start__, .ver_end = ver_end__, } 181 182 /** 183 * XE_RTP_RULE_IS_INTEGRATED - Create a rule matching integrated graphics devices 184 * 185 * Refer to XE_RTP_RULES() for expected usage. 186 */ 187 #define XE_RTP_RULE_IS_INTEGRATED \ 188 { .match_type = XE_RTP_MATCH_INTEGRATED } 189 190 /** 191 * XE_RTP_RULE_IS_DISCRETE - Create a rule matching discrete graphics devices 192 * 193 * Refer to XE_RTP_RULES() for expected usage. 194 */ 195 #define XE_RTP_RULE_IS_DISCRETE \ 196 { .match_type = XE_RTP_MATCH_DISCRETE } 197 198 /** 199 * XE_RTP_ACTION_WR - Helper to write a value to the register, overriding all 200 * the bits 201 * @reg_: Register 202 * @reg_type_: Register type - automatically expanded by MCR_REG/_MMIO 203 * @val_: Value to set 204 * @...: Additional fields to override in the struct xe_rtp_action entry 205 * 206 * The correspondent notation in bspec is: 207 * 208 * REGNAME = VALUE 209 */ 210 #define XE_RTP_ACTION_WR(reg_, reg_type_, val_, ...) \ 211 { .reg = (reg_), .reg_type = (reg_type_), \ 212 .clr_bits = ~0u, .set_bits = (val_), \ 213 .read_mask = (~0u), ##__VA_ARGS__ } 214 215 /** 216 * XE_RTP_ACTION_SET - Set bits from @val_ in the register. 217 * @reg_: Register 218 * @reg_type_: Register type - automatically expanded by MCR_REG/_MMIO 219 * @val_: Bits to set in the register 220 * @...: Additional fields to override in the struct xe_rtp_action entry 221 * 222 * For masked registers this translates to a single write, while for other 223 * registers it's a RMW. The correspondent bspec notation is (example for bits 2 224 * and 5, but could be any): 225 * 226 * REGNAME[2] = 1 227 * REGNAME[5] = 1 228 */ 229 #define XE_RTP_ACTION_SET(reg_, reg_type_, val_, ...) \ 230 { .reg = (reg_), .reg_type = (reg_type_), \ 231 .clr_bits = (val_), .set_bits = (val_), \ 232 .read_mask = (val_), ##__VA_ARGS__ } 233 234 /** 235 * XE_RTP_ACTION_CLR: Clear bits from @val_ in the register. 236 * @reg_: Register 237 * @reg_type_: Register type - automatically expanded by MCR_REG/_MMIO 238 * @val_: Bits to clear in the register 239 * @...: Additional fields to override in the struct xe_rtp_action entry 240 * 241 * For masked registers this translates to a single write, while for other 242 * registers it's a RMW. The correspondent bspec notation is (example for bits 2 243 * and 5, but could be any): 244 * 245 * REGNAME[2] = 0 246 * REGNAME[5] = 0 247 */ 248 #define XE_RTP_ACTION_CLR(reg_, reg_type_, val_, ...) \ 249 { .reg = (reg_), .reg_type = (reg_type_), \ 250 .clr_bits = (val_), .set_bits = 0, \ 251 .read_mask = (val_), ##__VA_ARGS__ } 252 253 /** 254 * XE_RTP_ACTION_FIELD_SET: Set a bit range 255 * @reg_: Register 256 * @reg_type_: Register type - automatically expanded by MCR_REG/_MMIO 257 * @mask_bits_: Mask of bits to be changed in the register, forming a field 258 * @val_: Value to set in the field denoted by @mask_bits_ 259 * @...: Additional fields to override in the struct xe_rtp_action entry 260 * 261 * For masked registers this translates to a single write, while for other 262 * registers it's a RMW. The correspondent bspec notation is: 263 * 264 * REGNAME[<end>:<start>] = VALUE 265 */ 266 #define XE_RTP_ACTION_FIELD_SET(reg_, reg_type_, mask_bits_, val_, ...) \ 267 { .reg = (reg_), .reg_type = (reg_type_), \ 268 .clr_bits = (mask_bits_), .set_bits = (val_), \ 269 .read_mask = (mask_bits_), ##__VA_ARGS__ } 270 271 #define XE_RTP_ACTION_FIELD_SET_NO_READ_MASK(reg_, reg_type_, mask_bits_, val_, ...) \ 272 { .reg = (reg_), .reg_type = (reg_type_), \ 273 .clr_bits = (mask_bits_), .set_bits = (val_), \ 274 .read_mask = 0, ##__VA_ARGS__ } 275 276 /** 277 * XE_RTP_ACTION_WHITELIST - Add register to userspace whitelist 278 * @reg_: Register 279 * @reg_type_: Register type - automatically expanded by MCR_REG/_MMIO 280 * @val_: Whitelist-specific flags to set 281 * @...: Additional fields to override in the struct xe_rtp_action entry 282 * 283 * Add a register to the whitelist, allowing userspace to modify the ster with 284 * regular user privileges. 285 */ 286 #define XE_RTP_ACTION_WHITELIST(reg_, reg_type_, val_, ...) \ 287 /* TODO fail build if ((flags) & ~(RING_FORCE_TO_NONPRIV_MASK_VALID)) */\ 288 { .reg = (reg_), .reg_type = (reg_type_), .set_bits = (val_), \ 289 .clr_bits = RING_FORCE_TO_NONPRIV_MASK_VALID, \ 290 ##__VA_ARGS__ } 291 292 /** 293 * XE_RTP_NAME - Helper to set the name in xe_rtp_entry 294 * @s_: Name describing this rule, often a HW-specific number 295 * 296 * TODO: maybe move this behind a debug config? 297 */ 298 #define XE_RTP_NAME(s_) .name = (s_) 299 300 /** 301 * XE_RTP_ENTRY_FLAG - Helper to add multiple flags to a struct xe_rtp_entry 302 * @f1_: Last part of a ``XE_RTP_ENTRY_FLAG_*`` 303 * @...: Additional flags, defined like @f1_ 304 * 305 * Helper to automatically add a ``XE_RTP_ENTRY_FLAG_`` prefix to @f1_ so it can 306 * be easily used to define struct xe_rtp_action entries. Example: 307 * 308 * .. code-block:: c 309 * 310 * const struct xe_rtp_entry wa_entries[] = { 311 * ... 312 * { XE_RTP_NAME("test-entry"), 313 * ... 314 * XE_RTP_ENTRY_FLAG(FOREACH_ENGINE), 315 * ... 316 * }, 317 * ... 318 * }; 319 */ 320 #define XE_RTP_ENTRY_FLAG(f1_, ...) \ 321 .flags = (CALL_FOR_EACH(__ADD_XE_RTP_ENTRY_FLAG_PREFIX, f1_, ##__VA_ARGS__) 0) 322 323 /** 324 * XE_RTP_ACTION_FLAG - Helper to add multiple flags to a struct xe_rtp_action 325 * @f1_: Last part of a ``XE_RTP_ENTRY_*`` 326 * @...: Additional flags, defined like @f1_ 327 * 328 * Helper to automatically add a ``XE_RTP_ACTION_FLAG_`` prefix to @f1_ so it 329 * can be easily used to define struct xe_rtp_action entries. Example: 330 * 331 * .. code-block:: c 332 * 333 * const struct xe_rtp_entry wa_entries[] = { 334 * ... 335 * { XE_RTP_NAME("test-entry"), 336 * ... 337 * XE_RTP_ACTION_SET(..., XE_RTP_ACTION_FLAG(FOREACH_ENGINE)), 338 * ... 339 * }, 340 * ... 341 * }; 342 */ 343 #define XE_RTP_ACTION_FLAG(f1_, ...) \ 344 .flags = (CALL_FOR_EACH(__ADD_XE_RTP_ACTION_FLAG_PREFIX, f1_, ##__VA_ARGS__) 0) 345 346 /** 347 * XE_RTP_RULES - Helper to set multiple rules to a struct xe_rtp_entry entry 348 * @r1: Last part of XE_RTP_MATCH_* 349 * @...: Additional rules, defined like @r1 350 * 351 * At least one rule is needed and up to 4 are supported. Multiple rules are 352 * AND'ed together, i.e. all the rules must evaluate to true for the entry to 353 * be processed. See XE_RTP_MATCH_* for the possible match rules. Example: 354 * 355 * .. code-block:: c 356 * 357 * const struct xe_rtp_entry wa_entries[] = { 358 * ... 359 * { XE_RTP_NAME("test-entry"), 360 * XE_RTP_RULES(SUBPLATFORM(DG2, G10), STEP(A0, B0)), 361 * ... 362 * }, 363 * ... 364 * }; 365 */ 366 #define XE_RTP_RULES(r1, ...) \ 367 .n_rules = COUNT_ARGS(r1, ##__VA_ARGS__), \ 368 .rules = (struct xe_rtp_rule[]) { \ 369 CALL_FOR_EACH(__ADD_XE_RTP_RULE_PREFIX, r1, ##__VA_ARGS__) \ 370 } 371 372 /** 373 * XE_RTP_ACTIONS - Helper to set multiple actions to a struct xe_rtp_entry 374 * @a1: Action to take. Last part of XE_RTP_ACTION_* 375 * @...: Additional rules, defined like @r1 376 * 377 * At least one rule is needed and up to 4 are supported. Multiple rules are 378 * AND'ed together, i.e. all the rules must evaluate to true for the entry to 379 * be processed. See XE_RTP_MATCH_* for the possible match rules. Example: 380 * 381 * .. code-block:: c 382 * 383 * const struct xe_rtp_entry wa_entries[] = { 384 * ... 385 * { XE_RTP_NAME("test-entry"), 386 * XE_RTP_RULES(...), 387 * XE_RTP_ACTIONS(SET(..), SET(...), CLR(...)), 388 * ... 389 * }, 390 * ... 391 * }; 392 */ 393 #define XE_RTP_ACTIONS(a1, ...) \ 394 .n_actions = COUNT_ARGS(a1, ##__VA_ARGS__), \ 395 .actions = (struct xe_rtp_action[]) { \ 396 CALL_FOR_EACH(__ADD_XE_RTP_ACTION_PREFIX, a1, ##__VA_ARGS__) \ 397 } 398 399 void xe_rtp_process(const struct xe_rtp_entry *entries, struct xe_reg_sr *sr, 400 struct xe_gt *gt, struct xe_hw_engine *hwe); 401 402 #endif 403