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