diff mbox series

[5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations.

Message ID 20220922221117.458087-6-daniele.ceraolospurio@intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915: prepare for uC loading on MTL | expand

Commit Message

Daniele Ceraolo Spurio Sept. 22, 2022, 10:11 p.m. UTC
From: Aravind Iddamsetty <aravind.iddamsetty@intel.com>

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

    +=====+===> +====================+ <== WOPCM TOP
    ^     ^     |                    |
    |     |     |                    |
    |    GCD    |   GCD RC6 Image    |
    |    GuC    |    Power Context   |
    |    WOPCM  |                    |
    |    Size   +--------------------+
    |     |     |   GCD GuC Image    |
    |     |     |                    |
    |     v     |                    |
    |     +===> +====================+ <== SA Media GuC WOPCM Top
    |     ^     |                    |
    |   SA Media|                    |
    |    GuC    | SA Media RC6 Image |
    |   WOPCM   |    Power Context   |
    |    Size   |                    |
  WOPCM   |     +--------------------+
    |     |     |                    |
    |     |     | SA Media GuC Image |
    |     v     |                    |
    |     +===> +====================+ <== GuC WOPCM base
    |           |     WOPCM RSVD     |
    |           +------------------- + <== HuC Firmware Top
    v           |      HuC FW        |
    +=========> +====================+ <== WOPCM Base

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.

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>
---
 drivers/gpu/drm/i915/Makefile               |  7 +--
 drivers/gpu/drm/i915/gt/intel_ggtt.c        |  2 +-
 drivers/gpu/drm/i915/gt/intel_gt.c          |  1 +
 drivers/gpu/drm/i915/gt/intel_gt_types.h    |  2 +
 drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c | 48 +++++++++++++++------
 drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h |  0
 drivers/gpu/drm/i915/gt/uc/intel_uc.c       |  4 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c    | 14 +++---
 drivers/gpu/drm/i915/i915_driver.c          |  2 -
 drivers/gpu/drm/i915/i915_drv.h             |  3 --
 drivers/gpu/drm/i915/i915_gem.c             |  5 ++-
 11 files changed, 56 insertions(+), 32 deletions(-)
 rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c (86%)
 rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h (100%)

Comments

Jani Nikula Sept. 23, 2022, 9:24 a.m. UTC | #1
On Thu, 22 Sep 2022, Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> wrote:
> From: Aravind Iddamsetty <aravind.iddamsetty@intel.com>
>
> With MTL standalone media architecture the wopcm layout has changed with
> separate partitioning in WOPCM for GCD/GT GuC and SA Media GuC. The size
> of WOPCM is 4MB with lower 2MB for SA Media and upper 2MB for GCD/GT.
>
>     +=====+===> +====================+ <== WOPCM TOP
>     ^     ^     |                    |
>     |     |     |                    |
>     |    GCD    |   GCD RC6 Image    |
>     |    GuC    |    Power Context   |
>     |    WOPCM  |                    |
>     |    Size   +--------------------+
>     |     |     |   GCD GuC Image    |
>     |     |     |                    |
>     |     v     |                    |
>     |     +===> +====================+ <== SA Media GuC WOPCM Top
>     |     ^     |                    |
>     |   SA Media|                    |
>     |    GuC    | SA Media RC6 Image |
>     |   WOPCM   |    Power Context   |
>     |    Size   |                    |
>   WOPCM   |     +--------------------+
>     |     |     |                    |
>     |     |     | SA Media GuC Image |
>     |     v     |                    |
>     |     +===> +====================+ <== GuC WOPCM base
>     |           |     WOPCM RSVD     |
>     |           +------------------- + <== HuC Firmware Top
>     v           |      HuC FW        |
>     +=========> +====================+ <== WOPCM Base
>
> 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.
>
> 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>
> ---
>  drivers/gpu/drm/i915/Makefile               |  7 +--
>  drivers/gpu/drm/i915/gt/intel_ggtt.c        |  2 +-
>  drivers/gpu/drm/i915/gt/intel_gt.c          |  1 +
>  drivers/gpu/drm/i915/gt/intel_gt_types.h    |  2 +
>  drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c | 48 +++++++++++++++------
>  drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h |  0
>  drivers/gpu/drm/i915/gt/uc/intel_uc.c       |  4 +-
>  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c    | 14 +++---
>  drivers/gpu/drm/i915/i915_driver.c          |  2 -
>  drivers/gpu/drm/i915/i915_drv.h             |  3 --
>  drivers/gpu/drm/i915/i915_gem.c             |  5 ++-
>  11 files changed, 56 insertions(+), 32 deletions(-)
>  rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c (86%)
>  rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h (100%)
>
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index a26edcdadc21..6ed4c745b226 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -129,7 +129,9 @@ gt-y += \
>  	gt/intel_timeline.o \
>  	gt/intel_workarounds.o \
>  	gt/shmem_utils.o \
> -	gt/sysfs_engines.o
> +	gt/sysfs_engines.o \
> +	gt/intel_wopcm.o

The comment near the top of the file:

# Please keep these build lists sorted!

> +
>  # x86 intel-gtt module support
>  gt-$(CONFIG_X86) += gt/intel_ggtt_gmch.o
>  # autogenerated null render state
> @@ -183,8 +185,7 @@ i915-y += \
>  	  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 \
> diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> index 30cf5c3369d9..605e1aa674d4 100644
> --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> @@ -560,7 +560,7 @@ static int init_ggtt(struct i915_ggtt *ggtt)
>  	 * 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)
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
> index b367cfff48d5..a95eb0b656d2 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt.c
> @@ -56,6 +56,7 @@ void intel_gt_common_init_early(struct intel_gt *gt)
>  	seqcount_mutex_init(&gt->tlb.seqno, &gt->tlb.invalidate_lock);
>  	intel_gt_pm_init_early(gt);
>  
> +	intel_wopcm_init_early(&gt->wopcm);
>  	intel_uc_init_early(&gt->uc);
>  	intel_rps_init_early(&gt->rps);
>  }
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
> index f19c2de77ff6..c20a32d2700f 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
> @@ -30,6 +30,7 @@
>  #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;
> @@ -97,6 +98,7 @@ struct intel_gt {
>  
>  	struct intel_uc uc;
>  	struct intel_gsc gsc;
> +	struct intel_wopcm wopcm;
>  
>  	struct {
>  		/* Serialize global tlb invalidations */
> diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/gt/intel_wopcm.c
> similarity index 86%
> rename from drivers/gpu/drm/i915/intel_wopcm.c
> rename to drivers/gpu/drm/i915/gt/intel_wopcm.c
> index 322fb9eeb880..487fbbbdf3d6 100644
> --- a/drivers/gpu/drm/i915/intel_wopcm.c
> +++ b/drivers/gpu/drm/i915/gt/intel_wopcm.c
> @@ -43,6 +43,7 @@
>  /* Default WOPCM size is 2MB from Gen11, 1MB on previous platforms */
>  #define GEN11_WOPCM_SIZE		SZ_2M
>  #define GEN9_WOPCM_SIZE			SZ_1M
> +#define XELPM_SAMEDIA_WOPCM_SIZE	SZ_2M
>  #define MAX_WOPCM_SIZE			SZ_8M
>  /* 16KB WOPCM (RSVD WOPCM) is reserved from HuC firmware top. */
>  #define WOPCM_RESERVED_SIZE		SZ_16K
> @@ -64,9 +65,9 @@
>  #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);
>  }
>  
>  /**
> @@ -77,7 +78,8 @@ static inline struct drm_i915_private *wopcm_to_i915(struct intel_wopcm *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;
> @@ -157,14 +159,18 @@ static bool check_hw_restrictions(struct drm_i915_private *i915,
>  	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;
>  
>  	size = wopcm_size - ctx_rsvd;
> +	if (MEDIA_VER(i915) >= 13)
> +		size += XELPM_SAMEDIA_WOPCM_SIZE;
> +
>  	if (unlikely(range_overflows(guc_wopcm_base, guc_wopcm_size, size))) {
>  		drm_err(&i915->drm,
>  			"WOPCM: invalid GuC region layout: %uK + %uK > %uK\n",
> @@ -181,12 +187,14 @@ static bool __check_layout(struct drm_i915_private *i915, u32 wopcm_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 (VDBOX_MASK(gt)) {
> +		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,
> @@ -228,8 +236,8 @@ static bool __wopcm_regs_writable(struct intel_uncore *uncore)
>   */
>  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(&gt->uc.guc.fw);
>  	u32 huc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.huc.fw);
>  	u32 ctx_rsvd = context_reserved_size(i915);
> @@ -274,6 +282,19 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
>  		goto check;
>  	}
>  
> +	/*
> +	 * 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 ctx
> +	 * that w would have to factor 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.
> @@ -289,13 +310,14 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
>  
>  	/* Aligned remainings of usable WOPCM space can be assigned to GuC. */
>  	guc_wopcm_size = wopcm_size - ctx_rsvd - guc_wopcm_base;
> +
>  	guc_wopcm_size &= GUC_WOPCM_SIZE_MASK;
>  
>  	drm_dbg(&i915->drm, "Calculated GuC WOPCM [%uK, %uK)\n",
>  		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;
> diff --git a/drivers/gpu/drm/i915/intel_wopcm.h b/drivers/gpu/drm/i915/gt/intel_wopcm.h
> similarity index 100%
> rename from drivers/gpu/drm/i915/intel_wopcm.h
> rename to drivers/gpu/drm/i915/gt/intel_wopcm.h
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> index dbd048b77e19..4cd8a787f9e5 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> @@ -357,8 +357,8 @@ static int uc_init_wopcm(struct intel_uc *uc)
>  {
>  	struct intel_gt *gt = uc_to_gt(uc);
>  	struct intel_uncore *uncore = gt->uncore;
> -	u32 base = intel_wopcm_guc_base(&gt->i915->wopcm);
> -	u32 size = intel_wopcm_guc_size(&gt->i915->wopcm);
> +	u32 base = intel_wopcm_guc_base(&gt->wopcm);
> +	u32 size = intel_wopcm_guc_size(&gt->wopcm);
>  	u32 huc_agent = intel_uc_uses_huc(uc) ? HUC_LOADING_AGENT_GUC : 0;
>  	u32 mask;
>  	int err;
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> index d6ca772e9f4b..a9ff9abb66db 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> @@ -469,10 +469,11 @@ static int check_gsc_manifest(const struct firmware *fw,
>  	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;
>  
> @@ -514,10 +515,10 @@ static int check_ccs_header(struct drm_i915_private *i915,
>  
>  	/* 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;
>  	}
>  
> @@ -545,7 +546,8 @@ static int check_ccs_header(struct drm_i915_private *i915,
>   */
>  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;
> @@ -553,7 +555,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>  	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);
> @@ -595,7 +597,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>  	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;
>  
> diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
> index 9d1fc2477f80..51fc030774fa 100644
> --- a/drivers/gpu/drm/i915/i915_driver.c
> +++ b/drivers/gpu/drm/i915/i915_driver.c
> @@ -369,8 +369,6 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
>  	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;
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 8ca575202e5d..587e43ad7941 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -63,7 +63,6 @@
>  #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;
> @@ -236,8 +235,6 @@ struct drm_i915_private {
>  
>  	struct intel_gvt *gvt;
>  
> -	struct intel_wopcm wopcm;
> -
>  	struct pci_dev *bridge_dev;
>  
>  	struct rb_root uabi_engines;
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index a5b192ac885c..cfc8b17c1ee5 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -1140,9 +1140,10 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
>  	if (ret)
>  		return ret;
>  
> -	for_each_gt(gt, dev_priv, i)
> +	for_each_gt(gt, dev_priv, i) {
>  		intel_uc_fetch_firmwares(&gt->uc);
> -	intel_wopcm_init(&dev_priv->wopcm);
> +		intel_wopcm_init(&gt->wopcm);
> +	}
>  
>  	ret = i915_init_ggtt(dev_priv);
>  	if (ret) {
Daniele Ceraolo Spurio Sept. 23, 2022, 3:34 p.m. UTC | #2
On 9/23/2022 2:24 AM, Jani Nikula wrote:
> On Thu, 22 Sep 2022, Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> wrote:
>> From: Aravind Iddamsetty <aravind.iddamsetty@intel.com>
>>
>> With MTL standalone media architecture the wopcm layout has changed with
>> separate partitioning in WOPCM for GCD/GT GuC and SA Media GuC. The size
>> of WOPCM is 4MB with lower 2MB for SA Media and upper 2MB for GCD/GT.
>>
>>      +=====+===> +====================+ <== WOPCM TOP
>>      ^     ^     |                    |
>>      |     |     |                    |
>>      |    GCD    |   GCD RC6 Image    |
>>      |    GuC    |    Power Context   |
>>      |    WOPCM  |                    |
>>      |    Size   +--------------------+
>>      |     |     |   GCD GuC Image    |
>>      |     |     |                    |
>>      |     v     |                    |
>>      |     +===> +====================+ <== SA Media GuC WOPCM Top
>>      |     ^     |                    |
>>      |   SA Media|                    |
>>      |    GuC    | SA Media RC6 Image |
>>      |   WOPCM   |    Power Context   |
>>      |    Size   |                    |
>>    WOPCM   |     +--------------------+
>>      |     |     |                    |
>>      |     |     | SA Media GuC Image |
>>      |     v     |                    |
>>      |     +===> +====================+ <== GuC WOPCM base
>>      |           |     WOPCM RSVD     |
>>      |           +------------------- + <== HuC Firmware Top
>>      v           |      HuC FW        |
>>      +=========> +====================+ <== WOPCM Base
>>
>> 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.
>>
>> 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>
>> ---
>>   drivers/gpu/drm/i915/Makefile               |  7 +--
>>   drivers/gpu/drm/i915/gt/intel_ggtt.c        |  2 +-
>>   drivers/gpu/drm/i915/gt/intel_gt.c          |  1 +
>>   drivers/gpu/drm/i915/gt/intel_gt_types.h    |  2 +
>>   drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c | 48 +++++++++++++++------
>>   drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h |  0
>>   drivers/gpu/drm/i915/gt/uc/intel_uc.c       |  4 +-
>>   drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c    | 14 +++---
>>   drivers/gpu/drm/i915/i915_driver.c          |  2 -
>>   drivers/gpu/drm/i915/i915_drv.h             |  3 --
>>   drivers/gpu/drm/i915/i915_gem.c             |  5 ++-
>>   11 files changed, 56 insertions(+), 32 deletions(-)
>>   rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c (86%)
>>   rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h (100%)
>>
>> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
>> index a26edcdadc21..6ed4c745b226 100644
>> --- a/drivers/gpu/drm/i915/Makefile
>> +++ b/drivers/gpu/drm/i915/Makefile
>> @@ -129,7 +129,9 @@ gt-y += \
>>   	gt/intel_timeline.o \
>>   	gt/intel_workarounds.o \
>>   	gt/shmem_utils.o \
>> -	gt/sysfs_engines.o
>> +	gt/sysfs_engines.o \
>> +	gt/intel_wopcm.o
> The comment near the top of the file:
>
> # Please keep these build lists sorted!

D'oh! My monkey brain saw that "wopcm" was correctly ordered after 
"engines" and completely ignored the first part of the name :/
Will fix next rev.

Daniele

>
>> +
>>   # x86 intel-gtt module support
>>   gt-$(CONFIG_X86) += gt/intel_ggtt_gmch.o
>>   # autogenerated null render state
>> @@ -183,8 +185,7 @@ i915-y += \
>>   	  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 \
>> diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
>> index 30cf5c3369d9..605e1aa674d4 100644
>> --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
>> +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
>> @@ -560,7 +560,7 @@ static int init_ggtt(struct i915_ggtt *ggtt)
>>   	 * 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)
>> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
>> index b367cfff48d5..a95eb0b656d2 100644
>> --- a/drivers/gpu/drm/i915/gt/intel_gt.c
>> +++ b/drivers/gpu/drm/i915/gt/intel_gt.c
>> @@ -56,6 +56,7 @@ void intel_gt_common_init_early(struct intel_gt *gt)
>>   	seqcount_mutex_init(&gt->tlb.seqno, &gt->tlb.invalidate_lock);
>>   	intel_gt_pm_init_early(gt);
>>   
>> +	intel_wopcm_init_early(&gt->wopcm);
>>   	intel_uc_init_early(&gt->uc);
>>   	intel_rps_init_early(&gt->rps);
>>   }
>> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
>> index f19c2de77ff6..c20a32d2700f 100644
>> --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
>> +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
>> @@ -30,6 +30,7 @@
>>   #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;
>> @@ -97,6 +98,7 @@ struct intel_gt {
>>   
>>   	struct intel_uc uc;
>>   	struct intel_gsc gsc;
>> +	struct intel_wopcm wopcm;
>>   
>>   	struct {
>>   		/* Serialize global tlb invalidations */
>> diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/gt/intel_wopcm.c
>> similarity index 86%
>> rename from drivers/gpu/drm/i915/intel_wopcm.c
>> rename to drivers/gpu/drm/i915/gt/intel_wopcm.c
>> index 322fb9eeb880..487fbbbdf3d6 100644
>> --- a/drivers/gpu/drm/i915/intel_wopcm.c
>> +++ b/drivers/gpu/drm/i915/gt/intel_wopcm.c
>> @@ -43,6 +43,7 @@
>>   /* Default WOPCM size is 2MB from Gen11, 1MB on previous platforms */
>>   #define GEN11_WOPCM_SIZE		SZ_2M
>>   #define GEN9_WOPCM_SIZE			SZ_1M
>> +#define XELPM_SAMEDIA_WOPCM_SIZE	SZ_2M
>>   #define MAX_WOPCM_SIZE			SZ_8M
>>   /* 16KB WOPCM (RSVD WOPCM) is reserved from HuC firmware top. */
>>   #define WOPCM_RESERVED_SIZE		SZ_16K
>> @@ -64,9 +65,9 @@
>>   #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);
>>   }
>>   
>>   /**
>> @@ -77,7 +78,8 @@ static inline struct drm_i915_private *wopcm_to_i915(struct intel_wopcm *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;
>> @@ -157,14 +159,18 @@ static bool check_hw_restrictions(struct drm_i915_private *i915,
>>   	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;
>>   
>>   	size = wopcm_size - ctx_rsvd;
>> +	if (MEDIA_VER(i915) >= 13)
>> +		size += XELPM_SAMEDIA_WOPCM_SIZE;
>> +
>>   	if (unlikely(range_overflows(guc_wopcm_base, guc_wopcm_size, size))) {
>>   		drm_err(&i915->drm,
>>   			"WOPCM: invalid GuC region layout: %uK + %uK > %uK\n",
>> @@ -181,12 +187,14 @@ static bool __check_layout(struct drm_i915_private *i915, u32 wopcm_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 (VDBOX_MASK(gt)) {
>> +		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,
>> @@ -228,8 +236,8 @@ static bool __wopcm_regs_writable(struct intel_uncore *uncore)
>>    */
>>   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(&gt->uc.guc.fw);
>>   	u32 huc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.huc.fw);
>>   	u32 ctx_rsvd = context_reserved_size(i915);
>> @@ -274,6 +282,19 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
>>   		goto check;
>>   	}
>>   
>> +	/*
>> +	 * 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 ctx
>> +	 * that w would have to factor 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.
>> @@ -289,13 +310,14 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
>>   
>>   	/* Aligned remainings of usable WOPCM space can be assigned to GuC. */
>>   	guc_wopcm_size = wopcm_size - ctx_rsvd - guc_wopcm_base;
>> +
>>   	guc_wopcm_size &= GUC_WOPCM_SIZE_MASK;
>>   
>>   	drm_dbg(&i915->drm, "Calculated GuC WOPCM [%uK, %uK)\n",
>>   		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;
>> diff --git a/drivers/gpu/drm/i915/intel_wopcm.h b/drivers/gpu/drm/i915/gt/intel_wopcm.h
>> similarity index 100%
>> rename from drivers/gpu/drm/i915/intel_wopcm.h
>> rename to drivers/gpu/drm/i915/gt/intel_wopcm.h
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
>> index dbd048b77e19..4cd8a787f9e5 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
>> @@ -357,8 +357,8 @@ static int uc_init_wopcm(struct intel_uc *uc)
>>   {
>>   	struct intel_gt *gt = uc_to_gt(uc);
>>   	struct intel_uncore *uncore = gt->uncore;
>> -	u32 base = intel_wopcm_guc_base(&gt->i915->wopcm);
>> -	u32 size = intel_wopcm_guc_size(&gt->i915->wopcm);
>> +	u32 base = intel_wopcm_guc_base(&gt->wopcm);
>> +	u32 size = intel_wopcm_guc_size(&gt->wopcm);
>>   	u32 huc_agent = intel_uc_uses_huc(uc) ? HUC_LOADING_AGENT_GUC : 0;
>>   	u32 mask;
>>   	int err;
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> index d6ca772e9f4b..a9ff9abb66db 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> @@ -469,10 +469,11 @@ static int check_gsc_manifest(const struct firmware *fw,
>>   	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;
>>   
>> @@ -514,10 +515,10 @@ static int check_ccs_header(struct drm_i915_private *i915,
>>   
>>   	/* 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;
>>   	}
>>   
>> @@ -545,7 +546,8 @@ static int check_ccs_header(struct drm_i915_private *i915,
>>    */
>>   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;
>> @@ -553,7 +555,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>>   	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);
>> @@ -595,7 +597,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>>   	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;
>>   
>> diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
>> index 9d1fc2477f80..51fc030774fa 100644
>> --- a/drivers/gpu/drm/i915/i915_driver.c
>> +++ b/drivers/gpu/drm/i915/i915_driver.c
>> @@ -369,8 +369,6 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
>>   	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;
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 8ca575202e5d..587e43ad7941 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -63,7 +63,6 @@
>>   #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;
>> @@ -236,8 +235,6 @@ struct drm_i915_private {
>>   
>>   	struct intel_gvt *gvt;
>>   
>> -	struct intel_wopcm wopcm;
>> -
>>   	struct pci_dev *bridge_dev;
>>   
>>   	struct rb_root uabi_engines;
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
>> index a5b192ac885c..cfc8b17c1ee5 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -1140,9 +1140,10 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
>>   	if (ret)
>>   		return ret;
>>   
>> -	for_each_gt(gt, dev_priv, i)
>> +	for_each_gt(gt, dev_priv, i) {
>>   		intel_uc_fetch_firmwares(&gt->uc);
>> -	intel_wopcm_init(&dev_priv->wopcm);
>> +		intel_wopcm_init(&gt->wopcm);
>> +	}
>>   
>>   	ret = i915_init_ggtt(dev_priv);
>>   	if (ret) {
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index a26edcdadc21..6ed4c745b226 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -129,7 +129,9 @@  gt-y += \
 	gt/intel_timeline.o \
 	gt/intel_workarounds.o \
 	gt/shmem_utils.o \
-	gt/sysfs_engines.o
+	gt/sysfs_engines.o \
+	gt/intel_wopcm.o
+
 # x86 intel-gtt module support
 gt-$(CONFIG_X86) += gt/intel_ggtt_gmch.o
 # autogenerated null render state
@@ -183,8 +185,7 @@  i915-y += \
 	  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 \
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 30cf5c3369d9..605e1aa674d4 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -560,7 +560,7 @@  static int init_ggtt(struct i915_ggtt *ggtt)
 	 * 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)
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
index b367cfff48d5..a95eb0b656d2 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -56,6 +56,7 @@  void intel_gt_common_init_early(struct intel_gt *gt)
 	seqcount_mutex_init(&gt->tlb.seqno, &gt->tlb.invalidate_lock);
 	intel_gt_pm_init_early(gt);
 
+	intel_wopcm_init_early(&gt->wopcm);
 	intel_uc_init_early(&gt->uc);
 	intel_rps_init_early(&gt->rps);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index f19c2de77ff6..c20a32d2700f 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -30,6 +30,7 @@ 
 #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;
@@ -97,6 +98,7 @@  struct intel_gt {
 
 	struct intel_uc uc;
 	struct intel_gsc gsc;
+	struct intel_wopcm wopcm;
 
 	struct {
 		/* Serialize global tlb invalidations */
diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/gt/intel_wopcm.c
similarity index 86%
rename from drivers/gpu/drm/i915/intel_wopcm.c
rename to drivers/gpu/drm/i915/gt/intel_wopcm.c
index 322fb9eeb880..487fbbbdf3d6 100644
--- a/drivers/gpu/drm/i915/intel_wopcm.c
+++ b/drivers/gpu/drm/i915/gt/intel_wopcm.c
@@ -43,6 +43,7 @@ 
 /* Default WOPCM size is 2MB from Gen11, 1MB on previous platforms */
 #define GEN11_WOPCM_SIZE		SZ_2M
 #define GEN9_WOPCM_SIZE			SZ_1M
+#define XELPM_SAMEDIA_WOPCM_SIZE	SZ_2M
 #define MAX_WOPCM_SIZE			SZ_8M
 /* 16KB WOPCM (RSVD WOPCM) is reserved from HuC firmware top. */
 #define WOPCM_RESERVED_SIZE		SZ_16K
@@ -64,9 +65,9 @@ 
 #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);
 }
 
 /**
@@ -77,7 +78,8 @@  static inline struct drm_i915_private *wopcm_to_i915(struct intel_wopcm *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;
@@ -157,14 +159,18 @@  static bool check_hw_restrictions(struct drm_i915_private *i915,
 	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;
 
 	size = wopcm_size - ctx_rsvd;
+	if (MEDIA_VER(i915) >= 13)
+		size += XELPM_SAMEDIA_WOPCM_SIZE;
+
 	if (unlikely(range_overflows(guc_wopcm_base, guc_wopcm_size, size))) {
 		drm_err(&i915->drm,
 			"WOPCM: invalid GuC region layout: %uK + %uK > %uK\n",
@@ -181,12 +187,14 @@  static bool __check_layout(struct drm_i915_private *i915, u32 wopcm_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 (VDBOX_MASK(gt)) {
+		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,
@@ -228,8 +236,8 @@  static bool __wopcm_regs_writable(struct intel_uncore *uncore)
  */
 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(&gt->uc.guc.fw);
 	u32 huc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.huc.fw);
 	u32 ctx_rsvd = context_reserved_size(i915);
@@ -274,6 +282,19 @@  void intel_wopcm_init(struct intel_wopcm *wopcm)
 		goto check;
 	}
 
+	/*
+	 * 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 ctx
+	 * that w would have to factor 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.
@@ -289,13 +310,14 @@  void intel_wopcm_init(struct intel_wopcm *wopcm)
 
 	/* Aligned remainings of usable WOPCM space can be assigned to GuC. */
 	guc_wopcm_size = wopcm_size - ctx_rsvd - guc_wopcm_base;
+
 	guc_wopcm_size &= GUC_WOPCM_SIZE_MASK;
 
 	drm_dbg(&i915->drm, "Calculated GuC WOPCM [%uK, %uK)\n",
 		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;
diff --git a/drivers/gpu/drm/i915/intel_wopcm.h b/drivers/gpu/drm/i915/gt/intel_wopcm.h
similarity index 100%
rename from drivers/gpu/drm/i915/intel_wopcm.h
rename to drivers/gpu/drm/i915/gt/intel_wopcm.h
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index dbd048b77e19..4cd8a787f9e5 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -357,8 +357,8 @@  static int uc_init_wopcm(struct intel_uc *uc)
 {
 	struct intel_gt *gt = uc_to_gt(uc);
 	struct intel_uncore *uncore = gt->uncore;
-	u32 base = intel_wopcm_guc_base(&gt->i915->wopcm);
-	u32 size = intel_wopcm_guc_size(&gt->i915->wopcm);
+	u32 base = intel_wopcm_guc_base(&gt->wopcm);
+	u32 size = intel_wopcm_guc_size(&gt->wopcm);
 	u32 huc_agent = intel_uc_uses_huc(uc) ? HUC_LOADING_AGENT_GUC : 0;
 	u32 mask;
 	int err;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index d6ca772e9f4b..a9ff9abb66db 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -469,10 +469,11 @@  static int check_gsc_manifest(const struct firmware *fw,
 	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;
 
@@ -514,10 +515,10 @@  static int check_ccs_header(struct drm_i915_private *i915,
 
 	/* 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;
 	}
 
@@ -545,7 +546,8 @@  static int check_ccs_header(struct drm_i915_private *i915,
  */
 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;
@@ -553,7 +555,7 @@  int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 	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);
@@ -595,7 +597,7 @@  int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 	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;
 
diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
index 9d1fc2477f80..51fc030774fa 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -369,8 +369,6 @@  static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
 	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;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8ca575202e5d..587e43ad7941 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -63,7 +63,6 @@ 
 #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;
@@ -236,8 +235,6 @@  struct drm_i915_private {
 
 	struct intel_gvt *gvt;
 
-	struct intel_wopcm wopcm;
-
 	struct pci_dev *bridge_dev;
 
 	struct rb_root uabi_engines;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a5b192ac885c..cfc8b17c1ee5 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1140,9 +1140,10 @@  int i915_gem_init(struct drm_i915_private *dev_priv)
 	if (ret)
 		return ret;
 
-	for_each_gt(gt, dev_priv, i)
+	for_each_gt(gt, dev_priv, i) {
 		intel_uc_fetch_firmwares(&gt->uc);
-	intel_wopcm_init(&dev_priv->wopcm);
+		intel_wopcm_init(&gt->wopcm);
+	}
 
 	ret = i915_init_ggtt(dev_priv);
 	if (ret) {