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
(cherry picked from commit
2e5fe3f706a404a087e110a9289818dd6c855c15)
Reviewed-on: http://git-master/r/454458
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Tested-by: Maxim Morin <mmorin@nvidia.com>
Reviewed-by: Mitch Luban <mluban@nvidia.com>
#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>
cpu_ctx->hrtimer.function = hrtimer_handler;
}
-u64 quadd_get_time(void)
+static inline u64 get_posix_clock_monotonic_time(void)
{
struct timespec ts;
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;
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)
atomic_t nr_active;
};
+struct timecounter;
+
struct quadd_hrt_ctx {
struct quadd_cpu_context * __percpu cpu_ctx;
u64 sample_period;
unsigned long vm_size_prev;
unsigned long rss_size_prev;
+
+ struct timecounter *tc;
};
#define QUADD_HRT_MIN_FREQ 100
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;
}
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");
#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 */
#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
#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
#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,