Commit c9ff14d0 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-gt-next-2024-10-23' of...

Merge tag 'drm-intel-gt-next-2024-10-23' of https://gitlab.freedesktop.org/drm/i915/kernel

 into drm-next

Driver Changes:

Fixes/improvements/new stuff:

- Enable PXP GuC autoteardown flow [guc] (Juston Li)
- Retry RING_HEAD reset until it get sticks [gt] (Nitin Gote)
- Add basic PMU support for gen2 [pmu] (Ville Syrjälä)

Miscellaneous:

- Prevent a possible int overflow in wq offsets [guc] (Nikita Zhandarovich)
- PMU code cleanups (Lucas De Marchi)
- Fixed "CPU" -> "GPU" typo [gt] (Zhang He)
- Gen2/3 interrupt handling cleanup (Ville Syrjälä)

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Tvrtko Ursulin <tursulin@igalia.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Zxi-3wkIwI-Y1Qvj@linux
parents 0a4d0b2d 6ef0e3ef
Loading
Loading
Loading
Loading
+3 −20
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ static u32 *__gen2_emit_breadcrumb(struct i915_request *rq, u32 *cs,
	return cs;
}

u32 *gen3_emit_breadcrumb(struct i915_request *rq, u32 *cs)
u32 *gen2_emit_breadcrumb(struct i915_request *rq, u32 *cs)
{
	return __gen2_emit_breadcrumb(rq, cs, 16, 8);
}
@@ -248,7 +248,7 @@ int i830_emit_bb_start(struct i915_request *rq,
	return 0;
}

