3 * (C) COPYRIGHT ARM Limited. All rights reserved.
5 * This program is free software and is provided to you under the terms of the
6 * GNU General Public License version 2 as published by the Free Software
7 * Foundation, and any use by you of this program is subject to the terms
10 * A copy of the licence is included with the program, and can also be obtained
11 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12 * Boston, MA 02110-1301, USA.
20 #if !defined(_KBASE_TRACE_TIMELINE_H)
21 #define _KBASE_TRACE_TIMELINE_H
23 #ifdef CONFIG_MALI_TRACE_TIMELINE
27 #define KBASE_TIMELINE_TRACE_CODE(enum_val, desc, format, format_desc) enum_val
28 #include "mali_kbase_trace_timeline_defs.h"
29 #undef KBASE_TIMELINE_TRACE_CODE
30 } kbase_trace_timeline_code;
32 /** Initialize Timeline DebugFS entries */
33 mali_error kbasep_trace_timeline_debugfs_init(kbase_device *kbdev);
34 /** Terminate Timeline DebugFS entries */
35 void kbasep_trace_timeline_debugfs_term(kbase_device *kbdev);
37 /* mali_timeline.h defines kernel tracepoints used by the KBASE_TIMELINE
39 * Output is timestamped by either sched_clock() (default), local_clock(), or
40 * cpu_clock(), depending on /sys/kernel/debug/tracing/trace_clock */
41 #include "mali_timeline.h"
43 /* Trace number of atoms in flight for kctx (atoms either not completed, or in
44 process of being returned to user */
45 #define KBASE_TIMELINE_ATOMS_IN_FLIGHT(kctx, count) \
49 getnstimeofday(&ts); \
50 trace_mali_timeline_atoms_in_flight(ts.tv_sec, ts.tv_nsec, \
51 (int)kctx->timeline.owner_tgid, \
55 /* Trace atom_id being Ready to Run */
56 #define KBASE_TIMELINE_ATOM_READY(kctx, atom_id) \
60 getnstimeofday(&ts); \
61 trace_mali_timeline_atom(ts.tv_sec, ts.tv_nsec, \
62 CTX_FLOW_ATOM_READY, \
63 (int)kctx->timeline.owner_tgid, \
68 /* Trace number of atoms submitted to job slot js
70 * NOTE: This uses a different tracepoint to the head/next/soft-stop actions,
71 * so that those actions can be filtered out separately from this
73 * This is because this is more useful, as we can use it to calculate general
74 * utilization easily and accurately */
75 #define KBASE_TIMELINE_ATOMS_SUBMITTED(kctx, js, count) \
79 getnstimeofday(&ts); \
80 trace_mali_timeline_gpu_slot_active(ts.tv_sec, ts.tv_nsec, \
81 SW_SET_GPU_SLOT_ACTIVE, \
82 (int)kctx->timeline.owner_tgid, \
87 /* Trace atoms present in JSn_NEXT */
88 #define KBASE_TIMELINE_JOB_START_NEXT(kctx, js, count) \
92 getnstimeofday(&ts); \
93 trace_mali_timeline_gpu_slot_action(ts.tv_sec, ts.tv_nsec, \
94 SW_SET_GPU_SLOT_NEXT, \
95 (int)kctx->timeline.owner_tgid, \
99 /* Trace atoms present in JSn_HEAD */
100 #define KBASE_TIMELINE_JOB_START_HEAD(kctx, js, count) \
103 struct timespec ts; \
104 getnstimeofday(&ts); \
105 trace_mali_timeline_gpu_slot_action(ts.tv_sec, ts.tv_nsec, \
106 SW_SET_GPU_SLOT_HEAD, \
107 (int)kctx->timeline.owner_tgid, \
111 /* Trace that a soft stop/evict from next is being attempted on a slot */
112 #define KBASE_TIMELINE_TRY_SOFT_STOP(kctx, js, count) \
115 struct timespec ts; \
116 getnstimeofday(&ts); \
117 trace_mali_timeline_gpu_slot_action(ts.tv_sec, ts.tv_nsec, \
118 SW_SET_GPU_SLOT_STOPPING, \
119 (kctx)?(int)kctx->timeline.owner_tgid:0, \
125 /* Trace state of overall GPU power */
126 #define KBASE_TIMELINE_GPU_POWER(kbdev, active) \
129 struct timespec ts; \
130 getnstimeofday(&ts); \
131 trace_mali_timeline_gpu_power_active(ts.tv_sec, ts.tv_nsec, \
132 SW_SET_GPU_POWER_ACTIVE, active); \
135 /* Trace state of tiler power */
136 #define KBASE_TIMELINE_POWER_TILER(kbdev, bitmap) \
139 struct timespec ts; \
140 getnstimeofday(&ts); \
141 trace_mali_timeline_gpu_power_active(ts.tv_sec, ts.tv_nsec, \
142 SW_SET_GPU_POWER_TILER_ACTIVE, \
143 hweight64(bitmap)); \
146 /* Trace number of shaders currently powered */
147 #define KBASE_TIMELINE_POWER_SHADER(kbdev, bitmap) \
150 struct timespec ts; \
151 getnstimeofday(&ts); \
152 trace_mali_timeline_gpu_power_active(ts.tv_sec, ts.tv_nsec, \
153 SW_SET_GPU_POWER_SHADER_ACTIVE, \
154 hweight64(bitmap)); \
157 /* Trace state of L2 power */
158 #define KBASE_TIMELINE_POWER_L2(kbdev, bitmap) \
161 struct timespec ts; \
162 getnstimeofday(&ts); \
163 trace_mali_timeline_gpu_power_active(ts.tv_sec, ts.tv_nsec, \
164 SW_SET_GPU_POWER_L2_ACTIVE, \
165 hweight64(bitmap)); \
168 /* Trace state of L2 cache*/
169 #define KBASE_TIMELINE_POWERING_L2(kbdev) \
172 struct timespec ts; \
173 getnstimeofday(&ts); \
174 trace_mali_timeline_l2_power_active(ts.tv_sec, ts.tv_nsec, \
175 SW_FLOW_GPU_POWER_L2_POWERING, \
179 #define KBASE_TIMELINE_POWERED_L2(kbdev) \
182 struct timespec ts; \
183 getnstimeofday(&ts); \
184 trace_mali_timeline_l2_power_active(ts.tv_sec, ts.tv_nsec, \
185 SW_FLOW_GPU_POWER_L2_ACTIVE, \
189 /* Trace kbase_pm_send_event message send */
190 #define KBASE_TIMELINE_PM_SEND_EVENT(kbdev, event_type, pm_event_id) \
193 struct timespec ts; \
194 getnstimeofday(&ts); \
195 trace_mali_timeline_pm_event(ts.tv_sec, ts.tv_nsec, \
196 SW_FLOW_PM_SEND_EVENT, \
197 event_type, pm_event_id); \
200 /* Trace kbase_pm_worker message receive */
201 #define KBASE_TIMELINE_PM_HANDLE_EVENT(kbdev, event_type, pm_event_id) \
204 struct timespec ts; \
205 getnstimeofday(&ts); \
206 trace_mali_timeline_pm_event(ts.tv_sec, ts.tv_nsec, \
207 SW_FLOW_PM_HANDLE_EVENT, \
208 event_type, pm_event_id); \
212 /* Trace atom_id starting in JSn_HEAD */
213 #define KBASE_TIMELINE_JOB_START(kctx, js, _consumerof_atom_number) \
216 struct timespec ts; \
217 getnstimeofday(&ts); \
218 trace_mali_timeline_slot_atom(ts.tv_sec, ts.tv_nsec, \
219 HW_START_GPU_JOB_CHAIN_SW_APPROX, \
220 (int)kctx->timeline.owner_tgid, \
221 js, _consumerof_atom_number); \
224 /* Trace atom_id stopping on JSn_HEAD */
225 #define KBASE_TIMELINE_JOB_STOP(kctx, js, _producerof_atom_number_completed) \
228 struct timespec ts; \
229 getnstimeofday(&ts); \
230 trace_mali_timeline_slot_atom(ts.tv_sec, ts.tv_nsec, \
231 HW_STOP_GPU_JOB_CHAIN_SW_APPROX, \
232 (int)kctx->timeline.owner_tgid, \
233 js, _producerof_atom_number_completed); \
236 /** Trace beginning/end of a call to kbase_pm_check_transitions_nolock from a
238 #define KBASE_TIMELINE_PM_CHECKTRANS(kbdev, trace_code) \
241 struct timespec ts; \
242 getnstimeofday(&ts); \
243 trace_mali_timeline_pm_checktrans(ts.tv_sec, ts.tv_nsec, \
248 /* NOTE: kbase_timeline_pm_cores_func() is in mali_kbase_pm_policy.c */
251 * Trace that an atom is starting on a job slot
253 * The caller must be holding kbasep_js_device_data::runpool_irq::lock
255 void kbase_timeline_job_slot_submit(kbase_device *kbdev, kbase_context *kctx,
256 kbase_jd_atom *katom, int js);
259 * Trace that an atom has done on a job slot
261 * 'Done' in this sense can occur either because:
262 * - the atom in JSn_HEAD finished
263 * - the atom in JSn_NEXT was evicted
265 * Whether the atom finished or was evicted is passed in @a done_code
267 * It is assumed that the atom has already been removed from the submit slot,
269 * - kbasep_jm_dequeue_submit_slot()
270 * - kbasep_jm_dequeue_tail_submit_slot()
272 * The caller must be holding kbasep_js_device_data::runpool_irq::lock
274 void kbase_timeline_job_slot_done(kbase_device *kbdev, kbase_context *kctx,
275 kbase_jd_atom *katom, int js,
276 kbasep_js_atom_done_code done_code);
279 /** Trace a pm event starting */
280 void kbase_timeline_pm_send_event(kbase_device *kbdev,
281 kbase_timeline_pm_event event_sent);
283 /** Trace a pm event finishing */
284 void kbase_timeline_pm_check_handle_event(kbase_device *kbdev, kbase_timeline_pm_event event);
286 /** Check whether a pm event was present, and if so trace finishing it */
287 void kbase_timeline_pm_handle_event(kbase_device *kbdev, kbase_timeline_pm_event event);
289 /** Trace L2 power-up start */
290 void kbase_timeline_pm_l2_transition_start(kbase_device *kbdev);
292 /** Trace L2 power-up done */
293 void kbase_timeline_pm_l2_transition_done(kbase_device *kbdev);
297 #define KBASE_TIMELINE_ATOMS_IN_FLIGHT(kctx, count) CSTD_NOP()
299 #define KBASE_TIMELINE_ATOM_READY(kctx, atom_id) CSTD_NOP()
301 #define KBASE_TIMELINE_ATOMS_SUBMITTED(kctx, js, count) CSTD_NOP()
303 #define KBASE_TIMELINE_JOB_START_NEXT(kctx, js, count) CSTD_NOP()
305 #define KBASE_TIMELINE_JOB_START_HEAD(kctx, js, count) CSTD_NOP()
307 #define KBASE_TIMELINE_TRY_SOFT_STOP(kctx, js, count) CSTD_NOP()
309 #define KBASE_TIMELINE_GPU_POWER(kbdev, active) CSTD_NOP()
311 #define KBASE_TIMELINE_POWER_TILER(kbdev, bitmap) CSTD_NOP()
313 #define KBASE_TIMELINE_POWER_SHADER(kbdev, bitmap) CSTD_NOP()
315 #define KBASE_TIMELINE_POWER_L2(kbdev, active) CSTD_NOP()
317 #define KBASE_TIMELINE_POWERING_L2(kbdev) CSTD_NOP()
319 #define KBASE_TIMELINE_POWERED_L2(kbdev) CSTD_NOP()
321 #define KBASE_TIMELINE_PM_SEND_EVENT(kbdev, event_type, pm_event_id) CSTD_NOP()
323 #define KBASE_TIMELINE_PM_HANDLE_EVENT(kbdev, event_type, pm_event_id) CSTD_NOP()
325 #define KBASE_TIMELINE_JOB_START(kctx, js, _consumerof_atom_number) CSTD_NOP()
327 #define KBASE_TIMELINE_JOB_STOP(kctx, js, _producerof_atom_number_completed) CSTD_NOP()
329 #define KBASE_TIMELINE_PM_CHECKTRANS(kbdev, trace_code) CSTD_NOP()
331 static INLINE void kbase_timeline_job_slot_submit(kbase_device *kbdev, kbase_context *kctx,
332 kbase_jd_atom *katom, int js)
334 lockdep_assert_held(&kbdev->js_data.runpool_irq.lock);
337 static INLINE void kbase_timeline_job_slot_done(kbase_device *kbdev, kbase_context *kctx,
338 kbase_jd_atom *katom, int js,
339 kbasep_js_atom_done_code done_code)
341 lockdep_assert_held(&kbdev->js_data.runpool_irq.lock);
344 static INLINE void kbase_timeline_pm_send_event(kbase_device *kbdev, kbase_timeline_pm_event event_sent)
348 static INLINE void kbase_timeline_pm_check_handle_event(kbase_device *kbdev, kbase_timeline_pm_event event)
352 static INLINE void kbase_timeline_pm_handle_event(kbase_device *kbdev, kbase_timeline_pm_event event)
356 static INLINE void kbase_timeline_pm_l2_transition_start(kbase_device *kbdev)
361 static INLINE void kbase_timeline_pm_l2_transition_done(kbase_device *kbdev)
365 #endif /* CONFIG_MALI_TRACE_TIMELINE */
367 #endif /* _KBASE_TRACE_TIMELINE_H */