Commit dac38381 authored by Umesh Nerlige Ramappa's avatar Umesh Nerlige Ramappa Committed by John Harrison
Browse files

drm/i915/guc: Enable Wa_22011802037 for gen12 GuC based platforms



Initiating a reset when the command streamer is not idle or in the
middle of executing an MI_FORCE_WAKE can result in a hang. Multiple
command streamers can be part of a single reset domain, so resetting one
would mean resetting all command streamers in that domain.

To workaround this, before initiating a reset, ensure that all command
streamers within that reset domain are either IDLE or are not executing
a MI_FORCE_WAKE.

Enable GuC PRE_PARSER WA bit so that GuC follows the WA sequence when
initiating engine-resets.

For gt-resets, ensure that i915 applies the WA sequence.

Opens to address in future patches:
- The part of the WA to wait for pending forcewakes is also applicable
  to execlists backend.
- The WA also needs to be applied for gen11

Signed-off-by: default avatarUmesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Reviewed-by: default avatarDaniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: default avatarJohn Harrison <John.C.Harrison@Intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220415224025.3693037-3-umesh.nerlige.ramappa@intel.com
parent f6aa0d71
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -181,15 +181,16 @@ static void gt_sanitize(struct intel_gt *gt, bool force)
	if (intel_gt_is_wedged(gt))
		intel_gt_unset_wedged(gt);

	for_each_engine(engine, gt, id)
	/* For GuC mode, ensure submission is disabled before stopping ring */
	intel_uc_reset_prepare(&gt->uc);

	for_each_engine(engine, gt, id) {
		if (engine->reset.prepare)
			engine->reset.prepare(engine);

	intel_uc_reset_prepare(&gt->uc);

	for_each_engine(engine, gt, id)
		if (engine->sanitize)
			engine->sanitize(engine);
	}

	if (reset_engines(gt) || force) {
		for_each_engine(engine, gt, id)
+18 −0
Original line number Diff line number Diff line
@@ -841,6 +841,24 @@
#define   CTC_SHIFT_PARAMETER_SHIFT		1
#define   CTC_SHIFT_PARAMETER_MASK		(0x3 << CTC_SHIFT_PARAMETER_SHIFT)

/* GPM MSG_IDLE */
#define MSG_IDLE_CS		_MMIO(0x8000)
#define MSG_IDLE_VCS0		_MMIO(0x8004)
#define MSG_IDLE_VCS1		_MMIO(0x8008)
#define MSG_IDLE_BCS		_MMIO(0x800C)
#define MSG_IDLE_VECS0		_MMIO(0x8010)
#define MSG_IDLE_VCS2		_MMIO(0x80C0)
#define MSG_IDLE_VCS3		_MMIO(0x80C4)
#define MSG_IDLE_VCS4		_MMIO(0x80C8)
#define MSG_IDLE_VCS5		_MMIO(0x80CC)
#define MSG_IDLE_VCS6		_MMIO(0x80D0)
#define MSG_IDLE_VCS7		_MMIO(0x80D4)
#define MSG_IDLE_VECS1		_MMIO(0x80D8)
#define MSG_IDLE_VECS2		_MMIO(0x80DC)
#define MSG_IDLE_VECS3		_MMIO(0x80E0)
#define  MSG_IDLE_FW_MASK	REG_GENMASK(13, 9)
#define  MSG_IDLE_FW_SHIFT	9

#define FORCEWAKE_MEDIA_GEN9			_MMIO(0xa270)
#define FORCEWAKE_RENDER_GEN9			_MMIO(0xa278)

+3 −2
Original line number Diff line number Diff line
@@ -771,14 +771,15 @@ static intel_engine_mask_t reset_prepare(struct intel_gt *gt)
	intel_engine_mask_t awake = 0;
	enum intel_engine_id id;

	/* For GuC mode, ensure submission is disabled before stopping ring */
	intel_uc_reset_prepare(&gt->uc);

	for_each_engine(engine, gt, id) {
		if (intel_engine_pm_get_if_awake(engine))
			awake |= engine->mask;
		reset_prepare_engine(engine);
	}

	intel_uc_reset_prepare(&gt->uc);

	return awake;
}

+4 −0
Original line number Diff line number Diff line
@@ -292,6 +292,10 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
	    GRAPHICS_VER_FULL(gt->i915) < IP_VER(12, 50))
		flags |= GUC_WA_POLLCS;

	/* Wa_22011802037: graphics version 12 */
	if (GRAPHICS_VER(gt->i915) == 12)
		flags |= GUC_WA_PRE_PARSER;

	return flags;
}

+2 −1
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@
#define   GUC_LOG_BUF_ADDR_SHIFT	12

#define GUC_CTL_WA			1
#define   GUC_WA_PRE_PARSER		BIT(14)
#define   GUC_WA_POLLCS			BIT(18)

#define GUC_CTL_FEATURE			2
Loading