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_FLAG_PREFIX(x) CONCATENATE(XE_RTP_FLAG_, x) | 57 #define __ADD_XE_RTP_RULE_PREFIX(x) CONCATENATE(XE_RTP_RULE_, 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_WR - Helper to write a value to the register, overriding all the bits 200 * @reg_: Register 201 * @val_: Value to set 202 * @...: Additional fields to override in the struct xe_rtp_action entry 203 * 204 * The correspondent notation in bspec is: 205 * 206 * REGNAME = VALUE 207 */ 208 #define XE_RTP_WR(reg_, val_, ...) \ 209 .action = { .reg = reg_, .clr_bits = ~0u, .set_bits = (val_), \ 210 .read_mask = (~0u), ##__VA_ARGS__ } 211 212 /** 213 * XE_RTP_SET - Set bits from @val_ in the register. 214 * @reg_: Register 215 * @val_: Bits to set in the register 216 * @...: Additional fields to override in the struct xe_rtp_action entry 217 * 218 * For masked registers this translates to a single write, while for other 219 * registers it's a RMW. The correspondent bspec notation is (example for bits 2 220 * and 5, but could be any): 221 * 222 * REGNAME[2] = 1 223 * REGNAME[5] = 1 224 */ 225 #define XE_RTP_SET(reg_, val_, ...) \ 226 .action = { .reg = reg_, .clr_bits = (val_), .set_bits = (val_), \ 227 .read_mask = (val_), ##__VA_ARGS__ } 228 229 /** 230 * XE_RTP_CLR: Clear bits from @val_ in the register. 231 * @reg_: Register 232 * @val_: Bits to clear in the register 233 * @...: Additional fields to override in the struct xe_rtp_action entry 234 * 235 * For masked registers this translates to a single write, while for other 236 * registers it's a RMW. The correspondent bspec notation is (example for bits 2 237 * and 5, but could be any): 238 * 239 * REGNAME[2] = 0 240 * REGNAME[5] = 0 241 */ 242 #define XE_RTP_CLR(reg_, val_, ...) \ 243 .action = { .reg = reg_, .clr_bits = (val_), .set_bits = 0, \ 244 .read_mask = (val_), ##__VA_ARGS__ } 245 246 /** 247 * XE_RTP_FIELD_SET: Set a bit range, defined by @mask_bits_, to the value in 248 * @reg_: Register 249 * @mask_bits_: Mask of bits to be changed in the register, forming a field 250 * @val_: Value to set in the field denoted by @mask_bits_ 251 * @...: Additional fields to override in the struct xe_rtp_action entry 252 * 253 * For masked registers this translates to a single write, while for other 254 * registers it's a RMW. The correspondent bspec notation is: 255 * 256 * REGNAME[<end>:<start>] = VALUE 257 */ 258 #define XE_RTP_FIELD_SET(reg_, mask_bits_, val_, ...) \ 259 .action = { .reg = reg_, .clr_bits = (mask_bits_), .set_bits = (val_),\ 260 .read_mask = (mask_bits_), ##__VA_ARGS__ } 261 262 #define XE_RTP_FIELD_SET_NO_READ_MASK(reg_, mask_bits_, val_, ...) \ 263 .action = { .reg = reg_, .clr_bits = (mask_bits_), .set_bits = (val_),\ 264 .read_mask = 0, ##__VA_ARGS__ } 265 266 /** 267 * XE_WHITELIST_REGISTER - Add register to userspace whitelist 268 * @reg_: Register 269 * @flags_: Whitelist-specific flags to set 270 * @...: Additional fields to override in the struct xe_rtp_action entry 271 * 272 * Add a register to the whitelist, allowing userspace to modify the ster with 273 * regular user privileges. 274 */ 275 #define XE_WHITELIST_REGISTER(reg_, flags_, ...) \ 276 /* TODO fail build if ((flags) & ~(RING_FORCE_TO_NONPRIV_MASK_VALID)) */\ 277 .action = { .reg = reg_, .set_bits = (flags_), \ 278 .clr_bits = RING_FORCE_TO_NONPRIV_MASK_VALID, \ 279 ##__VA_ARGS__ } 280 281 /** 282 * XE_RTP_NAME - Helper to set the name in xe_rtp_entry 283 * @s_: Name describing this rule, often a HW-specific number 284 * 285 * TODO: maybe move this behind a debug config? 286 */ 287 #define XE_RTP_NAME(s_) .name = (s_) 288 289 /** 290 * XE_RTP_FLAG - Helper to add multiple flags to a struct xe_rtp_action entry 291 * @f1_: Last part of a ``XE_RTP_FLAG_*`` 292 * @...: Additional flags, defined like @f1_ 293 * 294 * Helper to automatically add a ``XE_RTP_FLAG_`` prefix to @f1_ so it can be 295 * easily used to define struct xe_rtp_action entries. Example: 296 * 297 * .. code-block:: c 298 * 299 * const struct xe_rtp_entry wa_entries[] = { 300 * ... 301 * { XE_RTP_NAME("test-entry"), 302 * XE_RTP_FLAG(FOREACH_ENGINE, MASKED_REG), 303 * ... 304 * }, 305 * ... 306 * }; 307 */ 308 #define XE_RTP_FLAG(f1_, ...) \ 309 .flags = (CALL_FOR_EACH(__ADD_XE_RTP_FLAG_PREFIX, f1_, ##__VA_ARGS__) 0) 310 311 /** 312 * XE_RTP_RULES - Helper to set multiple rules to a struct xe_rtp_entry entry 313 * @r1: Last part of XE_RTP_MATCH_* 314 * @...: Additional rules, defined like @r1 315 * 316 * At least one rule is needed and up to 4 are supported. Multiple rules are 317 * AND'ed together, i.e. all the rules must evaluate to true for the entry to 318 * be processed. See XE_RTP_MATCH_* for the possible match rules. Example: 319 * 320 * .. code-block:: c 321 * 322 * const struct xe_rtp_entry wa_entries[] = { 323 * ... 324 * { XE_RTP_NAME("test-entry"), 325 * XE_RTP_RULES(SUBPLATFORM(DG2, G10), STEP(A0, B0)), 326 * ... 327 * }, 328 * ... 329 * }; 330 */ 331 #define XE_RTP_RULES(r1, ...) \ 332 .n_rules = COUNT_ARGS(r1, ##__VA_ARGS__), \ 333 .rules = (struct xe_rtp_rule[]) { \ 334 CALL_FOR_EACH(__ADD_XE_RTP_RULE_PREFIX, r1, ##__VA_ARGS__) \ 335 } 336 337 void xe_rtp_process(const struct xe_rtp_entry *entries, struct xe_reg_sr *sr, 338 struct xe_gt *gt, struct xe_hw_engine *hwe); 339 340 #endif 341