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