Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0fb6cf68 authored by Channagoud Kadabi's avatar Channagoud Kadabi Committed by Gerrit - the friendly Code Review server
Browse files

drivers: soc: qcom: Add snapshot of boot stats driver



Snapshot of boot stats driver as of msm-4.4 commit <c605e110ab18604>
(Merge "usb: gadget: composite: Return bcdUSB 0x0310
for Superspeed and higher").

CRs-Fixed: 1058357
Change-Id: I832b8250de7881fae00a2878875c34fb014da3e8
Signed-off-by: default avatarChannagoud Kadabi <ckadabi@codeaurora.org>
parent c3d2132a
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
* MSM MPM sleep counter (mpm-v2)

The MPM provides a timetick that starts when the device is powered up and
is not reset by any of the boot loaders or the HLOS. The MPM timetick counter
driver provides an api to get this value.

The required nodes for the MPM timetick counter driver are:

- compatible: "qcom,mpm2-sleep-counter"
- reg: Specifies the physical address of the timetick count register.
- clock-frequency: the physical counter frequency.

Example:
	qcom,mpm2-sleep-counter@4a3000 {
		compatible = "qcom,mpm2-sleep-counter";
		reg = <0x4a3000 0x1000>;
		clock-frequency = <32768>;
	};
+8 −0
Original line number Diff line number Diff line
@@ -90,6 +90,14 @@ config QCOM_WCNSS_CTRL
	  Client driver for the WCNSS_CTRL SMD channel, used to download nv
	  firmware to a newly booted WCNSS chip.

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.

config MSM_GLADIATOR_HANG_DETECT
       tristate "MSM Gladiator Hang Detection Support"
       help
+1 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
obj-$(CONFIG_QCOM_SCM)  +=      scm.o scm-boot.o
obj-$(CONFIG_SOC_BUS) += socinfo.o
obj-$(CONFIG_MSM_BOOT_STATS) += boot_stats.o
obj-$(CONFIG_MSM_GLADIATOR_HANG_DETECT) += gladiator_hang_detect.o
obj-$(CONFIG_MSM_GLADIATOR_ERP_V2) += gladiator_erp_v2.o
obj-$(CONFIG_QCOM_WATCHDOG_V2) += watchdog_v2.o
+106 −0
Original line number Diff line number Diff line
/* 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;
}