All of lore.kernel.org
 help / color / mirror / Atom feed
* [Intel-gfx] [PATCH 0/7] drm/i915: prepare for uC loading on MTL
@ 2022-09-22 22:11 ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alan Previn, dri-devel

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.

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               |  7 +--
 drivers/gpu/drm/i915/gt/intel_ggtt.c        |  2 +-
 drivers/gpu/drm/i915/gt/intel_gt.c          |  1 +
 drivers/gpu/drm/i915/gt/intel_gt_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      | 21 +++++++++
 drivers/gpu/drm/i915/gt/uc/intel_uc.c       | 12 ++++--
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c    | 36 ++++++++++++----
 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 +
 18 files changed, 161 insertions(+), 62 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] 48+ messages in thread

* [PATCH 0/7] drm/i915: prepare for uC loading on MTL
@ 2022-09-22 22:11 ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 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.

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               |  7 +--
 drivers/gpu/drm/i915/gt/intel_ggtt.c        |  2 +-
 drivers/gpu/drm/i915/gt/intel_gt.c          |  1 +
 drivers/gpu/drm/i915/gt/intel_gt_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      | 21 +++++++++
 drivers/gpu/drm/i915/gt/uc/intel_uc.c       | 12 ++++--
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c    | 36 ++++++++++++----
 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 +
 18 files changed, 161 insertions(+), 62 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] 48+ messages in thread

* [Intel-gfx] [PATCH 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines
  2022-09-22 22:11 ` Daniele Ceraolo Spurio
@ 2022-09-22 22:11   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alan Previn, dri-devel

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

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>
---
 drivers/gpu/drm/i915/gt/uc/intel_huc.c | 21 +++++++++++++++++++++
 drivers/gpu/drm/i915/i915_drv.h        |  9 ++++++---
 2 files changed, 27 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 3bb8838e325a..d4e2b252f16c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -42,12 +42,33 @@
  * HuC-specific commands.
  */
 
+static bool vcs_supported(struct intel_gt *gt)
+{
+	intel_engine_mask_t mask = gt->info.engine_mask;
+
+	/*
+	 * we can reach here from i915_driver_early_probe for primary
+	 * GT with it being not fully setup hence fall back to the device info's
+	 * engine mask
+	 */
+	if (!mask && gt_is_root(gt))
+		mask = RUNTIME_INFO(gt->i915)->platform_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 134fc1621821..8ca575202e5d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -777,12 +777,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] 48+ messages in thread

* [PATCH 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines
@ 2022-09-22 22:11   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 UTC (permalink / raw)
  To: intel-gfx
  Cc: John Harrison, Daniele Ceraolo Spurio, Alan Previn,
	Aravind Iddamsetty, dri-devel

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

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>
---
 drivers/gpu/drm/i915/gt/uc/intel_huc.c | 21 +++++++++++++++++++++
 drivers/gpu/drm/i915/i915_drv.h        |  9 ++++++---
 2 files changed, 27 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 3bb8838e325a..d4e2b252f16c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -42,12 +42,33 @@
  * HuC-specific commands.
  */
 
+static bool vcs_supported(struct intel_gt *gt)
+{
+	intel_engine_mask_t mask = gt->info.engine_mask;
+
+	/*
+	 * we can reach here from i915_driver_early_probe for primary
+	 * GT with it being not fully setup hence fall back to the device info's
+	 * engine mask
+	 */
+	if (!mask && gt_is_root(gt))
+		mask = RUNTIME_INFO(gt->i915)->platform_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 134fc1621821..8ca575202e5d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -777,12 +777,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] 48+ messages in thread

* [PATCH 2/7] drm/i915/uc: fetch uc firmwares for each GT
  2022-09-22 22:11 ` Daniele Ceraolo Spurio
@ 2022-09-22 22:11   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 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>
---
 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 88df9a35e0fe..a5b192ac885c 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] 48+ messages in thread

* [Intel-gfx] [PATCH 2/7] drm/i915/uc: fetch uc firmwares for each GT
@ 2022-09-22 22:11   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alan Previn, 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>
---
 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 88df9a35e0fe..a5b192ac885c 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] 48+ messages in thread

* [PATCH 3/7] drm/i915/uc: use different ggtt pin offsets for uc loads
  2022-09-22 22:11 ` Daniele Ceraolo Spurio
@ 2022-09-22 22:11   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 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.

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 | 22 +++++++++++++++++++---
 1 file changed, 19 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 b91ad4aede1f..d6ca772e9f4b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -666,16 +666,33 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 	return err;
 }
 
+/*
+ * The reserved GGTT space is ~18 MBs. All our blobs are well below 1MB, so for
+ * safety we reserve 2MB each.
+ */
+#define INTEL_UC_RSVD_GGTT_PER_FW SZ_2M
 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.
+	 */
+	BUILD_BUG_ON(INTEL_UC_FW_NUM_TYPES * INTEL_UC_RSVD_GGTT_PER_FW > SZ_8M);
+	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)
@@ -690,7 +707,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))
-- 
2.37.3


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

* [Intel-gfx] [PATCH 3/7] drm/i915/uc: use different ggtt pin offsets for uc loads
@ 2022-09-22 22:11   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alan Previn, 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.

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 | 22 +++++++++++++++++++---
 1 file changed, 19 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 b91ad4aede1f..d6ca772e9f4b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -666,16 +666,33 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 	return err;
 }
 
+/*
+ * The reserved GGTT space is ~18 MBs. All our blobs are well below 1MB, so for
+ * safety we reserve 2MB each.
+ */
+#define INTEL_UC_RSVD_GGTT_PER_FW SZ_2M
 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.
+	 */
+	BUILD_BUG_ON(INTEL_UC_FW_NUM_TYPES * INTEL_UC_RSVD_GGTT_PER_FW > SZ_8M);
+	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)
@@ -690,7 +707,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))
-- 
2.37.3


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

* [PATCH 4/7] drm/i915/guc: Add GuC deprivilege feature to MTL
  2022-09-22 22:11 ` Daniele Ceraolo Spurio
@ 2022-09-22 22:11   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 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>
---
 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 77e7df21f539..b1b720870da8 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -1143,6 +1143,7 @@ static const struct intel_device_info mtl_info = {
 	.display.has_modular_fia = 1,
 	.extra_gt_list = xelpmp_extra_gt,
 	.has_flat_ccs = 0,
+	.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] 48+ messages in thread

* [Intel-gfx] [PATCH 4/7] drm/i915/guc: Add GuC deprivilege feature to MTL
@ 2022-09-22 22:11   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alan Previn, dri-devel

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>
---
 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 77e7df21f539..b1b720870da8 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -1143,6 +1143,7 @@ static const struct intel_device_info mtl_info = {
 	.display.has_modular_fia = 1,
 	.extra_gt_list = xelpmp_extra_gt,
 	.has_flat_ccs = 0,
+	.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] 48+ messages in thread

