21a63246f02c0c9b53dc9771b786371dd4db0387
[android-sdk/arm-ds5-gator.git] / driver / gator_events_mali.c
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/module.h>
12 #include <linux/time.h>
13 #include <linux/math64.h>
15 #include "linux/mali_linux_trace.h"
17 /*
18  * There are (currently) three different variants of the comms between gator and Mali:
19  * 1 (deprecated): No software counter support
20  * 2 (deprecated): Tracepoint called for each separate s/w counter value as it appears
21  * 3 (default): Single tracepoint for all s/w counters in a bundle.
22  * Interface style 3 is the default if no other is specified.  1 and 2 will be eliminated when
23  * existing Mali DDKs are upgraded.
24  */
26 #if !defined(GATOR_MALI_INTERFACE_STYLE)
27 #define GATOR_MALI_INTERFACE_STYLE (3)
28 #endif
30 #define MALI_200     (0x0a07)
31 #define MALI_300     (0x0b06) //This is not actually true; Mali-300 is also 0x0b07
32 #define MALI_400     (0x0b07)
33 #define MALI_T6xx    (0x0056)
35 /*
36  * List of possible actions allowing DDK to be controlled by Streamline.
37  * The following numbers are used by DDK to control the frame buffer dumping.
38  */
39 #define FBDUMP_CONTROL_ENABLE (1)
40 #define FBDUMP_CONTROL_RATE (2)
41 #define SW_EVENTS_ENABLE      (3)
42 #define FBDUMP_CONTROL_RESIZE_FACTOR (4)
44 /*
45  * Check that the MALI_SUPPORT define is set to one of the allowable device codes.
46  */
47 #if !defined(MALI_SUPPORT)
48 #error MALI_SUPPORT not defined!
49 #elif (MALI_SUPPORT != MALI_200) && (MALI_SUPPORT != MALI_300) && (MALI_SUPPORT != MALI_400) && (MALI_SUPPORT != MALI_T6xx)
50 #error MALI_SUPPORT set to an invalid device code
51 #endif
53 static const char *mali_name;
55 enum counters {
56     /* Timeline activity */
57     ACTIVITY_VP = 0,
58     ACTIVITY_FP0,
59     ACTIVITY_FP1,
60     ACTIVITY_FP2,
61     ACTIVITY_FP3,
62     
63     /* L2 cache counters */
64     COUNTER_L2_C0,
65     COUNTER_L2_C1,
67     /* Vertex processor counters */
68     COUNTER_VP_C0,
69     COUNTER_VP_C1, 
71     /* Fragment processor counters */
72     COUNTER_FP0_C0,    
73     COUNTER_FP0_C1,     
74     COUNTER_FP1_C0,
75     COUNTER_FP1_C1,
76     COUNTER_FP2_C0,
77     COUNTER_FP2_C1,
78     COUNTER_FP3_C0,
79     COUNTER_FP3_C1,
81     /* EGL Software Counters */
82     COUNTER_EGL_BLIT_TIME,
84     /* GLES Software Counters */
85     COUNTER_GLES_DRAW_ELEMENTS_CALLS,
86     COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES,
87     COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED,
88     COUNTER_GLES_DRAW_ARRAYS_CALLS,
89     COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED,
90     COUNTER_GLES_DRAW_POINTS,
91     COUNTER_GLES_DRAW_LINES,
92     COUNTER_GLES_DRAW_LINE_LOOP,
93     COUNTER_GLES_DRAW_LINE_STRIP,
94     COUNTER_GLES_DRAW_TRIANGLES,
95     COUNTER_GLES_DRAW_TRIANGLE_STRIP,
96     COUNTER_GLES_DRAW_TRIANGLE_FAN,
97     COUNTER_GLES_NON_VBO_DATA_COPY_TIME,
98     COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI,
99     COUNTER_GLES_UPLOAD_TEXTURE_TIME,
100     COUNTER_GLES_UPLOAD_VBO_TIME,
101     COUNTER_GLES_NUM_FLUSHES,
102     COUNTER_GLES_NUM_VSHADERS_GENERATED,
103     COUNTER_GLES_NUM_FSHADERS_GENERATED,
104     COUNTER_GLES_VSHADER_GEN_TIME,
105     COUNTER_GLES_FSHADER_GEN_TIME,
106     COUNTER_GLES_INPUT_TRIANGLES,
107     COUNTER_GLES_VXCACHE_HIT,
108     COUNTER_GLES_VXCACHE_MISS,
109     COUNTER_GLES_VXCACHE_COLLISION,
110     COUNTER_GLES_CULLED_TRIANGLES,
111     COUNTER_GLES_CULLED_LINES,
112     COUNTER_GLES_BACKFACE_TRIANGLES,
113     COUNTER_GLES_GBCLIP_TRIANGLES,
114     COUNTER_GLES_GBCLIP_LINES,
115     COUNTER_GLES_TRIANGLES_DRAWN,
116     COUNTER_GLES_DRAWCALL_TIME,
117     COUNTER_GLES_TRIANGLES_COUNT,
118     COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT,
119     COUNTER_GLES_STRIP_TRIANGLES_COUNT,
120     COUNTER_GLES_FAN_TRIANGLES_COUNT,
121     COUNTER_GLES_LINES_COUNT,
122     COUNTER_GLES_INDEPENDENT_LINES_COUNT,
123     COUNTER_GLES_STRIP_LINES_COUNT,
124     COUNTER_GLES_LOOP_LINES_COUNT,
126         COUNTER_FILMSTRIP,
128     NUMBER_OF_EVENTS
129 };
131 #define FIRST_ACTIVITY_EVENT    ACTIVITY_VP
132 #define LAST_ACTIVITY_EVENT     ACTIVITY_FP3
134 #define FIRST_HW_COUNTER        COUNTER_L2_C0
135 #define LAST_HW_COUNTER         COUNTER_FP3_C1
137 #define FIRST_SW_COUNTER        COUNTER_EGL_BLIT_TIME
138 #define LAST_SW_COUNTER         COUNTER_GLES_LOOP_LINES_COUNT
140 #define FIRST_SPECIAL_COUNTER   COUNTER_FILMSTRIP
141 #define LAST_SPECIAL_COUNTER    COUNTER_FILMSTRIP
143 /* gatorfs variables for counter enable state,
144  * the event the counter should count and the
145  * 'key' (a unique id set by gatord and returned
146  * by gator.ko)
147  */
148 static unsigned long counter_enabled[NUMBER_OF_EVENTS];
149 static unsigned long counter_event[NUMBER_OF_EVENTS];
150 static unsigned long counter_key[NUMBER_OF_EVENTS];
152 /* The data we have recorded */
153 static u32 counter_data[NUMBER_OF_EVENTS];
154 /* The address to sample (or 0 if samples are sent to us) */
155 static u32* counter_address[NUMBER_OF_EVENTS];
157 /* An array used to return the data we recorded
158  * as key,value pairs hence the *2
159  */
160 static unsigned long counter_dump[NUMBER_OF_EVENTS * 2];
161 static unsigned long counter_prev[NUMBER_OF_EVENTS];
163 /* Note whether tracepoints have been registered */
164 static int trace_registered;
166 /**
167  * Calculate the difference and handle the overflow.
168  */
169 static u32 get_difference(u32 start, u32 end)
171         if (start - end >= 0)
172         {
173                 return start - end;
174         }
176         // Mali counters are unsigned 32 bit values that wrap.
177         return (4294967295u - end) + start;
180 /**
181  * Returns non-zero if the given counter ID is an activity counter.
182  */
183 static inline int is_activity_counter(unsigned int event_id)
185     return (event_id >= FIRST_ACTIVITY_EVENT && 
186         event_id <= LAST_ACTIVITY_EVENT);
189 /**
190  * Returns non-zero if the given counter ID is a hardware counter.
191  */
192 static inline int is_hw_counter(unsigned int event_id)
194     return (event_id >= FIRST_HW_COUNTER && event_id <= LAST_HW_COUNTER);
197 /**
198  * Returns non-zero if the given counter ID is a software counter.
199  */
200 static inline int is_sw_counter(unsigned int event_id)
202     return (event_id >= FIRST_SW_COUNTER && event_id <= LAST_SW_COUNTER);
205 /*
206  * The Mali DDK uses s64 types to contain software counter values, but gator
207  * can only use a maximum of 32 bits. This function scales a software counter
208  * to an appopriate range.
209  */
210 static u32 scale_sw_counter_value(unsigned int event_id, signed long long value)
212     u32 scaled_value;
214     switch (event_id) {
215         case COUNTER_GLES_UPLOAD_TEXTURE_TIME:
216         case COUNTER_GLES_UPLOAD_VBO_TIME:
217             scaled_value = (u32)div_s64(value, 1000000);
218             break;
219         default:
220             scaled_value = (u32)value;
221             break;
222     }
224     return scaled_value;
227 /* Probe for continuously sampled counter */
228 #if 0 //WE_DONT_CURRENTLY_USE_THIS_SO_SUPPRESS_WARNING
229 GATOR_DEFINE_PROBE(mali_sample_address, TP_PROTO(unsigned int event_id, u32* addr))
231     /* Turning on too many pr_debug statements in frequently called functions
232      * can cause stability and/or performance problems
233      */
234     //pr_debug("gator: mali_sample_address %d %d\n", event_id, addr);
235     if (event_id >= ACTIVITY_VP && event_id <= COUNTER_FP3_C1) {
236         counter_address[event_id] = addr;
237     }
239 #endif
241 /* Probe for hardware counter events */
242 GATOR_DEFINE_PROBE(mali_hw_counter, TP_PROTO(unsigned int event_id, unsigned int value))
244     /* Turning on too many pr_debug statements in frequently called functions
245      * can cause stability and/or performance problems
246      */
247     //pr_debug("gator: mali_hw_counter %d %d\n", event_id, value);
248     if (is_hw_counter(event_id)) {
249         counter_data[event_id] = value;
250     }
253 #if GATOR_MALI_INTERFACE_STYLE == 2
254 GATOR_DEFINE_PROBE(mali_sw_counter, TP_PROTO(unsigned int event_id, signed long long value))
256     if (is_sw_counter(event_id)) {
257         counter_data[event_id] = scale_sw_counter_value(event_id, value);
258     }
260 #endif /* GATOR_MALI_INTERFACE_STYLE == 2 */
263 #if GATOR_MALI_INTERFACE_STYLE == 3
264 GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void * surface_id, unsigned int * counters))
266         u32 i;
268         /* Copy over the values for those counters which are enabled. */
269         for(i=FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++)
270         {
271                 if(counter_enabled[i])
272                 {
273                         counter_data[i] = (u32)(counters[i - FIRST_SW_COUNTER]);
274                 }
275         }
277 #endif /* GATOR_MALI_INTERFACE_STYLE == 3 */
279 //TODO need to work out how many fp units we have
280 u32 gator_mali_get_n_fp(void) {
281     return 4;
284 //TODO need to work out what kind of Mali we are looking at
285 u32 gator_mali_get_id(void) {
286     return MALI_SUPPORT;
289 int gator_events_mali_create_files(struct super_block *sb, struct dentry *root) {
290     struct dentry *dir;
291     int event;
292     int n_fp = gator_mali_get_n_fp();
294     /*
295      * Create the filesystem entries for vertex processor, fragement processor
296      * and L2 cache timeline and hardware counters. Software counters get 
297      * special handling after this block.
298      */
299     for (event = FIRST_ACTIVITY_EVENT; event <= LAST_HW_COUNTER; event++)
300     {
301         char buf[40];
303         /* 
304          * We can skip this event if it's for a non-existent fragment
305          * processor.
306          */
307         if (((event - ACTIVITY_FP0 >= n_fp) && (event < COUNTER_L2_C0)) ||
308             (((event - COUNTER_FP0_C0)/2 >= n_fp)))
309         {
310             continue;
311         }
313         /* Otherwise, set up the filesystem entry for this event. */
314         switch (event) {
315             case ACTIVITY_VP:
316                 snprintf(buf, sizeof buf, "ARM_%s_VP_active", mali_name);
317                 break;
318             case ACTIVITY_FP0:
319             case ACTIVITY_FP1:
320             case ACTIVITY_FP2:
321             case ACTIVITY_FP3:
322                 snprintf(buf, sizeof buf, "ARM_%s_FP%d_active", 
323                     mali_name, event - ACTIVITY_FP0);
324                 break;
325             case COUNTER_L2_C0:
326             case COUNTER_L2_C1:
327                 snprintf(buf, sizeof buf, "ARM_%s_L2_cnt%d", 
328                     mali_name, event - COUNTER_L2_C0);
329                 break;
330             case COUNTER_VP_C0:
331             case COUNTER_VP_C1:
332                 snprintf(buf, sizeof buf, "ARM_%s_VP_cnt%d", 
333                     mali_name, event - COUNTER_VP_C0);
334                 break;
335             case COUNTER_FP0_C0:
336             case COUNTER_FP0_C1:
337             case COUNTER_FP1_C0:
338             case COUNTER_FP1_C1:
339             case COUNTER_FP2_C0:
340             case COUNTER_FP2_C1:
341             case COUNTER_FP3_C0:
342             case COUNTER_FP3_C1:
343                 snprintf(buf, sizeof buf, "ARM_%s_FP%d_cnt%d", mali_name, 
344                     (event - COUNTER_FP0_C0) / 2, (event - COUNTER_FP0_C0) % 2);
345                 break;
346             default:
347                 printk("gator: trying to create file for non-existent counter (%d)\n", event);
348                 continue;
349         }
351         dir = gatorfs_mkdir(sb, root, buf);
352         
353         if (!dir) {
354             return -1;
355         }
356         
357         gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
358         
359         /* Only create an event node for counters that can change what they count */
360         if (event >= COUNTER_L2_C0) {
361             gatorfs_create_ulong(sb, dir, "event", &counter_event[event]);
362         }
363         
364         gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
365     }
367     /* Now set up the software counter entries */
368     for (event = FIRST_SW_COUNTER; event <= LAST_SW_COUNTER; event++)
369     {
370         char buf[40];
372         snprintf(buf, sizeof(buf), "ARM_%s_SW_%d", mali_name, event);
374         dir = gatorfs_mkdir(sb, root, buf);
376         if (!dir) {
377             return -1;
378         }
380         gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
381         gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
382     }
384         /* Now set up the special counter entries */
385     for (event = FIRST_SPECIAL_COUNTER; event <= LAST_SPECIAL_COUNTER; event++)
386     {
387         char buf[40];
389         snprintf(buf, sizeof(buf), "ARM_%s_Filmstrip", mali_name);
391         dir = gatorfs_mkdir(sb, root, buf);
393         if (!dir) {
394             return -1;
395         }
397         gatorfs_create_ulong(sb, dir, "event", &counter_event[event]);
398         gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
399         gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
400     }
403     return 0;
406 //TODO
407 void _mali_profiling_set_event(unsigned int, unsigned int);
408 void _mali_osk_fb_control_set(unsigned int, unsigned int);
409 void _mali_profiling_control(unsigned int, unsigned int);
411 void _mali_profiling_get_counters(unsigned int*, unsigned int*, unsigned int*, unsigned int*);
412 void (*_mali_profiling_get_counters_function_pointer)(unsigned int*, unsigned int*, unsigned int*, unsigned int*);
414 /*
415  * Examine list of software counters and determine if any one is enabled.
416  * Returns 1 if any counter is enabled, 0 if none is.
417  */
418 static int is_any_sw_counter_enabled(void)
420         unsigned int i;
422         for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++)
423         {
424                 if (counter_enabled[i])
425                 {
426                         return 1;       /* At least one counter is enabled */
427                 }
428         }
430         return 0;       /* No s/w counters enabled */
433 static void mali_counter_initialize(void) 
435     /* If a Mali driver is present and exporting the appropriate symbol
436      * then we can request the HW counters (of which there are only 2)
437      * be configured to count the desired events
438      */
439     void (*set_hw_event)(unsigned int, unsigned int);
440         void (*set_fb_event)(unsigned int, unsigned int);
441         void (*mali_control)(unsigned int, unsigned int);
443     set_hw_event = symbol_get(_mali_profiling_set_event);
445     if (set_hw_event) {
446         int i;
448         pr_debug("gator: mali online _mali_profiling_set_event symbol @ %p\n",set_hw_event);
450         for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) {
451             if (counter_enabled[i]) {
452                 set_hw_event(i, counter_event[i]);
453             } else {
454                 set_hw_event(i, 0xFFFFFFFF);
455             }
456         }
458         symbol_put(_mali_profiling_set_event);
459     } else {
460         printk("gator: mali online _mali_profiling_set_event symbol not found\n");
461     }
463         set_fb_event = symbol_get(_mali_osk_fb_control_set);
465         if (set_fb_event) {
466                 pr_debug("gator: mali online _mali_osk_fb_control_set symbol @ %p\n", set_fb_event);
468         set_fb_event(0,(counter_enabled[COUNTER_FILMSTRIP]?1:0));
470                 symbol_put(_mali_osk_fb_control_set);
471         } else {
472                 printk("gator: mali online _mali_osk_fb_control_set symbol not found\n");
473         }
475         /* Generic control interface for Mali DDK. */
476         mali_control = symbol_get(_mali_profiling_control);
477         if (mali_control) {
478                 /* The event attribute in the XML file keeps the actual frame rate. */
479                 unsigned int rate = counter_event[COUNTER_FILMSTRIP] & 0xff;
480                 unsigned int resize_factor = (counter_event[COUNTER_FILMSTRIP] >> 8) & 0xff;
482                 pr_debug("gator: mali online _mali_profiling_control symbol @ %p\n", mali_control);
484                 mali_control(SW_EVENTS_ENABLE, (is_any_sw_counter_enabled()?1:0));
485                 mali_control(FBDUMP_CONTROL_ENABLE, (counter_enabled[COUNTER_FILMSTRIP]?1:0));
486                 mali_control(FBDUMP_CONTROL_RATE, rate);
487                 mali_control(FBDUMP_CONTROL_RESIZE_FACTOR, resize_factor);
489                 pr_debug("gator: sent mali_control enabled=%d, rate=%d\n", (counter_enabled[COUNTER_FILMSTRIP]?1:0), rate);
491                 symbol_put(_mali_profiling_control);
492         } else {
493                 printk("gator: mali online _mali_profiling_control symbol not found\n");
494         }
496         _mali_profiling_get_counters_function_pointer =  symbol_get(_mali_profiling_get_counters);
497         if (_mali_profiling_get_counters_function_pointer){
498                 pr_debug("gator: mali online _mali_profiling_get_counters symbol @ %p\n", _mali_profiling_get_counters_function_pointer);
499                 counter_prev[COUNTER_L2_C0] = 0;
500                 counter_prev[COUNTER_L2_C1] = 0;
501         }
502         else{
503                 pr_debug("gator WARNING: mali _mali_profiling_get_counters symbol  not defined");
504         }
507 static void mali_counter_deinitialize(void) 
509     void (*set_hw_event)(unsigned int, unsigned int);
510         void (*set_fb_event)(unsigned int, unsigned int);
511         void (*mali_control)(unsigned int, unsigned int);
513     set_hw_event = symbol_get(_mali_profiling_set_event);
515     if (set_hw_event) {
516         int i;
517         
518         pr_debug("gator: mali offline _mali_profiling_set_event symbol @ %p\n",set_hw_event);
519         for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) {
520             set_hw_event(i, 0xFFFFFFFF);
521         }
522         
523         symbol_put(_mali_profiling_set_event);
524     } else {
525         printk("gator: mali offline _mali_profiling_set_event symbol not found\n");
526     }
528         set_fb_event = symbol_get(_mali_osk_fb_control_set);
530         if (set_fb_event) {
531                 pr_debug("gator: mali offline _mali_osk_fb_control_set symbol @ %p\n", set_fb_event);
533         set_fb_event(0,0);
535                 symbol_put(_mali_osk_fb_control_set);
536         } else {
537                 printk("gator: mali offline _mali_osk_fb_control_set symbol not found\n");
538         }
539         
540         /* Generic control interface for Mali DDK. */
541         mali_control = symbol_get(_mali_profiling_control);
543         if (mali_control) {
544                 pr_debug("gator: mali offline _mali_profiling_control symbol @ %p\n", set_fb_event);
546                 /* Reset the DDK state - disable counter collection */
547                 mali_control(SW_EVENTS_ENABLE, 0);
549                 mali_control(FBDUMP_CONTROL_ENABLE, 0);
551                 symbol_put(_mali_profiling_control);
552         } else {
553                 printk("gator: mali offline _mali_profiling_control symbol not found\n");
554         }
556         if (_mali_profiling_get_counters_function_pointer){
557                 symbol_put(_mali_profiling_get_counters);
558         }
562 static int gator_events_mali_start(void) {
563     // register tracepoints
564     if (GATOR_REGISTER_TRACE(mali_hw_counter)) {
565         printk("gator: mali_hw_counter tracepoint failed to activate\n");
566         return -1;
567     }
569 #if GATOR_MALI_INTERFACE_STYLE == 1
570                 /* None. */
571 #elif GATOR_MALI_INTERFACE_STYLE == 2
572                 /* For patched Mali driver. */
573     if (GATOR_REGISTER_TRACE(mali_sw_counter)) {
574         printk("gator: mali_sw_counter tracepoint failed to activate\n");
575         return -1;
576     }
577 #elif GATOR_MALI_INTERFACE_STYLE == 3
578 /* For Mali drivers with built-in support. */
579     if (GATOR_REGISTER_TRACE(mali_sw_counters)) {
580         printk("gator: mali_sw_counters tracepoint failed to activate\n");
581         return -1;
582     }
583 #else
584 #error Unknown GATOR_MALI_INTERFACE_STYLE option.
585 #endif
587     trace_registered = 1;
589     mali_counter_initialize();
590     return 0;
593 static void gator_events_mali_stop(void) {
594     unsigned int cnt;
596     pr_debug("gator: mali stop\n");
598     if (trace_registered) {
599         GATOR_UNREGISTER_TRACE(mali_hw_counter);
601 #if GATOR_MALI_INTERFACE_STYLE == 1
602     /* None. */
603 #elif GATOR_MALI_INTERFACE_STYLE == 2
604     /* For patched Mali driver. */
605     GATOR_UNREGISTER_TRACE(mali_sw_counter);
606 #elif GATOR_MALI_INTERFACE_STYLE == 3
607     /* For Mali drivers with built-in support. */
608     GATOR_UNREGISTER_TRACE(mali_sw_counters);
609 #else
610 #error Unknown GATOR_MALI_INTERFACE_STYLE option.
611 #endif
613         pr_debug("gator: mali timeline tracepoint deactivated\n");
614         
615         trace_registered = 0;
616     }
618     for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) {
619         counter_enabled[cnt] = 0;
620         counter_event[cnt] = 0;
621         counter_address[cnt] = NULL;
622     }
624     mali_counter_deinitialize();
627 static int gator_events_mali_read(int **buffer) {
628     int cnt, len = 0;
630     if (smp_processor_id()) return 0;
632     // Read the L2 C0 and C1 here.
633     if (counter_enabled[COUNTER_L2_C0] || counter_enabled[COUNTER_L2_C1] ) {
634         u32 src0 = 0;
635         u32 val0 = 0;
636         u32 src1 = 0;
637         u32 val1 = 0;
639         // Poke the driver to get the counter values
640         if (_mali_profiling_get_counters_function_pointer){
641             _mali_profiling_get_counters_function_pointer(&src0, &val0, &src1, &val1);
642         }
644         if (counter_enabled[COUNTER_L2_C0])
645         {
646             // Calculate and save src0's counter val0
647             counter_dump[len++] = counter_key[COUNTER_L2_C0];
648             counter_dump[len++] = get_difference(val0, counter_prev[COUNTER_L2_C0]);
649         }
651         if (counter_enabled[COUNTER_L2_C1])
652         {
653             // Calculate and save src1's counter val1
654             counter_dump[len++] = counter_key[COUNTER_L2_C1];
655             counter_dump[len++] = get_difference(val1, counter_prev[COUNTER_L2_C1]);
656         }
658         // Save the previous values for the counters.
659         counter_prev[COUNTER_L2_C0] = val0;
660         counter_prev[COUNTER_L2_C1] = val1;
661     }
663     // Process other (non-timeline) counters.
664     for (cnt = COUNTER_VP_C0; cnt <= LAST_SW_COUNTER; cnt++) {
665         if (counter_enabled[cnt]) {
666             counter_dump[len++] = counter_key[cnt];
667             counter_dump[len++] = counter_data[cnt];
669             counter_data[cnt] = 0;
670         }
671     }
673     if (buffer) {
674         *buffer = (int*) counter_dump;
675     }
677     return len;
680 static struct gator_interface gator_events_mali_interface = {
681     .create_files = gator_events_mali_create_files,
682     .start = gator_events_mali_start,
683     .stop = gator_events_mali_stop,
684     .read = gator_events_mali_read,
685 };
687 int gator_events_mali_init(void)
689     unsigned int cnt;
690     u32 id = gator_mali_get_id();
692     switch (id) {
693     case MALI_T6xx:
694         mali_name = "Mali-T6xx";
695         break;
696     case MALI_400:
697         mali_name = "Mali-400";
698         break;
699     case MALI_300:
700         mali_name = "Mali-300";
701         break;
702     case MALI_200:
703         mali_name = "Mali-200";
704         break;
705     default:
706         printk("Unknown Mali ID (%d)\n", id);
707         return -1;
708     }
710     pr_debug("gator: mali init\n");
712     for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) {
713         counter_enabled[cnt] = 0;
714         counter_event[cnt] = 0;
715         counter_key[cnt] = gator_events_get_key();
716         counter_address[cnt] = NULL;
717                 counter_data[cnt] = 0;
718     }
720     trace_registered = 0;
722     return gator_events_install(&gator_events_mali_interface);
724 gator_events_init(gator_events_mali_init);