misc: tegra-profiler: use cntvct as time source
Igor Nabirushkin [Thu, 5 Jun 2014 05:52:29 +0000 (09:52 +0400)]
Tegra Profiler: use Virtual Count register (CNTVCT) as
time source.

Bug 1508327

Change-Id: If37e2dbe0a256ec28575d7c1b7d601d6bc1090f5
Signed-off-by: Igor Nabirushkin <inabirushkin@nvidia.com>
Reviewed-on: http://git-master/r/419305
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Daniel Horowitz <dhorowitz@nvidia.com>
Tested-by: Maxim Morin <mmorin@nvidia.com>

drivers/misc/tegra-profiler/hrt.c
drivers/misc/tegra-profiler/hrt.h
drivers/misc/tegra-profiler/main.c
drivers/misc/tegra-profiler/quadd_proc.c
drivers/misc/tegra-profiler/version.h
include/linux/tegra_profiler.h

index 9bbcb30..13b131b 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/err.h>
 #include <linux/nsproxy.h>
+#include <clocksource/arm_arch_timer.h>
 
 #include <asm/cputype.h>
 #include <asm/irq_regs.h>
+#include <asm/arch_timer.h>
 
 #include <linux/tegra_profiler.h>
 
@@ -91,7 +93,7 @@ static void init_hrtimer(struct quadd_cpu_context *cpu_ctx)
        cpu_ctx->hrtimer.function = hrtimer_handler;
 }
 
-u64 quadd_get_time(void)
+static inline u64 get_posix_clock_monotonic_time(void)
 {
        struct timespec ts;
 
@@ -99,6 +101,25 @@ u64 quadd_get_time(void)
        return timespec_to_ns(&ts);
 }
 
+static inline u64 get_arch_time(struct timecounter *tc)
+{
+       cycle_t value;
+       const struct cyclecounter *cc = tc->cc;
+
+       value = cc->read(cc);
+       return cyclecounter_cyc2ns(cc, value);
+}
+
+u64 quadd_get_time(void)
+{
+       struct timecounter *tc = hrt.tc;
+
+       if (tc)
+               return get_arch_time(tc);
+       else
+               return get_posix_clock_monotonic_time();
+}
+
 static void put_header(void)
 {
        int nr_events = 0, max_events = QUADD_MAX_COUNTERS;
@@ -616,6 +637,7 @@ struct quadd_hrt_ctx *quadd_hrt_init(struct quadd_ctx *ctx)
                hrt.ma_period = 0;
 
        atomic64_set(&hrt.counter_samples, 0);
+       hrt.tc = arch_timer_get_timecounter();
 
        hrt.cpu_ctx = alloc_percpu(struct quadd_cpu_context);
        if (!hrt.cpu_ctx)
index ef1f673..32b891d 100644 (file)
@@ -39,6 +39,8 @@ struct quadd_cpu_context {
        atomic_t nr_active;
 };
 
+struct timecounter;
+
 struct quadd_hrt_ctx {
        struct quadd_cpu_context * __percpu cpu_ctx;
        u64 sample_period;
@@ -54,6 +56,8 @@ struct quadd_hrt_ctx {
 
        unsigned long vm_size_prev;
        unsigned long rss_size_prev;
+
+       struct timecounter *tc;
 };
 
 #define QUADD_HRT_MIN_FREQ     100
index da0c15f..555cc25 100644 (file)
@@ -432,6 +432,9 @@ static void get_capabilities(struct quadd_comm_cap *cap)
        extra |= QUADD_COMM_CAP_EXTRA_UNWIND_MIXED;
        extra |= QUADD_COMM_CAP_EXTRA_UNW_ENTRY_TYPE;
 
+       if (ctx.hrt->tc)
+               extra |= QUADD_COMM_CAP_EXTRA_USE_ARCH_TIMER;
+
        cap->reserved[QUADD_COMM_CAP_IDX_EXTRA] = extra;
 }
 
index 8f656fa..12f5fc9 100644 (file)
@@ -96,6 +96,8 @@ static int show_capabilities(struct seq_file *f, void *offset)
                   YES_NO(extra & QUADD_COMM_CAP_EXTRA_UNWIND_MIXED));
        seq_printf(f, "information about unwind entry:        %s\n",
                   YES_NO(extra & QUADD_COMM_CAP_EXTRA_UNW_ENTRY_TYPE));
+       seq_printf(f, "use arch timer:                        %s\n",
+                  YES_NO(extra & QUADD_COMM_CAP_EXTRA_USE_ARCH_TIMER));
 
        seq_puts(f, "\n");
 
index 392ea70..d3913ff 100644 (file)
@@ -18,7 +18,7 @@
 #ifndef __QUADD_VERSION_H
 #define __QUADD_VERSION_H
 
-#define QUADD_MODULE_VERSION           "1.72"
+#define QUADD_MODULE_VERSION           "1.73"
 #define QUADD_MODULE_BRANCH            "Dev"
 
 #endif /* __QUADD_VERSION_H */
index bfab1ee..b0dcced 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <linux/ioctl.h>
 
-#define QUADD_SAMPLES_VERSION  26
+#define QUADD_SAMPLES_VERSION  27
 #define QUADD_IO_VERSION       12
 
 #define QUADD_IO_VERSION_DYNAMIC_RB            5
@@ -39,6 +39,7 @@
 #define QUADD_SAMPLE_VERSION_SPECIAL_MMAP      24
 #define QUADD_SAMPLE_VERSION_UNWIND_MIXED      25
 #define QUADD_SAMPLE_VERSION_UNW_ENTRY_TYPE    26
+#define QUADD_SAMPLE_VERSION_USE_ARCH_TIMER    27
 
 #define QUADD_MAX_COUNTERS     32
 #define QUADD_MAX_PROCESS      64
@@ -368,6 +369,7 @@ enum {
 #define QUADD_COMM_CAP_EXTRA_SPECIAL_ARCH_MMAP (1 << 5)
 #define QUADD_COMM_CAP_EXTRA_UNWIND_MIXED      (1 << 6)
 #define QUADD_COMM_CAP_EXTRA_UNW_ENTRY_TYPE    (1 << 7)
+#define QUADD_COMM_CAP_EXTRA_USE_ARCH_TIMER    (1 << 8)
 
 struct quadd_comm_cap {
        u32     pmu:1,