1 /**
2 * Copyright (C) ARM Limited 2010-2012. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
9 #include "gator.h"
11 #include <linux/slab.h>
12 #include <linux/module.h>
13 #include <linux/time.h>
14 #include <linux/math64.h>
16 #ifdef MALI_SUPPORT
17 #include "linux/mali_linux_trace.h"
18 #endif
19 #include "gator_trace_gpu.h"
21 #define ACTIVITY_START 1
22 #define ACTIVITY_STOP 2
24 /* Note whether tracepoints have been registered */
25 static int mali_trace_registered;
26 static int gpu_trace_registered;
28 #define GPU_START 1
29 #define GPU_STOP 2
31 #define GPU_UNIT_VP 1
32 #define GPU_UNIT_FP 2
33 #define GPU_UNIT_CL 3
35 #ifdef MALI_SUPPORT
37 enum components {
38 COMPONENT_VP0 = 1,
39 COMPONENT_FP0 = 5,
40 COMPONENT_FP1,
41 COMPONENT_FP2,
42 COMPONENT_FP3,
43 COMPONENT_FP4,
44 COMPONENT_FP5,
45 COMPONENT_FP6,
46 COMPONENT_FP7,
47 };
49 GATOR_DEFINE_PROBE(mali_timeline_event, TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, unsigned int d2, unsigned int d3, unsigned int d4))
50 {
51 unsigned int component, state;
52 int tgid = 0, pid = 0;
54 // do as much work as possible before disabling interrupts
55 component = (event_id >> 16) & 0xFF; // component is an 8-bit field
56 state = (event_id >> 24) & 0xF; // state is a 4-bit field
58 if ((component == COMPONENT_VP0) || (component >= COMPONENT_FP0 && component <= COMPONENT_FP7)) {
59 if (state == ACTIVITY_START || state == ACTIVITY_STOP) {
60 unsigned int type = (state == ACTIVITY_START) ? GPU_START : GPU_STOP;
61 unsigned int unit = (component < COMPONENT_FP0) ? GPU_UNIT_VP : GPU_UNIT_FP;
62 unsigned int core = (component < COMPONENT_FP0) ? component - COMPONENT_VP0 : component - COMPONENT_FP0;
63 if (state == ACTIVITY_START) {
64 tgid = d0;
65 pid = d1;
66 }
68 marshal_sched_gpu(type, unit, core, tgid, pid);
69 }
70 }
71 }
72 #endif
74 GATOR_DEFINE_PROBE(gpu_activity_start, TP_PROTO(int gpu_unit, int gpu_core, struct task_struct *p))
75 {
76 marshal_sched_gpu(GPU_START, gpu_unit, gpu_core, (int)p->tgid, (int)p->pid);
77 }
79 GATOR_DEFINE_PROBE(gpu_activity_stop, TP_PROTO(int gpu_unit, int gpu_core))
80 {
81 marshal_sched_gpu(GPU_STOP, gpu_unit, gpu_core, 0, 0);
82 }
84 int gator_trace_gpu_start(void)
85 {
86 /*
87 * Returns nonzero for installation failed
88 * Absence of gpu trace points is not an error
89 */
91 gpu_trace_registered = mali_trace_registered = 0;
93 #ifdef MALI_SUPPORT
94 if (!GATOR_REGISTER_TRACE(mali_timeline_event)) {
95 mali_trace_registered = 1;
96 }
97 #endif
99 if (!mali_trace_registered) {
100 if (GATOR_REGISTER_TRACE(gpu_activity_start)) {
101 return 0;
102 }
103 if (GATOR_REGISTER_TRACE(gpu_activity_stop)) {
104 GATOR_UNREGISTER_TRACE(gpu_activity_start);
105 return 0;
106 }
107 gpu_trace_registered = 1;
108 }
110 return 0;
111 }
113 void gator_trace_gpu_stop(void)
114 {
115 #ifdef MALI_SUPPORT
116 if (mali_trace_registered) {
117 GATOR_UNREGISTER_TRACE(mali_timeline_event);
118 }
119 #endif
120 if (gpu_trace_registered) {
121 GATOR_UNREGISTER_TRACE(gpu_activity_stop);
122 GATOR_UNREGISTER_TRACE(gpu_activity_start);
123 }
125 gpu_trace_registered = mali_trace_registered = 0;
126 }