Omap timestamp.stp

From OMAPpedia

Jump to: navigation, search
// omap_timestamp tapset

global trick

%{
#include <../include/linux/clk.h>
#include <../arch/arm/include/asm/io.h>
#include <../arch/arm/plat-omap/include/plat/dmtimer.h>
#include <../arch/arm/plat-omap/include/plat/clock.h>
%}

// Trick to force dependencies resolution when using plain C functions
function timestamp_init() {
	trick = 1;
}

%{
#define TIMER32K_FREQ	32768

struct omap_dm_timer *gptimer;

/*
 * timer_init_32k()
 *
 * Dummy init for 32k timer that simply returns the frequency of 32k timer timer.
 */
static inline int timer_init_32k(void)
{
	return TIMER32K_FREQ;
}

/*
 * timer_init_gptimer()
 *
 * Allocate and initialised a gptimer. On success return frequency of the
 * timer, otherwise return 0.
 */
unsigned long timer_init_gptimer(void)
{
	int prescaler = 0;
	unsigned long freq;
	struct clk *sys_clk;

	gptimer = omap_dm_timer_request();
	if (!gptimer)
		return 0;
	if (omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_SYS_CLK) < 0)
		return 0;

	omap_dm_timer_set_prescaler(gptimer, prescaler);

	sys_clk = clk_get(NULL, "sys_clkin_ck");
	if (!sys_clk)
		return 0;

	freq = (clk_get_rate(sys_clk) >> (prescaler + 1));
	clk_put(sys_clk);

	omap_dm_timer_set_load_start(gptimer, 1, 0);

	return freq;
}

/*
 * timer_free_gptimer()
 *
 * Free the gptimer that was allocated.
 */
void timer_free_gptimer(void)
{
	if (gptimer) {
		omap_dm_timer_stop(gptimer);
		omap_dm_timer_free(gptimer);
		gptimer = 0;
	}
}

/*
 * timer_get_ticks_gptimer()
 *
 * Returns current tick count of a gptimer.
 */
static inline u32 timer_get_ticks_gptimer(void)
{
	if (gptimer)
		return omap_dm_timer_read_counter(gptimer);
	else
		return 0;
}

/*
 * timer_ticksnsec()
 *
 * @ticks - tick count
 * @freq  - timer frequency
 *
 * Converts timer ticks into nanoseconds.
 */
static inline u64 timer_ticks2nsec(u32 ticks, unsigned long freq)
{
	return (u64)(((u64)ticks * (u64)(NSEC_PER_SEC/freq)));
}

/*
 * timer_get_ticks_32k()
 *
 * Returns current value of OMAP free running 32kHz timer counter. Unit is
 * ticks of 32kHz timer (i.e. 1/32768 sec).
 */
static inline u32 timer_get_ticks_32k(void)
{
#if defined(CONFIG_ARCH_OMAP3)
	return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10);
#elif defined(CONFIG_ARCH_OMAP4)
	return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10);
#elif defined(CONFIG_ARCH_OMAP5)
	return omap_readl(OMAP54XX_32KSYNCT_BASE + 0x30);
#else
	#error " OMAP RELEASE FAMILY IS NOT SPECIFIED, CONFIG_ARCH_OMAPX needed"
#endif
}
%}

function get_32k:long () %{ /* pure */ /* unprivileged */
  THIS->__retvalue = timer_get_ticks_32k();
%}

// gettimeofday() timestamping, which is internally based on 32kHz. Unit is in us:
//   - you can use it directly: do probe begin { ref = get_timeofday_ref() } then you can use get_timeofday(ref)
//   - another solution is to read 32kHz and gettimeofday() at beginning to compute the offset between the 2, then use 32kHz in kernel and gettimeofday() in userspace
%{
static inline u32 get_timeofday_ref(void)
{
	struct timeval tv;
	do_gettimeofday(&tv);
	return tv.tv_sec;
}
%}

function get_timeofday_ref:long () %{
	THIS->__retvalue = get_timeofday_ref();
%}

%{
static inline u32 get_timeofday(u32 ref)
{
	struct timeval tv;
	do_gettimeofday(&tv);
	return (tv.tv_sec - ref) * 1000000 + tv.tv_usec;
}
%}

function get_timeofday:long (ref:long) %{
  THIS->__retvalue = get_timeofday(THIS->ref);
%}

function elapsed_t_mod32k(time2, time1) {
  return ((time2-time1) % (1 << 32));
}

// this function is used to do "perf" tool timestamping. get_32k() + this function help computing time offset between the tools
function sys_sched_clock:long () %{ /* pure */ /* unprivileged */
  THIS->__retvalue = (uint64_t) sched_clock();
%}
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox