blob: b3e106689d0383ea42f7f709c194e768fbaec8b1 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001#include <linux/string.h>
2#include <linux/slab.h>
3#include <linux/kernel.h>
4
5#include "met_drv.h"
6#include "ondiemet_sspm.h"
7
8
9struct sspm_met_evnet_header {
10 unsigned int rts_event_id;
11 char *rts_event_name;
12 char *chart_line_name;
13 char *key_list;
14};
15
16
17enum {
18 #ifdef MET_SSPM_RTS_EVNET
19 #undef MET_SSPM_RTS_EVNET
20 #endif
21 #define MET_SSPM_RTS_EVNET(rts_event_id, key_list) rts_event_id,
22 #include "met_sspm_rts_event.h"
23
24 /**********************/
25 CUR_MET_RTS_EVENT_NUM,
26 MAX_MET_RTS_EVENT_NUM = 128
27};
28
29
30struct sspm_met_evnet_header met_evnet_header[MAX_MET_RTS_EVENT_NUM] = {
31 #ifdef MET_SSPM_RTS_EVNET
32 #undef MET_SSPM_RTS_EVNET
33 #endif
34 #define MET_SSPM_RTS_EVNET(rts_event_id, key_list) {rts_event_id, #rts_event_id, #rts_event_id, key_list},
35 #include "met_sspm_rts_event.h"
36};
37
38
39static void ondiemet_sspm_start(void);
40static void ondiemet_sspm_stop(void);
41static int ondiemet_sspm_print_help(char *buf, int len);
42static int ondiemet_sspm_process_argument(const char *arg, int len);
43static int ondiemet_sspm_print_header(char *buf, int len);
44
45
46static unsigned int event_id_flag0;
47static unsigned int event_id_flag1;
48static unsigned int event_id_flag2;
49static unsigned int event_id_flag3;
50static char *update_rts_event_tbl[MAX_MET_RTS_EVENT_NUM];
51static char sspm_help[] = " --sspm_common=rts_event_name\n";
52static char header[] = "met-info [000] 0.0: sspm_common_header: ";
53
54struct metdevice met_sspm_common = {
55 .name = "sspm_common",
56 .owner = THIS_MODULE,
57 .type = MET_TYPE_BUS,
58 .cpu_related = 0,
59 .ondiemet_mode = 1,
60 .ondiemet_start = ondiemet_sspm_start,
61 .ondiemet_stop = ondiemet_sspm_stop,
62 .ondiemet_process_argument = ondiemet_sspm_process_argument,
63 .ondiemet_print_help = ondiemet_sspm_print_help,
64 .ondiemet_print_header = ondiemet_sspm_print_header,
65};
66
67
68static int ondiemet_sspm_print_help(char *buf, int len)
69{
70 return snprintf(buf, PAGE_SIZE, sspm_help);
71}
72
73
74static int ondiemet_sspm_print_header(char *buf, int len)
75{
76 int i;
77 int write_len;
78 int flag = 0;
79 static int is_dump_header = 0;
80 static int read_idx = 0;
81
82 len = 0;
83 met_sspm_common.header_read_again = 0;
84 if (is_dump_header == 0) {
85 len = snprintf(buf, PAGE_SIZE, "%s", header);
86 is_dump_header = 1;
87 }
88
89 for (i=read_idx; i<MAX_MET_RTS_EVENT_NUM; i++) {
90 if (met_evnet_header[i].chart_line_name) {
91 if (i <32) {
92 flag = 1<<i;
93 flag = event_id_flag0 & flag;
94 } else if (i >=32 && i < 64) {
95 flag = 1<<(i-32);
96 flag = event_id_flag1 & flag;
97 } else if (i >=64 && i < 96) {
98 flag = 1<<(i-64);
99 flag = event_id_flag2 & flag;
100 } else if (i >=96 && i < 128) {
101 flag = 1<<(i-96);
102 flag = event_id_flag3 & flag;
103 }
104 if (flag == 0)
105 continue;
106
107 write_len = strlen(met_evnet_header[i].chart_line_name) + strlen(met_evnet_header[i].key_list) + 3;
108 if ((len+write_len) < PAGE_SIZE) {
109 len += snprintf(buf+len, PAGE_SIZE-len, "%u,%s,%s;",
110 met_evnet_header[i].rts_event_id,
111 met_evnet_header[i].chart_line_name,
112 met_evnet_header[i].key_list);
113 } else {
114 met_sspm_common.header_read_again = 1;
115 read_idx = i;
116 return len;
117 }
118 }
119 }
120
121 if (i == MAX_MET_RTS_EVENT_NUM) {
122 is_dump_header = 0;
123 read_idx = 0;
124 buf[len-1] = '\n';
125 for (i=0; i<MAX_MET_RTS_EVENT_NUM; i++) {
126 if (update_rts_event_tbl[i]) {
127 kfree(update_rts_event_tbl[i]);
128 update_rts_event_tbl[i] = NULL;
129 }
130 }
131 met_sspm_common.mode = 0;
132 event_id_flag0 = 0;
133 event_id_flag1 = 0;
134 event_id_flag2 = 0;
135 event_id_flag3 = 0;
136 }
137
138 return len;
139}
140
141
142static void ondiemet_sspm_start(void)
143{
144 if (sspm_buf_available == 0)
145 return ;
146
147 /* ID_COMMON = 1<<MID_COMMON */
148 ondiemet_module[ONDIEMET_SSPM] |= ID_COMMON;
149}
150
151
152static void ondiemet_sspm_stop(void)
153{
154 if (sspm_buf_available == 0)
155 return ;
156}
157
158
159static void update_event_id_flag(int event_id)
160{
161 unsigned int ipi_buf[4];
162 unsigned int rdata;
163 unsigned int res;
164
165 if (sspm_buf_available == 0)
166 return ;
167
168 /* main func ID: bit[31-24]; sub func ID: bit[23-18]; argu 0: bit[17-0]
169 #define MET_MAIN_ID_MASK 0xff000000
170 #define FUNC_BIT_SHIFT 18
171 #define MET_ARGU (4 << FUNC_BIT_SHIFT)
172 #define MID_BIT_SHIFT 9
173 */
174 if (event_id <32) {
175 event_id_flag0 |= 1<<event_id;
176 ipi_buf[0] = MET_MAIN_ID | MET_ARGU | MID_COMMON<<MID_BIT_SHIFT | 1;
177 ipi_buf[1] = 0;
178 ipi_buf[2] = event_id_flag0;
179 ipi_buf[3] = 0;
180 res = sspm_ipi_send_sync(IPI_ID_MET, IPI_OPT_WAIT, (void *)ipi_buf, 0, &rdata, 1);
181 } else if (event_id >=32 && event_id < 64) {
182 event_id_flag1 |= 1<<(event_id-32);
183 ipi_buf[0] = MET_MAIN_ID | MET_ARGU | MID_COMMON<<MID_BIT_SHIFT | 1;
184 ipi_buf[1] = 1;
185 ipi_buf[2] = event_id_flag1;
186 ipi_buf[3] = 0;
187 res = sspm_ipi_send_sync(IPI_ID_MET, IPI_OPT_WAIT, (void *)ipi_buf, 0, &rdata, 1);
188 } else if (event_id >=64 && event_id < 96) {
189 event_id_flag2 |= 1<<(event_id-64);
190 ipi_buf[0] = MET_MAIN_ID | MET_ARGU | MID_COMMON<<MID_BIT_SHIFT | 1;
191 ipi_buf[1] = 2;
192 ipi_buf[2] = event_id_flag2;
193 ipi_buf[3] = 0;
194 res = sspm_ipi_send_sync(IPI_ID_MET, IPI_OPT_WAIT, (void *)ipi_buf, 0, &rdata, 1);
195 } else if (event_id >=96 && event_id < 128) {
196 event_id_flag3 = 1<<(event_id-96);
197 ipi_buf[0] |= MET_MAIN_ID | MET_ARGU | MID_COMMON<<MID_BIT_SHIFT | 1;
198 ipi_buf[1] = 3;
199 ipi_buf[2] = event_id_flag3;
200 ipi_buf[3] = 0;
201 res = sspm_ipi_send_sync(IPI_ID_MET, IPI_OPT_WAIT, (void *)ipi_buf, 0, &rdata, 1);
202 }
203 met_sspm_common.mode = 1;
204}
205
206
207static char *strdup(const char *s)
208{
209 char *p = kmalloc(strlen(s) + 1, GFP_KERNEL);
210
211 if (p)
212 strcpy(p, s);
213 return p;
214}
215
216
217static int ondiemet_sspm_process_argument(const char *arg, int len)
218{
219 int i;
220 int rts_event_id = -1;
221 int res;
222 char *line;
223 char *token;
224
225 for (i=0; met_evnet_header[i].rts_event_name && i<MAX_MET_RTS_EVENT_NUM; i++) {
226 if (strcmp(met_evnet_header[i].rts_event_name, arg) == 0) {
227 rts_event_id = i;
228 break;
229 }
230 }
231 if (strstarts(arg, "update_rts_event_tbl")) {
232 char *ptr;
233
234 /* update_rts_event_tbl=rts_event_id;rts_event_name;chart_line_name;key_list*/
235 line = strdup(arg);
236 if (line == NULL)
237 return -1;
238 ptr = line;
239 token = strsep(&line, "=");
240
241 /* rts_event_id, */
242 token = strsep(&line, ";");
243 res = kstrtoint(token, 10, &rts_event_id);
244 met_evnet_header[rts_event_id].rts_event_id = rts_event_id;
245
246 /* rts_event_name */
247 token = strsep(&line, ";");
248 met_evnet_header[rts_event_id].rts_event_name = token;
249
250 /* chart_line_name */
251 token = strsep(&line, ";");
252 met_evnet_header[rts_event_id].chart_line_name = token;
253
254 /* key_list */
255 token = strsep(&line, ";\n");
256 met_evnet_header[rts_event_id].key_list = token;
257
258 update_rts_event_tbl[rts_event_id] = ptr;
259 }
260
261 if (rts_event_id >=0)
262 update_event_id_flag(rts_event_id);
263
264 return 0;
265}
266EXPORT_SYMBOL(met_sspm_common);