diff options
author | Abhimanyu Kapur <abhimany@codeaurora.org> | 2014-07-08 14:24:45 -0700 |
---|---|---|
committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 11:08:43 -0700 |
commit | 85b08d32e4bb7556f5e83a50841b69ed9eef9ba2 (patch) | |
tree | 02d3028f352ab9763f075872a90073c9b1aa5941 | |
parent | 6b75e9afc114cf300eaf7533830d54baa8ac7e38 (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/Kconfig | 7 | ||||
-rw-r--r-- | drivers/soc/qcom/Makefile | 2 | ||||
-rw-r--r-- | drivers/soc/qcom/boot_stats.c | 106 |
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; +} + |