mali mess
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / gpu / mt8127 / mali / mali / mtk_common / mtk_pp.c
CommitLineData
02af6beb 1
6fa3eb70
S
2#include <linux/sched.h>
3#include <linux/string.h>
4#include <linux/vmalloc.h>
5#include <linux/proc_fs.h>
6#include <linux/seq_file.h>
7
8#include "mtk_pp.h"
9
10#if defined(MTK_DEBUG) && defined(MTK_DEBUG_PROC_PRINT)
11
12static struct proc_dir_entry *g_MTKPP_proc;
13static MTK_PROC_PRINT_DATA *g_MTKPPdata[MTKPP_ID_SIZE];
14
15static void MTKPP_InitLock(MTK_PROC_PRINT_DATA *data)
16{
17 spin_lock_init(&data->lock);
18}
19
20static void MTKPP_Lock(MTK_PROC_PRINT_DATA *data)
21{
22 spin_lock_irqsave(&data->lock, data->irqflags);
23}
24static void MTKPP_UnLock(MTK_PROC_PRINT_DATA *data)
25{
26 spin_unlock_irqrestore(&data->lock, data->irqflags);
27}
28
29static void MTKPP_PrintQueueBuffer(MTK_PROC_PRINT_DATA *data, const char *fmt, ...) MTK_PP_FORMAT_PRINTF(2,3);
30
02af6beb 31//static void MTKPP_PrintQueueBuffer2(MTK_PROC_PRINT_DATA *data, const char *fmt, ...) MTK_PP_FORMAT_PRINTF(2,3);
6fa3eb70
S
32
33static void MTKPP_PrintRingBuffer(MTK_PROC_PRINT_DATA *data, const char *fmt, ...) MTK_PP_FORMAT_PRINTF(2,3);
34
35static int MTKPP_PrintTime(char *buf, int n)
36{
37 /* copy & modify from ./kernel/printk.c */
38 unsigned long long t;
39 unsigned long nanosec_rem;
40
41 t = cpu_clock(smp_processor_id());
42 nanosec_rem = do_div(t, 1000000000);
43
44 return snprintf(buf, n, "[%5lu.%06lu] ", (unsigned long) t, nanosec_rem / 1000);
45}
46
47static void MTKPP_PrintQueueBuffer(MTK_PROC_PRINT_DATA *data, const char *fmt, ...)
48{
49 va_list args;
50 char *buf;
51 int len;
52
53 MTKPP_Lock(data);
54
55 if ((data->current_line >= data->line_array_size)
56 || (data->current_data >= (data->data_array_size - 128)))
57 {
58 // out of buffer, ignore input
59 MTKPP_UnLock(data);
60 return;
61 }
62
63 /* Move to next line */
64 buf = data->line[data->current_line++] = data->data + data->current_data;
65
66 /* Print string */
67 va_start(args, fmt);
68 len = vsnprintf(buf, (data->data_array_size - data->current_data), fmt, args);
69 va_end(args);
70
71 data->current_data += len + 1;
72
73 MTKPP_UnLock(data);
74}
75
02af6beb 76#if 0
6fa3eb70
S
77static void MTKPP_PrintQueueBuffer2(MTK_PROC_PRINT_DATA *data, const char *fmt, ...)
78{
79 va_list args;
80 char *buf;
81 int len;
82
83 MTKPP_Lock(data);
84
85 if ((data->current_line >= data->line_array_size)
86 || (data->current_data >= (data->data_array_size - 128)))
87 {
88 // out of buffer, ignore input
89 MTKPP_UnLock(data);
90 return;
91 }
92
93 /* Move to next line */
94 buf = data->line[data->current_line++] = data->data + data->current_data;
95
96 /* Add the current time stamp */
97 len = MTKPP_PrintTime(buf, (data->data_array_size - data->current_data));
98 buf += len;
99 data->current_data += len;
100
101 /* Print string */
102 va_start(args, fmt);
103 len = vsnprintf(buf, (data->data_array_size - data->current_data), fmt, args);
104 va_end(args);
105
106 data->current_data += len + 1 ;
107
108 MTKPP_UnLock(data);
109}
02af6beb 110#endif
6fa3eb70
S
111
112static void MTKPP_PrintRingBuffer(MTK_PROC_PRINT_DATA *data, const char *fmt, ...)
113{
114 va_list args;
115 char *buf;
116 int len, s;
117
118 MTKPP_Lock(data);
119
120 if ((data->current_line >= data->line_array_size)
121 || (data->current_data >= (data->data_array_size - 128)))
122 {
123 data->current_line = 0;
124 data->current_data = 0;
125 }
126
127 /* Move to next line */
128 buf = data->line[data->current_line++] = data->data + data->current_data;
129
130 /* Add the current time stamp */
131 len = MTKPP_PrintTime(buf, (data->data_array_size - data->current_data));
132 buf += len;
133 data->current_data += len;
134
135 /* Print string */
136 va_start(args, fmt);
137 len = vsnprintf(buf, (data->data_array_size - data->current_data), fmt, args);
138 va_end(args);
139
140 data->current_data += len + 1 ;
141
142 /* Clear overflow data */
143 buf += len; s = data->current_line;
144 while (s < data->line_array_size
145 && data->line[s] != NULL
146 && data->line[s] <= buf)
147 {
148 data->line[s++] = NULL;
149 }
150
151 MTKPP_UnLock(data);
152}
153
154static MTK_PROC_PRINT_DATA *MTKPP_AllocStruct(int type)
155{
156 MTK_PROC_PRINT_DATA *data;
157
158 data = vmalloc(sizeof(MTK_PROC_PRINT_DATA));
159 if (data == NULL)
160 {
161 _MTKPP_DEBUG_LOG("%s: vmalloc fail", __func__);
162 goto err_out;
163 }
164
165 MTKPP_InitLock(data);
166
167 switch (type)
168 {
169 case MTKPP_BUFFERTYPE_QUEUEBUFFER:
170 data->pfn_print = MTKPP_PrintQueueBuffer;
171 break;
172 case MTKPP_BUFFERTYPE_RINGBUFFER:
173 data->pfn_print = MTKPP_PrintRingBuffer;
174 break;
175 default:
176 // something wrong
177 _MTKPP_DEBUG_LOG("%s: unknow flags: %d", __func__, type);
178 goto err_out2;
179 break;
180 }
181
182 data->data = NULL;
183 data->line = NULL;
184 data->data_array_size = 0;
185 data->line_array_size = 0;
186 data->current_data = 0;
187 data->current_line = 0;
188 data->type = type;
189
190 return data;
191
192err_out2:
193 vfree(data);
194err_out:
195 return NULL;
196
197}
198
199static void MTKPP_FreeStruct(MTK_PROC_PRINT_DATA **data)
200{
201 vfree(*data);
202 *data = NULL;
203}
204
205static void MTKPP_AllocData(MTK_PROC_PRINT_DATA *data, int data_size, int max_line)
206{
207 MTKPP_Lock(data);
208
209 data->data = (char *)kmalloc(sizeof(char)*data_size, GFP_ATOMIC);
210 if (data->data == NULL)
211 {
212 _MTKPP_DEBUG_LOG("%s, kmalloc data fail, size = %d", __func__, data_size);
213 goto err_alloc_struct;
214 }
215 data->line = (char **)kmalloc(sizeof(char*)*max_line, GFP_ATOMIC);
216 if (data->line == NULL)
217 {
218 _MTKPP_DEBUG_LOG("%s, kmalloc line fail, size = %d", __func__, data_size);
219 goto err_alloc_data;
220 }
221
222 data->data_array_size = data_size;
223 data->line_array_size = max_line;
224
225 MTKPP_UnLock(data);
226
227 return;
228
229err_alloc_data:
230 kfree(data->data);
231err_alloc_struct:
232 MTKPP_UnLock(data);
233 return;
234
235}
236
237static void MTKPP_FreeData(MTK_PROC_PRINT_DATA *data)
238{
239 MTKPP_Lock(data);
240
241 kfree(data->line);
242 kfree(data->data);
243
244 data->line = NULL;
245 data->data = NULL;
246 data->data_array_size = 0;
247 data->line_array_size = 0;
248 data->current_data = 0;
249 data->current_line = 0;
250
251 MTKPP_UnLock(data);
252}
253
254static void MTKPP_CleanData(MTK_PROC_PRINT_DATA *data)
255{
256 MTKPP_Lock(data);
257
258 memset(data->line, 0, sizeof(char*)*data->line_array_size);
259 data->current_data = 0;
260 data->current_line = 0;
261
262 MTKPP_UnLock(data);
263}
264
265static void* MTKPP_SeqStart(struct seq_file *s, loff_t *pos)
266{
267 loff_t *spos;
268
269 spos = kmalloc(sizeof(loff_t), GFP_KERNEL);
270
271 if (*pos >= MTKPP_ID_SIZE)
272 {
273 // MTK: lono@2013/1/7
274 return NULL;
275 }
276
277 if (spos == NULL)
278 {
279 return NULL;
280 }
281
282 *spos = *pos;
283 return spos;
284}
285
286static void* MTKPP_SeqNext(struct seq_file *s, void *v, loff_t *pos)
287{
288 loff_t *spos = (loff_t *) v;
289 *pos = ++(*spos);
290
291 return (*pos < MTKPP_ID_SIZE) ? spos : NULL;
292}
293
294static void MTKPP_SeqStop(struct seq_file *s, void *v)
295{
296 kfree(v);
297}
298
299static int MTKPP_SeqShow(struct seq_file *sfile, void *v)
300{
301 MTK_PROC_PRINT_DATA *data;
302 int off, i;
303 loff_t *spos = (loff_t *) v;
304
305 off = *spos;
306 data = g_MTKPPdata[off];
307
308 seq_printf(sfile, "\n" "===== buffer_id = %d =====\n", off);
309
310 MTKPP_Lock(data);
311
312 switch (data->type)
313 {
314 case MTKPP_BUFFERTYPE_QUEUEBUFFER:
315 seq_printf(sfile, "data_size = %d/%d\n", data->current_data, data->data_array_size);
316 seq_printf(sfile, "data_line = %d/%d\n", data->current_line, data->line_array_size);
317 for (i = 0; i < data->current_line; ++i)
318 {
319 seq_printf(sfile, "%s\n", data->line[i]);
320 }
321 break;
322 case MTKPP_BUFFERTYPE_RINGBUFFER:
323 seq_printf(sfile, "data_size = %d\n", data->data_array_size);
324 seq_printf(sfile, "data_line = %d\n", data->line_array_size);
325 for (i = data->current_line; i < data->line_array_size; ++i)
326 {
327 if (data->line[i] != NULL)
328 {
329 seq_printf(sfile, "%s\n", data->line[i]);
330 }
331 }
332 for (i = 0; i < data->current_line; ++i)
333 {
334 if (data->line[i] != NULL)
335 {
336 seq_printf(sfile, "%s\n", data->line[i]);
337 }
338 }
339 break;
340 default:
341 // FIXME: assert here
342 break;
343 }
344
345 MTKPP_UnLock(data);
346
347 return 0;
348}
349
350static struct seq_operations g_MTKPP_seq_ops = {
351 .start = MTKPP_SeqStart,
352 .next = MTKPP_SeqNext,
353 .stop = MTKPP_SeqStop,
354 .show = MTKPP_SeqShow
355};
356
357static int MTKPP_ProcOpen(struct inode *inode, struct file *file)
358{
359 return seq_open(file, &g_MTKPP_seq_ops);
360}
361
362static struct file_operations g_MTKPP_proc_ops = {
363 .open = MTKPP_ProcOpen,
364 .read = seq_read, // system
365 .llseek = seq_lseek, // system
366 .release = seq_release // system
367};
368
369void MTKPP_Init(void)
370{
371 int i;
372 struct {
373 MTKPP_ID uid;
374 MTKPP_BUFFERTYPE type;
375 int data_size;
376 int max_line;
377 } mtk_pp_register_tabls[] =
378 {
379 {MTKPP_ID_SYNC, MTKPP_BUFFERTYPE_RINGBUFFER, 1024 * 1024 * 2, 1024},
380 };
381
382 for (i = 0; i < MTKPP_ID_SIZE; ++i)
383 {
384 if (i != mtk_pp_register_tabls[i].uid)
385 {
386 _MTKPP_DEBUG_LOG("%s: index(%d) != tabel_uid(%d)", __func__, i, mtk_pp_register_tabls[i].uid);
387 goto err_out;
388 }
389
390 g_MTKPPdata[i] = MTKPP_AllocStruct(mtk_pp_register_tabls[i].type);
391
392 if (g_MTKPPdata[i] == NULL)
393 {
394 _MTKPP_DEBUG_LOG("%s: alloc struct fail: flags = %d", __func__, mtk_pp_register_tabls[i].type);
395 goto err_out;
396 }
397
398 if (mtk_pp_register_tabls[i].data_size > 0)
399 {
400 MTKPP_AllocData(
401 g_MTKPPdata[i],
402 mtk_pp_register_tabls[i].data_size,
403 mtk_pp_register_tabls[i].max_line
404 );
405
406 MTKPP_CleanData(g_MTKPPdata[i]);
407 }
408 }
409
02af6beb 410 g_MTKPP_proc = proc_create("gpulog", 0, NULL, &g_MTKPP_proc_ops);
6fa3eb70
S
411
412 return;
413
414err_out:
415 return;
416}
417
418void MTKPP_Deinit(void)
419{
420 int i;
421
422 remove_proc_entry("gpulog", NULL);
423
424 for (i = (MTKPP_ID_SIZE - 1); i >= 0; --i)
425 {
426 MTKPP_FreeData(g_MTKPPdata[i]);
427 MTKPP_FreeStruct(&g_MTKPPdata[i]);
428 }
429}
430
431MTK_PROC_PRINT_DATA *MTKPP_GetData(MTKPP_ID id)
432{
433 return (id >= 0 && id < MTKPP_ID_SIZE) ?
434 g_MTKPPdata[id] : NULL;
435}
436
437#endif