Omap timestamp.stp

From OMAPpedia

(Difference between revisions)
Jump to: navigation, search
 
Line 1: Line 1:
<pre>
<pre>
 +
// omap_timestamp tapset
 +
 +
global trick
 +
%{
%{
 +
#include <../include/linux/clk.h>
#include <../arch/arm/include/asm/io.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;
 +
}
%{
%{
-
#if defined(OMAP_L23)
+
#define TIMER32K_FREQ 32768
-
    #include <../arch/arm/plat-omap/include/plat/omap34xx.h>
+
 
-
#elif defined(OMAP_L25)
+
struct omap_dm_timer *gptimer;
-
    #include <../arch/arm/plat-omap/include/mach/io.h>
+
 
-
#elif defined(OMAP_L24) || defined(OMAP_L27)
+
/*
-
    #include <../arch/arm/plat-omap/include/plat/io.h>
+
* 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
#else
-
    #error " OMAP RELEASE FAMILY IS NOT SPECIFIED => add -D OMAP_L23 for eg when compiling the script"
+
#error " OMAP RELEASE FAMILY IS NOT SPECIFIED, CONFIG_ARCH_OMAPX needed"
#endif
#endif
 +
}
%}
%}
function get_32k:long () %{ /* pure */ /* unprivileged */
function get_32k:long () %{ /* pure */ /* unprivileged */
 +
  THIS->__retvalue = timer_get_ticks_32k();
 +
%}
-
  #if defined(OMAP_L25) || defined(OMAP_L23)
+
// gettimeofday() timestamping, which is internally based on 32kHz. Unit is in us:
-
    cycles_t c = omap_readl(OMAP3430_32KSYNCT_BASE + 0x10);
+
//  - you can use it directly: do probe begin { ref = get_timeofday_ref() } then you can use get_timeofday(ref)
-
   #elif defined(OMAP_L24) || defined(OMAP_L27)
+
//   - 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
-
    cycles_t c = omap_readl(OMAP4430_32KSYNCT_BASE + 0x10);
+
%{
-
  #else
+
static inline u32 get_timeofday_ref(void)
-
    cycles_t c = 0;
+
{
-
  #endif
+
struct timeval tv;
 +
do_gettimeofday(&tv);
 +
return tv.tv_sec;
 +
}
 +
%}
-
  THIS->__retvalue = (uint64_t) c;
+
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) {
function elapsed_t_mod32k(time2, time1) {
Line 35: Line 160:
}
}
-
// this function is used to "perf" tool timestamping. get_32k() + this function help computing time offset between the tools
+
// 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 */
function sys_sched_clock:long () %{ /* pure */ /* unprivileged */
   THIS->__retvalue = (uint64_t) sched_clock();
   THIS->__retvalue = (uint64_t) sched_clock();
-
%}
+
%}</pre>
-
 
+
-
 
+
-
 
+
-
// likewise jiffies, monotonic_clock ...
+
-
</pre>
+
[[Category:Patches and Release]]
[[Category:Patches and Release]]

Latest revision as of 21:49, 5 April 2012

// 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