Unverified Commit 21d07f5f authored by Ilia Levi's avatar Ilia Levi Committed by Rodrigo Vivi
Browse files

drm/xe: Initial MSI-X support for HW engines



- Configure the HW engines to work with MSI-X
- Program the LRC to use memirq infra (similar to VF)
- CS_INT_VEC field added to the LRC

Bspec: 60342, 72547

Signed-off-by: default avatarIlia Levi <ilia.levi@intel.com>
Reviewed-by: default avatarPiotr Piórkowski <piotr.piorkowski@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241213072538.6823-3-ilia.levi@intel.com


Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent da889070
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -83,6 +83,8 @@
#define RING_IMR(base)				XE_REG((base) + 0xa8)
#define RING_INT_STATUS_RPT_PTR(base)		XE_REG((base) + 0xac)

#define CS_INT_VEC(base)			XE_REG((base) + 0x1b8)

#define RING_EIR(base)				XE_REG((base) + 0xb0)
#define RING_EMR(base)				XE_REG((base) + 0xb4)
#define RING_ESR(base)				XE_REG((base) + 0xb8)
@@ -138,6 +140,7 @@

#define RING_MODE(base)				XE_REG((base) + 0x29c)
#define   GFX_DISABLE_LEGACY_MODE		REG_BIT(3)
#define   GFX_MSIX_INTERRUPT_ENABLE		REG_BIT(13)

#define RING_TIMESTAMP(base)			XE_REG((base) + 0x358)

+3 −0
Original line number Diff line number Diff line
@@ -25,6 +25,9 @@
#define CTX_INT_SRC_REPORT_REG		(CTX_LRI_INT_REPORT_PTR + 3)
#define CTX_INT_SRC_REPORT_PTR		(CTX_LRI_INT_REPORT_PTR + 4)

#define CTX_CS_INT_VEC_REG		0x5a
#define CTX_CS_INT_VEC_DATA		(CTX_CS_INT_VEC_REG + 1)

#define INDIRECT_CTX_RING_HEAD		(0x02 + 1)
#define INDIRECT_CTX_RING_TAIL		(0x04 + 1)
#define INDIRECT_CTX_RING_START		(0x06 + 1)
+3 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include "xe_hw_engine_class_sysfs.h"
#include "xe_hw_engine_group.h"
#include "xe_hw_fence.h"
#include "xe_irq.h"
#include "xe_lrc.h"
#include "xe_macros.h"
#include "xe_migrate.h"
@@ -68,6 +69,7 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe,
	q->gt = gt;
	q->class = hwe->class;
	q->width = width;
	q->msix_vec = XE_IRQ_DEFAULT_MSIX;
	q->logical_mask = logical_mask;
	q->fence_irq = &gt->fence_irq[hwe->class];
	q->ring_ops = gt->ring_ops[hwe->class];
@@ -117,7 +119,7 @@ static int __xe_exec_queue_init(struct xe_exec_queue *q)
	}

	for (i = 0; i < q->width; ++i) {
		q->lrc[i] = xe_lrc_create(q->hwe, q->vm, SZ_16K);
		q->lrc[i] = xe_lrc_create(q->hwe, q->vm, SZ_16K, q->msix_vec);
		if (IS_ERR(q->lrc[i])) {
			err = PTR_ERR(q->lrc[i]);
			goto err_unlock;
+2 −0
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@ struct xe_exec_queue {
	char name[MAX_FENCE_NAME_LEN];
	/** @width: width (number BB submitted per exec) of this exec queue */
	u16 width;
	/** @msix_vec: MSI-X vector (for platforms that support it) */
	u16 msix_vec;
	/** @fence_irq: fence IRQ used to signal job completion */
	struct xe_hw_fence_irq *fence_irq;

+7 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "xe_exec_queue.h"
#include "xe_gt.h"
#include "xe_hw_fence.h"
#include "xe_irq.h"
#include "xe_lrc.h"
#include "xe_macros.h"
#include "xe_mmio.h"
@@ -47,6 +48,7 @@ static void __start_lrc(struct xe_hw_engine *hwe, struct xe_lrc *lrc,
	struct xe_mmio *mmio = &gt->mmio;
	struct xe_device *xe = gt_to_xe(gt);
	u64 lrc_desc;
	u32 ring_mode = _MASKED_BIT_ENABLE(GFX_DISABLE_LEGACY_MODE);

	lrc_desc = xe_lrc_descriptor(lrc);

@@ -80,8 +82,10 @@ static void __start_lrc(struct xe_hw_engine *hwe, struct xe_lrc *lrc,
	xe_mmio_write32(mmio, RING_HWS_PGA(hwe->mmio_base),
			xe_bo_ggtt_addr(hwe->hwsp));
	xe_mmio_read32(mmio, RING_HWS_PGA(hwe->mmio_base));
	xe_mmio_write32(mmio, RING_MODE(hwe->mmio_base),
			_MASKED_BIT_ENABLE(GFX_DISABLE_LEGACY_MODE));

	if (xe_device_has_msix(gt_to_xe(hwe->gt)))
		ring_mode |= _MASKED_BIT_ENABLE(GFX_MSIX_INTERRUPT_ENABLE);
	xe_mmio_write32(mmio, RING_MODE(hwe->mmio_base), ring_mode);

	xe_mmio_write32(mmio, RING_EXECLIST_SQ_CONTENTS_LO(hwe->mmio_base),
			lower_32_bits(lrc_desc));
@@ -265,7 +269,7 @@ struct xe_execlist_port *xe_execlist_port_create(struct xe_device *xe,

	port->hwe = hwe;

	port->lrc = xe_lrc_create(hwe, NULL, SZ_16K);
	port->lrc = xe_lrc_create(hwe, NULL, SZ_16K, XE_IRQ_DEFAULT_MSIX);
	if (IS_ERR(port->lrc)) {
		err = PTR_ERR(port->lrc);
		goto err;
Loading