[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/devtools/met-driver/4.14/common/stat.c b/src/devtools/met-driver/4.14/common/stat.c
new file mode 100644
index 0000000..af7b738
--- /dev/null
+++ b/src/devtools/met-driver/4.14/common/stat.c
@@ -0,0 +1,198 @@
+/*
+ * 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/cpu.h>
+#include <linux/cpumask.h>
+/* #include <linux/fs.h> */
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+/* #include <linux/proc_fs.h> */
+#include <linux/sched.h>
+/* #include <linux/seq_file.h> */
+/* #include <linux/slab.h> */
+#include <linux/time.h>
+#include <linux/irqnr.h>
+#include <linux/vmalloc.h>
+/* #include <asm/cputime.h> */
+/* #include <asm-generic/cputime.h> */
+#include <linux/tick.h>
+#include <linux/jiffies.h>
+
+#include <asm/page.h>
+#include <linux/slab.h>
+
+#include "stat.h"
+#include "met_drv.h"
+#include "trace.h"
+
+#define MS_STAT_FMT "%5lu.%06lu"
+#define FMTLX7 ",%llx,%llx,%llx,%llx,%llx,%llx,%llx\n"
+#define FMTLX10 ",%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n"
+
+
+static DEFINE_PER_CPU(int, cpu_status);
+
+
+/* void ms_st(unsigned long long timestamp, unsigned char cnt, unsigned int *value) */
+noinline void ms_st(unsigned long long timestamp, unsigned char cnt, u64 *value)
+{
+ unsigned long nano_rem = do_div(timestamp, 1000000000);
+
+ switch (cnt) {
+ case 10:
+ MET_TRACE(MS_STAT_FMT FMTLX10, (unsigned long)(timestamp), (nano_rem/1000),
+ value[0], value[1], value[2], value[3], value[4],
+ value[5], value[6], value[7], value[8], value[9]);
+ break;
+ case 7:
+ MET_TRACE(MS_STAT_FMT FMTLX7, (unsigned long)(timestamp), (nano_rem/1000),
+ value[0], value[1], value[2], value[3], value[4],
+ value[5], value[6]);
+ break;
+ }
+}
+
+static void met_stat_start(void)
+{
+ int cpu = raw_smp_processor_id();
+
+ if (get_ctrl_flags() & 1)
+ met_stat.mode = 0;
+
+ per_cpu(cpu_status, cpu) = MET_CPU_ONLINE;
+}
+
+static void met_stat_stop(void)
+{
+}
+
+static int do_stat(void)
+{
+ return met_stat.mode;
+}
+
+u64 met_usecs_to_cputime64(u64 n)
+{
+#if (NSEC_PER_SEC % HZ) == 0
+ /* Common case, HZ = 100, 128, 200, 250, 256, 500, 512, 1000 etc. */
+ return div_u64(n, NSEC_PER_SEC / HZ);
+#elif (HZ % 512) == 0
+ /* overflow after 292 years if HZ = 1024 */
+ return div_u64(n * HZ / 512, NSEC_PER_SEC / 512);
+#else
+ /*
+ * Generic case - optimized for cases where HZ is a multiple of 3.
+ * overflow after 64.99 years, exact for HZ = 60, 72, 90, 120 etc.
+ */
+ return div_u64(n * 9, (9ull * NSEC_PER_SEC + HZ / 2) / HZ);
+#endif
+}
+
+static u64 get_idle_time(int cpu)
+{
+ u64 idle, idle_time = get_cpu_idle_time_us(cpu, NULL);
+
+ if (idle_time == -1ULL) {
+ /* !NO_HZ so we can rely on cpustat.idle */
+ idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE];
+ } else
+ idle = met_usecs_to_cputime64(idle_time);
+
+ return idle;
+}
+
+static u64 get_iowait_time(int cpu)
+{
+ u64 iowait, iowait_time = get_cpu_iowait_time_us(cpu, NULL);
+
+ if (iowait_time == -1ULL) {
+ /* !NO_HZ so we can rely on cpustat.iowait */
+ iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT];
+ } else
+ iowait = met_usecs_to_cputime64(iowait_time);
+
+ return iowait;
+}
+
+
+static unsigned int stat_os_polling(u64 *value, int i)
+{
+ int j = -1;
+
+ /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
+ value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_USER]); /* user */
+ value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_NICE]); /* nice */
+ value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM]); /* system */
+ value[++j] = jiffies_64_to_clock_t(get_idle_time(i)); /* idle */
+ value[++j] = jiffies_64_to_clock_t(get_iowait_time(i)); /* iowait */
+ value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_IRQ]); /* irq */
+ value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_SOFTIRQ]); /* softirq */
+ value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_STEAL]); /* steal */
+ value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_GUEST]); /* guest */
+ value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE]); /* guest_nice */
+
+ return j + 1;
+}
+
+static void met_stat_polling(unsigned long long stamp, int cpu)
+{
+ unsigned char count;
+ u64 value[10] = {0};
+
+ if (per_cpu(cpu_status, cpu) != MET_CPU_ONLINE)
+ return;
+
+ /* return; */
+ if (do_stat()) {
+ count = stat_os_polling(value, cpu);
+ if (count)
+ ms_st(stamp, count, value);
+ }
+}
+
+static const char header[] =
+ "met-info [000] 0.0: met_st_header: user,nice,system,idle,iowait,irq,softirq,steal,guest,guest_nice\n";
+
+static const char help[] = " --stat monitor stat\n";
+
+
+static int met_stat_print_help(char *buf, int len)
+{
+ return snprintf(buf, PAGE_SIZE, help);
+}
+
+static int met_stat_print_header(char *buf, int len)
+{
+ return snprintf(buf, PAGE_SIZE, header);
+}
+
+static void met_stat_cpu_state_notify(long cpu, unsigned long action)
+{
+ per_cpu(cpu_status, cpu) = action;
+}
+
+
+struct metdevice met_stat = {
+ .name = "stat",
+ .type = MET_TYPE_PMU,
+ .cpu_related = 1,
+ .start = met_stat_start,
+ .stop = met_stat_stop,
+ .polling_interval = 30,
+ .timed_polling = met_stat_polling,
+ .print_help = met_stat_print_help,
+ .print_header = met_stat_print_header,
+ .cpu_state_notify = met_stat_cpu_state_notify,
+};