summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra_bb.c
diff options
context:
space:
mode:
authorVinayak Pane <vpane@nvidia.com>2013-03-14 19:19:25 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 13:04:34 -0700
commit5e32d984e7fc4fd5f108b1f6f678a758e044455b (patch)
tree353526e15031f4ce9467a6e0b01cd380a87f5e74 /arch/arm/mach-tegra/tegra_bb.c
parent31d880a906064e6f143b2ecde2482807648c2993 (diff)
arm: tegra14x: bb: debugfs for LP0BB event counter
Add support to read LP0 to LP0BB transitions via debugfs. Also read number of LP0 to Active transitions. This will be utilized by test application. Bug 1253997 Change-Id: I30d2467d33509189283b92173022d1829a20d0d4 Signed-off-by: Vinayak Pane <vpane@nvidia.com> Reviewed-on: http://git-master/r/209821 Reviewed-by: Neil Patel <neilp@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Steve Lin <stlin@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/tegra_bb.c')
-rw-r--r--arch/arm/mach-tegra/tegra_bb.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/tegra_bb.c b/arch/arm/mach-tegra/tegra_bb.c
index 0fc3dd84fd47..4fbc92852df6 100644
--- a/arch/arm/mach-tegra/tegra_bb.c
+++ b/arch/arm/mach-tegra/tegra_bb.c
@@ -46,6 +46,11 @@
#define TEGRA_BB_IPC_COLDBOOT (0x0001)
#define TEGRA_BB_IPC_READY (0x0005)
+#define APBDEV_PMC_EVENT_COUNTER_0 (0x44c)
+#define APBDEV_PMC_EVENT_COUNTER_0_EN_MASK (1<<20)
+#define APBDEV_PMC_EVENT_COUNTER_0_LP0BB (0<<16)
+#define APBDEV_PMC_EVENT_COUNTER_0_LP0ACTIVE (1<<16)
+
#define APBDEV_PMC_IPC_PMC_IPC_STS_0 (0x500)
#define APBDEV_PMC_IPC_PMC_IPC_STS_0_AP2BB_RESET_SHIFT (1)
#define APBDEV_PMC_IPC_PMC_IPC_STS_0_AP2BB_RESET_DEFAULT_MASK (1)
@@ -1022,5 +1027,110 @@ static void __exit tegra_bb_exit(void)
fs_initcall(tegra_bb_init);
module_exit(tegra_bb_exit);
+#ifdef CONFIG_DEBUG_FS
+static struct dentry *bb_debugfs_root;
+static enum pmc_event_sel {
+ PMC_EVENT_NONE,
+ PMC_EVENT_LP0BB,
+ PMC_EVENT_LP0ACTIVE,
+} pmc_event_sel;
+
+static int lp0bb_transitions_set(void *data, u64 val)
+{
+ void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
+ u32 reg;
+
+ if (!val) {
+ /* disable event counting and clear counter */
+ reg = 0;
+ writel(reg, pmc + APBDEV_PMC_EVENT_COUNTER_0);
+ pmc_event_sel = PMC_EVENT_NONE;
+ } else if (val == 1) {
+ reg = APBDEV_PMC_EVENT_COUNTER_0_EN_MASK |
+ APBDEV_PMC_EVENT_COUNTER_0_LP0BB;
+ /* lp0->lp0bb transitions */
+ writel(reg, pmc + APBDEV_PMC_EVENT_COUNTER_0);
+ pmc_event_sel = PMC_EVENT_LP0BB;
+ }
+ return 0;
+}
+
+static inline unsigned long read_pmc_event_counter(void)
+{
+ void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
+ u32 reg = readl(pmc + APBDEV_PMC_EVENT_COUNTER_0);
+ /* hw event counter is 16 bit */
+ reg = reg & 0xffff;
+ return reg;
+}
+
+static int lp0bb_transitions_get(void *data, u64 *val)
+{
+ if (pmc_event_sel == PMC_EVENT_LP0BB)
+ *val = (u32) read_pmc_event_counter();
+ else
+ *val = 0;
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(lp0bb_fops, lp0bb_transitions_get,
+ lp0bb_transitions_set, "%lld\n");
+
+static int lp0active_transitions_set(void *data, u64 val)
+{
+ void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
+ u32 reg;
+
+ if (!val) {
+ /* disable event counting and clear counter */
+ reg = 0;
+ writel(reg, pmc + APBDEV_PMC_EVENT_COUNTER_0);
+ pmc_event_sel = PMC_EVENT_NONE;
+ } else if (val == 1) {
+ reg = APBDEV_PMC_EVENT_COUNTER_0_EN_MASK |
+ APBDEV_PMC_EVENT_COUNTER_0_LP0ACTIVE;
+ /* lp0->active transitions */
+ writel(reg, pmc + APBDEV_PMC_EVENT_COUNTER_0);
+ pmc_event_sel = PMC_EVENT_LP0ACTIVE;
+ }
+ return 0;
+}
+static int lp0active_transitions_get(void *data, u64 *val)
+{
+ if (pmc_event_sel == PMC_EVENT_LP0ACTIVE)
+ *val = (u32) read_pmc_event_counter();
+ else
+ *val = 0;
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(lp0active_fops, lp0active_transitions_get,
+ lp0active_transitions_set, "%lld\n");
+
+static int __init tegra_bb_debug_init(void)
+{
+ struct dentry *d;
+
+ bb_debugfs_root = debugfs_create_dir("tegra_bb", NULL);
+ if (!bb_debugfs_root)
+ return -ENOMEM;
+
+ d = debugfs_create_file("lp0bb_transitions", S_IWUSR | S_IRUGO,
+ bb_debugfs_root, NULL, &lp0bb_fops);
+ if (!d)
+ goto err;
+
+ d = debugfs_create_file("lp0active_transitions", S_IWUSR | S_IRUGO,
+ bb_debugfs_root, NULL, &lp0active_fops);
+ if (!d)
+ goto err;
+
+ return 0;
+err:
+ debugfs_remove_recursive(bb_debugfs_root);
+ return -ENOMEM;
+}
+
+late_initcall(tegra_bb_debug_init);
+#endif
+
MODULE_DESCRIPTION("Tegra T148 BB Module");
MODULE_LICENSE("GPL");