dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/7] drm/i915: prepare for uC loading on MTL
@ 2022-10-13  0:03 Daniele Ceraolo Spurio
  2022-10-13  0:03 ` [PATCH v2 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines Daniele Ceraolo Spurio
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-10-13  0:03 UTC (permalink / raw)
  To: intel-gfx
  Cc: Alan Previn, Radhakrishna Sripada, dri-devel,
	Daniele Ceraolo Spurio, Aravind Iddamsetty, John Harrison

The introduction of the media GT brings a few changes for GuC/HuC. The
main difference between the 2 GTs is that only the media one has the
HuC, while both have the GuC. Also, the fact that both GTs use the same
G-unit and GGTT means we now have parallel interrupt/communication
paths. Lastly, WOPCM is divided between the two GTs, with each having
their own private chunk.

v2: address review comments

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: Aravind Iddamsetty <aravind.iddamsetty@intel.com>
Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>

Aravind Iddamsetty (1):
  drm/i915/mtl: Handle wopcm per-GT and limit calculations.

Daniele Ceraolo Spurio (5):
  drm/i915/huc: only load HuC on GTs that have VCS engines
  drm/i915/uc: fetch uc firmwares for each GT
  drm/i915/uc: use different ggtt pin offsets for uc loads
  drm/i915/guc: define media GT GuC send regs
  drm/i915/guc: handle interrupts from media GuC

Stuart Summers (1):
  drm/i915/guc: Add GuC deprivilege feature to MTL

 drivers/gpu/drm/i915/Makefile               |  5 ++-
 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_irq.c      | 21 +++++++--
 drivers/gpu/drm/i915/gt/intel_gt_regs.h     |  2 +
 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_guc.c      | 43 ++++++++++--------
 drivers/gpu/drm/i915/gt/uc/intel_guc.h      |  5 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h  |  2 +
 drivers/gpu/drm/i915/gt/uc/intel_huc.c      | 29 +++++++++++++
 drivers/gpu/drm/i915/gt/uc/intel_uc.c       | 12 ++++--
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c    | 44 +++++++++++++++----
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h    | 13 ++++++
 drivers/gpu/drm/i915/i915_driver.c          |  2 -
 drivers/gpu/drm/i915/i915_drv.h             | 12 +++---
 drivers/gpu/drm/i915/i915_gem.c             |  6 ++-
 drivers/gpu/drm/i915/i915_pci.c             |  1 +
 19 files changed, 189 insertions(+), 61 deletions(-)
 rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c (86%)
 rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h (100%)

-- 
2.37.3


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines
  2022-10-13  0:03 [PATCH v2 0/7] drm/i915: prepare for uC loading on MTL Daniele Ceraolo Spurio
@ 2022-10-13  0:03 ` Daniele Ceraolo Spurio
  2022-10-19  9:31   ` Iddamsetty, Aravind
  2022-10-13  0:03 ` [PATCH v2 2/7] drm/i915/uc: fetch uc firmwares for each GT Daniele Ceraolo Spurio
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-10-13  0:03 UTC (permalink / raw)
  To: intel-gfx
  Cc: Tvrtko Ursulin, Alan Previn, dri-devel, Daniele Ceraolo Spurio,
	Aravind Iddamsetty, John Harrison

On MTL the primary GT doesn't have any media capabilities, so no video
engines and no HuC. We must therefore skip the HuC fetch and load on
that specific case. Given that other multi-GT platforms might have HuC
on the primary GT, we can't just check for that and it is easier to
instead check for the lack of VCS engines.

Based on code from Aravind Iddamsetty

v2: clarify which engine_mask is used for each GT and why (Tvrtko)

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Aravind Iddamsetty <aravind.iddamsetty@intel.com>
Cc: John Harrison <john.c.harrison@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Reviewed-by: Aravind Iddamsetty <aravind.iddamsetty@intel.com> #v1
---
 drivers/gpu/drm/i915/gt/uc/intel_huc.c | 29 ++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_drv.h        |  9 +++++---
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 4d1cc383b681..ca170ea3426c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -203,12 +203,41 @@ void intel_huc_unregister_gsc_notifier(struct intel_huc *huc, struct bus_type *b
 	huc->delayed_load.nb.notifier_call = NULL;
 }
 
+static bool vcs_supported(struct intel_gt *gt)
+{
+	intel_engine_mask_t mask = gt->info.engine_mask;
+
+	/*
+	 * We reach here from i915_driver_early_probe for the primary GT before
+	 * its engine mask is set, so we use the device info engine mask for it;
+	 * this means we're not taking VCS fusing into account, but if the
+	 * primary GT supports VCS engines we expect at least one of them to
+	 * remain unfused so we're fine.
+	 * For other GTs we expect the GT-specific mask to be set before we
+	 * call this function.
+	 */
+	GEM_BUG_ON(!gt_is_root(gt) && !gt->info.engine_mask);
+
+	if (gt_is_root(gt))
+		mask = RUNTIME_INFO(gt->i915)->platform_engine_mask;
+	else
+		mask = gt->info.engine_mask;
+
+	return __ENGINE_INSTANCES_MASK(mask, VCS0, I915_MAX_VCS);
+}
+
 void intel_huc_init_early(struct intel_huc *huc)
 {
 	struct drm_i915_private *i915 = huc_to_gt(huc)->i915;
+	struct intel_gt *gt = huc_to_gt(huc);
 
 	intel_uc_fw_init_early(&huc->fw, INTEL_UC_FW_TYPE_HUC);
 
+	if (!vcs_supported(gt)) {
+		intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_NOT_SUPPORTED);
+		return;
+	}
+
 	if (GRAPHICS_VER(i915) >= 11) {
 		huc->status.reg = GEN11_HUC_KERNEL_LOAD_INFO;
 		huc->status.mask = HUC_LOAD_SUCCESSFUL;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 90ed8e6db2fe..90a347140e90 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -776,12 +776,15 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define __HAS_ENGINE(engine_mask, id) ((engine_mask) & BIT(id))
 #define HAS_ENGINE(gt, id) __HAS_ENGINE((gt)->info.engine_mask, id)
 
-#define ENGINE_INSTANCES_MASK(gt, first, count) ({		\
+#define __ENGINE_INSTANCES_MASK(mask, first, count) ({			\
 	unsigned int first__ = (first);					\
 	unsigned int count__ = (count);					\
-	((gt)->info.engine_mask &						\
-	 GENMASK(first__ + count__ - 1, first__)) >> first__;		\
+	((mask) & GENMASK(first__ + count__ - 1, first__)) >> first__;	\
 })