* [PATCH 5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations.
  2022-09-22 22:11 ` Daniele Ceraolo Spurio
@ 2022-09-22 22:11   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 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.

Signed-off-by: Aravind Iddamsetty <aravind.iddamsetty@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: John Harrison <john.c.harrison@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
---
 drivers/gpu/drm/i915/Makefile               |  7 +--
 drivers/gpu/drm/i915/gt/intel_ggtt.c        |  2 +-
 drivers/gpu/drm/i915/gt/intel_gt.c          |  1 +
 drivers/gpu/drm/i915/gt/intel_gt_types.h    |  2 +
 drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c | 48 +++++++++++++++------
 drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h |  0
 drivers/gpu/drm/i915/gt/uc/intel_uc.c       |  4 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c    | 14 +++---
 drivers/gpu/drm/i915/i915_driver.c          |  2 -
 drivers/gpu/drm/i915/i915_drv.h             |  3 --
 drivers/gpu/drm/i915/i915_gem.c             |  5 ++-
 11 files changed, 56 insertions(+), 32 deletions(-)
 rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c (86%)
 rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h (100%)

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index a26edcdadc21..6ed4c745b226 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -129,7 +129,9 @@ gt-y += \
 	gt/intel_timeline.o \
 	gt/intel_workarounds.o \
 	gt/shmem_utils.o \
-	gt/sysfs_engines.o
+	gt/sysfs_engines.o \
+	gt/intel_wopcm.o
+
 # x86 intel-gtt module support
 gt-$(CONFIG_X86) += gt/intel_ggtt_gmch.o
 # autogenerated null render state
@@ -183,8 +185,7 @@ i915-y += \
 	  i915_trace_points.o \
 	  i915_ttm_buddy_manager.o \
 	  i915_vma.o \
-	  i915_vma_resource.o \
-	  intel_wopcm.o
+	  i915_vma_resource.o
 
 # general-purpose microcontroller (GuC) support
 i915-y += gt/uc/intel_uc.o \
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 30cf5c3369d9..605e1aa674d4 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -560,7 +560,7 @@ static int init_ggtt(struct i915_ggtt *ggtt)
 	 * why.
 	 */
 	ggtt->pin_bias = max_t(u32, I915_GTT_PAGE_SIZE,
-			       intel_wopcm_guc_size(&ggtt->vm.i915->wopcm));
+			       intel_wopcm_guc_size(&ggtt->vm.gt->wopcm));
 
 	ret = intel_vgt_balloon(ggtt);
 	if (ret)
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
index b367cfff48d5..a95eb0b656d2 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -56,6 +56,7 @@ void intel_gt_common_init_early(struct intel_gt *gt)
 	seqcount_mutex_init(&gt->tlb.seqno, &gt->tlb.invalidate_lock);
 	intel_gt_pm_init_early(gt);
 
+	intel_wopcm_init_early(&gt->wopcm);
 	intel_uc_init_early(&gt->uc);
 	intel_rps_init_early(&gt->rps);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index f19c2de77ff6..c20a32d2700f 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -30,6 +30,7 @@
 #include "intel_migrate_types.h"
 #include "intel_wakeref.h"
 #include "pxp/intel_pxp_types.h"
+#include "intel_wopcm.h"
 
 struct drm_i915_private;
 struct i915_ggtt;
@@ -97,6 +98,7 @@ struct intel_gt {
 
 	struct intel_uc uc;
 	struct intel_gsc gsc;
+	struct intel_wopcm wopcm;
 
 	struct {
 		/* Serialize global tlb invalidations */
diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/gt/intel_wopcm.c
similarity index 86%
rename from drivers/gpu/drm/i915/intel_wopcm.c
rename to drivers/gpu/drm/i915/gt/intel_wopcm.c
index 322fb9eeb880..487fbbbdf3d6 100644
--- a/drivers/gpu/drm/i915/intel_wopcm.c
+++ b/drivers/gpu/drm/i915/gt/intel_wopcm.c
@@ -43,6 +43,7 @@
 /* Default WOPCM size is 2MB from Gen11, 1MB on previous platforms */
 #define GEN11_WOPCM_SIZE		SZ_2M
 #define GEN9_WOPCM_SIZE			SZ_1M
+#define XELPM_SAMEDIA_WOPCM_SIZE	SZ_2M
 #define MAX_WOPCM_SIZE			SZ_8M
 /* 16KB WOPCM (RSVD WOPCM) is reserved from HuC firmware top. */
 #define WOPCM_RESERVED_SIZE		SZ_16K
@@ -64,9 +65,9 @@
 #define GEN9_GUC_FW_RESERVED	SZ_128K
 #define GEN9_GUC_WOPCM_OFFSET	(GUC_WOPCM_RESERVED + GEN9_GUC_FW_RESERVED)
 
-static inline struct drm_i915_private *wopcm_to_i915(struct intel_wopcm *wopcm)
+static inline struct intel_gt *wopcm_to_gt(struct intel_wopcm *wopcm)
 {
-	return container_of(wopcm, struct drm_i915_private, wopcm);
+	return container_of(wopcm, struct intel_gt, wopcm);
 }
 
 /**
@@ -77,7 +78,8 @@ static inline struct drm_i915_private *wopcm_to_i915(struct intel_wopcm *wopcm)
  */
 void intel_wopcm_init_early(struct intel_wopcm *wopcm)
 {
-	struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
+	struct intel_gt *gt = wopcm_to_gt(wopcm);
+	struct drm_i915_private *i915 = gt->i915;
 
 	if (!HAS_GT_UC(i915))
 		return;
@@ -157,14 +159,18 @@ static bool check_hw_restrictions(struct drm_i915_private *i915,
 	return true;
 }
 
-static bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
+static bool __check_layout(struct intel_gt *gt, u32 wopcm_size,
 			   u32 guc_wopcm_base, u32 guc_wopcm_size,
 			   u32 guc_fw_size, u32 huc_fw_size)
 {
+	struct drm_i915_private *i915 = gt->i915;
 	const u32 ctx_rsvd = context_reserved_size(i915);
 	u32 size;
 
 	size = wopcm_size - ctx_rsvd;
+	if (MEDIA_VER(i915) >= 13)
+		size += XELPM_SAMEDIA_WOPCM_SIZE;
+
 	if (unlikely(range_overflows(guc_wopcm_base, guc_wopcm_size, size))) {
 		drm_err(&i915->drm,
 			"WOPCM: invalid GuC region layout: %uK + %uK > %uK\n",
@@ -181,12 +187,14 @@ static bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
 		return false;
 	}
 
-	size = huc_fw_size + WOPCM_RESERVED_SIZE;
-	if (unlikely(guc_wopcm_base < size)) {
-		drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n",
-			intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
-			guc_wopcm_base / SZ_1K, size / SZ_1K);
-		return false;
+	if (VDBOX_MASK(gt)) {
+		size = huc_fw_size + WOPCM_RESERVED_SIZE;
+		if (unlikely(guc_wopcm_base < size)) {
+			drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n",
+				intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
+				guc_wopcm_base / SZ_1K, size / SZ_1K);
+			return false;
+		}
 	}
 
 	return check_hw_restrictions(i915, guc_wopcm_base, guc_wopcm_size,
@@ -228,8 +236,8 @@ static bool __wopcm_regs_writable(struct intel_uncore *uncore)
  */
 void intel_wopcm_init(struct intel_wopcm *wopcm)
 {
-	struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
-	struct intel_gt *gt = to_gt(i915);
+	struct intel_gt *gt = wopcm_to_gt(wopcm);
+	struct drm_i915_private *i915 = gt->i915;
 	u32 guc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.guc.fw);
 	u32 huc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.huc.fw);
 	u32 ctx_rsvd = context_reserved_size(i915);
@@ -274,6 +282,19 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
 		goto check;
 	}
 
+	/*
+	 * On platforms with a media GT, the WOPCM is partitioned between the
+	 * two GTs, so we would have to take that into account when doing the
+	 * math below. There is also a new section reserved for the GSC ctx
+	 * that w would have to factor in. However, all platforms with a media
+	 * GT also have GuC depriv enabled, so the WOPCM regs are pre-locked
+	 * and therefore we don't have to do the math ourselves.
+	 */
+	if (unlikely(i915->media_gt)) {
+		drm_err(&i915->drm, "Unlocked WOPCM regs with media GT\n");
+		return;
+	}
+
 	/*
 	 * Aligned value of guc_wopcm_base will determine available WOPCM space
 	 * for HuC firmware and mandatory reserved area.
@@ -289,13 +310,14 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
 
 	/* Aligned remainings of usable WOPCM space can be assigned to GuC. */
 	guc_wopcm_size = wopcm_size - ctx_rsvd - guc_wopcm_base;
+
 	guc_wopcm_size &= GUC_WOPCM_SIZE_MASK;
 
 	drm_dbg(&i915->drm, "Calculated GuC WOPCM [%uK, %uK)\n",
 		guc_wopcm_base / SZ_1K, guc_wopcm_size / SZ_1K);
 
 check:
-	if (__check_layout(i915, wopcm_size, guc_wopcm_base, guc_wopcm_size,
+	if (__check_layout(gt, wopcm_size, guc_wopcm_base, guc_wopcm_size,
 			   guc_fw_size, huc_fw_size)) {
 		wopcm->guc.base = guc_wopcm_base;
 		wopcm->guc.size = guc_wopcm_size;
diff --git a/drivers/gpu/drm/i915/intel_wopcm.h b/drivers/gpu/drm/i915/gt/intel_wopcm.h
similarity index 100%
rename from drivers/gpu/drm/i915/intel_wopcm.h
rename to drivers/gpu/drm/i915/gt/intel_wopcm.h
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index dbd048b77e19..4cd8a787f9e5 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -357,8 +357,8 @@ static int uc_init_wopcm(struct intel_uc *uc)
 {
 	struct intel_gt *gt = uc_to_gt(uc);
 	struct intel_uncore *uncore = gt->uncore;
-	u32 base = intel_wopcm_guc_base(&gt->i915->wopcm);
-	u32 size = intel_wopcm_guc_size(&gt->i915->wopcm);
+	u32 base = intel_wopcm_guc_base(&gt->wopcm);
+	u32 size = intel_wopcm_guc_size(&gt->wopcm);
 	u32 huc_agent = intel_uc_uses_huc(uc) ? HUC_LOADING_AGENT_GUC : 0;
 	u32 mask;
 	int err;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index d6ca772e9f4b..a9ff9abb66db 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -469,10 +469,11 @@ static int check_gsc_manifest(const struct firmware *fw,
 	return 0;
 }
 
-static int check_ccs_header(struct drm_i915_private *i915,
+static int check_ccs_header(struct intel_gt *gt,
 			    const struct firmware *fw,
 			    struct intel_uc_fw *uc_fw)
 {
+	struct drm_i915_private *i915 = gt->i915;
 	struct uc_css_header *css;
 	size_t size;
 
@@ -514,10 +515,10 @@ static int check_ccs_header(struct drm_i915_private *i915,
 
 	/* Sanity check whether this fw is not larger than whole WOPCM memory */
 	size = __intel_uc_fw_get_upload_size(uc_fw);
-	if (unlikely(size >= i915->wopcm.size)) {
+	if (unlikely(size >= gt->wopcm.size)) {
 		drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu > %zu\n",
 			 intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
-			 size, (size_t)i915->wopcm.size);
+			 size, (size_t)gt->wopcm.size);
 		return -E2BIG;
 	}
 
@@ -545,7 +546,8 @@ static int check_ccs_header(struct drm_i915_private *i915,
  */
 int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 {
-	struct drm_i915_private *i915 = __uc_fw_to_gt(uc_fw)->i915;
+	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
+	struct drm_i915_private *i915 = gt->i915;
 	struct intel_uc_fw_file file_ideal;
 	struct device *dev = i915->drm.dev;
 	struct drm_i915_gem_object *obj;
@@ -553,7 +555,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 	bool old_ver = false;
 	int err;
 
-	GEM_BUG_ON(!i915->wopcm.size);
+	GEM_BUG_ON(!gt->wopcm.size);
 	GEM_BUG_ON(!intel_uc_fw_is_enabled(uc_fw));
 
 	err = i915_inject_probe_error(i915, -ENXIO);
@@ -595,7 +597,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 	if (uc_fw->loaded_via_gsc)
 		err = check_gsc_manifest(fw, uc_fw);
 	else
-		err = check_ccs_header(i915, fw, uc_fw);
+		err = check_ccs_header(gt, fw, uc_fw);
 	if (err)
 		goto fail;
 
diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
index 9d1fc2477f80..51fc030774fa 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -369,8 +369,6 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
 	if (ret)
 		goto err_ttm;
 
-	intel_wopcm_init_early(&dev_priv->wopcm);
-
 	ret = intel_root_gt_init_early(dev_priv);
 	if (ret < 0)
 		goto err_rootgt;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8ca575202e5d..587e43ad7941 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -63,7 +63,6 @@
 #include "intel_runtime_pm.h"
 #include "intel_step.h"
 #include "intel_uncore.h"
-#include "intel_wopcm.h"
 
 struct drm_i915_clock_gating_funcs;
 struct drm_i915_gem_object;
@@ -236,8 +235,6 @@ struct drm_i915_private {
 
 	struct intel_gvt *gvt;
 
-	struct intel_wopcm wopcm;
-
 	struct pci_dev *bridge_dev;
 
 	struct rb_root uabi_engines;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a5b192ac885c..cfc8b17c1ee5 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1140,9 +1140,10 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
 	if (ret)
 		return ret;
 
-	for_each_gt(gt, dev_priv, i)
+	for_each_gt(gt, dev_priv, i) {
 		intel_uc_fetch_firmwares(&gt->uc);
-	intel_wopcm_init(&dev_priv->wopcm);
+		intel_wopcm_init(&gt->wopcm);
+	}
 
 	ret = i915_init_ggtt(dev_priv);
 	if (ret) {
-- 
2.37.3


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

* [Intel-gfx] [PATCH 5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations.
@ 2022-09-22 22:11   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alan Previn, dri-devel

From: Aravind Iddamsetty <aravind.iddamsetty@intel.com>

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

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

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

Signed-off-by: Aravind Iddamsetty <aravind.iddamsetty@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: John Harrison <john.c.harrison@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
---
 drivers/gpu/drm/i915/Makefile               |  7 +--
 drivers/gpu/drm/i915/gt/intel_ggtt.c        |  2 +-
 drivers/gpu/drm/i915/gt/intel_gt.c          |  1 +
 drivers/gpu/drm/i915/gt/intel_gt_types.h    |  2 +
 drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c | 48 +++++++++++++++------
 drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h |  0
 drivers/gpu/drm/i915/gt/uc/intel_uc.c       |  4 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c    | 14 +++---
 drivers/gpu/drm/i915/i915_driver.c          |  2 -
 drivers/gpu/drm/i915/i915_drv.h             |  3 --
 drivers/gpu/drm/i915/i915_gem.c             |  5 ++-
 11 files changed, 56 insertions(+), 32 deletions(-)
 rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c (86%)
 rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h (100%)

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index a26edcdadc21..6ed4c745b226 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -129,7 +129,9 @@ gt-y += \
 	gt/intel_timeline.o \
 	gt/intel_workarounds.o \
 	gt/shmem_utils.o \
-	gt/sysfs_engines.o
+	gt/sysfs_engines.o \
+	gt/intel_wopcm.o
+
 # x86 intel-gtt module support
 gt-$(CONFIG_X86) += gt/intel_ggtt_gmch.o
 # autogenerated null render state
@@ -183,8 +185,7 @@ i915-y += \
 	  i915_trace_points.o \
 	  i915_ttm_buddy_manager.o \
 	  i915_vma.o \
-	  i915_vma_resource.o \
-	  intel_wopcm.o
+	  i915_vma_resource.o
 
 # general-purpose microcontroller (GuC) support
 i915-y += gt/uc/intel_uc.o \
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 30cf5c3369d9..605e1aa674d4 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -560,7 +560,7 @@ static int init_ggtt(struct i915_ggtt *ggtt)
 	 * why.
 	 */
 	ggtt->pin_bias = max_t(u32, I915_GTT_PAGE_SIZE,
-			       intel_wopcm_guc_size(&ggtt->vm.i915->wopcm));
+			       intel_wopcm_guc_size(&ggtt->vm.gt->wopcm));
 
 	ret = intel_vgt_balloon(ggtt);
 	if (ret)
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
index b367cfff48d5..a95eb0b656d2 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -56,6 +56,7 @@ void intel_gt_common_init_early(struct intel_gt *gt)
 	seqcount_mutex_init(&gt->tlb.seqno, &gt->tlb.invalidate_lock);
 	intel_gt_pm_init_early(gt);
 
+	intel_wopcm_init_early(&gt->wopcm);
 	intel_uc_init_early(&gt->uc);
 	intel_rps_init_early(&gt->rps);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index f19c2de77ff6..c20a32d2700f 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -30,6 +30,7 @@
 #include "intel_migrate_types.h"
 #include "intel_wakeref.h"
 #include "pxp/intel_pxp_types.h"
+#include "intel_wopcm.h"
 
 struct drm_i915_private;
 struct i915_ggtt;
@@ -97,6 +98,7 @@ struct intel_gt {
 
 	struct intel_uc uc;
 	struct intel_gsc gsc;
+	struct intel_wopcm wopcm;
 
 	struct {
 		/* Serialize global tlb invalidations */
diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/gt/intel_wopcm.c
similarity index 86%
rename from drivers/gpu/drm/i915/intel_wopcm.c
rename to drivers/gpu/drm/i915/gt/intel_wopcm.c
index 322fb9eeb880..487fbbbdf3d6 100644
--- a/drivers/gpu/drm/i915/intel_wopcm.c
+++ b/drivers/gpu/drm/i915/gt/intel_wopcm.c
@@ -43,6 +43,7 @@
 /* Default WOPCM size is 2MB from Gen11, 1MB on previous platforms */
 #define GEN11_WOPCM_SIZE		SZ_2M
 #define GEN9_WOPCM_SIZE			SZ_1M
+#define XELPM_SAMEDIA_WOPCM_SIZE	SZ_2M
 #define MAX_WOPCM_SIZE			SZ_8M
 /* 16KB WOPCM (RSVD WOPCM) is reserved from HuC firmware top. */
 #define WOPCM_RESERVED_SIZE		SZ_16K
@@ -64,9 +65,9 @@
 #define GEN9_GUC_FW_RESERVED	SZ_128K
 #define GEN9_GUC_WOPCM_OFFSET	(GUC_WOPCM_RESERVED + GEN9_GUC_FW_RESERVED)
 
-static inline struct drm_i915_private *wopcm_to_i915(struct intel_wopcm *wopcm)
+static inline struct intel_gt *wopcm_to_gt(struct intel_wopcm *wopcm)
 {
-	return container_of(wopcm, struct drm_i915_private, wopcm);
+	return container_of(wopcm, struct intel_gt, wopcm);
 }
 
 /**
@@ -77,7 +78,8 @@ static inline struct drm_i915_private *wopcm_to_i915(struct intel_wopcm *wopcm)
  */
 void intel_wopcm_init_early(struct intel_wopcm *wopcm)
 {
-	struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
+	struct intel_gt *gt = wopcm_to_gt(wopcm);
+	struct drm_i915_private *i915 = gt->i915;
 
 	if (!HAS_GT_UC(i915))
 		return;
@@ -157,14 +159,18 @@ static bool check_hw_restrictions(struct drm_i915_private *i915,
 	return true;
 }
 
-static bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
+static bool __check_layout(struct intel_gt *gt, u32 wopcm_size,
 			   u32 guc_wopcm_base, u32 guc_wopcm_size,
 			   u32 guc_fw_size, u32 huc_fw_size)
 {
+	struct drm_i915_private *i915 = gt->i915;
 	const u32 ctx_rsvd = context_reserved_size(i915);
 	u32 size;
 
 	size = wopcm_size - ctx_rsvd;
+	if (MEDIA_VER(i915) >= 13)
+		size += XELPM_SAMEDIA_WOPCM_SIZE;
+
 	if (unlikely(range_overflows(guc_wopcm_base, guc_wopcm_size, size))) {
 		drm_err(&i915->drm,
 			"WOPCM: invalid GuC region layout: %uK + %uK > %uK\n",
@@ -181,12 +187,14 @@ static bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
 		return false;
 	}
 
-	size = huc_fw_size + WOPCM_RESERVED_SIZE;
-	if (unlikely(guc_wopcm_base < size)) {
-		drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n",
-			intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
-			guc_wopcm_base / SZ_1K, size / SZ_1K);
-		return false;
+	if (VDBOX_MASK(gt)) {
+		size = huc_fw_size + WOPCM_RESERVED_SIZE;
+		if (unlikely(guc_wopcm_base < size)) {
+			drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n",
+				intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
+				guc_wopcm_base / SZ_1K, size / SZ_1K);
+			return false;
+		}
 	}
 
 	return check_hw_restrictions(i915, guc_wopcm_base, guc_wopcm_size,
@@ -228,8 +236,8 @@ static bool __wopcm_regs_writable(struct intel_uncore *uncore)
  */
 void intel_wopcm_init(struct intel_wopcm *wopcm)
 {
-	struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
-	struct intel_gt *gt = to_gt(i915);
+	struct intel_gt *gt = wopcm_to_gt(wopcm);
+	struct drm_i915_private *i915 = gt->i915;
 	u32 guc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.guc.fw);
 	u32 huc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.huc.fw);
 	u32 ctx_rsvd = context_reserved_size(i915);
@@ -274,6 +282,19 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
 		goto check;
 	}
 
+	/*
+	 * On platforms with a media GT, the WOPCM is partitioned between the
+	 * two GTs, so we would have to take that into account when doing the
+	 * math below. There is also a new section reserved for the GSC ctx
+	 * that w would have to factor in. However, all platforms with a media
+	 * GT also have GuC depriv enabled, so the WOPCM regs are pre-locked
+	 * and therefore we don't have to do the math ourselves.
+	 */
+	if (unlikely(i915->media_gt)) {
+		drm_err(&i915->drm, "Unlocked WOPCM regs with media GT\n");
+		return;
+	}
+
 	/*
 	 * Aligned value of guc_wopcm_base will determine available WOPCM space
 	 * for HuC firmware and mandatory reserved area.
@@ -289,13 +310,14 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
 
 	/* Aligned remainings of usable WOPCM space can be assigned to GuC. */
 	guc_wopcm_size = wopcm_size - ctx_rsvd - guc_wopcm_base;
+
 	guc_wopcm_size &= GUC_WOPCM_SIZE_MASK;
 
 	drm_dbg(&i915->drm, "Calculated GuC WOPCM [%uK, %uK)\n",
 		guc_wopcm_base / SZ_1K, guc_wopcm_size / SZ_1K);
 
 check:
-	if (__check_layout(i915, wopcm_size, guc_wopcm_base, guc_wopcm_size,
+	if (__check_layout(gt, wopcm_size, guc_wopcm_base, guc_wopcm_size,
 			   guc_fw_size, huc_fw_size)) {
 		wopcm->guc.base = guc_wopcm_base;
 		wopcm->guc.size = guc_wopcm_size;
diff --git a/drivers/gpu/drm/i915/intel_wopcm.h b/drivers/gpu/drm/i915/gt/intel_wopcm.h
similarity index 100%
rename from drivers/gpu/drm/i915/intel_wopcm.h
rename to drivers/gpu/drm/i915/gt/intel_wopcm.h
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index dbd048b77e19..4cd8a787f9e5 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -357,8 +357,8 @@ static int uc_init_wopcm(struct intel_uc *uc)
 {
 	struct intel_gt *gt = uc_to_gt(uc);
 	struct intel_uncore *uncore = gt->uncore;
-	u32 base = intel_wopcm_guc_base(&gt->i915->wopcm);
-	u32 size = intel_wopcm_guc_size(&gt->i915->wopcm);
+	u32 base = intel_wopcm_guc_base(&gt->wopcm);
+	u32 size = intel_wopcm_guc_size(&gt->wopcm);
 	u32 huc_agent = intel_uc_uses_huc(uc) ? HUC_LOADING_AGENT_GUC : 0;
 	u32 mask;
 	int err;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index d6ca772e9f4b..a9ff9abb66db 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -469,10 +469,11 @@ static int check_gsc_manifest(const struct firmware *fw,
 	return 0;
 }
 
-static int check_ccs_header(struct drm_i915_private *i915,
+static int check_ccs_header(struct intel_gt *gt,
 			    const struct firmware *fw,
 			    struct intel_uc_fw *uc_fw)
 {
+	struct drm_i915_private *i915 = gt->i915;
 	struct uc_css_header *css;
 	size_t size;
 
@@ -514,10 +515,10 @@ static int check_ccs_header(struct drm_i915_private *i915,
 
 	/* Sanity check whether this fw is not larger than whole WOPCM memory */
 	size = __intel_uc_fw_get_upload_size(uc_fw);
-	if (unlikely(size >= i915->wopcm.size)) {
+	if (unlikely(size >= gt->wopcm.size)) {
 		drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu > %zu\n",
 			 intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
-			 size, (size_t)i915->wopcm.size);
+			 size, (size_t)gt->wopcm.size);
 		return -E2BIG;
 	}
 
@@ -545,7 +546,8 @@ static int check_ccs_header(struct drm_i915_private *i915,
  */
 int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 {
-	struct drm_i915_private *i915 = __uc_fw_to_gt(uc_fw)->i915;
+	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
+	struct drm_i915_private *i915 = gt->i915;
 	struct intel_uc_fw_file file_ideal;
 	struct device *dev = i915->drm.dev;
 	struct drm_i915_gem_object *obj;
@@ -553,7 +555,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 	bool old_ver = false;
 	int err;
 
-	GEM_BUG_ON(!i915->wopcm.size);
+	GEM_BUG_ON(!gt->wopcm.size);
 	GEM_BUG_ON(!intel_uc_fw_is_enabled(uc_fw));
 
 	err = i915_inject_probe_error(i915, -ENXIO);
@@ -595,7 +597,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 	if (uc_fw->loaded_via_gsc)
 		err = check_gsc_manifest(fw, uc_fw);
 	else
-		err = check_ccs_header(i915, fw, uc_fw);
+		err = check_ccs_header(gt, fw, uc_fw);
 	if (err)
 		goto fail;
 
diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
index 9d1fc2477f80..51fc030774fa 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -369,8 +369,6 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
 	if (ret)
 		goto err_ttm;
 
-	intel_wopcm_init_early(&dev_priv->wopcm);
-
 	ret = intel_root_gt_init_early(dev_priv);
 	if (ret < 0)
 		goto err_rootgt;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8ca575202e5d..587e43ad7941 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -63,7 +63,6 @@
 #include "intel_runtime_pm.h"
 #include "intel_step.h"
 #include "intel_uncore.h"
-#include "intel_wopcm.h"
 
 struct drm_i915_clock_gating_funcs;
 struct drm_i915_gem_object;
@@ -236,8 +235,6 @@ struct drm_i915_private {
 
 	struct intel_gvt *gvt;
 
-	struct intel_wopcm wopcm;
-
 	struct pci_dev *bridge_dev;
 
 	struct rb_root uabi_engines;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a5b192ac885c..cfc8b17c1ee5 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1140,9 +1140,10 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
 	if (ret)
 		return ret;
 
-	for_each_gt(gt, dev_priv, i)
+	for_each_gt(gt, dev_priv, i) {
 		intel_uc_fetch_firmwares(&gt->uc);
-	intel_wopcm_init(&dev_priv->wopcm);
+		intel_wopcm_init(&gt->wopcm);
+	}
 
 	ret = i915_init_ggtt(dev_priv);
 	if (ret) {
-- 
2.37.3


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

* [PATCH 6/7] drm/i915/guc: define media GT GuC send regs
  2022-09-22 22:11 ` Daniele Ceraolo Spurio
@ 2022-09-22 22:11   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 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>
---
 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 bac06e3d6f2c..b0beab44b34c 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] 48+ messages in thread

* [Intel-gfx] [PATCH 6/7] drm/i915/guc: define media GT GuC send regs
@ 2022-09-22 22:11   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alan Previn, 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>
---
 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 bac06e3d6f2c..b0beab44b34c 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] 48+ messages in thread

* [PATCH 7/7] drm/i915/guc: handle interrupts from media GuC
  2022-09-22 22:11 ` Daniele Ceraolo Spurio
@ 2022-09-22 22:11   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 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.

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..e33ed9ae1439 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, GEN12_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 1cbb7226400b..792809e49680 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1519,6 +1519,7 @@
 #define   GEN11_CSME				(31)
 #define   GEN11_GUNIT				(28)
 #define   GEN11_GUC				(25)
+#define   GEN12_GUCM				(24)
 #define   GEN11_WDPERF				(20)
 #define   GEN11_KCR				(19)
 #define   GEN11_GTPM				(16)
@@ -1573,6 +1574,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 GEN12_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 b0beab44b34c..ab0263d8e1cf 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 ? GEN12_GUCM : 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] 48+ messages in thread

* [Intel-gfx] [PATCH 7/7] drm/i915/guc: handle interrupts from media GuC
@ 2022-09-22 22:11   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 48+ messages in thread
From: Daniele Ceraolo Spurio @ 2022-09-22 22:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: 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.

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..e33ed9ae1439 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, GEN12_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 1cbb7226400b..792809e49680 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1519,6 +1519,7 @@
 #define   GEN11_CSME				(31)
 #define   GEN11_GUNIT				(28)
 #define   GEN11_GUC				(25)
+#define   GEN12_GUCM				(24)
 #define   GEN11_WDPERF				(20)
 #define   GEN11_KCR				(19)
 #define   GEN11_GTPM				(16)
@@ -1573,6 +1574,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 GEN12_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 b0beab44b34c..ab0263d8e1cf 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 ? GEN12_GUCM : 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] 48+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: prepare for uC loading on MTL
  2022-09-22 22:11 ` Daniele Ceraolo Spurio
                   ` (7 preceding siblings ...)
  (?)
@ 2022-09-23  1:12 ` Patchwork
  -1 siblings, 0 replies; 48+ messages in thread
From: Patchwork @ 2022-09-23  1:12 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: prepare for uC loading on MTL
URL   : https://patchwork.freedesktop.org/series/108925/
State : warning

== Summary ==

Error: dim checkpatch failed
c6f416737aa1 drm/i915/huc: only load HuC on GTs that have VCS engines
946fd3c4cb17 drm/i915/uc: fetch uc firmwares for each GT
ea97d7e64607 drm/i915/uc: use different ggtt pin offsets for uc loads
-:13: WARNING:TYPO_SPELLING: 'happend' may be misspelled - perhaps 'happened'?
#13: 
the same GGTT at the same time. On MTL, however, this can happend if both
                                                          ^^^^^^^

total: 0 errors, 1 warnings, 0 checks, 42 lines checked
f394b49db4fe drm/i915/guc: Add GuC deprivilege feature to MTL
811093c9215e drm/i915/mtl: Handle wopcm per-GT and limit calculations.
-:118: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#118: 
rename from drivers/gpu/drm/i915/intel_wopcm.c

total: 0 errors, 1 warnings, 0 checks, 252 lines checked
fa19820e3717 drm/i915/guc: define media GT GuC send regs
c0a6b5d87e24 drm/i915/guc: handle interrupts from media GuC



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

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/i915: prepare for uC loading on MTL
  2022-09-22 22:11 ` Daniele Ceraolo Spurio
                   ` (8 preceding siblings ...)
  (?)
@ 2022-09-23  1:12 ` Patchwork
  -1 siblings, 0 replies; 48+ messages in thread
From: Patchwork @ 2022-09-23  1:12 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: prepare for uC loading on MTL
URL   : https://patchwork.freedesktop.org/series/108925/
State : warning

== Summary ==

Error: dim sparse failed
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.



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

* [Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: prepare for uC loading on MTL
  2022-09-22 22:11 ` Daniele Ceraolo Spurio
                   ` (9 preceding siblings ...)
  (?)
@ 2022-09-23  1:31 ` Patchwork
  -1 siblings, 0 replies; 48+ messages in thread
From: Patchwork @ 2022-09-23  1:31 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 5175 bytes --]

== Series Details ==

Series: drm/i915: prepare for uC loading on MTL
URL   : https://patchwork.freedesktop.org/series/108925/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_12168 -> Patchwork_108925v1
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/index.html

Participating hosts (44 -> 42)
------------------------------

  Missing    (2): fi-bxt-dsi fi-bdw-samus 

