summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbhimanyu Kapur <abhimany@codeaurora.org>2014-07-08 14:24:45 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:08:43 -0700
commit85b08d32e4bb7556f5e83a50841b69ed9eef9ba2 (patch)
tree02d3028f352ab9763f075872a90073c9b1aa5941
parent6b75e9afc114cf300eaf7533830d54baa8ac7e38 (diff)
msm: boot_stats: Add snapshot of boot_stats driver
Add a snapshot of the msm boot_stats driver as of commit acdce027751d5a7488b283f0ce3111f873a5816d (Merge "defconfig: arm64: Enable ONESHOT_SYNC for msm8994") Change-Id: Iee7ec288fe44606b468dc533bb4221f8d018b3cb Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org> [abhimany: resolve trivial merge conflicts and add header file] Signed-off-by: Abhimanyu Kapur <abhimany@codeaurora.org>
-rw-r--r--drivers/soc/qcom/Kconfig7
-rw-r--r--drivers/soc/qcom/Makefile2
-rw-r--r--drivers/soc/qcom/boot_stats.c106
3 files changed, 115 insertions, 0 deletions
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 8e432ce97124..3b967ca2c4b3 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -346,6 +346,13 @@ config MSM_RUN_QUEUE_STATS
This information is exported to usespace via sysfs entries and userspace
algorithms uses info and decide when to turn on/off the cpu cores.
+config MSM_BOOT_STATS
+ bool "Use MSM boot stats reporting"
+ help
+ Use this to report msm boot stats such as bootloader throughput,
+ display init, total boot time.
+ This figures are reported in mpm sleep clock cycles and have a
+ resolution of 31 bits as 1 bit is used as an overflow check.
endif # ARCH_QCOM
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index d64c17fe1a81..2c8290adec44 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -55,3 +55,5 @@ obj-$(CONFIG_MSM_GLADIATOR_ERP) += gladiator_erp.o
obj-$(CONFIG_MSM_CORE_HANG_DETECT) += core_hang_detect.o
obj-$(CONFIG_MSM_GLADIATOR_HANG_DETECT) += gladiator_hang_detect.o
obj-$(CONFIG_MSM_RUN_QUEUE_STATS) += msm_rq_stats.o
+obj-$(CONFIG_MSM_BOOT_STATS) += boot_stats.o
+
diff --git a/drivers/soc/qcom/boot_stats.c b/drivers/soc/qcom/boot_stats.c
new file mode 100644
index 000000000000..2fc9cbf55d4b
--- /dev/null
+++ b/drivers/soc/qcom/boot_stats.c
@@ -0,0 +1,106 @@
+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/err.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/sched.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+struct boot_stats {
+ uint32_t bootloader_start;
+ uint32_t bootloader_end;
+ uint32_t bootloader_display;
+ uint32_t bootloader_load_kernel;
+};
+
+static void __iomem *mpm_counter_base;
+static uint32_t mpm_counter_freq;
+static struct boot_stats __iomem *boot_stats;
+
+static int mpm_parse_dt(void)
+{
+ struct device_node *np;
+ u32 freq;
+
+ np = of_find_compatible_node(NULL, NULL, "qcom,msm-imem-boot_stats");
+ if (!np) {
+ pr_err("can't find qcom,msm-imem node\n");
+ return -ENODEV;
+ }
+ boot_stats = of_iomap(np, 0);
+ if (!boot_stats) {
+ pr_err("boot_stats: Can't map imem\n");
+ return -ENODEV;
+ }
+
+ np = of_find_compatible_node(NULL, NULL, "qcom,mpm2-sleep-counter");
+ if (!np) {
+ pr_err("mpm_counter: can't find DT node\n");
+ return -ENODEV;
+ }
+
+ if (!of_property_read_u32(np, "clock-frequency", &freq))
+ mpm_counter_freq = freq;
+ else
+ return -ENODEV;
+
+ if (of_get_address(np, 0, NULL, NULL)) {
+ mpm_counter_base = of_iomap(np, 0);
+ if (!mpm_counter_base) {
+ pr_err("mpm_counter: cant map counter base\n");
+ return -ENODEV;
+ }
+ }
+
+ return 0;
+}
+
+static void print_boot_stats(void)
+{
+ pr_info("KPI: Bootloader start count = %u\n",
+ readl_relaxed(&boot_stats->bootloader_start));
+ pr_info("KPI: Bootloader end count = %u\n",
+ readl_relaxed(&boot_stats->bootloader_end));
+ pr_info("KPI: Bootloader display count = %u\n",
+ readl_relaxed(&boot_stats->bootloader_display));
+ pr_info("KPI: Bootloader load kernel count = %u\n",
+ readl_relaxed(&boot_stats->bootloader_load_kernel));
+ pr_info("KPI: Kernel MPM timestamp = %u\n",
+ readl_relaxed(mpm_counter_base));
+ pr_info("KPI: Kernel MPM Clock frequency = %u\n",
+ mpm_counter_freq);
+}
+
+int boot_stats_init(void)
+{
+ int ret;
+
+ ret = mpm_parse_dt();
+ if (ret < 0)
+ return -ENODEV;
+
+ print_boot_stats();
+
+ iounmap(boot_stats);
+ iounmap(mpm_counter_base);
+
+ return 0;
+}
+