[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/devtools/met-driver/4.4/common/met_emi.c b/src/devtools/met-driver/4.4/common/met_emi.c
new file mode 100644
index 0000000..14879ff
--- /dev/null
+++ b/src/devtools/met-driver/4.4/common/met_emi.c
@@ -0,0 +1,849 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#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 "interface.h"
+
+#include "mtk_typedefs.h"
+#include "core_plf_init.h"
+/* #include "plf_trace.h" */
+#include "mtk_emi_bm.h"
+
+#ifdef CONFIG_MTK_TINYSYS_SSPM_SUPPORT
+#include "sspm/ondiemet_sspm.h"
+#endif
+
+/*======================================================================*/
+/* Global variable definitions */
+/*======================================================================*/
+int emi_TP_busfiltr_enable;
+static int msel_enable;
+static unsigned int msel_group1 = _GP_1_Default;
+static unsigned int msel_group2 = _GP_2_Default;
+static unsigned int msel_group3 = _GP_3_Default;
+
+/* Global variables */
+static struct kobject *kobj_emi;
+
+static int ttype1_16_en = BM_TTYPE1_16_DISABLE;
+static int ttype17_21_en = BM_TTYPE17_21_DISABLE;
+
+
+
+static int times;
+static ssize_t test_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 (kstrtoint(buf, 10, ×) != 0)
+ return -EINVAL;
+ if (times < 0)
+ return -EINVAL;
+
+ if (times > 5000)
+ return -EINVAL;
+
+
+ src_addr_v = dma_alloc_coherent(met_device.this_device,
+ PAGE_SIZE,
+ &src_addr_p,
+ GFP_KERNEL);
+ if (src_addr_v == NULL) {
+#ifdef CONFIG_MET_MODULE
+ met_tag_oneshot_real(0, "test dma alloc fail", PAGE_SIZE);
+#else
+ met_tag_oneshot(0, "test dma alloc fail", PAGE_SIZE);
+#endif
+ return -ENOMEM;
+ }
+
+ preempt_disable();
+#ifdef CONFIG_MET_MODULE
+ met_tag_start_real(0, "TEST_EMI");
+#else
+ met_tag_start(0, "TEST_EMI");
+#endif
+ for (i = 0; i < times; i++) {
+ memset(src_addr_v, 2*i, PAGE_SIZE);
+#ifdef CONFIG_MET_MODULE
+ met_tag_oneshot_real(0, "TEST_EMI", PAGE_SIZE);
+#else
+ met_tag_oneshot(0, "TEST_EMI", PAGE_SIZE);
+#endif
+ }
+#ifdef CONFIG_MET_MODULE
+ met_tag_end_real(0, "TEST_EMI");
+#else
+ met_tag_end(0, "TEST_EMI");
+#endif
+
+ my_preempt_enable();
+
+ 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(emi_TP_busfiltr_enable, emi_TP_busfiltr_enable);
+DECLARE_KOBJ_ATTR_INT(msel_enable, msel_enable);
+DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group1, msel_group1, msel_group1 > 0 && msel_group1 <= _ALL);
+DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group2, msel_group2, msel_group2 > 0 && msel_group2 <= _ALL);
+DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group3, msel_group3, msel_group3 > 0 && msel_group3 <= _ALL);
+
+
+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);
+
+
+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);
+
+DECLARE_KOBJ_ATTR_STR_LIST_ITEM(
+ ttype_master,
+ KOBJ_ITEM_LIST(
+ { _M0, "M0" },
+ { _M1, "M1" },
+ { _M2, "M2" },
+ { _M3, "M3" },
+ { _M4, "M4" },
+ { _M5, "M5" },
+ { _M6, "M6" },
+ { _M7, "M7" }
+ )
+ );
+
+
+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" }
+ )
+ );
+
+
+DECLARE_KOBJ_ATTR_SHOW_INT(test, times);
+
+DECLARE_KOBJ_ATTR(test);
+
+
+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_TTYPE_MASTER(nr) \
+ DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _master, ttype_master_val[nr - 1], ttype_master)
+
+#define DECLARE_KOBJ_TTYPE_NBEAT(nr) \
+ DECLARE_KOBJ_ATTR_INT_LIST(ttype ## nr ## _nbeat, ttype_nbeat_val[nr - 1], ttype_nbeat)
+
+#define DECLARE_KOBJ_TTYPE_NBYTE(nr) \
+ DECLARE_KOBJ_ATTR_INT_LIST(ttype ## nr ## _nbyte, ttype_nbyte_val[nr - 1], ttype_nbyte)
+
+#define DECLARE_KOBJ_TTYPE_BURST(nr) \
+ DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _burst, ttype_burst_val[nr - 1], ttype_burst)
+
+#define DECLARE_KOBJ_TTYPE_RW(nr) \
+ DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _rw, ttype_rw_val[nr - 1], ttype_rw)
+
+#define DECLARE_KOBJ_TTYPE_BUSID_VAL(nr) \
+ DECLARE_KOBJ_ATTR_HEX(ttype ## nr ## _busid, ttype_busid_val[nr - 1])
+
+DECLARE_KOBJ_TTYPE_MASTER(1);
+DECLARE_KOBJ_TTYPE_NBEAT(1);
+DECLARE_KOBJ_TTYPE_NBYTE(1);
+DECLARE_KOBJ_TTYPE_BURST(1);
+DECLARE_KOBJ_TTYPE_RW(1);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(1);
+
+DECLARE_KOBJ_TTYPE_MASTER(2);
+DECLARE_KOBJ_TTYPE_NBEAT(2);
+DECLARE_KOBJ_TTYPE_NBYTE(2);
+DECLARE_KOBJ_TTYPE_BURST(2);
+DECLARE_KOBJ_TTYPE_RW(2);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(2);
+
+DECLARE_KOBJ_TTYPE_MASTER(3);
+DECLARE_KOBJ_TTYPE_NBEAT(3);
+DECLARE_KOBJ_TTYPE_NBYTE(3);
+DECLARE_KOBJ_TTYPE_BURST(3);
+DECLARE_KOBJ_TTYPE_RW(3);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(3);
+
+DECLARE_KOBJ_TTYPE_MASTER(4);
+DECLARE_KOBJ_TTYPE_NBEAT(4);
+DECLARE_KOBJ_TTYPE_NBYTE(4);
+DECLARE_KOBJ_TTYPE_BURST(4);
+DECLARE_KOBJ_TTYPE_RW(4);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(4);
+
+DECLARE_KOBJ_TTYPE_MASTER(5);
+DECLARE_KOBJ_TTYPE_NBEAT(5);
+DECLARE_KOBJ_TTYPE_NBYTE(5);
+DECLARE_KOBJ_TTYPE_BURST(5);
+DECLARE_KOBJ_TTYPE_RW(5);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(5);
+
+DECLARE_KOBJ_TTYPE_MASTER(6);
+DECLARE_KOBJ_TTYPE_NBEAT(6);
+DECLARE_KOBJ_TTYPE_NBYTE(6);
+DECLARE_KOBJ_TTYPE_BURST(6);
+DECLARE_KOBJ_TTYPE_RW(6);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(6);
+
+DECLARE_KOBJ_TTYPE_MASTER(7);
+DECLARE_KOBJ_TTYPE_NBEAT(7);
+DECLARE_KOBJ_TTYPE_NBYTE(7);
+DECLARE_KOBJ_TTYPE_BURST(7);
+DECLARE_KOBJ_TTYPE_RW(7);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(7);
+
+DECLARE_KOBJ_TTYPE_MASTER(8);
+DECLARE_KOBJ_TTYPE_NBEAT(8);
+DECLARE_KOBJ_TTYPE_NBYTE(8);
+DECLARE_KOBJ_TTYPE_BURST(8);
+DECLARE_KOBJ_TTYPE_RW(8);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(8);
+
+DECLARE_KOBJ_TTYPE_MASTER(9);
+DECLARE_KOBJ_TTYPE_NBEAT(9);
+DECLARE_KOBJ_TTYPE_NBYTE(9);
+DECLARE_KOBJ_TTYPE_BURST(9);
+DECLARE_KOBJ_TTYPE_RW(9);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(9);
+
+DECLARE_KOBJ_TTYPE_MASTER(10);
+DECLARE_KOBJ_TTYPE_NBEAT(10);
+DECLARE_KOBJ_TTYPE_NBYTE(10);
+DECLARE_KOBJ_TTYPE_BURST(10);
+DECLARE_KOBJ_TTYPE_RW(10);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(10);
+
+DECLARE_KOBJ_TTYPE_MASTER(11);
+DECLARE_KOBJ_TTYPE_NBEAT(11);
+DECLARE_KOBJ_TTYPE_NBYTE(11);
+DECLARE_KOBJ_TTYPE_BURST(11);
+DECLARE_KOBJ_TTYPE_RW(11);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(11);
+
+DECLARE_KOBJ_TTYPE_MASTER(12);
+DECLARE_KOBJ_TTYPE_NBEAT(12);
+DECLARE_KOBJ_TTYPE_NBYTE(12);
+DECLARE_KOBJ_TTYPE_BURST(12);
+DECLARE_KOBJ_TTYPE_RW(12);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(12);
+
+DECLARE_KOBJ_TTYPE_MASTER(13);
+DECLARE_KOBJ_TTYPE_NBEAT(13);
+DECLARE_KOBJ_TTYPE_NBYTE(13);
+DECLARE_KOBJ_TTYPE_BURST(13);
+DECLARE_KOBJ_TTYPE_RW(13);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(13);
+
+DECLARE_KOBJ_TTYPE_MASTER(14);
+DECLARE_KOBJ_TTYPE_NBEAT(14);
+DECLARE_KOBJ_TTYPE_NBYTE(14);
+DECLARE_KOBJ_TTYPE_BURST(14);
+DECLARE_KOBJ_TTYPE_RW(14);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(14);
+
+DECLARE_KOBJ_TTYPE_MASTER(15);
+DECLARE_KOBJ_TTYPE_NBEAT(15);
+DECLARE_KOBJ_TTYPE_NBYTE(15);
+DECLARE_KOBJ_TTYPE_BURST(15);
+DECLARE_KOBJ_TTYPE_RW(15);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(15);
+
+DECLARE_KOBJ_TTYPE_MASTER(16);
+DECLARE_KOBJ_TTYPE_NBEAT(16);
+DECLARE_KOBJ_TTYPE_NBYTE(16);
+DECLARE_KOBJ_TTYPE_BURST(16);
+DECLARE_KOBJ_TTYPE_RW(16);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(16);
+
+DECLARE_KOBJ_TTYPE_MASTER(17);
+DECLARE_KOBJ_TTYPE_NBEAT(17);
+DECLARE_KOBJ_TTYPE_NBYTE(17);
+DECLARE_KOBJ_TTYPE_BURST(17);
+DECLARE_KOBJ_TTYPE_RW(17);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(17);
+
+DECLARE_KOBJ_TTYPE_MASTER(18);
+DECLARE_KOBJ_TTYPE_NBEAT(18);
+DECLARE_KOBJ_TTYPE_NBYTE(18);
+DECLARE_KOBJ_TTYPE_BURST(18);
+DECLARE_KOBJ_TTYPE_RW(18);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(18);
+
+DECLARE_KOBJ_TTYPE_MASTER(19);
+DECLARE_KOBJ_TTYPE_NBEAT(19);
+DECLARE_KOBJ_TTYPE_NBYTE(19);
+DECLARE_KOBJ_TTYPE_BURST(19);
+DECLARE_KOBJ_TTYPE_RW(19);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(19);
+
+DECLARE_KOBJ_TTYPE_MASTER(20);
+DECLARE_KOBJ_TTYPE_NBEAT(20);
+DECLARE_KOBJ_TTYPE_NBYTE(20);
+DECLARE_KOBJ_TTYPE_BURST(20);
+DECLARE_KOBJ_TTYPE_RW(20);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(20);
+
+DECLARE_KOBJ_TTYPE_MASTER(21);
+DECLARE_KOBJ_TTYPE_NBEAT(21);
+DECLARE_KOBJ_TTYPE_NBYTE(21);
+DECLARE_KOBJ_TTYPE_BURST(21);
+DECLARE_KOBJ_TTYPE_RW(21);
+DECLARE_KOBJ_TTYPE_BUSID_VAL(21);
+
+#define KOBJ_ATTR_ITEM_SERIAL_FNODE(nr) \
+ do { \
+ 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); \
+ } while (0)
+
+#define KOBJ_ATTR_LIST \
+ do { \
+ KOBJ_ATTR_ITEM(high_priority_filter); \
+ KOBJ_ATTR_ITEM(emi_TP_busfiltr_enable); \
+ KOBJ_ATTR_ITEM(msel_enable); \
+ KOBJ_ATTR_ITEM(msel_group1); \
+ KOBJ_ATTR_ITEM(msel_group2); \
+ KOBJ_ATTR_ITEM(msel_group3); \
+ 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); \
+ } while (0)
+
+/*======================================================================*/
+/* EMI Operations */
+/*======================================================================*/
+static void emi_init(void)
+{
+ unsigned int bmrw0_val = 0, bmrw1_val = 0, i, enable;
+ unsigned int msel_group_val[4];
+
+ MET_BM_SaveCfg();
+
+ if ((ttype1_16_en != BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable != 1)) {
+ if (msel_enable) {
+ msel_group_val[0] = _ALL;
+ msel_group_val[1] = msel_group1;
+ msel_group_val[2] = msel_group2;
+ msel_group_val[3] = msel_group3;
+ } else {
+ msel_group_val[0] = _ALL;
+ msel_group_val[1] = _GP_1_Default;
+ msel_group_val[2] = _GP_2_Default;
+ msel_group_val[3] = _GP_3_Default;
+ }
+
+ MET_BM_SetLatencyCounter(1);
+
+ for (i = 1; i <= 4; i++) {
+ MET_BM_SetMonitorCounter(i,
+ msel_group_val[i - 1] & _ALL,
+ BM_TRANS_TYPE_4BEAT |
+ BM_TRANS_TYPE_8Byte |
+ BM_TRANS_TYPE_BURST_WRAP);
+ MET_BM_SetbusID(i, 0);
+ MET_BM_SetbusID_En(i, 0);
+ }
+ for (i = 0; i < 4; i++)
+ MET_BM_Set_WsctTsct_id_sel(i, 0);
+
+ } else if ((ttype1_16_en != BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable == 1)) {
+ MET_BM_SetLatencyCounter(1);
+
+ for (i = 1; i <= 4; 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_SetbusID(i, ttype_busid_val[i - 1]);
+ MET_BM_SetbusID_En(i, 0);
+ }
+ for (i = 0; i < 4; i++)
+ MET_BM_Set_WsctTsct_id_sel(i, 1);
+
+ } else if ((ttype1_16_en == BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable != 1)) {
+ 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_SetbusID(i, ttype_busid_val[i - 1]);
+
+ MET_BM_SetbusID_En(i, (ttype_busid_val[i - 1] > 0xffff) ? 0 : 1);
+ }
+ for (i = 0; i < 4; i++)
+ MET_BM_Set_WsctTsct_id_sel(i, 0);
+ } else { /* (ttype1_16_en == BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable == 1) */
+
+ 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_SetbusID(i, ttype_busid_val[i - 1]);
+
+ MET_BM_SetbusID_En(i, (ttype_busid_val[i - 1] > 0xffff) ? 0 : 1);
+ }
+ for (i = 0; i < 4; i++)
+ MET_BM_Set_WsctTsct_id_sel(i, 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_SetbusID(i, ttype_busid_val[i - 1]);
+
+ MET_BM_SetbusID_En(i, (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 < BM_COUNTER_MAX; i++) {
+ if ((high_priority_filter & (1 << i)) == 0)
+ enable = 0;
+ else
+ enable = 1;
+
+ MET_BM_SetUltraHighFilter(i + 1, enable);
+ }
+
+}
+
+static inline int do_emi(void)
+{
+ return met_sspm_emi.mode;
+}
+
+/*======================================================================*/
+/* 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] = _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] = 0xfffff;
+ ttype_rw_val[i] = BM_TRANS_RW_DEFAULT;
+ }
+ ret = MET_BM_Init();
+ if (ret != 0) {
+ pr_debug("MET_BM_Init failed!!!\n");
+ ret = 0;
+ } else
+ emi_inited = 1;
+
+ kobj_emi = parent;
+
+#define KOBJ_ATTR_ITEM(attr_name) \
+do { \
+ ret = sysfs_create_file(kobj_emi, &attr_name##_attr.attr); \
+ if (ret != 0) { \
+ pr_debug("Failed to create " #attr_name " in sysfs\n"); \
+ return ret; \
+ } \
+} while (0)
+ 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_resume(void)
+{
+ if (!do_emi())
+ return;
+
+ emi_init();
+}
+
+
+#ifdef CONFIG_MTK_TINYSYS_SSPM_SUPPORT
+static const char help[] = " --emi monitor EMI banwidth\n";
+
+#define TTYPE_NAME_STR_LEN 64
+static char ttype_name[21][TTYPE_NAME_STR_LEN];
+
+static int emi_print_help(char *buf, int len)
+{
+ return snprintf(buf, PAGE_SIZE, help);
+}
+
+static int emi_print_header(char *buf, int len)
+{
+ int ret = 0;
+ int ret_m[21];
+ int i = 0;
+
+
+ for (i = 0; i < 21; i++) {
+ int k;
+
+ 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);
+ 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]);
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+ }
+ if ((ttype1_16_en != BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable != 1)) {
+ if (msel_enable) {
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "met-info [000] 0.0: met_emi_msel: %x,%x,%x\n",
+ msel_group1 & _ALL,
+ msel_group2 & _ALL,
+ msel_group3 & _ALL);
+ } else {
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "met-info [000] 0.0: met_emi_msel: %x,%x,%x\n",
+ _GP_1_Default & _ALL,
+ _GP_2_Default & _ALL,
+ _GP_3_Default & _ALL);
+ }
+ } else {
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "met-info [000] 0.0: met_emi_ttype_master: %x,%x,%x,%x\n",
+ ttype_master_val[0], ttype_master_val[1], ttype_master_val[2], ttype_master_val[3]);
+
+ if (emi_TP_busfiltr_enable == 1) {
+
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "met-info [000] 0.0: met_emi_ttype_busid: %x,%x,%x,%x\n",
+ ttype_busid_val[0], ttype_busid_val[1], ttype_busid_val[2], ttype_busid_val[3]);
+ }
+ }
+
+ ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_rw_cfg: ");
+ ret += snprintf(buf + ret, PAGE_SIZE - ret, "BOTH");
+
+ for (i = 0; i < 21; i++) {
+ if (ttype_rw_val[i] == BM_TRANS_RW_DEFAULT)
+ ret += snprintf(buf + ret, PAGE_SIZE - ret, ",DEFAULT");
+ else if (ttype_rw_val[i] == BM_TRANS_RW_READONLY)
+ ret += snprintf(buf + ret, PAGE_SIZE - ret, ",R");
+ else if (ttype_rw_val[i] == BM_TRANS_RW_WRITEONLY)
+ ret += snprintf(buf + ret, PAGE_SIZE - ret, ",W");
+ else
+ ret += snprintf(buf + ret, PAGE_SIZE - ret, ",BOTH");
+ }
+ ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
+
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "met-info [000] 0.0: met_emi_ultra_filter: %x\n", high_priority_filter);
+ if ((ttype1_16_en == BM_TTYPE1_16_ENABLE) && (ttype17_21_en == BM_TTYPE17_21_ENABLE)) {
+ 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) {
+ 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");
+ }
+
+ return ret;
+}
+
+static int ondiemet_emi_print_header(char *buf, int len)
+{
+ return emi_print_header(buf, len);
+}
+
+static void MET_BM_IPI_REGISTER_CB(void)
+{
+ int ret, i;
+ unsigned int rdata;
+ unsigned int ipi_buf[4];
+
+ for (i = 0; i < 4; i++)
+ ipi_buf[i] = 0;
+
+ if (sspm_buf_available == 1) {
+ ipi_buf[0] = MET_MAIN_ID | (MID_EMI << MID_BIT_SHIFT) | MET_ARGU | SET_REGISTER_CB;
+ ret = sspm_ipi_send_sync(IPI_ID_MET, IPI_OPT_WAIT, (void *)ipi_buf, 0, &rdata, 1);
+ }
+}
+
+static void MET_BM_IPI_configs(void)
+{
+ int ret, i;
+ unsigned int rdata;
+ unsigned int ipi_buf[4];
+
+ for (i = 0; i < 4; i++)
+ ipi_buf[i] = 0;
+
+ if (sspm_buf_available == 1) {
+ ipi_buf[0] = MET_MAIN_ID | (MID_EMI << MID_BIT_SHIFT) | MET_ARGU | SET_EBM_CONFIGS1;
+ ret = sspm_ipi_send_sync(IPI_ID_MET, IPI_OPT_WAIT, (void *)ipi_buf, 0, &rdata, 1);
+ }
+}
+
+static void ondiemet_emi_start(void)
+{
+ MET_BM_IPI_REGISTER_CB();
+ if (!emi_inited) {
+ if (MET_BM_Init() != 0) {
+ met_sspm_emi.mode = 0;
+ pr_notice("MET_BM_Init failed!!!\n");
+ PR_BOOTMSG("MET_BM_Init failed!!!\n");
+ return;
+ }
+ emi_inited = 1;
+ }
+ MET_BM_IPI_configs();
+
+ if (do_emi())
+ emi_init();
+
+ ondiemet_module[ONDIEMET_SSPM] |= ID_EMI;
+}
+
+static void emi_uninit(void)
+{
+ MET_BM_RestoreCfg();
+}
+
+static void ondiemet_emi_stop(void)
+{
+ if (!emi_inited)
+ return;
+
+ if (do_emi())
+ emi_uninit();
+}
+#endif
+
+struct metdevice met_sspm_emi = {
+ .name = "emi",
+ .owner = THIS_MODULE,
+ .type = MET_TYPE_BUS,
+ .create_subfs = met_emi_create,
+ .delete_subfs = met_emi_delete,
+ .resume = met_emi_resume,
+#ifdef CONFIG_MTK_TINYSYS_SSPM_SUPPORT
+ .ondiemet_start = ondiemet_emi_start,
+ .ondiemet_stop = ondiemet_emi_stop,
+ .ondiemet_print_help = emi_print_help,
+ .ondiemet_print_header = ondiemet_emi_print_header,
+#endif
+ .ondiemet_mode = 1,
+};
+EXPORT_SYMBOL(met_sspm_emi);