Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915/xehp: Check new fuse bits for SFC availability

Xe_HP adds some new bits to the FUSE1 register to let us know whether a
given SFC unit is present. We should take this into account while
initializing SFC availability to our VCS and VECS engines.

While we're at it, update the FUSE1 register definition to use
REG_GENMASK / REG_FIELD_GET notation.

Note that, the bspec confusingly names the fuse bits "disable" despite
the register reflecting the *enable* status of the SFC units. The
original architecture documents which the bspec is based on do properly
name this field "SFC_ENABLE."

Bspec: 52543
Cc: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210917161203.812251-2-matthew.d.roper@intel.com

+27 -10
+20 -5
drivers/gpu/drm/i915/gt/intel_engine_cs.c
··· 398 398 engine->uabi_capabilities |= 399 399 I915_VIDEO_AND_ENHANCE_CLASS_CAPABILITY_SFC; 400 400 } else if (engine->class == VIDEO_ENHANCEMENT_CLASS) { 401 - if (GRAPHICS_VER(i915) >= 9) 401 + if (GRAPHICS_VER(i915) >= 9 && 402 + engine->gt->info.sfc_mask & BIT(engine->instance)) 402 403 engine->uabi_capabilities |= 403 404 I915_VIDEO_AND_ENHANCE_CLASS_CAPABILITY_SFC; 404 405 } ··· 475 474 } 476 475 477 476 static 478 - bool gen11_vdbox_has_sfc(struct drm_i915_private *i915, 477 + bool gen11_vdbox_has_sfc(struct intel_gt *gt, 479 478 unsigned int physical_vdbox, 480 479 unsigned int logical_vdbox, u16 vdbox_mask) 481 480 { 481 + struct drm_i915_private *i915 = gt->i915; 482 + 482 483 /* 483 484 * In Gen11, only even numbered logical VDBOXes are hooked 484 485 * up to an SFC (Scaler & Format Converter) unit. 485 486 * In Gen12, Even numbered physical instance always are connected 486 487 * to an SFC. Odd numbered physical instances have SFC only if 487 488 * previous even instance is fused off. 489 + * 490 + * Starting with Xe_HP, there's also a dedicated SFC_ENABLE field 491 + * in the fuse register that tells us whether a specific SFC is present. 488 492 */ 489 - if (GRAPHICS_VER(i915) == 12) 493 + if ((gt->info.sfc_mask & BIT(physical_vdbox / 2)) == 0) 494 + return false; 495 + else if (GRAPHICS_VER(i915) == 12) 490 496 return (physical_vdbox % 2 == 0) || 491 497 !(BIT(physical_vdbox - 1) & vdbox_mask); 492 498 else if (GRAPHICS_VER(i915) == 11) ··· 520 512 struct intel_uncore *uncore = gt->uncore; 521 513 unsigned int logical_vdbox = 0; 522 514 unsigned int i; 523 - u32 media_fuse; 515 + u32 media_fuse, fuse1; 524 516 u16 vdbox_mask; 525 517 u16 vebox_mask; 526 518 ··· 542 534 vebox_mask = (media_fuse & GEN11_GT_VEBOX_DISABLE_MASK) >> 543 535 GEN11_GT_VEBOX_DISABLE_SHIFT; 544 536 537 + if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50)) { 538 + fuse1 = intel_uncore_read(uncore, HSW_PAVP_FUSE1); 539 + gt->info.sfc_mask = REG_FIELD_GET(XEHP_SFC_ENABLE_MASK, fuse1); 540 + } else { 541 + gt->info.sfc_mask = ~0; 542 + } 543 + 545 544 for (i = 0; i < I915_MAX_VCS; i++) { 546 545 if (!HAS_ENGINE(gt, _VCS(i))) { 547 546 vdbox_mask &= ~BIT(i); ··· 561 546 continue; 562 547 } 563 548 564 - if (gen11_vdbox_has_sfc(i915, i, logical_vdbox, vdbox_mask)) 549 + if (gen11_vdbox_has_sfc(gt, i, logical_vdbox, vdbox_mask)) 565 550 gt->info.vdbox_sfc_access |= BIT(i); 566 551 logical_vdbox++; 567 552 }
+3
drivers/gpu/drm/i915/gt/intel_gt_types.h
··· 186 186 187 187 u8 num_engines; 188 188 189 + /* General presence of SFC units */ 190 + u8 sfc_mask; 191 + 189 192 /* Media engine access to SFC per instance */ 190 193 u8 vdbox_sfc_access; 191 194
+2 -3
drivers/gpu/drm/i915/gt/intel_sseu.c
··· 514 514 } 515 515 516 516 fuse1 = intel_uncore_read(gt->uncore, HSW_PAVP_FUSE1); 517 - switch ((fuse1 & HSW_F1_EU_DIS_MASK) >> HSW_F1_EU_DIS_SHIFT) { 517 + switch (REG_FIELD_GET(HSW_F1_EU_DIS_MASK, fuse1)) { 518 518 default: 519 - MISSING_CASE((fuse1 & HSW_F1_EU_DIS_MASK) >> 520 - HSW_F1_EU_DIS_SHIFT); 519 + MISSING_CASE(REG_FIELD_GET(HSW_F1_EU_DIS_MASK, fuse1)); 521 520 fallthrough; 522 521 case HSW_F1_EU_DIS_10EUS: 523 522 sseu->eu_per_subslice = 10;
+2 -2
drivers/gpu/drm/i915/i915_reg.h
··· 3108 3108 3109 3109 /* Fuse readout registers for GT */ 3110 3110 #define HSW_PAVP_FUSE1 _MMIO(0x911C) 3111 - #define HSW_F1_EU_DIS_SHIFT 16 3112 - #define HSW_F1_EU_DIS_MASK (0x3 << HSW_F1_EU_DIS_SHIFT) 3111 + #define XEHP_SFC_ENABLE_MASK REG_GENMASK(27, 24) 3112 + #define HSW_F1_EU_DIS_MASK REG_GENMASK(17, 16) 3113 3113 #define HSW_F1_EU_DIS_10EUS 0 3114 3114 #define HSW_F1_EU_DIS_8EUS 1 3115 3115 #define HSW_F1_EU_DIS_6EUS 2