driver: platform: tegra: Qb profiling module.
puneet saini [Wed, 22 Apr 2015 06:41:08 +0000 (11:41 +0530)]
This change preserve the memory area malloced by
QB and adds a debugfs entry to read from that area.

Bug 200079083

Change-Id: I0b27f407390048c54c1917ed7af61570f63f684c
Reviewed-on: http://git-master/r/728503
Cherry-picked from: f53ae1c758c5599424f1c344ad9df583039e57a3
Signed-off-by: puneet saini <psaini@nvidia.com>
Reviewed-on: http://git-master/r/749321
Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com>
Tested-by: Sumeet Gupta <sumeetg@nvidia.com>

drivers/platform/tegra/Kconfig
drivers/platform/tegra/common.c
drivers/platform/tegra/tegra_bootloader_debug.c

index 2781c55..a971e96 100644 (file)
@@ -1,5 +1,5 @@
 
-# Copyright (c) 2012-2014, NVIDIA CORPORATION.  All rights reserved.
+# Copyright (c) 2012-2015, NVIDIA CORPORATION.  All rights reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms and conditions of the GNU General Public License,
@@ -97,10 +97,12 @@ config TEGRA_BOARD_COMMON
          Enable Tegra common board support.
 
 config TEGRA_BOOTLOADER_DEBUG
-       tristate "Creates sys-fs interface dumping registers read by bootloader"
-       default n
+       tristate "Creates sys-fs debug interface for tegra bootloader"
+       default y
        help
-         When enabled, tegra_bootloader_verify_regs sys-fs is created.
+         Enable tegra bootloader debug interface that creates
+         tegra_bootloader_verify_regs and tegra_bootloader_prof
+         files in tegra_bootloader debugfs entry.
 
 config TEGRA_BPMP_SCLK_SKIP
        bool "Let bpmp firmware own the sclk skipper h/w"
index 12aaf9b..b6031bc 100644 (file)
@@ -194,6 +194,12 @@ EXPORT_SYMBOL(tegra_bl_debug_data_start);
 phys_addr_t tegra_bl_debug_data_size = 0;
 EXPORT_SYMBOL(tegra_bl_debug_data_size);
 
+phys_addr_t tegra_bl_prof_start;
+EXPORT_SYMBOL(tegra_bl_prof_start);
+
+phys_addr_t tegra_bl_prof_size;
+EXPORT_SYMBOL(tegra_bl_prof_size);
+
 #ifdef CONFIG_TEGRA_NVDUMPER
 unsigned long nvdumper_reserved;
 #endif
@@ -999,6 +1005,23 @@ static int __init tegra_lp0_vec_arg(char *options)
 }
 early_param("lp0_vec", tegra_lp0_vec_arg);
 
+static int __init tegra_bl_prof_arg(char *option)
+{
+       char *p = option;
+
+       tegra_bl_prof_size = memparse(p, &p);
+       if (*p == '@')
+               tegra_bl_prof_start = memparse(p+1, &p);
+
+       if (!tegra_bl_prof_size || !tegra_bl_prof_start) {
+               tegra_bl_prof_size = 0;
+               tegra_bl_prof_start = 0;
+       }
+
+       return 0;
+}
+early_param("bl_prof_dataptr", tegra_bl_prof_arg);
+
 static int __init tegra_bl_debug_data_arg(char *options)
 {
        char *p = options;
@@ -2020,6 +2043,17 @@ void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size,
        }
 
 out:
