blob: 14879ffd9ba668f72ec4ef53921c9ac4f8dc7da7 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (C) 2018 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/kernel.h>
15#include <linux/sched.h>
16#include <linux/device.h>
17#include <linux/miscdevice.h>
18#include <linux/module.h>
19#include <linux/dma-mapping.h>
20#include <linux/string.h>
21
22#define MET_USER_EVENT_SUPPORT
23#include "met_drv.h"
24#include "trace.h"
25#include "interface.h"
26
27#include "mtk_typedefs.h"
28#include "core_plf_init.h"
29/* #include "plf_trace.h" */
30#include "mtk_emi_bm.h"
31
32#ifdef CONFIG_MTK_TINYSYS_SSPM_SUPPORT
33#include "sspm/ondiemet_sspm.h"
34#endif
35
36/*======================================================================*/
37/* Global variable definitions */
38/*======================================================================*/
39int emi_TP_busfiltr_enable;
40static int msel_enable;
41static unsigned int msel_group1 = _GP_1_Default;
42static unsigned int msel_group2 = _GP_2_Default;
43static unsigned int msel_group3 = _GP_3_Default;
44
45/* Global variables */
46static struct kobject *kobj_emi;
47
48static int ttype1_16_en = BM_TTYPE1_16_DISABLE;
49static int ttype17_21_en = BM_TTYPE17_21_DISABLE;
50
51
52
53static int times;
54static ssize_t test_store(struct kobject *kobj,
55 struct kobj_attribute *attr,
56 const char *buf,
57 size_t n)
58{
59 int i;
60 unsigned int *src_addr_v;
61 dma_addr_t src_addr_p;
62
63 if ((n == 0) || (buf == NULL))
64 return -EINVAL;
65 if (kstrtoint(buf, 10, &times) != 0)
66 return -EINVAL;
67 if (times < 0)
68 return -EINVAL;
69
70 if (times > 5000)
71 return -EINVAL;
72
73
74 src_addr_v = dma_alloc_coherent(met_device.this_device,
75 PAGE_SIZE,
76 &src_addr_p,
77 GFP_KERNEL);
78 if (src_addr_v == NULL) {
79#ifdef CONFIG_MET_MODULE
80 met_tag_oneshot_real(0, "test dma alloc fail", PAGE_SIZE);
81#else
82 met_tag_oneshot(0, "test dma alloc fail", PAGE_SIZE);
83#endif
84 return -ENOMEM;
85 }
86
87 preempt_disable();
88#ifdef CONFIG_MET_MODULE
89 met_tag_start_real(0, "TEST_EMI");
90#else
91 met_tag_start(0, "TEST_EMI");
92#endif
93 for (i = 0; i < times; i++) {
94 memset(src_addr_v, 2*i, PAGE_SIZE);
95#ifdef CONFIG_MET_MODULE
96 met_tag_oneshot_real(0, "TEST_EMI", PAGE_SIZE);
97#else
98 met_tag_oneshot(0, "TEST_EMI", PAGE_SIZE);
99#endif
100 }
101#ifdef CONFIG_MET_MODULE
102 met_tag_end_real(0, "TEST_EMI");
103#else
104 met_tag_end(0, "TEST_EMI");
105#endif
106
107 my_preempt_enable();
108
109 if (src_addr_v != NULL)
110 dma_free_coherent(met_device.this_device,
111 PAGE_SIZE,
112 src_addr_v,
113 src_addr_p);
114 return n;
115}
116
117/*======================================================================*/
118/* KOBJ Declarations */
119/*======================================================================*/
120DECLARE_KOBJ_ATTR_INT(emi_TP_busfiltr_enable, emi_TP_busfiltr_enable);
121DECLARE_KOBJ_ATTR_INT(msel_enable, msel_enable);
122DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group1, msel_group1, msel_group1 > 0 && msel_group1 <= _ALL);
123DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group2, msel_group2, msel_group2 > 0 && msel_group2 <= _ALL);
124DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group3, msel_group3, msel_group3 > 0 && msel_group3 <= _ALL);
125
126
127DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
128 ttype1_16_en,
129 KOBJ_ITEM_LIST(
130 { BM_TTYPE1_16_ENABLE, "ENABLE" },
131 { BM_TTYPE1_16_DISABLE, "DISABLE" }
132 )
133 );
134DECLARE_KOBJ_ATTR_STR_LIST(ttype1_16_en, ttype1_16_en, ttype1_16_en);
135
136
137DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
138 ttype17_21_en,
139 KOBJ_ITEM_LIST(
140 { BM_TTYPE17_21_ENABLE, "ENABLE" },
141 { BM_TTYPE17_21_DISABLE, "DISABLE" }
142 )
143 );
144DECLARE_KOBJ_ATTR_STR_LIST(ttype17_21_en, ttype17_21_en, ttype17_21_en);
145
146DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
147 ttype_master,
148 KOBJ_ITEM_LIST(
149 { _M0, "M0" },
150 { _M1, "M1" },
151 { _M2, "M2" },
152 { _M3, "M3" },
153 { _M4, "M4" },
154 { _M5, "M5" },
155 { _M6, "M6" },
156 { _M7, "M7" }
157 )
158 );
159
160
161DECLARE_KOBJ_ATTR_INT_LIST_ITEM(
162 ttype_nbeat,
163 KOBJ_ITEM_LIST(
164 { BM_TRANS_TYPE_1BEAT, 1 },
165 { BM_TRANS_TYPE_2BEAT, 2 },
166 { BM_TRANS_TYPE_3BEAT, 3 },
167 { BM_TRANS_TYPE_4BEAT, 4 },
168 { BM_TRANS_TYPE_5BEAT, 5 },
169 { BM_TRANS_TYPE_6BEAT, 6 },
170 { BM_TRANS_TYPE_7BEAT, 7 },
171 { BM_TRANS_TYPE_8BEAT, 8 },
172 { BM_TRANS_TYPE_9BEAT, 9 },
173 { BM_TRANS_TYPE_10BEAT, 10 },
174 { BM_TRANS_TYPE_11BEAT, 11 },
175 { BM_TRANS_TYPE_12BEAT, 12 },
176 { BM_TRANS_TYPE_13BEAT, 13 },
177 { BM_TRANS_TYPE_14BEAT, 14 },
178 { BM_TRANS_TYPE_15BEAT, 15 },
179 { BM_TRANS_TYPE_16BEAT, 16 }
180 )
181 );
182DECLARE_KOBJ_ATTR_INT_LIST_ITEM(
183 ttype_nbyte,
184 KOBJ_ITEM_LIST(
185 { BM_TRANS_TYPE_1Byte, 1 },
186 { BM_TRANS_TYPE_2Byte, 2 },
187 { BM_TRANS_TYPE_4Byte, 4 },
188 { BM_TRANS_TYPE_8Byte, 8 },
189 { BM_TRANS_TYPE_16Byte, 16 },
190 { BM_TRANS_TYPE_32Byte, 32 }
191 )
192 );
193DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
194 ttype_burst,
195 KOBJ_ITEM_LIST(
196 { BM_TRANS_TYPE_BURST_INCR, "INCR" },
197 { BM_TRANS_TYPE_BURST_WRAP, "WRAP" }
198 )
199 );
200
201DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
202 ttype_rw,
203 KOBJ_ITEM_LIST(
204 { BM_TRANS_RW_DEFAULT, "DEFAULT" },
205 { BM_TRANS_RW_READONLY, "R" },
206 { BM_TRANS_RW_WRITEONLY, "W" },
207 { BM_TRANS_RW_RWBOTH, "BOTH" }
208 )
209 );
210
211
212DECLARE_KOBJ_ATTR_SHOW_INT(test, times);
213
214DECLARE_KOBJ_ATTR(test);
215
216
217static int high_priority_filter;
218DECLARE_KOBJ_ATTR_HEX(high_priority_filter, high_priority_filter);
219
220
221static int ttype_master_val[21];
222static int ttype_busid_val[21];
223static int ttype_nbeat_val[21];
224static int ttype_nbyte_val[21];
225static int ttype_burst_val[21];
226static int ttype_rw_val[21];
227
228#define DECLARE_KOBJ_TTYPE_MASTER(nr) \
229 DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _master, ttype_master_val[nr - 1], ttype_master)
230
231#define DECLARE_KOBJ_TTYPE_NBEAT(nr) \
232 DECLARE_KOBJ_ATTR_INT_LIST(ttype ## nr ## _nbeat, ttype_nbeat_val[nr - 1], ttype_nbeat)
233
234#define DECLARE_KOBJ_TTYPE_NBYTE(nr) \
235 DECLARE_KOBJ_ATTR_INT_LIST(ttype ## nr ## _nbyte, ttype_nbyte_val[nr - 1], ttype_nbyte)
236
237#define DECLARE_KOBJ_TTYPE_BURST(nr) \
238 DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _burst, ttype_burst_val[nr - 1], ttype_burst)
239
240#define DECLARE_KOBJ_TTYPE_RW(nr) \
241 DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _rw, ttype_rw_val[nr - 1], ttype_rw)
242
243#define DECLARE_KOBJ_TTYPE_BUSID_VAL(nr) \
244 DECLARE_KOBJ_ATTR_HEX(ttype ## nr ## _busid, ttype_busid_val[nr - 1])
245
246DECLARE_KOBJ_TTYPE_MASTER(1);
247DECLARE_KOBJ_TTYPE_NBEAT(1);
248DECLARE_KOBJ_TTYPE_NBYTE(1);
249DECLARE_KOBJ_TTYPE_BURST(1);
250DECLARE_KOBJ_TTYPE_RW(1);
251DECLARE_KOBJ_TTYPE_BUSID_VAL(1);
252
253DECLARE_KOBJ_TTYPE_MASTER(2);
254DECLARE_KOBJ_TTYPE_NBEAT(2);
255DECLARE_KOBJ_TTYPE_NBYTE(2);
256DECLARE_KOBJ_TTYPE_BURST(2);
257DECLARE_KOBJ_TTYPE_RW(2);
258DECLARE_KOBJ_TTYPE_BUSID_VAL(2);
259
260DECLARE_KOBJ_TTYPE_MASTER(3);
261DECLARE_KOBJ_TTYPE_NBEAT(3);
262DECLARE_KOBJ_TTYPE_NBYTE(3);
263DECLARE_KOBJ_TTYPE_BURST(3);
264DECLARE_KOBJ_TTYPE_RW(3);
265DECLARE_KOBJ_TTYPE_BUSID_VAL(3);
266
267DECLARE_KOBJ_TTYPE_MASTER(4);
268DECLARE_KOBJ_TTYPE_NBEAT(4);
269DECLARE_KOBJ_TTYPE_NBYTE(4);
270DECLARE_KOBJ_TTYPE_BURST(4);
271DECLARE_KOBJ_TTYPE_RW(4);
272DECLARE_KOBJ_TTYPE_BUSID_VAL(4);
273
274DECLARE_KOBJ_TTYPE_MASTER(5);
275DECLARE_KOBJ_TTYPE_NBEAT(5);
276DECLARE_KOBJ_TTYPE_NBYTE(5);
277DECLARE_KOBJ_TTYPE_BURST(5);
278DECLARE_KOBJ_TTYPE_RW(5);
279DECLARE_KOBJ_TTYPE_BUSID_VAL(5);
280
281DECLARE_KOBJ_TTYPE_MASTER(6);
282DECLARE_KOBJ_TTYPE_NBEAT(6);
283DECLARE_KOBJ_TTYPE_NBYTE(6);
284DECLARE_KOBJ_TTYPE_BURST(6);
285DECLARE_KOBJ_TTYPE_RW(6);
286DECLARE_KOBJ_TTYPE_BUSID_VAL(6);
287
288DECLARE_KOBJ_TTYPE_MASTER(7);
289DECLARE_KOBJ_TTYPE_NBEAT(7);
290DECLARE_KOBJ_TTYPE_NBYTE(7);
291DECLARE_KOBJ_TTYPE_BURST(7);
292DECLARE_KOBJ_TTYPE_RW(7);
293DECLARE_KOBJ_TTYPE_BUSID_VAL(7);
294
295DECLARE_KOBJ_TTYPE_MASTER(8);
296DECLARE_KOBJ_TTYPE_NBEAT(8);
297DECLARE_KOBJ_TTYPE_NBYTE(8);
298DECLARE_KOBJ_TTYPE_BURST(8);
299DECLARE_KOBJ_TTYPE_RW(8);
300DECLARE_KOBJ_TTYPE_BUSID_VAL(8);
301
302DECLARE_KOBJ_TTYPE_MASTER(9);
303DECLARE_KOBJ_TTYPE_NBEAT(9);
304DECLARE_KOBJ_TTYPE_NBYTE(9);
305DECLARE_KOBJ_TTYPE_BURST(9);
306DECLARE_KOBJ_TTYPE_RW(9);
307DECLARE_KOBJ_TTYPE_BUSID_VAL(9);
308
309DECLARE_KOBJ_TTYPE_MASTER(10);
310DECLARE_KOBJ_TTYPE_NBEAT(10);
311DECLARE_KOBJ_TTYPE_NBYTE(10);
312DECLARE_KOBJ_TTYPE_BURST(10);
313DECLARE_KOBJ_TTYPE_RW(10);
314DECLARE_KOBJ_TTYPE_BUSID_VAL(10);
315
316DECLARE_KOBJ_TTYPE_MASTER(11);
317DECLARE_KOBJ_TTYPE_NBEAT(11);
318DECLARE_KOBJ_TTYPE_NBYTE(11);
319DECLARE_KOBJ_TTYPE_BURST(11);
320DECLARE_KOBJ_TTYPE_RW(11);
321DECLARE_KOBJ_TTYPE_BUSID_VAL(11);
322
323DECLARE_KOBJ_TTYPE_MASTER(12);
324DECLARE_KOBJ_TTYPE_NBEAT(12);
325DECLARE_KOBJ_TTYPE_NBYTE(12);
326DECLARE_KOBJ_TTYPE_BURST(12);
327DECLARE_KOBJ_TTYPE_RW(12);
328DECLARE_KOBJ_TTYPE_BUSID_VAL(12);
329
330DECLARE_KOBJ_TTYPE_MASTER(13);
331DECLARE_KOBJ_TTYPE_NBEAT(13);
332DECLARE_KOBJ_TTYPE_NBYTE(13);
333DECLARE_KOBJ_TTYPE_BURST(13);
334DECLARE_KOBJ_TTYPE_RW(13);
335DECLARE_KOBJ_TTYPE_BUSID_VAL(13);
336
337DECLARE_KOBJ_TTYPE_MASTER(14);
338DECLARE_KOBJ_TTYPE_NBEAT(14);
339DECLARE_KOBJ_TTYPE_NBYTE(14);
340DECLARE_KOBJ_TTYPE_BURST(14);
341DECLARE_KOBJ_TTYPE_RW(14);
342DECLARE_KOBJ_TTYPE_BUSID_VAL(14);
343
344DECLARE_KOBJ_TTYPE_MASTER(15);
345DECLARE_KOBJ_TTYPE_NBEAT(15);
346DECLARE_KOBJ_TTYPE_NBYTE(15);
347DECLARE_KOBJ_TTYPE_BURST(15);
348DECLARE_KOBJ_TTYPE_RW(15);
349DECLARE_KOBJ_TTYPE_BUSID_VAL(15);
350
351DECLARE_KOBJ_TTYPE_MASTER(16);
352DECLARE_KOBJ_TTYPE_NBEAT(16);
353DECLARE_KOBJ_TTYPE_NBYTE(16);
354DECLARE_KOBJ_TTYPE_BURST(16);
355DECLARE_KOBJ_TTYPE_RW(16);
356DECLARE_KOBJ_TTYPE_BUSID_VAL(16);
357
358DECLARE_KOBJ_TTYPE_MASTER(17);
359DECLARE_KOBJ_TTYPE_NBEAT(17);
360DECLARE_KOBJ_TTYPE_NBYTE(17);
361DECLARE_KOBJ_TTYPE_BURST(17);
362DECLARE_KOBJ_TTYPE_RW(17);
363DECLARE_KOBJ_TTYPE_BUSID_VAL(17);
364
365DECLARE_KOBJ_TTYPE_MASTER(18);
366DECLARE_KOBJ_TTYPE_NBEAT(18);
367DECLARE_KOBJ_TTYPE_NBYTE(18);
368DECLARE_KOBJ_TTYPE_BURST(18);
369DECLARE_KOBJ_TTYPE_RW(18);
370DECLARE_KOBJ_TTYPE_BUSID_VAL(18);
371
372DECLARE_KOBJ_TTYPE_MASTER(19);
373DECLARE_KOBJ_TTYPE_NBEAT(19);
374DECLARE_KOBJ_TTYPE_NBYTE(19);
375DECLARE_KOBJ_TTYPE_BURST(19);
376DECLARE_KOBJ_TTYPE_RW(19);
377DECLARE_KOBJ_TTYPE_BUSID_VAL(19);
378
379DECLARE_KOBJ_TTYPE_MASTER(20);
380DECLARE_KOBJ_TTYPE_NBEAT(20);
381DECLARE_KOBJ_TTYPE_NBYTE(20);
382DECLARE_KOBJ_TTYPE_BURST(20);
383DECLARE_KOBJ_TTYPE_RW(20);
384DECLARE_KOBJ_TTYPE_BUSID_VAL(20);
385
386DECLARE_KOBJ_TTYPE_MASTER(21);
387DECLARE_KOBJ_TTYPE_NBEAT(21);
388DECLARE_KOBJ_TTYPE_NBYTE(21);
389DECLARE_KOBJ_TTYPE_BURST(21);
390DECLARE_KOBJ_TTYPE_RW(21);
391DECLARE_KOBJ_TTYPE_BUSID_VAL(21);
392
393#define KOBJ_ATTR_ITEM_SERIAL_FNODE(nr) \
394 do { \
395 KOBJ_ATTR_ITEM(ttype ## nr ## _master); \
396 KOBJ_ATTR_ITEM(ttype ## nr ## _nbeat); \
397 KOBJ_ATTR_ITEM(ttype ## nr ## _nbyte); \
398 KOBJ_ATTR_ITEM(ttype ## nr ## _burst); \
399 KOBJ_ATTR_ITEM(ttype ## nr ## _busid); \
400 KOBJ_ATTR_ITEM(ttype ## nr ## _rw); \
401 } while (0)
402
403#define KOBJ_ATTR_LIST \
404 do { \
405 KOBJ_ATTR_ITEM(high_priority_filter); \
406 KOBJ_ATTR_ITEM(emi_TP_busfiltr_enable); \
407 KOBJ_ATTR_ITEM(msel_enable); \
408 KOBJ_ATTR_ITEM(msel_group1); \
409 KOBJ_ATTR_ITEM(msel_group2); \
410 KOBJ_ATTR_ITEM(msel_group3); \
411 KOBJ_ATTR_ITEM(ttype17_21_en); \
412 KOBJ_ATTR_ITEM(ttype1_16_en); \
413 KOBJ_ATTR_ITEM_SERIAL_FNODE(1); \
414 KOBJ_ATTR_ITEM_SERIAL_FNODE(2); \
415 KOBJ_ATTR_ITEM_SERIAL_FNODE(3); \
416 KOBJ_ATTR_ITEM_SERIAL_FNODE(4); \
417 KOBJ_ATTR_ITEM_SERIAL_FNODE(5); \
418 KOBJ_ATTR_ITEM_SERIAL_FNODE(6); \
419 KOBJ_ATTR_ITEM_SERIAL_FNODE(7); \
420 KOBJ_ATTR_ITEM_SERIAL_FNODE(8); \
421 KOBJ_ATTR_ITEM_SERIAL_FNODE(9); \
422 KOBJ_ATTR_ITEM_SERIAL_FNODE(10); \
423 KOBJ_ATTR_ITEM_SERIAL_FNODE(11); \
424 KOBJ_ATTR_ITEM_SERIAL_FNODE(12); \
425 KOBJ_ATTR_ITEM_SERIAL_FNODE(13); \
426 KOBJ_ATTR_ITEM_SERIAL_FNODE(14); \
427 KOBJ_ATTR_ITEM_SERIAL_FNODE(15); \
428 KOBJ_ATTR_ITEM_SERIAL_FNODE(16); \
429 KOBJ_ATTR_ITEM_SERIAL_FNODE(17); \
430 KOBJ_ATTR_ITEM_SERIAL_FNODE(18); \
431 KOBJ_ATTR_ITEM_SERIAL_FNODE(19); \
432 KOBJ_ATTR_ITEM_SERIAL_FNODE(20); \
433 KOBJ_ATTR_ITEM_SERIAL_FNODE(21); \
434 KOBJ_ATTR_ITEM(test); \
435 } while (0)
436
437/*======================================================================*/
438/* EMI Operations */
439/*======================================================================*/
440static void emi_init(void)
441{
442 unsigned int bmrw0_val = 0, bmrw1_val = 0, i, enable;
443 unsigned int msel_group_val[4];
444
445 MET_BM_SaveCfg();
446
447 if ((ttype1_16_en != BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable != 1)) {
448 if (msel_enable) {
449 msel_group_val[0] = _ALL;
450 msel_group_val[1] = msel_group1;
451 msel_group_val[2] = msel_group2;
452 msel_group_val[3] = msel_group3;
453 } else {
454 msel_group_val[0] = _ALL;
455 msel_group_val[1] = _GP_1_Default;
456 msel_group_val[2] = _GP_2_Default;
457 msel_group_val[3] = _GP_3_Default;
458 }
459
460 MET_BM_SetLatencyCounter(1);
461
462 for (i = 1; i <= 4; i++) {
463 MET_BM_SetMonitorCounter(i,
464 msel_group_val[i - 1] & _ALL,
465 BM_TRANS_TYPE_4BEAT |
466 BM_TRANS_TYPE_8Byte |
467 BM_TRANS_TYPE_BURST_WRAP);
468 MET_BM_SetbusID(i, 0);
469 MET_BM_SetbusID_En(i, 0);
470 }
471 for (i = 0; i < 4; i++)
472 MET_BM_Set_WsctTsct_id_sel(i, 0);
473
474 } else if ((ttype1_16_en != BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable == 1)) {
475 MET_BM_SetLatencyCounter(1);
476
477 for (i = 1; i <= 4; i++) {
478 MET_BM_SetMonitorCounter(i,
479 ttype_master_val[i - 1],
480 ttype_nbeat_val[i - 1] |
481 ttype_nbyte_val[i - 1] |
482 ttype_burst_val[i - 1]);
483 MET_BM_SetbusID(i, ttype_busid_val[i - 1]);
484 MET_BM_SetbusID_En(i, 0);
485 }
486 for (i = 0; i < 4; i++)
487 MET_BM_Set_WsctTsct_id_sel(i, 1);
488
489 } else if ((ttype1_16_en == BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable != 1)) {
490 MET_BM_SetLatencyCounter(0);
491
492 for (i = 1; i <= 16; i++) {
493 MET_BM_SetMonitorCounter(i,
494 ttype_master_val[i - 1],
495 ttype_nbeat_val[i - 1] |
496 ttype_nbyte_val[i - 1] |
497 ttype_burst_val[i - 1]);
498
499 MET_BM_SetbusID(i, ttype_busid_val[i - 1]);
500
501 MET_BM_SetbusID_En(i, (ttype_busid_val[i - 1] > 0xffff) ? 0 : 1);
502 }
503 for (i = 0; i < 4; i++)
504 MET_BM_Set_WsctTsct_id_sel(i, 0);
505 } else { /* (ttype1_16_en == BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable == 1) */
506
507 MET_BM_SetLatencyCounter(0);
508
509 for (i = 1; i <= 16; i++) {
510 MET_BM_SetMonitorCounter(i,
511 ttype_master_val[i - 1],
512 ttype_nbeat_val[i - 1] |
513 ttype_nbyte_val[i - 1] |
514 ttype_burst_val[i - 1]);
515
516 MET_BM_SetbusID(i, ttype_busid_val[i - 1]);
517
518 MET_BM_SetbusID_En(i, (ttype_busid_val[i - 1] > 0xffff) ? 0 : 1);
519 }
520 for (i = 0; i < 4; i++)
521 MET_BM_Set_WsctTsct_id_sel(i, 1);
522 }
523
524 if (ttype17_21_en == BM_TTYPE17_21_ENABLE) {
525 for (i = 17; i <= 21; i++) {
526 MET_BM_SetMonitorCounter(i,
527 ttype_master_val[i - 1],
528 ttype_nbeat_val[i - 1] |
529 ttype_nbyte_val[i - 1] |
530 ttype_burst_val[i - 1]);
531 MET_BM_SetbusID(i, ttype_busid_val[i - 1]);
532
533 MET_BM_SetbusID_En(i, (ttype_busid_val[i - 1] > 0xffff) ? 0 : 1);
534 }
535 }
536
537 bmrw0_val = (
538 (ttype_rw_val[0] << 0) | (ttype_rw_val[1] << 2) |
539 (ttype_rw_val[2] << 4) | (ttype_rw_val[3] << 6) |
540 (ttype_rw_val[4] << 8) | (ttype_rw_val[5] << 10) |
541 (ttype_rw_val[6] << 12) | (ttype_rw_val[7] << 14) |
542 (ttype_rw_val[8] << 16) | (ttype_rw_val[9] << 18) |
543 (ttype_rw_val[10] << 20) | (ttype_rw_val[11] << 22) |
544 (ttype_rw_val[12] << 24) | (ttype_rw_val[13] << 26) |
545 (ttype_rw_val[14] << 28) | (ttype_rw_val[15] << 30));
546
547 bmrw1_val = (
548 (ttype_rw_val[16] << 0) | (ttype_rw_val[17] << 2) |
549 (ttype_rw_val[18] << 4) | (ttype_rw_val[19] << 6) |
550 (ttype_rw_val[20] << 8));
551
552 MET_BM_SetTtypeCounterRW(bmrw0_val, bmrw1_val);
553
554 for (i = 0; i < BM_COUNTER_MAX; i++) {
555 if ((high_priority_filter & (1 << i)) == 0)
556 enable = 0;
557 else
558 enable = 1;
559
560 MET_BM_SetUltraHighFilter(i + 1, enable);
561 }
562
563}
564
565static inline int do_emi(void)
566{
567 return met_sspm_emi.mode;
568}
569
570/*======================================================================*/
571/* MET Device Operations */
572/*======================================================================*/
573static int emi_inited;
574static int met_emi_create(struct kobject *parent)
575{
576 int ret = 0;
577 int i;
578
579 for (i = 0; i < 21; i++) {
580 ttype_master_val[i] = _M0;
581 ttype_nbeat_val[i] = BM_TRANS_TYPE_1BEAT;
582 ttype_nbyte_val[i] = BM_TRANS_TYPE_8Byte;
583 ttype_burst_val[i] = BM_TRANS_TYPE_BURST_INCR;
584 ttype_busid_val[i] = 0xfffff;
585 ttype_rw_val[i] = BM_TRANS_RW_DEFAULT;
586 }
587 ret = MET_BM_Init();
588 if (ret != 0) {
589 pr_debug("MET_BM_Init failed!!!\n");
590 ret = 0;
591 } else
592 emi_inited = 1;
593
594 kobj_emi = parent;
595
596#define KOBJ_ATTR_ITEM(attr_name) \
597do { \
598 ret = sysfs_create_file(kobj_emi, &attr_name##_attr.attr); \
599 if (ret != 0) { \
600 pr_debug("Failed to create " #attr_name " in sysfs\n"); \
601 return ret; \
602 } \
603} while (0)
604 KOBJ_ATTR_LIST;
605#undef KOBJ_ATTR_ITEM
606
607 return ret;
608}
609
610static void met_emi_delete(void)
611{
612#define KOBJ_ATTR_ITEM(attr_name) \
613 sysfs_remove_file(kobj_emi, &attr_name##_attr.attr)
614 if (kobj_emi != NULL) {
615 KOBJ_ATTR_LIST;
616 kobj_emi = NULL;
617 }
618#undef KOBJ_ATTR_ITEM
619
620 if (emi_inited)
621 MET_BM_DeInit();
622}
623
624
625static void met_emi_resume(void)
626{
627 if (!do_emi())
628 return;
629
630 emi_init();
631}
632
633
634#ifdef CONFIG_MTK_TINYSYS_SSPM_SUPPORT
635static const char help[] = " --emi monitor EMI banwidth\n";
636
637#define TTYPE_NAME_STR_LEN 64
638static char ttype_name[21][TTYPE_NAME_STR_LEN];
639
640static int emi_print_help(char *buf, int len)
641{
642 return snprintf(buf, PAGE_SIZE, help);
643}
644
645static int emi_print_header(char *buf, int len)
646{
647 int ret = 0;
648 int ret_m[21];
649 int i = 0;
650
651
652 for (i = 0; i < 21; i++) {
653 int k;
654
655 if (ttype_busid_val[i] > 0xffff) {
656 int j;
657
658 for (j = 0; j < ARRAY_SIZE(ttype_master_list_item); j++) {
659 if (ttype_master_val[i] == ttype_master_list_item[j].key) {
660 ret_m[i] = snprintf(ttype_name[i], TTYPE_NAME_STR_LEN, "ttyp%d_%s",
661 i + 1, ttype_master_list_item[j].val);
662 break;
663 }
664 }
665 if (j == ARRAY_SIZE(ttype_master_list_item))
666 ret_m[i] = snprintf(ttype_name[i], TTYPE_NAME_STR_LEN, "ttyp%d_%s",
667 i + 1, "unknown");
668 } else {
669 ret_m[i] = snprintf(ttype_name[i], TTYPE_NAME_STR_LEN, "ttyp%d_%x",
670 i + 1, ttype_busid_val[i]);
671 }
672
673 for (k = 0; k < ARRAY_SIZE(ttype_nbeat_list_item); k++) {
674 if (ttype_nbeat_val[i] == ttype_nbeat_list_item[k].key)
675 ret_m[i] += snprintf(ttype_name[i] + ret_m[i], TTYPE_NAME_STR_LEN - ret_m[i], "_%d",
676 ttype_nbeat_list_item[k].val);
677 }
678
679 for (k = 0; k < ARRAY_SIZE(ttype_nbyte_list_item); k++) {
680 if (ttype_nbyte_val[i] == ttype_nbyte_list_item[k].key)
681 ret_m[i] += snprintf(ttype_name[i] + ret_m[i], TTYPE_NAME_STR_LEN - ret_m[i], "x%d",
682 ttype_nbyte_list_item[k].val);
683 }
684
685 for (k = 0; k < ARRAY_SIZE(ttype_burst_list_item); k++) {
686 if (ttype_burst_val[i] == ttype_burst_list_item[k].key)
687 ret_m[i] += snprintf(ttype_name[i] + ret_m[i], TTYPE_NAME_STR_LEN - ret_m[i], "_%s",
688 ttype_burst_list_item[k].val);
689 }
690
691 for (k = 0; k < ARRAY_SIZE(ttype_rw_list_item); k++) {
692 if (ttype_rw_val[i] == ttype_rw_list_item[k].key)
693 ret_m[i] += snprintf(ttype_name[i] + ret_m[i], TTYPE_NAME_STR_LEN - ret_m[i], "_%s",
694 ttype_rw_list_item[k].val);
695 }
696 }
697 if ((ttype1_16_en != BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable != 1)) {
698 if (msel_enable) {
699 ret += snprintf(buf + ret, PAGE_SIZE - ret,
700 "met-info [000] 0.0: met_emi_msel: %x,%x,%x\n",
701 msel_group1 & _ALL,
702 msel_group2 & _ALL,
703 msel_group3 & _ALL);
704 } else {
705 ret += snprintf(buf + ret, PAGE_SIZE - ret,
706 "met-info [000] 0.0: met_emi_msel: %x,%x,%x\n",
707 _GP_1_Default & _ALL,
708 _GP_2_Default & _ALL,
709 _GP_3_Default & _ALL);
710 }
711 } else {
712 ret += snprintf(buf + ret, PAGE_SIZE - ret,
713 "met-info [000] 0.0: met_emi_ttype_master: %x,%x,%x,%x\n",
714 ttype_master_val[0], ttype_master_val[1], ttype_master_val[2], ttype_master_val[3]);
715
716 if (emi_TP_busfiltr_enable == 1) {
717
718 ret += snprintf(buf + ret, PAGE_SIZE - ret,
719 "met-info [000] 0.0: met_emi_ttype_busid: %x,%x,%x,%x\n",
720 ttype_busid_val[0], ttype_busid_val[1], ttype_busid_val[2], ttype_busid_val[3]);
721 }
722 }
723
724 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_rw_cfg: ");
725 ret += snprintf(buf + ret, PAGE_SIZE - ret, "BOTH");
726
727 for (i = 0; i < 21; i++) {
728 if (ttype_rw_val[i] == BM_TRANS_RW_DEFAULT)
729 ret += snprintf(buf + ret, PAGE_SIZE - ret, ",DEFAULT");
730 else if (ttype_rw_val[i] == BM_TRANS_RW_READONLY)
731 ret += snprintf(buf + ret, PAGE_SIZE - ret, ",R");
732 else if (ttype_rw_val[i] == BM_TRANS_RW_WRITEONLY)
733 ret += snprintf(buf + ret, PAGE_SIZE - ret, ",W");
734 else
735 ret += snprintf(buf + ret, PAGE_SIZE - ret, ",BOTH");
736 }
737 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
738
739 ret += snprintf(buf + ret, PAGE_SIZE - ret,
740 "met-info [000] 0.0: met_emi_ultra_filter: %x\n", high_priority_filter);
741 if ((ttype1_16_en == BM_TTYPE1_16_ENABLE) && (ttype17_21_en == BM_TTYPE17_21_ENABLE)) {
742 int i;
743
744 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: ms_ud_sys_header: ms_ttype,");
745 for (i = 0; i < 21; i++)
746 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s,", ttype_name[i]);
747
748 ret += snprintf(buf + ret, PAGE_SIZE - ret, "x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x\n");
749
750 } else if (ttype17_21_en == BM_TTYPE17_21_ENABLE) {
751 int i;
752
753 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: ms_ud_sys_header: ms_ttype,");
754
755 for (i = 16; i < 21; i++)
756 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s,", ttype_name[i]);
757
758 ret += snprintf(buf + ret, PAGE_SIZE - ret, "x,x,x,x,x\n");
759 }
760
761 return ret;
762}
763
764static int ondiemet_emi_print_header(char *buf, int len)
765{
766 return emi_print_header(buf, len);
767}
768
769static void MET_BM_IPI_REGISTER_CB(void)
770{
771 int ret, i;
772 unsigned int rdata;
773 unsigned int ipi_buf[4];
774
775 for (i = 0; i < 4; i++)
776 ipi_buf[i] = 0;
777
778 if (sspm_buf_available == 1) {
779 ipi_buf[0] = MET_MAIN_ID | (MID_EMI << MID_BIT_SHIFT) | MET_ARGU | SET_REGISTER_CB;
780 ret = sspm_ipi_send_sync(IPI_ID_MET, IPI_OPT_WAIT, (void *)ipi_buf, 0, &rdata, 1);
781 }
782}
783
784static void MET_BM_IPI_configs(void)
785{
786 int ret, i;
787 unsigned int rdata;
788 unsigned int ipi_buf[4];
789
790 for (i = 0; i < 4; i++)
791 ipi_buf[i] = 0;
792
793 if (sspm_buf_available == 1) {
794 ipi_buf[0] = MET_MAIN_ID | (MID_EMI << MID_BIT_SHIFT) | MET_ARGU | SET_EBM_CONFIGS1;
795 ret = sspm_ipi_send_sync(IPI_ID_MET, IPI_OPT_WAIT, (void *)ipi_buf, 0, &rdata, 1);
796 }
797}
798
799static void ondiemet_emi_start(void)
800{
801 MET_BM_IPI_REGISTER_CB();
802 if (!emi_inited) {
803 if (MET_BM_Init() != 0) {
804 met_sspm_emi.mode = 0;
805 pr_notice("MET_BM_Init failed!!!\n");
806 PR_BOOTMSG("MET_BM_Init failed!!!\n");
807 return;
808 }
809 emi_inited = 1;
810 }
811 MET_BM_IPI_configs();
812
813 if (do_emi())
814 emi_init();
815
816 ondiemet_module[ONDIEMET_SSPM] |= ID_EMI;
817}
818
819static void emi_uninit(void)
820{
821 MET_BM_RestoreCfg();
822}
823
824static void ondiemet_emi_stop(void)
825{
826 if (!emi_inited)
827 return;
828
829 if (do_emi())
830 emi_uninit();
831}
832#endif
833
834struct metdevice met_sspm_emi = {
835 .name = "emi",
836 .owner = THIS_MODULE,
837 .type = MET_TYPE_BUS,
838 .create_subfs = met_emi_create,
839 .delete_subfs = met_emi_delete,
840 .resume = met_emi_resume,
841#ifdef CONFIG_MTK_TINYSYS_SSPM_SUPPORT
842 .ondiemet_start = ondiemet_emi_start,
843 .ondiemet_stop = ondiemet_emi_stop,
844 .ondiemet_print_help = emi_print_help,
845 .ondiemet_print_header = ondiemet_emi_print_header,
846#endif
847 .ondiemet_mode = 1,
848};
849EXPORT_SYMBOL(met_sspm_emi);