[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/devtools/met-driver/met_drv/common/met_emi.c b/src/devtools/met-driver/met_drv/common/met_emi.c
new file mode 100644
index 0000000..7f18f4a
--- /dev/null
+++ b/src/devtools/met-driver/met_drv/common/met_emi.c
@@ -0,0 +1,1107 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/string.h>
+
+#define MET_USER_EVENT_SUPPORT
+#include "met_drv.h"
+#include "trace.h"
+
+#include "mtk_typedefs.h"
+#include "core_plf_init.h"
+#include "core_plf_trace.h"
+#include "mtk_emi_bm.h"
+
+extern struct miscdevice met_device;
+
+/*======================================================================*/
+/* Global variable definitions */
+/*======================================================================*/
+/*ondiemet emi sampling interval in us */
+int ondiemet_emi_polling_200us;
+int emi_tsct_enable;
+int emi_mdct_enable;
+
+
+int emi_use_ondiemet;
+int metemi_func_opt;
+
+int met_emi_regdump;
+/*WSCT/TSCT id selection enable*/
+int emi_wsct_tsct_id_selection[4];
+/* Dynamic MonitorCounter selection !!!EXPERIMENT!!! */
+static int msel_enable;
+static unsigned int msel_group1 = BM_Master_GP_1_Default;
+static unsigned int msel_group2 = BM_Master_GP_2_Default;
+static unsigned int msel_group3 = BM_Master_GP_3_Default;
+
+/* CVS Added changeable buffer for testing */
+static int mdmcu_sel_enable;
+static unsigned int rd_mdmcu_rsv_num = 0x5;
+
+/* Global variables */
+static struct kobject *kobj_emi;
+static int rwtype = BM_BOTH_READ_WRITE;
+
+/* BW Limiter */
+/*#define CNT_COUNTDOWN (1000-1)*/ /* 1000 * 1ms = 1sec */
+#define CNT_COUNTDOWN (0) /* 1ms */
+static int countdown;
+static int bw_limiter_enable = BM_BW_LIMITER_ENABLE;
+
+/* TTYPE counter */
+static int ttype1_16_en = BM_TTYPE1_16_DISABLE;
+static int ttype17_21_en = BM_TTYPE17_21_DISABLE;
+
+unsigned int fmem_divider_freq_1;
+unsigned int fmem_divider_freq_2;
+
+static int dramc_pdir_enable;
+static int dram_chann_num = 1;
+
+/*======================================================================*/
+/* EMI Test Operations */
+/*======================================================================*/
+static int times;
+
+static ssize_t test_apmcu_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf,
+ size_t n)
+{
+ int i;
+ unsigned int *src_addr_v;
+ dma_addr_t src_addr_p;
+
+ if ((n == 0) || (buf == NULL))
+ return -EINVAL;
+ if (sscanf(buf, "%d", ×) != 1)
+ return -EINVAL;
+ if (times < 0)
+ return -EINVAL;
+
+ if (times > 5000) /* Less than 20MB */
+ return -EINVAL;
+
+ /* dma_alloc */
+ src_addr_v = dma_alloc_coherent(met_device.this_device,
+ PAGE_SIZE,
+ &src_addr_p,
+ GFP_KERNEL);
+ if (src_addr_v == NULL) {
+ /* met_tag_oneshot(0, "test_apmcu dma alloc fail", PAGE_SIZE); */
+ return -ENOMEM;
+ }
+ /* testing */
+ preempt_disable();
+ /* met_tag_start(0, "TEST_EMI_APMCU"); */
+ for (i = 0; i < times; i++) {
+ memset(src_addr_v, 2*i, PAGE_SIZE);
+ /* met_tag_oneshot(0, "TEST_EMI_APMCU", PAGE_SIZE); */
+ }
+ /* met_tag_end(0, "TEST_EMI_APMCU"); */
+ preempt_enable();
+
+ /* dma_free */
+ if (src_addr_v != NULL)
+ dma_free_coherent(met_device.this_device,
+ PAGE_SIZE,
+ src_addr_v,
+ src_addr_p);
+ return n;
+}
+
+/*======================================================================*/
+/* KOBJ Declarations */
+/*======================================================================*/
+DECLARE_KOBJ_ATTR_INT(ondiemet_emi_polling_200us, ondiemet_emi_polling_200us)
+DECLARE_KOBJ_ATTR_INT(emi_tsct_enable, emi_tsct_enable)
+DECLARE_KOBJ_ATTR_INT(emi_mdct_enable, emi_mdct_enable)
+DECLARE_KOBJ_ATTR_INT(metemi_func_opt, metemi_func_opt)
+DECLARE_KOBJ_ATTR_INT(emi_regdump, met_emi_regdump)
+DECLARE_KOBJ_ATTR_INT(emi_wsct_tsct_id_selection1, emi_wsct_tsct_id_selection[0])
+DECLARE_KOBJ_ATTR_INT(emi_wsct_tsct_id_selection2, emi_wsct_tsct_id_selection[1])
+DECLARE_KOBJ_ATTR_INT(emi_wsct_tsct_id_selection3, emi_wsct_tsct_id_selection[2])
+DECLARE_KOBJ_ATTR_INT(emi_wsct_tsct_id_selection4, emi_wsct_tsct_id_selection[3])
+/* KOBJ: Dynamic MonitorCounter selection !!!EXPERIMENT!!! */
+DECLARE_KOBJ_ATTR_INT(msel_enable, msel_enable)
+DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group1, msel_group1, msel_group1 > 0 && msel_group1 <= BM_MASTER_ALL)
+DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group2, msel_group2, msel_group2 > 0 && msel_group2 <= BM_MASTER_ALL)
+DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group3, msel_group3, msel_group3 > 0 && msel_group3 <= BM_MASTER_ALL)
+DECLARE_KOBJ_ATTR_INT(mdmcu_sel_enable, mdmcu_sel_enable)
+DECLARE_KOBJ_ATTR_INT(rd_mdmcu_rsv_num, rd_mdmcu_rsv_num)
+
+
+/* KOBJ: rwtype */
+DECLARE_KOBJ_ATTR_INT_CHECK(rwtype, rwtype, rwtype >= 0 && rwtype <= BM_WRITE_ONLY)
+
+static unsigned int get_emi_clock_rate(unsigned int dram_data_rate_MHz)
+{
+ return dram_data_rate_MHz/DRAM_EMI_BASECLOCK_RATE/DRAM_DATARATE;
+}
+
+/* KOBJ: emi_clock_rate */
+static ssize_t emi_clock_rate_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ unsigned int dram_data_rate_MHz;
+
+ dram_data_rate_MHz = get_dram_data_rate();
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ get_emi_clock_rate(dram_data_rate_MHz));
+}
+
+DECLARE_KOBJ_ATTR_RO(emi_clock_rate)
+
+static ssize_t dram_data_rate_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ unsigned int dram_data_rate_MHz;
+
+ dram_data_rate_MHz = get_dram_data_rate();
+ return snprintf(buf, PAGE_SIZE, "%d\n", dram_data_rate_MHz);
+}
+
+DECLARE_KOBJ_ATTR_RO(dram_data_rate)
+
+/* KOBJ: ttype1_16_en */
+DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
+ ttype1_16_en,
+ KOBJ_ITEM_LIST(
+ {BM_TTYPE1_16_ENABLE, "ENABLE"},
+ {BM_TTYPE1_16_DISABLE, "DISABLE"}
+ )
+ )
+DECLARE_KOBJ_ATTR_STR_LIST(ttype1_16_en, ttype1_16_en, ttype1_16_en)
+
+/* KOBJ: ttype17_21_en */
+DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
+ ttype17_21_en,
+ KOBJ_ITEM_LIST(
+ {BM_TTYPE17_21_ENABLE, "ENABLE"},
+ {BM_TTYPE17_21_DISABLE, "DISABLE"}
+ )
+ )
+DECLARE_KOBJ_ATTR_STR_LIST(ttype17_21_en, ttype17_21_en, ttype17_21_en)
+
+/* KOBJ: bw_limiter_enable */
+DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
+ bw_limiter_enable,
+ KOBJ_ITEM_LIST(
+ {BM_BW_LIMITER_ENABLE, "ENABLE"},
+ {BM_BW_LIMITER_DISABLE, "DISABLE"}
+ )
+ )
+
+DECLARE_KOBJ_ATTR_STR_LIST(bw_limiter_enable, bw_limiter_enable, bw_limiter_enable)
+
+/* KOBJ: ttype_master */
+DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
+ ttype_master,
+ KOBJ_ITEM_LIST(
+ {BM_MASTER_M0, "M0"},
+ {BM_MASTER_M1, "M1"},
+ {BM_MASTER_M2, "M2"},
+ {BM_MASTER_M3, "M3"},
+ {BM_MASTER_M4, "M4"},
+ {BM_MASTER_M5, "M5"},
+ {BM_MASTER_M6, "M6"},
+ {BM_MASTER_M7, "M7"}
+ )
+ )
+
+
+/* KOBJ: ttypeX_nbeat, ttypeX_nbyte, ttypeX_burst */
+DECLARE_KOBJ_ATTR_INT_LIST_ITEM(
+ ttype_nbeat,
+ KOBJ_ITEM_LIST(
+ {BM_TRANS_TYPE_1BEAT, 1},
+ {BM_TRANS_TYPE_2BEAT, 2},
+ {BM_TRANS_TYPE_3BEAT, 3},
+ {BM_TRANS_TYPE_4BEAT, 4},
+ {BM_TRANS_TYPE_5BEAT, 5},
+ {BM_TRANS_TYPE_6BEAT, 6},
+ {BM_TRANS_TYPE_7BEAT, 7},
+ {BM_TRANS_TYPE_8BEAT, 8},
+ {BM_TRANS_TYPE_9BEAT, 9},
+ {BM_TRANS_TYPE_10BEAT, 10},
+ {BM_TRANS_TYPE_11BEAT, 11},
+ {BM_TRANS_TYPE_12BEAT, 12},
+ {BM_TRANS_TYPE_13BEAT, 13},
+ {BM_TRANS_TYPE_14BEAT, 14},
+ {BM_TRANS_TYPE_15BEAT, 15},
+ {BM_TRANS_TYPE_16BEAT, 16}
+ )
+ )
+DECLARE_KOBJ_ATTR_INT_LIST_ITEM(
+ ttype_nbyte,
+ KOBJ_ITEM_LIST(
+ {BM_TRANS_TYPE_1Byte, 1},
+ {BM_TRANS_TYPE_2Byte, 2},
+ {BM_TRANS_TYPE_4Byte, 4},
+ {BM_TRANS_TYPE_8Byte, 8},
+ {BM_TRANS_TYPE_16Byte, 16},
+ {BM_TRANS_TYPE_32Byte, 32}
+ )
+ )
+DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
+ ttype_burst,
+ KOBJ_ITEM_LIST(
+ {BM_TRANS_TYPE_BURST_INCR, "INCR"},
+ {BM_TRANS_TYPE_BURST_WRAP, "WRAP"}
+ )
+ )
+
+DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
+ ttype_rw,
+ KOBJ_ITEM_LIST(
+ {BM_TRANS_RW_DEFAULT, "DEFAULT"},
+ {BM_TRANS_RW_READONLY, "R"},
+ {BM_TRANS_RW_WRITEONLY, "W"},
+ {BM_TRANS_RW_RWBOTH, "BOTH"}
+ )
+ )
+
+/* KOBJ: test_apmcu */
+DECLARE_KOBJ_ATTR_SHOW_INT(test_apmcu, times)
+/* please refer to session: "EMI Test Operations" for store operation */
+DECLARE_KOBJ_ATTR(test_apmcu)
+
+DECLARE_KOBJ_ATTR_INT(dramc_pdir_enable, dramc_pdir_enable)
+
+/*enable high priority filter*/
+static int high_priority_filter;
+DECLARE_KOBJ_ATTR_HEX(high_priority_filter, high_priority_filter)
+
+
+/**/
+static int ttype_master_val[21];
+static int ttype_busid_val[21];
+static int ttype_nbeat_val[21];
+static int ttype_nbyte_val[21];
+static int ttype_burst_val[21];
+static int ttype_rw_val[21];
+
+#define DECLARE_KOBJ_SERIAL_FNODE(nr) \
+ DECLARE_KOBJ_ATTR_STR_LIST(ttype##nr##_master, ttype_master_val[nr-1], ttype_master) \
+ DECLARE_KOBJ_ATTR_HEX(ttype##nr##_busid, ttype_busid_val[nr-1]) \
+ DECLARE_KOBJ_ATTR_INT_LIST(ttype##nr##_nbeat, ttype_nbeat_val[nr-1], ttype_nbeat) \
+ DECLARE_KOBJ_ATTR_INT_LIST(ttype##nr##_nbyte, ttype_nbyte_val[nr-1], ttype_nbyte) \
+ DECLARE_KOBJ_ATTR_STR_LIST(ttype##nr##_burst, ttype_burst_val[nr-1], ttype_burst) \
+ DECLARE_KOBJ_ATTR_STR_LIST(ttype##nr##_rw, ttype_rw_val[nr-1], ttype_rw)
+
+DECLARE_KOBJ_SERIAL_FNODE(1)
+DECLARE_KOBJ_SERIAL_FNODE(2)
+DECLARE_KOBJ_SERIAL_FNODE(3)
+DECLARE_KOBJ_SERIAL_FNODE(4)
+DECLARE_KOBJ_SERIAL_FNODE(5)
+DECLARE_KOBJ_SERIAL_FNODE(6)
+DECLARE_KOBJ_SERIAL_FNODE(7)
+DECLARE_KOBJ_SERIAL_FNODE(8)
+DECLARE_KOBJ_SERIAL_FNODE(9)
+DECLARE_KOBJ_SERIAL_FNODE(10)
+DECLARE_KOBJ_SERIAL_FNODE(11)
+DECLARE_KOBJ_SERIAL_FNODE(12)
+DECLARE_KOBJ_SERIAL_FNODE(13)
+DECLARE_KOBJ_SERIAL_FNODE(14)
+DECLARE_KOBJ_SERIAL_FNODE(15)
+DECLARE_KOBJ_SERIAL_FNODE(16)
+DECLARE_KOBJ_SERIAL_FNODE(17)
+DECLARE_KOBJ_SERIAL_FNODE(18)
+DECLARE_KOBJ_SERIAL_FNODE(19)
+DECLARE_KOBJ_SERIAL_FNODE(20)
+DECLARE_KOBJ_SERIAL_FNODE(21)
+
+ /**/
+#define KOBJ_ATTR_ITEM_SERIAL_FNODE(nr) \
+ KOBJ_ATTR_ITEM(ttype##nr##_master) \
+ KOBJ_ATTR_ITEM(ttype##nr##_nbeat) \
+ KOBJ_ATTR_ITEM(ttype##nr##_nbyte) \
+ KOBJ_ATTR_ITEM(ttype##nr##_burst) \
+ KOBJ_ATTR_ITEM(ttype##nr##_busid) \
+ KOBJ_ATTR_ITEM(ttype##nr##_rw) \
+
+#define KOBJ_ATTR_LIST \
+ KOBJ_ATTR_ITEM(high_priority_filter) \
+ KOBJ_ATTR_ITEM(metemi_func_opt) \
+ KOBJ_ATTR_ITEM(emi_tsct_enable) \
+ KOBJ_ATTR_ITEM(emi_mdct_enable) \
+ KOBJ_ATTR_ITEM(ondiemet_emi_polling_200us) \
+ KOBJ_ATTR_ITEM(emi_regdump) \
+ KOBJ_ATTR_ITEM(emi_wsct_tsct_id_selection1) \
+ KOBJ_ATTR_ITEM(emi_wsct_tsct_id_selection2) \
+ KOBJ_ATTR_ITEM(emi_wsct_tsct_id_selection3) \
+ KOBJ_ATTR_ITEM(emi_wsct_tsct_id_selection4) \
+ KOBJ_ATTR_ITEM(msel_enable) \
+ KOBJ_ATTR_ITEM(msel_group1) \
+ KOBJ_ATTR_ITEM(msel_group2) \
+ KOBJ_ATTR_ITEM(msel_group3) \
+ KOBJ_ATTR_ITEM(emi_clock_rate) \
+ KOBJ_ATTR_ITEM(dram_data_rate) \
+ KOBJ_ATTR_ITEM(rwtype) \
+ KOBJ_ATTR_ITEM(ttype17_21_en) \
+ KOBJ_ATTR_ITEM(ttype1_16_en) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(1) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(2) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(3) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(4) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(5) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(6) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(7) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(8) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(9) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(10) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(11) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(12) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(13) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(14) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(15) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(16) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(17) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(18) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(19) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(20) \
+ KOBJ_ATTR_ITEM_SERIAL_FNODE(21) \
+ KOBJ_ATTR_ITEM(test_apmcu) \
+ KOBJ_ATTR_ITEM(bw_limiter_enable) \
+ KOBJ_ATTR_ITEM(dramc_pdir_enable) \
+ KOBJ_ATTR_ITEM(mdmcu_sel_enable) \
+ KOBJ_ATTR_ITEM(rd_mdmcu_rsv_num) \
+
+/*======================================================================*/
+/* EMI Operations */
+/*======================================================================*/
+static void emi_init(void)
+{
+ unsigned int bmrw0_val, bmrw1_val, i, enable;
+ unsigned int msel_group1_val, msel_group2_val, msel_group3_val;
+
+ /* get dram channel number */
+ dram_chann_num = MET_EMI_GetDramChannNum();
+
+ /* Init. EMI bus monitor */
+ MET_BM_SetReadWriteType(rwtype);
+
+ /* MSEL1: ALL */
+ MET_BM_SetMonitorCounter(1,
+ BM_MASTER_ALL,
+ BM_TRANS_TYPE_4BEAT |
+ BM_TRANS_TYPE_8Byte |
+ BM_TRANS_TYPE_BURST_WRAP);
+ if (msel_enable) {
+ msel_group1_val = msel_group1;
+ msel_group2_val = msel_group2;
+ msel_group3_val = msel_group3;
+ } else {
+ msel_group1_val = BM_Master_GP_1_Default;
+ msel_group2_val = BM_Master_GP_2_Default;
+ msel_group3_val = BM_Master_GP_3_Default;
+ }
+
+ /* MSEL2: msel_group1 */
+ MET_BM_SetMonitorCounter(2,
+ msel_group1_val & BM_MASTER_ALL,
+ BM_TRANS_TYPE_4BEAT |
+ BM_TRANS_TYPE_8Byte |
+ BM_TRANS_TYPE_BURST_WRAP);
+ /* MSEL3: msel_group2 */
+ MET_BM_SetMonitorCounter(3,
+ msel_group2_val & BM_MASTER_ALL,
+ BM_TRANS_TYPE_4BEAT |
+ BM_TRANS_TYPE_8Byte |
+ BM_TRANS_TYPE_BURST_WRAP);
+ /* MSEL4: msel_group3 */
+ MET_BM_SetMonitorCounter(4,
+ msel_group3_val & BM_MASTER_ALL,
+ BM_TRANS_TYPE_4BEAT |
+ BM_TRANS_TYPE_8Byte |
+ BM_TRANS_TYPE_BURST_WRAP);
+
+
+ if (ttype1_16_en == BM_TTYPE1_16_ENABLE) {
+ MET_BM_SetLatencyCounter(0);
+
+ for (i = 1; i <= 16; i++) {
+ MET_BM_SetMonitorCounter(i,
+ ttype_master_val[i - 1],
+ ttype_nbeat_val[i - 1] |
+ ttype_nbyte_val[i - 1] |
+ ttype_burst_val[i - 1]);
+ MET_BM_SetIDSelect(i, ttype_busid_val[i - 1], (ttype_busid_val[i - 1] >= 0xffff) ? 0 : 1);
+ }
+ } else {
+ MET_BM_SetLatencyCounter(1);
+ }
+
+ if (ttype17_21_en == BM_TTYPE17_21_ENABLE) {
+ for (i = 17; i <= 21; i++) {
+ MET_BM_SetMonitorCounter(i,
+ ttype_master_val[i - 1],
+ ttype_nbeat_val[i - 1] |
+ ttype_nbyte_val[i - 1] |
+ ttype_burst_val[i - 1]);
+ MET_BM_SetIDSelect(i, ttype_busid_val[i - 1], (ttype_busid_val[i - 1] >= 0xffff) ? 0 : 1);
+ }
+ }
+
+ bmrw0_val = (
+ (ttype_rw_val[0] << 0) | (ttype_rw_val[1] << 2) |
+ (ttype_rw_val[2] << 4) | (ttype_rw_val[3] << 6) |
+ (ttype_rw_val[4] << 8) | (ttype_rw_val[5] << 10) |
+ (ttype_rw_val[6] << 12) | (ttype_rw_val[7] << 14) |
+ (ttype_rw_val[8] << 16) | (ttype_rw_val[9] << 18) |
+ (ttype_rw_val[10] << 20) | (ttype_rw_val[11] << 22) |
+ (ttype_rw_val[12] << 24) | (ttype_rw_val[13] << 26) |
+ (ttype_rw_val[14] << 28) | (ttype_rw_val[15] << 30));
+
+ bmrw1_val = (
+ (ttype_rw_val[16] << 0) | (ttype_rw_val[17] << 2) |
+ (ttype_rw_val[18] << 4) | (ttype_rw_val[19] << 6) |
+ (ttype_rw_val[20] << 8));
+
+ MET_BM_SetTtypeCounterRW(bmrw0_val, bmrw1_val);
+
+ for (i = 0; i < 4; i++)
+ MET_BM_Set_WsctTsct_id_sel(i, emi_wsct_tsct_id_selection[i]);
+
+ for (i = 0; i < BM_COUNTER_MAX; i++) {
+ if ((high_priority_filter & (1<<i)) == 0)
+ enable = 0;
+ else
+ enable = 1;
+
+ MET_BM_SetUltraHighFilter(i+1, enable);
+ }
+
+ if (met_emi_regdump == 1)
+ emi_dump_reg();
+}
+
+static void emi_uninit(void)
+{
+}
+
+static inline void emi_start(void)
+{
+ MET_BM_Enable(1);
+}
+
+static inline void emi_stop(void)
+{
+ MET_BM_Enable(0);
+}
+
+static inline int do_emi(void)
+{
+ return met_emi.mode;
+}
+
+noinline void DRAM_DVFS(unsigned int dram_data_rate_MHz)
+{
+ MET_TRACE("%u\n", dram_data_rate_MHz);
+}
+
+static unsigned int emi_bw_limiter(unsigned int *__restrict__ array)
+{
+ int idx = 0;
+ unsigned int dram_data_rate_MHz;
+
+ dram_data_rate_MHz = get_dram_data_rate();
+
+ /* print dram data rate */
+ DRAM_DVFS(dram_data_rate_MHz);
+
+ /* get correct dram_clock_rate */
+ array[idx++] = dram_data_rate_MHz;
+
+ /* get correct ARB A->LAST */
+ array[idx++] = MET_EMI_GetARBA();
+ array[idx++] = MET_EMI_GetARBB();
+ array[idx++] = MET_EMI_GetARBC();
+ array[idx++] = MET_EMI_GetARBD();
+ array[idx++] = MET_EMI_GetARBE();
+ array[idx++] = MET_EMI_GetARBF();
+ array[idx++] = MET_EMI_GetARBG();
+ array[idx++] = MET_EMI_GetARBH();
+ /* EMI Total BW Thresholds */
+ array[idx++] = MET_EMI_GetBWCT0();
+ array[idx++] = MET_EMI_GetBWCT1();
+ array[idx++] = MET_EMI_GetBWCT2();
+ array[idx++] = MET_EMI_GetBWCT3();
+ array[idx++] = MET_EMI_GetBWCT4();
+ array[idx++] = MET_EMI_GetBWST0();
+ array[idx++] = MET_EMI_GetBWST1();
+ /* EMI C+G BW Thresholds */
+ array[idx++] = MET_EMI_GetBWCT0_2ND();
+ array[idx++] = MET_EMI_GetBWCT1_2ND();
+ array[idx++] = MET_EMI_GetBWST_2ND();
+
+ return idx;
+}
+
+
+static void _ms_dramc(unsigned int *__restrict__ dramc_pdir_value, int dram_chann_num)
+{
+ MET_DRAMC_GetDebugCounter(dramc_pdir_value, dram_chann_num);
+}
+
+static unsigned int emi_polling(unsigned int *__restrict__ emi_value, unsigned int *__restrict__ emi_tsct,
+ unsigned int *__restrict__ emi_ttype_value, unsigned int *__restrict__ dramc_pdir_value,
+ unsigned int *__restrict__ emi_mdct_value)
+{
+ int j = 4; /* skip 4 WSCTs */
+ int i = 0; /* ttype start at 0 */
+ int k = 0; /* tsct start at 0 */
+ int n;
+
+ MET_BM_Pause();
+
+ if (ttype1_16_en != BM_TTYPE1_16_ENABLE) { /*1~21 NOT for ttype*/
+
+ /* Get Word Count */
+
+ emi_value[0] = MET_BM_GetWordCount(1); /* All */
+ emi_value[1] = MET_BM_GetWordCount(2); /* Group 1 */
+ emi_value[2] = MET_BM_GetWordCount(3); /* Group 2 */
+ emi_value[3] = MET_BM_GetWordCount(4); /* Group 3 */
+
+
+ /* Get Latency */
+ emi_value[j++] = MET_BM_GetLatencyCycle(1);
+ emi_value[j++] = MET_BM_GetLatencyCycle(2);
+ emi_value[j++] = MET_BM_GetLatencyCycle(3);
+ emi_value[j++] = MET_BM_GetLatencyCycle(4);
+ emi_value[j++] = MET_BM_GetLatencyCycle(5);
+ emi_value[j++] = MET_BM_GetLatencyCycle(6);
+ emi_value[j++] = MET_BM_GetLatencyCycle(7);
+ emi_value[j++] = MET_BM_GetLatencyCycle(8);
+
+ /* Get Trans. */
+ emi_value[j++] = MET_BM_GetLatencyCycle(9);
+ emi_value[j++] = MET_BM_GetLatencyCycle(10);
+ emi_value[j++] = MET_BM_GetLatencyCycle(11);
+ emi_value[j++] = MET_BM_GetLatencyCycle(12);
+ emi_value[j++] = MET_BM_GetLatencyCycle(13);
+ emi_value[j++] = MET_BM_GetLatencyCycle(14);
+ emi_value[j++] = MET_BM_GetLatencyCycle(15);
+ emi_value[j++] = MET_BM_GetLatencyCycle(16);
+ } else {
+ for (n = 0; n < 20; n++)
+ emi_value[n] = 0;
+ j = 20;
+
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(1);
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(2);
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(3);
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(4);
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(5);
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(6);
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(7);
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(8);
+
+ /* Get Trans. */
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(9);
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(10);
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(11);
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(12);
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(13);
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(14);
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(15);
+ emi_ttype_value[i++] = MET_BM_GetLatencyCycle(16);
+ }
+
+ /* Get BACT/BSCT/BCNT */
+ emi_value[j++] = MET_BM_GetBandwidthWordCount();
+ emi_value[j++] = MET_BM_GetOverheadWordCount();
+ emi_value[j++] = MET_BM_GetBusCycCount();
+ /* Get PageHist/PageMiss/InterBank/Idle */
+ for (n = 0; n < dram_chann_num; n++) {
+#if 1
+ /* TBD */
+ emi_value[j++] = MET_DRAMC_GetPageHitCount(DRAMC_ALL, n);
+ emi_value[j++] = MET_DRAMC_GetPageMissCount(DRAMC_ALL, n);
+ emi_value[j++] = MET_DRAMC_GetInterbankCount(DRAMC_ALL, n);
+ emi_value[j++] = MET_DRAMC_GetIdleCount(n);
+ emi_value[j++] = ((MET_DRAMC_Misc_Status(n) >> 8) & 0x7);
+ emi_value[j++] = MET_DRAMC_RefPop(n);
+ emi_value[j++] = MET_DRAMC_Free26M(n);
+ emi_value[j++] = MET_DRAMC_RByte(n);
+ emi_value[j++] = MET_DRAMC_WByte(n);
+#else
+ emi_value[j++] = 0;
+ emi_value[j++] = 0;
+ emi_value[j++] = 0;
+ emi_value[j++] = 0;
+ emi_value[j++] = 0;
+ emi_value[j++] = 0;
+ emi_value[j++] = 0;
+ emi_value[j++] = 0;
+ emi_value[j++] = 0;
+#endif
+ }
+ /* TTYPE */
+ if (ttype17_21_en == BM_TTYPE17_21_ENABLE) { /*17~21 for ttype*/
+ emi_ttype_value[16] = MET_BM_GetLatencyCycle(17);
+ emi_ttype_value[17] = MET_BM_GetLatencyCycle(18);
+ emi_ttype_value[18] = MET_BM_GetLatencyCycle(19);
+ emi_ttype_value[19] = MET_BM_GetLatencyCycle(20);
+ emi_ttype_value[20] = MET_BM_GetLatencyCycle(21);
+ }
+
+ /* Get tsct */
+ if (emi_tsct_enable == 1) {
+ emi_tsct[k++] = MET_BM_GetTransCount(1);
+ emi_tsct[k++] = MET_BM_GetTransCount(2);
+ emi_tsct[k++] = MET_BM_GetTransCount(3);
+ }
+ /*get mdct rsv buffer*/
+ if (emi_mdct_enable == 1) {
+ emi_mdct_value[0] = (MET_BM_GetMDCT() >> 16) & 0x7;
+ emi_mdct_value[1] = (MET_BM_GetMDCT_2() & 0x7);
+ }
+
+ if (dramc_pdir_enable == 1)
+ _ms_dramc(dramc_pdir_value, dram_chann_num);
+
+ MET_BM_Continue();
+ MET_BM_Enable(0);
+ MET_BM_Enable(1);
+
+ return j;
+}
+
+/*======================================================================*/
+/* MET Device Operations */
+/*======================================================================*/
+static int emi_inited;
+
+static int met_emi_create(struct kobject *parent)
+{
+ int ret = 0;
+ int i;
+
+ for (i = 0; i < 21; i++) {
+ ttype_master_val[i] = BM_MASTER_M0;
+ ttype_nbeat_val[i] = BM_TRANS_TYPE_1BEAT;
+ ttype_nbyte_val[i] = BM_TRANS_TYPE_8Byte;
+ ttype_burst_val[i] = BM_TRANS_TYPE_BURST_INCR;
+ ttype_busid_val[i] = 0xffff;
+ ttype_rw_val[i] = BM_TRANS_RW_DEFAULT;
+ }
+
+ ret = MET_BM_Init();
+ if (ret != 0) {
+ pr_err("MET_BM_Init failed!!!\n");
+ ret = 0; /* will retry later */
+ } else {
+ emi_inited = 1;
+ }
+
+ kobj_emi = parent;
+
+#define KOBJ_ATTR_ITEM(attr_name) \
+ ret = sysfs_create_file(kobj_emi, &attr_name##_attr.attr); \
+ if (ret != 0) { \
+ pr_err("Failed to create " #attr_name " in sysfs\n"); \
+ return ret; \
+ }
+ KOBJ_ATTR_LIST
+#undef KOBJ_ATTR_ITEM
+
+ return ret;
+}
+
+static void met_emi_delete(void)
+{
+#define KOBJ_ATTR_ITEM(attr_name) \
+ sysfs_remove_file(kobj_emi, &attr_name##_attr.attr);
+ if (kobj_emi != NULL) {
+ KOBJ_ATTR_LIST
+ kobj_emi = NULL;
+ }
+#undef KOBJ_ATTR_ITEM
+
+ if (emi_inited)
+ MET_BM_DeInit();
+}
+
+static void met_emi_start(void)
+{
+ unsigned int bw_limiter[NIDX_BL];
+
+ if (!emi_inited) {
+ if (MET_BM_Init() != 0) {
+ met_emi.mode = 0;
+ pr_err("MET_BM_Init failed!!!\n");
+ return;
+ }
+ emi_inited = 1;
+ }
+
+ if (do_emi()) {
+ emi_init();
+ emi_stop();
+ emi_start();
+
+ /* Draw the first BW Limiter point */
+ if (bw_limiter_enable == BM_BW_LIMITER_ENABLE) {
+ emi_bw_limiter(bw_limiter);
+ ms_bw_limiter(NIDX_BL, bw_limiter);
+ /* init countdown value */
+ countdown = CNT_COUNTDOWN;
+ }
+ }
+}
+
+static void met_emi_stop(void)
+{
+ unsigned int bw_limiter[NIDX_BL];
+
+ if (!emi_inited)
+ return;
+
+ if (met_emi_regdump == 1)
+ emi_dump_reg();
+
+ if (do_emi()) {
+ /* Draw the last BW Limiter point */
+ if (bw_limiter_enable == BM_BW_LIMITER_ENABLE) {
+ /*
+ * Skip drawing when we just draw
+ * the point at last polling.
+ */
+ if (countdown < CNT_COUNTDOWN) {
+ emi_bw_limiter(bw_limiter);
+ ms_bw_limiter(NIDX_BL, bw_limiter);
+ }
+ }
+
+ emi_stop();
+ emi_uninit();
+ }
+}
+
+static void met_emi_polling(unsigned long long stamp, int cpu)
+{
+ unsigned int emi_value[NIDX];
+ unsigned int emi_tsct[3];
+ unsigned int emi_ttype_value[21];
+ unsigned int dramc_pdir_value[DRAMC_Debug_MAX_CNT*NCH];
+ unsigned int emi_mdct_value[2];
+
+ if (!do_emi())
+ return;
+
+ /* get emi & dramc counters */
+ emi_value[0] = 0; /* 0: pure linux MET , 0xa5: OnDieMET*/
+ emi_value[1] = 0; /* EBM pause duration (ns)*/
+ emi_polling(emi_value+2, emi_tsct, emi_ttype_value, dramc_pdir_value, emi_mdct_value);
+
+ /* get and output BW Limiter */
+ if (bw_limiter_enable == BM_BW_LIMITER_ENABLE) {
+ unsigned int bw_limiter[NIDX_BL];
+
+ if (countdown > 0) {
+ countdown--;
+ } else {
+ emi_bw_limiter(bw_limiter);
+ ms_bw_limiter(NIDX_BL, bw_limiter);
+ /* reload countdown value */
+ countdown = CNT_COUNTDOWN;
+ }
+ }
+
+ /* output emi */
+ ms_emi(NIDX_EMI-NTTYPE + (NCNT*dram_chann_num), emi_value);
+ /* output tsct*/
+
+
+
+ if (emi_tsct_enable == 1)
+ ms_emi_tsct(3, emi_tsct);
+
+ /* output mdct*/
+ if (emi_mdct_enable == 1)
+ ms_emi_mdct(2, emi_mdct_value);
+
+ /* output dramc*/
+ if (dramc_pdir_enable == 1)
+ ms_dramc(DRAMC_Debug_MAX_CNT*dram_chann_num, dramc_pdir_value);
+
+ /* output ms_ttype */
+ if ((ttype1_16_en == BM_TTYPE1_16_ENABLE) && (ttype17_21_en == BM_TTYPE17_21_ENABLE))
+ ms_ttype(21, emi_ttype_value);
+ else if (ttype17_21_en == BM_TTYPE17_21_ENABLE)
+ ms_ttype(5, (emi_ttype_value + 16));
+
+ /* adjust MDMCU buffer */
+ if (mdmcu_sel_enable == 1)
+ MET_BM_SetMDCT_MDMCU(rd_mdmcu_rsv_num);
+}
+
+static char help[] = " --emi monitor EMI banwidth\n";
+static int emi_print_help(char *buf, int len)
+{
+ return snprintf(buf, PAGE_SIZE, help);
+}
+
+
+#define TTYPE_NAME_STR_LEN 64
+static char ttype_name[21][TTYPE_NAME_STR_LEN];
+static int emi_print_header(char *buf, int len)
+{
+ int ret = 0;
+ int ret_m[21];
+ int i = 0;
+ unsigned int dram_data_rate_MHz;
+
+ /*ttype header info*/
+ for (i = 0; i < 21; i++) {
+
+ int k;
+
+ /*busid >= 0xffff not specific bus id , show all on specificmaster*/
+ if (ttype_busid_val[i] >= 0xffff) {
+
+ int j;
+
+ for (j = 0; j < ARRAY_SIZE(ttype_master_list_item); j++) {
+ if (ttype_master_val[i] == ttype_master_list_item[j].key) {
+ ret_m[i] = snprintf(ttype_name[i], TTYPE_NAME_STR_LEN, "ttyp%d_%s",
+ i+1, ttype_master_list_item[j].val);/*master*/
+ break;
+ }
+ }
+ if (j == ARRAY_SIZE(ttype_master_list_item))
+ ret_m[i] = snprintf(ttype_name[i], TTYPE_NAME_STR_LEN, "ttyp%d_%s",
+ i+1, "unknown");
+ } else {
+ ret_m[i] = snprintf(ttype_name[i], TTYPE_NAME_STR_LEN, "ttyp%d_%x",
+ i+1, ttype_busid_val[i]);/*busID*/
+ }
+
+ /*show beat type*/
+ for (k = 0; k < ARRAY_SIZE(ttype_nbeat_list_item); k++) {
+
+ if (ttype_nbeat_val[i] == ttype_nbeat_list_item[k].key)
+ ret_m[i] += snprintf(ttype_name[i]+ret_m[i], TTYPE_NAME_STR_LEN-ret_m[i], "_%d",
+ ttype_nbeat_list_item[k].val);/*beat*/
+ }
+
+ /*show byte type*/
+ for (k = 0; k < ARRAY_SIZE(ttype_nbyte_list_item); k++) {
+
+ if (ttype_nbyte_val[i] == ttype_nbyte_list_item[k].key)
+ ret_m[i] += snprintf(ttype_name[i]+ret_m[i], TTYPE_NAME_STR_LEN-ret_m[i], "x%d",
+ ttype_nbyte_list_item[k].val);/*byte*/
+ }
+
+ /*show burst type*/
+ for (k = 0; k < ARRAY_SIZE(ttype_burst_list_item); k++) {
+
+ if (ttype_burst_val[i] == ttype_burst_list_item[k].key)
+ ret_m[i] += snprintf(ttype_name[i]+ret_m[i], TTYPE_NAME_STR_LEN-ret_m[i], "_%s",
+ ttype_burst_list_item[k].val);/*burst*/
+ }
+
+ /*show rw type*/
+ for (k = 0; k < ARRAY_SIZE(ttype_rw_list_item); k++) {
+
+ if (ttype_rw_val[i] == ttype_rw_list_item[k].key)
+ ret_m[i] += snprintf(ttype_name[i]+ret_m[i], TTYPE_NAME_STR_LEN-ret_m[i], "_%s",
+ ttype_rw_list_item[k].val);/*rw*/
+ }
+ }
+
+ dram_chann_num = MET_EMI_GetDramChannNum();
+ /* met_dram_chann_num_header */
+ /* TBD: what is VID */
+ ret = snprintf(buf, PAGE_SIZE, "met-info [000] 0.0: met_dram_chann_num_header: %d,%d,%d,%d,%d\n",
+ dram_chann_num, DRAM_EMI_BASECLOCK_RATE, DRAM_IO_BUS_WIDTH, DRAM_DATARATE, 0);
+
+ /* metemi_func_opt for middleware */
+ ret += snprintf(buf+ret, PAGE_SIZE-ret, "met-info [000] 0.0: metemi_func_opt_header: %d\n",
+ metemi_func_opt);
+
+ dram_data_rate_MHz = get_dram_data_rate();
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "met-info [000] 0.0: met_dram_clockrate: %u\n",
+ dram_data_rate_MHz);
+
+ /*master port mapping*/
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "met-info [000] 0.0: met_emi_mport_map: %s,%s,%s,%s,%s,%s,%s,%s\n",
+ BM_Master_M0_name, BM_Master_M1_name, BM_Master_M2_name, BM_Master_M3_name,
+ BM_Master_M4_name, BM_Master_M5_name, BM_Master_M6_name, BM_Master_M7_name);
+
+ /* not to change by default master port sequency */
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "met-info [000] 0.0: met_emi_mgroup_map: %x,%x,%x,%x\n",
+ BM_Master_GP_AP, BM_Master_GP_MM, BM_Master_GP_GPU, BM_Master_GP_PERI);
+
+ /* 1 : by ondiemet, 0: by pure linux */
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "met-info [000] 0.0: emi_use_ondiemet: %u\n",
+ emi_use_ondiemet);
+
+ /* msel header */
+ if (msel_enable) {
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "met-info [000] 0.0: met_emi_msel: %x,%x,%x\n",
+ msel_group1 & BM_MASTER_ALL,
+ msel_group2 & BM_MASTER_ALL,
+ msel_group3 & BM_MASTER_ALL);
+ } else {
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "met-info [000] 0.0: met_emi_msel: %x,%x,%x\n",
+ BM_Master_GP_1_Default & BM_MASTER_ALL,
+ BM_Master_GP_2_Default & BM_MASTER_ALL,
+ BM_Master_GP_3_Default & BM_MASTER_ALL);
+ }
+
+ /* ms_emi */
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "# ms_emi: TS0,TS1,GP0_WSCT,GP1_WSCT,GP2_WSCT,GP3_WSCT,");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "M0_LATENCY,M1_LATENCY,M2_LATENCY,M3_LATENCY,M4_LATENCY,M5_LATENCY,M6_LATENCY,M7_LATENCY,");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "M0_TRANS,M1_TRANS,M2_TRANS,M3_TRANS,M4_TRANS,M5_TRANS,M6_TRANS,M7_TRANS,");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "BACT,BSCT,BCNT,");
+
+ for (i = 0; i < dram_chann_num; i++) {
+ if (i != 0)
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ ",");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "PageHit_%d,PageMiss_%d,InterBank_%d,Idle_%d,", i, i, i, i);
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "mr4_%d,refresh_pop_%d,freerun_26m_%d,", i, i, i);
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "read_bytes_%d,write_bytes_%d", i, i);
+ }
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "\n");
+
+
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "met-info [000] 0.0: met_emi_header: TS0,TS1,GP0_WSCT,GP1_WSCT,GP2_WSCT,GP3_WSCT,");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "M0_LATENCY,M1_LATENCY,M2_LATENCY,M3_LATENCY,M4_LATENCY,M5_LATENCY,M6_LATENCY,M7_LATENCY,");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "M0_TRANS,M1_TRANS,M2_TRANS,M3_TRANS,M4_TRANS,M5_TRANS,M6_TRANS,M7_TRANS,");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "BACT,BSCT,BCNT,");
+
+ for (i = 0; i < dram_chann_num; i++) {
+ if (i != 0)
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ ",");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "PageHit_%d,PageMiss_%d,InterBank_%d,Idle_%d,", i, i, i, i);
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "mr4_%d,refresh_pop_%d,freerun_26m_%d,", i, i, i);
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "read_bytes_%d,write_bytes_%d", i, i);
+ }
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "\n");
+
+
+ /*TSCT header*/
+ if (emi_tsct_enable == 1) {
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "met-info [000] 0.0: ms_ud_sys_header: ms_emi_tsct,");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "tsct1,tsct2,tsct3,x,x,x\n");
+ }
+
+
+ /*MDCT header*/
+ if (emi_mdct_enable == 1) {
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "met-info [000] 0.0: ms_ud_sys_header: ms_emi_mdct,");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "RD_ULTRA,RD_MDMCU,d,d\n");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "met-info [000] 0.0: ms_ud_sys_description: ms_emi_mdct:");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "CHART_TYPE=histogram_edge;STATISTICS_METHOD=histogram_edge;CHART_RESAMPLE_METHOD=del_dup\n");
+ }
+
+ /*ttype header*/
+ if ((ttype1_16_en == BM_TTYPE1_16_ENABLE) && (ttype17_21_en == BM_TTYPE17_21_ENABLE)) {
+ /*header = ttype1~21t*/
+ int i;
+
+ ret += snprintf(buf+ret, PAGE_SIZE-ret, "met-info [000] 0.0: ms_ud_sys_header: ms_ttype,");
+ for (i = 0; i < 21; i++)
+ ret += snprintf(buf+ret, PAGE_SIZE-ret, "%s,", ttype_name[i]);
+
+ 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");
+
+ } else if (ttype17_21_en == BM_TTYPE17_21_ENABLE) {
+ /*header = ttype17~21t*/
+ int i;
+
+ ret += snprintf(buf+ret, PAGE_SIZE-ret, "met-info [000] 0.0: ms_ud_sys_header: ms_ttype,");
+
+ for (i = 16; i < 21; i++)
+ ret += snprintf(buf+ret, PAGE_SIZE-ret, "%s,", ttype_name[i]);
+
+ ret += snprintf(buf+ret, PAGE_SIZE-ret, "x,x,x,x,x\n");
+ }
+
+ /* met_bw_limiter_header */
+ if (bw_limiter_enable == BM_BW_LIMITER_ENABLE) {
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "met-info [000] 0.0: met_bw_limiter_header: CLK,");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "ARBA,ARBB,ARBC,ARBD,ARBE,ARBF,ARBG,ARBH,BWCT0,BWCT1,BWCT2,BWCT3,BWCT4,BWST0,BWST1,BWCT0_2ND,BWCT1_2ND,BWST_2ND\n");
+ }
+ /* DRAM DVFS */
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "met-info [000] 0.0: ms_ud_sys_header: DRAM_DVFS,datarate(MHz),d\n");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "met-info [000] 0.0: ms_ud_sys_description: DRAM_DVFS:");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "CHART_TYPE=histogram_edge;STATISTICS_METHOD=histogram_edge;CHART_RESAMPLE_METHOD=del_dup\n");
+
+ /*PDIR met_dramc_header*/
+ if (dramc_pdir_enable == 1) {
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "met-info [000] 0.0: met_dramc_header: ");
+ for (i = 0; i < dram_chann_num; i++) {
+ if (i != 0)
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ ",");
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "rk0_pre_sb_%d,rk0_pre_pd_%d,rk0_act_sb_%d,rk0_act_pd_%d,", i, i, i, i);
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "rk1_pre_sb_%d,rk1_pre_pd_%d,rk1_act_sb_%d,rk1_act_pd_%d,", i, i, i, i);
+ ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ "rk2_pre_sb_%d,rk2_pre_pd_%d,rk2_act_sb_%d,rk2_act_pd_%d", i, i, i, i);
+ }
+ ret += snprintf(buf+ret, PAGE_SIZE-ret, "\n");
+ }
+ return ret;
+}
+
+struct metdevice met_emi = {
+ .name = "emi",
+ .owner = THIS_MODULE,
+ .type = MET_TYPE_BUS,
+ .create_subfs = met_emi_create,
+ .delete_subfs = met_emi_delete,
+ .cpu_related = 0,
+ .start = met_emi_start,
+ .stop = met_emi_stop,
+ .timed_polling = met_emi_polling,
+ .print_help = emi_print_help,
+ .print_header = emi_print_header,
+};