return __xe_lrc_regs_offset(lrc) + CTX_TIMESTAMP_UDW * sizeof(u32);
}
+static u32 __xe_lrc_queue_timestamp_offset(struct xe_lrc *lrc)
+{
+ return __xe_lrc_regs_offset(lrc) + CTX_QUEUE_TIMESTAMP * sizeof(u32);
+}
+
+static u32 __xe_lrc_queue_timestamp_udw_offset(struct xe_lrc *lrc)
+{
+ return __xe_lrc_regs_offset(lrc) + CTX_QUEUE_TIMESTAMP_UDW * sizeof(u32);
+}
+
static inline u32 __xe_lrc_indirect_ring_offset(struct xe_lrc *lrc)
{
u32 offset = xe_bo_size(lrc->bo) - LRC_WA_BB_SIZE -
DECL_MAP_ADDR_HELPERS(parallel, lrc->bo)
DECL_MAP_ADDR_HELPERS(indirect_ring, lrc->bo)
DECL_MAP_ADDR_HELPERS(engine_id, lrc->bo)
+DECL_MAP_ADDR_HELPERS(queue_timestamp, lrc->bo)
+DECL_MAP_ADDR_HELPERS(queue_timestamp_udw, lrc->bo)
#undef DECL_MAP_ADDR_HELPERS
return (u64)udw << 32 | ldw;
}
+/**
+ * xe_lrc_queue_timestamp() - Read queue timestamp value
+ * @lrc: Pointer to the lrc.
+ *
+ * Returns: queue timestamp value
+ */
+static u64 xe_lrc_queue_timestamp(struct xe_lrc *lrc)
+{
+ struct xe_device *xe = lrc_to_xe(lrc);
+ struct iosys_map map;
+ u32 ldw, udw = 0;
+
+ xe_assert(xe, xe_lrc_is_multi_queue(lrc));
+
+ map = __xe_lrc_queue_timestamp_map(lrc);
+ ldw = xe_map_read32(xe, &map);
+
+ map = __xe_lrc_queue_timestamp_udw_map(lrc);
+ udw = xe_map_read32(xe, &map);
+
+ return (u64)udw << 32 | ldw;
+}
+
/**
* xe_lrc_ctx_job_timestamp_ggtt_addr() - Get ctx job timestamp GGTT address
* @lrc: Pointer to the lrc.
if (lrc_to_xe(lrc)->info.has_64bit_timestamp)
xe_lrc_write_ctx_reg(lrc, CTX_TIMESTAMP_UDW, 0);
+ /*
+ * Note: It's possible that this LRC may belong to an exec_queue that is
+ * not part of a multi-queue group. That said, it doesn't hurt to set
+ * this field anyways since any class that supports multi-queue will
+ * have these LRC fields defined.
+ */
+ if (xe_gt_supports_multi_queue(gt, hwe->class)) {
+ lrc->queue_timestamp = 0;
+ xe_lrc_write_ctx_reg(lrc, CTX_QUEUE_TIMESTAMP, 0);
+ xe_lrc_write_ctx_reg(lrc, CTX_QUEUE_TIMESTAMP_UDW, 0);
+ }
+
if (xe->info.has_asid && vm)
xe_lrc_write_ctx_reg(lrc, CTX_ASID, vm->usm.asid);
snapshot->ctx_timestamp = xe_lrc_ctx_timestamp(lrc);
snapshot->ctx_timestamp_ms =
xe_gt_clock_interval_to_ms(lrc->gt, xe_lrc_ctx_timestamp(lrc));
+ if (xe_lrc_is_multi_queue(lrc)) {
+ snapshot->queue_timestamp = xe_lrc_queue_timestamp(lrc);
+ snapshot->queue_timestamp_ms =
+ xe_gt_clock_interval_to_ms(lrc->gt, snapshot->queue_timestamp);
+ } else {
+ snapshot->queue_timestamp = 0;
+ snapshot->queue_timestamp_ms = 0;
+ }
snapshot->ctx_job_timestamp = xe_lrc_ctx_job_timestamp(lrc);
return snapshot;
}
drm_printf(p, "\tSeqno: (memory) %d\n", snapshot->seqno);
drm_printf(p, "\tTimestamp: 0x%016llx\n", snapshot->ctx_timestamp);
drm_printf(p, "\tTimestamp ms: %llu\n", snapshot->ctx_timestamp_ms);
+ drm_printf(p, "\tQueue Timestamp: 0x%016llx\n", snapshot->queue_timestamp);
+ drm_printf(p, "\tQueue Timestamp ms: %llu\n", snapshot->queue_timestamp_ms);
drm_printf(p, "\tJob Timestamp: 0x%08x\n", snapshot->ctx_job_timestamp);
if (!snapshot->lrc_snapshot)