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

Merge tag 'drm-intel-fixes-2024-12-11' of...

Merge tag 'drm-intel-fixes-2024-12-11' of https://gitlab.freedesktop.org/drm/i915/kernel

 into drm-fixes

- Don't use indexed register writes needlessly [dsb] (Ville Syrjälä)
- Stop using non-posted DSB writes for legacy LUT [color] (Ville Syrjälä)
- Fix NULL pointer dereference in capture_engine (Eugene Kobyak)
- Fix memory leak by correcting cache object name in error handler (Jiasheng Jiang)

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Tvrtko Ursulin <tursulin@igalia.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Z1nULMrutE4HERvB@linux
parents fac04efc 2828e580
Loading
Loading
Loading
Loading
+51 −30
Original line number Diff line number Diff line
@@ -1343,6 +1343,17 @@ static void ilk_lut_write(const struct intel_crtc_state *crtc_state,
		intel_de_write_fw(display, reg, val);
}

static void ilk_lut_write_indexed(const struct intel_crtc_state *crtc_state,
				  i915_reg_t reg, u32 val)
{
	struct intel_display *display = to_intel_display(crtc_state);

	if (crtc_state->dsb_color_vblank)
		intel_dsb_reg_write_indexed(crtc_state->dsb_color_vblank, reg, val);
	else
		intel_de_write_fw(display, reg, val);
}

static void ilk_load_lut_8(const struct intel_crtc_state *crtc_state,
			   const struct drm_property_blob *blob)
{
@@ -1357,19 +1368,29 @@ static void ilk_load_lut_8(const struct intel_crtc_state *crtc_state,
	lut = blob->data;

	/*
	 * DSB fails to correctly load the legacy LUT
	 * unless we either write each entry twice,
	 * or use non-posted writes
	 * DSB fails to correctly load the legacy LUT unless
	 * we either write each entry twice when using posted
	 * writes, or we use non-posted writes.
	 *
	 * If palette anti-collision is active during LUT
	 * register writes:
	 * - posted writes simply get dropped and thus the LUT
	 *   contents may not be correctly updated
	 * - non-posted writes are blocked and thus the LUT
	 *   contents are always correct, but simultaneous CPU
	 *   MMIO access will start to fail
	 *
	 * Choose the lesser of two evils and use posted writes.
	 * Using posted writes is also faster, even when having
	 * to write each register twice.
	 */
	if (crtc_state->dsb_color_vblank)
		intel_dsb_nonpost_start(crtc_state->dsb_color_vblank);

	for (i = 0; i < 256; i++)
	for (i = 0; i < 256; i++) {
		ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
			      i9xx_lut_8(&lut[i]));

		if (crtc_state->dsb_color_vblank)
		intel_dsb_nonpost_end(crtc_state->dsb_color_vblank);
			ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
				      i9xx_lut_8(&lut[i]));
	}
}

static void ilk_load_lut_10(const struct intel_crtc_state *crtc_state,
@@ -1458,7 +1479,7 @@ static void bdw_load_lut_10(const struct intel_crtc_state *crtc_state,
		      prec_index);

	for (i = 0; i < lut_size; i++)
		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
		ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe),
				      ilk_lut_10(&lut[i]));

	/*
@@ -1612,14 +1633,14 @@ static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state,
		 * ToDo: Extend to max 7.0. Enable 32 bit input value
		 * as compared to just 16 to achieve this.
		 */
		ilk_lut_write(crtc_state, PRE_CSC_GAMC_DATA(pipe),
		ilk_lut_write_indexed(crtc_state, PRE_CSC_GAMC_DATA(pipe),
				      DISPLAY_VER(display) >= 14 ?
				      mtl_degamma_lut(&lut[i]) : glk_degamma_lut(&lut[i]));
	}

	/* Clamp values > 1.0. */
	while (i++ < glk_degamma_lut_size(display))
		ilk_lut_write(crtc_state, PRE_CSC_GAMC_DATA(pipe),
		ilk_lut_write_indexed(crtc_state, PRE_CSC_GAMC_DATA(pipe),
				      DISPLAY_VER(display) >= 14 ?
				      1 << 24 : 1 << 16);

@@ -1687,9 +1708,9 @@ icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
	for (i = 0; i < 9; i++) {
		const struct drm_color_lut *entry = &lut[i];

		ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe),
		ilk_lut_write_indexed(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe),
				      ilk_lut_12p4_ldw(entry));
		ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe),
		ilk_lut_write_indexed(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe),
				      ilk_lut_12p4_udw(entry));
	}