+
+#define ENGINE_INSTANCES_MASK(gt, first, count) \
+	__ENGINE_INSTANCES_MASK((gt)->info.engine_mask, first, count)
+
 #define RCS_MASK(gt) \
 	ENGINE_INSTANCES_MASK(gt, RCS0, I915_MAX_RCS)
 #define BCS_MASK(gt) \
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 2/7] drm/i915/uc: fetch uc firmwares for each GT
  2022-10-13  0:03 [PATCH v2 0/7] drm/i915: prepare for uC loading on MTL Daniele Ceraolo Spurio
  2022-10-13  0:03 ` [PATCH v2 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines Daniele Ceraolo Spurio
@ 2022-10-13  0:03 ` Daniele Ceraolo Spurio
  2022-10-13  0:03 ` [PATCH v2 3/7] drm/i915/uc: use different ggtt pin offsets for uc loads Daniele Ceraolo Spurio
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-10-13  0:03 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniele Ceraolo Spurio, Alan Previn, John Harrison, dri-devel

The FW binaries are independently loaded on each GT. On MTL, the memory
is shared so we could potentially re-use a single allocation, but on
discrete multi-gt platforms we are going to need independent copies,
so it is easier to do the same on MTL as well, given that the amount
of duplicated memory is relatively small (~500K).

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: John Harrison <john.c.harrison@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
Reviewed-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 55d605c0c55d..9093d2be9e1c 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1140,7 +1140,8 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
 	if (ret)
 		return ret;
 
-	intel_uc_fetch_firmwares(&to_gt(dev_priv)->uc);
+	for_each_gt(gt, dev_priv, i)
+		intel_uc_fetch_firmwares(&gt->uc);
 	intel_wopcm_init(&dev_priv->wopcm);
 
 	ret = i915_init_ggtt(dev_priv);
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 3/7] drm/i915/uc: use different ggtt pin offsets for uc loads
  2022-10-13  0:03 [PATCH v2 0/7] drm/i915: prepare for uC loading on MTL Daniele Ceraolo Spurio
  2022-10-13  0:03 ` [PATCH v2 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines Daniele Ceraolo Spurio
  2022-10-13  0:03 ` [PATCH v2 2/7] drm/i915/uc: fetch uc firmwares for each GT Daniele Ceraolo Spurio
@ 2022-10-13  0:03 ` Daniele Ceraolo Spurio
  2022-10-17 23:44   ` John Harrison
  2022-10-13  0:03 ` [PATCH v2 4/7] drm/i915/guc: Add GuC deprivilege feature to MTL Daniele Ceraolo Spurio
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-10-13  0:03 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniele Ceraolo Spurio, Alan Previn, John Harrison, dri-devel

Our current FW loading process is the same for all FWs:

- Pin FW to GGTT at the start of the ggtt->uc_fw node
- Load the FW
- Unpin

This worked because we didn't have a case where 2 FWs would be loaded on
the same GGTT at the same time. On MTL, however, this can happend if both
GTs are reset at the same time, so we can't pin everything in the same
spot and we need to use separate offset. For simplicity, instead of
calculating the exact required size, we reserve a 2MB slot for each fw.

v2: fail fetch if FW is > 2MBs, improve comments (John)

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: John Harrison <john.c.harrison@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 30 +++++++++++++++++++++---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 13 ++++++++++
 2 files changed, 40 insertions(+), 3 deletions(-)

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 de2843dc1307..021290a26195 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -575,6 +575,17 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 	err = firmware_request_nowarn(&fw, uc_fw->file_selected.path, dev);
 	memcpy(&file_ideal, &uc_fw->file_wanted, sizeof(file_ideal));
 
+	if (!err && fw->size > INTEL_UC_RSVD_GGTT_PER_FW) {
+		drm_err(&i915->drm,
+			"%s firmware %s: size (%zuKB) exceeds max supported size (%uKB)\n",
+			intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
+			fw->size / SZ_1K, INTEL_UC_RSVD_GGTT_PER_FW / SZ_1K);
+
+		/* try to find another blob to load */
+		release_firmware(fw);
+		err = -ENOENT;
+	}
+
 	/* Any error is terminal if overriding. Don't bother searching for older versions */
 	if (err && intel_uc_fw_is_overridden(uc_fw))
 		goto fail;
@@ -677,14 +688,28 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 
 static u32 uc_fw_ggtt_offset(struct intel_uc_fw *uc_fw)
 {
-	struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt;
+	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
+	struct i915_ggtt *ggtt = gt->ggtt;
 	struct drm_mm_node *node = &ggtt->uc_fw;
+	u32 offset = uc_fw->type * INTEL_UC_RSVD_GGTT_PER_FW;
+
+	/*
+	 * To keep the math simple, we use 8MB for the root tile and 8MB for
+	 * the media one. This will need to be updated if we ever have more
+	 * than 1 media GT
+	 */
+	BUILD_BUG_ON(INTEL_UC_FW_NUM_TYPES * INTEL_UC_RSVD_GGTT_PER_FW > SZ_8M);
+	GEM_BUG_ON(gt->type == GT_MEDIA && gt->info.id > 1);
+	if (gt->type == GT_MEDIA)
+		offset += SZ_8M;
 
 	GEM_BUG_ON(!drm_mm_node_allocated(node));
 	GEM_BUG_ON(upper_32_bits(node->start));
 	GEM_BUG_ON(upper_32_bits(node->start + node->size - 1));
+	GEM_BUG_ON(offset + uc_fw->obj->base.size > node->size);
+	GEM_BUG_ON(uc_fw->obj->base.size > INTEL_UC_RSVD_GGTT_PER_FW);
 
-	return lower_32_bits(node->start);
+	return lower_32_bits(node->start + offset);
 }
 
 static void uc_fw_bind_ggtt(struct intel_uc_fw *uc_fw)
@@ -699,7 +724,6 @@ static void uc_fw_bind_ggtt(struct intel_uc_fw *uc_fw)
 	dummy->bi.pages = obj->mm.pages;
 
 	GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
-	GEM_BUG_ON(dummy->node_size > ggtt->uc_fw.size);
 
 	/* uc_fw->obj cache domains were not controlled across suspend */
 	if (i915_gem_object_has_struct_page(obj))
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
index cb586f7df270..7b3db41efa6e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
@@ -6,6 +6,7 @@
 #ifndef _INTEL_UC_FW_H_
 #define _INTEL_UC_FW_H_
 
+#include <linux/sizes.h>
 #include <linux/types.h>
 #include "intel_uc_fw_abi.h"
 #include "intel_device_info.h"
@@ -114,6 +115,18 @@ struct intel_uc_fw {
 						     (uc)->fw.file_selected.minor_ver, \
 						     (uc)->fw.file_selected.patch_ver))
 
+/*
+ * When we load the uC binaries, we pin them in a reserved section at the top of
+ * the GGTT, which is ~18 MBs. On multi-GT systems where the GTs share the GGTT,
+ * we also need to make sure that each binary is pinned to a unique location
+ * during load, because the different GT can go through the FW load at the same
+ * time. Given that the available space is much greater than what is required by
+ * the binaries, to keep things simple instead of dynamically partitioning the
+ * reserved section to make space for all the blobs we can just reserve a static
+ * chunk for each binary.
+ */
+#define INTEL_UC_RSVD_GGTT_PER_FW SZ_2M
+
 #ifdef CONFIG_DRM_I915_DEBUG_GUC
 void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 			       enum intel_uc_fw_status status);
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 4/7] drm/i915/guc: Add GuC deprivilege feature to MTL
  2022-10-13  0:03 [PATCH v2 0/7] drm/i915: prepare for uC loading on MTL Daniele Ceraolo Spurio
                   ` (2 preceding siblings ...)
  2022-10-13  0:03 ` [PATCH v2 3/7] drm/i915/uc: use different ggtt pin offsets for uc loads Daniele Ceraolo Spurio
@ 2022-10-13  0:03 ` Daniele Ceraolo Spurio
  2022-10-13  0:03 ` [PATCH v2 5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations Daniele Ceraolo Spurio
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-10-13  0:03 UTC (permalink / raw)
  To: intel-gfx
  Cc: Stuart Summers, Alan Previn, John Harrison, dri-devel,
	Radhakrishna Sripada

From: Stuart Summers <stuart.summers@intel.com>

MTL supports GuC deprivilege. Add the feature flag to this platform.

Signed-off-by: Stuart Summers <stuart.summers@intel.com>
Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: John Harrison <john.c.harrison@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
Reviewed-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/i915_pci.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 38460a0bd7cb..c252ef31a610 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -1145,6 +1145,7 @@ static const struct intel_device_info mtl_info = {
 	.extra_gt_list = xelpmp_extra_gt,
 	.has_flat_ccs = 0,
 	.has_gmd_id = 1,
+	.has_guc_deprivilege = 1,
 	.has_snoop = 1,
 	.__runtime.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
 	.__runtime.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations.
  2022-10-13  0:03 [PATCH v2 0/7] drm/i915: prepare for uC loading on MTL Daniele Ceraolo Spurio
                   ` (3 preceding siblings ...)
  2022-10-13  0:03 ` [PATCH v2 4/7] drm/i915/guc: Add GuC deprivilege feature to MTL Daniele Ceraolo Spurio
@ 2022-10-13  0:03 ` Daniele Ceraolo Spurio
  2022-10-19  0:44   ` John Harrison
  2022-10-13  0:03 ` [PATCH v2 6/7] drm/i915/guc: define media GT GuC send regs Daniele Ceraolo Spurio
  2022-10-13  0:03 ` [PATCH v2 7/7] drm/i915/guc: handle interrupts from media GuC Daniele Ceraolo Spurio
  6 siblings, 1 reply; 16+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-10-13  0:03 UTC (permalink / raw)
  To: intel-gfx
  Cc: Alan Previn, dri-devel, Daniele Ceraolo Spurio,
	Aravind Iddamsetty, John Harrison

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.

v2: fix makefile file ordering (Jani)

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>
---
 drivers/gpu/drm/i915/Makefile               |  5 ++-
 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, 55 insertions(+), 31 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 f8cc1eb52626..4101b3507346 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -127,9 +127,11 @@ gt-y += \
 	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
@@ -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 5c67e49aacf6..b30560ab1c1b 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 30003d68fd51..a23cd3af5bf2 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;
@@ -98,6 +99,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 021290a26195..57eaece6dada 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -478,10 +478,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;
 
@@ -523,10 +524,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;
 	}
 
@@ -554,7 +555,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;
@@ -562,7 +564,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);
@@ -615,7 +617,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 24d3d2d85fd5..4ebb4ef982e2 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -370,8 +370,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 90a347140e90..24cffe4f9840 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -62,7 +62,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;
@@ -235,8 +234,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 9093d2be9e1c..7a9ce81600a0 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) {
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 6/7] drm/i915/guc: define media GT GuC send regs
  2022-10-13  0:03 [PATCH v2 0/7] drm/i915: prepare for uC loading on MTL Daniele Ceraolo Spurio
                   ` (4 preceding siblings ...)
  2022-10-13  0:03 ` [PATCH v2 5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations Daniele Ceraolo Spurio
@ 2022-10-13  0:03 ` Daniele Ceraolo Spurio
  2022-10-13  0:03 ` [PATCH v2 7/7] drm/i915/guc: handle interrupts from media GuC Daniele Ceraolo Spurio
  6 siblings, 0 replies; 16+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-10-13  0:03 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniele Ceraolo Spurio, Alan Previn, John Harrison, dri-devel

The media GT shares the G-unit with the root GT, so a second set of
communication registers is required for the media GuC.

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
Reviewed-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c     | 14 ++++++++++----
 drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h |  2 ++
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 27b09ba1d295..b3600be61a9a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -156,7 +156,8 @@ static void gen11_disable_guc_interrupts(struct intel_guc *guc)
 
 void intel_guc_init_early(struct intel_guc *guc)
 {
-	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
+	struct intel_gt *gt = guc_to_gt(guc);
+	struct drm_i915_private *i915 = gt->i915;
 
 	intel_uc_fw_init_early(&guc->fw, INTEL_UC_FW_TYPE_GUC);
 	intel_guc_ct_init_early(&guc->ct);
@@ -168,12 +169,17 @@ void intel_guc_init_early(struct intel_guc *guc)
 	mutex_init(&guc->send_mutex);
 	spin_lock_init(&guc->irq_lock);
 	if (GRAPHICS_VER(i915) >= 11) {
-		guc->notify_reg = GEN11_GUC_HOST_INTERRUPT;
 		guc->interrupts.reset = gen11_reset_guc_interrupts;
 		guc->interrupts.enable = gen11_enable_guc_interrupts;
 		guc->interrupts.disable = gen11_disable_guc_interrupts;
-		guc->send_regs.base =
-			i915_mmio_reg_offset(GEN11_SOFT_SCRATCH(0));
+		if (gt->type == GT_MEDIA) {
+			guc->notify_reg = MEDIA_GUC_HOST_INTERRUPT;
+			guc->send_regs.base = i915_mmio_reg_offset(MEDIA_SOFT_SCRATCH(0));
+		} else {
+			guc->notify_reg = GEN11_GUC_HOST_INTERRUPT;
+			guc->send_regs.base = i915_mmio_reg_offset(GEN11_SOFT_SCRATCH(0));
+		}
+
 		guc->send_regs.count = GEN11_SOFT_SCRATCH_COUNT;
 
 	} else {
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
index a7092f711e9c..9915de32e894 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
@@ -36,6 +36,7 @@
 #define SOFT_SCRATCH_COUNT		16
 
 #define GEN11_SOFT_SCRATCH(n)		_MMIO(0x190240 + (n) * 4)
+#define MEDIA_SOFT_SCRATCH(n)		_MMIO(0x190310 + (n) * 4)
 #define GEN11_SOFT_SCRATCH_COUNT	4
 
 #define UOS_RSA_SCRATCH(i)		_MMIO(0xc200 + (i) * 4)
@@ -101,6 +102,7 @@
 #define GUC_SEND_INTERRUPT		_MMIO(0xc4c8)
 #define   GUC_SEND_TRIGGER		  (1<<0)
 #define GEN11_GUC_HOST_INTERRUPT	_MMIO(0x1901f0)
+#define MEDIA_GUC_HOST_INTERRUPT	_MMIO(0x190304)
 
 #define GEN12_GUC_SEM_INTR_ENABLES	_MMIO(0xc71c)
 #define   GUC_SEM_INTR_ROUTE_TO_GUC	BIT(31)
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 7/7] drm/i915/guc: handle interrupts from media GuC
  2022-10-13  0:03 [PATCH v2 0/7] drm/i915: prepare for uC loading on MTL Daniele Ceraolo Spurio
                   ` (5 preceding siblings ...)
  2022-10-13  0:03 ` [PATCH v2 6/7] drm/i915/guc: define media GT GuC send regs Daniele Ceraolo Spurio
@ 2022-10-13  0:03 ` Daniele Ceraolo Spurio
  2022-10-15  0:02   ` Matt Roper
  6 siblings, 1 reply; 16+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-10-13  0:03 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniele Ceraolo Spurio, John Harrison, dri-devel, Alan Previn

The render and media GuCs share the same interrupt enable register, so
we can no longer disable interrupts when we disable communication for
one of the GuCs as this would impact the other GuC. Instead, we keep the
interrupts always enabled in HW and use a variable in the GuC structure
to determine if we want to service the received interrupts or not.

v2: use MTL_ prefix for reg definition (Matt)

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/gt/intel_gt_irq.c  | 21 ++++++++++++++----
 drivers/gpu/drm/i915/gt/intel_gt_regs.h |  2 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.c  | 29 ++++++++++++++-----------
 drivers/gpu/drm/i915/gt/uc/intel_guc.h  |  5 ++++-
 drivers/gpu/drm/i915/gt/uc/intel_uc.c   |  8 +++++--
 5 files changed, 45 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
index f26882fdc24c..f6805088c0eb 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -17,6 +17,9 @@
 
 static void guc_irq_handler(struct intel_guc *guc, u16 iir)
 {
+	if (unlikely(!guc->interrupts.enabled))
+		return;
+
 	if (iir & GUC_INTR_GUC2HOST)
 		intel_guc_to_host_event_handler(guc);
 }
@@ -249,6 +252,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
 {
 	struct intel_uncore *uncore = gt->uncore;
 	u32 irqs = GT_RENDER_USER_INTERRUPT;
+	u32 guc_mask = intel_uc_wants_guc(&gt->uc) ? GUC_INTR_GUC2HOST : 0;
 	const u32 gsc_mask = GSC_IRQ_INTF(0) | GSC_IRQ_INTF(1);
 	u32 dmask;
 	u32 smask;
@@ -299,6 +303,19 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
 	if (HAS_HECI_GSC(gt->i915))
 		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, ~gsc_mask);
 
+	if (guc_mask) {
+		/* the enable bit is common for both GTs but the masks are separate */
+		u32 mask = gt->type == GT_MEDIA ?
+			REG_FIELD_PREP(ENGINE0_MASK, guc_mask) :
+			REG_FIELD_PREP(ENGINE1_MASK, guc_mask);
+
+		intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE,
+				   REG_FIELD_PREP(ENGINE1_MASK, guc_mask));
+
+		/* we might not be the first GT to write this reg */
+		intel_uncore_rmw(uncore, MTL_GUC_MGUC_INTR_MASK, mask, 0);
+	}
+
 	/*
 	 * RPS interrupts will get enabled/disabled on demand when RPS itself
 	 * is enabled/disabled.
@@ -307,10 +324,6 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
 	gt->pm_imr = ~gt->pm_ier;
 	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0);
 	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
-
-	/* Same thing for GuC interrupts */
-	intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE, 0);
-	intel_uncore_write(uncore, GEN11_GUC_SG_INTR_MASK,  ~0);
 }
 
 void gen5_gt_irq_handler(struct intel_gt *gt, u32 gt_iir)
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index 7f79bbf97828..8b597a918f24 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1523,6 +1523,7 @@
 #define   GEN11_CSME				(31)
 #define   GEN11_GUNIT				(28)
 #define   GEN11_GUC				(25)
+#define   MTL_MGUC				(24)
 #define   GEN11_WDPERF				(20)
 #define   GEN11_KCR				(19)
 #define   GEN11_GTPM				(16)
@@ -1577,6 +1578,7 @@
 #define GEN11_VECS0_VECS1_INTR_MASK		_MMIO(0x1900d0)
 #define GEN12_VECS2_VECS3_INTR_MASK		_MMIO(0x1900d4)
 #define GEN11_GUC_SG_INTR_MASK			_MMIO(0x1900e8)
+#define MTL_GUC_MGUC_INTR_MASK			_MMIO(0x1900e8) /* MTL+ */
 #define GEN11_GPM_WGBOXPERF_INTR_MASK		_MMIO(0x1900ec)
 #define GEN11_CRYPTO_RSVD_INTR_MASK		_MMIO(0x1900f0)
 #define GEN11_GUNIT_CSME_INTR_MASK		_MMIO(0x1900f4)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index b3600be61a9a..09f2a673aa19 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -98,6 +98,8 @@ static void gen9_enable_guc_interrupts(struct intel_guc *guc)
 		     gt->pm_guc_events);
 	gen6_gt_pm_enable_irq(gt, gt->pm_guc_events);
 	spin_unlock_irq(gt->irq_lock);
+
+	guc->interrupts.enabled = true;
 }
 
 static void gen9_disable_guc_interrupts(struct intel_guc *guc)
@@ -105,6 +107,7 @@ static void gen9_disable_guc_interrupts(struct intel_guc *guc)
 	struct intel_gt *gt = guc_to_gt(guc);
 
 	assert_rpm_wakelock_held(&gt->i915->runtime_pm);
+	guc->interrupts.enabled = false;
 
 	spin_lock_irq(gt->irq_lock);
 
@@ -116,39 +119,39 @@ static void gen9_disable_guc_interrupts(struct intel_guc *guc)
 	gen9_reset_guc_interrupts(guc);
 }
 
+static bool __gen11_reset_guc_interrupts(struct intel_gt *gt)
+{
+	u32 irq = gt->type == GT_MEDIA ? MTL_MGUC : GEN11_GUC;
+
+	lockdep_assert_held(gt->irq_lock);
+	return gen11_gt_reset_one_iir(gt, 0, irq);
+}
+
 static void gen11_reset_guc_interrupts(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
 
 	spin_lock_irq(gt->irq_lock);
-	gen11_gt_reset_one_iir(gt, 0, GEN11_GUC);
+	__gen11_reset_guc_interrupts(gt);
 	spin_unlock_irq(gt->irq_lock);
 }
 
 static void gen11_enable_guc_interrupts(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
-	u32 events = REG_FIELD_PREP(ENGINE1_MASK, GUC_INTR_GUC2HOST);
 
 	spin_lock_irq(gt->irq_lock);
-	WARN_ON_ONCE(gen11_gt_reset_one_iir(gt, 0, GEN11_GUC));
-	intel_uncore_write(gt->uncore,
-			   GEN11_GUC_SG_INTR_ENABLE, events);
-	intel_uncore_write(gt->uncore,
-			   GEN11_GUC_SG_INTR_MASK, ~events);
+	__gen11_reset_guc_interrupts(gt);
 	spin_unlock_irq(gt->irq_lock);
+
+	guc->interrupts.enabled = true;
 }
 
 static void gen11_disable_guc_interrupts(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
 
-	spin_lock_irq(gt->irq_lock);
-
-	intel_uncore_write(gt->uncore, GEN11_GUC_SG_INTR_MASK, ~0);
-	intel_uncore_write(gt->uncore, GEN11_GUC_SG_INTR_ENABLE, 0);
-
-	spin_unlock_irq(gt->irq_lock);
+	guc->interrupts.enabled = false;
 	intel_synchronize_irq(gt->i915);
 
 	gen11_reset_guc_interrupts(guc);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 804133df1ac9..061d55de3a94 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -78,6 +78,7 @@ struct intel_guc {
 
 	/** @interrupts: pointers to GuC interrupt-managing functions. */
 	struct {
+		bool enabled;
 		void (*reset)(struct intel_guc *guc);
 		void (*enable)(struct intel_guc *guc);
 		void (*disable)(struct intel_guc *guc);
@@ -316,9 +317,11 @@ static inline int intel_guc_send_busy_loop(struct intel_guc *guc,
 	return err;
 }
 
+/* Only call this from the interrupt handler code */
 static inline void intel_guc_to_host_event_handler(struct intel_guc *guc)
 {
-	intel_guc_ct_event_handler(&guc->ct);
+	if (guc->interrupts.enabled)
+		intel_guc_ct_event_handler(&guc->ct);
 }
 
 /* GuC addresses above GUC_GGTT_TOP also don't map through the GTT */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 4cd8a787f9e5..1d28286e6f06 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -636,8 +636,10 @@ void intel_uc_runtime_suspend(struct intel_uc *uc)
 {
 	struct intel_guc *guc = &uc->guc;
 
-	if (!intel_guc_is_ready(guc))
+	if (!intel_guc_is_ready(guc)) {
+		guc->interrupts.enabled = false;
 		return;
+	}
 
 	/*
 	 * Wait for any outstanding CTB before tearing down communication /w the
@@ -657,8 +659,10 @@ void intel_uc_suspend(struct intel_uc *uc)
 	intel_wakeref_t wakeref;
 	int err;
 
-	if (!intel_guc_is_ready(guc))
+	if (!intel_guc_is_ready(guc)) {
+		guc->interrupts.enabled = false;
 		return;
+	}
 
 	with_intel_runtime_pm(&uc_to_gt(uc)->i915->runtime_pm, wakeref) {
 		err = intel_guc_suspend(guc);
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 7/7] drm/i915/guc: handle interrupts from media GuC
  2022-10-13  0:03 ` [PATCH v2 7/7] drm/i915/guc: handle interrupts from media GuC Daniele Ceraolo Spurio
@ 2022-10-15  0:02   ` Matt Roper
  0 siblings, 0 replies; 16+ messages in thread
From: Matt Roper @ 2022-10-15  0:02 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx, Alan Previn, John Harrison, dri-devel

On Wed, Oct 12, 2022 at 05:03:32PM -0700, Daniele Ceraolo Spurio wrote:
> The render and media GuCs share the same interrupt enable register, so
> we can no longer disable interrupts when we disable communication for
> one of the GuCs as this would impact the other GuC. Instead, we keep the
> interrupts always enabled in HW and use a variable in the GuC structure
> to determine if we want to service the received interrupts or not.
> 
> v2: use MTL_ prefix for reg definition (Matt)
> 
> 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>

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

> ---
>  drivers/gpu/drm/i915/gt/intel_gt_irq.c  | 21 ++++++++++++++----
>  drivers/gpu/drm/i915/gt/intel_gt_regs.h |  2 ++
>  drivers/gpu/drm/i915/gt/uc/intel_guc.c  | 29 ++++++++++++++-----------
>  drivers/gpu/drm/i915/gt/uc/intel_guc.h  |  5 ++++-
>  drivers/gpu/drm/i915/gt/uc/intel_uc.c   |  8 +++++--
>  5 files changed, 45 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> index f26882fdc24c..f6805088c0eb 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> @@ -17,6 +17,9 @@
>  
>  static void guc_irq_handler(struct intel_guc *guc, u16 iir)
>  {
> +	if (unlikely(!guc->interrupts.enabled))
> +		return;
> +
>  	if (iir & GUC_INTR_GUC2HOST)
>  		intel_guc_to_host_event_handler(guc);
>  }
> @@ -249,6 +252,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
>  {
>  	struct intel_uncore *uncore = gt->uncore;
>  	u32 irqs = GT_RENDER_USER_INTERRUPT;
> +	u32 guc_mask = intel_uc_wants_guc(&gt->uc) ? GUC_INTR_GUC2HOST : 0;
>  	const u32 gsc_mask = GSC_IRQ_INTF(0) | GSC_IRQ_INTF(1);
>  	u32 dmask;
>  	u32 smask;
> @@ -299,6 +303,19 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
>  	if (HAS_HECI_GSC(gt->i915))
>  		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, ~gsc_mask);
>  
> +	if (guc_mask) {
> +		/* the enable bit is common for both GTs but the masks are separate */
> +		u32 mask = gt->type == GT_MEDIA ?
> +			REG_FIELD_PREP(ENGINE0_MASK, guc_mask) :
> +			REG_FIELD_PREP(ENGINE1_MASK, guc_mask);
> +
> +		intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE,
> +				   REG_FIELD_PREP(ENGINE1_MASK, guc_mask));
> +
> +		/* we might not be the first GT to write this reg */
> +		intel_uncore_rmw(uncore, MTL_GUC_MGUC_INTR_MASK, mask, 0);
> +	}
> +
>  	/*
>  	 * RPS interrupts will get enabled/disabled on demand when RPS itself
>  	 * is enabled/disabled.
> @@ -307,10 +324,6 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
>  	gt->pm_imr = ~gt->pm_ier;
>  	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0);
>  	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
> -
> -	/* Same thing for GuC interrupts */
> -	intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE, 0);
> -	intel_uncore_write(uncore, GEN11_GUC_SG_INTR_MASK,  ~0);
>  }
>  
>  void gen5_gt_irq_handler(struct intel_gt *gt, u32 gt_iir)
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> index 7f79bbf97828..8b597a918f24 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> @@ -1523,6 +1523,7 @@
>  #define   GEN11_CSME				(31)
>  #define   GEN11_GUNIT				(28)
>  #define   GEN11_GUC				(25)
> +#define   MTL_MGUC				(24)
>  #define   GEN11_WDPERF				(20)
>  #define   GEN11_KCR				(19)
>  #define   GEN11_GTPM				(16)
> @@ -1577,6 +1578,7 @@
>  #define GEN11_VECS0_VECS1_INTR_MASK		_MMIO(0x1900d0)
>  #define GEN12_VECS2_VECS3_INTR_MASK		_MMIO(0x1900d4)
>  #define GEN11_GUC_SG_INTR_MASK			_MMIO(0x1900e8)
> +#define MTL_GUC_MGUC_INTR_MASK			_MMIO(0x1900e8) /* MTL+ */
>  #define GEN11_GPM_WGBOXPERF_INTR_MASK		_MMIO(0x1900ec)
>  #define GEN11_CRYPTO_RSVD_INTR_MASK		_MMIO(0x1900f0)
>  #define GEN11_GUNIT_CSME_INTR_MASK		_MMIO(0x1900f4)
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> index b3600be61a9a..09f2a673aa19 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> @@ -98,6 +98,8 @@ static void gen9_enable_guc_interrupts(struct intel_guc *guc)
>  		     gt->pm_guc_events);
>  	gen6_gt_pm_enable_irq(gt, gt->pm_guc_events);
>  	spin_unlock_irq(gt->irq_lock);
> +
> +	guc->interrupts.enabled = true;
>  }
>  
>  static void gen9_disable_guc_interrupts(struct intel_guc *guc)
> @@ -105,6 +107,7 @@ static void gen9_disable_guc_interrupts(struct intel_guc *guc)
>  	struct intel_gt *gt = guc_to_gt(guc);
>  
>  	assert_rpm_wakelock_held(&gt->i915->runtime_pm);
> +	guc->interrupts.enabled = false;
>  
>  	spin_lock_irq(gt->irq_lock);
>  
> @@ -116,39 +119,39 @@ static void gen9_disable_guc_interrupts(struct intel_guc *guc)
>  	gen9_reset_guc_interrupts(guc);
>  }
>  
> +static bool __gen11_reset_guc_interrupts(struct intel_gt *gt)
> +{
> +	u32 irq = gt->type == GT_MEDIA ? MTL_MGUC : GEN11_GUC;
> +
> +	lockdep_assert_held(gt->irq_lock);
> +	return gen11_gt_reset_one_iir(gt, 0, irq);
> +}
> +
>  static void gen11_reset_guc_interrupts(struct intel_guc *guc)
>  {
>  	struct intel_gt *gt = guc_to_gt(guc);
>  
>  	spin_lock_irq(gt->irq_lock);
> -	gen11_gt_reset_one_iir(gt, 0, GEN11_GUC);
> +	__gen11_reset_guc_interrupts(gt);
>  	spin_unlock_irq(gt->irq_lock);
>  }
>  
>  static void gen11_enable_guc_interrupts(struct intel_guc *guc)
>  {
>  	struct intel_gt *gt = guc_to_gt(guc);
> -	u32 events = REG_FIELD_PREP(ENGINE1_MASK, GUC_INTR_GUC2HOST);
>  
>  	spin_lock_irq(gt->irq_lock);
> -	WARN_ON_ONCE(gen11_gt_reset_one_iir(gt, 0, GEN11_GUC));
> -	intel_uncore_write(gt->uncore,
> -			   GEN11_GUC_SG_INTR_ENABLE, events);
> -	intel_uncore_write(gt->uncore,
> -			   GEN11_GUC_SG_INTR_MASK, ~events);
> +	__gen11_reset_guc_interrupts(gt);
>  	spin_unlock_irq(gt->irq_lock);
> +
> +	guc->interrupts.enabled = true;
>  }
>  
>  static void gen11_disable_guc_interrupts(struct intel_guc *guc)
>  {
>  	struct intel_gt *gt = guc_to_gt(guc);
>  
> -	spin_lock_irq(gt->irq_lock);
> -
> -	intel_uncore_write(gt->uncore, GEN11_GUC_SG_INTR_MASK, ~0);
> -	intel_uncore_write(gt->uncore, GEN11_GUC_SG_INTR_ENABLE, 0);
> -
> -	spin_unlock_irq(gt->irq_lock);
> +	guc->interrupts.enabled = false;
>  	intel_synchronize_irq(gt->i915);
>  
>  	gen11_reset_guc_interrupts(guc);
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> index 804133df1ac9..061d55de3a94 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> @@ -78,6 +78,7 @@ struct intel_guc {
>  
>  	/** @interrupts: pointers to GuC interrupt-managing functions. */
>  	struct {
> +		bool enabled;
>  		void (*reset)(struct intel_guc *guc);
>  		void (*enable)(struct intel_guc *guc);
>  		void (*disable)(struct intel_guc *guc);
> @@ -316,9 +317,11 @@ static inline int intel_guc_send_busy_loop(struct intel_guc *guc,
>  	return err;
>  }
>  
> +/* Only call this from the interrupt handler code */
>  static inline void intel_guc_to_host_event_handler(struct intel_guc *guc)
>  {
> -	intel_guc_ct_event_handler(&guc->ct);
> +	if (guc->interrupts.enabled)
> +		intel_guc_ct_event_handler(&guc->ct);
>  }
>  
>  /* GuC addresses above GUC_GGTT_TOP also don't map through the GTT */
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> index 4cd8a787f9e5..1d28286e6f06 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> @@ -636,8 +636,10 @@ void intel_uc_runtime_suspend(struct intel_uc *uc)
>  {
>  	struct intel_guc *guc = &uc->guc;
>  
> -	if (!intel_guc_is_ready(guc))
> +	if (!intel_guc_is_ready(guc)) {
> +		guc->interrupts.enabled = false;
>  		return;
> +	}
>  
>  	/*
>  	 * Wait for any outstanding CTB before tearing down communication /w the
> @@ -657,8 +659,10 @@ void intel_uc_suspend(struct intel_uc *uc)
>  	intel_wakeref_t wakeref;
>  	int err;
>  
> -	if (!intel_guc_is_ready(guc))
> +	if (!intel_guc_is_ready(guc)) {
> +		guc->interrupts.enabled = false;
>  		return;
> +	}
>  
>  	with_intel_runtime_pm(&uc_to_gt(uc)->i915->runtime_pm, wakeref) {
>  		err = intel_guc_suspend(guc);
> -- 
> 2.37.3
> 

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 3/7] drm/i915/uc: use different ggtt pin offsets for uc loads
  2022-10-13  0:03 ` [PATCH v2 3/7] drm/i915/uc: use different ggtt pin offsets for uc loads Daniele Ceraolo Spurio
@ 2022-10-17 23:44   ` John Harrison
  2022-10-18 20:25     ` Ceraolo Spurio, Daniele
  0 siblings, 1 reply; 16+ messages in thread
From: John Harrison @ 2022-10-17 23:44 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Alan Previn, dri-devel

On 10/12/2022 17:03, Daniele Ceraolo Spurio wrote:
> Our current FW loading process is the same for all FWs:
>
> - Pin FW to GGTT at the start of the ggtt->uc_fw node
> - Load the FW
> - Unpin
>
> This worked because we didn't have a case where 2 FWs would be loaded on
> the same GGTT at the same time. On MTL, however, this can happend if both
> GTs are reset at the same time, so we can't pin everything in the same
> spot and we need to use separate offset. For simplicity, instead of
> calculating the exact required size, we reserve a 2MB slot for each fw.
>
> v2: fail fetch if FW is > 2MBs, improve comments (John)
>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: John Harrison <john.c.harrison@intel.com>
> Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
> ---
>   drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 30 +++++++++++++++++++++---
>   drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 13 ++++++++++
>   2 files changed, 40 insertions(+), 3 deletions(-)
>
> 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 de2843dc1307..021290a26195 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> @@ -575,6 +575,17 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>   	err = firmware_request_nowarn(&fw, uc_fw->file_selected.path, dev);
>   	memcpy(&file_ideal, &uc_fw->file_wanted, sizeof(file_ideal));
>   
> +	if (!err && fw->size > INTEL_UC_RSVD_GGTT_PER_FW) {
> +		drm_err(&i915->drm,
> +			"%s firmware %s: size (%zuKB) exceeds max supported size (%uKB)\n",
> +			intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
> +			fw->size / SZ_1K, INTEL_UC_RSVD_GGTT_PER_FW / SZ_1K);
> +
> +		/* try to find another blob to load */
> +		release_firmware(fw);
> +		err = -ENOENT;
> +	}
> +
>   	/* Any error is terminal if overriding. Don't bother searching for older versions */
>   	if (err && intel_uc_fw_is_overridden(uc_fw))
>   		goto fail;
> @@ -677,14 +688,28 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>   
>   static u32 uc_fw_ggtt_offset(struct intel_uc_fw *uc_fw)
>   {
> -	struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt;
> +	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
> +	struct i915_ggtt *ggtt = gt->ggtt;
>   	struct drm_mm_node *node = &ggtt->uc_fw;
> +	u32 offset = uc_fw->type * INTEL_UC_RSVD_GGTT_PER_FW;
> +
> +	/*
> +	 * To keep the math simple, we use 8MB for the root tile and 8MB for
> +	 * the media one. This will need to be updated if we ever have more
> +	 * than 1 media GT
> +	 */
> +	BUILD_BUG_ON(INTEL_UC_FW_NUM_TYPES * INTEL_UC_RSVD_GGTT_PER_FW > SZ_8M);
> +	GEM_BUG_ON(gt->type == GT_MEDIA && gt->info.id > 1);
> +	if (gt->type == GT_MEDIA)
> +		offset += SZ_8M;
This is all because render/media GTs share the same page tables? Regular 
multi-tile is completely separate address spaces and can use a single 
common address? Otherwise, it seems like 'offset = gt->info.id * 2M' 
would be the generic solution and no reference to GT_MEDIA required. So 
maybe add a quick comment to that effect?


>   
>   	GEM_BUG_ON(!drm_mm_node_allocated(node));
>   	GEM_BUG_ON(upper_32_bits(node->start));
>   	GEM_BUG_ON(upper_32_bits(node->start + node->size - 1));
> +	GEM_BUG_ON(offset + uc_fw->obj->base.size > node->size);
> +	GEM_BUG_ON(uc_fw->obj->base.size > INTEL_UC_RSVD_GGTT_PER_FW);
>   
> -	return lower_32_bits(node->start);
> +	return lower_32_bits(node->start + offset);
>   }
>   
>   static void uc_fw_bind_ggtt(struct intel_uc_fw *uc_fw)
> @@ -699,7 +724,6 @@ static void uc_fw_bind_ggtt(struct intel_uc_fw *uc_fw)
>   	dummy->bi.pages = obj->mm.pages;
>   
>   	GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
> -	GEM_BUG_ON(dummy->node_size > ggtt->uc_fw.size);
>   
>   	/* uc_fw->obj cache domains were not controlled across suspend */
>   	if (i915_gem_object_has_struct_page(obj))
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> index cb586f7df270..7b3db41efa6e 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> @@ -6,6 +6,7 @@
>   #ifndef _INTEL_UC_FW_H_
>   #define _INTEL_UC_FW_H_
>   
> +#include <linux/sizes.h>
>   #include <linux/types.h>
>   #include "intel_uc_fw_abi.h"
>   #include "intel_device_info.h"
> @@ -114,6 +115,18 @@ struct intel_uc_fw {
>   						     (uc)->fw.file_selected.minor_ver, \
>   						     (uc)->fw.file_selected.patch_ver))
>   
> +/*
> + * When we load the uC binaries, we pin them in a reserved section at the top of
> + * the GGTT, which is ~18 MBs. On multi-GT systems where the GTs share the GGTT,
^^^ meaning only systems with a render GT + media GT as opposed to 
regular multi-GT systems? Would be good to make that explicit either 
here or above (or both).

John.

> + * we also need to make sure that each binary is pinned to a unique location
> + * during load, because the different GT can go through the FW load at the same
> + * time. Given that the available space is much greater than what is required by
> + * the binaries, to keep things simple instead of dynamically partitioning the
> + * reserved section to make space for all the blobs we can just reserve a static
> + * chunk for each binary.
> + */
> +#define INTEL_UC_RSVD_GGTT_PER_FW SZ_2M
> +
>   #ifdef CONFIG_DRM_I915_DEBUG_GUC
>   void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
>   			       enum intel_uc_fw_status status);


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 3/7] drm/i915/uc: use different ggtt pin offsets for uc loads
  2022-10-17 23:44   ` John Harrison
@ 2022-10-18 20:25     ` Ceraolo Spurio, Daniele
  0 siblings, 0 replies; 16+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-10-18 20:25 UTC (permalink / raw)
  To: John Harrison, intel-gfx; +Cc: Alan Previn, dri-devel



