Skip to content

Commit

Permalink
ARC: Timers/counters/delay management
Browse files Browse the repository at this point in the history
ARC700 includes 2 in-core 32bit timers TIMER0 and TIMER1.
Both have exactly same capabilies.

* programmable to count from TIMER<n>_CNT to TIMER<n>_LIMIT
* for count 0 and LIMIT ~1, provides a free-running counter by
    auto-wrapping when limit is reached.
* optionally interrupt when LIMIT is reached (oneshot event semantics)
* rearming the interrupt provides periodic semantics
* run at CPU clk

ARC Linux uses TIMER0 for clockevent (periodic/oneshot) and TIMER1 for
clocksource (free-running clock).

Newer cores provide RTSC insn which gives a 64bit cpu clk snapshot hence
is more apt for clocksource when available.

SMP poses a bit of challenge for global timekeeping clocksource /
sched_clock() backend:
 -TIMER1 based local clocks are out-of-sync hence can't be used
  (thus we default to jiffies based cs as well as sched_clock() one/both
  of which platform can override with it's specific hardware assist)
 -RTSC is only allowed in SMP if it's cross-core-sync (Kconfig glue
  ensures that) and thus usable for both requirements.

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
Vineet Gupta committed Feb 11, 2013
1 parent bf90e1e commit d8005e6
Show file tree
Hide file tree
Showing 7 changed files with 425 additions and 0 deletions.
11 changes: 11 additions & 0 deletions arch/arc/include/asm/arcregs.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@
#define AUX_ITRIGGER 0x40d
#define AUX_IPULSE 0x415

/* Timer related Aux registers */
#define ARC_REG_TIMER0_LIMIT 0x23 /* timer 0 limit */
#define ARC_REG_TIMER0_CTRL 0x22 /* timer 0 control */
#define ARC_REG_TIMER0_CNT 0x21 /* timer 0 count */
#define ARC_REG_TIMER1_LIMIT 0x102 /* timer 1 limit */
#define ARC_REG_TIMER1_CTRL 0x101 /* timer 1 control */
#define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */

#define TIMER_CTRL_IE (1 << 0) /* Interupt when Count reachs limit */
#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */

/*
* Floating Pt Registers
* Status regs are read-only (build-time) so need not be saved/restored
Expand Down
20 changes: 20 additions & 0 deletions arch/arc/include/asm/clk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#ifndef _ASM_ARC_CLK_H
#define _ASM_ARC_CLK_H

/* Although we can't really hide core_freq, the accessor is still better way */
extern unsigned long core_freq;

static inline unsigned long arc_get_core_freq(void)
{
return core_freq;
}

#endif
68 changes: 68 additions & 0 deletions arch/arc/include/asm/delay.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Delay routines using pre computed loops_per_jiffy value.
*
* vineetg: Feb 2012
* -Rewrote in "C" to avoid dealing with availability of H/w MPY
* -Also reduced the num of MPY operations from 3 to 2
*
* Amit Bhor: Codito Technologies 2004
*/

#ifndef __ASM_ARC_UDELAY_H
#define __ASM_ARC_UDELAY_H

#include <asm/param.h> /* HZ */

static inline void __delay(unsigned long loops)
{
__asm__ __volatile__(
"1: sub.f %0, %0, 1 \n"
" jpnz 1b \n"
: "+r"(loops)
:
: "cc");
}

extern void __bad_udelay(void);

/*
* Normal Math for computing loops in "N" usecs
* -we have precomputed @loops_per_jiffy
* -1 sec has HZ jiffies
* loops per "N" usecs = ((loops_per_jiffy * HZ / 1000000) * N)
*
* Approximate Division by multiplication:
* -Mathematically if we multiply and divide a number by same value the
* result remains unchanged: In this case, we use 2^32
* -> (loops_per_N_usec * 2^32 ) / 2^32
* -> (((loops_per_jiffy * HZ / 1000000) * N) * 2^32) / 2^32
* -> (loops_per_jiffy * HZ * N * 4295) / 2^32
*
* -Divide by 2^32 is very simply right shift by 32
* -We simply need to ensure that the multiply per above eqn happens in
* 64-bit precision (if CPU doesn't support it - gcc can emaulate it)
*/

static inline void __udelay(unsigned long usecs)
{
unsigned long loops;

/* (long long) cast ensures 64 bit MPY - real or emulated
* HZ * 4295 is pre-evaluated by gcc - hence only 2 mpy ops
*/
loops = ((long long)(usecs * 4295 * HZ) *
(long long)(loops_per_jiffy)) >> 32;

__delay(loops);
}

#define udelay(n) (__builtin_constant_p(n) ? ((n) > 20000 ? __bad_udelay() \
: __udelay(n)) : __udelay(n))

#endif /* __ASM_ARC_UDELAY_H */
2 changes: 2 additions & 0 deletions arch/arc/include/asm/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ extern void __init arc_init_IRQ(void);
extern void __init plat_init_IRQ(void);
extern int __init get_hw_config_num_irq(void);

void __cpuinit arc_local_timer_setup(unsigned int cpu);

#endif
18 changes: 18 additions & 0 deletions arch/arc/include/asm/timex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#ifndef _ASM_ARC_TIMEX_H
#define _ASM_ARC_TIMEX_H

#define CLOCK_TICK_RATE 80000000 /* slated to be removed */

#include <asm-generic/timex.h>

/* XXX: get_cycles() to be implemented with RTSC insn */

#endif /* _ASM_ARC_TIMEX_H */
11 changes: 11 additions & 0 deletions arch/arc/kernel/clk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#include <asm/clk.h>

unsigned long core_freq = CONFIG_ARC_PLAT_CLK;
Loading

0 comments on commit d8005e6

Please sign in to comment.