WOPCM Layout
~~~~~~~~~~~~
-.. kernel-doc:: drivers/gpu/drm/i915/intel_wopcm.c
+.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_wopcm.c
:doc: WOPCM Layout
GuC
gt/intel_sseu.o \
gt/intel_sseu_debugfs.o \
gt/intel_timeline.o \
+ gt/intel_wopcm.o \
gt/intel_workarounds.o \
gt/shmem_utils.o \
gt/sysfs_engines.o
+
# x86 intel-gtt module support
gt-$(CONFIG_X86) += gt/intel_ggtt_gmch.o
# autogenerated null render state
i915_trace_points.o \
i915_ttm_buddy_manager.o \
i915_vma.o \
- i915_vma_resource.o \
- intel_wopcm.o
+ i915_vma_resource.o
# general-purpose microcontroller (GuC) support
i915-y += gt/uc/intel_uc.o \
* why.
*/
ggtt->pin_bias = max_t(u32, I915_GTT_PAGE_SIZE,
- intel_wopcm_guc_size(&ggtt->vm.i915->wopcm));
+ intel_wopcm_guc_size(&ggtt->vm.gt->wopcm));
ret = intel_vgt_balloon(ggtt);
if (ret)
seqcount_mutex_init(>->tlb.seqno, >->tlb.invalidate_lock);
intel_gt_pm_init_early(gt);
+ intel_wopcm_init_early(>->wopcm);
intel_uc_init_early(>->uc);
intel_rps_init_early(>->rps);
}
#include "intel_migrate_types.h"
#include "intel_wakeref.h"
#include "pxp/intel_pxp_types.h"
+#include "intel_wopcm.h"
struct drm_i915_private;
struct i915_ggtt;
struct intel_uc uc;
struct intel_gsc gsc;
+ struct intel_wopcm wopcm;
struct {
/* Serialize global tlb invalidations */
#define GEN9_GUC_FW_RESERVED SZ_128K
#define GEN9_GUC_WOPCM_OFFSET (GUC_WOPCM_RESERVED + GEN9_GUC_FW_RESERVED)
-static inline struct drm_i915_private *wopcm_to_i915(struct intel_wopcm *wopcm)
+static inline struct intel_gt *wopcm_to_gt(struct intel_wopcm *wopcm)
{
- return container_of(wopcm, struct drm_i915_private, wopcm);
+ return container_of(wopcm, struct intel_gt, wopcm);
}
/**
*/
void intel_wopcm_init_early(struct intel_wopcm *wopcm)
{
- struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
+ struct intel_gt *gt = wopcm_to_gt(wopcm);
+ struct drm_i915_private *i915 = gt->i915;
if (!HAS_GT_UC(i915))
return;
return true;
}
-static bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
+static bool __check_layout(struct intel_gt *gt, u32 wopcm_size,
u32 guc_wopcm_base, u32 guc_wopcm_size,
u32 guc_fw_size, u32 huc_fw_size)
{
+ struct drm_i915_private *i915 = gt->i915;
const u32 ctx_rsvd = context_reserved_size(i915);
u32 size;
return false;
}
- size = huc_fw_size + WOPCM_RESERVED_SIZE;
- if (unlikely(guc_wopcm_base < size)) {
- drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n",
- intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
- guc_wopcm_base / SZ_1K, size / SZ_1K);
- return false;
+ if (intel_uc_supports_huc(>->uc)) {
+ size = huc_fw_size + WOPCM_RESERVED_SIZE;
+ if (unlikely(guc_wopcm_base < size)) {
+ drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n",
+ intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
+ guc_wopcm_base / SZ_1K, size / SZ_1K);
+ return false;
+ }
}
return check_hw_restrictions(i915, guc_wopcm_base, guc_wopcm_size,
*/
void intel_wopcm_init(struct intel_wopcm *wopcm)
{
- struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
- struct intel_gt *gt = to_gt(i915);
+ struct intel_gt *gt = wopcm_to_gt(wopcm);
+ struct drm_i915_private *i915 = gt->i915;
u32 guc_fw_size = intel_uc_fw_get_upload_size(>->uc.guc.fw);
u32 huc_fw_size = intel_uc_fw_get_upload_size(>->uc.huc.fw);
u32 ctx_rsvd = context_reserved_size(i915);
}
/*
+ * On platforms with a media GT, the WOPCM is partitioned between the
+ * two GTs, so we would have to take that into account when doing the
+ * math below. There is also a new section reserved for the GSC context
+ * that would have to be factored in. However, all platforms with a
+ * media GT also have GuC depriv enabled, so the WOPCM regs are
+ * pre-locked and therefore we don't have to do the math ourselves.
+ */
+ if (unlikely(i915->media_gt)) {
+ drm_err(&i915->drm, "Unlocked WOPCM regs with media GT\n");
+ return;
+ }
+
+ /*
* Aligned value of guc_wopcm_base will determine available WOPCM space
* for HuC firmware and mandatory reserved area.
*/
guc_wopcm_base / SZ_1K, guc_wopcm_size / SZ_1K);
check:
- if (__check_layout(i915, wopcm_size, guc_wopcm_base, guc_wopcm_size,
+ if (__check_layout(gt, wopcm_size, guc_wopcm_base, guc_wopcm_size,
guc_fw_size, huc_fw_size)) {
wopcm->guc.base = guc_wopcm_base;
wopcm->guc.size = guc_wopcm_size;
{
struct intel_gt *gt = uc_to_gt(uc);
struct intel_uncore *uncore = gt->uncore;
- u32 base = intel_wopcm_guc_base(>->i915->wopcm);
- u32 size = intel_wopcm_guc_size(>->i915->wopcm);
+ u32 base = intel_wopcm_guc_base(>->wopcm);
+ u32 size = intel_wopcm_guc_size(>->wopcm);
u32 huc_agent = intel_uc_uses_huc(uc) ? HUC_LOADING_AGENT_GUC : 0;
u32 mask;
int err;
return 0;
}
-static int check_ccs_header(struct drm_i915_private *i915,
+static int check_ccs_header(struct intel_gt *gt,
const struct firmware *fw,
struct intel_uc_fw *uc_fw)
{
+ struct drm_i915_private *i915 = gt->i915;
struct uc_css_header *css;
size_t size;
/* Sanity check whether this fw is not larger than whole WOPCM memory */
size = __intel_uc_fw_get_upload_size(uc_fw);
- if (unlikely(size >= i915->wopcm.size)) {
+ if (unlikely(size >= gt->wopcm.size)) {
drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu > %zu\n",
intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
- size, (size_t)i915->wopcm.size);
+ size, (size_t)gt->wopcm.size);
return -E2BIG;
}
*/
int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
{
- struct drm_i915_private *i915 = __uc_fw_to_gt(uc_fw)->i915;
+ struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
+ struct drm_i915_private *i915 = gt->i915;
struct intel_uc_fw_file file_ideal;
struct device *dev = i915->drm.dev;
struct drm_i915_gem_object *obj;
bool old_ver = false;
int err;
- GEM_BUG_ON(!i915->wopcm.size);
+ GEM_BUG_ON(!gt->wopcm.size);
GEM_BUG_ON(!intel_uc_fw_is_enabled(uc_fw));
err = i915_inject_probe_error(i915, -ENXIO);
if (uc_fw->loaded_via_gsc)
err = check_gsc_manifest(fw, uc_fw);
else
- err = check_ccs_header(i915, fw, uc_fw);
+ err = check_ccs_header(gt, fw, uc_fw);
if (err)
goto fail;
if (ret)
goto err_ttm;
- intel_wopcm_init_early(&dev_priv->wopcm);
-
ret = intel_root_gt_init_early(dev_priv);
if (ret < 0)
goto err_rootgt;
#include "intel_runtime_pm.h"
#include "intel_step.h"
#include "intel_uncore.h"
-#include "intel_wopcm.h"
struct drm_i915_clock_gating_funcs;
struct drm_i915_gem_object;
struct intel_gvt *gvt;
- struct intel_wopcm wopcm;
-
struct pci_dev *bridge_dev;
struct rb_root uabi_engines;
if (ret)
return ret;
- for_each_gt(gt, dev_priv, i)
+ for_each_gt(gt, dev_priv, i) {
intel_uc_fetch_firmwares(>->uc);
- intel_wopcm_init(&dev_priv->wopcm);
+ intel_wopcm_init(>->wopcm);
+ }
ret = i915_init_ggtt(dev_priv);
if (ret) {