On 10/17/2022 4:44 PM, John Harrison wrote:
> On 10/12/2022 17:03, Daniele Ceraolo Spurio wrote:
>> Our current FW loading process is the same for all FWs:
>>
>> - Pin FW to GGTT at the start of the ggtt->uc_fw node
>> - Load the FW
>> - Unpin
>>
>> This worked because we didn't have a case where 2 FWs would be loaded on
>> the same GGTT at the same time. On MTL, however, this can happend if 
>> both
>> GTs are reset at the same time, so we can't pin everything in the same
>> spot and we need to use separate offset. For simplicity, instead of
>> calculating the exact required size, we reserve a 2MB slot for each fw.
>>
>> v2: fail fetch if FW is > 2MBs, improve comments (John)
>>
>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>> Cc: John Harrison <john.c.harrison@intel.com>
>> Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
>> ---
>>   drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 30 +++++++++++++++++++++---
>>   drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 13 ++++++++++
>>   2 files changed, 40 insertions(+), 3 deletions(-)
>>
>> 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 de2843dc1307..021290a26195 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> @@ -575,6 +575,17 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>>       err = firmware_request_nowarn(&fw, uc_fw->file_selected.path, 
>> dev);
>>       memcpy(&file_ideal, &uc_fw->file_wanted, sizeof(file_ideal));
>>   +    if (!err && fw->size > INTEL_UC_RSVD_GGTT_PER_FW) {
>> +        drm_err(&i915->drm,
>> +            "%s firmware %s: size (%zuKB) exceeds max supported size 
>> (%uKB)\n",
>> +            intel_uc_fw_type_repr(uc_fw->type), 
>> uc_fw->file_selected.path,
>> +            fw->size / SZ_1K, INTEL_UC_RSVD_GGTT_PER_FW / SZ_1K);
>> +
>> +        /* try to find another blob to load */
>> +        release_firmware(fw);
>> +        err = -ENOENT;
>> +    }
>> +
>>       /* Any error is terminal if overriding. Don't bother searching 
>> for older versions */
>>       if (err && intel_uc_fw_is_overridden(uc_fw))
>>           goto fail;
>> @@ -677,14 +688,28 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>>     static u32 uc_fw_ggtt_offset(struct intel_uc_fw *uc_fw)
>>   {
>> -    struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt;
>> +    struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
>> +    struct i915_ggtt *ggtt = gt->ggtt;
>>       struct drm_mm_node *node = &ggtt->uc_fw;
>> +    u32 offset = uc_fw->type * INTEL_UC_RSVD_GGTT_PER_FW;
>> +
>> +    /*
>> +     * To keep the math simple, we use 8MB for the root tile and 8MB 
>> for
>> +     * the media one. This will need to be updated if we ever have more
>> +     * than 1 media GT
>> +     */
>> +    BUILD_BUG_ON(INTEL_UC_FW_NUM_TYPES * INTEL_UC_RSVD_GGTT_PER_FW > 
>> SZ_8M);
>> +    GEM_BUG_ON(gt->type == GT_MEDIA && gt->info.id > 1);
>> +    if (gt->type == GT_MEDIA)
>> +        offset += SZ_8M;
> This is all because render/media GTs share the same page tables? 
> Regular multi-tile is completely separate address spaces and can use a 
> single common address? Otherwise, it seems like 'offset = gt->info.id 
> * 2M' would be the generic solution and no reference to GT_MEDIA 
> required. So maybe add a quick comment to that effect?

Yup this is only because of the GGTT sharing. There is already a comment 
somewhere else, but I'll add one here as well.

>
>
>> GEM_BUG_ON(!drm_mm_node_allocated(node));
>>       GEM_BUG_ON(upper_32_bits(node->start));
>>       GEM_BUG_ON(upper_32_bits(node->start + node->size - 1));
>> +    GEM_BUG_ON(offset + uc_fw->obj->base.size > node->size);
>> +    GEM_BUG_ON(uc_fw->obj->base.size > INTEL_UC_RSVD_GGTT_PER_FW);
>>   -    return lower_32_bits(node->start);
>> +    return lower_32_bits(node->start + offset);
>>   }
>>     static void uc_fw_bind_ggtt(struct intel_uc_fw *uc_fw)
>> @@ -699,7 +724,6 @@ static void uc_fw_bind_ggtt(struct intel_uc_fw 
>> *uc_fw)
>>       dummy->bi.pages = obj->mm.pages;
>>         GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
>> -    GEM_BUG_ON(dummy->node_size > ggtt->uc_fw.size);
>>         /* uc_fw->obj cache domains were not controlled across 
>> suspend */
>>       if (i915_gem_object_has_struct_page(obj))
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h 
>> b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> index cb586f7df270..7b3db41efa6e 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> @@ -6,6 +6,7 @@
>>   #ifndef _INTEL_UC_FW_H_
>>   #define _INTEL_UC_FW_H_
>>   +#include <linux/sizes.h>
>>   #include <linux/types.h>
>>   #include "intel_uc_fw_abi.h"
>>   #include "intel_device_info.h"
>> @@ -114,6 +115,18 @@ struct intel_uc_fw {
>> (uc)->fw.file_selected.minor_ver, \
>> (uc)->fw.file_selected.patch_ver))
>>   +/*
>> + * When we load the uC binaries, we pin them in a reserved section 
>> at the top of
>> + * the GGTT, which is ~18 MBs. On multi-GT systems where the GTs 
>> share the GGTT,
> ^^^ meaning only systems with a render GT + media GT as opposed to 
> regular multi-GT systems? Would be good to make that explicit either 
> here or above (or both).

I'll add a comment above where we reference the media gt.

Daniele

>
> John.
>
>> + * we also need to make sure that each binary is pinned to a unique 
>> location
>> + * during load, because the different GT can go through the FW load 
>> at the same
>> + * time. Given that the available space is much greater than what is 
>> required by
>> + * the binaries, to keep things simple instead of dynamically 
>> partitioning the
>> + * reserved section to make space for all the blobs we can just 
>> reserve a static
>> + * chunk for each binary.
>> + */
>> +#define INTEL_UC_RSVD_GGTT_PER_FW SZ_2M
>> +
>>   #ifdef CONFIG_DRM_I915_DEBUG_GUC
>>   void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
>>                      enum intel_uc_fw_status status);
>


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations.
  2022-10-13  0:03 ` [PATCH v2 5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations Daniele Ceraolo Spurio
@ 2022-10-19  0:44   ` John Harrison
  2022-10-19  3:46     ` Matt Roper
                       ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: John Harrison @ 2022-10-19  0:44 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx
  Cc: Aravind Iddamsetty, dri-devel, Alan Previn

On 10/12/2022 17:03, Daniele Ceraolo Spurio 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
What is GCD?

> 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.
>
> v2: fix makefile file ordering (Jani)
>
> 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>
> ---
>   drivers/gpu/drm/i915/Makefile               |  5 ++-
>   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, 55 insertions(+), 31 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 f8cc1eb52626..4101b3507346 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -127,9 +127,11 @@ gt-y += \
>   	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
> @@ -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 5c67e49aacf6..b30560ab1c1b 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 30003d68fd51..a23cd3af5bf2 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;
> @@ -98,6 +99,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
XELPM? Isn't it just XELP?

>   #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;
This should check VDBOX_MASK as well?

> +
>   	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)) {
Should this not check for VEBOX as well? Or is it guaranteed that you 
can't have VECS without VCS?

> +		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
ctx -> context - should not use such abbreviations in comments. It's 
unnecessary and makes the text harder to read.
> +	 * that w would have to factor in. However, all platforms with a media
that w would have to fact in -> that would have to be factored in

> +	 * 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;
> +
Extra blank link part way through calculating the guc_wopcm_size 
variable because?

John.

>   	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 021290a26195..57eaece6dada 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> @@ -478,10 +478,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;
>   
> @@ -523,10 +524,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;
>   	}
>   
> @@ -554,7 +555,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;
> @@ -562,7 +564,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);
> @@ -615,7 +617,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 24d3d2d85fd5..4ebb4ef982e2 100644
> --- a/drivers/gpu/drm/i915/i915_driver.c
> +++ b/drivers/gpu/drm/i915/i915_driver.c
> @@ -370,8 +370,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 90a347140e90..24cffe4f9840 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -62,7 +62,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;
> @@ -235,8 +234,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 9093d2be9e1c..7a9ce81600a0 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) {


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations.
  2022-10-19  0:44   ` John Harrison
