blob: 411fc1a19648bdcf9aad1f8d64a94755bb0d089e [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#include <linux/kernel.h>
14#include <linux/sched.h>
15#include <linux/device.h>
16#include <linux/miscdevice.h>
17#include <linux/module.h>
18#include <linux/dma-mapping.h>
19#include <linux/string.h>
20
21#define MET_USER_EVENT_SUPPORT
22#include "met_drv.h"
23#include "trace.h"
24
25#include "mtk_typedefs.h"
26#include "core_plf_init.h"
27#include "mtk_emi_bm_35.h"
28#include "interface.h"
29#include "met_dramc.h"
30
31#if defined(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) && defined(ONDIEMET_SUPPORT)
32#include "sspm/ondiemet_sspm.h"
33#endif
34
35#define FILE_NODE_DBG
36
37/*======================================================================*/
38/* Global variable definitions */
39/*======================================================================*/
40/*ondiemet emi sampling interval in us */
41int emi_tsct_enable = 1;
42int emi_mdct_enable = 1;
43int emi_TP_busfiltr_enable;
44
45
46/* Dynamic MonitorCounter selection !!!EXPERIMENT!!! */
47static int msel_enable;
48static unsigned int msel_group1 = BM_MASTER_ALL;
49static unsigned int msel_group2 = BM_MASTER_ALL;
50static unsigned int msel_group3 = BM_MASTER_ALL;
51
52
53/* Global variables */
54static struct kobject *kobj_emi;
55static int rwtype = BM_BOTH_READ_WRITE;
56
57/* BW Limiter */
58/*#define CNT_COUNTDOWN (1000-1)*/ /* 1000 * 1ms = 1sec */
59#define CNT_COUNTDOWN (0) /* 1ms */
60static int countdown;
61static int bw_limiter_enable = BM_BW_LIMITER_ENABLE;
62
63/* TTYPE counter */
64static int ttype1_16_en = BM_TTYPE1_16_DISABLE;
65static int ttype17_21_en = BM_TTYPE17_21_DISABLE;
66
67static int dramc_pdir_enable;
68static int dram_chann_num = 1;
69
70enum SSPM_Mode {
71 CUSTOMER_MODE = 0x0,
72 UNDEFINE_MODE = 0x1,
73 INTERNAL_MODE = 0X2780
74};
75
76
77
78/*======================================================================*/
79/* KOBJ Declarations */
80/*======================================================================*/
81
82
83DECLARE_KOBJ_ATTR_INT(emi_TP_busfiltr_enable, emi_TP_busfiltr_enable);
84
85
86DECLARE_KOBJ_ATTR_INT(msel_enable, msel_enable);
87DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group1, msel_group1, msel_group1 > 0 && msel_group1 <= BM_MASTER_ALL);
88DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group2, msel_group2, msel_group2 > 0 && msel_group2 <= BM_MASTER_ALL);
89DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group3, msel_group3, msel_group3 > 0 && msel_group3 <= BM_MASTER_ALL);
90
91
92
93/* KOBJ: rwtype */
94DECLARE_KOBJ_ATTR_INT_CHECK(rwtype, rwtype, rwtype >= 0 && rwtype <= BM_WRITE_ONLY);
95
96static unsigned int get_emi_clock_rate(unsigned int dram_data_rate_MHz)
97{
98 unsigned int DRAM_TYPE;
99
100 if (get_ddr_type_symbol) {
101 DRAM_TYPE = get_ddr_type_symbol();
102
103 if ((DRAM_TYPE == 2) || (DRAM_TYPE == 3))
104 return dram_data_rate_MHz / DRAM_EMI_BASECLOCK_RATE_LP4 / DRAM_DATARATE;
105 else
106 return dram_data_rate_MHz / DRAM_EMI_BASECLOCK_RATE_LP3 / DRAM_DATARATE;
107 } else {
108 METERROR("[%s][%d]get_ddr_type_symbol = NULL , use the TYPE_LPDDR3 setting\n", __func__, __LINE__);
109 return dram_data_rate_MHz / DRAM_EMI_BASECLOCK_RATE_LP3 / DRAM_DATARATE;
110 }
111}
112
113
114/* KOBJ: ttype1_16_en */
115DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
116 ttype1_16_en,
117 KOBJ_ITEM_LIST(
118 { BM_TTYPE1_16_ENABLE, "ENABLE" },
119 { BM_TTYPE1_16_DISABLE, "DISABLE" }
120 )
121 );
122DECLARE_KOBJ_ATTR_STR_LIST(ttype1_16_en, ttype1_16_en, ttype1_16_en);
123
124/* KOBJ: ttype17_21_en */
125DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
126 ttype17_21_en,
127 KOBJ_ITEM_LIST(
128 { BM_TTYPE17_21_ENABLE, "ENABLE" },
129 { BM_TTYPE17_21_DISABLE, "DISABLE" }
130 )
131 );
132DECLARE_KOBJ_ATTR_STR_LIST(ttype17_21_en, ttype17_21_en, ttype17_21_en);
133
134/* KOBJ: bw_limiter_enable */
135DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
136 bw_limiter_enable,
137 KOBJ_ITEM_LIST(
138 { BM_BW_LIMITER_ENABLE, "ENABLE" },
139 { BM_BW_LIMITER_DISABLE, "DISABLE" }
140 )
141 );
142
143DECLARE_KOBJ_ATTR_STR_LIST(bw_limiter_enable, bw_limiter_enable, bw_limiter_enable);
144
145/* KOBJ: ttype_master */
146DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
147 ttype_master,
148 KOBJ_ITEM_LIST(
149 { BM_MASTER_M0, "M0" },
150 { BM_MASTER_M1, "M1" },
151 { BM_MASTER_M2, "M2" },
152 { BM_MASTER_M3, "M3" },
153 { BM_MASTER_M4, "M4" },
154 { BM_MASTER_M5, "M5" },
155 { BM_MASTER_M6, "M6" },
156 { BM_MASTER_M7, "M7" }
157 )
158 );
159
160
161/* KOBJ: ttypeX_nbeat, ttypeX_nbyte, ttypeX_burst */
162DECLARE_KOBJ_ATTR_INT_LIST_ITEM(
163 ttype_nbeat,
164 KOBJ_ITEM_LIST(
165 { BM_TRANS_TYPE_1BEAT, 1 },
166 { BM_TRANS_TYPE_2BEAT, 2 },
167 { BM_TRANS_TYPE_3BEAT, 3 },
168 { BM_TRANS_TYPE_4BEAT, 4 },
169 { BM_TRANS_TYPE_5BEAT, 5 },
170 { BM_TRANS_TYPE_6BEAT, 6 },
171 { BM_TRANS_TYPE_7BEAT, 7 },
172 { BM_TRANS_TYPE_8BEAT, 8 },
173 { BM_TRANS_TYPE_9BEAT, 9 },
174 { BM_TRANS_TYPE_10BEAT, 10 },
175 { BM_TRANS_TYPE_11BEAT, 11 },
176 { BM_TRANS_TYPE_12BEAT, 12 },
177 { BM_TRANS_TYPE_13BEAT, 13 },
178 { BM_TRANS_TYPE_14BEAT, 14 },
179 { BM_TRANS_TYPE_15BEAT, 15 },
180 { BM_TRANS_TYPE_16BEAT, 16 }
181 )
182 );
183DECLARE_KOBJ_ATTR_INT_LIST_ITEM(
184 ttype_nbyte,
185 KOBJ_ITEM_LIST(
186 { BM_TRANS_TYPE_1Byte, 1 },
187 { BM_TRANS_TYPE_2Byte, 2 },
188 { BM_TRANS_TYPE_4Byte, 4 },
189 { BM_TRANS_TYPE_8Byte, 8 },
190 { BM_TRANS_TYPE_16Byte, 16 },
191 { BM_TRANS_TYPE_32Byte, 32 }
192 )
193 );
194DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
195 ttype_burst,
196 KOBJ_ITEM_LIST(
197 { BM_TRANS_TYPE_BURST_INCR, "INCR" },
198 { BM_TRANS_TYPE_BURST_WRAP, "WRAP" }
199 )
200 );
201
202DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
203 ttype_rw,
204 KOBJ_ITEM_LIST(
205 { BM_TRANS_RW_DEFAULT, "DEFAULT" },
206 { BM_TRANS_RW_READONLY, "R" },
207 { BM_TRANS_RW_WRITEONLY, "W" },
208 { BM_TRANS_RW_RWBOTH, "BOTH" }
209 )
210 );
211
212
213DECLARE_KOBJ_ATTR_INT(dramc_pdir_enable, dramc_pdir_enable);
214
215/*enable high priority filter*/
216static int high_priority_filter;
217DECLARE_KOBJ_ATTR_HEX(high_priority_filter, high_priority_filter);
218
219
220
221/**/
222static int ttype_master_val[21];
223static int ttype_busid_val[21];
224static int ttype_nbeat_val[21];
225static int ttype_nbyte_val[21];
226static int ttype_burst_val[21];
227static int ttype_rw_val[21];
228
229#define DECLARE_KOBJ_TTYPE_MASTER(nr) \
230 DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _master, ttype_master_val[nr - 1], ttype_master)
231
232#define DECLARE_KOBJ_TTYPE_NBEAT(nr) \
233 DECLARE_KOBJ_ATTR_INT_LIST(ttype ## nr ## _nbeat, ttype_nbeat_val[nr - 1], ttype_nbeat)
234
235#define DECLARE_KOBJ_TTYPE_NBYTE(nr) \
236 DECLARE_KOBJ_ATTR_INT_LIST(ttype ## nr ## _nbyte, ttype_nbyte_val[nr - 1], ttype_nbyte)
237
238#define DECLARE_KOBJ_TTYPE_BURST(nr) \
239 DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _burst, ttype_burst_val[nr - 1], ttype_burst)
240
241#define DECLARE_KOBJ_TTYPE_RW(nr) \
242 DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _rw, ttype_rw_val[nr - 1], ttype_rw)
243
244#define DECLARE_KOBJ_TTYPE_BUSID_VAL(nr) \
245 DECLARE_KOBJ_ATTR_HEX(ttype ## nr ## _busid, ttype_busid_val[nr - 1])
246
247DECLARE_KOBJ_TTYPE_MASTER(1);
248DECLARE_KOBJ_TTYPE_NBEAT(1);
249DECLARE_KOBJ_TTYPE_NBYTE(1);
250DECLARE_KOBJ_TTYPE_BURST(1);
251DECLARE_KOBJ_TTYPE_RW(1);
252DECLARE_KOBJ_TTYPE_BUSID_VAL(1);
253
254DECLARE_KOBJ_TTYPE_MASTER(2);
255DECLARE_KOBJ_TTYPE_NBEAT(2);
256DECLARE_KOBJ_TTYPE_NBYTE(2);
257DECLARE_KOBJ_TTYPE_BURST(2);
258DECLARE_KOBJ_TTYPE_RW(2);
259DECLARE_KOBJ_TTYPE_BUSID_VAL(2);
260
261DECLARE_KOBJ_TTYPE_MASTER(3);
262DECLARE_KOBJ_TTYPE_NBEAT(3);
263DECLARE_KOBJ_TTYPE_NBYTE(3);
264DECLARE_KOBJ_TTYPE_BURST(3);
265DECLARE_KOBJ_TTYPE_RW(3);
266DECLARE_KOBJ_TTYPE_BUSID_VAL(3);
267
268DECLARE_KOBJ_TTYPE_MASTER(4);
269DECLARE_KOBJ_TTYPE_NBEAT(4);
270DECLARE_KOBJ_TTYPE_NBYTE(4);
271DECLARE_KOBJ_TTYPE_BURST(4);
272DECLARE_KOBJ_TTYPE_RW(4);
273DECLARE_KOBJ_TTYPE_BUSID_VAL(4);
274
275DECLARE_KOBJ_TTYPE_MASTER(5);
276DECLARE_KOBJ_TTYPE_NBEAT(5);
277DECLARE_KOBJ_TTYPE_NBYTE(5);
278DECLARE_KOBJ_TTYPE_BURST(5);
279DECLARE_KOBJ_TTYPE_RW(5);
280DECLARE_KOBJ_TTYPE_BUSID_VAL(5);
281
282DECLARE_KOBJ_TTYPE_MASTER(6);
283DECLARE_KOBJ_TTYPE_NBEAT(6);
284DECLARE_KOBJ_TTYPE_NBYTE(6);
285DECLARE_KOBJ_TTYPE_BURST(6);
286DECLARE_KOBJ_TTYPE_RW(6);
287DECLARE_KOBJ_TTYPE_BUSID_VAL(6);
288
289DECLARE_KOBJ_TTYPE_MASTER(7);
290DECLARE_KOBJ_TTYPE_NBEAT(7);
291DECLARE_KOBJ_TTYPE_NBYTE(7);
292DECLARE_KOBJ_TTYPE_BURST(7);
293DECLARE_KOBJ_TTYPE_RW(7);
294DECLARE_KOBJ_TTYPE_BUSID_VAL(7);
295
296DECLARE_KOBJ_TTYPE_MASTER(8);
297DECLARE_KOBJ_TTYPE_NBEAT(8);
298DECLARE_KOBJ_TTYPE_NBYTE(8);
299DECLARE_KOBJ_TTYPE_BURST(8);
300DECLARE_KOBJ_TTYPE_RW(8);
301DECLARE_KOBJ_TTYPE_BUSID_VAL(8);
302
303DECLARE_KOBJ_TTYPE_MASTER(9);
304DECLARE_KOBJ_TTYPE_NBEAT(9);
305DECLARE_KOBJ_TTYPE_NBYTE(9);
306DECLARE_KOBJ_TTYPE_BURST(9);
307DECLARE_KOBJ_TTYPE_RW(9);
308DECLARE_KOBJ_TTYPE_BUSID_VAL(9);
309
310DECLARE_KOBJ_TTYPE_MASTER(10);
311DECLARE_KOBJ_TTYPE_NBEAT(10);
312DECLARE_KOBJ_TTYPE_NBYTE(10);
313DECLARE_KOBJ_TTYPE_BURST(10);
314DECLARE_KOBJ_TTYPE_RW(10);
315DECLARE_KOBJ_TTYPE_BUSID_VAL(10);
316
317DECLARE_KOBJ_TTYPE_MASTER(11);
318DECLARE_KOBJ_TTYPE_NBEAT(11);
319DECLARE_KOBJ_TTYPE_NBYTE(11);
320DECLARE_KOBJ_TTYPE_BURST(11);
321DECLARE_KOBJ_TTYPE_RW(11);
322DECLARE_KOBJ_TTYPE_BUSID_VAL(11);
323
324DECLARE_KOBJ_TTYPE_MASTER(12);
325DECLARE_KOBJ_TTYPE_NBEAT(12);
326DECLARE_KOBJ_TTYPE_NBYTE(12);
327DECLARE_KOBJ_TTYPE_BURST(12);
328DECLARE_KOBJ_TTYPE_RW(12);
329DECLARE_KOBJ_TTYPE_BUSID_VAL(12);
330
331DECLARE_KOBJ_TTYPE_MASTER(13);
332DECLARE_KOBJ_TTYPE_NBEAT(13);
333DECLARE_KOBJ_TTYPE_NBYTE(13);
334DECLARE_KOBJ_TTYPE_BURST(13);
335DECLARE_KOBJ_TTYPE_RW(13);
336DECLARE_KOBJ_TTYPE_BUSID_VAL(13);
337
338DECLARE_KOBJ_TTYPE_MASTER(14);
339DECLARE_KOBJ_TTYPE_NBEAT(14);
340DECLARE_KOBJ_TTYPE_NBYTE(14);
341DECLARE_KOBJ_TTYPE_BURST(14);
342DECLARE_KOBJ_TTYPE_RW(14);
343DECLARE_KOBJ_TTYPE_BUSID_VAL(14);
344
345DECLARE_KOBJ_TTYPE_MASTER(15);
346DECLARE_KOBJ_TTYPE_NBEAT(15);
347DECLARE_KOBJ_TTYPE_NBYTE(15);
348DECLARE_KOBJ_TTYPE_BURST(15);
349DECLARE_KOBJ_TTYPE_RW(15);
350DECLARE_KOBJ_TTYPE_BUSID_VAL(15);
351
352DECLARE_KOBJ_TTYPE_MASTER(16);
353DECLARE_KOBJ_TTYPE_NBEAT(16);
354DECLARE_KOBJ_TTYPE_NBYTE(16);
355DECLARE_KOBJ_TTYPE_BURST(16);
356DECLARE_KOBJ_TTYPE_RW(16);
357DECLARE_KOBJ_TTYPE_BUSID_VAL(16);
358
359DECLARE_KOBJ_TTYPE_MASTER(17);
360DECLARE_KOBJ_TTYPE_NBEAT(17);
361DECLARE_KOBJ_TTYPE_NBYTE(17);
362DECLARE_KOBJ_TTYPE_BURST(17);
363DECLARE_KOBJ_TTYPE_RW(17);
364DECLARE_KOBJ_TTYPE_BUSID_VAL(17);
365
366DECLARE_KOBJ_TTYPE_MASTER(18);
367DECLARE_KOBJ_TTYPE_NBEAT(18);
368DECLARE_KOBJ_TTYPE_NBYTE(18);
369DECLARE_KOBJ_TTYPE_BURST(18);
370DECLARE_KOBJ_TTYPE_RW(18);
371DECLARE_KOBJ_TTYPE_BUSID_VAL(18);
372
373DECLARE_KOBJ_TTYPE_MASTER(19);
374DECLARE_KOBJ_TTYPE_NBEAT(19);
375DECLARE_KOBJ_TTYPE_NBYTE(19);
376DECLARE_KOBJ_TTYPE_BURST(19);
377DECLARE_KOBJ_TTYPE_RW(19);
378DECLARE_KOBJ_TTYPE_BUSID_VAL(19);
379
380DECLARE_KOBJ_TTYPE_MASTER(20);
381DECLARE_KOBJ_TTYPE_NBEAT(20);
382DECLARE_KOBJ_TTYPE_NBYTE(20);
383DECLARE_KOBJ_TTYPE_BURST(20);
384DECLARE_KOBJ_TTYPE_RW(20);
385DECLARE_KOBJ_TTYPE_BUSID_VAL(20);
386
387DECLARE_KOBJ_TTYPE_MASTER(21);
388DECLARE_KOBJ_TTYPE_NBEAT(21);
389DECLARE_KOBJ_TTYPE_NBYTE(21);
390DECLARE_KOBJ_TTYPE_BURST(21);
391DECLARE_KOBJ_TTYPE_RW(21);
392DECLARE_KOBJ_TTYPE_BUSID_VAL(21);
393
394
395/* SEDA 3.5 ext */
396static unsigned int msel_group_ext_val[WSCT_AMOUNT];
397static unsigned int wsct_rw_val[WSCT_AMOUNT];
398
399char* const delim_comma = ",";
400char* const delim_coclon = ":";
401
402
403char msel_group_ext[FILE_NODE_DATA_LEN] = {'\0'};
404
405static void _clear_msel_group_ext(void) {
406 int i;
407
408 for (i=0;i<WSCT_AMOUNT;i++) {
409 msel_group_ext_val[i] = BM_MASTER_ALL;
410 }
411
412 /*WSCT 4~5 default is ultra, pre-ultra total*/
413 msel_group_ext[0] = '\0';
414}
415
416static ssize_t msel_group_ext_store(struct kobject *kobj,
417 struct kobj_attribute *attr,
418 const char *buf,
419 size_t n)
420{
421 /*parse wsct_id:group,
422 1. split data by ","
423 2. split subdata by ":"
424 3. check the value is OK
425
426 don't clear the setting, do this by echo 1 > clear_setting
427 */
428
429 char *token, *cur= msel_group_ext;
430 char *_id = NULL, *_master_group = NULL;
431 int id_int = 0;
432
433 _clear_msel_group_ext();
434
435 snprintf(msel_group_ext, FILE_NODE_DATA_LEN, "%s", buf);
436 msel_group_ext[n-1]='\0';
437
438
439 while (cur != NULL) {
440 token = strsep(&cur, delim_comma);
441 PR_BOOTMSG("token: %s\n",token);
442 /*token EX: 4:0xff , (ID,master_group)*/
443
444 _id = strsep(&token, delim_coclon); // ID
445 _master_group = strsep(&token, delim_coclon);
446
447 PR_BOOTMSG("_id[%s] _master_group[%s]\n",_id,_master_group);
448
449 if (_id == NULL || _master_group == NULL) {
450 PR_BOOTMSG("err: _id[%s] _master_group[%s], para can't be NULL\n",_id,_master_group);
451 _clear_msel_group_ext();
452 return -EINVAL;
453 }
454
455 if (kstrtouint(_id, 0, &id_int) != 0) {
456 PR_BOOTMSG("_id[%s] trans to hex err\n",_id);
457 _clear_msel_group_ext();
458 return -EINVAL;
459 }
460
461
462 if ( id_int >= 0 && id_int < WSCT_AMOUNT) {
463 if (kstrtouint(_master_group, 0, &msel_group_ext_val[id_int]) != 0) {
464 PR_BOOTMSG("master_group[%s] trans to hex err\n",_master_group);
465 _clear_msel_group_ext();
466 return -EINVAL;
467 }
468 } else {
469 PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1);
470 _clear_msel_group_ext();
471 return -EINVAL;
472 }
473 }
474#ifdef FILE_NODE_DBG
475 PR_BOOTMSG("input data [%s]\n",msel_group_ext);
476 /*PR_BOOTMSG("msel_group_ext_store size para n[%d]\n",n);*/
477 int i;
478 PR_BOOTMSG("save data\n");
479 for (i=0;i<WSCT_AMOUNT;i++) {
480 PR_BOOTMSG("id[%d]=%X\n",i,msel_group_ext_val[i]);
481 }
482#endif
483 return n;
484}
485
486static ssize_t msel_group_ext_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
487{
488 return snprintf(buf, PAGE_SIZE, "%s\n", msel_group_ext);
489}
490
491
492char wsct_rw[FILE_NODE_DATA_LEN] = {'\0'};
493
494static void _clear_wsct_rw(void) {
495 int i;
496
497 for (i=0;i<WSCT_AMOUNT;i++) {
498 wsct_rw_val[i] = BM_WSCT_RW_RWBOTH;
499 }
500 wsct_rw[0] = '\0';
501}
502
503static ssize_t wsct_rw_store(struct kobject *kobj,
504 struct kobj_attribute *attr,
505 const char *buf,
506 size_t n)
507{
508 char *token, *cur= wsct_rw;
509 char *_id = NULL, *_rw_type = NULL;
510 int id_int = 0;
511
512 _clear_wsct_rw();
513
514 snprintf(wsct_rw, FILE_NODE_DATA_LEN, "%s", buf);
515 wsct_rw[n-1]='\0';
516
517 while (cur != NULL) {
518 token = strsep(&cur, delim_comma);
519 PR_BOOTMSG("token: %s\n",token);
520 /*token EX: 4:R , 5:W (ID,RW)*/
521
522 _id = strsep(&token, delim_coclon); // ID
523 _rw_type = strsep(&token, delim_coclon);
524
525 if (_id == NULL || _rw_type == NULL) {
526 PR_BOOTMSG("err: _id[%s] _rw_type[%s], para can't be NULL\n",_id, _rw_type);
527 _clear_wsct_rw();
528 return -EINVAL;
529 }
530
531 PR_BOOTMSG("_id[%s] _rw_type[%s]\n",_id, _rw_type);
532 if (kstrtouint(_id, 0, &id_int) != 0) {
533 PR_BOOTMSG("_id[%s] trans to hex err\n",_id);
534 _clear_wsct_rw();
535 return -EINVAL;
536 }
537
538
539 if ( id_int >= 0 && id_int < WSCT_AMOUNT) {
540 if ( 0 == strncmp("NONE",_rw_type,4))
541 wsct_rw_val[id_int] = BM_WSCT_RW_DISABLE;
542 else if (0 == strncmp("R",_rw_type,4))
543 wsct_rw_val[id_int] = BM_WSCT_RW_READONLY;
544 else if (0 == strncmp("W",_rw_type,4))
545 wsct_rw_val[id_int] = BM_WSCT_RW_WRITEONLY;
546 else if (0 == strncmp("RW",_rw_type,4))
547 wsct_rw_val[id_int] = BM_WSCT_RW_RWBOTH;
548 else {
549 PR_BOOTMSG("_id[%s] has err rwtype[%s]\n", _id, _rw_type);
550 _clear_wsct_rw();
551 return -EINVAL;
552 }
553
554 } else {
555 PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1);
556 _clear_wsct_rw();
557 return -EINVAL;
558 }
559 }
560
561#ifdef FILE_NODE_DBG
562 PR_BOOTMSG("wsct_rw_store input data [%s]\n",wsct_rw);
563 int i;
564 PR_BOOTMSG("rwtype save data\n");
565 for (i=0;i<WSCT_AMOUNT;i++) {
566 PR_BOOTMSG("id[%d]=%d\n",i,wsct_rw_val[i]);
567 }
568#endif
569 return n;
570}
571
572static ssize_t wsct_rw_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
573{
574 return snprintf(buf, PAGE_SIZE, "%s\n", wsct_rw);
575}
576
577
578static unsigned int WSCT_HPRI_DIS[WSCT_AMOUNT];
579static unsigned int WSCT_HPRI_SEL[WSCT_AMOUNT];
580char wsct_high_priority_enable[FILE_NODE_DATA_LEN] = {'\0'};
581
582static void _clear_wsct_high_priority_enable(void) {
583 int i;
584
585 for (i=0;i<WSCT_AMOUNT;i++) {
586 WSCT_HPRI_DIS[i] = 1;
587 WSCT_HPRI_SEL[i] = 0xF;
588 }
589
590 WSCT_HPRI_DIS[4] = 0;
591 WSCT_HPRI_SEL[4] = 0x8; /* ultra */
592
593 WSCT_HPRI_DIS[5] = 0;
594 WSCT_HPRI_SEL[5] = 0x4; /* pre_ultra */
595
596
597 wsct_high_priority_enable[0] = '\0';
598}
599
600static ssize_t wsct_high_priority_enable_store(struct kobject *kobj,
601 struct kobj_attribute *attr,
602 const char *buf,
603 size_t n)
604{
605 char *token, *cur= wsct_high_priority_enable;
606 char *_id = NULL, *_enable = NULL, *_level = NULL;
607 int id_int = 0, level_int = 0;
608
609 _clear_wsct_high_priority_enable();
610
611 snprintf(wsct_high_priority_enable, FILE_NODE_DATA_LEN, "%s", buf);
612 wsct_high_priority_enable[n-1]='\0';
613
614 while (cur != NULL) {
615 token = strsep(&cur, delim_comma);
616 PR_BOOTMSG("token: %s\n",token);
617 /*token EX: 4:R , 5:W (ID,RW)*/
618
619 _id = strsep(&token, delim_coclon); // ID
620 _enable = strsep(&token, delim_coclon);
621 _level = strsep(&token, delim_coclon);
622
623 PR_BOOTMSG("_id[%s] _enable[%s] _level[%s]\n",_id, _enable, _level);
624
625 if (_id == NULL || _enable == NULL || _level == NULL ) {
626 PR_BOOTMSG("err : _id[%s] _enable[%s] _level[%s], para can't be NULL\n",_id, _enable, _level);
627 _clear_wsct_high_priority_enable();
628 return -EINVAL;
629 }
630
631 if (kstrtouint(_id, 0, &id_int) != 0) {
632 PR_BOOTMSG("_id[%s] trans to hex err\n",_id);
633 _clear_wsct_high_priority_enable();
634 return -EINVAL;
635 }
636
637
638 if ( id_int >= 0 && id_int < WSCT_AMOUNT) {
639 if ( 0 == strncmp("disable", _enable, 7)) {
640
641 WSCT_HPRI_DIS[id_int] = 1;
642 WSCT_HPRI_SEL[id_int] = 0xf;
643 } else if ( 0 == strncmp("enable", _enable, 6)) {
644
645 WSCT_HPRI_DIS[id_int] = 0;
646 if (kstrtouint(_level, 0, &level_int) != 0) {
647 PR_BOOTMSG("_id[%s] trans ultraLevel[%s] to hex err\n",_id, _level);
648 _clear_wsct_high_priority_enable();
649 return -EINVAL;
650 }
651 WSCT_HPRI_SEL[id_int] = level_int & 0xF;
652 } else {
653 PR_BOOTMSG("_id[%s] has err enable[%s] (enable/disable)\n", _id, _enable);
654 _clear_wsct_high_priority_enable();
655 return -EINVAL;
656 }
657
658 } else {
659 PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1);
660 _clear_wsct_high_priority_enable();
661 return -EINVAL;
662 }
663 }
664#ifdef FILE_NODE_DBG
665 PR_BOOTMSG("input data [%s]\n",wsct_high_priority_enable);
666 int i;
667 PR_BOOTMSG("wsct_high_priority_enable save data\n");
668 for (i=0;i<WSCT_AMOUNT;i++) {
669 PR_BOOTMSG("id[%d]=(%X,%X)\n", i, WSCT_HPRI_DIS[i], WSCT_HPRI_SEL[i]);
670 }
671#endif
672 return n;
673}
674
675static ssize_t wsct_high_priority_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
676{
677 return snprintf(buf, PAGE_SIZE, "%s\n", wsct_high_priority_enable);
678}
679
680
681static unsigned int wsct_busid_val[WSCT_AMOUNT];
682static unsigned int wsct_idMask_val[WSCT_AMOUNT];
683
684char wsct_busid[FILE_NODE_DATA_LEN] = {'\0'};
685
686static void _clear_wsct_busid(void) {
687 int i;
688
689 for (i=0;i<WSCT_AMOUNT;i++) {
690 wsct_busid_val[i] = 0xfffff;
691 wsct_idMask_val[i] = 0x1FFF;
692 }
693 wsct_busid[0] = '\0';
694}
695
696static ssize_t wsct_busid_store(struct kobject *kobj,
697 struct kobj_attribute *attr,
698 const char *buf,
699 size_t n)
700{
701 char *token, *cur= wsct_busid;
702
703 char *_id = NULL, *_busid = NULL, *_idMask = NULL;
704 int id_int = 0, busid_int = 0, idMask_int = 0;
705
706 _clear_wsct_busid();
707
708 snprintf(wsct_busid, FILE_NODE_DATA_LEN, "%s", buf);
709 wsct_busid[n-1]='\0';
710
711 while (cur != NULL) {
712 token = strsep(&cur, delim_comma);
713 PR_BOOTMSG("token: %s\n",token);
714 /*token EX: 4:R , 5:W (ID,RW)*/
715
716 _id = strsep(&token, delim_coclon); // ID
717 _busid = strsep(&token, delim_coclon);
718 _idMask = strsep(&token, delim_coclon);
719
720 PR_BOOTMSG("_id[%s] _busid[%s] _idMask[%s]\n",_id, _busid, _idMask);
721
722 if (_id == NULL || _busid == NULL || _idMask == NULL) {
723 PR_BOOTMSG("err: _id[%s] _busid[%s] _idMask[%s] ,parameter can't be NULL\n",_id, _busid, _idMask);
724 _clear_wsct_busid();
725 return -EINVAL;
726 }
727
728
729 if (kstrtouint(_id, 0, &id_int) != 0) {
730 PR_BOOTMSG("_id[%s] trans to hex err\n",_id);
731 _clear_wsct_busid();
732 return -EINVAL;
733 }
734 if (kstrtouint(_busid, 0, &busid_int) != 0) {
735 PR_BOOTMSG("_busid[%s] trans to hex err\n",_busid);
736 _clear_wsct_busid();
737 return -EINVAL;
738 }
739 if (kstrtouint(_idMask, 0, &idMask_int) != 0) {
740 PR_BOOTMSG("_idMask[%s] trans to hex err\n",_idMask);
741 _clear_wsct_busid();
742 return -EINVAL;
743 }
744
745
746 if ( id_int >= 0 && id_int < WSCT_AMOUNT) {
747 wsct_busid_val[id_int] = busid_int;
748 wsct_idMask_val[id_int] = idMask_int;
749
750 } else {
751 PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1);
752 _clear_wsct_busid();
753 return -EINVAL;
754 }
755 }
756#ifdef FILE_NODE_DBG
757 PR_BOOTMSG("input data [%s]\n",wsct_busid);
758 int i;
759 PR_BOOTMSG("wsct_busid save data\n");
760 for (i=0;i<WSCT_AMOUNT;i++) {
761 PR_BOOTMSG("id[%d](busid,idMask)=(%X,%X)\n", i, wsct_busid_val[i], wsct_idMask_val[i]);
762 }
763#endif
764 return n;
765}
766
767static ssize_t wsct_busid_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
768{
769 return snprintf(buf, PAGE_SIZE, "%s\n", wsct_busid);
770}
771
772
773static unsigned int wsct_chn_rank_sel_val[WSCT_AMOUNT];
774char wsct_chn_rank_sel[FILE_NODE_DATA_LEN] = {'\0'};
775
776static void _clear_wsct_chn_rank_sel(void) {
777 int i;
778
779 for (i=0;i<WSCT_AMOUNT;i++) {
780 wsct_chn_rank_sel_val[i] = 0xF;
781 }
782 wsct_chn_rank_sel[0] = '\0';
783}
784
785static ssize_t wsct_chn_rank_sel_store(struct kobject *kobj,
786 struct kobj_attribute *attr,
787 const char *buf,
788 size_t n)
789{
790 char *token, *cur= wsct_chn_rank_sel;
791 char *_id = NULL, *_chn_rank = NULL;
792 int id_int = 0, chn_rank_int = 0;
793
794 _clear_wsct_chn_rank_sel();
795
796 snprintf(wsct_chn_rank_sel, FILE_NODE_DATA_LEN, "%s", buf);
797 wsct_chn_rank_sel[n-1]='\0';
798
799
800 while (cur != NULL) {
801 token = strsep(&cur, delim_comma);
802 PR_BOOTMSG("token: %s\n",token);
803 /*token EX: 4:f , 5:C (ID,chn_rnk_sel)*/
804
805 _id = strsep(&token, delim_coclon); // ID
806 _chn_rank = strsep(&token, delim_coclon);
807
808 PR_BOOTMSG("_id[%s] _chn_rank[%s]\n",_id, _chn_rank);
809
810 if (_id == NULL || _chn_rank == NULL) {
811 PR_BOOTMSG("err : _id[%s] _chn_rank[%s], para can't be NULL\n",_id, _chn_rank);
812 _clear_wsct_chn_rank_sel();
813 return -EINVAL;
814 }
815
816
817 if (kstrtouint(_id, 0, &id_int) != 0) {
818 PR_BOOTMSG("_id[%s] trans to hex err\n",_id);
819 _clear_wsct_chn_rank_sel();
820 return -EINVAL;
821 }
822 if (kstrtouint(_chn_rank, 0, &chn_rank_int) != 0) {
823 PR_BOOTMSG("_chn_rank[%s] trans to hex err\n",_id);
824 _clear_wsct_chn_rank_sel();
825 return -EINVAL;
826 }
827
828 if ( id_int >= 0 && id_int < WSCT_AMOUNT) {
829 wsct_chn_rank_sel_val[id_int] = chn_rank_int;
830
831 } else {
832 PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1);
833 _clear_wsct_chn_rank_sel();
834 return -EINVAL;
835 }
836 }
837
838#ifdef FILE_NODE_DBG
839 PR_BOOTMSG("wsct_chn_rank_sel input data [%s]\n",wsct_chn_rank_sel);
840 int i;
841 PR_BOOTMSG("wsct_chn_rank_sel_val save data\n");
842 for (i=0;i<WSCT_AMOUNT;i++) {
843 PR_BOOTMSG("id[%d]=%X\n",i,wsct_chn_rank_sel_val[i]);
844 }
845#endif
846 return n;
847}
848
849static ssize_t wsct_chn_rank_sel_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
850{
851 return snprintf(buf, PAGE_SIZE, "%s\n", wsct_chn_rank_sel);
852}
853
854static unsigned int wsct_byte_low_bnd_val[WSCT_AMOUNT];
855static unsigned int wsct_byte_up_bnd_val[WSCT_AMOUNT];
856static unsigned int wsct_byte_bnd_dis[WSCT_AMOUNT];
857char wsct_burst_range[FILE_NODE_DATA_LEN] = {'\0'};
858
859static void _clear_wsct_burst_range(void) {
860 int i;
861
862 for (i=0;i<WSCT_AMOUNT;i++) {
863 wsct_byte_low_bnd_val[i] = 0x0;
864 wsct_byte_up_bnd_val[i] = 0x1FF;
865 wsct_byte_bnd_dis[i] = 1;
866 }
867 wsct_burst_range[0] = '\0';
868}
869
870static ssize_t wsct_burst_range_store(struct kobject *kobj,
871 struct kobj_attribute *attr,
872 const char *buf,
873 size_t n)
874{
875 char *token, *cur= wsct_burst_range;
876 char *_id = NULL, *_low_bnd = NULL, *_up_bnd = NULL;
877 int id_int = 0, low_bnd_int = 0, up_bnd_int = 0;
878
879 _clear_wsct_burst_range();
880
881 snprintf(wsct_burst_range, FILE_NODE_DATA_LEN, "%s", buf);
882 wsct_burst_range[n-1]='\0';
883
884
885 while (cur != NULL) {
886 token = strsep(&cur, delim_comma);
887 PR_BOOTMSG("token: %s\n",token);
888 /*token EX: 4:f , 5:C (ID,chn_rnk_sel)*/
889
890 _id = strsep(&token, delim_coclon); // ID
891 _low_bnd = strsep(&token, delim_coclon);
892 _up_bnd = strsep(&token, delim_coclon);
893
894 PR_BOOTMSG("_id[%s] _low_bnd[%s] _up_bnd[%s]\n",_id, _low_bnd, _up_bnd);
895
896 if (_id == NULL || _low_bnd == NULL || _up_bnd == NULL) {
897 PR_BOOTMSG("err : _id[%s] _low_bnd[%s] _up_bnd[%s], para can't be NULL\n",_id, _low_bnd, _up_bnd);
898 _clear_wsct_burst_range();
899 return -EINVAL;
900 }
901
902 if (kstrtouint(_id, 0, &id_int) != 0) {
903 PR_BOOTMSG("_id[%s] trans to hex err\n",_id);
904 _clear_wsct_burst_range();
905 return -EINVAL;
906 }
907 if (kstrtouint(_low_bnd, 0, &low_bnd_int) != 0) {
908 PR_BOOTMSG("_low_bnd[%s] trans to hex err\n",_id);
909 _clear_wsct_burst_range();
910 return -EINVAL;
911 }
912 if (kstrtouint(_up_bnd, 0, &up_bnd_int) != 0) {
913 PR_BOOTMSG("_up_bnd[%s] trans to hex err\n",_id);
914 _clear_wsct_burst_range();
915 return -EINVAL;
916 }
917
918 if ( id_int >= 0 && id_int < WSCT_AMOUNT) {
919 wsct_byte_low_bnd_val[id_int] = low_bnd_int;
920 wsct_byte_up_bnd_val[id_int] = up_bnd_int;
921 wsct_byte_bnd_dis[id_int] = 0;
922 } else {
923 PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1);
924 _clear_wsct_burst_range();
925 return -EINVAL;
926 }
927 }
928
929#ifdef FILE_NODE_DBG
930 PR_BOOTMSG("wsct_burst_range_store input data [%s]\n",wsct_burst_range);
931 int i;
932 PR_BOOTMSG("wsct_burst_range save data\n");
933 for (i=0;i<WSCT_AMOUNT;i++) {
934 PR_BOOTMSG("id[%d](low_bnd,up_bnd)=(%X,%X)\n",i,wsct_byte_low_bnd_val[i],wsct_byte_up_bnd_val[i]);
935 }
936#endif
937 return n;
938}
939
940static ssize_t wsct_burst_range_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
941{
942 return snprintf(buf, PAGE_SIZE, "%s\n", wsct_burst_range);
943}
944
945
946
947static unsigned int tsct_busid_enable_val[TSCT_AMOUNT];
948char tsct_busid_enable[FILE_NODE_DATA_LEN] = {'\0'};
949
950static void _clear_tsct_busid_enable(void) {
951 int i;
952
953 for (i=0;i<TSCT_AMOUNT;i++) {
954 tsct_busid_enable_val[i] = 0;
955 }
956 tsct_busid_enable[0] = '\0';
957}
958
959static ssize_t tsct_busid_enable_store(struct kobject *kobj,
960 struct kobj_attribute *attr,
961 const char *buf,
962 size_t n)
963{
964 char *token, *cur= tsct_busid_enable;
965 char *_id = NULL, *_enable = NULL;
966 int id_int = 0;
967
968 _clear_tsct_busid_enable();
969
970 snprintf(tsct_busid_enable, FILE_NODE_DATA_LEN, "%s", buf);
971 tsct_busid_enable[n-1]='\0';
972
973
974 while (cur != NULL) {
975 token = strsep(&cur, delim_comma);
976 PR_BOOTMSG("token: %s\n",token);
977 /*token EX: 4:R , 5:W (ID,RW)*/
978
979 _id = strsep(&token, delim_coclon); // ID
980 _enable = strsep(&token, delim_coclon);
981
982
983 PR_BOOTMSG("_id[%s] _enable[%s]\n",_id, _enable);
984
985 if (_id == NULL || _enable == NULL) {
986 PR_BOOTMSG("err : _id[%s] _enable[%s], para can't be NULL\n",_id, _enable);
987 _clear_tsct_busid_enable();
988 return -EINVAL;
989 }
990
991 if (kstrtouint(_id, 0, &id_int) != 0) {
992 PR_BOOTMSG("_id[%s] trans to hex err\n",_id);
993 _clear_tsct_busid_enable();
994 return -EINVAL;
995 }
996
997
998 if ( id_int >= 0 && id_int < TSCT_AMOUNT) {
999 if ( 0 == strncmp("disable", _enable, 7)) {
1000 tsct_busid_enable_val[id_int] = 0;
1001 } else if ( 0 == strncmp("enable", _enable, 6)) {
1002 tsct_busid_enable_val[id_int] = 1;
1003 } else {
1004 PR_BOOTMSG("_id[%s] has err enable[%s] (enable/disable)\n", _id, _enable);
1005 _clear_tsct_busid_enable();
1006 return -EINVAL;
1007 }
1008
1009 } else {
1010 PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, TSCT_AMOUNT-1);
1011 _clear_tsct_busid_enable();
1012 return -EINVAL;
1013 }
1014 }
1015#ifdef FILE_NODE_DBG
1016 PR_BOOTMSG("tsct_busid_enable input data [%s]\n",tsct_busid_enable);
1017 int i;
1018 PR_BOOTMSG("wsct_high_priority_enable save data\n");
1019 for (i=0;i<TSCT_AMOUNT;i++) {
1020 PR_BOOTMSG("id[%d]=(%d)\n", i, tsct_busid_enable_val[i]);
1021 }
1022#endif
1023 return n;
1024}
1025
1026static ssize_t tsct_busid_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
1027{
1028 return snprintf(buf, PAGE_SIZE, "%s\n", tsct_busid_enable);
1029}
1030
1031
1032/* use the origin para high_priority_filter to save the en/dis setting */
1033static unsigned int TTYPE_HPRI_SEL[BM_COUNTER_MAX];
1034char ttype_high_priority_ext[FILE_NODE_DATA_LEN] = {'\0'};
1035
1036static void _clear_ttype_high_priority_ext(void) {
1037 int i;
1038
1039 for (i=0;i<BM_COUNTER_MAX;i++) {
1040 TTYPE_HPRI_SEL[i] = 0xf;
1041 }
1042
1043 high_priority_filter = 0x0;
1044 ttype_high_priority_ext[0] = '\0';
1045}
1046
1047static ssize_t ttype_high_priority_ext_store(struct kobject *kobj,
1048 struct kobj_attribute *attr,
1049 const char *buf,
1050 size_t n)
1051{
1052 char *token, *cur= ttype_high_priority_ext;
1053 char *_id = NULL, *_enable = NULL, *_level = NULL;
1054 int id_int = 0, level_int = 0;
1055
1056 _clear_ttype_high_priority_ext();
1057
1058 snprintf(ttype_high_priority_ext, FILE_NODE_DATA_LEN, "%s", buf);
1059 ttype_high_priority_ext[n-1]='\0';
1060
1061 while (cur != NULL) {
1062 token = strsep(&cur, delim_comma);
1063 PR_BOOTMSG("token: %s\n",token);
1064 /*token EX: 4:R , 5:W (ID,RW)*/
1065
1066 _id = strsep(&token, delim_coclon); // ID
1067 _enable = strsep(&token, delim_coclon);
1068 _level = strsep(&token, delim_coclon);
1069
1070 PR_BOOTMSG("_id[%s] _enable[%s] _level[%s]\n",_id, _enable, _level);
1071
1072 if (_id == NULL || _enable == NULL || _level == NULL ) {
1073 PR_BOOTMSG("err : _id[%s] _enable[%s] _level[%s], para can't be NULL\n",_id, _enable, _level);
1074 _clear_ttype_high_priority_ext();
1075 return -EINVAL;
1076 }
1077
1078 if (kstrtouint(_id, 0, &id_int) != 0) {
1079 PR_BOOTMSG("_id[%s] trans to hex err\n",_id);
1080 _clear_ttype_high_priority_ext();
1081 return -EINVAL;
1082 }
1083
1084 id_int = id_int - 1;
1085 if ( id_int >= 0 && id_int < BM_COUNTER_MAX) {
1086 if ( 0 == strncmp("disable", _enable, 7)) {
1087
1088 high_priority_filter = ( high_priority_filter & ~(1<<id_int) ) | ( 0<<id_int );
1089 TTYPE_HPRI_SEL[id_int] = 0xf;
1090 } else if ( 0 == strncmp("enable", _enable, 6)) {
1091
1092 high_priority_filter = ( high_priority_filter & ~(1<<id_int) ) | ( 1<<id_int );
1093 if (kstrtouint(_level, 0, &level_int) != 0) {
1094 PR_BOOTMSG("_id[%s] trans ultraLevel[%s] to hex err\n",_id, _level);
1095 _clear_ttype_high_priority_ext();
1096 return -EINVAL;
1097 }
1098 TTYPE_HPRI_SEL[id_int] = level_int & 0xF;
1099 } else {
1100 PR_BOOTMSG("ttype_high_priority_ext: _id[%s] has err enable[%s] (enable/disable)\n", _id, _enable);
1101 _clear_ttype_high_priority_ext();
1102 return -EINVAL;
1103 }
1104
1105 } else {
1106 PR_BOOTMSG("id[%d] exceed the range, it must be 1~%d\n",id_int+1, BM_COUNTER_MAX);
1107 _clear_ttype_high_priority_ext();
1108 return -EINVAL;
1109 }
1110 }
1111#ifdef FILE_NODE_DBG
1112 PR_BOOTMSG("input data [%s]\n",ttype_high_priority_ext);
1113
1114 int i;
1115 PR_BOOTMSG("wsct_high_priority_enable save data\n");
1116 for (i=0;i<BM_COUNTER_MAX;i++) {
1117 PR_BOOTMSG("id[%d]=(%X,%X)\n", i+1, high_priority_filter>>i & 0x1, TTYPE_HPRI_SEL[i]);
1118 }
1119#endif
1120 return n;
1121}
1122
1123static ssize_t ttype_high_priority_ext_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
1124{
1125 return snprintf(buf, PAGE_SIZE, "%s\n", ttype_high_priority_ext);
1126}
1127
1128
1129static unsigned int ttype_idMask_val[BM_COUNTER_MAX];
1130char ttype_busid_ext[FILE_NODE_DATA_LEN] = {'\0'};
1131
1132static void _clear_ttype_busid_ext(void) {
1133 int i;
1134
1135 for (i=0;i<BM_COUNTER_MAX;i++) {
1136 ttype_busid_val[i] = 0xfffff;
1137 ttype_idMask_val[i] = 0x1FFF;
1138 }
1139 ttype_busid_ext[0] = '\0';
1140}
1141
1142/*id: 1~21*/
1143static ssize_t ttype_busid_ext_store(struct kobject *kobj,
1144 struct kobj_attribute *attr,
1145 const char *buf,
1146 size_t n)
1147{
1148 char *token, *cur= ttype_busid_ext;
1149
1150 char *_id = NULL, *_busid = NULL, *_idMask = NULL;
1151 int id_int = 0, busid_int = 0, idMask_int = 0;
1152
1153 _clear_ttype_busid_ext();
1154
1155 snprintf(ttype_busid_ext, FILE_NODE_DATA_LEN, "%s", buf);
1156 ttype_busid_ext[n-1]='\0';
1157
1158 while (cur != NULL) {
1159 token = strsep(&cur, delim_comma);
1160 PR_BOOTMSG("token: %s\n",token);
1161 /*token EX: 4:R , 5:W (ID,RW)*/
1162
1163 _id = strsep(&token, delim_coclon); // ID
1164 _busid = strsep(&token, delim_coclon);
1165 _idMask = strsep(&token, delim_coclon);
1166
1167 PR_BOOTMSG("_id[%s] _busid[%s] _idMask[%s]\n",_id, _busid, _idMask);
1168
1169 if (_id == NULL || _busid == NULL || _idMask == NULL) {
1170 PR_BOOTMSG("err: ttype_busid_ext _id[%s] _busid[%s] _idMask[%s] ,parameter can't be NULL\n",_id, _busid, _idMask);
1171 _clear_ttype_busid_ext();
1172 return -EINVAL;
1173 }
1174
1175 if (kstrtouint(_id, 0, &id_int) != 0) {
1176 PR_BOOTMSG("_id[%s] trans to hex err\n",_id);
1177 _clear_ttype_busid_ext();
1178 return -EINVAL;
1179 }
1180 if (kstrtouint(_busid, 0, &busid_int) != 0) {
1181 PR_BOOTMSG("_busid[%s] trans to hex err\n",_busid);
1182 _clear_ttype_busid_ext();
1183 return -EINVAL;
1184 }
1185 if (kstrtouint(_idMask, 0, &idMask_int) != 0) {
1186 PR_BOOTMSG("_idMask[%s] trans to hex err\n",_idMask);
1187 _clear_ttype_busid_ext();
1188 return -EINVAL;
1189 }
1190
1191 id_int = id_int - 1;
1192 if ( id_int >= 0 && id_int < BM_COUNTER_MAX) {
1193 ttype_busid_val[id_int] = busid_int;
1194 ttype_idMask_val[id_int] = idMask_int;
1195
1196 } else {
1197 PR_BOOTMSG("ttype_busid_ext id[%d] exceed the range, it must be 1~%d\n",id_int+1, BM_COUNTER_MAX);
1198 _clear_ttype_busid_ext();
1199 return -EINVAL;
1200 }
1201 }
1202#ifdef FILE_NODE_DBG
1203 PR_BOOTMSG("ttype_busid_ext input data [%s]\n",ttype_busid_ext);
1204
1205 int i;
1206 PR_BOOTMSG("ttype_busid_ext save data\n");
1207 for (i=0;i<BM_COUNTER_MAX;i++) {
1208 PR_BOOTMSG("id[%d](busid,idMask)=(%X,%X)\n", i+1, ttype_busid_val[i], ttype_idMask_val[i]);
1209 }
1210#endif
1211 return n;
1212}
1213
1214static ssize_t ttype_busid_ext_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
1215{
1216 return snprintf(buf, PAGE_SIZE, "%s\n", ttype_busid_ext);
1217}
1218
1219
1220static unsigned int ttype_chn_rank_sel_val[BM_COUNTER_MAX];
1221char ttype_chn_rank_sel[FILE_NODE_DATA_LEN] = {'\0'};
1222
1223static void _clear_ttype_chn_rank_sel(void) {
1224 int i;
1225
1226 for (i=0;i<BM_COUNTER_MAX;i++) {
1227 ttype_chn_rank_sel_val[i] = 0xF;
1228 }
1229 ttype_chn_rank_sel[0] = '\0';
1230}
1231
1232static ssize_t ttype_chn_rank_sel_store(struct kobject *kobj,
1233 struct kobj_attribute *attr,
1234 const char *buf,
1235 size_t n)
1236{
1237 char *token, *cur= ttype_chn_rank_sel;
1238 char *_id = NULL, *_chn_rank = NULL;
1239 int id_int = 0, chn_rank_int = 0;
1240
1241 _clear_ttype_chn_rank_sel();
1242
1243 snprintf(ttype_chn_rank_sel, FILE_NODE_DATA_LEN, "%s", buf);
1244 ttype_chn_rank_sel[n-1]='\0';
1245
1246 while (cur != NULL) {
1247 token = strsep(&cur, delim_comma);
1248 PR_BOOTMSG("token: %s\n",token);
1249 /*token EX: 4:f , 5:C (ID,chn_rnk_sel)*/
1250
1251 _id = strsep(&token, delim_coclon); // ID
1252 _chn_rank = strsep(&token, delim_coclon);
1253
1254 PR_BOOTMSG("_id[%s] _chn_rank[%s]\n",_id, _chn_rank);
1255
1256 if (_id == NULL || _chn_rank == NULL) {
1257 PR_BOOTMSG("err (ttype_chn_rank_sel): _id[%s] _chn_rank[%s], para can't be NULL\n",_id, _chn_rank);
1258 _clear_ttype_chn_rank_sel();
1259 return -EINVAL;
1260 }
1261
1262
1263 if (kstrtouint(_id, 0, &id_int) != 0) {
1264 PR_BOOTMSG("_id[%s] trans to hex err\n",_id);
1265 _clear_ttype_chn_rank_sel();
1266 return -EINVAL;
1267 }
1268 if (kstrtouint(_chn_rank, 0, &chn_rank_int) != 0) {
1269 PR_BOOTMSG("_chn_rank[%s] trans to hex err\n",_id);
1270 _clear_ttype_chn_rank_sel();
1271 return -EINVAL;
1272 }
1273
1274 id_int = id_int -1;
1275
1276 if ( id_int >= 0 && id_int < BM_COUNTER_MAX) {
1277 ttype_chn_rank_sel[id_int] = chn_rank_int;
1278
1279 } else {
1280 PR_BOOTMSG("id[%d] exceed the range, it must be 1~%d\n",id_int+1, BM_COUNTER_MAX);
1281 _clear_ttype_chn_rank_sel();
1282 return -EINVAL;
1283 }
1284 }
1285
1286#ifdef FILE_NODE_DBG
1287 PR_BOOTMSG("ttype_chn_rank_sel input data [%s]\n",ttype_chn_rank_sel);
1288
1289 int i;
1290 PR_BOOTMSG("wsct_chn_rank_sel_val save data\n");
1291 for (i=0;i<BM_COUNTER_MAX;i++) {
1292 PR_BOOTMSG("id[%d]=%X\n",i+1,ttype_chn_rank_sel[i]);
1293 }
1294#endif
1295 return n;
1296}
1297
1298static ssize_t ttype_chn_rank_sel_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
1299{
1300 return snprintf(buf, PAGE_SIZE, "%s\n", ttype_chn_rank_sel);
1301}
1302
1303
1304static unsigned int ttype_byte_low_bnd_val[BM_COUNTER_MAX];
1305static unsigned int ttype_byte_up_bnd_val[BM_COUNTER_MAX];
1306static unsigned int ttype_byte_bnd_dis[BM_COUNTER_MAX];
1307char ttype_burst_range[FILE_NODE_DATA_LEN] = {'\0'};
1308
1309static void _clear_ttype_burst_range(void) {
1310 int i;
1311
1312 for (i=0;i<BM_COUNTER_MAX;i++) {
1313 ttype_byte_low_bnd_val[i] = 0x0;
1314 ttype_byte_up_bnd_val[i] = 0x1FF;
1315 ttype_byte_bnd_dis[i] = 1;
1316 }
1317 ttype_burst_range[0] = '\0';
1318}
1319
1320static ssize_t ttype_burst_range_store(struct kobject *kobj,
1321 struct kobj_attribute *attr,
1322 const char *buf,
1323 size_t n)
1324{
1325 char *token, *cur= ttype_burst_range;
1326 char *_id = NULL, *_low_bnd = NULL, *_up_bnd = NULL;
1327 int id_int = 0, low_bnd_int = 0, up_bnd_int = 0;
1328
1329 _clear_ttype_burst_range();
1330
1331 snprintf(ttype_burst_range, FILE_NODE_DATA_LEN, "%s", buf);
1332 ttype_burst_range[n-1]='\0';
1333
1334
1335 while (cur != NULL) {
1336 token = strsep(&cur, delim_comma);
1337 PR_BOOTMSG("token: %s\n",token);
1338 /*token EX: 4:f , 5:C (ID,chn_rnk_sel)*/
1339
1340 _id = strsep(&token, delim_coclon); // ID
1341 _low_bnd = strsep(&token, delim_coclon);
1342 _up_bnd = strsep(&token, delim_coclon);
1343
1344 PR_BOOTMSG("_id[%s] _low_bnd[%s] _up_bnd[%s]\n",_id, _low_bnd, _up_bnd);
1345
1346 if (_id == NULL || _low_bnd == NULL || _up_bnd == NULL) {
1347 PR_BOOTMSG("err (ttype_burst_range): _id[%s] _low_bnd[%s] _up_bnd[%s], para can't be NULL\n",
1348 _id, _low_bnd, _up_bnd);
1349 _clear_ttype_burst_range();
1350 return -EINVAL;
1351 }
1352
1353 if (kstrtouint(_id, 0, &id_int) != 0) {
1354 PR_BOOTMSG("_id[%s] trans to hex err\n",_id);
1355 _clear_ttype_burst_range();
1356 return -EINVAL;
1357 }
1358 if (kstrtouint(_low_bnd, 0, &low_bnd_int) != 0) {
1359 PR_BOOTMSG("_low_bnd[%s] trans to hex err\n",_id);
1360 _clear_ttype_burst_range();
1361 return -EINVAL;
1362 }
1363 if (kstrtouint(_up_bnd, 0, &up_bnd_int) != 0) {
1364 PR_BOOTMSG("_up_bnd[%s] trans to hex err\n",_id);
1365 _clear_ttype_burst_range();
1366 return -EINVAL;
1367 }
1368
1369 id_int = id_int - 1;
1370 if ( id_int >= 0 && id_int < BM_COUNTER_MAX) {
1371 ttype_byte_low_bnd_val[id_int] = low_bnd_int;
1372 ttype_byte_up_bnd_val[id_int] = up_bnd_int;
1373 ttype_byte_bnd_dis[id_int] = 0;
1374 } else {
1375 PR_BOOTMSG("id[%d] exceed the range, it must be 1~%d\n",id_int, BM_COUNTER_MAX);
1376 _clear_ttype_burst_range();
1377 return -EINVAL;
1378 }
1379 }
1380
1381#ifdef FILE_NODE_DBG
1382 PR_BOOTMSG("ttype_burst_range_store input data [%s]\n",ttype_burst_range);
1383
1384 int i;
1385 PR_BOOTMSG("ttype_burst_range save data\n");
1386 for (i=0;i<BM_COUNTER_MAX;i++) {
1387 PR_BOOTMSG("id[%d](low_bnd,up_bnd)=(%X,%X)\n",i+1,ttype_byte_low_bnd_val[i],ttype_byte_up_bnd_val[i]);
1388 }
1389#endif
1390 return n;
1391}
1392
1393static ssize_t ttype_burst_range_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
1394{
1395 return snprintf(buf, PAGE_SIZE, "%s\n", ttype_burst_range);
1396}
1397
1398static int reserve_wsct_setting;
1399DECLARE_KOBJ_ATTR_INT(reserve_wsct_setting, reserve_wsct_setting);
1400
1401static void _clear_setting(void) {
1402 /*clear all file node para here*/
1403
1404 PR_BOOTMSG("clear EMI file node setting\n");
1405
1406 _clear_msel_group_ext();
1407 _clear_wsct_rw();
1408 _clear_wsct_high_priority_enable();
1409 _clear_wsct_busid();
1410 _clear_wsct_chn_rank_sel();
1411 _clear_wsct_burst_range();
1412
1413 _clear_tsct_busid_enable();
1414 _clear_ttype_high_priority_ext();
1415 _clear_ttype_busid_ext();
1416 _clear_ttype_chn_rank_sel();
1417 _clear_ttype_burst_range();
1418 reserve_wsct_setting = 0;
1419
1420
1421
1422 emi_TP_busfiltr_enable = 0;
1423
1424 high_priority_filter = 0x0;
1425 rwtype = BM_BOTH_READ_WRITE;
1426 dramc_pdir_enable = 1;
1427
1428
1429 msel_enable = 0;
1430 msel_group1 = BM_MASTER_ALL;
1431 msel_group2 = BM_MASTER_ALL;
1432 msel_group3 = BM_MASTER_ALL;
1433
1434
1435 bw_limiter_enable = BM_BW_LIMITER_ENABLE;
1436 ttype1_16_en = BM_TTYPE1_16_DISABLE;
1437 ttype17_21_en = BM_TTYPE17_21_DISABLE;
1438
1439}
1440
1441static ssize_t clear_setting_store(struct kobject *kobj,
1442 struct kobj_attribute *attr,
1443 const char *buf,
1444 size_t n)
1445{
1446 int value;
1447
1448 if ((n == 0) || (buf == NULL))
1449 return -EINVAL;
1450
1451 if (kstrtoint(buf, 0, &value) != 0)
1452 return -EINVAL;
1453
1454 if (value == 1)
1455 _clear_setting();
1456
1457 return n;
1458}
1459
1460static struct kobj_attribute clear_setting_attr = __ATTR_WO(clear_setting); // OK
1461static struct kobj_attribute msel_group_ext_attr = __ATTR(msel_group_ext, 0664, msel_group_ext_show, msel_group_ext_store); //OK
1462static struct kobj_attribute wsct_rw_attr = __ATTR(wsct_rw, 0664, wsct_rw_show, wsct_rw_store);
1463static struct kobj_attribute wsct_high_priority_enable_attr = __ATTR(wsct_high_priority_enable, 0664, wsct_high_priority_enable_show, wsct_high_priority_enable_store);
1464static struct kobj_attribute wsct_busid_attr = __ATTR(wsct_busid, 0664, wsct_busid_show, wsct_busid_store);
1465static struct kobj_attribute wsct_chn_rank_sel_attr = __ATTR(wsct_chn_rank_sel, 0664, wsct_chn_rank_sel_show, wsct_chn_rank_sel_store);
1466static struct kobj_attribute wsct_burst_range_attr = __ATTR(wsct_burst_range, 0664, wsct_burst_range_show, wsct_burst_range_store);
1467static struct kobj_attribute tsct_busid_enable_attr = __ATTR(tsct_busid_enable, 0664, tsct_busid_enable_show, tsct_busid_enable_store);
1468static struct kobj_attribute ttype_high_priority_ext_attr = __ATTR(ttype_high_priority_ext, 0664, ttype_high_priority_ext_show, ttype_high_priority_ext_store);
1469static struct kobj_attribute ttype_busid_ext_attr = __ATTR(ttype_busid_ext, 0664, ttype_busid_ext_show, ttype_busid_ext_store);
1470static struct kobj_attribute ttype_chn_rank_sel_attr = __ATTR(ttype_chn_rank_sel, 0664, ttype_chn_rank_sel_show, ttype_chn_rank_sel_store);
1471static struct kobj_attribute ttype_burst_range_attr = __ATTR(ttype_burst_range, 0664, ttype_burst_range_show, ttype_burst_range_store);
1472
1473
1474
1475
1476
1477
1478/**/
1479#define KOBJ_ATTR_ITEM_SERIAL_FNODE(nr) \
1480 do { \
1481 KOBJ_ATTR_ITEM(ttype ## nr ## _master); \
1482 KOBJ_ATTR_ITEM(ttype ## nr ## _nbeat); \
1483 KOBJ_ATTR_ITEM(ttype ## nr ## _nbyte); \
1484 KOBJ_ATTR_ITEM(ttype ## nr ## _burst); \
1485 KOBJ_ATTR_ITEM(ttype ## nr ## _busid); \
1486 KOBJ_ATTR_ITEM(ttype ## nr ## _rw); \
1487 } while (0)
1488
1489#define KOBJ_ATTR_LIST \
1490 do { \
1491 KOBJ_ATTR_ITEM(high_priority_filter); \
1492 KOBJ_ATTR_ITEM(emi_TP_busfiltr_enable); \
1493 KOBJ_ATTR_ITEM(msel_enable); \
1494 KOBJ_ATTR_ITEM(msel_group1); \
1495 KOBJ_ATTR_ITEM(msel_group2); \
1496 KOBJ_ATTR_ITEM(msel_group3); \
1497 KOBJ_ATTR_ITEM(rwtype); \
1498 KOBJ_ATTR_ITEM(ttype17_21_en); \
1499 KOBJ_ATTR_ITEM(ttype1_16_en); \
1500 KOBJ_ATTR_ITEM_SERIAL_FNODE(1); \
1501 KOBJ_ATTR_ITEM_SERIAL_FNODE(2); \
1502 KOBJ_ATTR_ITEM_SERIAL_FNODE(3); \
1503 KOBJ_ATTR_ITEM_SERIAL_FNODE(4); \
1504 KOBJ_ATTR_ITEM_SERIAL_FNODE(5); \
1505 KOBJ_ATTR_ITEM_SERIAL_FNODE(6); \
1506 KOBJ_ATTR_ITEM_SERIAL_FNODE(7); \
1507 KOBJ_ATTR_ITEM_SERIAL_FNODE(8); \
1508 KOBJ_ATTR_ITEM_SERIAL_FNODE(9); \
1509 KOBJ_ATTR_ITEM_SERIAL_FNODE(10); \
1510 KOBJ_ATTR_ITEM_SERIAL_FNODE(11); \
1511 KOBJ_ATTR_ITEM_SERIAL_FNODE(12); \
1512 KOBJ_ATTR_ITEM_SERIAL_FNODE(13); \
1513 KOBJ_ATTR_ITEM_SERIAL_FNODE(14); \
1514 KOBJ_ATTR_ITEM_SERIAL_FNODE(15); \
1515 KOBJ_ATTR_ITEM_SERIAL_FNODE(16); \
1516 KOBJ_ATTR_ITEM_SERIAL_FNODE(17); \
1517 KOBJ_ATTR_ITEM_SERIAL_FNODE(18); \
1518 KOBJ_ATTR_ITEM_SERIAL_FNODE(19); \
1519 KOBJ_ATTR_ITEM_SERIAL_FNODE(20); \
1520 KOBJ_ATTR_ITEM_SERIAL_FNODE(21); \
1521 KOBJ_ATTR_ITEM(bw_limiter_enable); \
1522 KOBJ_ATTR_ITEM(dramc_pdir_enable); \
1523 KOBJ_ATTR_ITEM(clear_setting);\
1524 KOBJ_ATTR_ITEM(msel_group_ext);\
1525 KOBJ_ATTR_ITEM(wsct_rw);\
1526 KOBJ_ATTR_ITEM(wsct_high_priority_enable);\
1527 KOBJ_ATTR_ITEM(wsct_busid);\
1528 KOBJ_ATTR_ITEM(wsct_chn_rank_sel);\
1529 KOBJ_ATTR_ITEM(wsct_burst_range);\
1530 KOBJ_ATTR_ITEM(tsct_busid_enable);\
1531 KOBJ_ATTR_ITEM(ttype_high_priority_ext);\
1532 KOBJ_ATTR_ITEM(ttype_busid_ext);\
1533 KOBJ_ATTR_ITEM(ttype_chn_rank_sel);\
1534 KOBJ_ATTR_ITEM(ttype_burst_range);\
1535 KOBJ_ATTR_ITEM(reserve_wsct_setting);\
1536 } while (0)
1537
1538
1539
1540/*======================================================================*/
1541/* EMI Operations */
1542/*======================================================================*/
1543static void emi_init(void)
1544{
1545 unsigned int bmrw0_val, bmrw1_val, i, enable;
1546 /*unsigned int msel_group_val[4];*/
1547
1548 /*save origianl EMI config*/
1549 MET_BM_SaveCfg();
1550
1551 /* get dram channel number */
1552 dram_chann_num = MET_EMI_GetDramChannNum();
1553
1554 /* Init. EMI bus monitor */
1555 MET_BM_SetReadWriteType(rwtype);
1556
1557 /*handle the ori */
1558
1559 if (ttype1_16_en != BM_TTYPE1_16_ENABLE) {
1560 MET_BM_SetLatencyCounter(1); /*enable latency count*/
1561 }
1562 else {
1563 MET_BM_SetLatencyCounter(0); /*disable latency count*/
1564
1565 for (i = 1; i <= 16; i++) {
1566 MET_BM_SetMonitorCounter(i,
1567 ttype_master_val[i - 1],
1568 ttype_nbeat_val[i - 1] |
1569 ttype_nbyte_val[i - 1] |
1570 ttype_burst_val[i - 1]);
1571 }
1572 }
1573
1574 if (ttype17_21_en == BM_TTYPE17_21_ENABLE) {
1575 for (i = 17; i <= 21; i++) {
1576 MET_BM_SetMonitorCounter(i,
1577 ttype_master_val[i - 1],
1578 ttype_nbeat_val[i - 1] |
1579 ttype_nbyte_val[i - 1] |
1580 ttype_burst_val[i - 1]);
1581 }
1582 }
1583
1584 PR_BOOTMSG("[%s]reserve_wsct_setting=%d\n",__func__,reserve_wsct_setting);
1585
1586 if (reserve_wsct_setting == 0) {
1587 /* wsct 0 : total-all*/
1588 msel_group_ext_val[0] = BM_MASTER_ALL;
1589 wsct_rw_val[0] = BM_WSCT_RW_RWBOTH;
1590 WSCT_HPRI_DIS[0] = 1;
1591 WSCT_HPRI_SEL[0] = 0xF;
1592 wsct_busid_val[0] = 0xFFFFF;
1593 wsct_idMask_val[0] = 0x1FFF;
1594 wsct_chn_rank_sel_val[0] = 0xF;
1595 wsct_byte_bnd_dis[0] = 1;
1596
1597 /* wsct 4 : total-ultra*/
1598 msel_group_ext_val[4] = BM_MASTER_ALL;
1599 wsct_rw_val[4] = BM_WSCT_RW_RWBOTH;
1600 WSCT_HPRI_DIS[4] = 0;
1601 WSCT_HPRI_SEL[4] = 0x8; /* ultra */
1602 wsct_busid_val[4] = 0xFFFFF;
1603 wsct_idMask_val[4] = 0x1FFF;
1604 wsct_chn_rank_sel_val[4] = 0xF;
1605 wsct_byte_bnd_dis[4] = 1;
1606
1607 /* wsct 5 : total-pre_ultra*/
1608 msel_group_ext_val[5] = BM_MASTER_ALL;
1609 wsct_rw_val[5] = BM_WSCT_RW_RWBOTH;
1610 WSCT_HPRI_DIS[5] = 0;
1611 WSCT_HPRI_SEL[5] = 0x4; /* pre_ultra */
1612 wsct_busid_val[5] = 0xFFFFF;
1613 wsct_idMask_val[5] = 0x1FFF;
1614 wsct_chn_rank_sel_val[5] = 0xF;
1615 wsct_byte_bnd_dis[5] = 1;
1616 }
1617
1618 if (msel_enable) {
1619 /* if ole file node set, use the value */
1620 if ( msel_group1 != BM_MASTER_ALL )
1621 msel_group_ext_val[1] = msel_group1;
1622
1623 if ( msel_group2 != BM_MASTER_ALL )
1624 msel_group_ext_val[2] = msel_group2;
1625
1626 if ( msel_group3 != BM_MASTER_ALL )
1627 msel_group_ext_val[3] = msel_group3;
1628
1629 } else {
1630 for ( i=1; i<=3; i++) {
1631 msel_group_ext_val[i] = BM_MASTER_ALL;
1632 }
1633 }
1634
1635 MET_BM_SetWSCT_master_rw(msel_group_ext_val, wsct_rw_val);
1636 MET_BM_SetWSCT_high_priority(WSCT_HPRI_DIS, WSCT_HPRI_SEL);
1637 MET_BM_SetWSCT_busid_idmask(wsct_busid_val, wsct_idMask_val);
1638 MET_BM_SetWSCT_chn_rank_sel(wsct_chn_rank_sel_val);
1639 MET_BM_SetWSCT_burst_range(wsct_byte_bnd_dis, wsct_byte_low_bnd_val, wsct_byte_up_bnd_val);
1640 MET_BM_SetTSCT_busid_enable(tsct_busid_enable_val);
1641
1642 MET_BM_SetTtype_high_priority_sel(high_priority_filter, TTYPE_HPRI_SEL);
1643 MET_BM_SetTtype_busid_idmask(ttype_busid_val, ttype_idMask_val, ttype1_16_en, ttype17_21_en);
1644 MET_BM_SetTtype_chn_rank_sel(ttype_chn_rank_sel_val);
1645 MET_BM_SetTtype_burst_range(ttype_byte_bnd_dis, ttype_byte_low_bnd_val, ttype_byte_up_bnd_val);
1646
1647
1648 bmrw0_val = 0;
1649 for (i = 0; i < 16; i++)
1650 bmrw0_val |= (ttype_rw_val[i] << (i * 2));
1651
1652 bmrw1_val = 0;
1653 for (i = 16; i < 21; i++)
1654 bmrw1_val |= (ttype_rw_val[i] << ((i-16) * 2));
1655
1656 MET_BM_SetTtypeCounterRW(bmrw0_val, bmrw1_val);
1657
1658}
1659
1660
1661static void emi_uninit(void)
1662{
1663 MET_BM_RestoreCfg();
1664}
1665
1666
1667static inline int do_emi(void)
1668{
1669 return met_sspm_emi.mode;
1670}
1671
1672
1673
1674
1675
1676
1677
1678/*======================================================================*/
1679/* MET Device Operations */
1680/*======================================================================*/
1681static int emi_inited;
1682
1683static int met_emi_create(struct kobject *parent)
1684{
1685 int ret = 0;
1686 int i;
1687
1688 for (i = 0; i < 21; i++) {
1689 ttype_master_val[i] = BM_MASTER_M0;
1690 ttype_nbeat_val[i] = BM_TRANS_TYPE_1BEAT;
1691 ttype_nbyte_val[i] = BM_TRANS_TYPE_8Byte;
1692 ttype_burst_val[i] = BM_TRANS_TYPE_BURST_INCR;
1693 ttype_busid_val[i] = 0xfffff; /*default disable ttype bus sel if busid > 0xff_ff */
1694 ttype_rw_val[i] = BM_TRANS_RW_DEFAULT;
1695 }
1696
1697 _clear_msel_group_ext();
1698 _clear_wsct_rw();
1699 _clear_wsct_high_priority_enable();
1700 _clear_wsct_busid();
1701 _clear_wsct_chn_rank_sel();
1702 _clear_wsct_burst_range();
1703
1704 _clear_tsct_busid_enable();
1705 _clear_ttype_high_priority_ext();
1706 _clear_ttype_high_priority_ext();
1707 _clear_ttype_busid_ext();
1708 _clear_ttype_chn_rank_sel();
1709 _clear_ttype_burst_range();
1710
1711 reserve_wsct_setting = 0;
1712
1713
1714 ret = MET_BM_Init();
1715 if (ret != 0) {
1716 pr_notice("MET_BM_Init failed!!!\n");
1717 ret = 0; /* will retry later */
1718 } else {
1719 emi_inited = 1;
1720 }
1721
1722 kobj_emi = parent;
1723
1724#define KOBJ_ATTR_ITEM(attr_name) \
1725 do { \
1726 ret = sysfs_create_file(kobj_emi, &attr_name ## _attr.attr); \
1727 if (ret != 0) { \
1728 pr_notice("Failed to create " #attr_name " in sysfs\n"); \
1729 return ret; \
1730 } \
1731 } while (0)
1732 KOBJ_ATTR_LIST;
1733#undef KOBJ_ATTR_ITEM
1734
1735 return ret;
1736}
1737
1738
1739static void met_emi_delete(void)
1740{
1741#define KOBJ_ATTR_ITEM(attr_name) \
1742 sysfs_remove_file(kobj_emi, &attr_name##_attr.attr)
1743 if (kobj_emi != NULL) {
1744 KOBJ_ATTR_LIST;
1745 kobj_emi = NULL;
1746 }
1747#undef KOBJ_ATTR_ITEM
1748
1749 if (emi_inited)
1750 MET_BM_DeInit();
1751}
1752
1753
1754
1755static void met_emi_resume(void)
1756{
1757 if (!do_emi())
1758 return;
1759
1760 emi_init();
1761}
1762
1763
1764static const char help[] = " --emi monitor EMI banwidth\n";
1765static int emi_print_help(char *buf, int len)
1766{
1767 return snprintf(buf, PAGE_SIZE, help);
1768}
1769
1770
1771#define TTYPE_NAME_STR_LEN 64
1772/* static char ttype_name[21][TTYPE_NAME_STR_LEN]; */
1773static int emi_print_header(char *buf, int len)
1774{
1775 int ret = 0;
1776/* int ret_m[21]; */
1777 int i = 0;
1778
1779#if 1 /* move to AP side print header */
1780/*#ifndef CONFIG_MTK_TINYSYS_SSPM_SUPPORT*/
1781 unsigned int dram_data_rate_MHz;
1782 unsigned int DRAM_TYPE;
1783 unsigned int base_clock_rate;
1784#endif
1785
1786
1787 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1788 "met-info [000] 0.0: met_emi_wsct_amount: %d\n",WSCT_AMOUNT);
1789
1790 /* master selection header */
1791 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1792 "met-info [000] 0.0: met_emi_msel: %x,%x,%x\n",
1793 msel_group_ext_val[1] & BM_MASTER_ALL,
1794 msel_group_ext_val[2] & BM_MASTER_ALL,
1795 msel_group_ext_val[3] & BM_MASTER_ALL);
1796
1797 /*Ttype RW type header*/
1798 PR_BOOTMSG("rwtype=%d\n",rwtype);
1799 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_rw_cfg: ");
1800 if (rwtype == BM_READ_ONLY)
1801 ret += snprintf(buf + ret, PAGE_SIZE - ret, "R");
1802 else if (rwtype == BM_WRITE_ONLY)
1803 ret += snprintf(buf + ret, PAGE_SIZE - ret, "W");
1804 else
1805 ret += snprintf(buf + ret, PAGE_SIZE - ret, "BOTH");
1806
1807 for (i = 0; i < 21; i++) {
1808 if (ttype_rw_val[i] == BM_TRANS_RW_DEFAULT)
1809 ret += snprintf(buf + ret, PAGE_SIZE - ret, ",DEFAULT");
1810 else if (ttype_rw_val[i] == BM_TRANS_RW_READONLY)
1811 ret += snprintf(buf + ret, PAGE_SIZE - ret, ",R");
1812 else if (ttype_rw_val[i] == BM_TRANS_RW_WRITEONLY)
1813 ret += snprintf(buf + ret, PAGE_SIZE - ret, ",W");
1814 else /*BM_TRANS_RW_RWBOTH*/
1815 ret += snprintf(buf + ret, PAGE_SIZE - ret, ",BOTH");
1816 }
1817 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
1818
1819 /*ultra header*/
1820 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1821 "met-info [000] 0.0: met_emi_ultra_filter: %x\n", high_priority_filter);
1822
1823 /* ttype header */
1824 if (ttype17_21_en == BM_TTYPE17_21_ENABLE) {
1825 int i = 0;
1826 int j = 0;
1827
1828 /* ttype master list */
1829 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_ttype_master_list: ");
1830 for (i = 0; i < 21; i++) {
1831 for (j = 0; j < ARRAY_SIZE(ttype_master_list_item); j++) {
1832 if (ttype_master_val[i] == ttype_master_list_item[j].key) {
1833 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s,", ttype_master_list_item[j].val);
1834 }
1835 }
1836 }
1837 /* remove the last comma */
1838 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1839
1840 /* ttype busid list */
1841 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_ttype_busid_list: ");
1842 for (i = 0; i < 21; i++)
1843 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%x,", ttype_busid_val[i]);
1844
1845 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1846
1847 /* ttype nbeat list */
1848 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_ttype_nbeat_list: ");
1849 for (i = 0; i < 21; i++) {
1850 for (j = 0; j < ARRAY_SIZE(ttype_nbeat_list_item); j++) {
1851 if (ttype_nbeat_val[i] == ttype_nbeat_list_item[j].key) {
1852 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d,", ttype_nbeat_list_item[j].val);
1853 }
1854 }
1855 }
1856 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1857
1858 /* ttype nbyte list */
1859 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_ttype_nbyte_list: ");
1860 for (i = 0; i < 21; i++) {
1861 for (j = 0; j < ARRAY_SIZE(ttype_nbyte_list_item); j++) {
1862 if (ttype_nbyte_val[i] == ttype_nbyte_list_item[j].key) {
1863 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d,", ttype_nbyte_list_item[j].val);
1864 }
1865 }
1866 }
1867 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1868
1869 /* ttype burst list */
1870 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_ttype_burst_list: ");
1871 for (i = 0; i < 21; i++) {
1872 for (j = 0; j < ARRAY_SIZE(ttype_burst_list_item); j++) {
1873 if (ttype_burst_val[i] == ttype_burst_list_item[j].key) {
1874 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s,", ttype_burst_list_item[j].val);
1875 }
1876 }
1877 }
1878 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1879
1880 }
1881 /* ttype enable */
1882 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_ttype_enable: %d,%d\n",ttype1_16_en, ttype17_21_en);
1883
1884
1885#if 1 /*SEDA 3.5*/
1886
1887 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1888 "met-info [000] 0.0: met_emi_msel_ext: %x,%x,%x\n",
1889 msel_group_ext_val[0] & BM_MASTER_ALL,
1890 msel_group_ext_val[4] & BM_MASTER_ALL,
1891 msel_group_ext_val[5] & BM_MASTER_ALL);
1892
1893 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_wsct_rw: ");
1894
1895 for (i=0;i<WSCT_AMOUNT;i++) {
1896 if (wsct_rw_val[i] == BM_WSCT_RW_RWBOTH)
1897 ret += snprintf(buf + ret, PAGE_SIZE - ret, "RW,");
1898 else if (wsct_rw_val[i] == BM_WSCT_RW_READONLY)
1899 ret += snprintf(buf + ret, PAGE_SIZE - ret, "R,");
1900 else if (wsct_rw_val[i] == BM_WSCT_RW_WRITEONLY)
1901 ret += snprintf(buf + ret, PAGE_SIZE - ret, "W,");
1902 else /*disable*/
1903 ret += snprintf(buf + ret, PAGE_SIZE - ret, "NONE,");
1904 }
1905 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1906
1907
1908 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_wsct_HPRI_DIS: ");
1909 for (i=0;i<WSCT_AMOUNT;i++) {
1910 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d,",WSCT_HPRI_DIS[i]);
1911 }
1912 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1913
1914
1915 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_wsct_HPRI_SEL: ");
1916 for (i=0;i<WSCT_AMOUNT;i++) {
1917 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%x,",WSCT_HPRI_SEL[i]);
1918 }
1919 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1920
1921 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_wsct_busid: ");
1922 for (i=0;i<WSCT_AMOUNT;i++) {
1923 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%x,",wsct_busid_val[i]);
1924 }
1925 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1926
1927
1928 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_wsct_idMask: ");
1929 for (i=0;i<WSCT_AMOUNT;i++) {
1930 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%x,",wsct_idMask_val[i]);
1931 }
1932 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1933
1934 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: wsct_chn_rank_sel: ");
1935 for (i=0;i<WSCT_AMOUNT;i++) {
1936 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%x,",wsct_chn_rank_sel_val[i]);
1937 }
1938 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1939
1940 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: wsct_byte_bnd_dis: ");
1941 for (i=0;i<WSCT_AMOUNT;i++) {
1942 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d,",wsct_byte_bnd_dis[i]);
1943 }
1944 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1945
1946
1947 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: wsct_byte_low_bnd: ");
1948 for (i=0;i<WSCT_AMOUNT;i++) {
1949 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%x,",wsct_byte_low_bnd_val[i]);
1950 }
1951 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1952
1953 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: wsct_byte_up_bnd: ");
1954 for (i=0;i<WSCT_AMOUNT;i++) {
1955 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%x,",wsct_byte_up_bnd_val[i]);
1956 }
1957 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1958
1959 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: tsct_busid_enable: ");
1960 for (i=0;i<TSCT_AMOUNT;i++) {
1961 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d,",tsct_busid_enable_val[i]);
1962 }
1963 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1964
1965 /***************************** ttype ****************************************/
1966 if (ttype17_21_en == BM_TTYPE17_21_ENABLE) {
1967
1968 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: TTYPE_HPRI_SEL: ");
1969 for (i=0;i<BM_COUNTER_MAX;i++) {
1970 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%x,",TTYPE_HPRI_SEL[i]);
1971 }
1972 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1973
1974 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: ttype_idMask: ");
1975 for (i=0;i<BM_COUNTER_MAX;i++) {
1976 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%x,",ttype_idMask_val[i]);
1977 }
1978 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1979
1980 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: ttype_chn_rank_sel: ");
1981 for (i=0;i<BM_COUNTER_MAX;i++) {
1982 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%x,",ttype_chn_rank_sel_val[i]);
1983 }
1984 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1985
1986 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: ttype_byte_bnd_dis: ");
1987 for (i=0;i<BM_COUNTER_MAX;i++) {
1988 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d,",ttype_byte_bnd_dis[i]);
1989 }
1990 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1991
1992 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: ttype_byte_low_bnd_val: ");
1993 for (i=0;i<BM_COUNTER_MAX;i++) {
1994 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%x,",ttype_byte_low_bnd_val[i]);
1995 }
1996 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
1997
1998 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: ttype_byte_up_bnd_val: ");
1999 for (i=0;i<BM_COUNTER_MAX;i++) {
2000 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%x,",ttype_byte_up_bnd_val[i]);
2001 }
2002 snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n");
2003 }
2004#endif
2005
2006 /*IP version*/
2007 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2008 "met-info [000] 0.0: DRAMC_VER: %d\n", DRAMC_VER);
2009
2010 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2011 "met-info [000] 0.0: EMI_VER: %d.%d\n", EMI_VER_MAJOR, EMI_VER_MINOR);
2012
2013#if 1 /* SEDA3.5 header print move to AP side */
2014
2015 dram_chann_num = MET_EMI_GetDramChannNum();
2016
2017 if (!get_cur_ddr_ratio_symbol)
2018 PR_BOOTMSG("[%s][%d]get_cur_ddr_ratio_symbol = NULL , use the TYPE_LPDDR4 get_cur_ddr_ratio_symbol\n", __func__, __LINE__);
2019
2020 if (get_ddr_type_symbol) {
2021 DRAM_TYPE = get_ddr_type_symbol();
2022
2023 base_clock_rate = MET_EMI_Get_BaseClock_Rate();
2024
2025 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_dram_type: %d\n", DRAM_TYPE);
2026
2027 if ((DRAM_TYPE == 2) || (DRAM_TYPE == 3))
2028 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_dram_chann_num_header: %d,%d,%d,%d\n",
2029 dram_chann_num, base_clock_rate,
2030 DRAM_IO_BUS_WIDTH_LP4, DRAM_DATARATE);
2031 else
2032 ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_dram_chann_num_header: %d,%d,%d,%d\n",
2033 dram_chann_num, base_clock_rate,
2034 DRAM_IO_BUS_WIDTH_LP3, DRAM_DATARATE);
2035 } else
2036 METERROR("[%s][%d]get_ddr_type_symbol = NULL , use the TYPE_LPDDR3 setting\n", __func__, __LINE__);
2037
2038
2039 /* met_emi_clockrate */
2040 if (get_dram_data_rate_symbol) {
2041 dram_data_rate_MHz = get_dram_data_rate_symbol();
2042 } else {
2043 METERROR("get_dram_data_rate_symbol = NULL\n");
2044 dram_data_rate_MHz = 0;
2045 }
2046
2047 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2048 "met-info [000] 0.0: met_dram_clockrate: %d\n",
2049 dram_data_rate_MHz);
2050
2051
2052 /*dram bank num*/
2053 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2054 "met-info [000] 0.0: met_dram_rank_num_header: %u,%u\n", MET_EMI_GetDramRankNum(),
2055 MET_EMI_GetDramRankNum());
2056
2057 /* ms_emi header */
2058 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2059 "# ms_emi: TS0,TS1,GP0_WSCT,GP1_WSCT,GP2_WSCT,GP3_WSCT,");
2060 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2061 "M0_LATENCY,M1_LATENCY,M2_LATENCY,M3_LATENCY,M4_LATENCY,M5_LATENCY,M6_LATENCY,M7_LATENCY,");
2062 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2063 "M0_TRANS,M1_TRANS,M2_TRANS,M3_TRANS,M4_TRANS,M5_TRANS,M6_TRANS,M7_TRANS,");
2064 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2065 "BACT,BSCT,BCNT,WACT,DCM_CTRL,TACT,");
2066
2067 for (i = 0; i < dram_chann_num; i++) {
2068 if (i != 0)
2069 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2070 ",");
2071 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2072 "PageHit_%d,PageMiss_%d,InterBank_%d,Idle_%d,", i, i, i, i);
2073 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2074 "mr4_%d,refresh_pop_%d,freerun_26m_%d,", i, i, i);
2075 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2076 "read_bytes_%d,write_bytes_%d", i, i);
2077 }
2078 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
2079
2080 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2081 "met-info [000] 0.0: met_emi_header: TS0,TS1,GP0_WSCT,GP1_WSCT,GP2_WSCT,GP3_WSCT,");
2082 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2083 "M0_LATENCY,M1_LATENCY,M2_LATENCY,M3_LATENCY,M4_LATENCY,M5_LATENCY,M6_LATENCY,M7_LATENCY,");
2084 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2085 "M0_TRANS,M1_TRANS,M2_TRANS,M3_TRANS,M4_TRANS,M5_TRANS,M6_TRANS,M7_TRANS,");
2086 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2087 "BACT,BSCT,BCNT,WACT,DCM_CTRL,TACT,");
2088
2089 for (i = 0; i < dram_chann_num; i++) {
2090 if (i != 0)
2091 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2092 ",");
2093 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2094 "PageHit_%d,PageMiss_%d,InterBank_%d,Idle_%d,", i, i, i, i);
2095 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2096 "mr4_%d,refresh_pop_%d,freerun_26m_%d,", i, i, i);
2097 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2098 "read_bytes_%d,write_bytes_%d", i, i);
2099 }
2100 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
2101
2102 /*TSCT header*/
2103 if (emi_tsct_enable == 1) {
2104 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2105 "met-info [000] 0.0: ms_emi_tsct_header: ms_emi_tsct,");
2106 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2107 "tsct1,tsct2,tsct3\n");
2108 }
2109
2110 /*MDCT header*/
2111 if (emi_mdct_enable == 1) {
2112 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2113 "met-info [000] 0.0: ms_emi_mdct_header: ms_emi_mdct,");
2114 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2115 "RD_ULTRA,RD_MDMCU\n");
2116 }
2117
2118 /* met_bw_limiter_header */
2119 if (bw_limiter_enable == BM_BW_LIMITER_ENABLE) {
2120 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2121 "met-info [000] 0.0: met_bw_limiter_header: CLK,");
2122 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2123 "ARBA,ARBB,ARBC,ARBD,ARBE,ARBF,ARBG,ARBH,BWCT0,BWCT1,BWCT2,BWCT3,BWCT4,BWST0,BWST1,BWCT0_2ND,BWCT1_2ND,BWST_2ND\n");
2124 }
2125
2126 /* DRAM DVFS header */
2127 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2128 "met-info [000] 0.0: DRAM_DVFS_header: datarate(MHz)\n");
2129
2130 /*PDIR met_dramc_header*/
2131 if (dramc_pdir_enable == 1 && DRAMC_VER >= 2 ) {
2132 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2133 "met-info [000] 0.0: met_dramc_header: ");
2134 for (i = 0; i < dram_chann_num; i++) {
2135 if (i != 0)
2136 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2137 ",");
2138 ret += snprintf(buf + ret, PAGE_SIZE - ret, "freerun_26m_%d,", i);
2139 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2140 "rk0_pre_sb_%d,rk0_pre_pd_%d,rk0_act_sb_%d,rk0_act_pd_%d,", i, i, i, i);
2141 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2142 "rk1_pre_sb_%d,rk1_pre_pd_%d,rk1_act_sb_%d,rk1_act_pd_%d,", i, i, i, i);
2143 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2144 "rk2_pre_sb_%d,rk2_pre_pd_%d,rk2_act_sb_%d,rk2_act_pd_%d", i, i, i, i);
2145 }
2146 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
2147 }
2148
2149 /* DRS header */
2150 ret += snprintf(buf + ret, PAGE_SIZE - ret,
2151 "met-info [000] 0.0: emi_drs_header: ch0_RANK1_GP(%%),ch0_RANK1_SF(%%),ch0_ALL_SF(%%),ch1_RANK1_GP(%%),ch1_RANK1_SF(%%),ch1_ALL_SF(%%)\n");
2152#endif
2153
2154 return ret;
2155}
2156
2157
2158
2159static int ondiemet_emi_print_header(char *buf, int len)
2160{
2161 return emi_print_header(buf, len);
2162}
2163
2164
2165
2166static void MET_BM_IPI_REGISTER_CB(void)
2167{
2168 int ret, i;
2169 unsigned int rdata;
2170 unsigned int ipi_buf[4];
2171
2172 for (i = 0; i < 4; i++)
2173 ipi_buf[i] = 0;
2174
2175 if (sspm_buf_available == 1) {
2176 ipi_buf[0] = MET_MAIN_ID | (MID_EMI << MID_BIT_SHIFT) | MET_ARGU | SET_REGISTER_CB;
2177 ret = sspm_ipi_send_sync(IPI_ID_MET, IPI_OPT_WAIT, (void *)ipi_buf, 0, &rdata, 1);
2178 }
2179}
2180
2181
2182static void MET_BM_IPI_configs(void)
2183{
2184 int ret, i;
2185 unsigned int rdata;
2186 unsigned int ipi_buf[4];
2187
2188 for (i = 0; i < 4; i++)
2189 ipi_buf[i] = 0;
2190
2191 if (sspm_buf_available == 1) {
2192 ipi_buf[0] = MET_MAIN_ID | (MID_EMI << MID_BIT_SHIFT) | MET_ARGU | SET_EBM_CONFIGS1;
2193 ipi_buf[2] = EMI_VER_MAJOR << 24 | EMI_VER_MINOR << 16 | DRAMC_VER << 8 | 0;
2194 ret = sspm_ipi_send_sync(IPI_ID_MET, IPI_OPT_WAIT, (void *)ipi_buf, 0, &rdata, 1);
2195 }
2196}
2197
2198
2199static void ondiemet_emi_start(void)
2200{
2201 MET_BM_IPI_REGISTER_CB();
2202 if (!emi_inited) {
2203 if (MET_BM_Init() != 0) {
2204 met_sspm_emi.mode = 0;
2205 pr_notice("MET_BM_Init failed!!!\n");
2206 return;
2207 }
2208 emi_inited = 1;
2209 }
2210 MET_BM_IPI_configs();
2211
2212 if (do_emi())
2213 emi_init();
2214
2215 ondiemet_module[ONDIEMET_SSPM] |= ID_EMI;
2216}
2217
2218static void ondiemet_emi_stop(void)
2219{
2220 if (!emi_inited)
2221 return;
2222
2223 if (do_emi())
2224 emi_uninit();
2225}
2226
2227
2228
2229struct metdevice met_sspm_emi = {
2230 .name = "emi",
2231 .owner = THIS_MODULE,
2232 .type = MET_TYPE_BUS,
2233 .create_subfs = met_emi_create,
2234 .delete_subfs = met_emi_delete,
2235 .resume = met_emi_resume,
2236#if defined(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) && defined(ONDIEMET_SUPPORT)
2237 .ondiemet_start = ondiemet_emi_start,
2238 .ondiemet_stop = ondiemet_emi_stop,
2239 .ondiemet_print_help = emi_print_help,
2240 .ondiemet_print_header = ondiemet_emi_print_header,
2241#endif
2242 .ondiemet_mode = 1,
2243};
2244EXPORT_SYMBOL(met_sspm_emi);