Known issues
------------

  Here are the changes found in Patchwork_108925v1 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@i915_selftest@live@hangcheck:
    - fi-adl-ddr5:        [PASS][1] -> [DMESG-WARN][2] ([i915#5591])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/fi-adl-ddr5/igt@i915_selftest@live@hangcheck.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/fi-adl-ddr5/igt@i915_selftest@live@hangcheck.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor@atomic-transitions:
    - fi-bsw-kefka:       [PASS][3] -> [FAIL][4] ([i915#6298])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/fi-bsw-kefka/igt@kms_cursor_legacy@basic-busy-flip-before-cursor@atomic-transitions.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/fi-bsw-kefka/igt@kms_cursor_legacy@basic-busy-flip-before-cursor@atomic-transitions.html

  
#### Possible fixes ####

  * igt@gem_exec_suspend@basic-s3@smem:
    - {bat-rplp-1}:       [DMESG-WARN][5] ([i915#2867]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/bat-rplp-1/igt@gem_exec_suspend@basic-s3@smem.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/bat-rplp-1/igt@gem_exec_suspend@basic-s3@smem.html

  * igt@i915_selftest@live@gt_lrc:
    - {bat-adln-1}:       [INCOMPLETE][7] -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/bat-adln-1/igt@i915_selftest@live@gt_lrc.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/bat-adln-1/igt@i915_selftest@live@gt_lrc.html

  * igt@i915_selftest@live@mman:
    - fi-rkl-guc:         [INCOMPLETE][9] ([i915#6794]) -> [PASS][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/fi-rkl-guc/igt@i915_selftest@live@mman.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/fi-rkl-guc/igt@i915_selftest@live@mman.html

  * igt@i915_selftest@live@requests:
    - {bat-rpls-1}:       [INCOMPLETE][11] ([i915#6257] / [i915#6380]) -> [PASS][12]
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/bat-rpls-1/igt@i915_selftest@live@requests.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/bat-rpls-1/igt@i915_selftest@live@requests.html

  * igt@kms_pipe_crc_basic@suspend-read-crc@pipe-d-dp-2:
    - {bat-dg2-11}:       [FAIL][13] ([i915#6818]) -> [PASS][14]
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/bat-dg2-11/igt@kms_pipe_crc_basic@suspend-read-crc@pipe-d-dp-2.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/bat-dg2-11/igt@kms_pipe_crc_basic@suspend-read-crc@pipe-d-dp-2.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#2867]: https://gitlab.freedesktop.org/drm/intel/issues/2867
  [i915#4312]: https://gitlab.freedesktop.org/drm/intel/issues/4312
  [i915#4983]: https://gitlab.freedesktop.org/drm/intel/issues/4983
  [i915#5591]: https://gitlab.freedesktop.org/drm/intel/issues/5591
  [i915#6257]: https://gitlab.freedesktop.org/drm/intel/issues/6257
  [i915#6298]: https://gitlab.freedesktop.org/drm/intel/issues/6298
  [i915#6380]: https://gitlab.freedesktop.org/drm/intel/issues/6380
  [i915#6794]: https://gitlab.freedesktop.org/drm/intel/issues/6794
  [i915#6816]: https://gitlab.freedesktop.org/drm/intel/issues/6816
  [i915#6818]: https://gitlab.freedesktop.org/drm/intel/issues/6818
  [i915#6854]: https://gitlab.freedesktop.org/drm/intel/issues/6854


Build changes
-------------

  * Linux: CI_DRM_12168 -> Patchwork_108925v1

  CI-20190529: 20190529
  CI_DRM_12168: fea329811a7bc341aac5f51ab66ec41a3d0844af @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6662: dcb1d7a8822e62935f4fe3f2e6a04caaee669369 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_108925v1: fea329811a7bc341aac5f51ab66ec41a3d0844af @ git://anongit.freedesktop.org/gfx-ci/linux


### Linux commits

85ca45c81b85 drm/i915/guc: handle interrupts from media GuC
16e1705e7106 drm/i915/guc: define media GT GuC send regs
b03657839c2c drm/i915/mtl: Handle wopcm per-GT and limit calculations.
8fcdcc5511b8 drm/i915/guc: Add GuC deprivilege feature to MTL
64cea9853e7b drm/i915/uc: use different ggtt pin offsets for uc loads
687f99567183 drm/i915/uc: fetch uc firmwares for each GT
5bba78773b1b drm/i915/huc: only load HuC on GTs that have VCS engines

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/index.html

[-- Attachment #2: Type: text/html, Size: 5655 bytes --]

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

* Re: [Intel-gfx] [PATCH 5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations.
  2022-09-22 22:11   ` [Intel-gfx] " Daniele Ceraolo Spurio
  (?)
@ 2022-09-23  9:24   ` Jani Nikula
  2022-09-23 15:34     ` Ceraolo Spurio, Daniele
  -1 siblings, 1 reply; 48+ messages in thread
From: Jani Nikula @ 2022-09-23  9:24 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: dri-devel, Alan Previn

On Thu, 22 Sep 2022, Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> wrote:
> From: Aravind Iddamsetty <aravind.iddamsetty@intel.com>
>
> With MTL standalone media architecture the wopcm layout has changed with
> separate partitioning in WOPCM for GCD/GT GuC and SA Media GuC. The size
> of WOPCM is 4MB with lower 2MB for SA Media and upper 2MB for GCD/GT.
>
>     +=====+===> +====================+ <== WOPCM TOP
>     ^     ^     |                    |
>     |     |     |                    |
>     |    GCD    |   GCD RC6 Image    |
>     |    GuC    |    Power Context   |
>     |    WOPCM  |                    |
>     |    Size   +--------------------+
>     |     |     |   GCD GuC Image    |
>     |     |     |                    |
>     |     v     |                    |
>     |     +===> +====================+ <== SA Media GuC WOPCM Top
>     |     ^     |                    |
>     |   SA Media|                    |
>     |    GuC    | SA Media RC6 Image |
>     |   WOPCM   |    Power Context   |
>     |    Size   |                    |
>   WOPCM   |     +--------------------+
>     |     |     |                    |
>     |     |     | SA Media GuC Image |
>     |     v     |                    |
>     |     +===> +====================+ <== GuC WOPCM base
>     |           |     WOPCM RSVD     |
>     |           +------------------- + <== HuC Firmware Top
>     v           |      HuC FW        |
>     +=========> +====================+ <== WOPCM Base
>
> Given that MTL has GuC deprivilege, the WOPCM registers are pre-locked
> by the bios. Therefore, we can skip all the math for the partitioning
> and just limit ourselves to sanity checking the values.
>
> Signed-off-by: Aravind Iddamsetty <aravind.iddamsetty@intel.com>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Matt Roper <matthew.d.roper@intel.com>
> Cc: John Harrison <john.c.harrison@intel.com>
> Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
> ---
>  drivers/gpu/drm/i915/Makefile               |  7 +--
>  drivers/gpu/drm/i915/gt/intel_ggtt.c        |  2 +-
>  drivers/gpu/drm/i915/gt/intel_gt.c          |  1 +
>  drivers/gpu/drm/i915/gt/intel_gt_types.h    |  2 +
>  drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c | 48 +++++++++++++++------
>  drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h |  0
>  drivers/gpu/drm/i915/gt/uc/intel_uc.c       |  4 +-
>  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c    | 14 +++---
>  drivers/gpu/drm/i915/i915_driver.c          |  2 -
>  drivers/gpu/drm/i915/i915_drv.h             |  3 --
>  drivers/gpu/drm/i915/i915_gem.c             |  5 ++-
>  11 files changed, 56 insertions(+), 32 deletions(-)
>  rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c (86%)
>  rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h (100%)
>
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index a26edcdadc21..6ed4c745b226 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -129,7 +129,9 @@ gt-y += \
>  	gt/intel_timeline.o \
>  	gt/intel_workarounds.o \
>  	gt/shmem_utils.o \
> -	gt/sysfs_engines.o
> +	gt/sysfs_engines.o \
> +	gt/intel_wopcm.o

The comment near the top of the file:

# Please keep these build lists sorted!

> +
>  # x86 intel-gtt module support
>  gt-$(CONFIG_X86) += gt/intel_ggtt_gmch.o
>  # autogenerated null render state
> @@ -183,8 +185,7 @@ i915-y += \
>  	  i915_trace_points.o \
>  	  i915_ttm_buddy_manager.o \
>  	  i915_vma.o \
> -	  i915_vma_resource.o \
> -	  intel_wopcm.o
> +	  i915_vma_resource.o
>  
>  # general-purpose microcontroller (GuC) support
>  i915-y += gt/uc/intel_uc.o \
> diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> index 30cf5c3369d9..605e1aa674d4 100644
> --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> @@ -560,7 +560,7 @@ static int init_ggtt(struct i915_ggtt *ggtt)
>  	 * why.
>  	 */
>  	ggtt->pin_bias = max_t(u32, I915_GTT_PAGE_SIZE,
> -			       intel_wopcm_guc_size(&ggtt->vm.i915->wopcm));
> +			       intel_wopcm_guc_size(&ggtt->vm.gt->wopcm));
>  
>  	ret = intel_vgt_balloon(ggtt);
>  	if (ret)
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
> index b367cfff48d5..a95eb0b656d2 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt.c
> @@ -56,6 +56,7 @@ void intel_gt_common_init_early(struct intel_gt *gt)
>  	seqcount_mutex_init(&gt->tlb.seqno, &gt->tlb.invalidate_lock);
>  	intel_gt_pm_init_early(gt);
>  
> +	intel_wopcm_init_early(&gt->wopcm);
>  	intel_uc_init_early(&gt->uc);
>  	intel_rps_init_early(&gt->rps);
>  }
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
> index f19c2de77ff6..c20a32d2700f 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
> @@ -30,6 +30,7 @@
>  #include "intel_migrate_types.h"
>  #include "intel_wakeref.h"
>  #include "pxp/intel_pxp_types.h"
> +#include "intel_wopcm.h"
>  
>  struct drm_i915_private;
>  struct i915_ggtt;
> @@ -97,6 +98,7 @@ struct intel_gt {
>  
>  	struct intel_uc uc;
>  	struct intel_gsc gsc;
> +	struct intel_wopcm wopcm;
>  
>  	struct {
>  		/* Serialize global tlb invalidations */
> diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/gt/intel_wopcm.c
> similarity index 86%
> rename from drivers/gpu/drm/i915/intel_wopcm.c
> rename to drivers/gpu/drm/i915/gt/intel_wopcm.c
> index 322fb9eeb880..487fbbbdf3d6 100644
> --- a/drivers/gpu/drm/i915/intel_wopcm.c
> +++ b/drivers/gpu/drm/i915/gt/intel_wopcm.c
> @@ -43,6 +43,7 @@
>  /* Default WOPCM size is 2MB from Gen11, 1MB on previous platforms */
>  #define GEN11_WOPCM_SIZE		SZ_2M
>  #define GEN9_WOPCM_SIZE			SZ_1M
> +#define XELPM_SAMEDIA_WOPCM_SIZE	SZ_2M
>  #define MAX_WOPCM_SIZE			SZ_8M
>  /* 16KB WOPCM (RSVD WOPCM) is reserved from HuC firmware top. */
>  #define WOPCM_RESERVED_SIZE		SZ_16K
> @@ -64,9 +65,9 @@
>  #define GEN9_GUC_FW_RESERVED	SZ_128K
>  #define GEN9_GUC_WOPCM_OFFSET	(GUC_WOPCM_RESERVED + GEN9_GUC_FW_RESERVED)
>  
> -static inline struct drm_i915_private *wopcm_to_i915(struct intel_wopcm *wopcm)
> +static inline struct intel_gt *wopcm_to_gt(struct intel_wopcm *wopcm)
>  {
> -	return container_of(wopcm, struct drm_i915_private, wopcm);
> +	return container_of(wopcm, struct intel_gt, wopcm);
>  }
>  
>  /**
> @@ -77,7 +78,8 @@ static inline struct drm_i915_private *wopcm_to_i915(struct intel_wopcm *wopcm)
>   */
>  void intel_wopcm_init_early(struct intel_wopcm *wopcm)
>  {
> -	struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
> +	struct intel_gt *gt = wopcm_to_gt(wopcm);
> +	struct drm_i915_private *i915 = gt->i915;
>  
>  	if (!HAS_GT_UC(i915))
>  		return;
> @@ -157,14 +159,18 @@ static bool check_hw_restrictions(struct drm_i915_private *i915,
>  	return true;
>  }
>  
> -static bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
> +static bool __check_layout(struct intel_gt *gt, u32 wopcm_size,
>  			   u32 guc_wopcm_base, u32 guc_wopcm_size,
>  			   u32 guc_fw_size, u32 huc_fw_size)
>  {
> +	struct drm_i915_private *i915 = gt->i915;
>  	const u32 ctx_rsvd = context_reserved_size(i915);
>  	u32 size;
>  
>  	size = wopcm_size - ctx_rsvd;
> +	if (MEDIA_VER(i915) >= 13)
> +		size += XELPM_SAMEDIA_WOPCM_SIZE;
> +
>  	if (unlikely(range_overflows(guc_wopcm_base, guc_wopcm_size, size))) {
>  		drm_err(&i915->drm,
>  			"WOPCM: invalid GuC region layout: %uK + %uK > %uK\n",
> @@ -181,12 +187,14 @@ static bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
>  		return false;
>  	}
>  
> -	size = huc_fw_size + WOPCM_RESERVED_SIZE;
> -	if (unlikely(guc_wopcm_base < size)) {
> -		drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n",
> -			intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
> -			guc_wopcm_base / SZ_1K, size / SZ_1K);
> -		return false;
> +	if (VDBOX_MASK(gt)) {
> +		size = huc_fw_size + WOPCM_RESERVED_SIZE;
> +		if (unlikely(guc_wopcm_base < size)) {
> +			drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n",
> +				intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
> +				guc_wopcm_base / SZ_1K, size / SZ_1K);
> +			return false;
> +		}
>  	}
>  
>  	return check_hw_restrictions(i915, guc_wopcm_base, guc_wopcm_size,
> @@ -228,8 +236,8 @@ static bool __wopcm_regs_writable(struct intel_uncore *uncore)
>   */
>  void intel_wopcm_init(struct intel_wopcm *wopcm)
>  {
> -	struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
> -	struct intel_gt *gt = to_gt(i915);
> +	struct intel_gt *gt = wopcm_to_gt(wopcm);
> +	struct drm_i915_private *i915 = gt->i915;
>  	u32 guc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.guc.fw);
>  	u32 huc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.huc.fw);
>  	u32 ctx_rsvd = context_reserved_size(i915);
> @@ -274,6 +282,19 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
>  		goto check;
>  	}
>  
> +	/*
> +	 * On platforms with a media GT, the WOPCM is partitioned between the
> +	 * two GTs, so we would have to take that into account when doing the
> +	 * math below. There is also a new section reserved for the GSC ctx
> +	 * that w would have to factor in. However, all platforms with a media
> +	 * GT also have GuC depriv enabled, so the WOPCM regs are pre-locked
> +	 * and therefore we don't have to do the math ourselves.
> +	 */
> +	if (unlikely(i915->media_gt)) {
> +		drm_err(&i915->drm, "Unlocked WOPCM regs with media GT\n");
> +		return;
> +	}
> +
>  	/*
>  	 * Aligned value of guc_wopcm_base will determine available WOPCM space
>  	 * for HuC firmware and mandatory reserved area.
> @@ -289,13 +310,14 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
>  
>  	/* Aligned remainings of usable WOPCM space can be assigned to GuC. */
>  	guc_wopcm_size = wopcm_size - ctx_rsvd - guc_wopcm_base;
> +
>  	guc_wopcm_size &= GUC_WOPCM_SIZE_MASK;
>  
>  	drm_dbg(&i915->drm, "Calculated GuC WOPCM [%uK, %uK)\n",
>  		guc_wopcm_base / SZ_1K, guc_wopcm_size / SZ_1K);
>  
>  check:
> -	if (__check_layout(i915, wopcm_size, guc_wopcm_base, guc_wopcm_size,
> +	if (__check_layout(gt, wopcm_size, guc_wopcm_base, guc_wopcm_size,
>  			   guc_fw_size, huc_fw_size)) {
>  		wopcm->guc.base = guc_wopcm_base;
>  		wopcm->guc.size = guc_wopcm_size;
> diff --git a/drivers/gpu/drm/i915/intel_wopcm.h b/drivers/gpu/drm/i915/gt/intel_wopcm.h
> similarity index 100%
> rename from drivers/gpu/drm/i915/intel_wopcm.h
> rename to drivers/gpu/drm/i915/gt/intel_wopcm.h
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> index dbd048b77e19..4cd8a787f9e5 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> @@ -357,8 +357,8 @@ static int uc_init_wopcm(struct intel_uc *uc)
>  {
>  	struct intel_gt *gt = uc_to_gt(uc);
>  	struct intel_uncore *uncore = gt->uncore;
> -	u32 base = intel_wopcm_guc_base(&gt->i915->wopcm);
> -	u32 size = intel_wopcm_guc_size(&gt->i915->wopcm);
> +	u32 base = intel_wopcm_guc_base(&gt->wopcm);
> +	u32 size = intel_wopcm_guc_size(&gt->wopcm);
>  	u32 huc_agent = intel_uc_uses_huc(uc) ? HUC_LOADING_AGENT_GUC : 0;
>  	u32 mask;
>  	int err;
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> index d6ca772e9f4b..a9ff9abb66db 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> @@ -469,10 +469,11 @@ static int check_gsc_manifest(const struct firmware *fw,
>  	return 0;
>  }
>  
> -static int check_ccs_header(struct drm_i915_private *i915,
> +static int check_ccs_header(struct intel_gt *gt,
>  			    const struct firmware *fw,
>  			    struct intel_uc_fw *uc_fw)
>  {
> +	struct drm_i915_private *i915 = gt->i915;
>  	struct uc_css_header *css;
>  	size_t size;
>  
> @@ -514,10 +515,10 @@ static int check_ccs_header(struct drm_i915_private *i915,
>  
>  	/* Sanity check whether this fw is not larger than whole WOPCM memory */
>  	size = __intel_uc_fw_get_upload_size(uc_fw);
> -	if (unlikely(size >= i915->wopcm.size)) {
> +	if (unlikely(size >= gt->wopcm.size)) {
>  		drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu > %zu\n",
>  			 intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
> -			 size, (size_t)i915->wopcm.size);
> +			 size, (size_t)gt->wopcm.size);
>  		return -E2BIG;
>  	}
>  
> @@ -545,7 +546,8 @@ static int check_ccs_header(struct drm_i915_private *i915,
>   */
>  int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>  {
> -	struct drm_i915_private *i915 = __uc_fw_to_gt(uc_fw)->i915;
> +	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
> +	struct drm_i915_private *i915 = gt->i915;
>  	struct intel_uc_fw_file file_ideal;
>  	struct device *dev = i915->drm.dev;
>  	struct drm_i915_gem_object *obj;
> @@ -553,7 +555,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>  	bool old_ver = false;
>  	int err;
>  
> -	GEM_BUG_ON(!i915->wopcm.size);
> +	GEM_BUG_ON(!gt->wopcm.size);
>  	GEM_BUG_ON(!intel_uc_fw_is_enabled(uc_fw));
>  
>  	err = i915_inject_probe_error(i915, -ENXIO);
> @@ -595,7 +597,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>  	if (uc_fw->loaded_via_gsc)
>  		err = check_gsc_manifest(fw, uc_fw);
>  	else
> -		err = check_ccs_header(i915, fw, uc_fw);
> +		err = check_ccs_header(gt, fw, uc_fw);
>  	if (err)
>  		goto fail;
>  
> diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
> index 9d1fc2477f80..51fc030774fa 100644
> --- a/drivers/gpu/drm/i915/i915_driver.c
> +++ b/drivers/gpu/drm/i915/i915_driver.c
> @@ -369,8 +369,6 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
>  	if (ret)
>  		goto err_ttm;
>  
> -	intel_wopcm_init_early(&dev_priv->wopcm);
> -
>  	ret = intel_root_gt_init_early(dev_priv);
>  	if (ret < 0)
>  		goto err_rootgt;
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 8ca575202e5d..587e43ad7941 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -63,7 +63,6 @@
>  #include "intel_runtime_pm.h"
>  #include "intel_step.h"
>  #include "intel_uncore.h"
> -#include "intel_wopcm.h"
>  
>  struct drm_i915_clock_gating_funcs;
>  struct drm_i915_gem_object;
> @@ -236,8 +235,6 @@ struct drm_i915_private {
>  
>  	struct intel_gvt *gvt;
>  
> -	struct intel_wopcm wopcm;
> -
>  	struct pci_dev *bridge_dev;
>  
>  	struct rb_root uabi_engines;
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index a5b192ac885c..cfc8b17c1ee5 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -1140,9 +1140,10 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
>  	if (ret)
>  		return ret;
>  
> -	for_each_gt(gt, dev_priv, i)
> +	for_each_gt(gt, dev_priv, i) {
>  		intel_uc_fetch_firmwares(&gt->uc);
> -	intel_wopcm_init(&dev_priv->wopcm);
> +		intel_wopcm_init(&gt->wopcm);
> +	}
>  
>  	ret = i915_init_ggtt(dev_priv);
>  	if (ret) {

-- 
Jani Nikula, Intel Open Source Graphics Center

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

* [Intel-gfx] ✓ Fi.CI.IGT: success for drm/i915: prepare for uC loading on MTL
  2022-09-22 22:11 ` Daniele Ceraolo Spurio
                   ` (10 preceding siblings ...)
  (?)
@ 2022-09-23  9:24 ` Patchwork
  -1 siblings, 0 replies; 48+ messages in thread
From: Patchwork @ 2022-09-23  9:24 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 25864 bytes --]

== Series Details ==

Series: drm/i915: prepare for uC loading on MTL
URL   : https://patchwork.freedesktop.org/series/108925/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_12168_full -> Patchwork_108925v1_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

Participating hosts (9 -> 9)
------------------------------

  No changes in participating hosts

Known issues
------------

  Here are the changes found in Patchwork_108925v1_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_balancer@parallel-contexts:
    - shard-iclb:         NOTRUN -> [SKIP][1] ([i915#4525])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb8/igt@gem_exec_balancer@parallel-contexts.html

  * igt@gem_exec_fair@basic-none@vcs1:
    - shard-iclb:         NOTRUN -> [FAIL][2] ([i915#2842]) +1 similar issue
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb2/igt@gem_exec_fair@basic-none@vcs1.html

  * igt@gem_exec_fair@basic-throttle@rcs0:
    - shard-glk:          [PASS][3] -> [FAIL][4] ([i915#2842])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-glk5/igt@gem_exec_fair@basic-throttle@rcs0.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-glk9/igt@gem_exec_fair@basic-throttle@rcs0.html

  * igt@gem_exec_flush@basic-batch-kernel-default-cmd:
    - shard-iclb:         NOTRUN -> [SKIP][5] ([fdo#109313])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb1/igt@gem_exec_flush@basic-batch-kernel-default-cmd.html

  * igt@gem_lmem_swapping@basic:
    - shard-iclb:         NOTRUN -> [SKIP][6] ([i915#4613])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb5/igt@gem_lmem_swapping@basic.html

  * igt@gem_pxp@create-regular-context-1:
    - shard-iclb:         NOTRUN -> [SKIP][7] ([i915#4270]) +2 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb8/igt@gem_pxp@create-regular-context-1.html

  * igt@gem_render_copy@y-tiled-to-vebox-linear:
    - shard-iclb:         NOTRUN -> [SKIP][8] ([i915#768]) +2 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb1/igt@gem_render_copy@y-tiled-to-vebox-linear.html

  * igt@gem_softpin@evict-snoop-interruptible:
    - shard-iclb:         NOTRUN -> [SKIP][9] ([fdo#109312])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb1/igt@gem_softpin@evict-snoop-interruptible.html

  * igt@gem_userptr_blits@coherency-unsync:
    - shard-iclb:         NOTRUN -> [SKIP][10] ([i915#3297]) +1 similar issue
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb8/igt@gem_userptr_blits@coherency-unsync.html

  * igt@gem_userptr_blits@vma-merge:
    - shard-iclb:         NOTRUN -> [FAIL][11] ([i915#3318])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb8/igt@gem_userptr_blits@vma-merge.html

  * igt@gen3_render_linear_blits:
    - shard-iclb:         NOTRUN -> [SKIP][12] ([fdo#109289]) +3 similar issues
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb5/igt@gen3_render_linear_blits.html

  * igt@gen9_exec_parse@bb-start-param:
    - shard-iclb:         NOTRUN -> [SKIP][13] ([i915#2856]) +2 similar issues
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb5/igt@gen9_exec_parse@bb-start-param.html

  * igt@i915_pm_dc@dc3co-vpb-simulation:
    - shard-iclb:         NOTRUN -> [SKIP][14] ([i915#658]) +1 similar issue
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb1/igt@i915_pm_dc@dc3co-vpb-simulation.html

  * igt@i915_pm_dc@dc6-dpms:
    - shard-iclb:         [PASS][15] -> [FAIL][16] ([i915#3989] / [i915#454])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-iclb6/igt@i915_pm_dc@dc6-dpms.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb3/igt@i915_pm_dc@dc6-dpms.html

  * igt@i915_pm_rpm@modeset-non-lpsp:
    - shard-iclb:         NOTRUN -> [SKIP][17] ([fdo#110892])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb1/igt@i915_pm_rpm@modeset-non-lpsp.html

  * igt@i915_selftest@live@gt_heartbeat:
    - shard-glk:          [PASS][18] -> [DMESG-FAIL][19] ([i915#5334])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-glk6/igt@i915_selftest@live@gt_heartbeat.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-glk7/igt@i915_selftest@live@gt_heartbeat.html

  * igt@kms_big_fb@4-tiled-8bpp-rotate-180:
    - shard-iclb:         NOTRUN -> [SKIP][20] ([i915#5286]) +2 similar issues
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb5/igt@kms_big_fb@4-tiled-8bpp-rotate-180.html

  * igt@kms_big_fb@y-tiled-64bpp-rotate-90:
    - shard-iclb:         NOTRUN -> [SKIP][21] ([fdo#110725] / [fdo#111614]) +1 similar issue
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb8/igt@kms_big_fb@y-tiled-64bpp-rotate-90.html

  * igt@kms_big_fb@yf-tiled-64bpp-rotate-180:
    - shard-iclb:         NOTRUN -> [SKIP][22] ([fdo#110723])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb8/igt@kms_big_fb@yf-tiled-64bpp-rotate-180.html

  * igt@kms_ccs@pipe-b-crc-primary-basic-y_tiled_gen12_rc_ccs_cc:
    - shard-iclb:         NOTRUN -> [SKIP][23] ([fdo#109278] / [i915#3886]) +6 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb1/igt@kms_ccs@pipe-b-crc-primary-basic-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-c-crc-primary-basic-y_tiled_gen12_mc_ccs:
    - shard-apl:          NOTRUN -> [SKIP][24] ([fdo#109271] / [i915#3886]) +4 similar issues
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-apl6/igt@kms_ccs@pipe-c-crc-primary-basic-y_tiled_gen12_mc_ccs.html

  * igt@kms_chamelium@dp-mode-timings:
    - shard-iclb:         NOTRUN -> [SKIP][25] ([fdo#109284] / [fdo#111827]) +5 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb8/igt@kms_chamelium@dp-mode-timings.html

  * igt@kms_chamelium@vga-hpd:
    - shard-apl:          NOTRUN -> [SKIP][26] ([fdo#109271] / [fdo#111827]) +7 similar issues
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-apl1/igt@kms_chamelium@vga-hpd.html

  * igt@kms_content_protection@atomic:
    - shard-apl:          NOTRUN -> [TIMEOUT][27] ([i915#1319])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-apl2/igt@kms_content_protection@atomic.html

  * igt@kms_content_protection@dp-mst-type-1:
    - shard-iclb:         NOTRUN -> [SKIP][28] ([i915#3116])
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb1/igt@kms_content_protection@dp-mst-type-1.html

  * igt@kms_content_protection@uevent:
    - shard-iclb:         NOTRUN -> [SKIP][29] ([fdo#109300] / [fdo#111066])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb8/igt@kms_content_protection@uevent.html

  * igt@kms_cursor_crc@cursor-random-512x512:
    - shard-iclb:         NOTRUN -> [SKIP][30] ([i915#3359])
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb1/igt@kms_cursor_crc@cursor-random-512x512.html

  * igt@kms_cursor_legacy@flip-vs-cursor@atomic-transitions-varying-size:
    - shard-tglb:         [PASS][31] -> [FAIL][32] ([i915#2346])
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-tglb5/igt@kms_cursor_legacy@flip-vs-cursor@atomic-transitions-varying-size.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-tglb8/igt@kms_cursor_legacy@flip-vs-cursor@atomic-transitions-varying-size.html
    - shard-glk:          [PASS][33] -> [FAIL][34] ([i915#2346])
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-glk3/igt@kms_cursor_legacy@flip-vs-cursor@atomic-transitions-varying-size.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-glk2/igt@kms_cursor_legacy@flip-vs-cursor@atomic-transitions-varying-size.html

  * igt@kms_cursor_legacy@short-busy-flip-before-cursor:
    - shard-iclb:         NOTRUN -> [SKIP][35] ([i915#4103])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb5/igt@kms_cursor_legacy@short-busy-flip-before-cursor.html

  * igt@kms_flip@2x-wf_vblank-ts-check:
    - shard-iclb:         NOTRUN -> [SKIP][36] ([fdo#109274]) +3 similar issues
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb5/igt@kms_flip@2x-wf_vblank-ts-check.html

  * igt@kms_flip@plain-flip-fb-recreate-interruptible@a-hdmi-a1:
    - shard-glk:          [PASS][37] -> [FAIL][38] ([i915#2122])
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-glk8/igt@kms_flip@plain-flip-fb-recreate-interruptible@a-hdmi-a1.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-glk8/igt@kms_flip@plain-flip-fb-recreate-interruptible@a-hdmi-a1.html

  * igt@kms_flip_scaled_crc@flip-32bpp-4tile-to-64bpp-4tile-downscaling@pipe-a-valid-mode:
    - shard-iclb:         NOTRUN -> [SKIP][39] ([i915#2587] / [i915#2672]) +4 similar issues
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb1/igt@kms_flip_scaled_crc@flip-32bpp-4tile-to-64bpp-4tile-downscaling@pipe-a-valid-mode.html

  * igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-32bpp-yftile-upscaling@pipe-a-default-mode:
    - shard-iclb:         NOTRUN -> [SKIP][40] ([i915#2672]) +5 similar issues
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb2/igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-32bpp-yftile-upscaling@pipe-a-default-mode.html

  * igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling@pipe-a-default-mode:
    - shard-iclb:         NOTRUN -> [SKIP][41] ([i915#2672] / [i915#3555])
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb3/igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling@pipe-a-default-mode.html

  * igt@kms_force_connector_basic@force-load-detect:
    - shard-iclb:         NOTRUN -> [SKIP][42] ([fdo#109285])
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb8/igt@kms_force_connector_basic@force-load-detect.html

  * igt@kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-mmap-wc:
    - shard-iclb:         NOTRUN -> [SKIP][43] ([fdo#109280]) +22 similar issues
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb5/igt@kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-mmap-wc.html

  * igt@kms_hdr@static-toggle:
    - shard-iclb:         NOTRUN -> [SKIP][44] ([i915#3555]) +5 similar issues
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb5/igt@kms_hdr@static-toggle.html

  * igt@kms_pipe_crc_basic@nonblocking-crc:
    - shard-snb:          NOTRUN -> [SKIP][45] ([fdo#109271])
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-snb4/igt@kms_pipe_crc_basic@nonblocking-crc.html

  * igt@kms_plane_scaling@plane-downscale-with-rotation-factor-0-25@pipe-c-edp-1:
    - shard-iclb:         NOTRUN -> [SKIP][46] ([i915#5176]) +5 similar issues
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb5/igt@kms_plane_scaling@plane-downscale-with-rotation-factor-0-25@pipe-c-edp-1.html

  * igt@kms_plane_scaling@planes-upscale-factor-0-25-downscale-factor-0-25@pipe-b-edp-1:
    - shard-iclb:         NOTRUN -> [SKIP][47] ([i915#5235]) +2 similar issues
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb1/igt@kms_plane_scaling@planes-upscale-factor-0-25-downscale-factor-0-25@pipe-b-edp-1.html

  * igt@kms_prime@basic-modeset-hybrid:
    - shard-iclb:         NOTRUN -> [SKIP][48] ([i915#6524])
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb1/igt@kms_prime@basic-modeset-hybrid.html

  * igt@kms_psr2_sf@plane-move-sf-dmg-area:
    - shard-apl:          NOTRUN -> [SKIP][49] ([fdo#109271] / [i915#658]) +2 similar issues
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-apl2/igt@kms_psr2_sf@plane-move-sf-dmg-area.html

  * igt@kms_psr@psr2_cursor_blt:
    - shard-iclb:         NOTRUN -> [SKIP][50] ([fdo#109441]) +2 similar issues
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb5/igt@kms_psr@psr2_cursor_blt.html

  * igt@kms_psr@psr2_sprite_plane_move:
    - shard-iclb:         [PASS][51] -> [SKIP][52] ([fdo#109441]) +2 similar issues
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-iclb2/igt@kms_psr@psr2_sprite_plane_move.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb5/igt@kms_psr@psr2_sprite_plane_move.html

  * igt@kms_psr@psr2_sprite_plane_onoff:
    - shard-apl:          NOTRUN -> [SKIP][53] ([fdo#109271]) +116 similar issues
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-apl2/igt@kms_psr@psr2_sprite_plane_onoff.html

  * igt@kms_scaling_modes@scaling-mode-none@edp-1-pipe-b:
    - shard-iclb:         NOTRUN -> [SKIP][54] ([i915#5030]) +2 similar issues
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb5/igt@kms_scaling_modes@scaling-mode-none@edp-1-pipe-b.html

  * igt@kms_vblank@pipe-d-wait-forked:
    - shard-iclb:         NOTRUN -> [SKIP][55] ([fdo#109278]) +23 similar issues
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb5/igt@kms_vblank@pipe-d-wait-forked.html

  * igt@kms_writeback@writeback-invalid-parameters:
    - shard-apl:          NOTRUN -> [SKIP][56] ([fdo#109271] / [i915#2437])
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-apl2/igt@kms_writeback@writeback-invalid-parameters.html

  * igt@nouveau_crc@pipe-c-source-outp-inactive:
    - shard-iclb:         NOTRUN -> [SKIP][57] ([i915#2530]) +2 similar issues
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb8/igt@nouveau_crc@pipe-c-source-outp-inactive.html

  * igt@perf_pmu@rc6-suspend:
    - shard-apl:          [PASS][58] -> [DMESG-WARN][59] ([i915#180]) +1 similar issue
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-apl1/igt@perf_pmu@rc6-suspend.html
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-apl8/igt@perf_pmu@rc6-suspend.html

  * igt@prime_nv_pcopy@test3_2:
    - shard-iclb:         NOTRUN -> [SKIP][60] ([fdo#109291]) +3 similar issues
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb8/igt@prime_nv_pcopy@test3_2.html

  * igt@sysfs_clients@pidname:
    - shard-apl:          NOTRUN -> [SKIP][61] ([fdo#109271] / [i915#2994]) +1 similar issue
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-apl2/igt@sysfs_clients@pidname.html

  
#### Possible fixes ####

  * igt@gem_eio@kms:
    - shard-tglb:         [FAIL][62] ([i915#5784]) -> [PASS][63]
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-tglb2/igt@gem_eio@kms.html
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-tglb5/igt@gem_eio@kms.html

  * igt@gem_exec_balancer@parallel-bb-first:
    - shard-iclb:         [SKIP][64] ([i915#4525]) -> [PASS][65]
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-iclb8/igt@gem_exec_balancer@parallel-bb-first.html
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb2/igt@gem_exec_balancer@parallel-bb-first.html

  * igt@gem_exec_fair@basic-none-share@rcs0:
    - shard-glk:          [FAIL][66] ([i915#2842]) -> [PASS][67]
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-glk7/igt@gem_exec_fair@basic-none-share@rcs0.html
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-glk6/igt@gem_exec_fair@basic-none-share@rcs0.html

  * igt@gem_exec_fair@basic-none-solo@rcs0:
    - shard-apl:          [FAIL][68] ([i915#2842]) -> [PASS][69] +1 similar issue
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-apl6/igt@gem_exec_fair@basic-none-solo@rcs0.html
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-apl1/igt@gem_exec_fair@basic-none-solo@rcs0.html

  * igt@gem_exec_fair@basic-pace-solo@rcs0:
    - shard-tglb:         [FAIL][70] ([i915#2842]) -> [PASS][71]
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-tglb7/igt@gem_exec_fair@basic-pace-solo@rcs0.html
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-tglb7/igt@gem_exec_fair@basic-pace-solo@rcs0.html

  * igt@gem_workarounds@suspend-resume:
    - shard-apl:          [DMESG-WARN][72] ([i915#180]) -> [PASS][73] +3 similar issues
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-apl8/igt@gem_workarounds@suspend-resume.html
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-apl6/igt@gem_workarounds@suspend-resume.html

  * igt@kms_async_flips@alternate-sync-async-flip@pipe-c-hdmi-a-1:
    - shard-glk:          [FAIL][74] ([i915#2521]) -> [PASS][75]
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-glk9/igt@kms_async_flips@alternate-sync-async-flip@pipe-c-hdmi-a-1.html
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-glk5/igt@kms_async_flips@alternate-sync-async-flip@pipe-c-hdmi-a-1.html

  * igt@kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-downscaling@pipe-a-default-mode:
    - shard-iclb:         [SKIP][76] ([i915#3555]) -> [PASS][77]
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-iclb2/igt@kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-downscaling@pipe-a-default-mode.html
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb3/igt@kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-downscaling@pipe-a-default-mode.html

  * igt@kms_psr@psr2_primary_blt:
    - shard-iclb:         [SKIP][78] ([fdo#109441]) -> [PASS][79]
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-iclb3/igt@kms_psr@psr2_primary_blt.html
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb2/igt@kms_psr@psr2_primary_blt.html

  
#### Warnings ####

  * igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-fully-sf:
    - shard-iclb:         [SKIP][80] ([i915#2920]) -> [SKIP][81] ([i915#658])
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-iclb2/igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-fully-sf.html
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb3/igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-fully-sf.html

  * igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area:
    - shard-iclb:         [SKIP][82] ([fdo#111068] / [i915#658]) -> [SKIP][83] ([i915#2920]) +1 similar issue
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-iclb6/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area.html
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb2/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area.html

  * igt@kms_psr2_sf@plane-move-sf-dmg-area:
    - shard-iclb:         [SKIP][84] ([i915#2920]) -> [SKIP][85] ([fdo#111068] / [i915#658]) +1 similar issue
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-iclb2/igt@kms_psr2_sf@plane-move-sf-dmg-area.html
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb3/igt@kms_psr2_sf@plane-move-sf-dmg-area.html

  * igt@kms_psr2_su@page_flip-nv12:
    - shard-iclb:         [SKIP][86] ([fdo#109642] / [fdo#111068] / [i915#658]) -> [FAIL][87] ([i915#5939])
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-iclb8/igt@kms_psr2_su@page_flip-nv12.html
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-iclb2/igt@kms_psr2_su@page_flip-nv12.html

  * igt@runner@aborted:
    - shard-apl:          ([FAIL][88], [FAIL][89], [FAIL][90], [FAIL][91], [FAIL][92], [FAIL][93]) ([fdo#109271] / [i915#180] / [i915#3002] / [i915#4312]) -> ([FAIL][94], [FAIL][95], [FAIL][96], [FAIL][97]) ([i915#180] / [i915#3002] / [i915#4312])
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-apl3/igt@runner@aborted.html
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-apl8/igt@runner@aborted.html
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-apl7/igt@runner@aborted.html
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-apl1/igt@runner@aborted.html
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-apl8/igt@runner@aborted.html
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12168/shard-apl6/igt@runner@aborted.html
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-apl8/igt@runner@aborted.html
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-apl7/igt@runner@aborted.html
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-apl1/igt@runner@aborted.html
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/shard-apl8/igt@runner@aborted.html

  
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109274]: https://bugs.freedesktop.org/show_bug.cgi?id=109274
  [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
  [fdo#109280]: https://bugs.freedesktop.org/show_bug.cgi?id=109280
  [fdo#109284]: https://bugs.freedesktop.org/show_bug.cgi?id=109284
  [fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
  [fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
  [fdo#109291]: https://bugs.freedesktop.org/show_bug.cgi?id=109291
  [fdo#109300]: https://bugs.freedesktop.org/show_bug.cgi?id=109300
  [fdo#109312]: https://bugs.freedesktop.org/show_bug.cgi?id=109312
  [fdo#109313]: https://bugs.freedesktop.org/show_bug.cgi?id=109313
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
  [fdo#110723]: https://bugs.freedesktop.org/show_bug.cgi?id=110723
  [fdo#110725]: https://bugs.freedesktop.org/show_bug.cgi?id=110725
  [fdo#110892]: https://bugs.freedesktop.org/show_bug.cgi?id=110892
  [fdo#111066]: https://bugs.freedesktop.org/show_bug.cgi?id=111066
  [fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
  [fdo#111614]: https://bugs.freedesktop.org/show_bug.cgi?id=111614
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#1319]: https://gitlab.freedesktop.org/drm/intel/issues/1319
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#2122]: https://gitlab.freedesktop.org/drm/intel/issues/2122
  [i915#2346]: https://gitlab.freedesktop.org/drm/intel/issues/2346
  [i915#2437]: https://gitlab.freedesktop.org/drm/intel/issues/2437
  [i915#2521]: https://gitlab.freedesktop.org/drm/intel/issues/2521
  [i915#2530]: https://gitlab.freedesktop.org/drm/intel/issues/2530
  [i915#2587]: https://gitlab.freedesktop.org/drm/intel/issues/2587
  [i915#2672]: https://gitlab.freedesktop.org/drm/intel/issues/2672
  [i915#2842]: https://gitlab.freedesktop.org/drm/intel/issues/2842
  [i915#2856]: https://gitlab.freedesktop.org/drm/intel/issues/2856
  [i915#2920]: https://gitlab.freedesktop.org/drm/intel/issues/2920
  [i915#2994]: https://gitlab.freedesktop.org/drm/intel/issues/2994
  [i915#3002]: https://gitlab.freedesktop.org/drm/intel/issues/3002
  [i915#3116]: https://gitlab.freedesktop.org/drm/intel/issues/3116
  [i915#3297]: https://gitlab.freedesktop.org/drm/intel/issues/3297
  [i915#3318]: https://gitlab.freedesktop.org/drm/intel/issues/3318
  [i915#3359]: https://gitlab.freedesktop.org/drm/intel/issues/3359
  [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
  [i915#3886]: https://gitlab.freedesktop.org/drm/intel/issues/3886
  [i915#3989]: https://gitlab.freedesktop.org/drm/intel/issues/3989
  [i915#4103]: https://gitlab.freedesktop.org/drm/intel/issues/4103
  [i915#4270]: https://gitlab.freedesktop.org/drm/intel/issues/4270
  [i915#4312]: https://gitlab.freedesktop.org/drm/intel/issues/4312
  [i915#4525]: https://gitlab.freedesktop.org/drm/intel/issues/4525
  [i915#454]: https://gitlab.freedesktop.org/drm/intel/issues/454
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#5030]: https://gitlab.freedesktop.org/drm/intel/issues/5030
  [i915#5176]: https://gitlab.freedesktop.org/drm/intel/issues/5176
  [i915#5235]: https://gitlab.freedesktop.org/drm/intel/issues/5235
  [i915#5286]: https://gitlab.freedesktop.org/drm/intel/issues/5286
  [i915#5334]: https://gitlab.freedesktop.org/drm/intel/issues/5334
  [i915#5784]: https://gitlab.freedesktop.org/drm/intel/issues/5784
  [i915#5939]: https://gitlab.freedesktop.org/drm/intel/issues/5939
  [i915#6524]: https://gitlab.freedesktop.org/drm/intel/issues/6524
  [i915#658]: https://gitlab.freedesktop.org/drm/intel/issues/658
  [i915#768]: https://gitlab.freedesktop.org/drm/intel/issues/768


Build changes
-------------

  * Linux: CI_DRM_12168 -> Patchwork_108925v1

  CI-20190529: 20190529
  CI_DRM_12168: fea329811a7bc341aac5f51ab66ec41a3d0844af @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6662: dcb1d7a8822e62935f4fe3f2e6a04caaee669369 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_108925v1: fea329811a7bc341aac5f51ab66ec41a3d0844af @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_108925v1/index.html

[-- Attachment #2: Type: text/html, Size: 30952 bytes --]

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

* Re: [Intel-gfx] [PATCH 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines
  2022-09-22 22:11   ` Daniele Ceraolo Spurio
  (?)
@ 2022-09-23 10:53   ` Tvrtko Ursulin
  2022-09-23 15:41     ` Ceraolo Spurio, Daniele
  -1 siblings, 1 reply; 48+ messages in thread
From: Tvrtko Ursulin @ 2022-09-23 10:53 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: dri-devel, Alan Previn


On 22/09/2022 23:11, 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
> 
> 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>
> ---
>   drivers/gpu/drm/i915/gt/uc/intel_huc.c | 21 +++++++++++++++++++++
>   drivers/gpu/drm/i915/i915_drv.h        |  9 ++++++---
>   2 files changed, 27 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 3bb8838e325a..d4e2b252f16c 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> @@ -42,12 +42,33 @@
>    * HuC-specific commands.
>    */
>   
> +static bool vcs_supported(struct intel_gt *gt)
> +{
> +	intel_engine_mask_t mask = gt->info.engine_mask;
> +
> +	/*
> +	 * we can reach here from i915_driver_early_probe for primary
> +	 * GT with it being not fully setup hence fall back to the device info's
> +	 * engine mask
> +	 */
> +	if (!mask && gt_is_root(gt))
> +		mask = RUNTIME_INFO(gt->i915)->platform_engine_mask;

Is it possible for all instances to be fused off? Wondering if the 
function shouldn't just use platform_engine_mask.

Regards,

Tvrtko

> +
> +	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 134fc1621821..8ca575202e5d 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -777,12 +777,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] 48+ messages in thread

* Re: [Intel-gfx] [PATCH 5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations.
  2022-09-23  9:24   ` Jani Nikula
@ 2022-09-23 15:34     ` Ceraolo Spurio, Daniele
  0 siblings, 0 replies; 48+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-09-23 15:34 UTC (permalink / raw)
  To: Jani Nikula, intel-gfx; +Cc: dri-devel, Alan Previn



On 9/23/2022 2:24 AM, Jani Nikula wrote:
> On Thu, 22 Sep 2022, Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> wrote:
>> From: Aravind Iddamsetty <aravind.iddamsetty@intel.com>
>>
>> With MTL standalone media architecture the wopcm layout has changed with
>> separate partitioning in WOPCM for GCD/GT GuC and SA Media GuC. The size
>> of WOPCM is 4MB with lower 2MB for SA Media and upper 2MB for GCD/GT.
>>
>>      +=====+===> +====================+ <== WOPCM TOP
>>      ^     ^     |                    |
>>      |     |     |                    |
>>      |    GCD    |   GCD RC6 Image    |
>>      |    GuC    |    Power Context   |
>>      |    WOPCM  |                    |
>>      |    Size   +--------------------+
>>      |     |     |   GCD GuC Image    |
>>      |     |     |                    |
>>      |     v     |                    |
>>      |     +===> +====================+ <== SA Media GuC WOPCM Top
>>      |     ^     |                    |
>>      |   SA Media|                    |
>>      |    GuC    | SA Media RC6 Image |
>>      |   WOPCM   |    Power Context   |
>>      |    Size   |                    |
>>    WOPCM   |     +--------------------+
>>      |     |     |                    |
>>      |     |     | SA Media GuC Image |
>>      |     v     |                    |
>>      |     +===> +====================+ <== GuC WOPCM base
>>      |           |     WOPCM RSVD     |
>>      |           +------------------- + <== HuC Firmware Top
>>      v           |      HuC FW        |
>>      +=========> +====================+ <== WOPCM Base
>>
>> Given that MTL has GuC deprivilege, the WOPCM registers are pre-locked
>> by the bios. Therefore, we can skip all the math for the partitioning
>> and just limit ourselves to sanity checking the values.
>>
>> Signed-off-by: Aravind Iddamsetty <aravind.iddamsetty@intel.com>
>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>> Cc: Matt Roper <matthew.d.roper@intel.com>
>> Cc: John Harrison <john.c.harrison@intel.com>
>> Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
>> ---
>>   drivers/gpu/drm/i915/Makefile               |  7 +--
>>   drivers/gpu/drm/i915/gt/intel_ggtt.c        |  2 +-
>>   drivers/gpu/drm/i915/gt/intel_gt.c          |  1 +
>>   drivers/gpu/drm/i915/gt/intel_gt_types.h    |  2 +
>>   drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c | 48 +++++++++++++++------
>>   drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h |  0
>>   drivers/gpu/drm/i915/gt/uc/intel_uc.c       |  4 +-
>>   drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c    | 14 +++---
>>   drivers/gpu/drm/i915/i915_driver.c          |  2 -
>>   drivers/gpu/drm/i915/i915_drv.h             |  3 --
>>   drivers/gpu/drm/i915/i915_gem.c             |  5 ++-
>>   11 files changed, 56 insertions(+), 32 deletions(-)
>>   rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.c (86%)
>>   rename drivers/gpu/drm/i915/{ => gt}/intel_wopcm.h (100%)
>>
>> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
>> index a26edcdadc21..6ed4c745b226 100644
>> --- a/drivers/gpu/drm/i915/Makefile
>> +++ b/drivers/gpu/drm/i915/Makefile
>> @@ -129,7 +129,9 @@ gt-y += \
>>   	gt/intel_timeline.o \
>>   	gt/intel_workarounds.o \
>>   	gt/shmem_utils.o \
>> -	gt/sysfs_engines.o
>> +	gt/sysfs_engines.o \
>> +	gt/intel_wopcm.o
> The comment near the top of the file:
>
> # Please keep these build lists sorted!

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

Daniele

>
>> +
>>   # x86 intel-gtt module support
>>   gt-$(CONFIG_X86) += gt/intel_ggtt_gmch.o
>>   # autogenerated null render state
>> @@ -183,8 +185,7 @@ i915-y += \
>>   	  i915_trace_points.o \
>>   	  i915_ttm_buddy_manager.o \
>>   	  i915_vma.o \
>> -	  i915_vma_resource.o \
>> -	  intel_wopcm.o
>> +	  i915_vma_resource.o
>>   
>>   # general-purpose microcontroller (GuC) support
>>   i915-y += gt/uc/intel_uc.o \
>> diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
>> index 30cf5c3369d9..605e1aa674d4 100644
>> --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
>> +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
>> @@ -560,7 +560,7 @@ static int init_ggtt(struct i915_ggtt *ggtt)
>>   	 * why.
>>   	 */
>>   	ggtt->pin_bias = max_t(u32, I915_GTT_PAGE_SIZE,
>> -			       intel_wopcm_guc_size(&ggtt->vm.i915->wopcm));
>> +			       intel_wopcm_guc_size(&ggtt->vm.gt->wopcm));
>>   
>>   	ret = intel_vgt_balloon(ggtt);
>>   	if (ret)
>> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
>> index b367cfff48d5..a95eb0b656d2 100644
>> --- a/drivers/gpu/drm/i915/gt/intel_gt.c
>> +++ b/drivers/gpu/drm/i915/gt/intel_gt.c
>> @@ -56,6 +56,7 @@ void intel_gt_common_init_early(struct intel_gt *gt)
>>   	seqcount_mutex_init(&gt->tlb.seqno, &gt->tlb.invalidate_lock);
>>   	intel_gt_pm_init_early(gt);
>>   
>> +	intel_wopcm_init_early(&gt->wopcm);
>>   	intel_uc_init_early(&gt->uc);
>>   	intel_rps_init_early(&gt->rps);
>>   }
>> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
>> index f19c2de77ff6..c20a32d2700f 100644
>> --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
>> +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
>> @@ -30,6 +30,7 @@
>>   #include "intel_migrate_types.h"
>>   #include "intel_wakeref.h"
>>   #include "pxp/intel_pxp_types.h"
>> +#include "intel_wopcm.h"
>>   
>>   struct drm_i915_private;
>>   struct i915_ggtt;
>> @@ -97,6 +98,7 @@ struct intel_gt {
>>   
>>   	struct intel_uc uc;
>>   	struct intel_gsc gsc;
>> +	struct intel_wopcm wopcm;
>>   
>>   	struct {
>>   		/* Serialize global tlb invalidations */
>> diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/gt/intel_wopcm.c
>> similarity index 86%
>> rename from drivers/gpu/drm/i915/intel_wopcm.c
>> rename to drivers/gpu/drm/i915/gt/intel_wopcm.c
>> index 322fb9eeb880..487fbbbdf3d6 100644
>> --- a/drivers/gpu/drm/i915/intel_wopcm.c
>> +++ b/drivers/gpu/drm/i915/gt/intel_wopcm.c
>> @@ -43,6 +43,7 @@
>>   /* Default WOPCM size is 2MB from Gen11, 1MB on previous platforms */
>>   #define GEN11_WOPCM_SIZE		SZ_2M
>>   #define GEN9_WOPCM_SIZE			SZ_1M
>> +#define XELPM_SAMEDIA_WOPCM_SIZE	SZ_2M
>>   #define MAX_WOPCM_SIZE			SZ_8M
>>   /* 16KB WOPCM (RSVD WOPCM) is reserved from HuC firmware top. */
>>   #define WOPCM_RESERVED_SIZE		SZ_16K
>> @@ -64,9 +65,9 @@
>>   #define GEN9_GUC_FW_RESERVED	SZ_128K
>>   #define GEN9_GUC_WOPCM_OFFSET	(GUC_WOPCM_RESERVED + GEN9_GUC_FW_RESERVED)
>>   
>> -static inline struct drm_i915_private *wopcm_to_i915(struct intel_wopcm *wopcm)
>> +static inline struct intel_gt *wopcm_to_gt(struct intel_wopcm *wopcm)
>>   {
>> -	return container_of(wopcm, struct drm_i915_private, wopcm);
>> +	return container_of(wopcm, struct intel_gt, wopcm);
>>   }
>>   
>>   /**
>> @@ -77,7 +78,8 @@ static inline struct drm_i915_private *wopcm_to_i915(struct intel_wopcm *wopcm)
>>    */
>>   void intel_wopcm_init_early(struct intel_wopcm *wopcm)
>>   {
>> -	struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
>> +	struct intel_gt *gt = wopcm_to_gt(wopcm);
>> +	struct drm_i915_private *i915 = gt->i915;
>>   
>>   	if (!HAS_GT_UC(i915))
>>   		return;
>> @@ -157,14 +159,18 @@ static bool check_hw_restrictions(struct drm_i915_private *i915,
>>   	return true;
>>   }
>>   
>> -static bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
>> +static bool __check_layout(struct intel_gt *gt, u32 wopcm_size,
>>   			   u32 guc_wopcm_base, u32 guc_wopcm_size,
>>   			   u32 guc_fw_size, u32 huc_fw_size)
>>   {
>> +	struct drm_i915_private *i915 = gt->i915;
>>   	const u32 ctx_rsvd = context_reserved_size(i915);
>>   	u32 size;
>>   
>>   	size = wopcm_size - ctx_rsvd;
>> +	if (MEDIA_VER(i915) >= 13)
>> +		size += XELPM_SAMEDIA_WOPCM_SIZE;
>> +
>>   	if (unlikely(range_overflows(guc_wopcm_base, guc_wopcm_size, size))) {
>>   		drm_err(&i915->drm,
>>   			"WOPCM: invalid GuC region layout: %uK + %uK > %uK\n",
>> @@ -181,12 +187,14 @@ static bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
>>   		return false;
>>   	}
>>   
>> -	size = huc_fw_size + WOPCM_RESERVED_SIZE;
>> -	if (unlikely(guc_wopcm_base < size)) {
>> -		drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n",
>> -			intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
>> -			guc_wopcm_base / SZ_1K, size / SZ_1K);
>> -		return false;
>> +	if (VDBOX_MASK(gt)) {
>> +		size = huc_fw_size + WOPCM_RESERVED_SIZE;
>> +		if (unlikely(guc_wopcm_base < size)) {
>> +			drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n",
>> +				intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
>> +				guc_wopcm_base / SZ_1K, size / SZ_1K);
>> +			return false;
>> +		}
>>   	}
>>   
>>   	return check_hw_restrictions(i915, guc_wopcm_base, guc_wopcm_size,
>> @@ -228,8 +236,8 @@ static bool __wopcm_regs_writable(struct intel_uncore *uncore)
>>    */
>>   void intel_wopcm_init(struct intel_wopcm *wopcm)
>>   {
>> -	struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
>> -	struct intel_gt *gt = to_gt(i915);
>> +	struct intel_gt *gt = wopcm_to_gt(wopcm);
>> +	struct drm_i915_private *i915 = gt->i915;
>>   	u32 guc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.guc.fw);
>>   	u32 huc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.huc.fw);
>>   	u32 ctx_rsvd = context_reserved_size(i915);
>> @@ -274,6 +282,19 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
>>   		goto check;
>>   	}
>>   
>> +	/*
>> +	 * On platforms with a media GT, the WOPCM is partitioned between the
>> +	 * two GTs, so we would have to take that into account when doing the
>> +	 * math below. There is also a new section reserved for the GSC ctx
>> +	 * that w would have to factor in. However, all platforms with a media
>> +	 * GT also have GuC depriv enabled, so the WOPCM regs are pre-locked
>> +	 * and therefore we don't have to do the math ourselves.
>> +	 */
>> +	if (unlikely(i915->media_gt)) {
>> +		drm_err(&i915->drm, "Unlocked WOPCM regs with media GT\n");
>> +		return;
>> +	}
>> +
>>   	/*
>>   	 * Aligned value of guc_wopcm_base will determine available WOPCM space
>>   	 * for HuC firmware and mandatory reserved area.
>> @@ -289,13 +310,14 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
>>   
>>   	/* Aligned remainings of usable WOPCM space can be assigned to GuC. */
>>   	guc_wopcm_size = wopcm_size - ctx_rsvd - guc_wopcm_base;
>> +
>>   	guc_wopcm_size &= GUC_WOPCM_SIZE_MASK;
>>   
>>   	drm_dbg(&i915->drm, "Calculated GuC WOPCM [%uK, %uK)\n",
>>   		guc_wopcm_base / SZ_1K, guc_wopcm_size / SZ_1K);
>>   
>>   check:
>> -	if (__check_layout(i915, wopcm_size, guc_wopcm_base, guc_wopcm_size,
>> +	if (__check_layout(gt, wopcm_size, guc_wopcm_base, guc_wopcm_size,
>>   			   guc_fw_size, huc_fw_size)) {
>>   		wopcm->guc.base = guc_wopcm_base;
>>   		wopcm->guc.size = guc_wopcm_size;
>> diff --git a/drivers/gpu/drm/i915/intel_wopcm.h b/drivers/gpu/drm/i915/gt/intel_wopcm.h
>> similarity index 100%
>> rename from drivers/gpu/drm/i915/intel_wopcm.h
>> rename to drivers/gpu/drm/i915/gt/intel_wopcm.h
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
>> index dbd048b77e19..4cd8a787f9e5 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
>> @@ -357,8 +357,8 @@ static int uc_init_wopcm(struct intel_uc *uc)
>>   {
>>   	struct intel_gt *gt = uc_to_gt(uc);
>>   	struct intel_uncore *uncore = gt->uncore;
>> -	u32 base = intel_wopcm_guc_base(&gt->i915->wopcm);
>> -	u32 size = intel_wopcm_guc_size(&gt->i915->wopcm);
>> +	u32 base = intel_wopcm_guc_base(&gt->wopcm);
>> +	u32 size = intel_wopcm_guc_size(&gt->wopcm);
>>   	u32 huc_agent = intel_uc_uses_huc(uc) ? HUC_LOADING_AGENT_GUC : 0;
>>   	u32 mask;
>>   	int err;
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> index d6ca772e9f4b..a9ff9abb66db 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> @@ -469,10 +469,11 @@ static int check_gsc_manifest(const struct firmware *fw,
>>   	return 0;
>>   }
>>   
>> -static int check_ccs_header(struct drm_i915_private *i915,
>> +static int check_ccs_header(struct intel_gt *gt,
>>   			    const struct firmware *fw,
>>   			    struct intel_uc_fw *uc_fw)
>>   {
>> +	struct drm_i915_private *i915 = gt->i915;
>>   	struct uc_css_header *css;
>>   	size_t size;
>>   
>> @@ -514,10 +515,10 @@ static int check_ccs_header(struct drm_i915_private *i915,
>>   
>>   	/* Sanity check whether this fw is not larger than whole WOPCM memory */
>>   	size = __intel_uc_fw_get_upload_size(uc_fw);
>> -	if (unlikely(size >= i915->wopcm.size)) {
>> +	if (unlikely(size >= gt->wopcm.size)) {
>>   		drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu > %zu\n",
>>   			 intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
>> -			 size, (size_t)i915->wopcm.size);
>> +			 size, (size_t)gt->wopcm.size);
>>   		return -E2BIG;
>>   	}
>>   
>> @@ -545,7 +546,8 @@ static int check_ccs_header(struct drm_i915_private *i915,
>>    */
>>   int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>>   {
>> -	struct drm_i915_private *i915 = __uc_fw_to_gt(uc_fw)->i915;
>> +	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
>> +	struct drm_i915_private *i915 = gt->i915;
>>   	struct intel_uc_fw_file file_ideal;
>>   	struct device *dev = i915->drm.dev;
>>   	struct drm_i915_gem_object *obj;
>> @@ -553,7 +555,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>>   	bool old_ver = false;
>>   	int err;
>>   
>> -	GEM_BUG_ON(!i915->wopcm.size);
>> +	GEM_BUG_ON(!gt->wopcm.size);
>>   	GEM_BUG_ON(!intel_uc_fw_is_enabled(uc_fw));
>>   
>>   	err = i915_inject_probe_error(i915, -ENXIO);
>> @@ -595,7 +597,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>>   	if (uc_fw->loaded_via_gsc)
>>   		err = check_gsc_manifest(fw, uc_fw);
>>   	else
>> -		err = check_ccs_header(i915, fw, uc_fw);
>> +		err = check_ccs_header(gt, fw, uc_fw);
>>   	if (err)
>>   		goto fail;
>>   
>> diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
>> index 9d1fc2477f80..51fc030774fa 100644
>> --- a/drivers/gpu/drm/i915/i915_driver.c
>> +++ b/drivers/gpu/drm/i915/i915_driver.c
>> @@ -369,8 +369,6 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
>>   	if (ret)
>>   		goto err_ttm;
>>   
>> -	intel_wopcm_init_early(&dev_priv->wopcm);
>> -
>>   	ret = intel_root_gt_init_early(dev_priv);
>>   	if (ret < 0)
>>   		goto err_rootgt;
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 8ca575202e5d..587e43ad7941 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -63,7 +63,6 @@
>>   #include "intel_runtime_pm.h"
>>   #include "intel_step.h"
>>   #include "intel_uncore.h"
>> -#include "intel_wopcm.h"
>>   
>>   struct drm_i915_clock_gating_funcs;
>>   struct drm_i915_gem_object;
>> @@ -236,8 +235,6 @@ struct drm_i915_private {
>>   
>>   	struct intel_gvt *gvt;
>>   
>> -	struct intel_wopcm wopcm;
>> -
>>   	struct pci_dev *bridge_dev;
>>   
>>   	struct rb_root uabi_engines;
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
>> index a5b192ac885c..cfc8b17c1ee5 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -1140,9 +1140,10 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
>>   	if (ret)
>>   		return ret;
>>   
>> -	for_each_gt(gt, dev_priv, i)
>> +	for_each_gt(gt, dev_priv, i) {
>>   		intel_uc_fetch_firmwares(&gt->uc);
>> -	intel_wopcm_init(&dev_priv->wopcm);
>> +		intel_wopcm_init(&gt->wopcm);
>> +	}
>>   
>>   	ret = i915_init_ggtt(dev_priv);
>>   	if (ret) {


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

* Re: [Intel-gfx] [PATCH 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines
  2022-09-23 10:53   ` [Intel-gfx] " Tvrtko Ursulin
@ 2022-09-23 15:41     ` Ceraolo Spurio, Daniele
  2022-09-26 16:15       ` Tvrtko Ursulin
  0 siblings, 1 reply; 48+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-09-23 15:41 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx; +Cc: dri-devel, Alan Previn



On 9/23/2022 3:53 AM, Tvrtko Ursulin wrote:
>
> On 22/09/2022 23:11, 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
>>
>> 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>
>> ---
>>   drivers/gpu/drm/i915/gt/uc/intel_huc.c | 21 +++++++++++++++++++++
>>   drivers/gpu/drm/i915/i915_drv.h        |  9 ++++++---
>>   2 files changed, 27 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 3bb8838e325a..d4e2b252f16c 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> @@ -42,12 +42,33 @@
>>    * HuC-specific commands.
>>    */
>>   +static bool vcs_supported(struct intel_gt *gt)
>> +{
>> +    intel_engine_mask_t mask = gt->info.engine_mask;
>> +
>> +    /*
>> +     * we can reach here from i915_driver_early_probe for primary
>> +     * GT with it being not fully setup hence fall back to the 
>> device info's
>> +     * engine mask
>> +     */
>> +    if (!mask && gt_is_root(gt))
>> +        mask = RUNTIME_INFO(gt->i915)->platform_engine_mask;
>
> Is it possible for all instances to be fused off? Wondering if the 
> function shouldn't just use platform_engine_mask.

The spec says that there is always going to be at least 1 VCS (bspec 
55417 in case you want to double-check). I don't see that changing in 
the future, because what's the point of having a media GT if you don't 
have any enabled VCS engines on it?
Also, platform_engine_mask only contains the entries of the primary GT, 
for the other GTs we'd have to navigate the array in the device info 
structure and I don't think we want to do that from here when we've 
already copied the mask inside gt->info.engine_mask.

Daniele

>
> Regards,
>
> Tvrtko
>
>> +
>> +    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 134fc1621821..8ca575202e5d 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -777,12 +777,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] 48+ messages in thread

* Re: [Intel-gfx] [PATCH 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines
  2022-09-23 15:41     ` Ceraolo Spurio, Daniele
@ 2022-09-26 16:15       ` Tvrtko Ursulin
  2022-09-26 16:28         ` Ceraolo Spurio, Daniele
  0 siblings, 1 reply; 48+ messages in thread
From: Tvrtko Ursulin @ 2022-09-26 16:15 UTC (permalink / raw)
  To: Ceraolo Spurio, Daniele, intel-gfx; +Cc: dri-devel, Alan Previn


On 23/09/2022 16:41, Ceraolo Spurio, Daniele wrote:
> On 9/23/2022 3:53 AM, Tvrtko Ursulin wrote:
>>
>> On 22/09/2022 23:11, 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
>>>
>>> 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>
>>> ---
>>>   drivers/gpu/drm/i915/gt/uc/intel_huc.c | 21 +++++++++++++++++++++
>>>   drivers/gpu/drm/i915/i915_drv.h        |  9 ++++++---
>>>   2 files changed, 27 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 3bb8838e325a..d4e2b252f16c 100644
>>> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>>> @@ -42,12 +42,33 @@
>>>    * HuC-specific commands.
>>>    */
>>>   +static bool vcs_supported(struct intel_gt *gt)
>>> +{
>>> +    intel_engine_mask_t mask = gt->info.engine_mask;
>>> +
>>> +    /*
>>> +     * we can reach here from i915_driver_early_probe for primary
>>> +     * GT with it being not fully setup hence fall back to the 
>>> device info's
>>> +     * engine mask
>>> +     */
>>> +    if (!mask && gt_is_root(gt))
>>> +        mask = RUNTIME_INFO(gt->i915)->platform_engine_mask;
>>
>> Is it possible for all instances to be fused off? Wondering if the 
>> function shouldn't just use platform_engine_mask.
> 
> The spec says that there is always going to be at least 1 VCS (bspec 
> 55417 in case you want to double-check). I don't see that changing in 
> the future, because what's the point of having a media GT if you don't 
> have any enabled VCS engines on it?

That was my gut feeling as well, however..

> Also, platform_engine_mask only contains the entries of the primary GT, 
> for the other GTs we'd have to navigate the array in the device info 
> structure and I don't think we want to do that from here when we've 
> already copied the mask inside gt->info.engine_mask.

... this is very annoying. Because function is now a bit dodgy, no? 
Maybe gets the caller a real answer for a _specific_ gt, or maybe gets a 
fake-ish answer for a root gt. Or if not a root gt and called too early 
maybe it returns a false zero?

Hm would GEM_BUG_ON(!mask && !gt_is_root(gt)) be correct?

And not even bother to implement is as fallback?

if (gt_is_root)
	return platform_mask;
else
	return gt_mask;

Would that be clearer? Coupled with the comment from the patch, maybe 
expanded with the statement that if there are some vcs engines, at least 
one must remain post fusing?

Regards,

Tvrtko

>>> +
>>> +    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 134fc1621821..8ca575202e5d 100644
>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>> @@ -777,12 +777,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] 48+ messages in thread

* Re: [Intel-gfx] [PATCH 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines
  2022-09-26 16:15       ` Tvrtko Ursulin
@ 2022-09-26 16:28         ` Ceraolo Spurio, Daniele
  0 siblings, 0 replies; 48+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-09-26 16:28 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx; +Cc: dri-devel, Alan Previn



On 9/26/2022 9:15 AM, Tvrtko Ursulin wrote:
>
> On 23/09/2022 16:41, Ceraolo Spurio, Daniele wrote:
>> On 9/23/2022 3:53 AM, Tvrtko Ursulin wrote:
>>>
>>> On 22/09/2022 23:11, 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
>>>>
>>>> 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>
>>>> ---
>>>>   drivers/gpu/drm/i915/gt/uc/intel_huc.c | 21 +++++++++++++++++++++
>>>>   drivers/gpu/drm/i915/i915_drv.h        |  9 ++++++---
>>>>   2 files changed, 27 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 3bb8838e325a..d4e2b252f16c 100644
>>>> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>>>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>>>> @@ -42,12 +42,33 @@
>>>>    * HuC-specific commands.
>>>>    */
>>>>   +static bool vcs_supported(struct intel_gt *gt)
>>>> +{
>>>> +    intel_engine_mask_t mask = gt->info.engine_mask;
>>>> +
>>>> +    /*
>>>> +     * we can reach here from i915_driver_early_probe for primary
>>>> +     * GT with it being not fully setup hence fall back to the 
>>>> device info's
>>>> +     * engine mask
>>>> +     */
>>>> +    if (!mask && gt_is_root(gt))
>>>> +        mask = RUNTIME_INFO(gt->i915)->platform_engine_mask;
>>>
>>> Is it possible for all instances to be fused off? Wondering if the 
>>> function shouldn't just use platform_engine_mask.
>>
>> The spec says that there is always going to be at least 1 VCS (bspec 
>> 55417 in case you want to double-check). I don't see that changing in 
>> the future, because what's the point of having a media GT if you 
>> don't have any enabled VCS engines on it?
>
> That was my gut feeling as well, however..
>
>> Also, platform_engine_mask only contains the entries of the primary 
>> GT, for the other GTs we'd have to navigate the array in the device 
>> info structure and I don't think we want to do that from here when 
>> we've already copied the mask inside gt->info.engine_mask.
>
> ... this is very annoying. Because function is now a bit dodgy, no? 
> Maybe gets the caller a real answer for a _specific_ gt, or maybe gets 
> a fake-ish answer for a root gt. Or if not a root gt and called too 
> early maybe it returns a false zero?
>
> Hm would GEM_BUG_ON(!mask && !gt_is_root(gt)) be correct?
>
> And not even bother to implement is as fallback?
>
> if (gt_is_root)
>     return platform_mask;
> else
>     return gt_mask;
>
> Would that be clearer? Coupled with the comment from the patch, maybe 
> expanded with the statement that if there are some vcs engines, at 
> least one must remain post fusing?

This works for me. I'll wait a bit to see if there are comments on the 
other patches and then send an update.

Thanks,
Daniele

>
> Regards,
>
> Tvrtko
>
>>>> +
>>>> +    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 134fc1621821..8ca575202e5d 100644
>>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>>> @@ -777,12 +777,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] 48+ messages in thread

* Re: [PATCH 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines
  2022-09-22 22:11   ` Daniele Ceraolo Spurio
@ 2022-09-27  9:58     ` Iddamsetty, Aravind
  -1 siblings, 0 replies; 48+ messages in thread
From: Iddamsetty, Aravind @ 2022-09-27  9:58 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Alan Previn, John Harrison, dri-devel



On 23-09-2022 03:41, 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
> 
> 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>
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_huc.c | 21 +++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_drv.h        |  9 ++++++---
>  2 files changed, 27 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 3bb8838e325a..d4e2b252f16c 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> @@ -42,12 +42,33 @@
>   * HuC-specific commands.
>   */
>  
> +static bool vcs_supported(struct intel_gt *gt)
> +{
> +	intel_engine_mask_t mask = gt->info.engine_mask;
> +
> +	/*
> +	 * we can reach here from i915_driver_early_probe for primary
> +	 * GT with it being not fully setup hence fall back to the device info's
> +	 * engine mask
> +	 */
> +	if (!mask && gt_is_root(gt))
> +		mask = RUNTIME_INFO(gt->i915)->platform_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 134fc1621821..8ca575202e5d 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -777,12 +777,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) \

LGTM.

Reviewed-by: Aravind Iddamsetty <aravind.iddamsetty@intel.com>

Thanks,
Aravind.

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

* Re: [Intel-gfx] [PATCH 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines
@ 2022-09-27  9:58     ` Iddamsetty, Aravind
  0 siblings, 0 replies; 48+ messages in thread
From: Iddamsetty, Aravind @ 2022-09-27  9:58 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Alan Previn, dri-devel



On 23-09-2022 03:41, 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
> 
> 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>
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_huc.c | 21 +++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_drv.h        |  9 ++++++---
>  2 files changed, 27 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 3bb8838e325a..d4e2b252f16c 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> @@ -42,12 +42,33 @@
>   * HuC-specific commands.
>   */
>  
> +static bool vcs_supported(struct intel_gt *gt)
> +{
> +	intel_engine_mask_t mask = gt->info.engine_mask;
> +
> +	/*
> +	 * we can reach here from i915_driver_early_probe for primary
> +	 * GT with it being not fully setup hence fall back to the device info's
> +	 * engine mask
> +	 */
> +	if (!mask && gt_is_root(gt))
> +		mask = RUNTIME_INFO(gt->i915)->platform_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 134fc1621821..8ca575202e5d 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -777,12 +777,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) \

LGTM.

Reviewed-by: Aravind Iddamsetty <aravind.iddamsetty@intel.com>

Thanks,
Aravind.

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

* Re: [PATCH 7/7] drm/i915/guc: handle interrupts from media GuC
  2022-09-22 22:11   ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2022-09-28  0:10     ` Matt Roper
  -1 siblings, 0 replies; 48+ messages in thread
From: Matt Roper @ 2022-09-28  0:10 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx, Alan Previn, John Harrison, dri-devel

On Thu, Sep 22, 2022 at 03:11:17PM -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.

Even if they have a unified enable bit, can't we still just update the
per-GuC mask bit to get the same behavior (i.e., no interrupts
delivered to the host for that specific GuC)?

> 
> 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..e33ed9ae1439 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, GEN12_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 1cbb7226400b..792809e49680 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> @@ -1519,6 +1519,7 @@
>  #define   GEN11_CSME				(31)
>  #define   GEN11_GUNIT				(28)
>  #define   GEN11_GUC				(25)
> +#define   GEN12_GUCM				(24)
>  #define   GEN11_WDPERF				(20)
>  #define   GEN11_KCR				(19)
>  #define   GEN11_GTPM				(16)
> @@ -1573,6 +1574,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 GEN12_GUC_MGUC_INTR_MASK		_MMIO(0x1900e8) /* MTL+ */

Technically we should probably give this a "MTL_" prefix or something
since we're not referring to new platforms as "gen12" anymore.

>  #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 b0beab44b34c..ab0263d8e1cf 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 ? GEN12_GUCM : 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);

The modified postinstall left us with GUC2HOST enabled but masked.
Don't we still need to clear the mask so the interrupts will start being
delivered?


Matt

> +	__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] 48+ messages in thread

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

On Thu, Sep 22, 2022 at 03:11:17PM -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.

Even if they have a unified enable bit, can't we still just update the
per-GuC mask bit to get the same behavior (i.e., no interrupts
delivered to the host for that specific GuC)?

> 
> 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..e33ed9ae1439 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, GEN12_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 1cbb7226400b..792809e49680 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> @@ -1519,6 +1519,7 @@
>  #define   GEN11_CSME				(31)
>  #define   GEN11_GUNIT				(28)
>  #define   GEN11_GUC				(25)
> +#define   GEN12_GUCM				(24)
>  #define   GEN11_WDPERF				(20)
>  #define   GEN11_KCR				(19)
>  #define   GEN11_GTPM				(16)
> @@ -1573,6 +1574,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 GEN12_GUC_MGUC_INTR_MASK		_MMIO(0x1900e8) /* MTL+ */

Technically we should probably give this a "MTL_" prefix or something
since we're not referring to new platforms as "gen12" anymore.

>  #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 b0beab44b34c..ab0263d8e1cf 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 ? GEN12_GUCM : 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);

The modified postinstall left us with GUC2HOST enabled but masked.
Don't we still need to clear the mask so the interrupts will start being
delivered?


Matt

> +	__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] 48+ messages in thread

* Re: [PATCH 7/7] drm/i915/guc: handle interrupts from media GuC
  2022-09-28  0:10     ` [Intel-gfx] " Matt Roper
@ 2022-09-28  0:22       ` Ceraolo Spurio, Daniele
  -1 siblings, 0 replies; 48+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-09-28  0:22 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx, Alan Previn, John Harrison, dri-devel



On 9/27/2022 5:10 PM, Matt Roper wrote:
> On Thu, Sep 22, 2022 at 03:11:17PM -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.
> Even if they have a unified enable bit, can't we still just update the
> per-GuC mask bit to get the same behavior (i.e., no interrupts
> delivered to the host for that specific GuC)?

We could yes, but we've avoided dynamically using masks for gen11+ 
because it can mess with rc6 (e.g., see 
https://patchwork.freedesktop.org/patch/207829/).

>
>> 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..e33ed9ae1439 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, GEN12_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 1cbb7226400b..792809e49680 100644
>> --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
>> +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
>> @@ -1519,6 +1519,7 @@
>>   #define   GEN11_CSME				(31)
>>   #define   GEN11_GUNIT				(28)
>>   #define   GEN11_GUC				(25)
>> +#define   GEN12_GUCM				(24)
>>   #define   GEN11_WDPERF				(20)
>>   #define   GEN11_KCR				(19)
>>   #define   GEN11_GTPM				(16)
>> @@ -1573,6 +1574,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 GEN12_GUC_MGUC_INTR_MASK		_MMIO(0x1900e8) /* MTL+ */
> Technically we should probably give this a "MTL_" prefix or something
> since we're not referring to new platforms as "gen12" anymore.

ok. Should I change GEN12_GUCM as well?

>
>>   #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 b0beab44b34c..ab0263d8e1cf 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 ? GEN12_GUCM : 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);
> The modified postinstall left us with GUC2HOST enabled but masked.
> Don't we still need to clear the mask so the interrupts will start being
> delivered?

The postinstall does:

intel_uncore_rmw(uncore, GEN12_GUC_MGUC_INTR_MASK, mask, 0);

which clears the "mask" (i.e. the G2H interrupt shifted based on which 
GuC it is) in the mask register, so the G2H is allowed.

Daniele

>
>
> Matt
>
>> +	__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	[flat|nested] 48+ messages in thread

* Re: [Intel-gfx] [PATCH 7/7] drm/i915/guc: handle interrupts from media GuC
@ 2022-09-28  0:22       ` Ceraolo Spurio, Daniele
  0 siblings, 0 replies; 48+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-09-28  0:22 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx, Alan Previn, dri-devel



On 9/27/2022 5:10 PM, Matt Roper wrote:
> On Thu, Sep 22, 2022 at 03:11:17PM -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.
> Even if they have a unified enable bit, can't we still just update the
> per-GuC mask bit to get the same behavior (i.e., no interrupts
> delivered to the host for that specific GuC)?

We could yes, but we've avoided dynamically using masks for gen11+ 
because it can mess with rc6 (e.g., see 
https://patchwork.freedesktop.org/patch/207829/).

>
>> 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..e33ed9ae1439 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, GEN12_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 1cbb7226400b..792809e49680 100644
>> --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
>> +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
>> @@ -1519,6 +1519,7 @@
>>   #define   GEN11_CSME				(31)
>>   #define   GEN11_GUNIT				(28)
>>   #define   GEN11_GUC				(25)
>> +#define   GEN12_GUCM				(24)
>>   #define   GEN11_WDPERF				(20)
>>   #define   GEN11_KCR				(19)
>>   #define   GEN11_GTPM				(16)
>> @@ -1573,6 +1574,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 GEN12_GUC_MGUC_INTR_MASK		_MMIO(0x1900e8) /* MTL+ */
> Technically we should probably give this a "MTL_" prefix or something
> since we're not referring to new platforms as "gen12" anymore.

ok. Should I change GEN12_GUCM as well?

>
>>   #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 b0beab44b34c..ab0263d8e1cf 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 ? GEN12_GUCM : 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);
> The modified postinstall left us with GUC2HOST enabled but masked.
> Don't we still need to clear the mask so the interrupts will start being
> delivered?

The postinstall does:

intel_uncore_rmw(uncore, GEN12_GUC_MGUC_INTR_MASK, mask, 0);

which clears the "mask" (i.e. the G2H interrupt shifted based on which 
GuC it is) in the mask register, so the G2H is allowed.

Daniele

>
>
> Matt
>
>> +	__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	[flat|nested] 48+ messages in thread

* Re: [PATCH 7/7] drm/i915/guc: handle interrupts from media GuC
  2022-09-28  0:22       ` [Intel-gfx] " Ceraolo Spurio, Daniele
@ 2022-09-28 18:07         ` Matt Roper
  -1 siblings, 0 replies; 48+ messages in thread
From: Matt Roper @ 2022-09-28 18:07 UTC (permalink / raw)
  To: Ceraolo Spurio, Daniele
  Cc: Alan Previn, Tvrtko Ursulin, Mika Kuoppala, intel-gfx, dri-devel,
	John Harrison

On Tue, Sep 27, 2022 at 05:22:41PM -0700, Ceraolo Spurio, Daniele wrote:
> 
> 
> On 9/27/2022 5:10 PM, Matt Roper wrote:
> > On Thu, Sep 22, 2022 at 03:11:17PM -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.
> > Even if they have a unified enable bit, can't we still just update the
> > per-GuC mask bit to get the same behavior (i.e., no interrupts
> > delivered to the host for that specific GuC)?
> 
> We could yes, but we've avoided dynamically using masks for gen11+ because
> it can mess with rc6 (e.g., see
> https://patchwork.freedesktop.org/patch/207829/).

+Cc Mika & Tvrtko in case they remember more historic details.

Is that expected/documented behavior?  Or is it an unlabelled workaround
that might not be an issue anymore on newer platforms?  Also, it looks
like that patch only applies to RING_IMR and doesn't necessarily impact
other interrupt masking such as the GuC mask.

The code today (which seems to be in use without problem on both gen12
and xehp) is setting all mask bits in GEN11_GUC_SG_INTR_MASK and only
clearing the single G2H bit at the point G2H interrupts are enabled.
GEN11_GUC_SG_INTR_MASK has now become GEN12_GUC_MGUC_INTR_MASK, but it
seems like keeping the masking logic the same as we've been using on
gen12 and xehp would be fine if we just never clear the enable bit?

> 
> > 
> > > 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..e33ed9ae1439 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, GEN12_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 1cbb7226400b..792809e49680 100644
> > > --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > > +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > > @@ -1519,6 +1519,7 @@
> > >   #define   GEN11_CSME				(31)
> > >   #define   GEN11_GUNIT				(28)
> > >   #define   GEN11_GUC				(25)
> > > +#define   GEN12_GUCM				(24)
> > >   #define   GEN11_WDPERF				(20)
> > >   #define   GEN11_KCR				(19)
> > >   #define   GEN11_GTPM				(16)
> > > @@ -1573,6 +1574,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 GEN12_GUC_MGUC_INTR_MASK		_MMIO(0x1900e8) /* MTL+ */
> > Technically we should probably give this a "MTL_" prefix or something
> > since we're not referring to new platforms as "gen12" anymore.
> 
> ok. Should I change GEN12_GUCM as well?

Yeah, at this point "gen12" is a historic term that only covers the
pre-Xe_HP platforms and we've been asked not to use it for any newer
platforms, even if they happen to have an IP version with a major number
of "12."

> 
> > 
> > >   #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 b0beab44b34c..ab0263d8e1cf 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 ? GEN12_GUCM : 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);
> > The modified postinstall left us with GUC2HOST enabled but masked.
> > Don't we still need to clear the mask so the interrupts will start being
> > delivered?
> 
> The postinstall does:
> 
> intel_uncore_rmw(uncore, GEN12_GUC_MGUC_INTR_MASK, mask, 0);
> 
> which clears the "mask" (i.e. the G2H interrupt shifted based on which GuC
> it is) in the mask register, so the G2H is allowed.

Woops, yeah.  I got the order of the rmw parameters mixed up here.


Matt

> 
> Daniele
> 
> > 
> > 
> > Matt
> > 
> > > +	__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] 48+ messages in thread

* Re: [Intel-gfx] [PATCH 7/7] drm/i915/guc: handle interrupts from media GuC
@ 2022-09-28 18:07         ` Matt Roper
  0 siblings, 0 replies; 48+ messages in thread
From: Matt Roper @ 2022-09-28 18:07 UTC (permalink / raw)
  To: Ceraolo Spurio, Daniele; +Cc: Alan Previn, intel-gfx, dri-devel

On Tue, Sep 27, 2022 at 05:22:41PM -0700, Ceraolo Spurio, Daniele wrote:
> 
> 
> On 9/27/2022 5:10 PM, Matt Roper wrote:
> > On Thu, Sep 22, 2022 at 03:11:17PM -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.
> > Even if they have a unified enable bit, can't we still just update the
> > per-GuC mask bit to get the same behavior (i.e., no interrupts
> > delivered to the host for that specific GuC)?
> 
> We could yes, but we've avoided dynamically using masks for gen11+ because
> it can mess with rc6 (e.g., see
> https://patchwork.freedesktop.org/patch/207829/).

+Cc Mika & Tvrtko in case they remember more historic details.

Is that expected/documented behavior?  Or is it an unlabelled workaround
that might not be an issue anymore on newer platforms?  Also, it looks
like that patch only applies to RING_IMR and doesn't necessarily impact
other interrupt masking such as the GuC mask.

The code today (which seems to be in use without problem on both gen12
and xehp) is setting all mask bits in GEN11_GUC_SG_INTR_MASK and only
clearing the single G2H bit at the point G2H interrupts are enabled.
GEN11_GUC_SG_INTR_MASK has now become GEN12_GUC_MGUC_INTR_MASK, but it
seems like keeping the masking logic the same as we've been using on
gen12 and xehp would be fine if we just never clear the enable bit?

> 
> > 
> > > 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..e33ed9ae1439 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, GEN12_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 1cbb7226400b..792809e49680 100644
> > > --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > > +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > > @@ -1519,6 +1519,7 @@
> > >   #define   GEN11_CSME				(31)
> > >   #define   GEN11_GUNIT				(28)
> > >   #define   GEN11_GUC				(25)
> > > +#define   GEN12_GUCM				(24)
> > >   #define   GEN11_WDPERF				(20)
> > >   #define   GEN11_KCR				(19)
> > >   #define   GEN11_GTPM				(16)
> > > @@ -1573,6 +1574,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 GEN12_GUC_MGUC_INTR_MASK		_MMIO(0x1900e8) /* MTL+ */
> > Technically we should probably give this a "MTL_" prefix or something
> > since we're not referring to new platforms as "gen12" anymore.
> 
> ok. Should I change GEN12_GUCM as well?

Yeah, at this point "gen12" is a historic term that only covers the
pre-Xe_HP platforms and we've been asked not to use it for any newer
platforms, even if they happen to have an IP version with a major number
of "12."

> 
> > 
> > >   #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 b0beab44b34c..ab0263d8e1cf 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 ? GEN12_GUCM : 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);
> > The modified postinstall left us with GUC2HOST enabled but masked.
> > Don't we still need to clear the mask so the interrupts will start being
> > delivered?
> 
> The postinstall does:
> 
> intel_uncore_rmw(uncore, GEN12_GUC_MGUC_INTR_MASK, mask, 0);
> 
> which clears the "mask" (i.e. the G2H interrupt shifted based on which GuC
> it is) in the mask register, so the G2H is allowed.

Woops, yeah.  I got the order of the rmw parameters mixed up here.


Matt

> 
> Daniele
> 
> > 
> > 
> > Matt
> > 
> > > +	__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] 48+ messages in thread

* Re: [PATCH 7/7] drm/i915/guc: handle interrupts from media GuC
  2022-09-28 18:07         ` [Intel-gfx] " Matt Roper
@ 2022-09-28 18:25           ` Ceraolo Spurio, Daniele
  -1 siblings, 0 replies; 48+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-09-28 18:25 UTC (permalink / raw)
  To: Matt Roper
  Cc: Alan Previn, Tvrtko Ursulin, Mika Kuoppala, intel-gfx, dri-devel,
	John Harrison



On 9/28/2022 11:07 AM, Matt Roper wrote:
> On Tue, Sep 27, 2022 at 05:22:41PM -0700, Ceraolo Spurio, Daniele wrote:
>>
>> On 9/27/2022 5:10 PM, Matt Roper wrote:
>>> On Thu, Sep 22, 2022 at 03:11:17PM -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.
>>> Even if they have a unified enable bit, can't we still just update the
>>> per-GuC mask bit to get the same behavior (i.e., no interrupts
>>> delivered to the host for that specific GuC)?
>> We could yes, but we've avoided dynamically using masks for gen11+ because
>> it can mess with rc6 (e.g., see
>> https://patchwork.freedesktop.org/patch/207829/).
> +Cc Mika & Tvrtko in case they remember more historic details.
>
> Is that expected/documented behavior?  Or is it an unlabelled workaround
> that might not be an issue anymore on newer platforms?  Also, it looks
> like that patch only applies to RING_IMR and doesn't necessarily impact
> other interrupt masking such as the GuC mask.

It was documented, though don't ask me where because it was an ICL doc 
and it's been too long :).
IIRC the issue is that enabled but masked interrupts are still 
accumulated (and immediately triggered once the mask is cleared) and 
they can keep the power up until they're actually serviced.

>
> The code today (which seems to be in use without problem on both gen12
> and xehp) is setting all mask bits in GEN11_GUC_SG_INTR_MASK and only
> clearing the single G2H bit at the point G2H interrupts are enabled.
> GEN11_GUC_SG_INTR_MASK has now become GEN12_GUC_MGUC_INTR_MASK, but it
> seems like keeping the masking logic the same as we've been using on
> gen12 and xehp would be fine if we just never clear the enable bit?

The main difference is that with the current gen12 code the interrupts 
are enabled and unmasked at the same time, so the situation above 
(pending interrupt stuck behind the mask keeping the power up) can never 
happen, while it can if we keep interrupts always enabled and start 
using the masks dynamically. We usually only disable and re-enable 
interrupts when the GuC is dead so it's not likely that we get an 
interrupt stuck behind the mask, but I'm not confident that all paths 
are safe (particularly around suspend). Instead of sanitizing all 
possible paths to make sure they're ok, keeping the interrupts enabled 
and dropping the rare unexpected ones seemed simpler to me.

Daniele

>>>> 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..e33ed9ae1439 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, GEN12_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 1cbb7226400b..792809e49680 100644
>>>> --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
>>>> +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
>>>> @@ -1519,6 +1519,7 @@
>>>>    #define   GEN11_CSME				(31)
>>>>    #define   GEN11_GUNIT				(28)
>>>>    #define   GEN11_GUC				(25)
>>>> +#define   GEN12_GUCM				(24)
>>>>    #define   GEN11_WDPERF				(20)
>>>>    #define   GEN11_KCR				(19)
>>>>    #define   GEN11_GTPM				(16)
>>>> @@ -1573,6 +1574,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 GEN12_GUC_MGUC_INTR_MASK		_MMIO(0x1900e8) /* MTL+ */
>>> Technically we should probably give this a "MTL_" prefix or something
>>> since we're not referring to new platforms as "gen12" anymore.
>> ok. Should I change GEN12_GUCM as well?
> Yeah, at this point "gen12" is a historic term that only covers the
> pre-Xe_HP platforms and we've been asked not to use it for any newer
> platforms, even if they happen to have an IP version with a major number
> of "12."
>
>>>>    #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 b0beab44b34c..ab0263d8e1cf 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 ? GEN12_GUCM : 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);
>>> The modified postinstall left us with GUC2HOST enabled but masked.
>>> Don't we still need to clear the mask so the interrupts will start being
>>> delivered?
>> The postinstall does:
>>
>> intel_uncore_rmw(uncore, GEN12_GUC_MGUC_INTR_MASK, mask, 0);
>>
>> which clears the "mask" (i.e. the G2H interrupt shifted based on which GuC
>> it is) in the mask register, so the G2H is allowed.
> Woops, yeah.  I got the order of the rmw parameters mixed up here.
>
>
> Matt
>
>> Daniele
>>
>>>
>>> Matt
>>>
>>>> +	__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	[flat|nested] 48+ messages in thread

* Re: [Intel-gfx] [PATCH 7/7] drm/i915/guc: handle interrupts from media GuC
@ 2022-09-28 18:25           ` Ceraolo Spurio, Daniele
  0 siblings, 0 replies; 48+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-09-28 18:25 UTC (permalink / raw)
  To: Matt Roper; +Cc: Alan Previn, intel-gfx, dri-devel



On 9/28/2022 11:07 AM, Matt Roper wrote:
> On Tue, Sep 27, 2022 at 05:22:41PM -0700, Ceraolo Spurio, Daniele wrote:
>>
>> On 9/27/2022 5:10 PM, Matt Roper wrote:
>>> On Thu, Sep 22, 2022 at 03:11:17PM -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.
>>> Even if they have a unified enable bit, can't we still just update the
>>> per-GuC mask bit to get the same behavior (i.e., no interrupts
>>> delivered to the host for that specific GuC)?
>> We could yes, but we've avoided dynamically using masks for gen11+ because
>> it can mess with rc6 (e.g., see
>> https://patchwork.freedesktop.org/patch/207829/).
> +Cc Mika & Tvrtko in case they remember more historic details.
>
> Is that expected/documented behavior?  Or is it an unlabelled workaround
> that might not be an issue anymore on newer platforms?  Also, it looks
> like that patch only applies to RING_IMR and doesn't necessarily impact
> other interrupt masking such as the GuC mask.

It was documented, though don't ask me where because it was an ICL doc 
and it's been too long :).
IIRC the issue is that enabled but masked interrupts are still 
accumulated (and immediately triggered once the mask is cleared) and 
they can keep the power up until they're actually serviced.

>
> The code today (which seems to be in use without problem on both gen12
> and xehp) is setting all mask bits in GEN11_GUC_SG_INTR_MASK and only
> clearing the single G2H bit at the point G2H interrupts are enabled.
> GEN11_GUC_SG_INTR_MASK has now become GEN12_GUC_MGUC_INTR_MASK, but it
> seems like keeping the masking logic the same as we've been using on
> gen12 and xehp would be fine if we just never clear the enable bit?

The main difference is that with the current gen12 code the interrupts 
are enabled and unmasked at the same time, so the situation above 
(pending interrupt stuck behind the mask keeping the power up) can never 
happen, while it can if we keep interrupts always enabled and start 
using the masks dynamically. We usually only disable and re-enable 
interrupts when the GuC is dead so it's not likely that we get an 
interrupt stuck behind the mask, but I'm not confident that all paths 
are safe (particularly around suspend). Instead of sanitizing all 
possible paths to make sure they're ok, keeping the interrupts enabled 
and dropping the rare unexpected ones seemed simpler to me.

Daniele

>>>> 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..e33ed9ae1439 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, GEN12_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 1cbb7226400b..792809e49680 100644
>>>> --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
>>>> +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
>>>> @@ -1519,6 +1519,7 @@
>>>>    #define   GEN11_CSME				(31)
>>>>    #define   GEN11_GUNIT				(28)
>>>>    #define   GEN11_GUC				(25)
>>>> +#define   GEN12_GUCM				(24)
>>>>    #define   GEN11_WDPERF				(20)
>>>>    #define   GEN11_KCR				(19)
>>>>    #define   GEN11_GTPM				(16)
>>>> @@ -1573,6 +1574,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 GEN12_GUC_MGUC_INTR_MASK		_MMIO(0x1900e8) /* MTL+ */
>>> Technically we should probably give this a "MTL_" prefix or something
>>> since we're not referring to new platforms as "gen12" anymore.
>> ok. Should I change GEN12_GUCM as well?
> Yeah, at this point "gen12" is a historic term that only covers the
> pre-Xe_HP platforms and we've been asked not to use it for any newer
> platforms, even if they happen to have an IP version with a major number
> of "12."
>
>>>>    #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 b0beab44b34c..ab0263d8e1cf 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 ? GEN12_GUCM : 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);
>>> The modified postinstall left us with GUC2HOST enabled but masked.
>>> Don't we still need to clear the mask so the interrupts will start being
>>> delivered?
>> The postinstall does:
>>
>> intel_uncore_rmw(uncore, GEN12_GUC_MGUC_INTR_MASK, mask, 0);
>>
>> which clears the "mask" (i.e. the G2H interrupt shifted based on which GuC
>> it is) in the mask register, so the G2H is allowed.
> Woops, yeah.  I got the order of the rmw parameters mixed up here.
>
>
> Matt
>
>> Daniele
>>
>>>
>>> Matt
>>>
>>>> +	__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	[flat|nested] 48+ messages in thread

* Re: [PATCH 2/7] drm/i915/uc: fetch uc firmwares for each GT
  2022-09-22 22:11   ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2022-09-30 22:49     ` John Harrison
  -1 siblings, 0 replies; 48+ messages in thread
From: John Harrison @ 2022-09-30 22:49 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Alan Previn, dri-devel

On 9/22/2022 15:11, Daniele Ceraolo Spurio wrote:
> 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 88df9a35e0fe..a5b192ac885c 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);


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

* Re: [Intel-gfx] [PATCH 2/7] drm/i915/uc: fetch uc firmwares for each GT
@ 2022-09-30 22:49     ` John Harrison
  0 siblings, 0 replies; 48+ messages in thread
From: John Harrison @ 2022-09-30 22:49 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Alan Previn, dri-devel

On 9/22/2022 15:11, Daniele Ceraolo Spurio wrote:
> 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 88df9a35e0fe..a5b192ac885c 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);


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

* Re: [PATCH 3/7] drm/i915/uc: use different ggtt pin offsets for uc loads
  2022-09-22 22:11   ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2022-09-30 23:24     ` John Harrison
  -1 siblings, 0 replies; 48+ messages in thread
From: John Harrison @ 2022-09-30 23:24 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Alan Previn, dri-devel



On 9/22/2022 15:11, 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
The point being that the mapping is done using a single 'dummy' vma that 
can't be mapped to two different places at the same time? But isn't 
there a separate dummy object per uc instance. So there would be one for 
the GuC on the render GT and another for the GuC on the media GT. So 
each would be mapped separately to it's own unique address and there is 
no conflict? Or what am I missing?

> 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.
>
> 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 | 22 +++++++++++++++++++---
>   1 file changed, 19 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 b91ad4aede1f..d6ca772e9f4b 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> @@ -666,16 +666,33 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>   	return err;
>   }
>   
> +/*
> + * The reserved GGTT space is ~18 MBs. All our blobs are well below 1MB, so for
> + * safety we reserve 2MB each.
> + */
> +#define INTEL_UC_RSVD_GGTT_PER_FW SZ_2M
>   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.
> +	 */
> +	BUILD_BUG_ON(INTEL_UC_FW_NUM_TYPES * INTEL_UC_RSVD_GGTT_PER_FW > SZ_8M);
Doesn't this need to be >= ?

> +	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);
Given that the firmware blob is loaded from the disk and therefore under 
user control, is a BUG_ON appropriate? Although there doesn't look to be 
any obvious way to abort at this point. Could the size check be moved to 
where we actually load the firmware rather than where it is being mapped?

>   
> -	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)
> @@ -690,7 +707,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);
Why remove this?

John.

>   
>   	/* uc_fw->obj cache domains were not controlled across suspend */
>   	if (i915_gem_object_has_struct_page(obj))


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

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



On 9/22/2022 15:11, 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
The point being that the mapping is done using a single 'dummy' vma that 
can't be mapped to two different places at the same time? But isn't 
there a separate dummy object per uc instance. So there would be one for 
the GuC on the render GT and another for the GuC on the media GT. So 
each would be mapped separately to it's own unique address and there is 
no conflict? Or what am I missing?

> 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.
>
> 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 | 22 +++++++++++++++++++---
>   1 file changed, 19 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 b91ad4aede1f..d6ca772e9f4b 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> @@ -666,16 +666,33 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>   	return err;
>   }
>   
> +/*
> + * The reserved GGTT space is ~18 MBs. All our blobs are well below 1MB, so for
> + * safety we reserve 2MB each.
> + */
> +#define INTEL_UC_RSVD_GGTT_PER_FW SZ_2M
>   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.
> +	 */
> +	BUILD_BUG_ON(INTEL_UC_FW_NUM_TYPES * INTEL_UC_RSVD_GGTT_PER_FW > SZ_8M);
Doesn't this need to be >= ?

> +	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);
Given that the firmware blob is loaded from the disk and therefore under 
user control, is a BUG_ON appropriate? Although there doesn't look to be 
any obvious way to abort at this point. Could the size check be moved to 
where we actually load the firmware rather than where it is being mapped?

>   
> -	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)
> @@ -690,7 +707,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);
Why remove this?

John.

>   
>   	/* uc_fw->obj cache domains were not controlled across suspend */
>   	if (i915_gem_object_has_struct_page(obj))


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

* Re: [PATCH 4/7] drm/i915/guc: Add GuC deprivilege feature to MTL
  2022-09-22 22:11   ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2022-09-30 23:33     ` John Harrison
  -1 siblings, 0 replies; 48+ messages in thread
From: John Harrison @ 2022-09-30 23:33 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx
  Cc: Stuart Summers, Alan Previn, dri-devel, Radhakrishna Sripada

On 9/22/2022 15:11, Daniele Ceraolo Spurio wrote:
> 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 77e7df21f539..b1b720870da8 100644
> --- a/drivers/gpu/drm/i915/i915_pci.c
> +++ b/drivers/gpu/drm/i915/i915_pci.c
> @@ -1143,6 +1143,7 @@ static const struct intel_device_info mtl_info = {
>   	.display.has_modular_fia = 1,
>   	.extra_gt_list = xelpmp_extra_gt,
>   	.has_flat_ccs = 0,
> +	.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),


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

* Re: [Intel-gfx] [PATCH 4/7] drm/i915/guc: Add GuC deprivilege feature to MTL
@ 2022-09-30 23:33     ` John Harrison
  0 siblings, 0 replies; 48+ messages in thread
From: John Harrison @ 2022-09-30 23:33 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Alan Previn, dri-devel

On 9/22/2022 15:11, Daniele Ceraolo Spurio wrote:
> 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 77e7df21f539..b1b720870da8 100644
> --- a/drivers/gpu/drm/i915/i915_pci.c
> +++ b/drivers/gpu/drm/i915/i915_pci.c
> @@ -1143,6 +1143,7 @@ static const struct intel_device_info mtl_info = {
>   	.display.has_modular_fia = 1,
>   	.extra_gt_list = xelpmp_extra_gt,
>   	.has_flat_ccs = 0,
> +	.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),


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

* Re: [PATCH 3/7] drm/i915/uc: use different ggtt pin offsets for uc loads
  2022-09-30 23:24     ` [Intel-gfx] " John Harrison
@ 2022-09-30 23:42       ` Ceraolo Spurio, Daniele
  -1 siblings, 0 replies; 48+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-09-30 23:42 UTC (permalink / raw)
  To: John Harrison, intel-gfx; +Cc: Alan Previn, dri-devel



On 9/30/2022 4:24 PM, John Harrison wrote:
>
>
> On 9/22/2022 15:11, 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
> The point being that the mapping is done using a single 'dummy' vma 
> that can't be mapped to two different places at the same time? But 
> isn't there a separate dummy object per uc instance. So there would be 
> one for the GuC on the render GT and another for the GuC on the media 
> GT. So each would be mapped separately to it's own unique address and 
> there is no conflict? Or what am I missing?

The issue is that without this patch all the dummy vmas are inserted at 
the same address (start of the reserved node), which only works if they 
can't be mapped at the same time. Note that we don't use the generic vm 
functions to insert the dummy vma and we instead specify the exact 
offset we want it mapped at. This patch makes it so that each dummy vma 
has its own private offset.

>
>> 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.
>>
>> 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 | 22 +++++++++++++++++++---
>>   1 file changed, 19 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 b91ad4aede1f..d6ca772e9f4b 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> @@ -666,16 +666,33 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>>       return err;
>>   }
>>   +/*
>> + * The reserved GGTT space is ~18 MBs. All our blobs are well below 
>> 1MB, so for
>> + * safety we reserve 2MB each.
>> + */
>> +#define INTEL_UC_RSVD_GGTT_PER_FW SZ_2M
>>   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.
>> +     */
>> +    BUILD_BUG_ON(INTEL_UC_FW_NUM_TYPES * INTEL_UC_RSVD_GGTT_PER_FW > 
>> SZ_8M);
> Doesn't this need to be >= ?

No, this is a size check and 8MB is fine for a size.

>
>> +    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);
> Given that the firmware blob is loaded from the disk and therefore 
> under user control, is a BUG_ON appropriate? Although there doesn't 
> look to be any obvious way to abort at this point. Could the size 
> check be moved to where we actually load the firmware rather than 
> where it is being mapped?

My idea was that we wouldn't release a blob that violates this without 
updating the kernel first, so the only way a user can violate this is if 
they try to load a bogus file. But I can still move this check to fetch 
time and fail the fetch if the size is too big, so we can fall-back to 
something sensible.

>
>>   -    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)
>> @@ -690,7 +707,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);
> Why remove this?

The new GEM_BUG_ONs in the function above perform a more strict test, so 
this is redundant.

Daniele

>
> John.
>
>>         /* uc_fw->obj cache domains were not controlled across 
>> suspend */
>>       if (i915_gem_object_has_struct_page(obj))
>


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

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



On 9/30/2022 4:24 PM, John Harrison wrote:
>
>
> On 9/22/2022 15:11, 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
> The point being that the mapping is done using a single 'dummy' vma 
> that can't be mapped to two different places at the same time? But 
> isn't there a separate dummy object per uc instance. So there would be 
> one for the GuC on the render GT and another for the GuC on the media 
> GT. So each would be mapped separately to it's own unique address and 
> there is no conflict? Or what am I missing?

The issue is that without this patch all the dummy vmas are inserted at 
the same address (start of the reserved node), which only works if they 
can't be mapped at the same time. Note that we don't use the generic vm 
functions to insert the dummy vma and we instead specify the exact 
offset we want it mapped at. This patch makes it so that each dummy vma 
has its own private offset.

>
>> 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.
>>
>> 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 | 22 +++++++++++++++++++---
>>   1 file changed, 19 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 b91ad4aede1f..d6ca772e9f4b 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> @@ -666,16 +666,33 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>>       return err;
>>   }
>>   +/*
>> + * The reserved GGTT space is ~18 MBs. All our blobs are well below 
>> 1MB, so for
>> + * safety we reserve 2MB each.
>> + */
>> +#define INTEL_UC_RSVD_GGTT_PER_FW SZ_2M
>>   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.
>> +     */
>> +    BUILD_BUG_ON(INTEL_UC_FW_NUM_TYPES * INTEL_UC_RSVD_GGTT_PER_FW > 
>> SZ_8M);
> Doesn't this need to be >= ?

No, this is a size check and 8MB is fine for a size.

>
>> +    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);
> Given that the firmware blob is loaded from the disk and therefore 
> under user control, is a BUG_ON appropriate? Although there doesn't 
> look to be any obvious way to abort at this point. Could the size 
> check be moved to where we actually load the firmware rather than 
> where it is being mapped?

My idea was that we wouldn't release a blob that violates this without 
updating the kernel first, so the only way a user can violate this is if 
they try to load a bogus file. But I can still move this check to fetch 
time and fail the fetch if the size is too big, so we can fall-back to 
something sensible.

>
>>   -    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)
>> @@ -690,7 +707,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);
> Why remove this?

The new GEM_BUG_ONs in the function above perform a more strict test, so 
this is redundant.

Daniele

>
> John.
>
>>         /* uc_fw->obj cache domains were not controlled across 
>> suspend */
>>       if (i915_gem_object_has_struct_page(obj))
>


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

* Re: [PATCH 6/7] drm/i915/guc: define media GT GuC send regs
  2022-09-22 22:11   ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2022-10-01  0:26     ` John Harrison
  -1 siblings, 0 replies; 48+ messages in thread
From: John Harrison @ 2022-10-01  0:26 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Alan Previn, dri-devel

On 9/22/2022 15:11, Daniele Ceraolo Spurio wrote:
> 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 bac06e3d6f2c..b0beab44b34c 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)


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

* Re: [Intel-gfx] [PATCH 6/7] drm/i915/guc: define media GT GuC send regs
@ 2022-10-01  0:26     ` John Harrison
  0 siblings, 0 replies; 48+ messages in thread
From: John Harrison @ 2022-10-01  0:26 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Alan Previn, dri-devel

On 9/22/2022 15:11, Daniele Ceraolo Spurio wrote:
> 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 bac06e3d6f2c..b0beab44b34c 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)


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

* Re: [PATCH 3/7] drm/i915/uc: use different ggtt pin offsets for uc loads
  2022-09-30 23:42       ` [Intel-gfx] " Ceraolo Spurio, Daniele
@ 2022-10-10 19:18         ` John Harrison
  -1 siblings, 0 replies; 48+ messages in thread
From: John Harrison @ 2022-10-10 19:18 UTC (permalink / raw)
  To: Ceraolo Spurio, Daniele, intel-gfx; +Cc: Alan Previn, dri-devel

On 9/30/2022 16:42, Ceraolo Spurio, Daniele wrote:
> On 9/30/2022 4:24 PM, John Harrison wrote:
>> On 9/22/2022 15:11, 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
>> The point being that the mapping is done using a single 'dummy' vma 
>> that can't be mapped to two different places at the same time? But 
>> isn't there a separate dummy object per uc instance. So there would 
>> be one for the GuC on the render GT and another for the GuC on the 
>> media GT. So each would be mapped separately to it's own unique 
>> address and there is no conflict? Or what am I missing?
>
> The issue is that without this patch all the dummy vmas are inserted 
> at the same address (start of the reserved node), which only works if 
> they can't be mapped at the same time. Note that we don't use the 
> generic vm functions to insert the dummy vma and we instead specify 
> the exact offset we want it mapped at. This patch makes it so that 
> each dummy vma has its own private offset.
>
Got it. I think it would be worth adding some documentation about the 
forced mapping address and why it is necessary.

>>> 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.
>>>
>>> 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 | 22 +++++++++++++++++++---
>>>   1 file changed, 19 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 b91ad4aede1f..d6ca772e9f4b 100644
>>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>>> @@ -666,16 +666,33 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>>>       return err;
>>>   }
>>>   +/*
>>> + * The reserved GGTT space is ~18 MBs. All our blobs are well below 
>>> 1MB, so for
>>> + * safety we reserve 2MB each.
>>> + */
>>> +#define INTEL_UC_RSVD_GGTT_PER_FW SZ_2M
>>>   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.
>>> +     */
>>> +    BUILD_BUG_ON(INTEL_UC_FW_NUM_TYPES * INTEL_UC_RSVD_GGTT_PER_FW 
>>> > SZ_8M);
>> Doesn't this need to be >= ?
>
> No, this is a size check and 8MB is fine for a size.
>
>>
>>> +    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);
>> Given that the firmware blob is loaded from the disk and therefore 
>> under user control, is a BUG_ON appropriate? Although there doesn't 
>> look to be any obvious way to abort at this point. Could the size 
>> check be moved to where we actually load the firmware rather than 
>> where it is being mapped?
>
> My idea was that we wouldn't release a blob that violates this without 
> updating the kernel first, so the only way a user can violate this is 
> if they try to load a bogus file. But I can still move this check to 
> fetch time and fail the fetch if the size is too big, so we can 
> fall-back to something sensible.
Can't trust those pesky users. They can download a HTML page of an ASCII 
dump of a firmware blob and try to load that. For example. I've seen 
that before. So yeah, I think there definitely needs to be a 'drm_err; 
goto fail' rather than a BUG_ON somewhere.

Otherwise, it all seems good.

John.


>
>>
>>>   -    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)
>>> @@ -690,7 +707,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);
>> Why remove this?
>
> The new GEM_BUG_ONs in the function above perform a more strict test, 
> so this is redundant.
>
> Daniele
>
>>
>> John.
>>
>>>         /* uc_fw->obj cache domains were not controlled across 
>>> suspend */
>>>       if (i915_gem_object_has_struct_page(obj))
>>
>


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

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

On 9/30/2022 16:42, Ceraolo Spurio, Daniele wrote:
> On 9/30/2022 4:24 PM, John Harrison wrote:
>> On 9/22/2022 15:11, 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
>> The point being that the mapping is done using a single 'dummy' vma 
>> that can't be mapped to two different places at the same time? But 
>> isn't there a separate dummy object per uc instance. So there would 
>> be one for the GuC on the render GT and another for the GuC on the 
>> media GT. So each would be mapped separately to it's own unique 
>> address and there is no conflict? Or what am I missing?
>
> The issue is that without this patch all the dummy vmas are inserted 
> at the same address (start of the reserved node), which only works if 
> they can't be mapped at the same time. Note that we don't use the 
> generic vm functions to insert the dummy vma and we instead specify 
> the exact offset we want it mapped at. This patch makes it so that 
> each dummy vma has its own private offset.
>
Got it. I think it would be worth adding some documentation about the 
forced mapping address and why it is necessary.

>>> 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.
>>>
>>> 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 | 22 +++++++++++++++++++---
>>>   1 file changed, 19 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 b91ad4aede1f..d6ca772e9f4b 100644
>>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>>> @@ -666,16 +666,33 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
>>>       return err;
>>>   }
>>>   +/*
>>> + * The reserved GGTT space is ~18 MBs. All our blobs are well below 
>>> 1MB, so for
>>> + * safety we reserve 2MB each.
>>> + */
>>> +#define INTEL_UC_RSVD_GGTT_PER_FW SZ_2M
>>>   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.
>>> +     */
>>> +    BUILD_BUG_ON(INTEL_UC_FW_NUM_TYPES * INTEL_UC_RSVD_GGTT_PER_FW 
>>> > SZ_8M);
>> Doesn't this need to be >= ?
>
> No, this is a size check and 8MB is fine for a size.
>
>>
>>> +    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);
>> Given that the firmware blob is loaded from the disk and therefore 
>> under user control, is a BUG_ON appropriate? Although there doesn't 
>> look to be any obvious way to abort at this point. Could the size 
>> check be moved to where we actually load the firmware rather than 
>> where it is being mapped?
>
> My idea was that we wouldn't release a blob that violates this without 
> updating the kernel first, so the only way a user can violate this is 
> if they try to load a bogus file. But I can still move this check to 
> fetch time and fail the fetch if the size is too big, so we can 
> fall-back to something sensible.
Can't trust those pesky users. They can download a HTML page of an ASCII 
dump of a firmware blob and try to load that. For example. I've seen 
that before. So yeah, I think there definitely needs to be a 'drm_err; 
goto fail' rather than a BUG_ON somewhere.

Otherwise, it all seems good.

John.


>
>>
>>>   -    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)
>>> @@ -690,7 +707,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);
>> Why remove this?
>
> The new GEM_BUG_ONs in the function above perform a more strict test, 
> so this is redundant.
>
> Daniele
>
>>
>> John.
>>
>>>         /* uc_fw->obj cache domains were not controlled across 
>>> suspend */
>>>       if (i915_gem_object_has_struct_page(obj))
>>
>


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

end of thread, other threads:[~2022-10-10 19:18 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-22 22:11 [Intel-gfx] [PATCH 0/7] drm/i915: prepare for uC loading on MTL Daniele Ceraolo Spurio
2022-09-22 22:11 ` Daniele Ceraolo Spurio
2022-09-22 22:11 ` [Intel-gfx] [PATCH 1/7] drm/i915/huc: only load HuC on GTs that have VCS engines Daniele Ceraolo Spurio
2022-09-22 22:11   ` Daniele Ceraolo Spurio
2022-09-23 10:53   ` [Intel-gfx] " Tvrtko Ursulin
2022-09-23 15:41     ` Ceraolo Spurio, Daniele
2022-09-26 16:15       ` Tvrtko Ursulin
2022-09-26 16:28         ` Ceraolo Spurio, Daniele
2022-09-27  9:58   ` Iddamsetty, Aravind
2022-09-27  9:58     ` [Intel-gfx] " Iddamsetty, Aravind
2022-09-22 22:11 ` [PATCH 2/7] drm/i915/uc: fetch uc firmwares for each GT Daniele Ceraolo Spurio
2022-09-22 22:11   ` [Intel-gfx] " Daniele Ceraolo Spurio
2022-09-30 22:49   ` John Harrison
2022-09-30 22:49     ` [Intel-gfx] " John Harrison
2022-09-22 22:11 ` [PATCH 3/7] drm/i915/uc: use different ggtt pin offsets for uc loads Daniele Ceraolo Spurio
2022-09-22 22:11   ` [Intel-gfx] " Daniele Ceraolo Spurio
2022-09-30 23:24   ` John Harrison
2022-09-30 23:24     ` [Intel-gfx] " John Harrison
2022-09-30 23:42     ` Ceraolo Spurio, Daniele
2022-09-30 23:42       ` [Intel-gfx] " Ceraolo Spurio, Daniele
2022-10-10 19:18       ` John Harrison
2022-10-10 19:18         ` [Intel-gfx] " John Harrison
2022-09-22 22:11 ` [PATCH 4/7] drm/i915/guc: Add GuC deprivilege feature to MTL Daniele Ceraolo Spurio
2022-09-22 22:11   ` [Intel-gfx] " Daniele Ceraolo Spurio
2022-09-30 23:33   ` John Harrison
2022-09-30 23:33     ` [Intel-gfx] " John Harrison
2022-09-22 22:11 ` [PATCH 5/7] drm/i915/mtl: Handle wopcm per-GT and limit calculations Daniele Ceraolo Spurio
2022-09-22 22:11   ` [Intel-gfx] " Daniele Ceraolo Spurio
2022-09-23  9:24   ` Jani Nikula
2022-09-23 15:34     ` Ceraolo Spurio, Daniele
2022-09-22 22:11 ` [PATCH 6/7] drm/i915/guc: define media GT GuC send regs Daniele Ceraolo Spurio
2022-09-22 22:11   ` [Intel-gfx] " Daniele Ceraolo Spurio
2022-10-01  0:26   ` John Harrison
2022-10-01  0:26     ` [Intel-gfx] " John Harrison
2022-09-22 22:11 ` [PATCH 7/7] drm/i915/guc: handle interrupts from media GuC Daniele Ceraolo Spurio
2022-09-22 22:11   ` [Intel-gfx] " Daniele Ceraolo Spurio
2022-09-28  0:10   ` Matt Roper
2022-09-28  0:10     ` [Intel-gfx] " Matt Roper
2022-09-28  0:22     ` Ceraolo Spurio, Daniele
2022-09-28  0:22       ` [Intel-gfx] " Ceraolo Spurio, Daniele
2022-09-28 18:07       ` Matt Roper
2022-09-28 18:07         ` [Intel-gfx] " Matt Roper
2022-09-28 18:25         ` Ceraolo Spurio, Daniele
2022-09-28 18:25           ` [Intel-gfx] " Ceraolo Spurio, Daniele
2022-09-23  1:12 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: prepare for uC loading on MTL Patchwork
2022-09-23  1:12 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2022-09-23  1:31 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-09-23  9:24 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.