@ 2022-10-19  3:46     ` Matt Roper
  2022-10-19  9:39     ` Iddamsetty, Aravind
  2022-10-20 23:24     ` Ceraolo Spurio, Daniele
  2 siblings, 0 replies; 16+ messages in thread
From: Matt Roper @ 2022-10-19  3:46 UTC (permalink / raw)
  To: John Harrison
  Cc: Alan Previn, intel-gfx, Daniele Ceraolo Spurio, dri-devel,
	Aravind Iddamsetty

On Tue, Oct 18, 2022 at 05:44:38PM -0700, John Harrison wrote:
> On 10/12/2022 17:03, Daniele Ceraolo Spurio wrote:
> > From: Aravind Iddamsetty <aravind.iddamsetty@intel.com>
> > 
...
> > 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
> XELPM? Isn't it just XELP?

Xe_LP is the older TGL-ADL gfx IP name.  MTL's media IP is called
Xe_LPM+ (which we should label as XELPMP in code, so it looks like the
final "P" is missing here).


Matt

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines
  2022-10-13  0:03 ` [PATCH v2 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines Daniele Ceraolo Spurio
@ 2022-10-19  9:31   ` Iddamsetty, Aravind
  0 siblings, 0 replies; 16+ messages in thread
From: Iddamsetty, Aravind @ 2022-10-19  9:31 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx
  Cc: Tvrtko Ursulin, Alan Previn, John Harrison, dri-devel



On 13-10-2022 05:33, Daniele Ceraolo Spurio wrote:
> On MTL the primary GT doesn't have any media capabilities, so no video
> engines and no HuC. We must therefore skip the HuC fetch and load on
> that specific case. Given that other multi-GT platforms might have HuC
> on the primary GT, we can't just check for that and it is easier to
> instead check for the lack of VCS engines.
> 
> Based on code from Aravind Iddamsetty
> 
> v2: clarify which engine_mask is used for each GT and why (Tvrtko)
> 
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Aravind Iddamsetty <aravind.iddamsetty@intel.com>
> Cc: John Harrison <john.c.harrison@intel.com>
> Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> Reviewed-by: Aravind Iddamsetty <aravind.iddamsetty@intel.com> #v1
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_huc.c | 29 ++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_drv.h        |  9 +++++---
>  2 files changed, 35 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> index 4d1cc383b681..ca170ea3426c 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> @@ -203,12 +203,41 @@ void intel_huc_unregister_gsc_notifier(struct intel_huc *huc, struct bus_type *b
>  	huc->delayed_load.nb.notifier_call = NULL;
>  }
>  
> +static bool vcs_supported(struct intel_gt *gt)
> +{
> +	intel_engine_mask_t mask = gt->info.engine_mask;
> +
> +	/*
> +	 * We reach here from i915_driver_early_probe for the primary GT before
> +	 * its engine mask is set, so we use the device info engine mask for it;
> +	 * this means we're not taking VCS fusing into account, but if the
> +	 * primary GT supports VCS engines we expect at least one of them to
> +	 * remain unfused so we're fine.
> +	 * For other GTs we expect the GT-specific mask to be set before we
> +	 * call this function.
> +	 */
Comment sounds good to me. as the rest of the change is same as v1, You
can have my r-b for this.

Thanks,
Aravind.
> +	GEM_BUG_ON(!gt_is_root(gt) && !gt->info.engine_mask);
> +
> +	if (gt_is_root(gt))
> +		mask = RUNTIME_INFO(gt->i915)->platform_engine_mask;
> +	else
> +		mask = gt->info.engine_mask;
> +
> +	return __ENGINE_INSTANCES_MASK(mask, VCS0, I915_MAX_VCS);
> +}
> +
>  void intel_huc_init_early(struct intel_huc *huc)
>  {
>  	struct drm_i915_private *i915 = huc_to_gt(huc)->i915;
> +	struct intel_gt *gt = huc_to_gt(huc);
>  
>  	intel_uc_fw_init_early(&huc->fw, INTEL_UC_FW_TYPE_HUC);
>  
> +	if (!vcs_supported(gt)) {
> +		intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_NOT_SUPPORTED);
> +		return;
> +	}
> +
>  	if (GRAPHICS_VER(i915) >= 11) {
>  		huc->status.reg = GEN11_HUC_KERNEL_LOAD_INFO;
>  		huc->status.mask = HUC_LOAD_SUCCESSFUL;
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 90ed8e6db2fe..90a347140e90 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -776,12 +776,15 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
>  #define __HAS_ENGINE(engine_mask, id) ((engine_mask) & BIT(id))
>  #define HAS_ENGINE(gt, id) __HAS_ENGINE((gt)->info.engine_mask, id)
>  
> -#define ENGINE_INSTANCES_MASK(gt, first, count) ({		\
> +#define __ENGINE_INSTANCES_MASK(mask, first, count) ({			\
>  	unsigned int first__ = (first);					\
>  	unsigned int count__ = (count);					\
> -	((gt)->info.engine_mask &						\
> -	 GENMASK(first__ + count__ - 1, first__)) >> first__;		\
> +	((mask) & GENMASK(first__ + count__ - 1, first__)) >> first__;	\
>  })
> +
> +#define ENGINE_INSTANCES_MASK(gt, first, count) \
> +	__ENGINE_INSTANCES_MASK((gt)->info.engine_mask, first, count)
> +
>  #define RCS_MASK(gt) \
>  	ENGINE_INSTANCES_MASK(gt, RCS0, I915_MAX_RCS)
>  #define BCS_MASK(gt) \

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations.
  2022-10-19  0:44   ` John Harrison
  2022-10-19  3:46     ` Matt Roper
@ 2022-10-19  9:39     ` Iddamsetty, Aravind
  2022-10-20 23:24     ` Ceraolo Spurio, Daniele
  2 siblings, 0 replies; 16+ messages in thread
From: Iddamsetty, Aravind @ 2022-10-19  9:39 UTC (permalink / raw)
  To: John Harrison, Daniele Ceraolo Spurio, intel-gfx; +Cc: Alan Previn, dri-devel



On 19-10-2022 06:14, John Harrison wrote:
> On 10/12/2022 17:03, Daniele Ceraolo Spurio 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
> What is GCD?

Graphics Companion Die, no media on it.

Thanks,
Aravind.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations.
  2022-10-19  0:44   ` John Harrison
  2022-10-19  3:46     ` Matt Roper
  2022-10-19  9:39     ` Iddamsetty, Aravind
@ 2022-10-20 23:24     ` Ceraolo Spurio, Daniele
  2 siblings, 0 replies; 16+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-10-20 23:24 UTC (permalink / raw)
  To: John Harrison, intel-gfx; +Cc: Aravind Iddamsetty, dri-devel, Alan Previn



On 10/18/2022 5:44 PM, John Harrison wrote:
> On 10/12/2022 17:03, Daniele Ceraolo Spurio 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
> What is GCD?
>
>> 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.
>>
>> v2: fix makefile file ordering (Jani)
>>
>> 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>
>> ---
>>   drivers/gpu/drm/i915/Makefile               |  5 ++-
>>   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, 55 insertions(+), 31 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 f8cc1eb52626..4101b3507346 100644
>> --- a/drivers/gpu/drm/i915/Makefile
>> +++ b/drivers/gpu/drm/i915/Makefile
>> @@ -127,9 +127,11 @@ gt-y += \
>>       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
>> @@ -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 5c67e49aacf6..b30560ab1c1b 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 30003d68fd51..a23cd3af5bf2 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;
>> @@ -98,6 +99,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
> XELPM? Isn't it just XELP?
>
>>   #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;
> This should check VDBOX_MASK as well?

No, because the total WOPCM size that we must verify the settings 
against includes both the root and the media partition. However, this is 
not really needed because we're already bumping the size to WOPCM_MAX 
(because the register are pre-locked by the bios, so we only need to 
make sure they are within the boundaries).

>
>> +
>>       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)) {
> Should this not check for VEBOX as well? Or is it guaranteed that you 
> can't have VECS without VCS?

This is to check for HuC support, which is VCS-specific. I'll switch it 
to intel_uc_supports_huc

Daniele

>
>> +        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
> ctx -> context - should not use such abbreviations in comments. It's 
> unnecessary and makes the text harder to read.
>> +     * that w would have to factor in. However, all platforms with a 
>> media
> that w would have to fact in -> that would have to be factored in
>
>> +     * 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;
>> +
> Extra blank link part way through calculating the guc_wopcm_size 
> variable because?
>
> John.
>
>>       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 021290a26195..57eaece6dada 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> @@ -478,10 +478,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;
>>   @@ -523,10 +524,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;
>>       }
>>   @@ -554,7 +555,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;
>> @@ -562,7 +564,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);
>> @@ -615,7 +617,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 24d3d2d85fd5..4ebb4ef982e2 100644
>> --- a/drivers/gpu/drm/i915/i915_driver.c
>> +++ b/drivers/gpu/drm/i915/i915_driver.c
>> @@ -370,8 +370,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 90a347140e90..24cffe4f9840 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -62,7 +62,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;
>> @@ -235,8 +234,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 9093d2be9e1c..7a9ce81600a0 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) {
>


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2022-10-20 23:24 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-13  0:03 [PATCH v2 0/7] drm/i915: prepare for uC loading on MTL Daniele Ceraolo Spurio
2022-10-13  0:03 ` [PATCH v2 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines Daniele Ceraolo Spurio
2022-10-19  9:31   ` Iddamsetty, Aravind
2022-10-13  0:03 ` [PATCH v2 2/7] drm/i915/uc: fetch uc firmwares for each GT Daniele Ceraolo Spurio
2022-10-13  0:03 ` [PATCH v2 3/7] drm/i915/uc: use different ggtt pin offsets for uc loads Daniele Ceraolo Spurio
2022-10-17 23:44   ` John Harrison
2022-10-18 20:25     ` Ceraolo Spurio, Daniele
2022-10-13  0:03 ` [PATCH v2 4/7] drm/i915/guc: Add GuC deprivilege feature to MTL Daniele Ceraolo Spurio
2022-10-13  0:03 ` [PATCH v2 5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations Daniele Ceraolo Spurio
2022-10-19  0:44   ` John Harrison
2022-10-19  3:46     ` Matt Roper
2022-10-19  9:39     ` Iddamsetty, Aravind
2022-10-20 23:24     ` Ceraolo Spurio, Daniele
2022-10-13  0:03 ` [PATCH v2 6/7] drm/i915/guc: define media GT GuC send regs Daniele Ceraolo Spurio
2022-10-13  0:03 ` [PATCH v2 7/7] drm/i915/guc: handle interrupts from media GuC Daniele Ceraolo Spurio
2022-10-15  0:02   ` Matt Roper

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).