@@ -1726,9 +1747,9 @@ icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
	for (i = 1; i < 257; i++) {
		entry = &lut[i * 8];

		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
		ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe),
				      ilk_lut_12p4_ldw(entry));
		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
		ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe),
				      ilk_lut_12p4_udw(entry));
	}

@@ -1747,9 +1768,9 @@ icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
	for (i = 0; i < 256; i++) {
		entry = &lut[i * 8 * 128];

		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
		ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe),
				      ilk_lut_12p4_ldw(entry));
		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
		ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe),
				      ilk_lut_12p4_udw(entry));
	}

+16 −3
Original line number Diff line number Diff line
@@ -273,15 +273,19 @@ static bool intel_dsb_prev_ins_is_indexed_write(struct intel_dsb *dsb, i915_reg_
}

/**
 * intel_dsb_reg_write() - Emit register wriite to the DSB context
 * intel_dsb_reg_write_indexed() - Emit register wriite to the DSB context
 * @dsb: DSB context
 * @reg: register address.
 * @val: value.
 *
 * This function is used for writing register-value pair in command
 * buffer of DSB.
 *
 * Note that indexed writes are slower than normal MMIO writes
 * for a small number (less than 5 or so) of writes to the same
 * register.
 */
void intel_dsb_reg_write(struct intel_dsb *dsb,
void intel_dsb_reg_write_indexed(struct intel_dsb *dsb,
				 i915_reg_t reg, u32 val)
{
	/*
@@ -340,6 +344,15 @@ void intel_dsb_reg_write(struct intel_dsb *dsb,
	}
}

void intel_dsb_reg_write(struct intel_dsb *dsb,
			 i915_reg_t reg, u32 val)
{
	intel_dsb_emit(dsb, val,
		       (DSB_OPCODE_MMIO_WRITE << DSB_OPCODE_SHIFT) |
		       (DSB_BYTE_EN << DSB_BYTE_EN_SHIFT) |
		       i915_mmio_reg_offset(reg));
}

static u32 intel_dsb_mask_to_byte_en(u32 mask)
{
	return (!!(mask & 0xff000000) << 3 |
+2 −0
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ void intel_dsb_finish(struct intel_dsb *dsb);
void intel_dsb_cleanup(struct intel_dsb *dsb);
void intel_dsb_reg_write(struct intel_dsb *dsb,
			 i915_reg_t reg, u32 val);
void intel_dsb_reg_write_indexed(struct intel_dsb *dsb,
				 i915_reg_t reg, u32 val);
void intel_dsb_reg_write_masked(struct intel_dsb *dsb,
				i915_reg_t reg, u32 mask, u32 val);
void intel_dsb_noop(struct intel_dsb *dsb, int count);
+15 −3
Original line number Diff line number Diff line
@@ -1643,9 +1643,21 @@ capture_engine(struct intel_engine_cs *engine,
		return NULL;

	intel_engine_get_hung_entity(engine, &ce, &rq);
	if (rq && !i915_request_started(rq))
		drm_info(&engine->gt->i915->drm, "Got hung context on %s with active request %lld:%lld [0x%04X] not yet started\n",
	if (rq && !i915_request_started(rq)) {
		/*
		 * We want to know also what is the guc_id of the context,
		 * but if we don't have the context reference, then skip
		 * printing it.
		 */
		if (ce)
			drm_info(&engine->gt->i915->drm,
				 "Got hung context on %s with active request %lld:%lld [0x%04X] not yet started\n",
				 engine->name, rq->fence.context, rq->fence.seqno, ce->guc_id.id);
		else
			drm_info(&engine->gt->i915->drm,
				 "Got hung context on %s with active request %lld:%lld not yet started\n",
				 engine->name, rq->fence.context, rq->fence.seqno);
	}

	if (rq) {
		capture = intel_engine_coredump_add_request(ee, rq, ATOMIC_MAYFAIL);
+1 −1
Original line number Diff line number Diff line
@@ -506,6 +506,6 @@ int __init i915_scheduler_module_init(void)
	return 0;

err_priorities:
	kmem_cache_destroy(slab_priorities);
	kmem_cache_destroy(slab_dependencies);
	return -ENOMEM;
}