int gen3_emit_bb_start(struct i915_request *rq,
int gen2_emit_bb_start(struct i915_request *rq,
		       u64 offset, u32 len,
		       unsigned int dispatch_flags)
{
@@ -291,30 +291,13 @@ int gen4_emit_bb_start(struct i915_request *rq,
}

void gen2_irq_enable(struct intel_engine_cs *engine)
{
	struct drm_i915_private *i915 = engine->i915;

	i915->irq_mask &= ~engine->irq_enable_mask;
	intel_uncore_write16(&i915->uncore, GEN2_IMR, i915->irq_mask);
	ENGINE_POSTING_READ16(engine, RING_IMR);
}

void gen2_irq_disable(struct intel_engine_cs *engine)
{
	struct drm_i915_private *i915 = engine->i915;

	i915->irq_mask |= engine->irq_enable_mask;
	intel_uncore_write16(&i915->uncore, GEN2_IMR, i915->irq_mask);
}

void gen3_irq_enable(struct intel_engine_cs *engine)
{
	engine->i915->irq_mask &= ~engine->irq_enable_mask;
	intel_uncore_write(engine->uncore, GEN2_IMR, engine->i915->irq_mask);
	intel_uncore_posting_read_fw(engine->uncore, GEN2_IMR);
}

void gen3_irq_disable(struct intel_engine_cs *engine)
void gen2_irq_disable(struct intel_engine_cs *engine)
{
	engine->i915->irq_mask |= engine->irq_enable_mask;
	intel_uncore_write(engine->uncore, GEN2_IMR, engine->i915->irq_mask);
+2 −4
Original line number Diff line number Diff line
@@ -15,13 +15,13 @@ int gen2_emit_flush(struct i915_request *rq, u32 mode);
int gen4_emit_flush_rcs(struct i915_request *rq, u32 mode);
int gen4_emit_flush_vcs(struct i915_request *rq, u32 mode);

u32 *gen3_emit_breadcrumb(struct i915_request *rq, u32 *cs);
u32 *gen2_emit_breadcrumb(struct i915_request *rq, u32 *cs);
u32 *gen5_emit_breadcrumb(struct i915_request *rq, u32 *cs);

int i830_emit_bb_start(struct i915_request *rq,
		       u64 offset, u32 len,
		       unsigned int dispatch_flags);
int gen3_emit_bb_start(struct i915_request *rq,
int gen2_emit_bb_start(struct i915_request *rq,
		       u64 offset, u32 len,
		       unsigned int dispatch_flags);
int gen4_emit_bb_start(struct i915_request *rq,
@@ -30,8 +30,6 @@ int gen4_emit_bb_start(struct i915_request *rq,

void gen2_irq_enable(struct intel_engine_cs *engine);
void gen2_irq_disable(struct intel_engine_cs *engine);
void gen3_irq_enable(struct intel_engine_cs *engine);
void gen3_irq_disable(struct intel_engine_cs *engine);
void gen5_irq_enable(struct intel_engine_cs *engine);
void gen5_irq_disable(struct intel_engine_cs *engine);

+1 −1
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#define   HEAD_WRAP_COUNT			0xFFE00000
#define   HEAD_WRAP_ONE				0x00200000
#define   HEAD_ADDR				0x001FFFFC
#define   HEAD_WAIT_I8XX			(1 << 0) /* gen2, PRBx_HEAD */
#define RING_START(base)			_MMIO((base) + 0x38)
#define RING_CTL(base)				_MMIO((base) + 0x3c)
#define   RING_CTL_SIZE(size)			((size) - PAGE_SIZE) /* in bytes -> pages */
@@ -26,7 +27,6 @@
#define   RING_VALID_MASK			0x00000001
#define   RING_VALID				0x00000001
#define   RING_INVALID				0x00000000
#define   RING_WAIT_I8XX			(1 << 0) /* gen2, PRBx_HEAD */
#define   RING_WAIT				(1 << 11) /* gen3+, PRBx_CTL */
#define   RING_WAIT_SEMAPHORE			(1 << 10) /* gen6+ */
#define RING_SYNC_0(base)			_MMIO((base) + 0x40)
+1 −1
Original line number Diff line number Diff line
@@ -431,7 +431,7 @@ static int llc_show(struct seq_file *m, void *data)
		max_gpu_freq /= GEN9_FREQ_SCALER;
	}

	seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n");
	seq_puts(m, "GPU freq (MHz)\tEffective GPU freq (MHz)\tEffective Ring freq (MHz)\n");

	wakeref = intel_runtime_pm_get(gt->uncore->rpm);
	for (gpu_freq = min_gpu_freq; gpu_freq <= max_gpu_freq; gpu_freq++) {
+29 −9
Original line number Diff line number Diff line
@@ -192,6 +192,7 @@ static bool stop_ring(struct intel_engine_cs *engine)
static int xcs_resume(struct intel_engine_cs *engine)
{
	struct intel_ring *ring = engine->legacy.ring;
	ktime_t kt;

	ENGINE_TRACE(engine, "ring:{HEAD:%04x, TAIL:%04x}\n",
		     ring->head, ring->tail);
@@ -230,9 +231,27 @@ static int xcs_resume(struct intel_engine_cs *engine)
	set_pp_dir(engine);

	/* First wake the ring up to an empty/idle ring */
	for ((kt) = ktime_get() + (2 * NSEC_PER_MSEC);
			ktime_before(ktime_get(), (kt)); cpu_relax()) {
		/*
		 * In case of resets fails because engine resumes from
		 * incorrect RING_HEAD and then GPU may be then fed
		 * to invalid instrcutions, which may lead to unrecoverable
		 * hang. So at first write doesn't succeed then try again.
		 */
		ENGINE_WRITE_FW(engine, RING_HEAD, ring->head);
		if (ENGINE_READ_FW(engine, RING_HEAD) == ring->head)
			break;
	}

	ENGINE_WRITE_FW(engine, RING_TAIL, ring->head);
	ENGINE_POSTING_READ(engine, RING_TAIL);
	if (ENGINE_READ_FW(engine, RING_HEAD) != ENGINE_READ_FW(engine, RING_TAIL)) {
		ENGINE_TRACE(engine, "failed to reset empty ring: [%x, %x]: %x\n",
			     ENGINE_READ_FW(engine, RING_HEAD),
			     ENGINE_READ_FW(engine, RING_TAIL),
			     ring->head);
		goto err;
	}

	ENGINE_WRITE_FW(engine, RING_CTL,
			RING_CTL_SIZE(ring->size) | RING_VALID);
@@ -241,12 +260,16 @@ static int xcs_resume(struct intel_engine_cs *engine)
	if (__intel_wait_for_register_fw(engine->uncore,
					 RING_CTL(engine->mmio_base),
					 RING_VALID, RING_VALID,
					 5000, 0, NULL))
					 5000, 0, NULL)) {
		ENGINE_TRACE(engine, "failed to restart\n");
		goto err;
	}

	if (GRAPHICS_VER(engine->i915) > 2)
	if (GRAPHICS_VER(engine->i915) > 2) {
		ENGINE_WRITE_FW(engine,
				RING_MI_MODE, _MASKED_BIT_DISABLE(STOP_RING));
		ENGINE_POSTING_READ(engine, RING_MI_MODE);
	}

	/* Now awake, let it get started */
	if (ring->tail != ring->head) {
@@ -1090,9 +1113,6 @@ static void setup_irq(struct intel_engine_cs *engine)
	} else if (GRAPHICS_VER(i915) >= 5) {
		engine->irq_enable = gen5_irq_enable;
		engine->irq_disable = gen5_irq_disable;
	} else if (GRAPHICS_VER(i915) >= 3) {
		engine->irq_enable = gen3_irq_enable;
		engine->irq_disable = gen3_irq_disable;
	} else {
		engine->irq_enable = gen2_irq_enable;
		engine->irq_disable = gen2_irq_disable;
@@ -1146,7 +1166,7 @@ static void setup_common(struct intel_engine_cs *engine)
	 * equivalent to our next initial bread so we can elide
	 * engine->emit_init_breadcrumb().
	 */
	engine->emit_fini_breadcrumb = gen3_emit_breadcrumb;
	engine->emit_fini_breadcrumb = gen2_emit_breadcrumb;
	if (GRAPHICS_VER(i915) == 5)
		engine->emit_fini_breadcrumb = gen5_emit_breadcrumb;

@@ -1159,7 +1179,7 @@ static void setup_common(struct intel_engine_cs *engine)
	else if (IS_I830(i915) || IS_I845G(i915))
		engine->emit_bb_start = i830_emit_bb_start;
	else
		engine->emit_bb_start = gen3_emit_bb_start;
		engine->emit_bb_start = gen2_emit_bb_start;
}

static void setup_rcs(struct intel_engine_cs *engine)
Loading