Commit 273b3eb6 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-xe-fixes-2025-01-02' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-fixes



Driver Changes:
- A couple of OA fixes squashed for stable backporting (Umesh)

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Thomas Hellstrom <thomas.hellstrom@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Z3bur0RmH6-70YSh@fedora
parents 198c653e f0ed3983
Loading
Loading
Loading
Loading
+45 −89
Original line number Diff line number Diff line
@@ -74,12 +74,6 @@ struct xe_oa_config {
	struct rcu_head rcu;
};

struct flex {
	struct xe_reg reg;
	u32 offset;
	u32 value;
};

struct xe_oa_open_param {
	struct xe_file *xef;
	u32 oa_unit_id;
@@ -596,19 +590,38 @@ static __poll_t xe_oa_poll(struct file *file, poll_table *wait)
	return ret;
}

static void xe_oa_lock_vma(struct xe_exec_queue *q)
{
	if (q->vm) {
		down_read(&q->vm->lock);
		xe_vm_lock(q->vm, false);
	}
}

static void xe_oa_unlock_vma(struct xe_exec_queue *q)
{
	if (q->vm) {
		xe_vm_unlock(q->vm);
		up_read(&q->vm->lock);
	}
}

static struct dma_fence *xe_oa_submit_bb(struct xe_oa_stream *stream, enum xe_oa_submit_deps deps,
					 struct xe_bb *bb)
{
	struct xe_exec_queue *q = stream->exec_q ?: stream->k_exec_q;
	struct xe_sched_job *job;
	struct dma_fence *fence;
	int err = 0;

	/* Kernel configuration is issued on stream->k_exec_q, not stream->exec_q */
	job = xe_bb_create_job(stream->k_exec_q, bb);
	xe_oa_lock_vma(q);

	job = xe_bb_create_job(q, bb);
	if (IS_ERR(job)) {
		err = PTR_ERR(job);
		goto exit;
	}
	job->ggtt = true;

	if (deps == XE_OA_SUBMIT_ADD_DEPS) {
		for (int i = 0; i < stream->num_syncs && !err; i++)
@@ -623,10 +636,13 @@ static struct dma_fence *xe_oa_submit_bb(struct xe_oa_stream *stream, enum xe_oa
	fence = dma_fence_get(&job->drm.s_fence->finished);
	xe_sched_job_push(job);

	xe_oa_unlock_vma(q);

	return fence;
err_put_job:
	xe_sched_job_put(job);
exit:
	xe_oa_unlock_vma(q);
	return ERR_PTR(err);
}

@@ -675,63 +691,19 @@ static void xe_oa_free_configs(struct xe_oa_stream *stream)
	dma_fence_put(stream->last_fence);
}

static void xe_oa_store_flex(struct xe_oa_stream *stream, struct xe_lrc *lrc,
			     struct xe_bb *bb, const struct flex *flex, u32 count)
{
	u32 offset = xe_bo_ggtt_addr(lrc->bo);

