drm/xe/vf: Update LRC with memory based interrupts data
authorMichal Wajdeczko <michal.wajdeczko@intel.com>
Mon, 18 Dec 2023 16:53:42 +0000 (17:53 +0100)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Thu, 21 Dec 2023 21:31:29 +0000 (16:31 -0500)
When Memory Based Interrupts are used, the VF driver must provide
in the LRC the references to the Source and Status Report Pages.

Update the LRC according to the requirements.

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://lore.kernel.org/r/20231214185955.1791-9-michal.wajdeczko@intel.com
Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
drivers/gpu/drm/xe/xe_lrc.c

index 44586e612eaf5d4ae99faddac4d906e62c2a0619..f17e9785355e8a257435d0e83c2741422cf3a1d9 100644 (file)
@@ -19,6 +19,8 @@
 #include "xe_gt_printk.h"
 #include "xe_hw_fence.h"
 #include "xe_map.h"
+#include "xe_memirq.h"
+#include "xe_sriov.h"
 #include "xe_vm.h"
 
 #define CTX_VALID                              (1 << 0)
@@ -532,6 +534,27 @@ static void set_context_control(u32 *regs, struct xe_hw_engine *hwe)
        /* TODO: Timestamp */
 }
 
+static void set_memory_based_intr(u32 *regs, struct xe_hw_engine *hwe)
+{
+       struct xe_memirq *memirq = &gt_to_tile(hwe->gt)->sriov.vf.memirq;
+       struct xe_device *xe = gt_to_xe(hwe->gt);
+
+       if (!IS_SRIOV_VF(xe) || !xe_device_has_memirq(xe))
+               return;
+
+       regs[CTX_LRM_INT_MASK_ENABLE] = MI_LOAD_REGISTER_MEM |
+                                       MI_LRI_LRM_CS_MMIO | MI_LRM_USE_GGTT;
+       regs[CTX_INT_MASK_ENABLE_REG] = RING_IMR(0).addr;
+       regs[CTX_INT_MASK_ENABLE_PTR] = xe_memirq_enable_ptr(memirq);
+
+       regs[CTX_LRI_INT_REPORT_PTR] = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(2) |
+                                      MI_LRI_LRM_CS_MMIO | MI_LRI_FORCE_POSTED;
+       regs[CTX_INT_STATUS_REPORT_REG] = RING_INT_STATUS_RPT_PTR(0).addr;
+       regs[CTX_INT_STATUS_REPORT_PTR] = xe_memirq_status_ptr(memirq);
+       regs[CTX_INT_SRC_REPORT_REG] = RING_INT_SRC_RPT_PTR(0).addr;
+       regs[CTX_INT_SRC_REPORT_PTR] = xe_memirq_source_ptr(memirq);
+}
+
 static int lrc_ring_mi_mode(struct xe_hw_engine *hwe)
 {
        struct xe_device *xe = gt_to_xe(hwe->gt);
@@ -667,6 +690,7 @@ static void *empty_lrc_data(struct xe_hw_engine *hwe)
        regs = data + LRC_PPHWSP_SIZE;
        set_offsets(regs, reg_offsets(xe, hwe->class), hwe);
        set_context_control(regs, hwe);
+       set_memory_based_intr(regs, hwe);
        reset_stop_ring(regs, hwe);
 
        return data;