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/types.h> 10 #include <linux/xarray.h> 11 12 #define _XE_RTP_INCLUDE_PRIVATE_HELPERS 13 14 #include "xe_rtp_helpers.h" 15 #include "xe_rtp_types.h" 16 17 #undef _XE_RTP_INCLUDE_PRIVATE_HELPERS 18 19 /* 20 * Register table poke infrastructure 21 */ 22 23 struct xe_hw_engine; 24 struct xe_gt; 25 struct xe_reg_sr; 26 27 /* 28 * Macros to encode rules to match against platform, IP version, stepping, etc. 29 * Shouldn't be used directly - see XE_RTP_RULES() 30 */ 31 #define _XE_RTP_RULE_PLATFORM(plat__) \ 32 { .match_type = XE_RTP_MATCH_PLATFORM, .platform = plat__ } 33 34 #define _XE_RTP_RULE_SUBPLATFORM(plat__, sub__) \ 35 { .match_type = XE_RTP_MATCH_SUBPLATFORM, \ 36 .platform = plat__, .subplatform = sub__ } 37 38 #define _XE_RTP_RULE_GRAPHICS_STEP(start__, end__) \ 39 { .match_type = XE_RTP_MATCH_GRAPHICS_STEP, \ 40 .step_start = start__, .step_end = end__ } 41 42 #define _XE_RTP_RULE_MEDIA_STEP(start__, end__) \ 43 { .match_type = XE_RTP_MATCH_MEDIA_STEP, \ 44 .step_start = start__, .step_end = end__ } 45 46 #define _XE_RTP_RULE_ENGINE_CLASS(cls__) \ 47 { .match_type = XE_RTP_MATCH_ENGINE_CLASS, \ 48 .engine_class = (cls__) } 49 50 /** 51 * XE_RTP_RULE_PLATFORM - Create rule matching platform 52 * @plat_: platform to match 53 * 54 * Refer to XE_RTP_RULES() for expected usage. 55 */ 56 #define XE_RTP_RULE_PLATFORM(plat_) \ 57 _XE_RTP_RULE_PLATFORM(XE_##plat_) 58 59 /** 60 * XE_RTP_RULE_SUBPLATFORM - Create rule matching platform and sub-platform 61 * @plat_: platform to match 62 * @sub_: sub-platform to match 63 * 64 * Refer to XE_RTP_RULES() for expected usage. 65 */ 66 #define XE_RTP_RULE_SUBPLATFORM(plat_, sub_) \ 67 _XE_RTP_RULE_SUBPLATFORM(XE_##plat_, XE_SUBPLATFORM_##plat_##_##sub_) 68 69 /** 70 * XE_RTP_RULE_GRAPHICS_STEP - Create rule matching graphics stepping 71 * @start_: First stepping matching the rule 72 * @end_: First stepping that does not match the rule 73 * 74 * Note that the range matching this rule is [ @start_, @end_ ), i.e. inclusive 75 * on the left, exclusive on the right. 76 * 77 * Refer to XE_RTP_RULES() for expected usage. 78 */ 79 #define XE_RTP_RULE_GRAPHICS_STEP(start_, end_) \ 80 _XE_RTP_RULE_GRAPHICS_STEP(STEP_##start_, STEP_##end_) 81 82 /** 83 * XE_RTP_RULE_MEDIA_STEP - Create rule matching media stepping 84 * @start_: First stepping matching the rule 85 * @end_: First stepping that does not match the rule 86 * 87 * Note that the range matching this rule is [ @start_, @end_ ), i.e. inclusive 88 * on the left, exclusive on the right. 89 * 90 * Refer to XE_RTP_RULES() for expected usage. 91 */ 92 #define XE_RTP_RULE_MEDIA_STEP(start_, end_) \ 93 _XE_RTP_RULE_MEDIA_STEP(STEP_##start_, STEP_##end_) 94 95 /** 96 * XE_RTP_RULE_ENGINE_CLASS - Create rule matching an engine class 97 * @cls_: Engine class to match 98 * 99 * Refer to XE_RTP_RULES() for expected usage. 100 */ 101 #define XE_RTP_RULE_ENGINE_CLASS(cls_) \ 102 _XE_RTP_RULE_ENGINE_CLASS(XE_ENGINE_CLASS_##cls_) 103 104 /** 105 * XE_RTP_RULE_FUNC - Create rule using callback function for match 106 * @func__: Function to call to decide if rule matches 107 * 108 * This allows more complex checks to be performed. The ``XE_RTP`` 109 * infrastructure will simply call the function @func_ passed to decide if this 110 * rule matches the device. 111 * 112 * Refer to XE_RTP_RULES() for expected usage. 113 */ 114 #define XE_RTP_RULE_FUNC(func__) \ 115 { .match_type = XE_RTP_MATCH_FUNC, \ 116 .match_func = (func__) } 117 118 /** 119 * XE_RTP_RULE_GRAPHICS_VERSION - Create rule matching graphics version 120 * @ver__: Graphics IP version to match 121 * 122 * Refer to XE_RTP_RULES() for expected usage. 123 */ 124 #define XE_RTP_RULE_GRAPHICS_VERSION(ver__) \ 125 { .match_type = XE_RTP_MATCH_GRAPHICS_VERSION, \ 126 .ver_start = ver__, } 127 128 /** 129 * XE_RTP_RULE_GRAPHICS_VERSION_RANGE - Create rule matching a range of graphics version 130 * @ver_start__: First graphics IP version to match 131 * @ver_end__: Last graphics IP version to match 132 * 133 * Note that the range matching this rule is [ @ver_start__, @ver_end__ ], i.e. 134 * inclusive on boths sides 135 * 136 * Refer to XE_RTP_RULES() for expected usage. 137 */ 138 #define XE_RTP_RULE_GRAPHICS_VERSION_RANGE(ver_start__, ver_end__) \ 139 { .match_type = XE_RTP_MATCH_GRAPHICS_VERSION_RANGE, \ 140 .ver_start = ver_start__, .ver_end = ver_end__, } 141 142 /** 143 * XE_RTP_RULE_MEDIA_VERSION - Create rule matching media version 144 * @ver__: Graphics IP version to match 145 * 146 * Refer to XE_RTP_RULES() for expected usage. 147 */ 148 #define XE_RTP_RULE_MEDIA_VERSION(ver__) \ 149 { .match_type = XE_RTP_MATCH_MEDIA_VERSION, \ 150 .ver_start = ver__, } 151 152 /** 153 * XE_RTP_RULE_MEDIA_VERSION_RANGE - Create rule matching a range of media version 154 * @ver_start__: First media IP version to match 155 * @ver_end__: Last media IP version to match 156 * 157 * Note that the range matching this rule is [ @ver_start__, @ver_end__ ], i.e. 158 * inclusive on boths sides 159 * 160 * Refer to XE_RTP_RULES() for expected usage. 161 */ 162 #define XE_RTP_RULE_MEDIA_VERSION_RANGE(ver_start__, ver_end__) \ 163 { .match_type = XE_RTP_MATCH_MEDIA_VERSION_RANGE, \ 164 .ver_start = ver_start__, .ver_end = ver_end__, } 165 166 /** 167 * XE_RTP_RULE_IS_INTEGRATED - Create a rule matching integrated graphics devices 168 * 169 * Refer to XE_RTP_RULES() for expected usage. 170 */ 171 #define XE_RTP_RULE_IS_INTEGRATED \ 172 { .match_type = XE_RTP_MATCH_INTEGRATED } 173 174 /** 175 * XE_RTP_RULE_IS_DISCRETE - Create a rule matching discrete graphics devices 176 * 177 * Refer to XE_RTP_RULES() for expected usage. 178 */ 179 #define XE_RTP_RULE_IS_DISCRETE \ 180 { .match_type = XE_RTP_MATCH_DISCRETE } 181 182 /** 183 * XE_RTP_ACTION_WR - Helper to write a value to the register, overriding all 184 * the bits 185 * @reg_: Register 186 * @val_: Value to set 187 * @...: Additional fields to override in the struct xe_rtp_action entry 188 * 189 * The correspondent notation in bspec is: 190 * 191 * REGNAME = VALUE 192 */ 193 #define XE_RTP_ACTION_WR(reg_, val_, ...) \ 194 { .reg = XE_RTP_DROP_CAST(reg_), \ 195 .clr_bits = ~0u, .set_bits = (val_), \ 196 .read_mask = (~0u), ##__VA_ARGS__ } 197 198 /** 199 * XE_RTP_ACTION_SET - Set bits from @val_ in the register. 200 * @reg_: Register 201 * @val_: Bits to set in the register 202 * @...: Additional fields to override in the struct xe_rtp_action entry 203 * 204 * For masked registers this translates to a single write, while for other 205 * registers it's a RMW. The correspondent bspec notation is (example for bits 2 206 * and 5, but could be any): 207 * 208 * REGNAME[2] = 1 209 * REGNAME[5] = 1 210 */ 211 #define XE_RTP_ACTION_SET(reg_, val_, ...) \ 212 { .reg = XE_RTP_DROP_CAST(reg_), \ 213 .clr_bits = val_, .set_bits = val_, \ 214 .read_mask = val_, ##__VA_ARGS__ } 215 216 /** 217 * XE_RTP_ACTION_CLR: Clear bits from @val_ in the register. 218 * @reg_: Register 219 * @val_: Bits to clear 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] = 0 227 * REGNAME[5] = 0 228 */ 229 #define XE_RTP_ACTION_CLR(reg_, val_, ...) \ 230 { .reg = XE_RTP_DROP_CAST(reg_), \ 231 .clr_bits = val_, .set_bits = 0, \ 232 .read_mask = val_, ##__VA_ARGS__ } 233 234 /** 235 * XE_RTP_ACTION_FIELD_SET: Set a bit range 236 * @reg_: Register 237 * @mask_bits_: Mask of bits to be changed in the register, forming a field 238 * @val_: Value to set in the field denoted by @mask_bits_ 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: 243 * 244 * REGNAME[<end>:<start>] = VALUE 245 */ 246 #define XE_RTP_ACTION_FIELD_SET(reg_, mask_bits_, val_, ...) \ 247 { .reg = XE_RTP_DROP_CAST(reg_), \ 248 .clr_bits = mask_bits_, .set_bits = val_, \ 249 .read_mask = mask_bits_, ##__VA_ARGS__ } 250 251 #define XE_RTP_ACTION_FIELD_SET_NO_READ_MASK(reg_, mask_bits_, val_, ...) \ 252 { .reg = XE_RTP_DROP_CAST(reg_), \ 253 .clr_bits = (mask_bits_), .set_bits = (val_), \ 254 .read_mask = 0, ##__VA_ARGS__ } 255 256 /** 257 * XE_RTP_ACTION_WHITELIST - Add register to userspace whitelist 258 * @reg_: Register 259 * @val_: Whitelist-specific flags to set 260 * @...: Additional fields to override in the struct xe_rtp_action entry 261 * 262 * Add a register to the whitelist, allowing userspace to modify the ster with 263 * regular user privileges. 264 */ 265 #define XE_RTP_ACTION_WHITELIST(reg_, val_, ...) \ 266 /* TODO fail build if ((flags) & ~(RING_FORCE_TO_NONPRIV_MASK_VALID)) */\ 267 { .reg = XE_RTP_DROP_CAST(reg_), \ 268 .set_bits = val_, \ 269 .clr_bits = RING_FORCE_TO_NONPRIV_MASK_VALID, \ 270 ##__VA_ARGS__ } 271 272 /** 273 * XE_RTP_NAME - Helper to set the name in xe_rtp_entry 274 * @s_: Name describing this rule, often a HW-specific number 275 * 276 * TODO: maybe move this behind a debug config? 277 */ 278 #define XE_RTP_NAME(s_) .name = (s_) 279 280 /** 281 * XE_RTP_ENTRY_FLAG - Helper to add multiple flags to a struct xe_rtp_entry_sr 282 * @...: Entry flags, without the ``XE_RTP_ENTRY_FLAG_`` prefix 283 * 284 * Helper to automatically add a ``XE_RTP_ENTRY_FLAG_`` prefix to the flags 285 * when defining struct xe_rtp_entry entries. Example: 286 * 287 * .. code-block:: c 288 * 289 * const struct xe_rtp_entry_sr wa_entries[] = { 290 * ... 291 * { XE_RTP_NAME("test-entry"), 292 * ... 293 * XE_RTP_ENTRY_FLAG(FOREACH_ENGINE), 294 * ... 295 * }, 296 * ... 297 * }; 298 */ 299 #define XE_RTP_ENTRY_FLAG(...) \ 300 .flags = (XE_RTP_PASTE_FOREACH(ENTRY_FLAG_, BITWISE_OR, (__VA_ARGS__))) 301 302 /** 303 * XE_RTP_ACTION_FLAG - Helper to add multiple flags to a struct xe_rtp_action 304 * @...: Action flags, without the ``XE_RTP_ACTION_FLAG_`` prefix 305 * 306 * Helper to automatically add a ``XE_RTP_ACTION_FLAG_`` prefix to the flags 307 * when defining struct xe_rtp_action entries. Example: 308 * 309 * .. code-block:: c 310 * 311 * const struct xe_rtp_entry_sr wa_entries[] = { 312 * ... 313 * { XE_RTP_NAME("test-entry"), 314 * ... 315 * XE_RTP_ACTION_SET(..., XE_RTP_ACTION_FLAG(FOREACH_ENGINE)), 316 * ... 317 * }, 318 * ... 319 * }; 320 */ 321 #define XE_RTP_ACTION_FLAG(...) \ 322 .flags = (XE_RTP_PASTE_FOREACH(ACTION_FLAG_, BITWISE_OR, (__VA_ARGS__))) 323 324 /** 325 * XE_RTP_RULES - Helper to set multiple rules to a struct xe_rtp_entry_sr entry 326 * @...: Rules 327 * 328 * At least one rule is needed and up to 4 are supported. Multiple rules are 329 * AND'ed together, i.e. all the rules must evaluate to true for the entry to 330 * be processed. See XE_RTP_MATCH_* for the possible match rules. Example: 331 * 332 * .. code-block:: c 333 * 334 * const struct xe_rtp_entry_sr wa_entries[] = { 335 * ... 336 * { XE_RTP_NAME("test-entry"), 337 * XE_RTP_RULES(SUBPLATFORM(DG2, G10), GRAPHICS_STEP(A0, B0)), 338 * ... 339 * }, 340 * ... 341 * }; 342 */ 343 #define XE_RTP_RULES(...) \ 344 .n_rules = _XE_COUNT_ARGS(__VA_ARGS__), \ 345 .rules = (const struct xe_rtp_rule[]) { \ 346 XE_RTP_PASTE_FOREACH(RULE_, COMMA, (__VA_ARGS__)) \ 347 } 348 349 /** 350 * XE_RTP_ACTIONS - Helper to set multiple actions to a struct xe_rtp_entry_sr 351 * @...: Actions to be taken 352 * 353 * At least one action is needed and up to 4 are supported. See XE_RTP_ACTION_* 354 * for the possible actions. Example: 355 * 356 * .. code-block:: c 357 * 358 * const struct xe_rtp_entry_sr wa_entries[] = { 359 * ... 360 * { XE_RTP_NAME("test-entry"), 361 * XE_RTP_RULES(...), 362 * XE_RTP_ACTIONS(SET(..), SET(...), CLR(...)), 363 * ... 364 * }, 365 * ... 366 * }; 367 */ 368 #define XE_RTP_ACTIONS(...) \ 369 .n_actions = _XE_COUNT_ARGS(__VA_ARGS__), \ 370 .actions = (const struct xe_rtp_action[]) { \ 371 XE_RTP_PASTE_FOREACH(ACTION_, COMMA, (__VA_ARGS__)) \ 372 } 373 374 #define XE_RTP_PROCESS_CTX_INITIALIZER(arg__) _Generic((arg__), \ 375 struct xe_hw_engine * : (struct xe_rtp_process_ctx){ { (void *)(arg__) }, XE_RTP_PROCESS_TYPE_ENGINE }, \ 376 struct xe_gt * : (struct xe_rtp_process_ctx){ { (void *)(arg__) }, XE_RTP_PROCESS_TYPE_GT }) 377 378 void xe_rtp_process_ctx_enable_active_tracking(struct xe_rtp_process_ctx *ctx, 379 unsigned long *active_entries, 380 size_t n_entries); 381 382 void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx, 383 const struct xe_rtp_entry_sr *entries, 384 struct xe_reg_sr *sr); 385 386 void xe_rtp_process(struct xe_rtp_process_ctx *ctx, 387 const struct xe_rtp_entry *entries); 388 389 /* Match functions to be used with XE_RTP_MATCH_FUNC */ 390 391 /** 392 * xe_rtp_match_even_instance - Match if engine instance is even 393 * @gt: GT structure 394 * @hwe: Engine instance 395 * 396 * Returns: true if engine instance is even, false otherwise 397 */ 398 bool xe_rtp_match_even_instance(const struct xe_gt *gt, 399 const struct xe_hw_engine *hwe); 400 401 /* 402 * xe_rtp_match_first_render_or_compute - Match if it's first render or compute 403 * engine in the GT 404 * 405 * @gt: GT structure 406 * @hwe: Engine instance 407 * 408 * Registers on the render reset domain need to have their values re-applied 409 * when any of those engines are reset. Since the engines reset together, a 410 * programming can be set to just one of them. For simplicity the first engine 411 * of either render or compute class can be chosen. 412 * 413 * Returns: true if engine id is the first to match the render reset domain, 414 * false otherwise. 415 */ 416 bool xe_rtp_match_first_render_or_compute(const struct xe_gt *gt, 417 const struct xe_hw_engine *hwe); 418 419 /* 420 * xe_rtp_match_first_gslice_fused_off - Match when first gslice is fused off 421 * 422 * @gt: GT structure 423 * @hwe: Engine instance 424 * 425 * Returns: true if first gslice is fused off, false otherwise. 426 */ 427 bool xe_rtp_match_first_gslice_fused_off(const struct xe_gt *gt, 428 const struct xe_hw_engine *hwe); 429 430 #endif 431