blob: 7f18f4a2ed293650f459391a2ef4288fc72799ef [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001#include <linux/kernel.h>
2#include <linux/sched.h>
3#include <linux/device.h>
4#include <linux/miscdevice.h>
5#include <linux/module.h>
6#include <linux/dma-mapping.h>
7#include <linux/string.h>
8
9#define MET_USER_EVENT_SUPPORT
10#include "met_drv.h"
11#include "trace.h"
12
13#include "mtk_typedefs.h"
14#include "core_plf_init.h"
15#include "core_plf_trace.h"
16#include "mtk_emi_bm.h"
17
18extern struct miscdevice met_device;
19
20/*======================================================================*/
21/* Global variable definitions */
22/*======================================================================*/
23/*ondiemet emi sampling interval in us */
24int ondiemet_emi_polling_200us;
25int emi_tsct_enable;
26int emi_mdct_enable;
27
28
29int emi_use_ondiemet;
30int metemi_func_opt;
31
32int met_emi_regdump;
33/*WSCT/TSCT id selection enable*/
34int emi_wsct_tsct_id_selection[4];
35/* Dynamic MonitorCounter selection !!!EXPERIMENT!!! */
36static int msel_enable;
37static unsigned int msel_group1 = BM_Master_GP_1_Default;
38static unsigned int msel_group2 = BM_Master_GP_2_Default;
39static unsigned int msel_group3 = BM_Master_GP_3_Default;
40
41/* CVS Added changeable buffer for testing */
42static int mdmcu_sel_enable;
43static unsigned int rd_mdmcu_rsv_num = 0x5;
44
45/* Global variables */
46static struct kobject *kobj_emi;
47static int rwtype = BM_BOTH_READ_WRITE;
48
49/* BW Limiter */
50/*#define CNT_COUNTDOWN (1000-1)*/ /* 1000 * 1ms = 1sec */
51#define CNT_COUNTDOWN (0) /* 1ms */
52static int countdown;
53static int bw_limiter_enable = BM_BW_LIMITER_ENABLE;
54
55/* TTYPE counter */
56static int ttype1_16_en = BM_TTYPE1_16_DISABLE;
57static int ttype17_21_en = BM_TTYPE17_21_DISABLE;
58
59unsigned int fmem_divider_freq_1;
60unsigned int fmem_divider_freq_2;
61
62static int dramc_pdir_enable;
63static int dram_chann_num = 1;
64
65/*======================================================================*/
66/* EMI Test Operations */
67/*======================================================================*/
68static int times;
69
70static ssize_t test_apmcu_store(struct kobject *kobj,
71 struct kobj_attribute *attr,
72 const char *buf,
73 size_t n)
74{
75 int i;
76 unsigned int *src_addr_v;
77 dma_addr_t src_addr_p;
78
79 if ((n == 0) || (buf == NULL))
80 return -EINVAL;
81 if (sscanf(buf, "%d", &times) != 1)
82 return -EINVAL;
83 if (times < 0)
84 return -EINVAL;
85
86 if (times > 5000) /* Less than 20MB */
87 return -EINVAL;
88
89 /* dma_alloc */
90 src_addr_v = dma_alloc_coherent(met_device.this_device,
91 PAGE_SIZE,
92 &src_addr_p,
93 GFP_KERNEL);
94 if (src_addr_v == NULL) {
95 /* met_tag_oneshot(0, "test_apmcu dma alloc fail", PAGE_SIZE); */
96 return -ENOMEM;
97 }
98 /* testing */
99 preempt_disable();
100 /* met_tag_start(0, "TEST_EMI_APMCU"); */
101 for (i = 0; i < times; i++) {
102 memset(src_addr_v, 2*i, PAGE_SIZE);
103 /* met_tag_oneshot(0, "TEST_EMI_APMCU", PAGE_SIZE); */
104 }
105 /* met_tag_end(0, "TEST_EMI_APMCU"); */
106 preempt_enable();
107
108 /* dma_free */
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(ondiemet_emi_polling_200us, ondiemet_emi_polling_200us)
121DECLARE_KOBJ_ATTR_INT(emi_tsct_enable, emi_tsct_enable)
122DECLARE_KOBJ_ATTR_INT(emi_mdct_enable, emi_mdct_enable)
123DECLARE_KOBJ_ATTR_INT(metemi_func_opt, metemi_func_opt)
124DECLARE_KOBJ_ATTR_INT(emi_regdump, met_emi_regdump)
125DECLARE_KOBJ_ATTR_INT(emi_wsct_tsct_id_selection1, emi_wsct_tsct_id_selection[0])
126DECLARE_KOBJ_ATTR_INT(emi_wsct_tsct_id_selection2, emi_wsct_tsct_id_selection[1])
127DECLARE_KOBJ_ATTR_INT(emi_wsct_tsct_id_selection3, emi_wsct_tsct_id_selection[2])
128DECLARE_KOBJ_ATTR_INT(emi_wsct_tsct_id_selection4, emi_wsct_tsct_id_selection[3])
129/* KOBJ: Dynamic MonitorCounter selection !!!EXPERIMENT!!! */
130DECLARE_KOBJ_ATTR_INT(msel_enable, msel_enable)
131DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group1, msel_group1, msel_group1 > 0 && msel_group1 <= BM_MASTER_ALL)
132DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group2, msel_group2, msel_group2 > 0 && msel_group2 <= BM_MASTER_ALL)
133DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group3, msel_group3, msel_group3 > 0 && msel_group3 <= BM_MASTER_ALL)
134DECLARE_KOBJ_ATTR_INT(mdmcu_sel_enable, mdmcu_sel_enable)
135DECLARE_KOBJ_ATTR_INT(rd_mdmcu_rsv_num, rd_mdmcu_rsv_num)
136
137
138/* KOBJ: rwtype */
139DECLARE_KOBJ_ATTR_INT_CHECK(rwtype, rwtype, rwtype >= 0 && rwtype <= BM_WRITE_ONLY)
140
141static unsigned int get_emi_clock_rate(unsigned int dram_data_rate_MHz)
142{
143 return dram_data_rate_MHz/DRAM_EMI_BASECLOCK_RATE/DRAM_DATARATE;
144}
145
146/* KOBJ: emi_clock_rate */
147static ssize_t emi_clock_rate_show(struct kobject *kobj,
148 struct kobj_attribute *attr,
149 char *buf)
150{
151 unsigned int dram_data_rate_MHz;
152
153 dram_data_rate_MHz = get_dram_data_rate();
154 return snprintf(buf, PAGE_SIZE, "%d\n",
155 get_emi_clock_rate(dram_data_rate_MHz));
156}
157
158DECLARE_KOBJ_ATTR_RO(emi_clock_rate)
159
160static ssize_t dram_data_rate_show(struct kobject *kobj,
161 struct kobj_attribute *attr,
162 char *buf)
163{
164 unsigned int dram_data_rate_MHz;
165
166 dram_data_rate_MHz = get_dram_data_rate();
167 return snprintf(buf, PAGE_SIZE, "%d\n", dram_data_rate_MHz);
168}
169
170DECLARE_KOBJ_ATTR_RO(dram_data_rate)
171
172/* KOBJ: ttype1_16_en */
173DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
174 ttype1_16_en,
175 KOBJ_ITEM_LIST(
176 {BM_TTYPE1_16_ENABLE, "ENABLE"},
177 {BM_TTYPE1_16_DISABLE, "DISABLE"}
178 )
179 )
180DECLARE_KOBJ_ATTR_STR_LIST(ttype1_16_en, ttype1_16_en, ttype1_16_en)
181
182/* KOBJ: ttype17_21_en */
183DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
184 ttype17_21_en,
185 KOBJ_ITEM_LIST(
186 {BM_TTYPE17_21_ENABLE, "ENABLE"},
187 {BM_TTYPE17_21_DISABLE, "DISABLE"}
188 )
189 )
190DECLARE_KOBJ_ATTR_STR_LIST(ttype17_21_en, ttype17_21_en, ttype17_21_en)
191
192/* KOBJ: bw_limiter_enable */
193DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
194 bw_limiter_enable,
195 KOBJ_ITEM_LIST(
196 {BM_BW_LIMITER_ENABLE, "ENABLE"},
197 {BM_BW_LIMITER_DISABLE, "DISABLE"}
198 )
199 )
200
201DECLARE_KOBJ_ATTR_STR_LIST(bw_limiter_enable, bw_limiter_enable, bw_limiter_enable)
202
203/* KOBJ: ttype_master */
204DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
205 ttype_master,
206 KOBJ_ITEM_LIST(
207 {BM_MASTER_M0, "M0"},
208 {BM_MASTER_M1, "M1"},
209 {BM_MASTER_M2, "M2"},
210 {BM_MASTER_M3, "M3"},
211 {BM_MASTER_M4, "M4"},
212 {BM_MASTER_M5, "M5"},
213 {BM_MASTER_M6, "M6"},
214 {BM_MASTER_M7, "M7"}
215 )
216 )
217
218
219/* KOBJ: ttypeX_nbeat, ttypeX_nbyte, ttypeX_burst */
220DECLARE_KOBJ_ATTR_INT_LIST_ITEM(
221 ttype_nbeat,
222 KOBJ_ITEM_LIST(
223 {BM_TRANS_TYPE_1BEAT, 1},
224 {BM_TRANS_TYPE_2BEAT, 2},
225 {BM_TRANS_TYPE_3BEAT, 3},
226 {BM_TRANS_TYPE_4BEAT, 4},
227 {BM_TRANS_TYPE_5BEAT, 5},
228 {BM_TRANS_TYPE_6BEAT, 6},
229 {BM_TRANS_TYPE_7BEAT, 7},
230 {BM_TRANS_TYPE_8BEAT, 8},
231 {BM_TRANS_TYPE_9BEAT, 9},
232 {BM_TRANS_TYPE_10BEAT, 10},
233 {BM_TRANS_TYPE_11BEAT, 11},
234 {BM_TRANS_TYPE_12BEAT, 12},
235 {BM_TRANS_TYPE_13BEAT, 13},
236 {BM_TRANS_TYPE_14BEAT, 14},
237 {BM_TRANS_TYPE_15BEAT, 15},
238 {BM_TRANS_TYPE_16BEAT, 16}
239 )
240 )
241DECLARE_KOBJ_ATTR_INT_LIST_ITEM(
242 ttype_nbyte,
243 KOBJ_ITEM_LIST(
244 {BM_TRANS_TYPE_1Byte, 1},
245 {BM_TRANS_TYPE_2Byte, 2},
246 {BM_TRANS_TYPE_4Byte, 4},
247 {BM_TRANS_TYPE_8Byte, 8},
248 {BM_TRANS_TYPE_16Byte, 16},
249 {BM_TRANS_TYPE_32Byte, 32}
250 )
251 )
252DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
253 ttype_burst,
254 KOBJ_ITEM_LIST(
255 {BM_TRANS_TYPE_BURST_INCR, "INCR"},
256 {BM_TRANS_TYPE_BURST_WRAP, "WRAP"}
257 )
258 )
259
260DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
261 ttype_rw,
262 KOBJ_ITEM_LIST(
263 {BM_TRANS_RW_DEFAULT, "DEFAULT"},
264 {BM_TRANS_RW_READONLY, "R"},
265 {BM_TRANS_RW_WRITEONLY, "W"},
266 {BM_TRANS_RW_RWBOTH, "BOTH"}
267 )
268 )
269
270/* KOBJ: test_apmcu */
271DECLARE_KOBJ_ATTR_SHOW_INT(test_apmcu, times)
272/* please refer to session: "EMI Test Operations" for store operation */
273DECLARE_KOBJ_ATTR(test_apmcu)
274
275DECLARE_KOBJ_ATTR_INT(dramc_pdir_enable, dramc_pdir_enable)
276
277/*enable high priority filter*/
278static int high_priority_filter;
279DECLARE_KOBJ_ATTR_HEX(high_priority_filter, high_priority_filter)
280
281
282/**/
283static int ttype_master_val[21];
284static int ttype_busid_val[21];
285static int ttype_nbeat_val[21];
286static int ttype_nbyte_val[21];
287static int ttype_burst_val[21];
288static int ttype_rw_val[21];
289
290#define DECLARE_KOBJ_SERIAL_FNODE(nr) \
291 DECLARE_KOBJ_ATTR_STR_LIST(ttype##nr##_master, ttype_master_val[nr-1], ttype_master) \
292 DECLARE_KOBJ_ATTR_HEX(ttype##nr##_busid, ttype_busid_val[nr-1]) \
293 DECLARE_KOBJ_ATTR_INT_LIST(ttype##nr##_nbeat, ttype_nbeat_val[nr-1], ttype_nbeat) \
294 DECLARE_KOBJ_ATTR_INT_LIST(ttype##nr##_nbyte, ttype_nbyte_val[nr-1], ttype_nbyte) \
295 DECLARE_KOBJ_ATTR_STR_LIST(ttype##nr##_burst, ttype_burst_val[nr-1], ttype_burst) \
296 DECLARE_KOBJ_ATTR_STR_LIST(ttype##nr##_rw, ttype_rw_val[nr-1], ttype_rw)
297
298DECLARE_KOBJ_SERIAL_FNODE(1)
299DECLARE_KOBJ_SERIAL_FNODE(2)
300DECLARE_KOBJ_SERIAL_FNODE(3)
301DECLARE_KOBJ_SERIAL_FNODE(4)
302DECLARE_KOBJ_SERIAL_FNODE(5)
303DECLARE_KOBJ_SERIAL_FNODE(6)
304DECLARE_KOBJ_SERIAL_FNODE(7)
305DECLARE_KOBJ_SERIAL_FNODE(8)
306DECLARE_KOBJ_SERIAL_FNODE(9)
307DECLARE_KOBJ_SERIAL_FNODE(10)
308DECLARE_KOBJ_SERIAL_FNODE(11)
309DECLARE_KOBJ_SERIAL_FNODE(12)
310DECLARE_KOBJ_SERIAL_FNODE(13)
311DECLARE_KOBJ_SERIAL_FNODE(14)
312DECLARE_KOBJ_SERIAL_FNODE(15)
313DECLARE_KOBJ_SERIAL_FNODE(16)
314DECLARE_KOBJ_SERIAL_FNODE(17)
315DECLARE_KOBJ_SERIAL_FNODE(18)
316DECLARE_KOBJ_SERIAL_FNODE(19)
317DECLARE_KOBJ_SERIAL_FNODE(20)
318DECLARE_KOBJ_SERIAL_FNODE(21)
319
320 /**/
321#define KOBJ_ATTR_ITEM_SERIAL_FNODE(nr) \
322 KOBJ_ATTR_ITEM(ttype##nr##_master) \
323 KOBJ_ATTR_ITEM(ttype##nr##_nbeat) \
324 KOBJ_ATTR_ITEM(ttype##nr##_nbyte) \
325 KOBJ_ATTR_ITEM(ttype##nr##_burst) \
326 KOBJ_ATTR_ITEM(ttype##nr##_busid) \
327 KOBJ_ATTR_ITEM(ttype##nr##_rw) \
328
329#define KOBJ_ATTR_LIST \
330 KOBJ_ATTR_ITEM(high_priority_filter) \
331 KOBJ_ATTR_ITEM(metemi_func_opt) \
332 KOBJ_ATTR_ITEM(emi_tsct_enable) \
333 KOBJ_ATTR_ITEM(emi_mdct_enable) \
334 KOBJ_ATTR_ITEM(ondiemet_emi_polling_200us) \
335 KOBJ_ATTR_ITEM(emi_regdump) \
336 KOBJ_ATTR_ITEM(emi_wsct_tsct_id_selection1) \
337 KOBJ_ATTR_ITEM(emi_wsct_tsct_id_selection2) \
338 KOBJ_ATTR_ITEM(emi_wsct_tsct_id_selection3) \
339 KOBJ_ATTR_ITEM(emi_wsct_tsct_id_selection4) \
340 KOBJ_ATTR_ITEM(msel_enable) \
341 KOBJ_ATTR_ITEM(msel_group1) \
342 KOBJ_ATTR_ITEM(msel_group2) \
343 KOBJ_ATTR_ITEM(msel_group3) \
344 KOBJ_ATTR_ITEM(emi_clock_rate) \
345 KOBJ_ATTR_ITEM(dram_data_rate) \
346 KOBJ_ATTR_ITEM(rwtype) \
347 KOBJ_ATTR_ITEM(ttype17_21_en) \
348 KOBJ_ATTR_ITEM(ttype1_16_en) \
349 KOBJ_ATTR_ITEM_SERIAL_FNODE(1) \
350 KOBJ_ATTR_ITEM_SERIAL_FNODE(2) \
351 KOBJ_ATTR_ITEM_SERIAL_FNODE(3) \
352 KOBJ_ATTR_ITEM_SERIAL_FNODE(4) \
353 KOBJ_ATTR_ITEM_SERIAL_FNODE(5) \
354 KOBJ_ATTR_ITEM_SERIAL_FNODE(6) \
355 KOBJ_ATTR_ITEM_SERIAL_FNODE(7) \
356 KOBJ_ATTR_ITEM_SERIAL_FNODE(8) \
357 KOBJ_ATTR_ITEM_SERIAL_FNODE(9) \
358 KOBJ_ATTR_ITEM_SERIAL_FNODE(10) \
359 KOBJ_ATTR_ITEM_SERIAL_FNODE(11) \
360 KOBJ_ATTR_ITEM_SERIAL_FNODE(12) \
361 KOBJ_ATTR_ITEM_SERIAL_FNODE(13) \
362 KOBJ_ATTR_ITEM_SERIAL_FNODE(14) \
363 KOBJ_ATTR_ITEM_SERIAL_FNODE(15) \
364 KOBJ_ATTR_ITEM_SERIAL_FNODE(16) \
365 KOBJ_ATTR_ITEM_SERIAL_FNODE(17) \
366 KOBJ_ATTR_ITEM_SERIAL_FNODE(18) \
367 KOBJ_ATTR_ITEM_SERIAL_FNODE(19) \
368 KOBJ_ATTR_ITEM_SERIAL_FNODE(20) \
369 KOBJ_ATTR_ITEM_SERIAL_FNODE(21) \
370 KOBJ_ATTR_ITEM(test_apmcu) \
371 KOBJ_ATTR_ITEM(bw_limiter_enable) \
372 KOBJ_ATTR_ITEM(dramc_pdir_enable) \
373 KOBJ_ATTR_ITEM(mdmcu_sel_enable) \
374 KOBJ_ATTR_ITEM(rd_mdmcu_rsv_num) \
375
376/*======================================================================*/
377/* EMI Operations */
378/*======================================================================*/
379static void emi_init(void)
380{
381 unsigned int bmrw0_val, bmrw1_val, i, enable;
382 unsigned int msel_group1_val, msel_group2_val, msel_group3_val;
383
384 /* get dram channel number */
385 dram_chann_num = MET_EMI_GetDramChannNum();
386
387 /* Init. EMI bus monitor */
388 MET_BM_SetReadWriteType(rwtype);
389
390 /* MSEL1: ALL */
391 MET_BM_SetMonitorCounter(1,
392 BM_MASTER_ALL,
393 BM_TRANS_TYPE_4BEAT |
394 BM_TRANS_TYPE_8Byte |
395 BM_TRANS_TYPE_BURST_WRAP);
396 if (msel_enable) {
397 msel_group1_val = msel_group1;
398 msel_group2_val = msel_group2;
399 msel_group3_val = msel_group3;
400 } else {
401 msel_group1_val = BM_Master_GP_1_Default;
402 msel_group2_val = BM_Master_GP_2_Default;
403 msel_group3_val = BM_Master_GP_3_Default;
404 }
405
406 /* MSEL2: msel_group1 */
407 MET_BM_SetMonitorCounter(2,
408 msel_group1_val & BM_MASTER_ALL,
409 BM_TRANS_TYPE_4BEAT |
410 BM_TRANS_TYPE_8Byte |
411 BM_TRANS_TYPE_BURST_WRAP);
412 /* MSEL3: msel_group2 */
413 MET_BM_SetMonitorCounter(3,
414 msel_group2_val & BM_MASTER_ALL,
415 BM_TRANS_TYPE_4BEAT |
416 BM_TRANS_TYPE_8Byte |
417 BM_TRANS_TYPE_BURST_WRAP);
418 /* MSEL4: msel_group3 */
419 MET_BM_SetMonitorCounter(4,
420 msel_group3_val & BM_MASTER_ALL,
421 BM_TRANS_TYPE_4BEAT |
422 BM_TRANS_TYPE_8Byte |
423 BM_TRANS_TYPE_BURST_WRAP);
424
425
426 if (ttype1_16_en == BM_TTYPE1_16_ENABLE) {
427 MET_BM_SetLatencyCounter(0);
428
429 for (i = 1; i <= 16; i++) {
430 MET_BM_SetMonitorCounter(i,
431 ttype_master_val[i - 1],
432 ttype_nbeat_val[i - 1] |
433 ttype_nbyte_val[i - 1] |
434 ttype_burst_val[i - 1]);
435 MET_BM_SetIDSelect(i, ttype_busid_val[i - 1], (ttype_busid_val[i - 1] >= 0xffff) ? 0 : 1);
436 }
437 } else {
438 MET_BM_SetLatencyCounter(1);
439 }
440
441 if (ttype17_21_en == BM_TTYPE17_21_ENABLE) {
442 for (i = 17; i <= 21; i++) {
443 MET_BM_SetMonitorCounter(i,
444 ttype_master_val[i - 1],
445 ttype_nbeat_val[i - 1] |
446 ttype_nbyte_val[i - 1] |
447 ttype_burst_val[i - 1]);
448 MET_BM_SetIDSelect(i, ttype_busid_val[i - 1], (ttype_busid_val[i - 1] >= 0xffff) ? 0 : 1);
449 }
450 }
451
452 bmrw0_val = (
453 (ttype_rw_val[0] << 0) | (ttype_rw_val[1] << 2) |
454 (ttype_rw_val[2] << 4) | (ttype_rw_val[3] << 6) |
455 (ttype_rw_val[4] << 8) | (ttype_rw_val[5] << 10) |
456 (ttype_rw_val[6] << 12) | (ttype_rw_val[7] << 14) |
457 (ttype_rw_val[8] << 16) | (ttype_rw_val[9] << 18) |
458 (ttype_rw_val[10] << 20) | (ttype_rw_val[11] << 22) |
459 (ttype_rw_val[12] << 24) | (ttype_rw_val[13] << 26) |
460 (ttype_rw_val[14] << 28) | (ttype_rw_val[15] << 30));
461
462 bmrw1_val = (
463 (ttype_rw_val[16] << 0) | (ttype_rw_val[17] << 2) |
464 (ttype_rw_val[18] << 4) | (ttype_rw_val[19] << 6) |
465 (ttype_rw_val[20] << 8));
466
467 MET_BM_SetTtypeCounterRW(bmrw0_val, bmrw1_val);
468
469 for (i = 0; i < 4; i++)
470 MET_BM_Set_WsctTsct_id_sel(i, emi_wsct_tsct_id_selection[i]);
471
472 for (i = 0; i < BM_COUNTER_MAX; i++) {
473 if ((high_priority_filter & (1<<i)) == 0)
474 enable = 0;
475 else
476 enable = 1;
477
478 MET_BM_SetUltraHighFilter(i+1, enable);
479 }
480
481 if (met_emi_regdump == 1)
482 emi_dump_reg();
483}
484
485static void emi_uninit(void)
486{
487}
488
489static inline void emi_start(void)
490{
491 MET_BM_Enable(1);
492}
493
494static inline void emi_stop(void)
495{
496 MET_BM_Enable(0);
497}
498
499static inline int do_emi(void)
500{
501 return met_emi.mode;
502}
503
504noinline void DRAM_DVFS(unsigned int dram_data_rate_MHz)
505{
506 MET_TRACE("%u\n", dram_data_rate_MHz);
507}
508
509static unsigned int emi_bw_limiter(unsigned int *__restrict__ array)
510{
511 int idx = 0;
512 unsigned int dram_data_rate_MHz;
513
514 dram_data_rate_MHz = get_dram_data_rate();
515
516 /* print dram data rate */
517 DRAM_DVFS(dram_data_rate_MHz);
518
519 /* get correct dram_clock_rate */
520 array[idx++] = dram_data_rate_MHz;
521
522 /* get correct ARB A->LAST */
523 array[idx++] = MET_EMI_GetARBA();
524 array[idx++] = MET_EMI_GetARBB();
525 array[idx++] = MET_EMI_GetARBC();
526 array[idx++] = MET_EMI_GetARBD();
527 array[idx++] = MET_EMI_GetARBE();
528 array[idx++] = MET_EMI_GetARBF();
529 array[idx++] = MET_EMI_GetARBG();
530 array[idx++] = MET_EMI_GetARBH();
531 /* EMI Total BW Thresholds */
532 array[idx++] = MET_EMI_GetBWCT0();
533 array[idx++] = MET_EMI_GetBWCT1();
534 array[idx++] = MET_EMI_GetBWCT2();
535 array[idx++] = MET_EMI_GetBWCT3();
536 array[idx++] = MET_EMI_GetBWCT4();
537 array[idx++] = MET_EMI_GetBWST0();
538 array[idx++] = MET_EMI_GetBWST1();
539 /* EMI C+G BW Thresholds */
540 array[idx++] = MET_EMI_GetBWCT0_2ND();
541 array[idx++] = MET_EMI_GetBWCT1_2ND();
542 array[idx++] = MET_EMI_GetBWST_2ND();
543
544 return idx;
545}
546
547
548static void _ms_dramc(unsigned int *__restrict__ dramc_pdir_value, int dram_chann_num)
549{
550 MET_DRAMC_GetDebugCounter(dramc_pdir_value, dram_chann_num);
551}
552
553static unsigned int emi_polling(unsigned int *__restrict__ emi_value, unsigned int *__restrict__ emi_tsct,
554 unsigned int *__restrict__ emi_ttype_value, unsigned int *__restrict__ dramc_pdir_value,
555 unsigned int *__restrict__ emi_mdct_value)
556{
557 int j = 4; /* skip 4 WSCTs */
558 int i = 0; /* ttype start at 0 */
559 int k = 0; /* tsct start at 0 */
560 int n;
561
562 MET_BM_Pause();
563
564 if (ttype1_16_en != BM_TTYPE1_16_ENABLE) { /*1~21 NOT for ttype*/
565
566 /* Get Word Count */
567
568 emi_value[0] = MET_BM_GetWordCount(1); /* All */
569 emi_value[1] = MET_BM_GetWordCount(2); /* Group 1 */
570 emi_value[2] = MET_BM_GetWordCount(3); /* Group 2 */
571 emi_value[3] = MET_BM_GetWordCount(4); /* Group 3 */
572
573
574 /* Get Latency */
575 emi_value[j++] = MET_BM_GetLatencyCycle(1);
576 emi_value[j++] = MET_BM_GetLatencyCycle(2);
577 emi_value[j++] = MET_BM_GetLatencyCycle(3);
578 emi_value[j++] = MET_BM_GetLatencyCycle(4);
579 emi_value[j++] = MET_BM_GetLatencyCycle(5);
580 emi_value[j++] = MET_BM_GetLatencyCycle(6);
581 emi_value[j++] = MET_BM_GetLatencyCycle(7);
582 emi_value[j++] = MET_BM_GetLatencyCycle(8);
583
584 /* Get Trans. */
585 emi_value[j++] = MET_BM_GetLatencyCycle(9);
586 emi_value[j++] = MET_BM_GetLatencyCycle(10);
587 emi_value[j++] = MET_BM_GetLatencyCycle(11);
588 emi_value[j++] = MET_BM_GetLatencyCycle(12);
589 emi_value[j++] = MET_BM_GetLatencyCycle(13);
590 emi_value[j++] = MET_BM_GetLatencyCycle(14);
591 emi_value[j++] = MET_BM_GetLatencyCycle(15);
592 emi_value[j++] = MET_BM_GetLatencyCycle(16);
593 } else {
594 for (n = 0; n < 20; n++)
595 emi_value[n] = 0;
596 j = 20;
597
598 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(1);
599 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(2);
600 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(3);
601 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(4);
602 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(5);
603 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(6);
604 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(7);
605 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(8);
606
607 /* Get Trans. */
608 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(9);
609 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(10);
610 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(11);
611 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(12);
612 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(13);
613 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(14);
614 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(15);
615 emi_ttype_value[i++] = MET_BM_GetLatencyCycle(16);
616 }
617
618 /* Get BACT/BSCT/BCNT */
619 emi_value[j++] = MET_BM_GetBandwidthWordCount();
620 emi_value[j++] = MET_BM_GetOverheadWordCount();
621 emi_value[j++] = MET_BM_GetBusCycCount();
622 /* Get PageHist/PageMiss/InterBank/Idle */
623 for (n = 0; n < dram_chann_num; n++) {
624#if 1
625 /* TBD */
626 emi_value[j++] = MET_DRAMC_GetPageHitCount(DRAMC_ALL, n);
627 emi_value[j++] = MET_DRAMC_GetPageMissCount(DRAMC_ALL, n);
628 emi_value[j++] = MET_DRAMC_GetInterbankCount(DRAMC_ALL, n);
629 emi_value[j++] = MET_DRAMC_GetIdleCount(n);
630 emi_value[j++] = ((MET_DRAMC_Misc_Status(n) >> 8) & 0x7);
631 emi_value[j++] = MET_DRAMC_RefPop(n);
632 emi_value[j++] = MET_DRAMC_Free26M(n);
633 emi_value[j++] = MET_DRAMC_RByte(n);
634 emi_value[j++] = MET_DRAMC_WByte(n);
635#else
636 emi_value[j++] = 0;
637 emi_value[j++] = 0;
638 emi_value[j++] = 0;
639 emi_value[j++] = 0;
640 emi_value[j++] = 0;
641 emi_value[j++] = 0;
642 emi_value[j++] = 0;
643 emi_value[j++] = 0;
644 emi_value[j++] = 0;
645#endif
646 }
647 /* TTYPE */
648 if (ttype17_21_en == BM_TTYPE17_21_ENABLE) { /*17~21 for ttype*/
649 emi_ttype_value[16] = MET_BM_GetLatencyCycle(17);
650 emi_ttype_value[17] = MET_BM_GetLatencyCycle(18);
651 emi_ttype_value[18] = MET_BM_GetLatencyCycle(19);
652 emi_ttype_value[19] = MET_BM_GetLatencyCycle(20);
653 emi_ttype_value[20] = MET_BM_GetLatencyCycle(21);
654 }
655
656 /* Get tsct */
657 if (emi_tsct_enable == 1) {
658 emi_tsct[k++] = MET_BM_GetTransCount(1);
659 emi_tsct[k++] = MET_BM_GetTransCount(2);
660 emi_tsct[k++] = MET_BM_GetTransCount(3);
661 }
662 /*get mdct rsv buffer*/
663 if (emi_mdct_enable == 1) {
664 emi_mdct_value[0] = (MET_BM_GetMDCT() >> 16) & 0x7;
665 emi_mdct_value[1] = (MET_BM_GetMDCT_2() & 0x7);
666 }
667
668 if (dramc_pdir_enable == 1)
669 _ms_dramc(dramc_pdir_value, dram_chann_num);
670
671 MET_BM_Continue();
672 MET_BM_Enable(0);
673 MET_BM_Enable(1);
674
675 return j;
676}
677
678/*======================================================================*/
679/* MET Device Operations */
680/*======================================================================*/
681static int emi_inited;
682
683static int met_emi_create(struct kobject *parent)
684{
685 int ret = 0;
686 int i;
687
688 for (i = 0; i < 21; i++) {
689 ttype_master_val[i] = BM_MASTER_M0;
690 ttype_nbeat_val[i] = BM_TRANS_TYPE_1BEAT;
691 ttype_nbyte_val[i] = BM_TRANS_TYPE_8Byte;
692 ttype_burst_val[i] = BM_TRANS_TYPE_BURST_INCR;
693 ttype_busid_val[i] = 0xffff;
694 ttype_rw_val[i] = BM_TRANS_RW_DEFAULT;
695 }
696
697 ret = MET_BM_Init();
698 if (ret != 0) {
699 pr_err("MET_BM_Init failed!!!\n");
700 ret = 0; /* will retry later */
701 } else {
702 emi_inited = 1;
703 }
704
705 kobj_emi = parent;
706
707#define KOBJ_ATTR_ITEM(attr_name) \
708 ret = sysfs_create_file(kobj_emi, &attr_name##_attr.attr); \
709 if (ret != 0) { \
710 pr_err("Failed to create " #attr_name " in sysfs\n"); \
711 return ret; \
712 }
713 KOBJ_ATTR_LIST
714#undef KOBJ_ATTR_ITEM
715
716 return ret;
717}
718
719static void met_emi_delete(void)
720{
721#define KOBJ_ATTR_ITEM(attr_name) \
722 sysfs_remove_file(kobj_emi, &attr_name##_attr.attr);
723 if (kobj_emi != NULL) {
724 KOBJ_ATTR_LIST
725 kobj_emi = NULL;
726 }
727#undef KOBJ_ATTR_ITEM
728
729 if (emi_inited)
730 MET_BM_DeInit();
731}
732
733static void met_emi_start(void)
734{
735 unsigned int bw_limiter[NIDX_BL];
736
737 if (!emi_inited) {
738 if (MET_BM_Init() != 0) {
739 met_emi.mode = 0;
740 pr_err("MET_BM_Init failed!!!\n");
741 return;
742 }
743 emi_inited = 1;
744 }
745
746 if (do_emi()) {
747 emi_init();
748 emi_stop();
749 emi_start();
750
751 /* Draw the first BW Limiter point */
752 if (bw_limiter_enable == BM_BW_LIMITER_ENABLE) {
753 emi_bw_limiter(bw_limiter);
754 ms_bw_limiter(NIDX_BL, bw_limiter);
755 /* init countdown value */
756 countdown = CNT_COUNTDOWN;
757 }
758 }
759}
760
761static void met_emi_stop(void)
762{
763 unsigned int bw_limiter[NIDX_BL];
764
765 if (!emi_inited)
766 return;
767
768 if (met_emi_regdump == 1)
769 emi_dump_reg();
770
771 if (do_emi()) {
772 /* Draw the last BW Limiter point */
773 if (bw_limiter_enable == BM_BW_LIMITER_ENABLE) {
774 /*
775 * Skip drawing when we just draw
776 * the point at last polling.
777 */
778 if (countdown < CNT_COUNTDOWN) {
779 emi_bw_limiter(bw_limiter);
780 ms_bw_limiter(NIDX_BL, bw_limiter);
781 }
782 }
783
784 emi_stop();
785 emi_uninit();
786 }
787}
788
789static void met_emi_polling(unsigned long long stamp, int cpu)
790{
791 unsigned int emi_value[NIDX];
792 unsigned int emi_tsct[3];
793 unsigned int emi_ttype_value[21];
794 unsigned int dramc_pdir_value[DRAMC_Debug_MAX_CNT*NCH];
795 unsigned int emi_mdct_value[2];
796
797 if (!do_emi())
798 return;
799
800 /* get emi & dramc counters */
801 emi_value[0] = 0; /* 0: pure linux MET , 0xa5: OnDieMET*/
802 emi_value[1] = 0; /* EBM pause duration (ns)*/
803 emi_polling(emi_value+2, emi_tsct, emi_ttype_value, dramc_pdir_value, emi_mdct_value);
804
805 /* get and output BW Limiter */
806 if (bw_limiter_enable == BM_BW_LIMITER_ENABLE) {
807 unsigned int bw_limiter[NIDX_BL];
808
809 if (countdown > 0) {
810 countdown--;
811 } else {
812 emi_bw_limiter(bw_limiter);
813 ms_bw_limiter(NIDX_BL, bw_limiter);
814 /* reload countdown value */
815 countdown = CNT_COUNTDOWN;
816 }
817 }
818
819 /* output emi */
820 ms_emi(NIDX_EMI-NTTYPE + (NCNT*dram_chann_num), emi_value);
821 /* output tsct*/
822
823
824
825 if (emi_tsct_enable == 1)
826 ms_emi_tsct(3, emi_tsct);
827
828 /* output mdct*/
829 if (emi_mdct_enable == 1)
830 ms_emi_mdct(2, emi_mdct_value);
831
832 /* output dramc*/
833 if (dramc_pdir_enable == 1)
834 ms_dramc(DRAMC_Debug_MAX_CNT*dram_chann_num, dramc_pdir_value);
835
836 /* output ms_ttype */
837 if ((ttype1_16_en == BM_TTYPE1_16_ENABLE) && (ttype17_21_en == BM_TTYPE17_21_ENABLE))
838 ms_ttype(21, emi_ttype_value);
839 else if (ttype17_21_en == BM_TTYPE17_21_ENABLE)
840 ms_ttype(5, (emi_ttype_value + 16));
841
842 /* adjust MDMCU buffer */
843 if (mdmcu_sel_enable == 1)
844 MET_BM_SetMDCT_MDMCU(rd_mdmcu_rsv_num);
845}
846
847static char help[] = " --emi monitor EMI banwidth\n";
848static int emi_print_help(char *buf, int len)
849{
850 return snprintf(buf, PAGE_SIZE, help);
851}
852
853
854#define TTYPE_NAME_STR_LEN 64
855static char ttype_name[21][TTYPE_NAME_STR_LEN];
856static int emi_print_header(char *buf, int len)
857{
858 int ret = 0;
859 int ret_m[21];
860 int i = 0;
861 unsigned int dram_data_rate_MHz;
862
863 /*ttype header info*/
864 for (i = 0; i < 21; i++) {
865
866 int k;
867
868 /*busid >= 0xffff not specific bus id , show all on specificmaster*/
869 if (ttype_busid_val[i] >= 0xffff) {
870
871 int j;
872
873 for (j = 0; j < ARRAY_SIZE(ttype_master_list_item); j++) {
874 if (ttype_master_val[i] == ttype_master_list_item[j].key) {
875 ret_m[i] = snprintf(ttype_name[i], TTYPE_NAME_STR_LEN, "ttyp%d_%s",
876 i+1, ttype_master_list_item[j].val);/*master*/
877 break;
878 }
879 }
880 if (j == ARRAY_SIZE(ttype_master_list_item))
881 ret_m[i] = snprintf(ttype_name[i], TTYPE_NAME_STR_LEN, "ttyp%d_%s",
882 i+1, "unknown");
883 } else {
884 ret_m[i] = snprintf(ttype_name[i], TTYPE_NAME_STR_LEN, "ttyp%d_%x",
885 i+1, ttype_busid_val[i]);/*busID*/
886 }
887
888 /*show beat type*/
889 for (k = 0; k < ARRAY_SIZE(ttype_nbeat_list_item); k++) {
890
891 if (ttype_nbeat_val[i] == ttype_nbeat_list_item[k].key)
892 ret_m[i] += snprintf(ttype_name[i]+ret_m[i], TTYPE_NAME_STR_LEN-ret_m[i], "_%d",
893 ttype_nbeat_list_item[k].val);/*beat*/
894 }
895
896 /*show byte type*/
897 for (k = 0; k < ARRAY_SIZE(ttype_nbyte_list_item); k++) {
898
899 if (ttype_nbyte_val[i] == ttype_nbyte_list_item[k].key)
900 ret_m[i] += snprintf(ttype_name[i]+ret_m[i], TTYPE_NAME_STR_LEN-ret_m[i], "x%d",
901 ttype_nbyte_list_item[k].val);/*byte*/
902 }
903
904 /*show burst type*/
905 for (k = 0; k < ARRAY_SIZE(ttype_burst_list_item); k++) {
906
907 if (ttype_burst_val[i] == ttype_burst_list_item[k].key)
908 ret_m[i] += snprintf(ttype_name[i]+ret_m[i], TTYPE_NAME_STR_LEN-ret_m[i], "_%s",
909 ttype_burst_list_item[k].val);/*burst*/
910 }
911
912 /*show rw type*/
913 for (k = 0; k < ARRAY_SIZE(ttype_rw_list_item); k++) {
914
915 if (ttype_rw_val[i] == ttype_rw_list_item[k].key)
916 ret_m[i] += snprintf(ttype_name[i]+ret_m[i], TTYPE_NAME_STR_LEN-ret_m[i], "_%s",
917 ttype_rw_list_item[k].val);/*rw*/
918 }
919 }
920
921 dram_chann_num = MET_EMI_GetDramChannNum();
922 /* met_dram_chann_num_header */
923 /* TBD: what is VID */
924 ret = snprintf(buf, PAGE_SIZE, "met-info [000] 0.0: met_dram_chann_num_header: %d,%d,%d,%d,%d\n",
925 dram_chann_num, DRAM_EMI_BASECLOCK_RATE, DRAM_IO_BUS_WIDTH, DRAM_DATARATE, 0);
926
927 /* metemi_func_opt for middleware */
928 ret += snprintf(buf+ret, PAGE_SIZE-ret, "met-info [000] 0.0: metemi_func_opt_header: %d\n",
929 metemi_func_opt);
930
931 dram_data_rate_MHz = get_dram_data_rate();
932 ret += snprintf(buf+ret, PAGE_SIZE-ret,
933 "met-info [000] 0.0: met_dram_clockrate: %u\n",
934 dram_data_rate_MHz);
935
936 /*master port mapping*/
937 ret += snprintf(buf+ret, PAGE_SIZE-ret,
938 "met-info [000] 0.0: met_emi_mport_map: %s,%s,%s,%s,%s,%s,%s,%s\n",
939 BM_Master_M0_name, BM_Master_M1_name, BM_Master_M2_name, BM_Master_M3_name,
940 BM_Master_M4_name, BM_Master_M5_name, BM_Master_M6_name, BM_Master_M7_name);
941
942 /* not to change by default master port sequency */
943 ret += snprintf(buf+ret, PAGE_SIZE-ret,
944 "met-info [000] 0.0: met_emi_mgroup_map: %x,%x,%x,%x\n",
945 BM_Master_GP_AP, BM_Master_GP_MM, BM_Master_GP_GPU, BM_Master_GP_PERI);
946
947 /* 1 : by ondiemet, 0: by pure linux */
948 ret += snprintf(buf+ret, PAGE_SIZE-ret,
949 "met-info [000] 0.0: emi_use_ondiemet: %u\n",
950 emi_use_ondiemet);
951
952 /* msel header */
953 if (msel_enable) {
954 ret += snprintf(buf+ret, PAGE_SIZE-ret,
955 "met-info [000] 0.0: met_emi_msel: %x,%x,%x\n",
956 msel_group1 & BM_MASTER_ALL,
957 msel_group2 & BM_MASTER_ALL,
958 msel_group3 & BM_MASTER_ALL);
959 } else {
960 ret += snprintf(buf+ret, PAGE_SIZE-ret,
961 "met-info [000] 0.0: met_emi_msel: %x,%x,%x\n",
962 BM_Master_GP_1_Default & BM_MASTER_ALL,
963 BM_Master_GP_2_Default & BM_MASTER_ALL,
964 BM_Master_GP_3_Default & BM_MASTER_ALL);
965 }
966
967 /* ms_emi */
968 ret += snprintf(buf+ret, PAGE_SIZE-ret,
969 "# ms_emi: TS0,TS1,GP0_WSCT,GP1_WSCT,GP2_WSCT,GP3_WSCT,");
970 ret += snprintf(buf+ret, PAGE_SIZE-ret,
971 "M0_LATENCY,M1_LATENCY,M2_LATENCY,M3_LATENCY,M4_LATENCY,M5_LATENCY,M6_LATENCY,M7_LATENCY,");
972 ret += snprintf(buf+ret, PAGE_SIZE-ret,
973 "M0_TRANS,M1_TRANS,M2_TRANS,M3_TRANS,M4_TRANS,M5_TRANS,M6_TRANS,M7_TRANS,");
974 ret += snprintf(buf+ret, PAGE_SIZE-ret,
975 "BACT,BSCT,BCNT,");
976
977 for (i = 0; i < dram_chann_num; i++) {
978 if (i != 0)
979 ret += snprintf(buf+ret, PAGE_SIZE-ret,
980 ",");
981 ret += snprintf(buf+ret, PAGE_SIZE-ret,
982 "PageHit_%d,PageMiss_%d,InterBank_%d,Idle_%d,", i, i, i, i);
983 ret += snprintf(buf+ret, PAGE_SIZE-ret,
984 "mr4_%d,refresh_pop_%d,freerun_26m_%d,", i, i, i);
985 ret += snprintf(buf+ret, PAGE_SIZE-ret,
986 "read_bytes_%d,write_bytes_%d", i, i);
987 }
988 ret += snprintf(buf+ret, PAGE_SIZE-ret,
989 "\n");
990
991
992 ret += snprintf(buf+ret, PAGE_SIZE-ret,
993 "met-info [000] 0.0: met_emi_header: TS0,TS1,GP0_WSCT,GP1_WSCT,GP2_WSCT,GP3_WSCT,");
994 ret += snprintf(buf+ret, PAGE_SIZE-ret,
995 "M0_LATENCY,M1_LATENCY,M2_LATENCY,M3_LATENCY,M4_LATENCY,M5_LATENCY,M6_LATENCY,M7_LATENCY,");
996 ret += snprintf(buf+ret, PAGE_SIZE-ret,
997 "M0_TRANS,M1_TRANS,M2_TRANS,M3_TRANS,M4_TRANS,M5_TRANS,M6_TRANS,M7_TRANS,");
998 ret += snprintf(buf+ret, PAGE_SIZE-ret,
999 "BACT,BSCT,BCNT,");
1000
1001 for (i = 0; i < dram_chann_num; i++) {
1002 if (i != 0)
1003 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1004 ",");
1005 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1006 "PageHit_%d,PageMiss_%d,InterBank_%d,Idle_%d,", i, i, i, i);
1007 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1008 "mr4_%d,refresh_pop_%d,freerun_26m_%d,", i, i, i);
1009 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1010 "read_bytes_%d,write_bytes_%d", i, i);
1011 }
1012 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1013 "\n");
1014
1015
1016 /*TSCT header*/
1017 if (emi_tsct_enable == 1) {
1018 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1019 "met-info [000] 0.0: ms_ud_sys_header: ms_emi_tsct,");
1020 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1021 "tsct1,tsct2,tsct3,x,x,x\n");
1022 }
1023
1024
1025 /*MDCT header*/
1026 if (emi_mdct_enable == 1) {
1027 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1028 "met-info [000] 0.0: ms_ud_sys_header: ms_emi_mdct,");
1029 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1030 "RD_ULTRA,RD_MDMCU,d,d\n");
1031 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1032 "met-info [000] 0.0: ms_ud_sys_description: ms_emi_mdct:");
1033 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1034 "CHART_TYPE=histogram_edge;STATISTICS_METHOD=histogram_edge;CHART_RESAMPLE_METHOD=del_dup\n");
1035 }
1036
1037 /*ttype header*/
1038 if ((ttype1_16_en == BM_TTYPE1_16_ENABLE) && (ttype17_21_en == BM_TTYPE17_21_ENABLE)) {
1039 /*header = ttype1~21t*/
1040 int i;
1041
1042 ret += snprintf(buf+ret, PAGE_SIZE-ret, "met-info [000] 0.0: ms_ud_sys_header: ms_ttype,");
1043 for (i = 0; i < 21; i++)
1044 ret += snprintf(buf+ret, PAGE_SIZE-ret, "%s,", ttype_name[i]);
1045
1046 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");
1047
1048 } else if (ttype17_21_en == BM_TTYPE17_21_ENABLE) {
1049 /*header = ttype17~21t*/
1050 int i;
1051
1052 ret += snprintf(buf+ret, PAGE_SIZE-ret, "met-info [000] 0.0: ms_ud_sys_header: ms_ttype,");
1053
1054 for (i = 16; i < 21; i++)
1055 ret += snprintf(buf+ret, PAGE_SIZE-ret, "%s,", ttype_name[i]);
1056
1057 ret += snprintf(buf+ret, PAGE_SIZE-ret, "x,x,x,x,x\n");
1058 }
1059
1060 /* met_bw_limiter_header */
1061 if (bw_limiter_enable == BM_BW_LIMITER_ENABLE) {
1062 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1063 "met-info [000] 0.0: met_bw_limiter_header: CLK,");
1064 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1065 "ARBA,ARBB,ARBC,ARBD,ARBE,ARBF,ARBG,ARBH,BWCT0,BWCT1,BWCT2,BWCT3,BWCT4,BWST0,BWST1,BWCT0_2ND,BWCT1_2ND,BWST_2ND\n");
1066 }
1067 /* DRAM DVFS */
1068 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1069 "met-info [000] 0.0: ms_ud_sys_header: DRAM_DVFS,datarate(MHz),d\n");
1070 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1071 "met-info [000] 0.0: ms_ud_sys_description: DRAM_DVFS:");
1072 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1073 "CHART_TYPE=histogram_edge;STATISTICS_METHOD=histogram_edge;CHART_RESAMPLE_METHOD=del_dup\n");
1074
1075 /*PDIR met_dramc_header*/
1076 if (dramc_pdir_enable == 1) {
1077 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1078 "met-info [000] 0.0: met_dramc_header: ");
1079 for (i = 0; i < dram_chann_num; i++) {
1080 if (i != 0)
1081 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1082 ",");
1083 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1084 "rk0_pre_sb_%d,rk0_pre_pd_%d,rk0_act_sb_%d,rk0_act_pd_%d,", i, i, i, i);
1085 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1086 "rk1_pre_sb_%d,rk1_pre_pd_%d,rk1_act_sb_%d,rk1_act_pd_%d,", i, i, i, i);
1087 ret += snprintf(buf+ret, PAGE_SIZE-ret,
1088 "rk2_pre_sb_%d,rk2_pre_pd_%d,rk2_act_sb_%d,rk2_act_pd_%d", i, i, i, i);
1089 }
1090 ret += snprintf(buf+ret, PAGE_SIZE-ret, "\n");
1091 }
1092 return ret;
1093}
1094
1095struct metdevice met_emi = {
1096 .name = "emi",
1097 .owner = THIS_MODULE,
1098 .type = MET_TYPE_BUS,
1099 .create_subfs = met_emi_create,
1100 .delete_subfs = met_emi_delete,
1101 .cpu_related = 0,
1102 .start = met_emi_start,
1103 .stop = met_emi_stop,
1104 .timed_polling = met_emi_polling,
1105 .print_help = emi_print_help,
1106 .print_header = emi_print_header,
1107};