uart...
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / gpu / mt8127 / mediatek / mtk_mali_trace.c
1 #include <linux/kallsyms.h>
2 #include <linux/cache.h>
3 #include <linux/ftrace_event.h>
4 #include <linux/workqueue.h>
5 #include <linux/kthread.h>
6 #include "mtk_mali_trace.h"
7
8 static struct task_struct *gTraceThread[MTK_MALI_MAX_CORE_COUNT]; // Trace task
9 static wait_queue_head_t gTraceQueue[MTK_MALI_MAX_CORE_COUNT]; // Trace queue
10 static mtk_mali_trace_work gTraceEvent[MTK_MALI_MAX_CORE_COUNT]; // Trace event
11 static spinlock_t gThreadLock[MTK_MALI_MAX_CORE_COUNT]; // Trace lock
12
13 // Mark address
14 static unsigned long __read_mostly gMarkWriteAddr = 0;
15
16
17 static void inline mali_update_write_addr(void)
18 {
19 #if 0
20 if(unlikely(0 == gMarkWriteAddr))
21 {
22 gMarkWriteAddr = kallsyms_lookup_name("tracing_mark_write");
23 }
24 #endif // 0
25 }
26
27
28 static void mali_kernel_trace_begin(char *pName)
29 {
30 #if 0
31 mali_update_write_addr();
32
33 event_trace_printk(gMarkWriteAddr,
34 "B|%d|%s\n",
35 current->tgid, pName);
36 #endif // 0
37 }
38
39
40 static void mali_kernel_trace_counter(char *pName, int count)
41 {
42 #if 0
43 mali_update_write_addr();
44
45 event_trace_printk(gMarkWriteAddr,
46 "C|%d|%s|%d\n",
47 (in_interrupt()? -1: current->tgid),
48 pName,
49 count);
50 #endif // 0
51 }
52
53
54 static void mali_kernel_trace_end(void)
55 {
56 #if 0
57 mali_update_write_addr();
58
59 event_trace_printk(gMarkWriteAddr,
60 "E\n");
61 #endif // 0
62 }
63
64
65 static inline int mali_core_index_to_event_id(MALI_CORE_ENUM coreType,
66 int index,
67 int traceType)
68 {
69 int eventID;
70
71 eventID = 0;
72
73 switch(coreType)
74 {
75 case MALI_CORE_TYPE_GP:
76 eventID = ((1 == traceType)? 0: 1);
77 break;
78 case MALI_CORE_TYPE_PP:
79 if (0 == index)
80 {
81 eventID = ((1 == traceType)? 2: 3);
82 }
83 else
84 {
85 eventID = ((1 == traceType)? 4: 5);
86 }
87 break;
88 default:
89 // assert(0);
90 break;
91 }
92
93 return eventID;
94 }
95
96
97 static inline int mali_core_index_to_core_id(MALI_CORE_ENUM coreType,
98 int index)
99 {
100 int coreID;
101
102 coreID = 0;
103
104 switch(coreType)
105 {
106 case MALI_CORE_TYPE_GP:
107 coreID = 0;
108 break;
109 case MALI_CORE_TYPE_PP:
110 coreID = ((0 == index)? 1: 2);
111 break;
112 default:
113 // assert(0);
114 break;
115 }
116
117 return coreID;
118 }
119
120
121 static inline int mali_core_id_to_core_name(int coreID)
122 {
123 static const char *pName[] =
124 {
125 "MALI_GP0",
126 "MALI_PP0",
127 "MALI_PP1"
128 };
129
130 switch(coreID)
131 {
132 case 0:
133 case 1:
134 case 2:
135 return pName[coreID];
136 default:
137 // assert(0);
138 break;
139 }
140
141 return "MALI_ERR";
142 }
143
144
145 static int mtk_mali_trace_handler(struct mtk_mali_trace_work *pWork)
146 {
147 struct task_struct *pTask;
148 struct sched_param param;;
149 long flags;
150 int coreID;
151 int eventID;
152 char *pName;
153
154 pTask = current;
155
156 //sched_getparam(0, &param);
157 memset(&param, 0, sizeof(param));
158 param.sched_priority = 90;
159 sched_setscheduler(pTask, SCHED_RR, &param);
160
161 coreID = pWork->coreID;
162
163 do
164 {
165 wait_event_interruptible(gTraceQueue[coreID], ((pWork->total > 0) || (1 == pWork->stop)));
166
167 if(kthread_should_stop() || (1 == pWork->stop))
168 {
169 break;
170 }
171
172 spin_lock_irqsave(&gThreadLock[coreID], flags);
173
174 smp_mb();
175
176 if (pWork->total <= 0)
177 {
178 spin_unlock_irqrestore(&gThreadLock[coreID], flags);
179 continue;
180 }
181
182 eventID = pWork->event[pWork->read].theID;
183 pName = pWork->event[pWork->read].name;
184 pWork->read++;
185 if (pWork->read >= MTK_MALI_MAX_QUEUE_SIZE)
186 {
187 pWork->read = 0;
188 }
189
190 pWork->total--;
191 spin_unlock_irqrestore(&gThreadLock[coreID], flags);
192
193 switch(eventID)
194 {
195 case 0: // GP0 begin
196 mali_kernel_trace_begin(pName);
197 break;
198 case 1: // GP0 end
199 mali_kernel_trace_end();
200 break;
201 case 2: // PP0 begin
202 mali_kernel_trace_begin(pName);
203 break;
204 case 3: // PP0 end
205 mali_kernel_trace_end();
206 break;
207 case 4: // PP1 begin
208 mali_kernel_trace_begin(pName);
209 break;
210 case 5: // PP1 end
211 mali_kernel_trace_end();
212 break;
213 break;
214 //assert(0);
215 break;
216 }
217 } while(1);
218
219 return 0;
220 }
221
222
223 int mtk_mali_kernel_trace_init(void)
224 {
225 int index;
226 char *pName;
227
228 for (index = 0; index < MTK_MALI_MAX_CORE_COUNT; index++)
229 {
230 init_waitqueue_head(&gTraceQueue[index]);
231
232 memset(&gTraceEvent[index], 0x0, sizeof(mtk_mali_trace_work));
233
234 // Record the core ID
235 gTraceEvent[index].coreID = index;
236
237 spin_lock_init(&gThreadLock[index]);
238
239 gTraceThread[index] = kthread_run(mtk_mali_trace_handler,
240 &gTraceEvent[index],
241 "%s",
242 mali_core_id_to_core_name(index));
243 if(IS_ERR(gTraceThread[index]))
244 {
245 printk("Unable to start kernel thread for core%d\n", index);
246 }
247 }
248
249 return 0;
250 }
251
252
253 void mtk_mali_kernel_trace_begin(MALI_CORE_ENUM coreType,
254 int index,
255 struct task_struct *pTask)
256 {
257 long flags;
258 int coreID;
259 int eventID;
260 int slotID;
261
262 coreID = mali_core_index_to_core_id(coreType, index);
263 eventID = mali_core_index_to_event_id(coreType, index, 1);
264
265 if (eventID < MTK_MALI_MAX_EVENT_COUNT)
266 {
267 spin_lock_irqsave(&gThreadLock[coreID], flags);
268
269 smp_mb();
270
271 slotID = gTraceEvent[coreID].write;
272 gTraceEvent[coreID].write++;
273 if (gTraceEvent[coreID].write >= MTK_MALI_MAX_QUEUE_SIZE)
274 {
275 gTraceEvent[coreID].write = 0;
276 }
277
278 gTraceEvent[coreID].total++;
279 spin_unlock_irqrestore(&gThreadLock[coreID], flags);
280
281 gTraceEvent[coreID].event[slotID].theID = eventID;
282 memcpy(gTraceEvent[coreID].event[slotID].name, pTask->comm, sizeof(current->comm));
283
284 wake_up_interruptible(&gTraceQueue[coreID]);
285 }
286 }
287
288
289 void mtk_mali_kernel_trace_end(MALI_CORE_ENUM coreType,
290 int index)
291 {
292 long flags;
293 int coreID;
294 int eventID;
295 int slotID;
296
297 coreID = mali_core_index_to_core_id(coreType, index);
298 eventID = mali_core_index_to_event_id(coreType, index, 0);
299
300 if (eventID < MTK_MALI_MAX_EVENT_COUNT)
301 {
302 spin_lock_irqsave(&gThreadLock[coreID], flags);
303
304 smp_mb();
305
306 slotID = gTraceEvent[coreID].write;
307 gTraceEvent[coreID].write++;
308 if (gTraceEvent[coreID].write >= MTK_MALI_MAX_QUEUE_SIZE)
309 {
310 gTraceEvent[coreID].write = 0;
311 }
312
313 gTraceEvent[coreID].total++;
314 spin_unlock_irqrestore(&gThreadLock[coreID], flags);
315
316 gTraceEvent[coreID].event[slotID].theID = eventID;
317
318 wake_up_interruptible(&gTraceQueue[coreID]);
319 }
320 }
321
322
323 int mtk_mali_kernel_trace_exit()
324 {
325 int index;
326
327 for (index = 0; index < MTK_MALI_MAX_CORE_COUNT; index++)
328 {
329 gTraceEvent[index].stop = 1;
330 kthread_stop(gTraceThread[index]);
331 }
332
333 return 0;
334 }