Skip to content

Commit 6eb0168

Browse files
mwajdeczrodrigovivi
authored andcommitted
drm/xe/memirq: Update interrupt handler logic
To workaround some corner case hardware limitations, new programming note for the memory based interrupt handler suggests to assume that some status bytes, like GT_MI_USER_INTERRUPT and GUC_INTR_GUC2HOST, are always set. Update our interrupt handler to follow the new rules. Bspec: 53672 Fixes: a6581eb ("drm/xe/vf: Introduce Memory Based Interrupts Handler") Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Michał Winiarski <michal.winiarski@intel.com> Link: https://patch.msgid.link/20260511172838.2299-2-michal.wajdeczko@intel.com (cherry picked from commit 284f4ca) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
1 parent 5200f5f commit 6eb0168

1 file changed

Lines changed: 22 additions & 4 deletions

File tree

drivers/gpu/drm/xe/xe_memirq.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -427,13 +427,25 @@ static bool memirq_received(struct xe_memirq *memirq, struct iosys_map *vector,
427427
return __memirq_received(memirq, vector, offset, name, true);
428428
}
429429

430+
static void memirq_assume_received(struct xe_memirq *memirq, const char *source,
431+
u16 offset, const char *status)
432+
{
433+
memirq_debug(memirq, "ASSUME %s %s(%u)\n", source, status, offset);
434+
}
435+
430436
static void memirq_dispatch_engine(struct xe_memirq *memirq, struct iosys_map *status,
431437
struct xe_hw_engine *hwe)
432438
{
433439
memirq_debug(memirq, "STATUS %s %*ph\n", hwe->name, 16, status->vaddr);
434440

435-
if (memirq_received(memirq, status, ilog2(GT_MI_USER_INTERRUPT), hwe->name))
436-
xe_hw_engine_handle_irq(hwe, GT_MI_USER_INTERRUPT);
441+
/*
442+
* The programming note says to assume that GT_MI_USER_INTERRUPT is always
443+
* set. Check and clear related status byte just for a debug.
444+
*/
445+
if (IS_ENABLED(CONFIG_DRM_XE_DEBUG_MEMIRQ) &&
446+
!memirq_received(memirq, status, ilog2(GT_MI_USER_INTERRUPT), hwe->name))
447+
memirq_assume_received(memirq, hwe->name, ilog2(GT_MI_USER_INTERRUPT), "USER");
448+
xe_hw_engine_handle_irq(hwe, GT_MI_USER_INTERRUPT);
437449
}
438450

439451
static void memirq_dispatch_guc(struct xe_memirq *memirq, struct iosys_map *status,
@@ -443,8 +455,14 @@ static void memirq_dispatch_guc(struct xe_memirq *memirq, struct iosys_map *stat
443455

444456
memirq_debug(memirq, "STATUS %s %*ph\n", name, 16, status->vaddr);
445457

446-
if (memirq_received(memirq, status, ilog2(GUC_INTR_GUC2HOST), name))
447-
xe_guc_irq_handler(guc, GUC_INTR_GUC2HOST);
458+
/*
459+
* The programming note says to assume that GUC_INTR_GUC2HOST is always
460+
* set. Check and clear related status byte just for a debug.
461+
*/
462+
if (IS_ENABLED(CONFIG_DRM_XE_DEBUG_MEMIRQ) &&
463+
!memirq_received(memirq, status, ilog2(GUC_INTR_GUC2HOST), name))
464+
memirq_assume_received(memirq, name, ilog2(GUC_INTR_GUC2HOST), "GUC2HOST");
465+
xe_guc_irq_handler(guc, GUC_INTR_GUC2HOST);
448466

449467
/*
450468
* This is a software interrupt that must be cleared after it's consumed

0 commit comments

Comments
 (0)