+       if (tegra_bl_prof_size &&
+               tegra_bl_prof_start) {
+               if (memblock_reserve(tegra_bl_prof_start, tegra_bl_prof_size)) {
+                       pr_err("Failed to reserve bl_prof %08llx@%08llx\n",
+                               (u64)tegra_bl_prof_size,
+                               (u64)tegra_bl_prof_start);
+                               tegra_bl_prof_start = 0;
+                               tegra_bl_prof_size = 0;
+               }
+       }
+
 #ifdef CONFIG_TEGRA_NVDUMPER
        if (nvdumper_reserved) {
                if (memblock_reserve(nvdumper_reserved, NVDUMPER_RESERVED_SIZE)) {
index abf8e98..b250d2c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/platform/tegra/tegra_bootloader_debug.c
  *
- * Copyright (C) 2014 NVIDIA Corporation. All rights reserved.
+ * Copyright (C) 2014-2015 NVIDIA Corporation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -27,6 +27,7 @@
 const char *module_name = "tegra_bootloader_debug";
 const char *dir_name = "tegra_bootloader";
 const char *gr_file = "tegra_bootloader_verify_regs";
+const char *prof_file = "tegra_bootloader_prof";
 
 struct gr_address_value {
        unsigned int gr_address;
@@ -35,11 +36,15 @@ struct gr_address_value {
 
 extern phys_addr_t tegra_bl_debug_data_start;
 extern phys_addr_t tegra_bl_debug_data_size;
+extern phys_addr_t tegra_bl_prof_start;
 
 static int dbg_golden_register_show(struct seq_file *s, void *unused);
 static int dbg_golden_register_open(struct inode *inode, struct file *file);
+static int dbg_prof_show(struct seq_file *s, void *unused);
+static int dbg_prof_open(struct inode *inode, struct file *file);
 static struct dentry *bl_debug_node;
 static struct dentry *bl_debug_verify_reg_node;
+static struct dentry *bl_debug_verify_prof_node;
 
 static const struct file_operations debug_gr_fops = {
        .open           = dbg_golden_register_open,
@@ -48,6 +53,13 @@ static const struct file_operations debug_gr_fops = {
        .release        = single_release,
 };
 
+static const struct file_operations debug_prof_fops = {
+       .open           = dbg_prof_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
 static int dbg_golden_register_show(struct seq_file *s, void *unused)
 {
        struct gr_address_value *gr_memory_dump;
@@ -69,23 +81,33 @@ static int dbg_golden_register_show(struct seq_file *s, void *unused)
        return 0;
 }
 
+static int dbg_prof_show(struct seq_file *s, void *unused)
+{
+       char *addr;
+       addr = (char *)
+               phys_to_virt(tegra_bl_prof_start);
+
+       if (!addr) {
+               printk(KERN_INFO "No Bootloader profiling data in kernel commandline");
+               return -EFAULT;
+       }
+
+       seq_printf(s, "%s\n", addr);
+       return 0;
+}
+
 static int dbg_golden_register_open(struct inode *inode, struct file *file)
 {
        return single_open(file, dbg_golden_register_show, &inode->i_private);
 }
 
+static int dbg_prof_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, dbg_prof_show, &inode->i_private);
+}
 
 static int __init tegra_bootloader_golden_register_debuginit(void)
 {
-       bl_debug_node = debugfs_create_dir(dir_name, NULL);
-
-       if (!bl_debug_node) {
-               printk(KERN_ERR "%s: failed to create debugfs entries: %ld\n",
-                       module_name, PTR_ERR(bl_debug_node));
-               goto out_err;
-       }
-
-       printk(KERN_INFO "%s: Created %s directory\n", module_name, dir_name);
 
        bl_debug_verify_reg_node = debugfs_create_file(gr_file, S_IRUGO,
                                bl_debug_node, NULL, &debug_gr_fops);
@@ -96,22 +118,64 @@ static int __init tegra_bootloader_golden_register_debuginit(void)
                goto out_err;
        }
 
-       printk("%s: Created sysfs interface %s in %s directory\n",
+       printk(KERN_INFO "%s: Created sysfs interface %s in %s directory\n",
                module_name, gr_file, dir_name);
 
        return 0;
 
 out_err:
-       if (bl_debug_node)
-               debugfs_remove_recursive(bl_debug_node);
+
+       return -ENODEV;
+}
+
+static int __init tegra_bootloader_prof_debuginit(void)
+{
+
+       bl_debug_verify_prof_node = debugfs_create_file(prof_file, S_IRUGO,
+                               bl_debug_node, NULL, &debug_prof_fops);
+
+       if (!bl_debug_verify_prof_node) {
+               printk(KERN_ERR "%s: failed to create debugfs entries: %ld\n",
+                       module_name, PTR_ERR(bl_debug_verify_prof_node));
+               goto out_err;
+       }
+
+       printk(KERN_INFO "%s: Created sysfs interface %s in %s directory\n",
+               module_name, prof_file, dir_name);
+
+       return 0;
+
+out_err:
 
        return -ENODEV;
 }
 
 static int __init tegra_bl_debuginit_module_init(void)
 {
-       tegra_bootloader_golden_register_debuginit();
+       int err1 = 0, err2 = 0;
+       bl_debug_node = debugfs_create_dir(dir_name, NULL);
+
+       if (!bl_debug_node) {
+               printk(KERN_ERR "%s: failed to create debugfs entries: %ld\n",
+                       module_name, PTR_ERR(bl_debug_node));
+               goto out_err;
+       }
+
+       printk(KERN_INFO "%s: Created %s directory\n", module_name, dir_name);
+
+       err1 = tegra_bootloader_golden_register_debuginit();
+       err2 = tegra_bootloader_prof_debuginit();
+
+       if ((err1 < 0) && (err2 < 0))
+               goto out_err;
+
        return 0;
+
+out_err:
+       if (bl_debug_node)
+               debugfs_remove_recursive(bl_debug_node);
+
+       return -ENODEV;
 }
 
 static void __exit tegra_bl_debuginit_module_exit(void)