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

drm/i915/mtl: Handle wopcm per-GT and limit calculations.

With MTL standalone media architecture the wopcm layout has changed,
with separate partitioning in WOPCM for the root GT GuC and the media
GT GuC. The size of WOPCM is 4MB with the lower 2MB reserved for the
media GT and the upper 2MB for the root GT.

Given that MTL has GuC deprivilege, the WOPCM registers are pre-locked
by the bios. Therefore, we can skip all the math for the partitioning
and just limit ourselves to sanity-checking the values.

v2: fix makefile file ordering (Jani)
v3: drop XELPM_SAMEDIA_WOPCM_SIZE, check huc instead of VDBOX (John)
v4: further clarify commit message, remove blank line (John)

Signed-off-by: Aravind Iddamsetty <aravind.iddamsetty@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: John Harrison <john.c.harrison@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Reviewed-by: John Harrison <John.C.Harrison@Intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221108020600.3575467-5-daniele.ceraolospurio@intel.com

authored by

Aravind Iddamsetty and committed by
Daniele Ceraolo Spurio
ee71434e 00b4c0ef

+51 -32
+1 -1
Documentation/gpu/i915.rst
··· 494 494 WOPCM Layout 495 495 ~~~~~~~~~~~~ 496 496 497 - .. kernel-doc:: drivers/gpu/drm/i915/intel_wopcm.c 497 + .. kernel-doc:: drivers/gpu/drm/i915/gt/intel_wopcm.c 498 498 :doc: WOPCM Layout 499 499 500 500 GuC
+3 -2
drivers/gpu/drm/i915/Makefile
··· 127 127 gt/intel_sseu.o \ 128 128 gt/intel_sseu_debugfs.o \ 129 129 gt/intel_timeline.o \ 130 + gt/intel_wopcm.o \ 130 131 gt/intel_workarounds.o \ 131 132 gt/shmem_utils.o \ 132 133 gt/sysfs_engines.o 134 + 133 135 # x86 intel-gtt module support 134 136 gt-$(CONFIG_X86) += gt/intel_ggtt_gmch.o 135 137 # autogenerated null render state ··· 185 183 i915_trace_points.o \ 186 184 i915_ttm_buddy_manager.o \ 187 185 i915_vma.o \ 188 - i915_vma_resource.o \ 189 - intel_wopcm.o 186 + i915_vma_resource.o 190 187 191 188 # general-purpose microcontroller (GuC) support 192 189 i915-y += gt/uc/intel_uc.o \
+1 -1
drivers/gpu/drm/i915/gt/intel_ggtt.c
··· 560 560 * why. 561 561 */ 562 562 ggtt->pin_bias = max_t(u32, I915_GTT_PAGE_SIZE, 563 - intel_wopcm_guc_size(&ggtt->vm.i915->wopcm)); 563 + intel_wopcm_guc_size(&ggtt->vm.gt->wopcm)); 564 564 565 565 ret = intel_vgt_balloon(ggtt); 566 566 if (ret)
+1
drivers/gpu/drm/i915/gt/intel_gt.c
··· 54 54 seqcount_mutex_init(&gt->tlb.seqno, &gt->tlb.invalidate_lock); 55 55 intel_gt_pm_init_early(gt); 56 56 57 + intel_wopcm_init_early(&gt->wopcm); 57 58 intel_uc_init_early(&gt->uc); 58 59 intel_rps_init_early(&gt->rps); 59 60 }
+2
drivers/gpu/drm/i915/gt/intel_gt_types.h
··· 31 31 #include "intel_migrate_types.h" 32 32 #include "intel_wakeref.h" 33 33 #include "pxp/intel_pxp_types.h" 34 + #include "intel_wopcm.h" 34 35 35 36 struct drm_i915_private; 36 37 struct i915_ggtt; ··· 102 101 103 102 struct intel_uc uc; 104 103 struct intel_gsc gsc; 104 + struct intel_wopcm wopcm; 105 105 106 106 struct { 107 107 /* Serialize global tlb invalidations */
+2 -2
drivers/gpu/drm/i915/gt/uc/intel_uc.c
··· 357 357 { 358 358 struct intel_gt *gt = uc_to_gt(uc); 359 359 struct intel_uncore *uncore = gt->uncore; 360 - u32 base = intel_wopcm_guc_base(&gt->i915->wopcm); 361 - u32 size = intel_wopcm_guc_size(&gt->i915->wopcm); 360 + u32 base = intel_wopcm_guc_base(&gt->wopcm); 361 + u32 size = intel_wopcm_guc_size(&gt->wopcm); 362 362 u32 huc_agent = intel_uc_uses_huc(uc) ? HUC_LOADING_AGENT_GUC : 0; 363 363 u32 mask; 364 364 int err;
+8 -6
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
··· 478 478 return 0; 479 479 } 480 480 481 - static int check_ccs_header(struct drm_i915_private *i915, 481 + static int check_ccs_header(struct intel_gt *gt, 482 482 const struct firmware *fw, 483 483 struct intel_uc_fw *uc_fw) 484 484 { 485 + struct drm_i915_private *i915 = gt->i915; 485 486 struct uc_css_header *css; 486 487 size_t size; 487 488 ··· 524 523 525 524 /* Sanity check whether this fw is not larger than whole WOPCM memory */ 526 525 size = __intel_uc_fw_get_upload_size(uc_fw); 527 - if (unlikely(size >= i915->wopcm.size)) { 526 + if (unlikely(size >= gt->wopcm.size)) { 528 527 drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu > %zu\n", 529 528 intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path, 530 - size, (size_t)i915->wopcm.size); 529 + size, (size_t)gt->wopcm.size); 531 530 return -E2BIG; 532 531 } 533 532 ··· 555 554 */ 556 555 int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw) 557 556 { 558 - struct drm_i915_private *i915 = __uc_fw_to_gt(uc_fw)->i915; 557 + struct intel_gt *gt = __uc_fw_to_gt(uc_fw); 558 + struct drm_i915_private *i915 = gt->i915; 559 559 struct intel_uc_fw_file file_ideal; 560 560 struct device *dev = i915->drm.dev; 561 561 struct drm_i915_gem_object *obj; ··· 564 562 bool old_ver = false; 565 563 int err; 566 564 567 - GEM_BUG_ON(!i915->wopcm.size); 565 + GEM_BUG_ON(!gt->wopcm.size); 568 566 GEM_BUG_ON(!intel_uc_fw_is_enabled(uc_fw)); 569 567 570 568 err = i915_inject_probe_error(i915, -ENXIO); ··· 617 615 if (uc_fw->loaded_via_gsc) 618 616 err = check_gsc_manifest(fw, uc_fw); 619 617 else 620 - err = check_ccs_header(i915, fw, uc_fw); 618 + err = check_ccs_header(gt, fw, uc_fw); 621 619 if (err) 622 620 goto fail; 623 621
-2
drivers/gpu/drm/i915/i915_driver.c
··· 372 372 if (ret) 373 373 goto err_ttm; 374 374 375 - intel_wopcm_init_early(&dev_priv->wopcm); 376 - 377 375 ret = intel_root_gt_init_early(dev_priv); 378 376 if (ret < 0) 379 377 goto err_rootgt;
-3
drivers/gpu/drm/i915/i915_drv.h
··· 62 62 #include "intel_runtime_pm.h" 63 63 #include "intel_step.h" 64 64 #include "intel_uncore.h" 65 - #include "intel_wopcm.h" 66 65 67 66 struct drm_i915_clock_gating_funcs; 68 67 struct drm_i915_gem_object; ··· 233 234 struct i915_virtual_gpu vgpu; 234 235 235 236 struct intel_gvt *gvt; 236 - 237 - struct intel_wopcm wopcm; 238 237 239 238 struct pci_dev *bridge_dev; 240 239
+3 -2
drivers/gpu/drm/i915/i915_gem.c
··· 1140 1140 if (ret) 1141 1141 return ret; 1142 1142 1143 - for_each_gt(gt, dev_priv, i) 1143 + for_each_gt(gt, dev_priv, i) { 1144 1144 intel_uc_fetch_firmwares(&gt->uc); 1145 - intel_wopcm_init(&dev_priv->wopcm); 1145 + intel_wopcm_init(&gt->wopcm); 1146 + } 1146 1147 1147 1148 ret = i915_init_ggtt(dev_priv); 1148 1149 if (ret) {
+30 -13
drivers/gpu/drm/i915/intel_wopcm.c drivers/gpu/drm/i915/gt/intel_wopcm.c
··· 64 64 #define GEN9_GUC_FW_RESERVED SZ_128K 65 65 #define GEN9_GUC_WOPCM_OFFSET (GUC_WOPCM_RESERVED + GEN9_GUC_FW_RESERVED) 66 66 67 - static inline struct drm_i915_private *wopcm_to_i915(struct intel_wopcm *wopcm) 67 + static inline struct intel_gt *wopcm_to_gt(struct intel_wopcm *wopcm) 68 68 { 69 - return container_of(wopcm, struct drm_i915_private, wopcm); 69 + return container_of(wopcm, struct intel_gt, wopcm); 70 70 } 71 71 72 72 /** ··· 77 77 */ 78 78 void intel_wopcm_init_early(struct intel_wopcm *wopcm) 79 79 { 80 - struct drm_i915_private *i915 = wopcm_to_i915(wopcm); 80 + struct intel_gt *gt = wopcm_to_gt(wopcm); 81 + struct drm_i915_private *i915 = gt->i915; 81 82 82 83 if (!HAS_GT_UC(i915)) 83 84 return; ··· 158 157 return true; 159 158 } 160 159 161 - static bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size, 160 + static bool __check_layout(struct intel_gt *gt, u32 wopcm_size, 162 161 u32 guc_wopcm_base, u32 guc_wopcm_size, 163 162 u32 guc_fw_size, u32 huc_fw_size) 164 163 { 164 + struct drm_i915_private *i915 = gt->i915; 165 165 const u32 ctx_rsvd = context_reserved_size(i915); 166 166 u32 size; 167 167 ··· 183 181 return false; 184 182 } 185 183 186 - size = huc_fw_size + WOPCM_RESERVED_SIZE; 187 - if (unlikely(guc_wopcm_base < size)) { 188 - drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n", 189 - intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC), 190 - guc_wopcm_base / SZ_1K, size / SZ_1K); 191 - return false; 184 + if (intel_uc_supports_huc(&gt->uc)) { 185 + size = huc_fw_size + WOPCM_RESERVED_SIZE; 186 + if (unlikely(guc_wopcm_base < size)) { 187 + drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n", 188 + intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC), 189 + guc_wopcm_base / SZ_1K, size / SZ_1K); 190 + return false; 191 + } 192 192 } 193 193 194 194 return check_hw_restrictions(i915, guc_wopcm_base, guc_wopcm_size, ··· 232 228 */ 233 229 void intel_wopcm_init(struct intel_wopcm *wopcm) 234 230 { 235 - struct drm_i915_private *i915 = wopcm_to_i915(wopcm); 236 - struct intel_gt *gt = to_gt(i915); 231 + struct intel_gt *gt = wopcm_to_gt(wopcm); 232 + struct drm_i915_private *i915 = gt->i915; 237 233 u32 guc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.guc.fw); 238 234 u32 huc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.huc.fw); 239 235 u32 ctx_rsvd = context_reserved_size(i915); ··· 279 275 } 280 276 281 277 /* 278 + * On platforms with a media GT, the WOPCM is partitioned between the 279 + * two GTs, so we would have to take that into account when doing the 280 + * math below. There is also a new section reserved for the GSC context 281 + * that would have to be factored in. However, all platforms with a 282 + * media GT also have GuC depriv enabled, so the WOPCM regs are 283 + * pre-locked and therefore we don't have to do the math ourselves. 284 + */ 285 + if (unlikely(i915->media_gt)) { 286 + drm_err(&i915->drm, "Unlocked WOPCM regs with media GT\n"); 287 + return; 288 + } 289 + 290 + /* 282 291 * Aligned value of guc_wopcm_base will determine available WOPCM space 283 292 * for HuC firmware and mandatory reserved area. 284 293 */ ··· 312 295 guc_wopcm_base / SZ_1K, guc_wopcm_size / SZ_1K); 313 296 314 297 check: 315 - if (__check_layout(i915, wopcm_size, guc_wopcm_base, guc_wopcm_size, 298 + if (__check_layout(gt, wopcm_size, guc_wopcm_base, guc_wopcm_size, 316 299 guc_fw_size, huc_fw_size)) { 317 300 wopcm->guc.base = guc_wopcm_base; 318 301 wopcm->guc.size = guc_wopcm_size;
drivers/gpu/drm/i915/intel_wopcm.h drivers/gpu/drm/i915/gt/intel_wopcm.h