]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/arm-ds5-gator.git/blob - driver/gator_events_mmaped.c
Merge branch 'master' into android
[android-sdk/arm-ds5-gator.git] / driver / gator_events_mmaped.c
1 /*
2  * Example events provider
3  *
4  * Copyright (C) ARM Limited 2010-2012. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * Similar entries to those below must be present in the events.xml file.
11  * To add them to the events.xml, create an events-mmap.xml with the 
12  * following contents and rebuild gatord:
13  *
14  * <counter_set name="mmaped_cnt" count="3"/>
15  * <category name="mmaped" counter_set="mmaped_cnt" per_cpu="no">
16  *   <event event="0x0" title="Simulated" name="Sine" display="maximum" average_selection="yes" description="Sort-of-sine"/>
17  *   <event event="0x1" title="Simulated" name="Triangle" display="maximum" average_selection="yes" description="Triangular wave"/>
18  *   <event event="0x2" title="Simulated" name="PWM" display="maximum" average_selection="yes" description="PWM Signal"/>
19  * </category>
20  */
22 #include <linux/init.h>
23 #include <linux/io.h>
24 #include <linux/ratelimit.h>
26 #include "gator.h"
28 #define MMAPED_COUNTERS_NUM 3
30 static struct {
31         unsigned long enabled;
32         unsigned long event;
33         unsigned long key;
34 } mmaped_counters[MMAPED_COUNTERS_NUM];
36 static int mmaped_buffer[MMAPED_COUNTERS_NUM * 2];
38 #ifdef TODO
39 static void __iomem *mmaped_base;
40 #endif
42 #ifndef TODO
43 static s64 prev_time;
44 #endif
46 /* Adds mmaped_cntX directories and enabled, event, and key files to /dev/gator/events */
47 static int gator_events_mmaped_create_files(struct super_block *sb,
48                 struct dentry *root)
49 {
50         int i;
52         for (i = 0; i < MMAPED_COUNTERS_NUM; i++) {
53                 char buf[16];
54                 struct dentry *dir;
56                 snprintf(buf, sizeof(buf), "mmaped_cnt%d", i);
57                 dir = gatorfs_mkdir(sb, root, buf);
58                 if (WARN_ON(!dir))
59                         return -1;
60                 gatorfs_create_ulong(sb, dir, "enabled",
61                                 &mmaped_counters[i].enabled);
62                 gatorfs_create_ulong(sb, dir, "event",
63                                 &mmaped_counters[i].event);
64                 gatorfs_create_ro_ulong(sb, dir, "key",
65                                 &mmaped_counters[i].key);
66         }
68         return 0;
69 }
71 static int gator_events_mmaped_start(void)
72 {
73 #ifdef TODO
74         for (i = 0; i < MMAPED_COUNTERS_NUM; i++)
75                 writel(mmaped_counters[i].event,
76                                 mmaped_base + COUNTERS_CONFIG_OFFSET[i]);
78         writel(ENABLED, COUNTERS_CONTROL_OFFSET);
79 #endif
81 #ifndef TODO
82         struct timespec ts;
83         getnstimeofday(&ts);
84         prev_time = timespec_to_ns(&ts);
85 #endif
87         return 0;
88 }
90 static void gator_events_mmaped_stop(void)
91 {
92 #ifdef TODO
93         writel(DISABLED, COUNTERS_CONTROL_OFFSET);
94 #endif
95 }
97 #ifndef TODO
98 /* This function "simulates" counters, generating values of fancy
99  * functions like sine or triangle... */
100 static int mmaped_simulate(int counter, int delta_in_us)
102         int result = 0;
104         switch (counter) {
105         case 0: /* sort-of-sine */
106                 {
107                         static int t = 0;
108                         int x;
110                         t += delta_in_us;
111                         if (t > 2048000)
112                                 t = 0;
114                         if (t % 1024000 < 512000)
115                                 x = 512000 - (t % 512000);
116                         else
117                                 x = t % 512000;
119                         result = 32 * x / 512000;
120                         result = result * result;
122                         if (t < 1024000)
123                                 result = 1922 - result;
124                 }
125                 break;
126         case 1: /* triangle */
127                 {
128                         static int v, d = 1;
130                         v = v + d * delta_in_us;
131                         if (v < 0) {
132                                 v = 0;
133                                 d = 1;
134                         } else if (v > 1000000) {
135                                 v = 1000000;
136                                 d = -1;
137                         }
139                         result = v;
140                 }
141                 break;
142         case 2: /* PWM signal */
143                 {
144                         static int t, dc, x;
146                         t += delta_in_us;
147                         if (t > 1000000)
148                                 t = 0;
149                         if (x / 1000000 != (x + delta_in_us) / 1000000)
150                                 dc = (dc + 100000) % 1000000;
151                         x += delta_in_us;
152                         
153                         result = t < dc ? 0 : 10;
154                 }
155                 break;
156         }
158         return result;
160 #endif
162 static int gator_events_mmaped_read(int **buffer)
164         int i;
165         int len = 0;
166 #ifndef TODO
167         int delta_in_us;
168         struct timespec ts;
169         s64 time;
170 #endif
172         /* System wide counters - read from one core only */
173         if (smp_processor_id())
174                 return 0;
176 #ifndef TODO    
177         getnstimeofday(&ts);
178         time = timespec_to_ns(&ts);
179         delta_in_us = (int)(time - prev_time) / 1000;
180         prev_time = time;
181 #endif
183         for (i = 0; i < MMAPED_COUNTERS_NUM; i++) {
184                 if (mmaped_counters[i].enabled) {
185                         mmaped_buffer[len++] = mmaped_counters[i].key;
186 #ifdef TODO
187                         mmaped_buffer[len++] = readl(mmaped_base +
188                                         COUNTERS_VALUE_OFFSET[i]);
189 #else
190                         mmaped_buffer[len++] = mmaped_simulate(
191                                         mmaped_counters[i].event, delta_in_us);
192 #endif
193                 }
194         }
195         
196         if (buffer)
197                 *buffer = mmaped_buffer;
199         return len;
202 static struct gator_interface gator_events_mmaped_interface = {
203         .create_files = gator_events_mmaped_create_files,
204         .start = gator_events_mmaped_start,
205         .stop = gator_events_mmaped_stop,
206         .read = gator_events_mmaped_read,
207 };
209 /* Must not be static! */
210 int __init gator_events_mmaped_init(void)
212         int i;
214 #ifdef TODO
215         mmaped_base = ioremap(COUNTERS_PHYS_ADDR, SZ_4K);
216         if (!mmaped_base)
217                 return -ENOMEM; 
218 #endif
220         for (i = 0; i < MMAPED_COUNTERS_NUM; i++) {
221                 mmaped_counters[i].enabled = 0;
222                 mmaped_counters[i].key = gator_events_get_key();
223         }
225         return gator_events_install(&gator_events_mmaped_interface);
227 gator_events_init(gator_events_mmaped_init);