	do {
		bb->cs[bb->len++] = MI_STORE_DATA_IMM | MI_SDI_GGTT | MI_SDI_NUM_DW(1);
		bb->cs[bb->len++] = offset + flex->offset * sizeof(u32);
		bb->cs[bb->len++] = 0;
		bb->cs[bb->len++] = flex->value;

	} while (flex++, --count);
}

static int xe_oa_modify_ctx_image(struct xe_oa_stream *stream, struct xe_lrc *lrc,
				  const struct flex *flex, u32 count)
static int xe_oa_load_with_lri(struct xe_oa_stream *stream, struct xe_oa_reg *reg_lri, u32 count)
{
	struct dma_fence *fence;
	struct xe_bb *bb;
	int err;

	bb = xe_bb_new(stream->gt, 4 * count, false);
	bb = xe_bb_new(stream->gt, 2 * count + 1, false);
	if (IS_ERR(bb)) {
		err = PTR_ERR(bb);
		goto exit;
	}

	xe_oa_store_flex(stream, lrc, bb, flex, count);

	fence = xe_oa_submit_bb(stream, XE_OA_SUBMIT_NO_DEPS, bb);
	if (IS_ERR(fence)) {
		err = PTR_ERR(fence);
		goto free_bb;
	}
	xe_bb_free(bb, fence);
	dma_fence_put(fence);

	return 0;
free_bb:
	xe_bb_free(bb, NULL);
exit:
	return err;
}

static int xe_oa_load_with_lri(struct xe_oa_stream *stream, struct xe_oa_reg *reg_lri)
{
	struct dma_fence *fence;
	struct xe_bb *bb;
	int err;

	bb = xe_bb_new(stream->gt, 3, false);
	if (IS_ERR(bb)) {
		err = PTR_ERR(bb);
		goto exit;
	}

	write_cs_mi_lri(bb, reg_lri, 1);
	write_cs_mi_lri(bb, reg_lri, count);

	fence = xe_oa_submit_bb(stream, XE_OA_SUBMIT_NO_DEPS, bb);
	if (IS_ERR(fence)) {
@@ -751,71 +723,55 @@ static int xe_oa_load_with_lri(struct xe_oa_stream *stream, struct xe_oa_reg *re
static int xe_oa_configure_oar_context(struct xe_oa_stream *stream, bool enable)
{
	const struct xe_oa_format *format = stream->oa_buffer.format;
	struct xe_lrc *lrc = stream->exec_q->lrc[0];
	u32 regs_offset = xe_lrc_regs_offset(lrc) / sizeof(u32);
	u32 oacontrol = __format_to_oactrl(format, OAR_OACONTROL_COUNTER_SEL_MASK) |
		(enable ? OAR_OACONTROL_COUNTER_ENABLE : 0);

	struct flex regs_context[] = {
	struct xe_oa_reg reg_lri[] = {
		{
			OACTXCONTROL(stream->hwe->mmio_base),
			stream->oa->ctx_oactxctrl_offset[stream->hwe->class] + 1,
			enable ? OA_COUNTER_RESUME : 0,
		},
		{
			OAR_OACONTROL,
			oacontrol,
		},
		{
			RING_CONTEXT_CONTROL(stream->hwe->mmio_base),
			regs_offset + CTX_CONTEXT_CONTROL,
			_MASKED_BIT_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE),
			_MASKED_FIELD(CTX_CTRL_OAC_CONTEXT_ENABLE,
				      enable ? CTX_CTRL_OAC_CONTEXT_ENABLE : 0)
		},
	};
	struct xe_oa_reg reg_lri = { OAR_OACONTROL, oacontrol };
	int err;

	/* Modify stream hwe context image with regs_context */
	err = xe_oa_modify_ctx_image(stream, stream->exec_q->lrc[0],
				     regs_context, ARRAY_SIZE(regs_context));
	if (err)
		return err;

	/* Apply reg_lri using LRI */
	return xe_oa_load_with_lri(stream, &reg_lri);
	return xe_oa_load_with_lri(stream, reg_lri, ARRAY_SIZE(reg_lri));
}

static int xe_oa_configure_oac_context(struct xe_oa_stream *stream, bool enable)
{
	const struct xe_oa_format *format = stream->oa_buffer.format;
	struct xe_lrc *lrc = stream->exec_q->lrc[0];
	u32 regs_offset = xe_lrc_regs_offset(lrc) / sizeof(u32);
	u32 oacontrol = __format_to_oactrl(format, OAR_OACONTROL_COUNTER_SEL_MASK) |
		(enable ? OAR_OACONTROL_COUNTER_ENABLE : 0);
	struct flex regs_context[] = {
	struct xe_oa_reg reg_lri[] = {
		{
			OACTXCONTROL(stream->hwe->mmio_base),
			stream->oa->ctx_oactxctrl_offset[stream->hwe->class] + 1,
			enable ? OA_COUNTER_RESUME : 0,
		},
		{
			OAC_OACONTROL,
			oacontrol
		},
		{
			RING_CONTEXT_CONTROL(stream->hwe->mmio_base),
			regs_offset + CTX_CONTEXT_CONTROL,
			_MASKED_BIT_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE) |
			_MASKED_FIELD(CTX_CTRL_OAC_CONTEXT_ENABLE,
				      enable ? CTX_CTRL_OAC_CONTEXT_ENABLE : 0) |
			_MASKED_FIELD(CTX_CTRL_RUN_ALONE, enable ? CTX_CTRL_RUN_ALONE : 0),
		},
	};
	struct xe_oa_reg reg_lri = { OAC_OACONTROL, oacontrol };
	int err;

	/* Set ccs select to enable programming of OAC_OACONTROL */
	xe_mmio_write32(&stream->gt->mmio, __oa_regs(stream)->oa_ctrl,
			__oa_ccs_select(stream));

	/* Modify stream hwe context image with regs_context */
	err = xe_oa_modify_ctx_image(stream, stream->exec_q->lrc[0],
				     regs_context, ARRAY_SIZE(regs_context));
	if (err)
		return err;

	/* Apply reg_lri using LRI */
	return xe_oa_load_with_lri(stream, &reg_lri);
	return xe_oa_load_with_lri(stream, reg_lri, ARRAY_SIZE(reg_lri));
}

static int xe_oa_configure_oa_context(struct xe_oa_stream *stream, bool enable)
@@ -2066,8 +2022,8 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
		if (XE_IOCTL_DBG(oa->xe, !param.exec_q))
			return -ENOENT;

		if (param.exec_q->width > 1)
			drm_dbg(&oa->xe->drm, "exec_q->width > 1, programming only exec_q->lrc[0]\n");
		if (XE_IOCTL_DBG(oa->xe, param.exec_q->width > 1))
			return -EOPNOTSUPP;
	}

	/*
+4 −1
Original line number Diff line number Diff line
@@ -221,7 +221,10 @@ static int emit_pipe_imm_ggtt(u32 addr, u32 value, bool stall_only, u32 *dw,

static u32 get_ppgtt_flag(struct xe_sched_job *job)
{
	return job->q->vm ? BIT(8) : 0;
	if (job->q->vm && !job->ggtt)
		return BIT(8);

	return 0;
}

static int emit_copy_timestamp(struct xe_lrc *lrc, u32 *dw, int i)
+2 −0
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ struct xe_sched_job {
	u32 migrate_flush_flags;
	/** @ring_ops_flush_tlb: The ring ops need to flush TLB before payload. */
	bool ring_ops_flush_tlb;
	/** @ggtt: mapped in ggtt. */
	bool ggtt;
	/** @ptrs: per instance pointers. */
	struct xe_job_ptrs ptrs[];
};