summaryrefslogtreecommitdiff
path: root/mali_kbase/debug
diff options
context:
space:
mode:
authorSidath Senanayake <sidaths@google.com>2020-06-18 09:26:13 +0200
committerSidath Senanayake <sidaths@google.com>2020-06-18 09:26:13 +0200
commitbc3c01e61c8ce9783a8ab091053905effcae12de (patch)
tree43f9f48736f7259d8cc996b11eed003dc80d5bef /mali_kbase/debug
parentb64f568f943e567534694cc993270adca96dcd06 (diff)
downloadgpu-bc3c01e61c8ce9783a8ab091053905effcae12de.tar.gz
Mali Valhall DDK r25p0 KMD
Provenance: 395644cb0 (collaborate/EAC/v_r25p0) VX504X08X-BU-00000-r25p0-01eac0 - Android DDK VX504X08X-BU-60000-r25p0-01eac0 - Android Document Bundle Signed-off-by: Sidath Senanayake <sidaths@google.com> Change-Id: I2cffddb42a554696d45b7f65c7bae8827a71341f
Diffstat (limited to 'mali_kbase/debug')
-rw-r--r--mali_kbase/debug/backend/mali_kbase_debug_ktrace_codes_jm.h170
-rw-r--r--mali_kbase/debug/backend/mali_kbase_debug_ktrace_defs_jm.h75
-rw-r--r--mali_kbase/debug/backend/mali_kbase_debug_ktrace_jm.c113
-rw-r--r--mali_kbase/debug/backend/mali_kbase_debug_ktrace_jm.h362
-rw-r--r--mali_kbase/debug/backend/mali_kbase_debug_linux_ktrace_jm.h150
-rw-r--r--mali_kbase/debug/mali_kbase_debug_ktrace.c342
-rw-r--r--mali_kbase/debug/mali_kbase_debug_ktrace.h219
-rw-r--r--mali_kbase/debug/mali_kbase_debug_ktrace_codes.h158
-rw-r--r--mali_kbase/debug/mali_kbase_debug_ktrace_defs.h152
-rw-r--r--mali_kbase/debug/mali_kbase_debug_ktrace_internal.h89
-rw-r--r--mali_kbase/debug/mali_kbase_debug_linux_ktrace.h99
11 files changed, 1929 insertions, 0 deletions
diff --git a/mali_kbase/debug/backend/mali_kbase_debug_ktrace_codes_jm.h b/mali_kbase/debug/backend/mali_kbase_debug_ktrace_codes_jm.h
new file mode 100644
index 0000000..d534f30
--- /dev/null
+++ b/mali_kbase/debug/backend/mali_kbase_debug_ktrace_codes_jm.h
@@ -0,0 +1,170 @@
+/*
+ *
+ * (C) COPYRIGHT 2011-2015,2018-2020 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+/*
+ * ***** IMPORTANT: THIS IS NOT A NORMAL HEADER FILE *****
+ * ***** DO NOT INCLUDE DIRECTLY *****
+ * ***** THE LACK OF HEADER GUARDS IS INTENTIONAL *****
+ */
+
+/*
+ * The purpose of this header file is just to contain a list of trace code
+ * identifiers
+ *
+ * IMPORTANT: THIS FILE MUST NOT BE USED FOR ANY OTHER PURPOSE OTHER THAN THAT
+ * DESCRIBED IN mali_kbase_debug_ktrace_codes.h
+ */
+
+#if 0 /* Dummy section to avoid breaking formatting */
+int dummy_array[] = {
+#endif
+
+ /*
+ * Job Slot management events
+ */
+ /* info_val==irq rawstat at start */
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_IRQ),
+ /* info_val==jobs processed */
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_IRQ_END),
+ /* In the following:
+ *
+ * - ctx is set if a corresponding job found (NULL otherwise, e.g. some
+ * soft-stop cases)
+ * - uatom==kernel-side mapped uatom address (for correlation with
+ * user-side)
+ */
+ /* info_val==exit code; gpu_addr==chain gpuaddr */
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_JOB_DONE),
+ /* gpu_addr==JS_HEAD_NEXT written, info_val==lower 32 bits of
+ * affinity
+ */
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_SUBMIT),
+ /* gpu_addr is as follows:
+ * - If JS_STATUS active after soft-stop, val==gpu addr written to
+ * JS_HEAD on submit
+ * - otherwise gpu_addr==0
+ */
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_SOFTSTOP),
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_SOFTSTOP_0),
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_SOFTSTOP_1),
+ /* gpu_addr==JS_HEAD read */
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_HARDSTOP),
+ /* gpu_addr==JS_HEAD read */
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_HARDSTOP_0),
+ /* gpu_addr==JS_HEAD read */
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_HARDSTOP_1),
+ /* gpu_addr==JS_TAIL read */
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_UPDATE_HEAD),
+ /* gpu_addr is as follows:
+ * - If JS_STATUS active before soft-stop, val==JS_HEAD
+ * - otherwise gpu_addr==0
+ */
+ /* gpu_addr==JS_HEAD read */
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_CHECK_HEAD),
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_FLUSH_WORKQS),
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_FLUSH_WORKQS_DONE),
+ /* info_val == is_scheduled */
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_ZAP_NON_SCHEDULED),
+ /* info_val == is_scheduled */
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_ZAP_SCHEDULED),
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_ZAP_DONE),
+ /* info_val == nr jobs submitted */
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_SLOT_SOFT_OR_HARD_STOP),
+ /* gpu_addr==JS_HEAD_NEXT last written */
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_SLOT_EVICT),
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_SUBMIT_AFTER_RESET),
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_BEGIN_RESET_WORKER),
+ KBASE_KTRACE_CODE_MAKE_CODE(JM_END_RESET_WORKER),
+ /*
+ * Job dispatch events
+ */
+ /* gpu_addr==value to write into JS_HEAD */
+ KBASE_KTRACE_CODE_MAKE_CODE(JD_DONE),
+ /* gpu_addr==value to write into JS_HEAD */
+ KBASE_KTRACE_CODE_MAKE_CODE(JD_DONE_WORKER),
+ /* gpu_addr==value to write into JS_HEAD */
+ KBASE_KTRACE_CODE_MAKE_CODE(JD_DONE_WORKER_END),
+ /* gpu_addr==value to write into JS_HEAD */
+ KBASE_KTRACE_CODE_MAKE_CODE(JD_DONE_TRY_RUN_NEXT_JOB),
+ /* gpu_addr==0, info_val==0, uatom==0 */
+ KBASE_KTRACE_CODE_MAKE_CODE(JD_ZAP_CONTEXT),
+ /* gpu_addr==value to write into JS_HEAD */
+ KBASE_KTRACE_CODE_MAKE_CODE(JD_CANCEL),
+ /* gpu_addr==value to write into JS_HEAD */
+ KBASE_KTRACE_CODE_MAKE_CODE(JD_CANCEL_WORKER),
+ /*
+ * Scheduler Core events
+ */
+ /* gpu_addr==value to write into JS_HEAD */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_ADD_JOB),
+ /* gpu_addr==last value written/would be written to JS_HEAD */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_REMOVE_JOB),
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_TRY_SCHEDULE_HEAD_CTX),
+ /* gpu_addr==value to write into JS_HEAD */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_JOB_DONE_TRY_RUN_NEXT_JOB),
+ /* gpu_addr==value to write into JS_HEAD */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_JOB_DONE_RETRY_NEEDED),
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_AFFINITY_SUBMIT_TO_BLOCKED),
+ /* info_val == lower 32 bits of affinity */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_AFFINITY_CURRENT),
+ /* info_val == lower 32 bits of affinity */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_CORE_REF_REQUEST_CORES_FAILED),
+ /* info_val == lower 32 bits of affinity */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_CORE_REF_REGISTER_INUSE_FAILED),
+ /* info_val == lower 32 bits of rechecked affinity */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_CORE_REF_REQUEST_ON_RECHECK_FAILED),
+ /* info_val == lower 32 bits of rechecked affinity */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_CORE_REF_REGISTER_ON_RECHECK_FAILED),
+ /* info_val == lower 32 bits of affinity */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_CORE_REF_AFFINITY_WOULD_VIOLATE),
+ /* info_val == the ctx attribute now on ctx */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_CTX_ATTR_NOW_ON_CTX),
+ /* info_val == the ctx attribute now on runpool */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_CTX_ATTR_NOW_ON_RUNPOOL),
+ /* info_val == the ctx attribute now off ctx */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_CTX_ATTR_NOW_OFF_CTX),
+ /* info_val == the ctx attribute now off runpool */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_CTX_ATTR_NOW_OFF_RUNPOOL),
+ /*
+ * Scheduler Policy events
+ */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_POLICY_INIT_CTX),
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_POLICY_TERM_CTX),
+ /* info_val == whether it was evicted */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_POLICY_TRY_EVICT_CTX),
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_POLICY_FOREACH_CTX_JOBS),
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_POLICY_ENQUEUE_CTX),
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_POLICY_DEQUEUE_HEAD_CTX),
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_POLICY_RUNPOOL_ADD_CTX),
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_POLICY_RUNPOOL_REMOVE_CTX),
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_POLICY_DEQUEUE_JOB),
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_POLICY_DEQUEUE_JOB_IRQ),
+ /* gpu_addr==JS_HEAD to write if the job were run */
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_POLICY_ENQUEUE_JOB),
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_POLICY_TIMER_START),
+ KBASE_KTRACE_CODE_MAKE_CODE(JS_POLICY_TIMER_END),
+
+#if 0 /* Dummy section to avoid breaking formatting */
+};
+#endif
+
+/* ***** THE LACK OF HEADER GUARDS IS INTENTIONAL ***** */
diff --git a/mali_kbase/debug/backend/mali_kbase_debug_ktrace_defs_jm.h b/mali_kbase/debug/backend/mali_kbase_debug_ktrace_defs_jm.h
new file mode 100644
index 0000000..55b66ad
--- /dev/null
+++ b/mali_kbase/debug/backend/mali_kbase_debug_ktrace_defs_jm.h
@@ -0,0 +1,75 @@
+/*
+ *
+ * (C) COPYRIGHT 2020 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+#ifndef _KBASE_DEBUG_KTRACE_DEFS_JM_H_
+#define _KBASE_DEBUG_KTRACE_DEFS_JM_H_
+
+/**
+ * DOC: KTrace version history, JM variant
+ * 1.0:
+ * - Original version (implicit, header did not carry version information)
+ * 2.0:
+ * - Introduced version information into the header
+ * - some changes of parameter names in header
+ * - trace now uses all 64-bits of info_val
+ * - Non-JM specific parts moved to using info_val instead of refcount/gpu_addr
+ */
+#define KBASE_KTRACE_VERSION_MAJOR 2
+#define KBASE_KTRACE_VERSION_MINOR 0
+
+/* indicates if the trace message has a valid refcount member */
+#define KBASE_KTRACE_FLAG_JM_REFCOUNT (((kbase_ktrace_flag_t)1) << 0)
+/* indicates if the trace message has a valid jobslot member */
+#define KBASE_KTRACE_FLAG_JM_JOBSLOT (((kbase_ktrace_flag_t)1) << 1)
+/* indicates if the trace message has valid atom related info. */
+#define KBASE_KTRACE_FLAG_JM_ATOM (((kbase_ktrace_flag_t)1) << 2)
+
+
+/**
+ * struct kbase_ktrace_backend - backend specific part of a trace message
+ *
+ * @atom_udata: Copy of the user data sent for the atom in base_jd_submit.
+ * Only valid if KBASE_KTRACE_FLAG_JM_ATOM is set in @flags
+ * @gpu_addr: GPU address, usually of the job-chain represented by an atom.
+ * @atom_number: id of the atom for which trace message was added. Only valid
+ * if KBASE_KTRACE_FLAG_JM_ATOM is set in @flags
+ * @code: Identifies the event, refer to enum kbase_ktrace_code.
+ * @flags: indicates information about the trace message itself. Used
+ * during dumping of the message.
+ * @jobslot: job-slot for which trace message was added, valid only for
+ * job-slot management events.
+ * @refcount: reference count for the context, valid for certain events
+ * related to scheduler core and policy.
+ */
+struct kbase_ktrace_backend {
+ /* Place 64 and 32-bit members together */
+ u64 atom_udata[2]; /* Only valid for KBASE_KTRACE_FLAG_JM_ATOM */
+ u64 gpu_addr;
+ int atom_number; /* Only valid for KBASE_KTRACE_FLAG_JM_ATOM */
+ /* Pack smaller members together */
+ kbase_ktrace_code_t code;
+ kbase_ktrace_flag_t flags;
+ u8 jobslot;
+ u8 refcount;
+};
+
+#endif /* _KBASE_DEBUG_KTRACE_DEFS_JM_H_ */
diff --git a/mali_kbase/debug/backend/mali_kbase_debug_ktrace_jm.c b/mali_kbase/debug/backend/mali_kbase_debug_ktrace_jm.c
new file mode 100644
index 0000000..e651a09
--- /dev/null
+++ b/mali_kbase/debug/backend/mali_kbase_debug_ktrace_jm.c
@@ -0,0 +1,113 @@
+/*
+ *
+ * (C) COPYRIGHT 2020 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+#include <mali_kbase.h>
+#include "debug/mali_kbase_debug_ktrace_internal.h"
+#include "debug/backend/mali_kbase_debug_ktrace_jm.h"
+
+#if KBASE_KTRACE_TARGET_RBUF
+
+void kbasep_ktrace_backend_format_header(char *buffer, int sz, s32 *written)
+{
+ *written += MAX(snprintf(buffer + *written, MAX(sz - *written, 0),
+ "katom,gpu_addr,jobslot,refcount"), 0);
+}
+
+void kbasep_ktrace_backend_format_msg(struct kbase_ktrace_msg *trace_msg,
+ char *buffer, int sz, s32 *written)
+{
+ /* katom */
+ if (trace_msg->backend.flags & KBASE_KTRACE_FLAG_JM_ATOM)
+ *written += MAX(snprintf(buffer + *written,
+ MAX(sz - *written, 0),
+ "atom %d (ud: 0x%llx 0x%llx)",
+ trace_msg->backend.atom_number,
+ trace_msg->backend.atom_udata[0],
+ trace_msg->backend.atom_udata[1]), 0);
+
+ /* gpu_addr */
+ if (trace_msg->backend.flags & KBASE_KTRACE_FLAG_BACKEND)
+ *written += MAX(snprintf(buffer + *written,
+ MAX(sz - *written, 0),
+ ",%.8llx,", trace_msg->backend.gpu_addr), 0);
+ else
+ *written += MAX(snprintf(buffer + *written,
+ MAX(sz - *written, 0),
+ ",,"), 0);
+
+ /* jobslot */
+ if (trace_msg->backend.flags & KBASE_KTRACE_FLAG_JM_JOBSLOT)
+ *written += MAX(snprintf(buffer + *written,
+ MAX(sz - *written, 0),
+ "%d", trace_msg->backend.jobslot), 0);
+
+ *written += MAX(snprintf(buffer + *written, MAX(sz - *written, 0),
+ ","), 0);
+
+ /* refcount */
+ if (trace_msg->backend.flags & KBASE_KTRACE_FLAG_JM_REFCOUNT)
+ *written += MAX(snprintf(buffer + *written,
+ MAX(sz - *written, 0),
+ "%d", trace_msg->backend.refcount), 0);
+}
+
+void kbasep_ktrace_add_jm(struct kbase_device *kbdev,
+ enum kbase_ktrace_code code, struct kbase_context *kctx,
+ struct kbase_jd_atom *katom, u64 gpu_addr,
+ kbase_ktrace_flag_t flags, int refcount, int jobslot,
+ u64 info_val)
+{
+ unsigned long irqflags;
+ struct kbase_ktrace_msg *trace_msg;
+
+ spin_lock_irqsave(&kbdev->ktrace.lock, irqflags);
+
+ /* Reserve and update indices */
+ trace_msg = kbasep_ktrace_reserve(&kbdev->ktrace);
+
+ /* Fill the common part of the message (including backend.flags) */
+ kbasep_ktrace_msg_init(&kbdev->ktrace, trace_msg, code, kctx, flags,
+ info_val);
+
+ /* Indicate to the common code that backend-specific parts will be
+ * valid
+ */
+ trace_msg->backend.flags |= KBASE_KTRACE_FLAG_BACKEND;
+
+ /* Fill the JM-specific parts of the message */
+ if (katom) {
+ trace_msg->backend.flags |= KBASE_KTRACE_FLAG_JM_ATOM;
+
+ trace_msg->backend.atom_number = kbase_jd_atom_id(katom->kctx, katom);
+ trace_msg->backend.atom_udata[0] = katom->udata.blob[0];
+ trace_msg->backend.atom_udata[1] = katom->udata.blob[1];
+ }
+
+ trace_msg->backend.gpu_addr = gpu_addr;
+ trace_msg->backend.jobslot = jobslot;
+ /* Clamp refcount */
+ trace_msg->backend.refcount = MIN((unsigned int)refcount, 0xFF);
+
+ /* Done */
+ spin_unlock_irqrestore(&kbdev->ktrace.lock, irqflags);
+}
+
+#endif /* KBASE_KTRACE_TARGET_RBUF */
diff --git a/mali_kbase/debug/backend/mali_kbase_debug_ktrace_jm.h b/mali_kbase/debug/backend/mali_kbase_debug_ktrace_jm.h
new file mode 100644
index 0000000..c1bacf9
--- /dev/null
+++ b/mali_kbase/debug/backend/mali_kbase_debug_ktrace_jm.h
@@ -0,0 +1,362 @@
+/*
+ *
+ * (C) COPYRIGHT 2020 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+#ifndef _KBASE_DEBUG_KTRACE_JM_H_
+#define _KBASE_DEBUG_KTRACE_JM_H_
+
+/*
+ * KTrace target for internal ringbuffer
+ */
+#if KBASE_KTRACE_TARGET_RBUF
+/**
+ * kbasep_ktrace_add_jm - internal function to add trace about Job Management
+ * @kbdev: kbase device
+ * @code: trace code
+ * @kctx: kbase context, or NULL if no context
+ * @katom: kbase atom, or NULL if no atom
+ * @gpu_addr: GPU address, usually related to @katom
+ * @flags: flags about the message
+ * @refcount: reference count information to add to the trace
+ * @jobslot: jobslot information to add to the trace
+ * @info_val: generic information about @code to add to the trace
+ *
+ * PRIVATE: do not use directly. Use KBASE_KTRACE_ADD_JM() instead.
+ */
+void kbasep_ktrace_add_jm(struct kbase_device *kbdev,
+ enum kbase_ktrace_code code, struct kbase_context *kctx,
+ struct kbase_jd_atom *katom, u64 gpu_addr,
+ kbase_ktrace_flag_t flags, int refcount, int jobslot,
+ u64 info_val);
+
+#define KBASE_KTRACE_RBUF_ADD_JM_SLOT(kbdev, code, kctx, katom, gpu_addr, \
+ jobslot) \
+ kbasep_ktrace_add_jm(kbdev, KBASE_KTRACE_CODE(code), kctx, katom, \
+ gpu_addr, KBASE_KTRACE_FLAG_JM_JOBSLOT, 0, jobslot, 0)
+
+#define KBASE_KTRACE_RBUF_ADD_JM_SLOT_INFO(kbdev, code, kctx, katom, gpu_addr, \
+ jobslot, info_val) \
+ kbasep_ktrace_add_jm(kbdev, KBASE_KTRACE_CODE(code), kctx, katom, \
+ gpu_addr, KBASE_KTRACE_FLAG_JM_JOBSLOT, 0, jobslot, \
+ info_val)
+
+#define KBASE_KTRACE_RBUF_ADD_JM_REFCOUNT(kbdev, code, kctx, katom, gpu_addr, \
+ refcount) \
+ kbasep_ktrace_add_jm(kbdev, KBASE_KTRACE_CODE(code), kctx, katom, \
+ gpu_addr, KBASE_KTRACE_FLAG_JM_REFCOUNT, refcount, 0, 0)
+#define KBASE_KTRACE_RBUF_ADD_JM_REFCOUNT_INFO(kbdev, code, kctx, katom, \
+ gpu_addr, refcount, info_val) \
+ kbasep_ktrace_add_jm(kbdev, KBASE_KTRACE_CODE(code), kctx, katom, \
+ gpu_addr, KBASE_KTRACE_FLAG_JM_REFCOUNT, refcount, 0, \
+ info_val)
+
+#define KBASE_KTRACE_RBUF_ADD_JM(kbdev, code, kctx, katom, gpu_addr, info_val) \
+ kbasep_ktrace_add_jm(kbdev, KBASE_KTRACE_CODE(code), kctx, katom, \
+ gpu_addr, 0, 0, 0, info_val)
+
+#else /* KBASE_KTRACE_TARGET_RBUF */
+#define KBASE_KTRACE_RBUF_ADD_JM_SLOT(kbdev, code, kctx, katom, gpu_addr, \
+ jobslot) \
+ do {\
+ CSTD_UNUSED(kbdev);\
+ CSTD_NOP(code);\
+ CSTD_UNUSED(kctx);\
+ CSTD_UNUSED(katom);\
+ CSTD_UNUSED(gpu_addr);\
+ CSTD_UNUSED(jobslot);\
+ CSTD_NOP(0);\
+ } while (0)
+
+#define KBASE_KTRACE_RBUF_ADD_JM_SLOT_INFO(kbdev, code, kctx, katom, gpu_addr, \
+ jobslot, info_val) \
+ do {\
+ CSTD_UNUSED(kbdev);\
+ CSTD_NOP(code);\
+ CSTD_UNUSED(kctx);\
+ CSTD_UNUSED(katom);\
+ CSTD_UNUSED(gpu_addr);\
+ CSTD_UNUSED(jobslot);\
+ CSTD_UNUSED(info_val);\
+ CSTD_NOP(0);\
+ } while (0)
+
+#define KBASE_KTRACE_RBUF_ADD_JM_REFCOUNT(kbdev, code, kctx, katom, gpu_addr, \
+ refcount) \
+ do {\
+ CSTD_UNUSED(kbdev);\
+ CSTD_NOP(code);\
+ CSTD_UNUSED(kctx);\
+ CSTD_UNUSED(katom);\
+ CSTD_UNUSED(gpu_addr);\
+ CSTD_UNUSED(refcount);\
+ CSTD_NOP(0);\
+ } while (0)
+
+#define KBASE_KTRACE_RBUF_ADD_JM_REFCOUNT_INFO(kbdev, code, kctx, katom, \
+ gpu_addr, refcount, info_val) \
+ do {\
+ CSTD_UNUSED(kbdev);\
+ CSTD_NOP(code);\
+ CSTD_UNUSED(kctx);\
+ CSTD_UNUSED(katom);\
+ CSTD_UNUSED(gpu_addr);\
+ CSTD_UNUSED(info_val);\
+ CSTD_NOP(0);\
+ } while (0)
+
+#define KBASE_KTRACE_RBUF_ADD_JM(kbdev, code, kctx, katom, gpu_addr, \
+ info_val)\
+ do {\
+ CSTD_UNUSED(kbdev);\
+ CSTD_NOP(code);\
+ CSTD_UNUSED(kctx);\
+ CSTD_UNUSED(katom);\
+ CSTD_UNUSED(gpu_addr);\
+ CSTD_UNUSED(info_val);\
+ CSTD_NOP(0);\
+ } while (0)
+#endif /* KBASE_KTRACE_TARGET_RBUF */
+
+/*
+ * KTrace target for Linux's ftrace
+ */
+#if KBASE_KTRACE_TARGET_FTRACE
+#define KBASE_KTRACE_FTRACE_ADD_JM_SLOT(kbdev, code, kctx, katom, gpu_addr, \
+ jobslot) \
+ trace_mali_##code(jobslot, 0)
+
+#define KBASE_KTRACE_FTRACE_ADD_JM_SLOT_INFO(kbdev, code, kctx, katom, \
+ gpu_addr, jobslot, info_val) \
+ trace_mali_##code(jobslot, info_val)
+
+#define KBASE_KTRACE_FTRACE_ADD_JM_REFCOUNT(kbdev, code, kctx, katom, \
+ gpu_addr, refcount) \
+ trace_mali_##code(refcount, 0)
+
+#define KBASE_KTRACE_FTRACE_ADD_JM_REFCOUNT_INFO(kbdev, code, kctx, katom, \
+ gpu_addr, refcount, info_val) \
+ trace_mali_##code(refcount, info_val)
+
+#define KBASE_KTRACE_FTRACE_ADD_JM(kbdev, code, kctx, katom, gpu_addr, \
+ info_val) \
+ trace_mali_##code(gpu_addr, info_val)
+#else /* KBASE_KTRACE_TARGET_FTRACE */
+#define KBASE_KTRACE_FTRACE_ADD_JM_SLOT(kbdev, code, kctx, katom, gpu_addr, \
+ jobslot) \
+ do {\
+ CSTD_UNUSED(kbdev);\
+ CSTD_NOP(code);\
+ CSTD_UNUSED(kctx);\
+ CSTD_UNUSED(katom);\
+ CSTD_UNUSED(gpu_addr);\
+ CSTD_UNUSED(jobslot);\
+ CSTD_NOP(0);\
+ } while (0)
+
+#define KBASE_KTRACE_FTRACE_ADD_JM_SLOT_INFO(kbdev, code, kctx, katom, \
+ gpu_addr, jobslot, info_val) \
+ do {\
+ CSTD_UNUSED(kbdev);\
+ CSTD_NOP(code);\
+ CSTD_UNUSED(kctx);\
+ CSTD_UNUSED(katom);\
+ CSTD_UNUSED(gpu_addr);\
+ CSTD_UNUSED(jobslot);\
+ CSTD_UNUSED(info_val);\
+ CSTD_NOP(0);\
+ } while (0)
+
+#define KBASE_KTRACE_FTRACE_ADD_JM_REFCOUNT(kbdev, code, kctx, katom, \
+ gpu_addr, refcount) \
+ do {\
+ CSTD_UNUSED(kbdev);\
+ CSTD_NOP(code);\
+ CSTD_UNUSED(kctx);\
+ CSTD_UNUSED(katom);\
+ CSTD_UNUSED(gpu_addr);\
+ CSTD_UNUSED(refcount);\
+ CSTD_NOP(0);\
+ } while (0)
+
+#define KBASE_KTRACE_FTRACE_ADD_JM_REFCOUNT_INFO(kbdev, code, kctx, katom, \
+ gpu_addr, refcount, info_val) \
+ do {\
+ CSTD_UNUSED(kbdev);\
+ CSTD_NOP(code);\
+ CSTD_UNUSED(kctx);\
+ CSTD_UNUSED(katom);\
+ CSTD_UNUSED(gpu_addr);\
+ CSTD_UNUSED(info_val);\
+ CSTD_NOP(0);\
+ } while (0)
+
+#define KBASE_KTRACE_FTRACE_ADD_JM(kbdev, code, kctx, katom, gpu_addr, \
+ info_val)\
+ do {\
+ CSTD_UNUSED(kbdev);\
+ CSTD_NOP(code);\
+ CSTD_UNUSED(kctx);\
+ CSTD_UNUSED(katom);\
+ CSTD_UNUSED(gpu_addr);\
+ CSTD_UNUSED(info_val);\
+ CSTD_NOP(0);\
+ } while (0)
+#endif /* KBASE_KTRACE_TARGET_FTRACE */
+
+/*
+ * Master set of macros to route KTrace to any of the targets
+ */
+
+/**
+ * KBASE_KTRACE_ADD_JM_SLOT - Add trace values about a job-slot
+ * @kbdev: kbase device
+ * @code: trace code
+ * @kctx: kbase context, or NULL if no context
+ * @katom: kbase atom, or NULL if no atom
+ * @gpu_addr: GPU address, usually related to @katom
+ * @jobslot: jobslot information to add to the trace
+ *
+ * Note: Any functions called through this macro will still be evaluated in
+ * Release builds (CONFIG_MALI_DEBUG not defined). Therefore, when
+ * KBASE_KTRACE_ENABLE == 0 any functions called to get the parameters supplied
+ * to this macro must:
+ * a) be static or static inline, and
+ * b) just return 0 and have no other statements present in the body.
+ */
+#define KBASE_KTRACE_ADD_JM_SLOT(kbdev, code, kctx, katom, gpu_addr, \
+ jobslot) \
+ do { \
+ /* capture values that could come from non-pure function calls */ \
+ u64 __gpu_addr = gpu_addr; \
+ int __jobslot = jobslot; \
+ KBASE_KTRACE_RBUF_ADD_JM_SLOT(kbdev, code, kctx, katom, __gpu_addr, __jobslot); \
+ KBASE_KTRACE_FTRACE_ADD_JM_SLOT(kbdev, code, kctx, katom, __gpu_addr, __jobslot); \
+ } while (0)
+
+/**
+ * KBASE_KTRACE_ADD_JM_SLOT_INFO - Add trace values about a job-slot, with info
+ * @kbdev: kbase device
+ * @code: trace code
+ * @kctx: kbase context, or NULL if no context
+ * @katom: kbase atom, or NULL if no atom
+ * @gpu_addr: GPU address, usually related to @katom
+ * @jobslot: jobslot information to add to the trace
+ * @info_val: generic information about @code to add to the trace
+ *
+ * Note: Any functions called through this macro will still be evaluated in
+ * Release builds (CONFIG_MALI_DEBUG not defined). Therefore, when
+ * KBASE_KTRACE_ENABLE == 0 any functions called to get the parameters supplied
+ * to this macro must:
+ * a) be static or static inline, and
+ * b) just return 0 and have no other statements present in the body.
+ */
+#define KBASE_KTRACE_ADD_JM_SLOT_INFO(kbdev, code, kctx, katom, gpu_addr, \
+ jobslot, info_val) \
+ do { \
+ /* capture values that could come from non-pure function calls */ \
+ u64 __gpu_addr = gpu_addr; \
+ int __jobslot = jobslot; \
+ u64 __info_val = info_val; \
+ KBASE_KTRACE_RBUF_ADD_JM_SLOT_INFO(kbdev, code, kctx, katom, __gpu_addr, __jobslot, __info_val); \
+ KBASE_KTRACE_FTRACE_ADD_JM_SLOT_INFO(kbdev, code, kctx, katom, __gpu_addr, __jobslot, __info_val); \
+ } while (0)
+
+/**
+ * KBASE_KTRACE_ADD_JM_REFCOUNT - Add trace values about a kctx refcount
+ * @kbdev: kbase device
+ * @code: trace code
+ * @kctx: kbase context, or NULL if no context
+ * @katom: kbase atom, or NULL if no atom
+ * @gpu_addr: GPU address, usually related to @katom
+ * @refcount: reference count information to add to the trace
+ *
+ * Note: Any functions called through this macro will still be evaluated in
+ * Release builds (CONFIG_MALI_DEBUG not defined). Therefore, when
+ * KBASE_KTRACE_ENABLE == 0 any functions called to get the parameters supplied
+ * to this macro must:
+ * a) be static or static inline, and
+ * b) just return 0 and have no other statements present in the body.
+ */
+#define KBASE_KTRACE_ADD_JM_REFCOUNT(kbdev, code, kctx, katom, gpu_addr, \
+ refcount) \
+ do { \
+ /* capture values that could come from non-pure function calls */ \
+ u64 __gpu_addr = gpu_addr; \
+ int __refcount = refcount; \
+ KBASE_KTRACE_RBUF_ADD_JM_REFCOUNT(kbdev, code, kctx, katom, __gpu_addr, __refcount); \
+ KBASE_KTRACE_FTRACE_ADD_JM_REFCOUNT(kbdev, code, kctx, katom, __gpu_addr, __refcount); \
+ } while (0)
+
+/**
+ * KBASE_KTRACE_ADD_JM_REFCOUNT_INFO - Add trace values about a kctx refcount,
+ * and info
+ * @kbdev: kbase device
+ * @code: trace code
+ * @kctx: kbase context, or NULL if no context
+ * @katom: kbase atom, or NULL if no atom
+ * @gpu_addr: GPU address, usually related to @katom
+ * @refcount: reference count information to add to the trace
+ * @info_val: generic information about @code to add to the trace
+ *
+ * Note: Any functions called through this macro will still be evaluated in
+ * Release builds (CONFIG_MALI_DEBUG not defined). Therefore, when
+ * KBASE_KTRACE_ENABLE == 0 any functions called to get the parameters supplied
+ * to this macro must:
+ * a) be static or static inline, and
+ * b) just return 0 and have no other statements present in the body.
+ */
+#define KBASE_KTRACE_ADD_JM_REFCOUNT_INFO(kbdev, code, kctx, katom, \
+ gpu_addr, refcount, info_val) \
+ do { \
+ /* capture values that could come from non-pure function calls */ \
+ u64 __gpu_addr = gpu_addr; \
+ int __refcount = refcount; \
+ u64 __info_val = info_val; \
+ KBASE_KTRACE_RBUF_ADD_JM_REFCOUNT(kbdev, code, kctx, katom, __gpu_addr, __refcount, __info_val); \
+ KBASE_KTRACE_FTRACE_ADD_JM_REFCOUNT(kbdev, code, kctx, katom, __gpu_addr, __refcount, __info_val); \
+ } while (0)
+
+/**
+ * KBASE_KTRACE_ADD_JM - Add trace values (no slot or refcount)
+ * @kbdev: kbase device
+ * @code: trace code
+ * @kctx: kbase context, or NULL if no context
+ * @katom: kbase atom, or NULL if no atom
+ * @gpu_addr: GPU address, usually related to @katom
+ * @info_val: generic information about @code to add to the trace
+ *
+ * Note: Any functions called through this macro will still be evaluated in
+ * Release builds (CONFIG_MALI_DEBUG not defined). Therefore, when
+ * KBASE_KTRACE_ENABLE == 0 any functions called to get the parameters supplied
+ * to this macro must:
+ * a) be static or static inline, and
+ * b) just return 0 and have no other statements present in the body.
+ */
+#define KBASE_KTRACE_ADD_JM(kbdev, code, kctx, katom, gpu_addr, info_val) \
+ do { \
+ /* capture values that could come from non-pure function calls */ \
+ u64 __gpu_addr = gpu_addr; \
+ u64 __info_val = info_val; \
+ KBASE_KTRACE_RBUF_ADD_JM(kbdev, code, kctx, katom, __gpu_addr, __info_val); \
+ KBASE_KTRACE_FTRACE_ADD_JM(kbdev, code, kctx, katom, __gpu_addr, __info_val); \
+ } while (0)
+
+#endif /* _KBASE_DEBUG_KTRACE_JM_H_ */
diff --git a/mali_kbase/debug/backend/mali_kbase_debug_linux_ktrace_jm.h b/mali_kbase/debug/backend/mali_kbase_debug_linux_ktrace_jm.h
new file mode 100644
index 0000000..d964e5a
--- /dev/null
+++ b/mali_kbase/debug/backend/mali_kbase_debug_linux_ktrace_jm.h
@@ -0,0 +1,150 @@
+/*
+ *
+ * (C) COPYRIGHT 2014,2018,2020 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+/*
+ * NOTE: This must **only** be included through mali_linux_trace.h,
+ * otherwise it will fail to setup tracepoints correctly
+ */
+
+#if !defined(_KBASE_DEBUG_LINUX_KTRACE_JM_H_) || defined(TRACE_HEADER_MULTI_READ)
+#define _KBASE_DEBUG_LINUX_KTRACE_JM_H_
+
+DECLARE_EVENT_CLASS(mali_jm_slot_template,
+ TP_PROTO(int jobslot, u64 info_val),
+ TP_ARGS(jobslot, info_val),
+ TP_STRUCT__entry(
+ __field(unsigned int, jobslot)
+ __field(u64, info_val)
+ ),
+ TP_fast_assign(
+ __entry->jobslot = jobslot;
+ __entry->info_val = info_val;
+ ),
+ TP_printk("jobslot=%u info=0x%llx", __entry->jobslot, __entry->info_val)
+);
+
+#define DEFINE_MALI_JM_SLOT_EVENT(name) \
+DEFINE_EVENT(mali_jm_slot_template, mali_##name, \
+ TP_PROTO(int jobslot, u64 info_val), \
+ TP_ARGS(jobslot, info_val))
+DEFINE_MALI_JM_SLOT_EVENT(JM_SUBMIT);
+DEFINE_MALI_JM_SLOT_EVENT(JM_JOB_DONE);
+DEFINE_MALI_JM_SLOT_EVENT(JM_UPDATE_HEAD);
+DEFINE_MALI_JM_SLOT_EVENT(JM_CHECK_HEAD);
+DEFINE_MALI_JM_SLOT_EVENT(JM_SOFTSTOP);
+DEFINE_MALI_JM_SLOT_EVENT(JM_SOFTSTOP_0);
+DEFINE_MALI_JM_SLOT_EVENT(JM_SOFTSTOP_1);
+DEFINE_MALI_JM_SLOT_EVENT(JM_HARDSTOP);
+DEFINE_MALI_JM_SLOT_EVENT(JM_HARDSTOP_0);
+DEFINE_MALI_JM_SLOT_EVENT(JM_HARDSTOP_1);
+DEFINE_MALI_JM_SLOT_EVENT(JM_SLOT_SOFT_OR_HARD_STOP);
+DEFINE_MALI_JM_SLOT_EVENT(JM_SLOT_EVICT);
+DEFINE_MALI_JM_SLOT_EVENT(JM_BEGIN_RESET_WORKER);
+DEFINE_MALI_JM_SLOT_EVENT(JM_END_RESET_WORKER);
+DEFINE_MALI_JM_SLOT_EVENT(JS_CORE_REF_REGISTER_ON_RECHECK_FAILED);
+DEFINE_MALI_JM_SLOT_EVENT(JS_AFFINITY_SUBMIT_TO_BLOCKED);
+DEFINE_MALI_JM_SLOT_EVENT(JS_AFFINITY_CURRENT);
+DEFINE_MALI_JM_SLOT_EVENT(JD_DONE_TRY_RUN_NEXT_JOB);
+DEFINE_MALI_JM_SLOT_EVENT(JS_CORE_REF_REQUEST_CORES_FAILED);
+DEFINE_MALI_JM_SLOT_EVENT(JS_CORE_REF_REGISTER_INUSE_FAILED);
+DEFINE_MALI_JM_SLOT_EVENT(JS_CORE_REF_REQUEST_ON_RECHECK_FAILED);
+DEFINE_MALI_JM_SLOT_EVENT(JS_CORE_REF_AFFINITY_WOULD_VIOLATE);
+DEFINE_MALI_JM_SLOT_EVENT(JS_JOB_DONE_TRY_RUN_NEXT_JOB);
+DEFINE_MALI_JM_SLOT_EVENT(JS_JOB_DONE_RETRY_NEEDED);
+DEFINE_MALI_JM_SLOT_EVENT(JS_POLICY_DEQUEUE_JOB);
+DEFINE_MALI_JM_SLOT_EVENT(JS_POLICY_DEQUEUE_JOB_IRQ);
+#undef DEFINE_MALI_JM_SLOT_EVENT
+
+DECLARE_EVENT_CLASS(mali_jm_refcount_template,
+ TP_PROTO(int refcount, u64 info_val),
+ TP_ARGS(refcount, info_val),
+ TP_STRUCT__entry(
+ __field(unsigned int, refcount)
+ __field(u64, info_val)
+ ),
+ TP_fast_assign(
+ __entry->refcount = refcount;
+ __entry->info_val = info_val;
+ ),
+ TP_printk("refcount=%u info=0x%llx", __entry->refcount, __entry->info_val)
+);
+
+#define DEFINE_MALI_JM_REFCOUNT_EVENT(name) \
+DEFINE_EVENT(mali_jm_refcount_template, mali_##name, \
+ TP_PROTO(int refcount, u64 info_val), \
+ TP_ARGS(refcount, info_val))
+DEFINE_MALI_JM_REFCOUNT_EVENT(JS_ADD_JOB);
+DEFINE_MALI_JM_REFCOUNT_EVENT(JS_REMOVE_JOB);
+DEFINE_MALI_JM_REFCOUNT_EVENT(JS_TRY_SCHEDULE_HEAD_CTX);
+DEFINE_MALI_JM_REFCOUNT_EVENT(JS_POLICY_INIT_CTX);
+DEFINE_MALI_JM_REFCOUNT_EVENT(JS_POLICY_TERM_CTX);
+DEFINE_MALI_JM_REFCOUNT_EVENT(JS_POLICY_ENQUEUE_CTX);
+DEFINE_MALI_JM_REFCOUNT_EVENT(JS_POLICY_DEQUEUE_HEAD_CTX);
+DEFINE_MALI_JM_REFCOUNT_EVENT(JS_POLICY_TRY_EVICT_CTX);
+DEFINE_MALI_JM_REFCOUNT_EVENT(JS_POLICY_RUNPOOL_ADD_CTX);
+DEFINE_MALI_JM_REFCOUNT_EVENT(JS_POLICY_RUNPOOL_REMOVE_CTX);
+DEFINE_MALI_JM_REFCOUNT_EVENT(JS_POLICY_FOREACH_CTX_JOBS);
+#undef DEFINE_MALI_JM_REFCOUNT_EVENT
+
+DECLARE_EVENT_CLASS(mali_jm_add_template,
+ TP_PROTO(u64 gpu_addr, u64 info_val),
+ TP_ARGS(gpu_addr, info_val),
+ TP_STRUCT__entry(
+ __field(u64, gpu_addr)
+ __field(u64, info_val)
+ ),
+ TP_fast_assign(
+ __entry->gpu_addr = gpu_addr;
+ __entry->info_val = info_val;
+ ),
+ TP_printk("gpu_addr=0x%llx info=0x%llx", __entry->gpu_addr, __entry->info_val)
+);
+
+#define DEFINE_MALI_JM_ADD_EVENT(name) \
+DEFINE_EVENT(mali_jm_add_template, mali_##name, \
+ TP_PROTO(u64 gpu_addr, u64 info_val), \
+ TP_ARGS(gpu_addr, info_val))
+DEFINE_MALI_JM_ADD_EVENT(JD_DONE_WORKER);
+DEFINE_MALI_JM_ADD_EVENT(JD_DONE_WORKER_END);
+DEFINE_MALI_JM_ADD_EVENT(JD_CANCEL_WORKER);
+DEFINE_MALI_JM_ADD_EVENT(JD_DONE);
+DEFINE_MALI_JM_ADD_EVENT(JD_CANCEL);
+DEFINE_MALI_JM_ADD_EVENT(JD_ZAP_CONTEXT);
+DEFINE_MALI_JM_ADD_EVENT(JM_IRQ);
+DEFINE_MALI_JM_ADD_EVENT(JM_IRQ_END);
+DEFINE_MALI_JM_ADD_EVENT(JM_FLUSH_WORKQS);
+DEFINE_MALI_JM_ADD_EVENT(JM_FLUSH_WORKQS_DONE);
+DEFINE_MALI_JM_ADD_EVENT(JM_ZAP_NON_SCHEDULED);
+DEFINE_MALI_JM_ADD_EVENT(JM_ZAP_SCHEDULED);
+DEFINE_MALI_JM_ADD_EVENT(JM_ZAP_DONE);
+DEFINE_MALI_JM_ADD_EVENT(JM_SUBMIT_AFTER_RESET);
+DEFINE_MALI_JM_ADD_EVENT(JM_JOB_COMPLETE);
+DEFINE_MALI_JM_ADD_EVENT(JS_CTX_ATTR_NOW_ON_RUNPOOL);
+DEFINE_MALI_JM_ADD_EVENT(JS_CTX_ATTR_NOW_OFF_RUNPOOL);
+DEFINE_MALI_JM_ADD_EVENT(JS_CTX_ATTR_NOW_ON_CTX);
+DEFINE_MALI_JM_ADD_EVENT(JS_CTX_ATTR_NOW_OFF_CTX);
+DEFINE_MALI_JM_ADD_EVENT(JS_POLICY_TIMER_END);
+DEFINE_MALI_JM_ADD_EVENT(JS_POLICY_TIMER_START);
+DEFINE_MALI_JM_ADD_EVENT(JS_POLICY_ENQUEUE_JOB);
+#undef DEFINE_MALI_JM_ADD_EVENT
+
+#endif /* !defined(_KBASE_DEBUG_LINUX_KTRACE_JM_H_) || defined(TRACE_HEADER_MULTI_READ)*/
diff --git a/mali_kbase/debug/mali_kbase_debug_ktrace.c b/mali_kbase/debug/mali_kbase_debug_ktrace.c
new file mode 100644
index 0000000..6322abb
--- /dev/null
+++ b/mali_kbase/debug/mali_kbase_debug_ktrace.c
@@ -0,0 +1,342 @@
+/*
+ *
+ * (C) COPYRIGHT 2020 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+#include <mali_kbase.h>
+#include "debug/mali_kbase_debug_ktrace_internal.h"
+
+int kbase_ktrace_init(struct kbase_device *kbdev)
+{
+#if KBASE_KTRACE_TARGET_RBUF
+ struct kbase_ktrace_msg *rbuf;
+
+ /* See also documentation of enum kbase_ktrace_code */
+ compiletime_assert(sizeof(kbase_ktrace_code_t) == sizeof(unsigned long long) ||
+ KBASE_KTRACE_CODE_COUNT <= (1ull << (sizeof(kbase_ktrace_code_t) * BITS_PER_BYTE)),
+ "kbase_ktrace_code_t not wide enough for KBASE_KTRACE_CODE_COUNT");
+
+ rbuf = kmalloc_array(KBASE_KTRACE_SIZE, sizeof(*rbuf), GFP_KERNEL);
+
+ if (!rbuf)
+ return -EINVAL;
+
+ kbdev->ktrace.rbuf = rbuf;
+ spin_lock_init(&kbdev->ktrace.lock);
+#endif /* KBASE_KTRACE_TARGET_RBUF */
+ return 0;
+}
+
+void kbase_ktrace_term(struct kbase_device *kbdev)
+{
+#if KBASE_KTRACE_TARGET_RBUF
+ kfree(kbdev->ktrace.rbuf);
+#endif /* KBASE_KTRACE_TARGET_RBUF */
+}
+
+void kbase_ktrace_hook_wrapper(void *param)
+{
+ struct kbase_device *kbdev = (struct kbase_device *)param;
+
+ KBASE_KTRACE_DUMP(kbdev);
+}
+
+#if KBASE_KTRACE_TARGET_RBUF
+
+static const char * const kbasep_ktrace_code_string[] = {
+ /*
+ * IMPORTANT: USE OF SPECIAL #INCLUDE OF NON-STANDARD HEADER FILE
+ * THIS MUST BE USED AT THE START OF THE ARRAY
+ */
+#define KBASE_KTRACE_CODE_MAKE_CODE(X) # X
+#include "debug/mali_kbase_debug_ktrace_codes.h"
+#undef KBASE_KTRACE_CODE_MAKE_CODE
+};
+
+static void kbasep_ktrace_format_header(char *buffer, int sz, s32 written)
+{
+ written += MAX(snprintf(buffer + written, MAX(sz - written, 0),
+ "secs,thread_id,cpu,code,kctx,"), 0);
+
+ kbasep_ktrace_backend_format_header(buffer, sz, &written);
+
+ written += MAX(snprintf(buffer + written, MAX(sz - written, 0),
+ ",info_val,ktrace_version=%u.%u",
+ KBASE_KTRACE_VERSION_MAJOR,
+ KBASE_KTRACE_VERSION_MINOR), 0);
+
+ buffer[sz - 1] = 0;
+}
+
+static void kbasep_ktrace_format_msg(struct kbase_ktrace_msg *trace_msg,
+ char *buffer, int sz)
+{
+ s32 written = 0;
+
+ /* Initial part of message:
+ *
+ * secs,thread_id,cpu,code,kctx,
+ */
+ written += MAX(snprintf(buffer + written, MAX(sz - written, 0),
+ "%d.%.6d,%d,%d,%s,%p,",
+ (int)trace_msg->timestamp.tv_sec,
+ (int)(trace_msg->timestamp.tv_nsec / 1000),
+ trace_msg->thread_id, trace_msg->cpu,
+ kbasep_ktrace_code_string[trace_msg->backend.code],
+ trace_msg->kctx), 0);
+
+ /* Backend parts */
+ kbasep_ktrace_backend_format_msg(trace_msg, buffer, sz,
+ &written);
+
+ /* Rest of message:
+ *
+ * ,info_val
+ *
+ * Note that the last column is empty, it's simply to hold the ktrace
+ * version in the header
+ */
+ written += MAX(snprintf(buffer + written, MAX(sz - written, 0),
+ ",0x%.16llx",
+ (unsigned long long)trace_msg->info_val), 0);
+ buffer[sz - 1] = 0;
+}
+
+static void kbasep_ktrace_dump_msg(struct kbase_device *kbdev,
+ struct kbase_ktrace_msg *trace_msg)
+{
+ char buffer[KTRACE_DUMP_MESSAGE_SIZE];
+
+ lockdep_assert_held(&kbdev->ktrace.lock);
+
+ kbasep_ktrace_format_msg(trace_msg, buffer, sizeof(buffer));
+ dev_dbg(kbdev->dev, "%s", buffer);
+}
+
+struct kbase_ktrace_msg *kbasep_ktrace_reserve(struct kbase_ktrace *ktrace)
+{
+ struct kbase_ktrace_msg *trace_msg;
+
+ lockdep_assert_held(&ktrace->lock);
+
+ trace_msg = &ktrace->rbuf[ktrace->next_in];
+
+ /* Update the ringbuffer indices */
+ ktrace->next_in = (ktrace->next_in + 1) & KBASE_KTRACE_MASK;
+ if (ktrace->next_in == ktrace->first_out)
+ ktrace->first_out = (ktrace->first_out + 1) & KBASE_KTRACE_MASK;
+
+ return trace_msg;
+}
+void kbasep_ktrace_msg_init(struct kbase_ktrace *ktrace,
+ struct kbase_ktrace_msg *trace_msg, enum kbase_ktrace_code code,
+ struct kbase_context *kctx, kbase_ktrace_flag_t flags,
+ u64 info_val)
+{
+ lockdep_assert_held(&ktrace->lock);
+
+ trace_msg->thread_id = task_pid_nr(current);
+ trace_msg->cpu = task_cpu(current);
+
+ ktime_get_real_ts64(&trace_msg->timestamp);
+
+ trace_msg->kctx = kctx;
+
+ trace_msg->info_val = info_val;
+ trace_msg->backend.code = code;
+ trace_msg->backend.flags = flags;
+}
+
+void kbasep_ktrace_add(struct kbase_device *kbdev, enum kbase_ktrace_code code,
+ struct kbase_context *kctx, kbase_ktrace_flag_t flags,
+ u64 info_val)
+{
+ unsigned long irqflags;
+ struct kbase_ktrace_msg *trace_msg;
+
+ spin_lock_irqsave(&kbdev->ktrace.lock, irqflags);
+
+ /* Reserve and update indices */
+ trace_msg = kbasep_ktrace_reserve(&kbdev->ktrace);
+
+ /* Fill the common part of the message (including backend.flags) */
+ kbasep_ktrace_msg_init(&kbdev->ktrace, trace_msg, code, kctx, flags,
+ info_val);
+
+ /* Done */
+ spin_unlock_irqrestore(&kbdev->ktrace.lock, irqflags);
+}
+
+static void kbasep_ktrace_clear_locked(struct kbase_device *kbdev)
+{
+ lockdep_assert_held(&kbdev->ktrace.lock);
+ kbdev->ktrace.first_out = kbdev->ktrace.next_in;
+}
+void kbasep_ktrace_clear(struct kbase_device *kbdev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&kbdev->ktrace.lock, flags);
+ kbasep_ktrace_clear_locked(kbdev);
+ spin_unlock_irqrestore(&kbdev->ktrace.lock, flags);
+}
+
+void kbasep_ktrace_dump(struct kbase_device *kbdev)
+{
+ unsigned long flags;
+ u32 start;
+ u32 end;
+ char buffer[KTRACE_DUMP_MESSAGE_SIZE] = "Dumping trace:\n";
+
+ kbasep_ktrace_format_header(buffer, sizeof(buffer), strlen(buffer));
+ dev_dbg(kbdev->dev, "%s", buffer);
+
+ spin_lock_irqsave(&kbdev->ktrace.lock, flags);
+ start = kbdev->ktrace.first_out;
+ end = kbdev->ktrace.next_in;
+
+ while (start != end) {
+ struct kbase_ktrace_msg *trace_msg = &kbdev->ktrace.rbuf[start];
+
+ kbasep_ktrace_dump_msg(kbdev, trace_msg);
+
+ start = (start + 1) & KBASE_KTRACE_MASK;
+ }
+ dev_dbg(kbdev->dev, "TRACE_END");
+
+ kbasep_ktrace_clear_locked(kbdev);
+
+ spin_unlock_irqrestore(&kbdev->ktrace.lock, flags);
+}
+
+#ifdef CONFIG_DEBUG_FS
+struct trace_seq_state {
+ struct kbase_ktrace_msg trace_buf[KBASE_KTRACE_SIZE];
+ u32 start;
+ u32 end;
+};
+
+static void *kbasep_ktrace_seq_start(struct seq_file *s, loff_t *pos)
+{
+ struct trace_seq_state *state = s->private;
+ int i;
+
+ if (*pos == 0)
+ /* See Documentation/filesystems/seq_file.txt */
+ return SEQ_START_TOKEN;
+
+ if (*pos > KBASE_KTRACE_SIZE)
+ return NULL;
+ i = state->start + *pos;
+ if ((state->end >= state->start && i >= state->end) ||
+ i >= state->end + KBASE_KTRACE_SIZE)
+ return NULL;
+
+ i &= KBASE_KTRACE_MASK;
+
+ return &state->trace_buf[i];
+}
+
+static void kbasep_ktrace_seq_stop(struct seq_file *s, void *data)
+{
+}
+
+static void *kbasep_ktrace_seq_next(struct seq_file *s, void *data, loff_t *pos)
+{
+ struct trace_seq_state *state = s->private;
+ int i;
+
+ if (data != SEQ_START_TOKEN)
+ (*pos)++;
+
+ i = (state->start + *pos) & KBASE_KTRACE_MASK;
+ if (i == state->end)
+ return NULL;
+
+ return &state->trace_buf[i];
+}
+
+static int kbasep_ktrace_seq_show(struct seq_file *s, void *data)
+{
+ struct kbase_ktrace_msg *trace_msg = data;
+ char buffer[KTRACE_DUMP_MESSAGE_SIZE];
+
+ /* If this is the start, print a header */
+ if (data == SEQ_START_TOKEN)
+ kbasep_ktrace_format_header(buffer, sizeof(buffer), 0);
+ else
+ kbasep_ktrace_format_msg(trace_msg, buffer, sizeof(buffer));
+
+ seq_printf(s, "%s\n", buffer);
+ return 0;
+}
+
+static const struct seq_operations kbasep_ktrace_seq_ops = {
+ .start = kbasep_ktrace_seq_start,
+ .next = kbasep_ktrace_seq_next,
+ .stop = kbasep_ktrace_seq_stop,
+ .show = kbasep_ktrace_seq_show,
+};
+
+static int kbasep_ktrace_debugfs_open(struct inode *inode, struct file *file)
+{
+ struct kbase_device *kbdev = inode->i_private;
+ unsigned long flags;
+
+ struct trace_seq_state *state;
+
+ state = __seq_open_private(file, &kbasep_ktrace_seq_ops,
+ sizeof(*state));
+ if (!state)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&kbdev->ktrace.lock, flags);
+ state->start = kbdev->ktrace.first_out;
+ state->end = kbdev->ktrace.next_in;
+ memcpy(state->trace_buf, kbdev->ktrace.rbuf, sizeof(state->trace_buf));
+ spin_unlock_irqrestore(&kbdev->ktrace.lock, flags);
+
+ return 0;
+}
+
+static const struct file_operations kbasep_ktrace_debugfs_fops = {
+ .owner = THIS_MODULE,
+ .open = kbasep_ktrace_debugfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private,
+};
+
+void kbase_ktrace_debugfs_init(struct kbase_device *kbdev)
+{
+ debugfs_create_file("mali_trace", 0444,
+ kbdev->mali_debugfs_directory, kbdev,
+ &kbasep_ktrace_debugfs_fops);
+}
+#endif /* CONFIG_DEBUG_FS */
+
+#else /* KBASE_KTRACE_TARGET_RBUF */
+
+#ifdef CONFIG_DEBUG_FS
+void kbase_ktrace_debugfs_init(struct kbase_device *kbdev)
+{
+ CSTD_UNUSED(kbdev);
+}
+#endif /* CONFIG_DEBUG_FS */
+#endif /* KBASE_KTRACE_TARGET_RBUF */
diff --git a/mali_kbase/debug/mali_kbase_debug_ktrace.h b/mali_kbase/debug/mali_kbase_debug_ktrace.h
new file mode 100644
index 0000000..0dd8b7a
--- /dev/null
+++ b/mali_kbase/debug/mali_kbase_debug_ktrace.h
@@ -0,0 +1,219 @@
+/*
+ *
+ * (C) COPYRIGHT 2020 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+/*
+ * DOC: Kbase's own trace, 'KTrace'
+ *
+ * Low overhead trace specific to kbase, aimed at:
+ * - common use-cases for tracing kbase specific functionality to do with
+ * running work on the GPU
+ * - easy 1-line addition of new types of trace
+ *
+ * KTrace can be recorded in one or more of the following targets:
+ * - KBASE_KTRACE_TARGET_RBUF: low overhead ringbuffer protected by an
+ * irq-spinlock, output available via dev_dbg() and debugfs file
+ * - KBASE_KTRACE_TARGET_FTRACE: ftrace based tracepoints under 'mali' events
+ */
+
+#ifndef _KBASE_DEBUG_KTRACE_H_
+#define _KBASE_DEBUG_KTRACE_H_
+
+#include "debug/backend/mali_kbase_debug_ktrace_jm.h"
+
+/**
+ * kbase_ktrace_init - initialize kbase ktrace.
+ * @kbdev: kbase device
+ */
+int kbase_ktrace_init(struct kbase_device *kbdev);
+
+/**
+ * kbase_ktrace_term - terminate kbase ktrace.
+ * @kbdev: kbase device
+ */
+void kbase_ktrace_term(struct kbase_device *kbdev);
+
+/**
+ * kbase_ktrace_hook_wrapper - wrapper so that dumping ktrace can be done via a
+ * callback.
+ * @param: kbase device, cast to void pointer
+ */
+void kbase_ktrace_hook_wrapper(void *param);
+
+#ifdef CONFIG_DEBUG_FS
+/**
+ * kbase_ktrace_debugfs_init - initialize kbase ktrace for debugfs usage, if
+ * the selected targets support it.
+ * @kbdev: kbase device
+ *
+ * There is no matching 'term' call, debugfs_remove_recursive() is sufficient.
+ */
+void kbase_ktrace_debugfs_init(struct kbase_device *kbdev);
+#endif /* CONFIG_DEBUG_FS */
+
+/*
+ * KTrace target for internal ringbuffer
+ */
+#if KBASE_KTRACE_TARGET_RBUF
+/**
+ * kbasep_ktrace_add - internal function to add trace to the ringbuffer.
+ * @kbdev: kbase device
+ * @code: ktrace code
+ * @kctx: kbase context, or NULL if no context
+ * @flags: flags about the message
+ * @info_val: generic information about @code to add to the trace
+ *
+ * PRIVATE: do not use directly. Use KBASE_KTRACE_ADD() instead.
+ */
+void kbasep_ktrace_add(struct kbase_device *kbdev, enum kbase_ktrace_code code,
+ struct kbase_context *kctx, kbase_ktrace_flag_t flags,
+ u64 info_val);
+
+/**
+ * kbasep_ktrace_clear - clear the trace ringbuffer
+ * @kbdev: kbase device
+ *
+ * PRIVATE: do not use directly. Use KBASE_KTRACE_CLEAR() instead.
+ */
+void kbasep_ktrace_clear(struct kbase_device *kbdev);
+
+/**
+ * kbasep_ktrace_dump - dump ktrace ringbuffer to dev_dbg(), then clear it
+ * @kbdev: kbase device
+ *
+ * PRIVATE: do not use directly. Use KBASE_KTRACE_DUMP() instead.
+ */
+void kbasep_ktrace_dump(struct kbase_device *kbdev);
+
+#define KBASE_KTRACE_RBUF_ADD(kbdev, code, kctx, info_val) \
+ kbasep_ktrace_add(kbdev, KBASE_KTRACE_CODE(code), kctx, 0, \
+ info_val) \
+
+#define KBASE_KTRACE_RBUF_CLEAR(kbdev) \
+ kbasep_ktrace_clear(kbdev)
+
+#define KBASE_KTRACE_RBUF_DUMP(kbdev) \
+ kbasep_ktrace_dump(kbdev)
+
+#else /* KBASE_KTRACE_TARGET_RBUF */
+
+#define KBASE_KTRACE_RBUF_ADD(kbdev, code, kctx, info_val) \
+ do { \
+ CSTD_UNUSED(kbdev); \
+ CSTD_NOP(code); \
+ CSTD_UNUSED(kctx); \
+ CSTD_UNUSED(info_val); \
+ CSTD_NOP(0); \
+ } while (0)
+
+#define KBASE_KTRACE_RBUF_CLEAR(kbdev) \
+ do { \
+ CSTD_UNUSED(kbdev); \
+ CSTD_NOP(0); \
+ } while (0)
+#define KBASE_KTRACE_RBUF_DUMP(kbdev) \
+ do { \
+ CSTD_UNUSED(kbdev); \
+ CSTD_NOP(0); \
+ } while (0)
+#endif /* KBASE_KTRACE_TARGET_RBUF */
+
+/*
+ * KTrace target for Linux's ftrace
+ */
+#if KBASE_KTRACE_TARGET_FTRACE
+#include "mali_linux_trace.h"
+
+#define KBASE_KTRACE_FTRACE_ADD(kbdev, code, kctx, info_val) \
+ trace_mali_##code(info_val)
+
+#else /* KBASE_KTRACE_TARGET_FTRACE */
+#define KBASE_KTRACE_FTRACE_ADD(kbdev, code, kctx, info_val) \
+ do { \
+ CSTD_UNUSED(kbdev); \
+ CSTD_NOP(code); \
+ CSTD_UNUSED(kctx); \
+ CSTD_UNUSED(info_val); \
+ CSTD_NOP(0); \
+ } while (0)
+#endif /* KBASE_KTRACE_TARGET_FTRACE */
+
+/* No 'clear' implementation for ftrace yet */
+#define KBASE_KTRACE_FTRACE_CLEAR(kbdev) \
+ do { \
+ CSTD_UNUSED(kbdev); \
+ CSTD_NOP(0); \
+ } while (0)
+
+/* No 'dump' implementation for ftrace yet */
+#define KBASE_KTRACE_FTRACE_DUMP(kbdev) \
+ do { \
+ CSTD_UNUSED(kbdev); \
+ CSTD_NOP(0); \
+ } while (0)
+
+/*
+ * Master set of macros to route KTrace to any of the targets
+ */
+
+/**
+ * KBASE_KTRACE_ADD - Add trace values
+ * @kbdev: kbase device
+ * @code: trace code
+ * @kctx: kbase context, or NULL if no context
+ * @info_val: generic information about @code to add to the trace
+ *
+ * Note: Any functions called through this macro will still be evaluated in
+ * Release builds (CONFIG_MALI_DEBUG not defined). Therefore, when
+ * KBASE_KTRACE_ENABLE == 0 any functions called to get the parameters supplied
+ * to this macro must:
+ * a) be static or static inline, and
+ * b) just return 0 and have no other statements present in the body.
+ */
+#define KBASE_KTRACE_ADD(kbdev, code, kctx, info_val) \
+ do { \
+ /* capture values that could come from non-pure function calls */ \
+ u64 __info_val = info_val; \
+ KBASE_KTRACE_RBUF_ADD(kbdev, code, kctx, __info_val); \
+ KBASE_KTRACE_FTRACE_ADD(kbdev, code, kctx, __info_val); \
+ } while (0)
+
+/**
+ * KBASE_KTRACE_CLEAR - Clear the trace, if applicable to the target(s)
+ * @kbdev: kbase device
+ */
+#define KBASE_KTRACE_CLEAR(kbdev) \
+ do { \
+ KBASE_KTRACE_RBUF_CLEAR(kbdev); \
+ KBASE_KTRACE_FTRACE_CLEAR(kbdev); \
+ } while (0)
+
+/**
+ * KBASE_KTRACE_DUMP - Dump the trace, if applicable to the target(s)
+ * @kbdev: kbase device
+ */
+#define KBASE_KTRACE_DUMP(kbdev) \
+ do { \
+ KBASE_KTRACE_RBUF_DUMP(kbdev); \
+ KBASE_KTRACE_FTRACE_DUMP(kbdev); \
+ } while (0)
+
+#endif /* _KBASE_DEBUG_KTRACE_H_ */
diff --git a/mali_kbase/debug/mali_kbase_debug_ktrace_codes.h b/mali_kbase/debug/mali_kbase_debug_ktrace_codes.h
new file mode 100644
index 0000000..364ed60
--- /dev/null
+++ b/mali_kbase/debug/mali_kbase_debug_ktrace_codes.h
@@ -0,0 +1,158 @@
+/*
+ *
+ * (C) COPYRIGHT 2011-2015,2018-2020 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+/*
+ * ***** IMPORTANT: THIS IS NOT A NORMAL HEADER FILE *****
+ * ***** DO NOT INCLUDE DIRECTLY *****
+ * ***** THE LACK OF HEADER GUARDS IS INTENTIONAL *****
+ */
+
+/*
+ * The purpose of this header file is just to contain a list of trace code
+ * identifiers
+ *
+ * Each identifier is wrapped in a macro, so that its string form and enum form
+ * can be created
+ *
+ * Each macro is separated with a comma, to allow insertion into an array
+ * initializer or enum definition block.
+ *
+ * This allows automatic creation of an enum and a corresponding array of
+ * strings
+ *
+ * Before #including, the includer MUST #define KBASE_KTRACE_CODE_MAKE_CODE.
+ * After #including, the includer MUST #under KBASE_KTRACE_CODE_MAKE_CODE.
+ *
+ * e.g.:
+ * #define KBASE_KTRACE_CODE( X ) KBASE_KTRACE_CODE_ ## X
+ * typedef enum
+ * {
+ * #define KBASE_KTRACE_CODE_MAKE_CODE( X ) KBASE_KTRACE_CODE( X )
+ * #include "mali_kbase_debug_ktrace_codes.h"
+ * #undef KBASE_KTRACE_CODE_MAKE_CODE
+ * } kbase_ktrace_code;
+ *
+ * IMPORTANT: THIS FILE MUST NOT BE USED FOR ANY OTHER PURPOSE OTHER THAN THE ABOVE
+ *
+ *
+ * The use of the macro here is:
+ * - KBASE_KTRACE_CODE_MAKE_CODE( X )
+ *
+ * Which produces:
+ * - For an enum, KBASE_KTRACE_CODE_X
+ * - For a string, "X"
+ *
+ *
+ * For example:
+ * - KBASE_KTRACE_CODE_MAKE_CODE( JM_JOB_COMPLETE ) expands to:
+ * - KBASE_KTRACE_CODE_JM_JOB_COMPLETE for the enum
+ * - "JM_JOB_COMPLETE" for the string
+ * - To use it to trace an event, do:
+ * - KBASE_KTRACE_ADD( kbdev, JM_JOB_COMPLETE, subcode, kctx, uatom, val );
+ */
+
+#if 0 /* Dummy section to avoid breaking formatting */
+int dummy_array[] = {
+#endif
+
+ /*
+ * Core events
+ */
+ /* no info_val */
+ KBASE_KTRACE_CODE_MAKE_CODE(CORE_CTX_DESTROY),
+ /* no info_val */
+ KBASE_KTRACE_CODE_MAKE_CODE(CORE_CTX_HWINSTR_TERM),
+ /* info_val == GPU_IRQ_STATUS register */
+ KBASE_KTRACE_CODE_MAKE_CODE(CORE_GPU_IRQ),
+ /* info_val == bits cleared */
+ KBASE_KTRACE_CODE_MAKE_CODE(CORE_GPU_IRQ_CLEAR),
+ /* info_val == GPU_IRQ_STATUS register */
+ KBASE_KTRACE_CODE_MAKE_CODE(CORE_GPU_IRQ_DONE),
+ KBASE_KTRACE_CODE_MAKE_CODE(CORE_GPU_SOFT_RESET),
+ KBASE_KTRACE_CODE_MAKE_CODE(CORE_GPU_HARD_RESET),
+ KBASE_KTRACE_CODE_MAKE_CODE(CORE_GPU_PRFCNT_CLEAR),
+ /* info_val == dump address */
+ KBASE_KTRACE_CODE_MAKE_CODE(CORE_GPU_PRFCNT_SAMPLE),
+ KBASE_KTRACE_CODE_MAKE_CODE(CORE_GPU_CLEAN_INV_CACHES),
+
+ /*
+ * Power Management Events
+ */
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_JOB_SUBMIT_AFTER_POWERING_UP),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_JOB_SUBMIT_AFTER_POWERED_UP),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_PWRON),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_PWRON_TILER),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_PWRON_L2),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_PWROFF),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_PWROFF_TILER),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_PWROFF_L2),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_CORES_POWERED),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_CORES_POWERED_TILER),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_CORES_POWERED_L2),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_CORES_CHANGE_DESIRED),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_CORES_CHANGE_DESIRED_TILER),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_CORES_CHANGE_AVAILABLE),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_CORES_CHANGE_AVAILABLE_TILER),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_CORES_AVAILABLE),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_CORES_AVAILABLE_TILER),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_DESIRED_REACHED),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_DESIRED_REACHED_TILER),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_RELEASE_CHANGE_SHADER_NEEDED),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_RELEASE_CHANGE_TILER_NEEDED),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_REQUEST_CHANGE_SHADER_NEEDED),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_REQUEST_CHANGE_TILER_NEEDED),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_WAKE_WAITERS),
+ /* info_val == kbdev->pm.active_count*/
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_CONTEXT_ACTIVE),
+ /* info_val == kbdev->pm.active_count*/
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_CONTEXT_IDLE),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_GPU_ON),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_GPU_OFF),
+ /* info_val == policy number, or -1 for "Already changing" */
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_SET_POLICY),
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_CA_SET_POLICY),
+ /* info_val == policy number */
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_CURRENT_POLICY_INIT),
+ /* info_val == policy number */
+ KBASE_KTRACE_CODE_MAKE_CODE(PM_CURRENT_POLICY_TERM),
+
+ /*
+ * Context Scheduler events
+ */
+ /* info_val == kctx->refcount */
+ KBASE_KTRACE_CODE_MAKE_CODE(SCHED_RETAIN_CTX_NOLOCK),
+ /* info_val == kctx->refcount */
+ KBASE_KTRACE_CODE_MAKE_CODE(SCHED_RELEASE_CTX),
+
+
+#include "debug/backend/mali_kbase_debug_ktrace_codes_jm.h"
+ /*
+ * Unused code just to make it easier to not have a comma at the end.
+ * All other codes MUST come before this
+ */
+ KBASE_KTRACE_CODE_MAKE_CODE(DUMMY)
+
+#if 0 /* Dummy section to avoid breaking formatting */
+};
+#endif
+
+/* ***** THE LACK OF HEADER GUARDS IS INTENTIONAL ***** */
diff --git a/mali_kbase/debug/mali_kbase_debug_ktrace_defs.h b/mali_kbase/debug/mali_kbase_debug_ktrace_defs.h
new file mode 100644
index 0000000..d6baaf1
--- /dev/null
+++ b/mali_kbase/debug/mali_kbase_debug_ktrace_defs.h
@@ -0,0 +1,152 @@
+/*
+ *
+ * (C) COPYRIGHT 2020 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+#ifndef _KBASE_DEBUG_KTRACE_DEFS_H_
+#define _KBASE_DEBUG_KTRACE_DEFS_H_
+
+/* Enable SW tracing when set */
+#if defined(CONFIG_MALI_MIDGARD_ENABLE_TRACE) || defined(CONFIG_MALI_SYSTEM_TRACE)
+#define KBASE_KTRACE_ENABLE 1
+#endif
+
+#ifndef KBASE_KTRACE_ENABLE
+#ifdef CONFIG_MALI_DEBUG
+#define KBASE_KTRACE_ENABLE 1
+#else /* CONFIG_MALI_DEBUG */
+#define KBASE_KTRACE_ENABLE 0
+#endif /* CONFIG_MALI_DEBUG */
+#endif /* KBASE_KTRACE_ENABLE */
+
+/* Select targets for recording of trace:
+ *
+ */
+#if KBASE_KTRACE_ENABLE
+
+#ifdef CONFIG_MALI_SYSTEM_TRACE
+#define KBASE_KTRACE_TARGET_FTRACE 1
+#else /* CONFIG_MALI_SYSTEM_TRACE */
+#define KBASE_KTRACE_TARGET_FTRACE 0
+#endif /* CONFIG_MALI_SYSTEM_TRACE */
+
+#ifdef CONFIG_MALI_MIDGARD_ENABLE_TRACE
+#define KBASE_KTRACE_TARGET_RBUF 1
+#else /* CONFIG_MALI_MIDGARD_ENABLE_TRACE*/
+#define KBASE_KTRACE_TARGET_RBUF 0
+#endif /* CONFIG_MALI_MIDGARD_ENABLE_TRACE */
+
+#else /* KBASE_KTRACE_ENABLE */
+#define KBASE_KTRACE_TARGET_FTRACE 0
+#define KBASE_KTRACE_TARGET_RBUF 0
+#endif /* KBASE_KTRACE_ENABLE */
+
+/*
+ * NOTE: KBASE_KTRACE_VERSION_MAJOR, KBASE_KTRACE_VERSION_MINOR are kept in
+ * the backend, since updates can be made to one backend in a way that doesn't
+ * affect the other.
+ *
+ * However, modifying the common part could require both backend versions to be
+ * updated.
+ */
+
+#if KBASE_KTRACE_TARGET_RBUF
+typedef u8 kbase_ktrace_flag_t;
+typedef u8 kbase_ktrace_code_t;
+
+/*
+ * struct kbase_ktrace_backend - backend specific part of a trace message
+ *
+ * At the very least, this must contain a kbase_ktrace_code_t 'code' member and
+ * a kbase_ktrace_flag_t 'flags' member
+ */
+struct kbase_ktrace_backend;
+
+#include "debug/backend/mali_kbase_debug_ktrace_defs_jm.h"
+
+/* Indicates if the trace message has backend related info.
+ *
+ * If not set, consider the &kbase_ktrace_backend part of a &kbase_ktrace_msg
+ * as uninitialized, apart from the mandatory parts:
+ * - code
+ * - flags
+ */
+#define KBASE_KTRACE_FLAG_BACKEND (((kbase_ktrace_flag_t)1) << 7)
+
+#define KBASE_KTRACE_SHIFT 8 /* 256 entries */
+#define KBASE_KTRACE_SIZE (1 << KBASE_KTRACE_SHIFT)
+#define KBASE_KTRACE_MASK ((1 << KBASE_KTRACE_SHIFT)-1)
+
+#define KBASE_KTRACE_CODE(X) KBASE_KTRACE_CODE_ ## X
+
+/* Note: compiletime_assert() about this against kbase_ktrace_code_t is in
+ * kbase_ktrace_init()
+ */
+enum kbase_ktrace_code {
+ /*
+ * IMPORTANT: USE OF SPECIAL #INCLUDE OF NON-STANDARD HEADER FILE
+ * THIS MUST BE USED AT THE START OF THE ENUM
+ */
+#define KBASE_KTRACE_CODE_MAKE_CODE(X) KBASE_KTRACE_CODE(X)
+#include <debug/mali_kbase_debug_ktrace_codes.h>
+#undef KBASE_KTRACE_CODE_MAKE_CODE
+ /* Comma on its own, to extend the list */
+ ,
+ /* Must be the last in the enum */
+ KBASE_KTRACE_CODE_COUNT
+};
+
+/**
+ * struct kbase_ktrace - object representing a trace message added to trace
+ * buffer trace_rbuf in &kbase_device
+ * @timestamp: CPU timestamp at which the trace message was added.
+ * @thread_id: id of the thread in the context of which trace message was
+ * added.
+ * @cpu: indicates which CPU the @thread_id was scheduled on when the
+ * trace message was added.
+ * @kctx: Pointer to the kbase context for which the trace message was
+ * added. Will be NULL for certain trace messages associated with
+ * the &kbase_device itself, such as power management events.
+ * Will point to the appropriate context corresponding to
+ * backend-specific events.
+ * @info_val: value specific to the type of event being traced. Refer to the
+ * specific code in enum kbase_ktrace_code
+ * @backend: backend-specific trace information. All backends must implement
+ * a minimum common set of members
+ */
+struct kbase_ktrace_msg {
+ struct timespec64 timestamp;
+ u32 thread_id;
+ u32 cpu;
+ void *kctx;
+ u64 info_val;
+
+ struct kbase_ktrace_backend backend;
+};
+
+struct kbase_ktrace {
+ spinlock_t lock;
+ u16 first_out;
+ u16 next_in;
+ struct kbase_ktrace_msg *rbuf;
+};
+
+#endif /* KBASE_KTRACE_TARGET_RBUF */
+#endif /* _KBASE_DEBUG_KTRACE_DEFS_H_ */
diff --git a/mali_kbase/debug/mali_kbase_debug_ktrace_internal.h b/mali_kbase/debug/mali_kbase_debug_ktrace_internal.h
new file mode 100644
index 0000000..e450760
--- /dev/null
+++ b/mali_kbase/debug/mali_kbase_debug_ktrace_internal.h
@@ -0,0 +1,89 @@
+/*
+ *
+ * (C) COPYRIGHT 2020 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+#ifndef _KBASE_DEBUG_KTRACE_INTERNAL_H_
+#define _KBASE_DEBUG_KTRACE_INTERNAL_H_
+
+#if KBASE_KTRACE_TARGET_RBUF
+
+#define KTRACE_DUMP_MESSAGE_SIZE 256
+
+/**
+ * kbasep_ktrace_backend_format_header - format the backend part of the header
+ * @buffer: buffer to write to
+ * @sz: size of @buffer in bytes
+ * @written: pointer to storage for updating bytes written so far to @buffer
+ *
+ * The backend must format only the non-common backend specific parts of the
+ * header. It must format them as though they were standalone. The caller will
+ * handle adding any delimiters around this.
+ */
+void kbasep_ktrace_backend_format_header(char *buffer, int sz, s32 *written);
+
+/**
+ * kbasep_ktrace_backend_format_msg - format the backend part of the message
+ * @trace_msg: ktrace message
+ * @buffer: buffer to write to
+ * @sz: size of @buffer in bytes
+ * @written: pointer to storage for updating bytes written so far to @buffer
+ *
+ * The backend must format only the non-common backend specific parts of the
+ * message. It must format them as though they were standalone. The caller will
+ * handle adding any delimiters around this.
+ *
+ * A caller may have the flags member of @trace_msg with
+ * %KBASE_KTRACE_FLAG_BACKEND clear. The backend must handle that setting
+ * appropriately.
+ */
+void kbasep_ktrace_backend_format_msg(struct kbase_ktrace_msg *trace_msg,
+ char *buffer, int sz, s32 *written);
+
+
+/**
+ * kbasep_ktrace_reserve - internal function to reserve space for a ktrace
+ * message
+ * @ktrace: kbase device's ktrace
+ *
+ * This may also empty the oldest entry in the ringbuffer to make space.
+ */
+struct kbase_ktrace_msg *kbasep_ktrace_reserve(struct kbase_ktrace *ktrace);
+
+/**
+ * kbasep_ktrace_msg_init - internal function to initialize just the common
+ * part of a ktrace message
+ * @ktrace: kbase device's ktrace
+ * @trace_msg: ktrace message to initialize
+ * @code: ktrace code
+ * @kctx: kbase context, or NULL if no context
+ * @flags: flags about the message
+ * @info_val: generic information about @code to add to the trace
+ *
+ * The common part includes the mandatory parts of the backend part
+ */
+void kbasep_ktrace_msg_init(struct kbase_ktrace *ktrace,
+ struct kbase_ktrace_msg *trace_msg, enum kbase_ktrace_code code,
+ struct kbase_context *kctx, kbase_ktrace_flag_t flags,
+ u64 info_val);
+
+#endif /* KBASE_KTRACE_TARGET_RBUF */
+
+#endif /* _KBASE_DEBUG_KTRACE_INTERNAL_H_ */
diff --git a/mali_kbase/debug/mali_kbase_debug_linux_ktrace.h b/mali_kbase/debug/mali_kbase_debug_linux_ktrace.h
new file mode 100644
index 0000000..18e4f7c
--- /dev/null
+++ b/mali_kbase/debug/mali_kbase_debug_linux_ktrace.h
@@ -0,0 +1,99 @@
+/*
+ *
+ * (C) COPYRIGHT 2014,2018,2020 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+/*
+ * NOTE: This must **only** be included through mali_linux_trace.h,
+ * otherwise it will fail to setup tracepoints correctly
+ */
+
+#if !defined(_KBASE_DEBUG_LINUX_KTRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
+#define _KBASE_DEBUG_LINUX_KTRACE_H_
+
+#if KBASE_KTRACE_TARGET_FTRACE
+
+DECLARE_EVENT_CLASS(mali_add_template,
+ TP_PROTO(u64 info_val),
+ TP_ARGS(info_val),
+ TP_STRUCT__entry(
+ __field(u64, info_val)
+ ),
+ TP_fast_assign(
+ __entry->info_val = info_val;
+ ),
+ TP_printk("info=0x%llx", __entry->info_val)
+);
+
+#define DEFINE_MALI_ADD_EVENT(name) \
+DEFINE_EVENT(mali_add_template, mali_##name, \
+ TP_PROTO(u64 info_val), \
+ TP_ARGS(info_val))
+DEFINE_MALI_ADD_EVENT(CORE_CTX_DESTROY);
+DEFINE_MALI_ADD_EVENT(CORE_CTX_HWINSTR_TERM);
+DEFINE_MALI_ADD_EVENT(CORE_GPU_IRQ);
+DEFINE_MALI_ADD_EVENT(CORE_GPU_IRQ_CLEAR);
+DEFINE_MALI_ADD_EVENT(CORE_GPU_IRQ_DONE);
+DEFINE_MALI_ADD_EVENT(CORE_GPU_SOFT_RESET);
+DEFINE_MALI_ADD_EVENT(CORE_GPU_HARD_RESET);
+DEFINE_MALI_ADD_EVENT(CORE_GPU_PRFCNT_SAMPLE);
+DEFINE_MALI_ADD_EVENT(CORE_GPU_PRFCNT_CLEAR);
+DEFINE_MALI_ADD_EVENT(CORE_GPU_CLEAN_INV_CACHES);
+DEFINE_MALI_ADD_EVENT(PM_CORES_CHANGE_DESIRED);
+DEFINE_MALI_ADD_EVENT(PM_JOB_SUBMIT_AFTER_POWERING_UP);
+DEFINE_MALI_ADD_EVENT(PM_JOB_SUBMIT_AFTER_POWERED_UP);
+DEFINE_MALI_ADD_EVENT(PM_PWRON);
+DEFINE_MALI_ADD_EVENT(PM_PWRON_TILER);
+DEFINE_MALI_ADD_EVENT(PM_PWRON_L2);
+DEFINE_MALI_ADD_EVENT(PM_PWROFF);
+DEFINE_MALI_ADD_EVENT(PM_PWROFF_TILER);
+DEFINE_MALI_ADD_EVENT(PM_PWROFF_L2);
+DEFINE_MALI_ADD_EVENT(PM_CORES_POWERED);
+DEFINE_MALI_ADD_EVENT(PM_CORES_POWERED_TILER);
+DEFINE_MALI_ADD_EVENT(PM_CORES_POWERED_L2);
+DEFINE_MALI_ADD_EVENT(PM_DESIRED_REACHED);
+DEFINE_MALI_ADD_EVENT(PM_DESIRED_REACHED_TILER);
+DEFINE_MALI_ADD_EVENT(PM_REQUEST_CHANGE_SHADER_NEEDED);
+DEFINE_MALI_ADD_EVENT(PM_REQUEST_CHANGE_TILER_NEEDED);
+DEFINE_MALI_ADD_EVENT(PM_RELEASE_CHANGE_SHADER_NEEDED);
+DEFINE_MALI_ADD_EVENT(PM_RELEASE_CHANGE_TILER_NEEDED);
+DEFINE_MALI_ADD_EVENT(PM_CORES_AVAILABLE);
+DEFINE_MALI_ADD_EVENT(PM_CORES_AVAILABLE_TILER);
+DEFINE_MALI_ADD_EVENT(PM_CORES_CHANGE_AVAILABLE);
+DEFINE_MALI_ADD_EVENT(PM_CORES_CHANGE_AVAILABLE_TILER);
+DEFINE_MALI_ADD_EVENT(PM_GPU_ON);
+DEFINE_MALI_ADD_EVENT(PM_GPU_OFF);
+DEFINE_MALI_ADD_EVENT(PM_SET_POLICY);
+DEFINE_MALI_ADD_EVENT(PM_CURRENT_POLICY_INIT);
+DEFINE_MALI_ADD_EVENT(PM_CURRENT_POLICY_TERM);
+DEFINE_MALI_ADD_EVENT(PM_CA_SET_POLICY);
+DEFINE_MALI_ADD_EVENT(PM_CONTEXT_ACTIVE);
+DEFINE_MALI_ADD_EVENT(PM_CONTEXT_IDLE);
+DEFINE_MALI_ADD_EVENT(PM_WAKE_WAITERS);
+DEFINE_MALI_ADD_EVENT(SCHED_RETAIN_CTX_NOLOCK);
+DEFINE_MALI_ADD_EVENT(SCHED_RELEASE_CTX);
+
+#undef DEFINE_MALI_ADD_EVENT
+
+#include "mali_kbase_debug_linux_ktrace_jm.h"
+
+#endif /* KBASE_KTRACE_TARGET_FTRACE */
+
+#endif /* !defined(_KBASE_DEBUG_LINUX_KTRACE_H_) || defined(TRACE_HEADER_MULTI_READ) */