#include "panthor_mmu.h"
#include "panthor_regs.h"
#include "panthor_sched.h"
+#include "panthor_trace.h"
#define CSF_FW_NAME "mali_csffw.bin"
static void panthor_job_irq_handler(struct panthor_device *ptdev, u32 status)
{
+ u32 duration;
+ u64 start = 0;
+
+ if (tracepoint_enabled(gpu_job_irq))
+ start = ktime_get_ns();
+
gpu_write(ptdev, JOB_INT_CLEAR, status);
if (!ptdev->fw->booted && (status & JOB_INT_GLOBAL_IF))
return;
panthor_sched_report_fw_events(ptdev, status);
+
+ if (tracepoint_enabled(gpu_job_irq) && start) {
+ if (check_sub_overflow(ktime_get_ns(), start, &duration))
+ duration = U32_MAX;
+ trace_gpu_job_irq(ptdev->base.dev, status, duration);
+ }
}
PANTHOR_IRQ_HANDLER(job, JOB, panthor_job_irq_handler);
panthor_hw_power_status_register, panthor_hw_power_status_unregister
);
+/**
+ * gpu_job_irq - called after a job interrupt from firmware completes
+ * @dev: pointer to the &struct device, for printing the device name
+ * @events: bitmask of BIT(CSG id) | BIT(31) for a global event
+ * @duration_ns: Nanoseconds between job IRQ handler entry and exit
+ *
+ * The panthor_job_irq_handler() function instrumented by this tracepoint exits
+ * once it has queued the firmware interrupts for processing, not when the
+ * firmware interrupts are fully processed. This tracepoint allows for debugging
+ * issues with delays in the workqueue's processing of events.
+ */
+TRACE_EVENT(gpu_job_irq,
+ TP_PROTO(const struct device *dev, u32 events, u32 duration_ns),
+ TP_ARGS(dev, events, duration_ns),
+ TP_STRUCT__entry(
+ __string(dev_name, dev_name(dev))
+ __field(u32, events)
+ __field(u32, duration_ns)
+ ),
+ TP_fast_assign(
+ __assign_str(dev_name);
+ __entry->events = events;
+ __entry->duration_ns = duration_ns;
+ ),
+ TP_printk("%s: events=0x%x duration_ns=%d", __get_str(dev_name),
+ __entry->events, __entry->duration_ns)
+);
+
#endif /* __PANTHOR_TRACE_H__ */
#undef TRACE_INCLUDE_PATH