rk fb: update pixclock init value and scale mode only support ONE_DUAL mode
[firefly-linux-kernel-4.4.55.git] / drivers / gator / gator_marshaling.c
1 /**
2  * Copyright (C) ARM Limited 2012-2014. 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  *
8  */
9
10 #define NEWLINE_CANARY \
11         /* Unix */ \
12         "1\n" \
13         /* Windows */ \
14         "2\r\n" \
15         /* Mac OS */ \
16         "3\r" \
17         /* RISC OS */ \
18         "4\n\r" \
19         /* Add another character so the length isn't 0x0a bytes */ \
20         "5"
21
22 #ifdef MALI_SUPPORT
23 #include "gator_events_mali_common.h"
24 #endif
25
26 static void marshal_summary(long long timestamp, long long uptime, long long monotonic_delta, const char *uname)
27 {
28         unsigned long flags;
29         int cpu = 0;
30
31         local_irq_save(flags);
32         gator_buffer_write_packed_int(cpu, SUMMARY_BUF, MESSAGE_SUMMARY);
33         gator_buffer_write_string(cpu, SUMMARY_BUF, NEWLINE_CANARY);
34         gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, timestamp);
35         gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, uptime);
36         gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, monotonic_delta);
37         gator_buffer_write_string(cpu, SUMMARY_BUF, "uname");
38         gator_buffer_write_string(cpu, SUMMARY_BUF, uname);
39 #if GATOR_IKS_SUPPORT
40         gator_buffer_write_string(cpu, SUMMARY_BUF, "iks");
41         gator_buffer_write_string(cpu, SUMMARY_BUF, "");
42 #endif
43 #ifdef CONFIG_PREEMPT_RTB
44         gator_buffer_write_string(cpu, SUMMARY_BUF, "preempt_rtb");
45         gator_buffer_write_string(cpu, SUMMARY_BUF, "");
46 #endif
47 #ifdef CONFIG_PREEMPT_RT_FULL
48         gator_buffer_write_string(cpu, SUMMARY_BUF, "preempt_rt_full");
49         gator_buffer_write_string(cpu, SUMMARY_BUF, "");
50 #endif
51         /* Let Streamline know which GPU is used so that it can label the GPU Activity appropriately. This is a temporary fix, to be improved in a future release. */
52 #ifdef MALI_SUPPORT
53         gator_buffer_write_string(cpu, SUMMARY_BUF, "mali_type");
54 #if (MALI_SUPPORT == MALI_4xx)
55         gator_buffer_write_string(cpu, SUMMARY_BUF, "4xx");
56 #elif (MALI_SUPPORT == MALI_MIDGARD)
57         gator_buffer_write_string(cpu, SUMMARY_BUF, "6xx");
58 #else
59         gator_buffer_write_string(cpu, SUMMARY_BUF, "unknown");
60 #endif
61 #endif
62         gator_buffer_write_string(cpu, SUMMARY_BUF, "");
63         /* Commit the buffer now so it can be one of the first frames read by Streamline */
64         local_irq_restore(flags);
65         gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time());
66 }
67
68 static bool marshal_cookie_header(const char *text)
69 {
70         int cpu = get_physical_cpu();
71
72         return buffer_check_space(cpu, NAME_BUF, strlen(text) + 3 * MAXSIZE_PACK32);
73 }
74
75 static void marshal_cookie(int cookie, const char *text)
76 {
77         int cpu = get_physical_cpu();
78         /* buffer_check_space already called by marshal_cookie_header */
79         gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_COOKIE);
80         gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
81         gator_buffer_write_string(cpu, NAME_BUF, text);
82         buffer_check(cpu, NAME_BUF, gator_get_time());
83 }
84
85 static void marshal_thread_name(int pid, char *name)
86 {
87         unsigned long flags, cpu;
88         u64 time;
89
90         local_irq_save(flags);
91         cpu = get_physical_cpu();
92         time = gator_get_time();
93         if (buffer_check_space(cpu, NAME_BUF, TASK_COMM_LEN + 3 * MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
94                 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_THREAD_NAME);
95                 gator_buffer_write_packed_int64(cpu, NAME_BUF, time);
96                 gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
97                 gator_buffer_write_string(cpu, NAME_BUF, name);
98         }
99         local_irq_restore(flags);
100         buffer_check(cpu, NAME_BUF, time);
101 }
102
103 static void marshal_link(int cookie, int tgid, int pid)
104 {
105         unsigned long cpu = get_physical_cpu(), flags;
106         u64 time;
107
108         local_irq_save(flags);
109         time = gator_get_time();
110         if (buffer_check_space(cpu, NAME_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
111                 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_LINK);
112                 gator_buffer_write_packed_int64(cpu, NAME_BUF, time);
113                 gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
114                 gator_buffer_write_packed_int(cpu, NAME_BUF, tgid);
115                 gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
116         }
117         local_irq_restore(flags);
118         /* Check and commit; commit is set to occur once buffer is 3/4 full */
119         buffer_check(cpu, NAME_BUF, time);
120 }
121
122 static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, u64 time)
123 {
124         int cpu = get_physical_cpu();
125
126         if (!buffer_check_space(cpu, BACKTRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32 + gator_backtrace_depth * 2 * MAXSIZE_PACK32)) {
127                 /* Check and commit; commit is set to occur once buffer is 3/4 full */
128                 buffer_check(cpu, BACKTRACE_BUF, time);
129
130                 return false;
131         }
132
133         gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, time);
134         gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, exec_cookie);
135         gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, tgid);
136         gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid);
137
138         return true;
139 }
140
141 static void marshal_backtrace(unsigned long address, int cookie, int in_kernel)
142 {
143         int cpu = get_physical_cpu();
144
145         if (cookie == 0 && !in_kernel)
146                 cookie = UNRESOLVED_COOKIE;
147         gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie);
148         gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address);
149 }
150
151 static void marshal_backtrace_footer(u64 time)
152 {
153         int cpu = get_physical_cpu();
154
155         gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_END_BACKTRACE);
156
157         /* Check and commit; commit is set to occur once buffer is 3/4 full */
158         buffer_check(cpu, BACKTRACE_BUF, time);
159 }
160
161 static bool marshal_event_header(u64 time)
162 {
163         unsigned long flags, cpu = get_physical_cpu();
164         bool retval = false;
165
166         local_irq_save(flags);
167         if (buffer_check_space(cpu, BLOCK_COUNTER_BUF, MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
168                 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, 0);       /* key of zero indicates a timestamp */
169                 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, time);
170                 retval = true;
171         }
172         local_irq_restore(flags);
173
174         return retval;
175 }
176
177 static void marshal_event(int len, int *buffer)
178 {
179         unsigned long i, flags, cpu = get_physical_cpu();
180
181         if (len <= 0)
182                 return;
183
184         /* length must be even since all data is a (key, value) pair */
185         if (len & 0x1) {
186                 pr_err("gator: invalid counter data detected and discarded\n");
187                 return;
188         }
189
190         /* events must be written in key,value pairs */
191         local_irq_save(flags);
192         for (i = 0; i < len; i += 2) {
193                 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK32))
194                         break;
195                 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i]);
196                 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i + 1]);
197         }
198         local_irq_restore(flags);
199 }
200
201 static void marshal_event64(int len, long long *buffer64)
202 {
203         unsigned long i, flags, cpu = get_physical_cpu();
204
205         if (len <= 0)
206                 return;
207
208         /* length must be even since all data is a (key, value) pair */
209         if (len & 0x1) {
210                 pr_err("gator: invalid counter data detected and discarded\n");
211                 return;
212         }
213
214         /* events must be written in key,value pairs */
215         local_irq_save(flags);
216         for (i = 0; i < len; i += 2) {
217                 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK64))
218                         break;
219                 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i]);
220                 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i + 1]);
221         }
222         local_irq_restore(flags);
223 }
224
225 static void __maybe_unused marshal_event_single(int core, int key, int value)
226 {
227         unsigned long flags, cpu;
228         u64 time;
229
230         local_irq_save(flags);
231         cpu = get_physical_cpu();
232         time = gator_get_time();
233         if (buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
234                 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, time);
235                 gator_buffer_write_packed_int(cpu, COUNTER_BUF, core);
236                 gator_buffer_write_packed_int(cpu, COUNTER_BUF, key);
237                 gator_buffer_write_packed_int(cpu, COUNTER_BUF, value);
238         }
239         local_irq_restore(flags);
240         /* Check and commit; commit is set to occur once buffer is 3/4 full */
241         buffer_check(cpu, COUNTER_BUF, time);
242 }
243
244 static void __maybe_unused marshal_event_single64(int core, int key, long long value)
245 {
246         unsigned long flags, cpu;
247         u64 time;
248
249         local_irq_save(flags);
250         cpu = get_physical_cpu();
251         time = gator_get_time();
252         if (buffer_check_space(cpu, COUNTER_BUF, 2 * MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
253                 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, time);
254                 gator_buffer_write_packed_int(cpu, COUNTER_BUF, core);
255                 gator_buffer_write_packed_int(cpu, COUNTER_BUF, key);
256                 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, value);
257         }
258         local_irq_restore(flags);
259         /* Check and commit; commit is set to occur once buffer is 3/4 full */
260         buffer_check(cpu, COUNTER_BUF, time);
261 }
262
263 static void marshal_sched_trace_switch(int pid, int state)
264 {
265         unsigned long cpu = get_physical_cpu(), flags;
266         u64 time;
267
268         if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
269                 return;
270
271         local_irq_save(flags);
272         time = gator_get_time();
273         if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
274                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_SWITCH);
275                 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
276                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
277                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state);
278         }
279         local_irq_restore(flags);
280         /* Check and commit; commit is set to occur once buffer is 3/4 full */
281         buffer_check(cpu, SCHED_TRACE_BUF, time);
282 }
283
284 static void marshal_sched_trace_exit(int tgid, int pid)
285 {
286         unsigned long cpu = get_physical_cpu(), flags;
287         u64 time;
288
289         if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
290                 return;
291
292         local_irq_save(flags);
293         time = gator_get_time();
294         if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
295                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_EXIT);
296                 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
297                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
298         }
299         local_irq_restore(flags);
300         /* Check and commit; commit is set to occur once buffer is 3/4 full */
301         buffer_check(cpu, SCHED_TRACE_BUF, time);
302 }
303
304 #if GATOR_CPU_FREQ_SUPPORT
305 static void marshal_idle(int core, int state)
306 {
307         unsigned long flags, cpu;
308         u64 time;
309
310         local_irq_save(flags);
311         cpu = get_physical_cpu();
312         time = gator_get_time();
313         if (buffer_check_space(cpu, IDLE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
314                 gator_buffer_write_packed_int(cpu, IDLE_BUF, state);
315                 gator_buffer_write_packed_int64(cpu, IDLE_BUF, time);
316                 gator_buffer_write_packed_int(cpu, IDLE_BUF, core);
317         }
318         local_irq_restore(flags);
319         /* Check and commit; commit is set to occur once buffer is 3/4 full */
320         buffer_check(cpu, IDLE_BUF, time);
321 }
322 #endif
323
324 #if defined(__arm__) || defined(__aarch64__)
325 static void marshal_core_name(const int core, const int cpuid, const char *name)
326 {
327         int cpu = get_physical_cpu();
328         unsigned long flags;
329
330         local_irq_save(flags);
331         if (buffer_check_space(cpu, SUMMARY_BUF, MAXSIZE_PACK32 + MAXSIZE_CORE_NAME)) {
332                 gator_buffer_write_packed_int(cpu, SUMMARY_BUF, MESSAGE_CORE_NAME);
333                 gator_buffer_write_packed_int(cpu, SUMMARY_BUF, core);
334                 gator_buffer_write_packed_int(cpu, SUMMARY_BUF, cpuid);
335                 gator_buffer_write_string(cpu, SUMMARY_BUF, name);
336         }
337         /* Commit core names now so that they can show up in live */
338         local_irq_restore(flags);
339         gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time());
340 }
341 #endif
342
343 static void marshal_activity_switch(int core, int key, int activity, int pid, int state)
344 {
345         unsigned long cpu = get_physical_cpu(), flags;
346         u64 time;
347
348         if (!per_cpu(gator_buffer, cpu)[ACTIVITY_BUF])
349                 return;
350
351         local_irq_save(flags);
352         time = gator_get_time();
353         if (buffer_check_space(cpu, ACTIVITY_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
354                 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, MESSAGE_SWITCH);
355                 gator_buffer_write_packed_int64(cpu, ACTIVITY_BUF, time);
356                 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, core);
357                 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, key);
358                 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, activity);
359                 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, pid);
360                 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, state);
361         }
362         local_irq_restore(flags);
363         /* Check and commit; commit is set to occur once buffer is 3/4 full */
364         buffer_check(cpu, ACTIVITY_BUF, time);
365 }
366
367 void gator_marshal_activity_switch(int core, int key, int activity, int pid)
368 {
369         /* state is reserved for cpu use only */
370         marshal_activity_switch(core, key, activity, pid, 0);
371 }