Commit | Line | Data |
---|---|---|
d25bc64b JY |
1 | /* |
2 | * | |
51f89798 | 3 | * (C) COPYRIGHT 2012-2016 ARM Limited. All rights reserved. |
d25bc64b JY |
4 | * |
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 | |
8 | * of such GNU licence. | |
9 | * | |
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. | |
13 | * | |
14 | */ | |
15 | ||
16 | ||
17 | ||
18 | ||
19 | ||
20 | #if !defined(_KBASE_TRACE_TIMELINE_H) | |
21 | #define _KBASE_TRACE_TIMELINE_H | |
22 | ||
23 | #ifdef CONFIG_MALI_TRACE_TIMELINE | |
24 | ||
25 | enum kbase_trace_timeline_code { | |
26 | #define KBASE_TIMELINE_TRACE_CODE(enum_val, desc, format, format_desc) enum_val | |
27 | #include "mali_kbase_trace_timeline_defs.h" | |
28 | #undef KBASE_TIMELINE_TRACE_CODE | |
29 | }; | |
30 | ||
dd8e48ad JY |
31 | #ifdef CONFIG_DEBUG_FS |
32 | ||
d25bc64b JY |
33 | /** Initialize Timeline DebugFS entries */ |
34 | void kbasep_trace_timeline_debugfs_init(struct kbase_device *kbdev); | |
35 | ||
dd8e48ad JY |
36 | #else /* CONFIG_DEBUG_FS */ |
37 | ||
38 | #define kbasep_trace_timeline_debugfs_init CSTD_NOP | |
39 | ||
40 | #endif /* CONFIG_DEBUG_FS */ | |
41 | ||
d25bc64b JY |
42 | /* mali_timeline.h defines kernel tracepoints used by the KBASE_TIMELINE |
43 | * functions. | |
44 | * Output is timestamped by either sched_clock() (default), local_clock(), or | |
45 | * cpu_clock(), depending on /sys/kernel/debug/tracing/trace_clock */ | |
46 | #include "mali_timeline.h" | |
47 | ||
48 | /* Trace number of atoms in flight for kctx (atoms either not completed, or in | |
49 | process of being returned to user */ | |
50 | #define KBASE_TIMELINE_ATOMS_IN_FLIGHT(kctx, count) \ | |
51 | do { \ | |
52 | struct timespec ts; \ | |
53 | getrawmonotonic(&ts); \ | |
54 | trace_mali_timeline_atoms_in_flight(ts.tv_sec, ts.tv_nsec, \ | |
55 | (int)kctx->timeline.owner_tgid, \ | |
56 | count); \ | |
57 | } while (0) | |
58 | ||
59 | /* Trace atom_id being Ready to Run */ | |
60 | #define KBASE_TIMELINE_ATOM_READY(kctx, atom_id) \ | |
61 | do { \ | |
62 | struct timespec ts; \ | |
63 | getrawmonotonic(&ts); \ | |
64 | trace_mali_timeline_atom(ts.tv_sec, ts.tv_nsec, \ | |
65 | CTX_FLOW_ATOM_READY, \ | |
66 | (int)kctx->timeline.owner_tgid, \ | |
67 | atom_id); \ | |
68 | } while (0) | |
69 | ||
70 | /* Trace number of atoms submitted to job slot js | |
71 | * | |
72 | * NOTE: This uses a different tracepoint to the head/next/soft-stop actions, | |
73 | * so that those actions can be filtered out separately from this | |
74 | * | |
75 | * This is because this is more useful, as we can use it to calculate general | |
76 | * utilization easily and accurately */ | |
77 | #define KBASE_TIMELINE_ATOMS_SUBMITTED(kctx, js, count) \ | |
78 | do { \ | |
79 | struct timespec ts; \ | |
80 | getrawmonotonic(&ts); \ | |
81 | trace_mali_timeline_gpu_slot_active(ts.tv_sec, ts.tv_nsec, \ | |
82 | SW_SET_GPU_SLOT_ACTIVE, \ | |
83 | (int)kctx->timeline.owner_tgid, \ | |
84 | js, count); \ | |
85 | } while (0) | |
86 | ||
87 | ||
88 | /* Trace atoms present in JS_NEXT */ | |
89 | #define KBASE_TIMELINE_JOB_START_NEXT(kctx, js, count) \ | |
90 | do { \ | |
91 | struct timespec ts; \ | |
92 | getrawmonotonic(&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, \ | |
96 | js, count); \ | |
97 | } while (0) | |
98 | ||
99 | /* Trace atoms present in JS_HEAD */ | |
100 | #define KBASE_TIMELINE_JOB_START_HEAD(kctx, js, count) \ | |
101 | do { \ | |
102 | struct timespec ts; \ | |
103 | getrawmonotonic(&ts); \ | |
104 | trace_mali_timeline_gpu_slot_action(ts.tv_sec, ts.tv_nsec, \ | |
105 | SW_SET_GPU_SLOT_HEAD, \ | |
106 | (int)kctx->timeline.owner_tgid, \ | |
107 | js, count); \ | |
108 | } while (0) | |
109 | ||
110 | /* Trace that a soft stop/evict from next is being attempted on a slot */ | |
111 | #define KBASE_TIMELINE_TRY_SOFT_STOP(kctx, js, count) \ | |
112 | do { \ | |
113 | struct timespec ts; \ | |
114 | getrawmonotonic(&ts); \ | |
115 | trace_mali_timeline_gpu_slot_action(ts.tv_sec, ts.tv_nsec, \ | |
116 | SW_SET_GPU_SLOT_STOPPING, \ | |
117 | (kctx) ? (int)kctx->timeline.owner_tgid : 0, \ | |
118 | js, count); \ | |
119 | } while (0) | |
120 | ||
121 | ||
122 | ||
123 | /* Trace state of overall GPU power */ | |
124 | #define KBASE_TIMELINE_GPU_POWER(kbdev, active) \ | |
125 | do { \ | |
126 | struct timespec ts; \ | |
127 | getrawmonotonic(&ts); \ | |
128 | trace_mali_timeline_gpu_power_active(ts.tv_sec, ts.tv_nsec, \ | |
129 | SW_SET_GPU_POWER_ACTIVE, active); \ | |
130 | } while (0) | |
131 | ||
132 | /* Trace state of tiler power */ | |
133 | #define KBASE_TIMELINE_POWER_TILER(kbdev, bitmap) \ | |
134 | do { \ | |
135 | struct timespec ts; \ | |
136 | getrawmonotonic(&ts); \ | |
137 | trace_mali_timeline_gpu_power_active(ts.tv_sec, ts.tv_nsec, \ | |
138 | SW_SET_GPU_POWER_TILER_ACTIVE, \ | |
139 | hweight64(bitmap)); \ | |
140 | } while (0) | |
141 | ||
142 | /* Trace number of shaders currently powered */ | |
143 | #define KBASE_TIMELINE_POWER_SHADER(kbdev, bitmap) \ | |
144 | do { \ | |
145 | struct timespec ts; \ | |
146 | getrawmonotonic(&ts); \ | |
147 | trace_mali_timeline_gpu_power_active(ts.tv_sec, ts.tv_nsec, \ | |
148 | SW_SET_GPU_POWER_SHADER_ACTIVE, \ | |
149 | hweight64(bitmap)); \ | |
150 | } while (0) | |
151 | ||
152 | /* Trace state of L2 power */ | |
153 | #define KBASE_TIMELINE_POWER_L2(kbdev, bitmap) \ | |
154 | do { \ | |
155 | struct timespec ts; \ | |
156 | getrawmonotonic(&ts); \ | |
157 | trace_mali_timeline_gpu_power_active(ts.tv_sec, ts.tv_nsec, \ | |
158 | SW_SET_GPU_POWER_L2_ACTIVE, \ | |
159 | hweight64(bitmap)); \ | |
160 | } while (0) | |
161 | ||
162 | /* Trace state of L2 cache*/ | |
163 | #define KBASE_TIMELINE_POWERING_L2(kbdev) \ | |
164 | do { \ | |
165 | struct timespec ts; \ | |
166 | getrawmonotonic(&ts); \ | |
167 | trace_mali_timeline_l2_power_active(ts.tv_sec, ts.tv_nsec, \ | |
168 | SW_FLOW_GPU_POWER_L2_POWERING, \ | |
169 | 1); \ | |
170 | } while (0) | |
171 | ||
172 | #define KBASE_TIMELINE_POWERED_L2(kbdev) \ | |
173 | do { \ | |
174 | struct timespec ts; \ | |
175 | getrawmonotonic(&ts); \ | |
176 | trace_mali_timeline_l2_power_active(ts.tv_sec, ts.tv_nsec, \ | |
177 | SW_FLOW_GPU_POWER_L2_ACTIVE, \ | |
178 | 1); \ | |
179 | } while (0) | |
180 | ||
181 | /* Trace kbase_pm_send_event message send */ | |
182 | #define KBASE_TIMELINE_PM_SEND_EVENT(kbdev, event_type, pm_event_id) \ | |
183 | do { \ | |
184 | struct timespec ts; \ | |
185 | getrawmonotonic(&ts); \ | |
186 | trace_mali_timeline_pm_event(ts.tv_sec, ts.tv_nsec, \ | |
187 | SW_FLOW_PM_SEND_EVENT, \ | |
188 | event_type, pm_event_id); \ | |
189 | } while (0) | |
190 | ||
191 | /* Trace kbase_pm_worker message receive */ | |
192 | #define KBASE_TIMELINE_PM_HANDLE_EVENT(kbdev, event_type, pm_event_id) \ | |
193 | do { \ | |
194 | struct timespec ts; \ | |
195 | getrawmonotonic(&ts); \ | |
196 | trace_mali_timeline_pm_event(ts.tv_sec, ts.tv_nsec, \ | |
197 | SW_FLOW_PM_HANDLE_EVENT, \ | |
198 | event_type, pm_event_id); \ | |
199 | } while (0) | |
200 | ||
201 | ||
202 | /* Trace atom_id starting in JS_HEAD */ | |
203 | #define KBASE_TIMELINE_JOB_START(kctx, js, _consumerof_atom_number) \ | |
204 | do { \ | |
205 | struct timespec ts; \ | |
206 | getrawmonotonic(&ts); \ | |
207 | trace_mali_timeline_slot_atom(ts.tv_sec, ts.tv_nsec, \ | |
208 | HW_START_GPU_JOB_CHAIN_SW_APPROX, \ | |
209 | (int)kctx->timeline.owner_tgid, \ | |
210 | js, _consumerof_atom_number); \ | |
211 | } while (0) | |
212 | ||
213 | /* Trace atom_id stopping on JS_HEAD */ | |
214 | #define KBASE_TIMELINE_JOB_STOP(kctx, js, _producerof_atom_number_completed) \ | |
215 | do { \ | |
216 | struct timespec ts; \ | |
217 | getrawmonotonic(&ts); \ | |
218 | trace_mali_timeline_slot_atom(ts.tv_sec, ts.tv_nsec, \ | |
219 | HW_STOP_GPU_JOB_CHAIN_SW_APPROX, \ | |
220 | (int)kctx->timeline.owner_tgid, \ | |
221 | js, _producerof_atom_number_completed); \ | |
222 | } while (0) | |
223 | ||
d25bc64b JY |
224 | /** Trace beginning/end of a call to kbase_pm_check_transitions_nolock from a |
225 | * certin caller */ | |
226 | #define KBASE_TIMELINE_PM_CHECKTRANS(kbdev, trace_code) \ | |
227 | do { \ | |
228 | struct timespec ts; \ | |
229 | getrawmonotonic(&ts); \ | |
230 | trace_mali_timeline_pm_checktrans(ts.tv_sec, ts.tv_nsec, \ | |
231 | trace_code, 1); \ | |
232 | } while (0) | |
233 | ||
234 | /* Trace number of contexts active */ | |
235 | #define KBASE_TIMELINE_CONTEXT_ACTIVE(kbdev, count) \ | |
236 | do { \ | |
237 | struct timespec ts; \ | |
238 | getrawmonotonic(&ts); \ | |
239 | trace_mali_timeline_context_active(ts.tv_sec, ts.tv_nsec, \ | |
240 | count); \ | |
241 | } while (0) | |
242 | ||
d25bc64b JY |
243 | /* NOTE: kbase_timeline_pm_cores_func() is in mali_kbase_pm_policy.c */ |
244 | ||
245 | /** | |
246 | * Trace that an atom is starting on a job slot | |
247 | * | |
dd8e48ad | 248 | * The caller must be holding hwaccess_lock |
d25bc64b JY |
249 | */ |
250 | void kbase_timeline_job_slot_submit(struct kbase_device *kbdev, struct kbase_context *kctx, | |
251 | struct kbase_jd_atom *katom, int js); | |
252 | ||
253 | /** | |
254 | * Trace that an atom has done on a job slot | |
255 | * | |
256 | * 'Done' in this sense can occur either because: | |
257 | * - the atom in JS_HEAD finished | |
258 | * - the atom in JS_NEXT was evicted | |
259 | * | |
260 | * Whether the atom finished or was evicted is passed in @a done_code | |
261 | * | |
262 | * It is assumed that the atom has already been removed from the submit slot, | |
263 | * with either: | |
264 | * - kbasep_jm_dequeue_submit_slot() | |
265 | * - kbasep_jm_dequeue_tail_submit_slot() | |
266 | * | |
dd8e48ad | 267 | * The caller must be holding hwaccess_lock |
d25bc64b JY |
268 | */ |
269 | void kbase_timeline_job_slot_done(struct kbase_device *kbdev, struct kbase_context *kctx, | |
270 | struct kbase_jd_atom *katom, int js, | |
271 | kbasep_js_atom_done_code done_code); | |
272 | ||
273 | ||
274 | /** Trace a pm event starting */ | |
275 | void kbase_timeline_pm_send_event(struct kbase_device *kbdev, | |
276 | enum kbase_timeline_pm_event event_sent); | |
277 | ||
278 | /** Trace a pm event finishing */ | |
279 | void kbase_timeline_pm_check_handle_event(struct kbase_device *kbdev, enum kbase_timeline_pm_event event); | |
280 | ||
281 | /** Check whether a pm event was present, and if so trace finishing it */ | |
282 | void kbase_timeline_pm_handle_event(struct kbase_device *kbdev, enum kbase_timeline_pm_event event); | |
283 | ||
284 | /** Trace L2 power-up start */ | |
285 | void kbase_timeline_pm_l2_transition_start(struct kbase_device *kbdev); | |
286 | ||
287 | /** Trace L2 power-up done */ | |
288 | void kbase_timeline_pm_l2_transition_done(struct kbase_device *kbdev); | |
289 | ||
290 | #else | |
291 | ||
292 | #define KBASE_TIMELINE_ATOMS_IN_FLIGHT(kctx, count) CSTD_NOP() | |
293 | ||
294 | #define KBASE_TIMELINE_ATOM_READY(kctx, atom_id) CSTD_NOP() | |
295 | ||
296 | #define KBASE_TIMELINE_ATOMS_SUBMITTED(kctx, js, count) CSTD_NOP() | |
297 | ||
298 | #define KBASE_TIMELINE_JOB_START_NEXT(kctx, js, count) CSTD_NOP() | |
299 | ||
300 | #define KBASE_TIMELINE_JOB_START_HEAD(kctx, js, count) CSTD_NOP() | |
301 | ||
302 | #define KBASE_TIMELINE_TRY_SOFT_STOP(kctx, js, count) CSTD_NOP() | |
303 | ||
304 | #define KBASE_TIMELINE_GPU_POWER(kbdev, active) CSTD_NOP() | |
305 | ||
306 | #define KBASE_TIMELINE_POWER_TILER(kbdev, bitmap) CSTD_NOP() | |
307 | ||
308 | #define KBASE_TIMELINE_POWER_SHADER(kbdev, bitmap) CSTD_NOP() | |
309 | ||
310 | #define KBASE_TIMELINE_POWER_L2(kbdev, active) CSTD_NOP() | |
311 | ||
312 | #define KBASE_TIMELINE_POWERING_L2(kbdev) CSTD_NOP() | |
313 | ||
314 | #define KBASE_TIMELINE_POWERED_L2(kbdev) CSTD_NOP() | |
315 | ||
316 | #define KBASE_TIMELINE_PM_SEND_EVENT(kbdev, event_type, pm_event_id) CSTD_NOP() | |
317 | ||
318 | #define KBASE_TIMELINE_PM_HANDLE_EVENT(kbdev, event_type, pm_event_id) CSTD_NOP() | |
319 | ||
320 | #define KBASE_TIMELINE_JOB_START(kctx, js, _consumerof_atom_number) CSTD_NOP() | |
321 | ||
322 | #define KBASE_TIMELINE_JOB_STOP(kctx, js, _producerof_atom_number_completed) CSTD_NOP() | |
323 | ||
324 | #define KBASE_TIMELINE_PM_CHECKTRANS(kbdev, trace_code) CSTD_NOP() | |
325 | ||
326 | #define KBASE_TIMELINE_CONTEXT_ACTIVE(kbdev, count) CSTD_NOP() | |
327 | ||
d25bc64b JY |
328 | static inline void kbase_timeline_job_slot_submit(struct kbase_device *kbdev, struct kbase_context *kctx, |
329 | struct kbase_jd_atom *katom, int js) | |
330 | { | |
dd8e48ad | 331 | lockdep_assert_held(&kbdev->hwaccess_lock); |
d25bc64b JY |
332 | } |
333 | ||
334 | static inline void kbase_timeline_job_slot_done(struct kbase_device *kbdev, struct kbase_context *kctx, | |
335 | struct kbase_jd_atom *katom, int js, | |
336 | kbasep_js_atom_done_code done_code) | |
337 | { | |
dd8e48ad | 338 | lockdep_assert_held(&kbdev->hwaccess_lock); |
d25bc64b JY |
339 | } |
340 | ||
341 | static inline void kbase_timeline_pm_send_event(struct kbase_device *kbdev, enum kbase_timeline_pm_event event_sent) | |
342 | { | |
343 | } | |
344 | ||
345 | static inline void kbase_timeline_pm_check_handle_event(struct kbase_device *kbdev, enum kbase_timeline_pm_event event) | |
346 | { | |
347 | } | |
348 | ||
349 | static inline void kbase_timeline_pm_handle_event(struct kbase_device *kbdev, enum kbase_timeline_pm_event event) | |
350 | { | |
351 | } | |
352 | ||
353 | static inline void kbase_timeline_pm_l2_transition_start(struct kbase_device *kbdev) | |
354 | { | |
355 | } | |
356 | ||
357 | static inline void kbase_timeline_pm_l2_transition_done(struct kbase_device *kbdev) | |
358 | { | |
359 | } | |
360 | #endif /* CONFIG_MALI_TRACE_TIMELINE */ | |
361 | ||
362 | #endif /* _KBASE_TRACE_TIMELINE_H */ | |
363 |