linux/arch/arm/mach-davinci/include/mach/common.h
Mark A. Greer 3abd5acfff davinci: Add compare register support to timer code
The Timer64p timer has 8 compare registers that can
be used to generate interrupts when the timer value
matches the compare reg's value.  They do not disturb
the timer itself.  This can be useful when there is
only one timer available for both clock events and
clocksource.

When enabled, the clocksource remains a continuous
32-bit counter but the clock event will no longer
support periodic interrupts.  Instead only oneshot
timers will be supported and implemented by setting
the compare register to the current timer value plus
the period that the clock event subsystem is requesting.

Compare registers support is enabled automatically
when the following conditions are met:
1) The same timer is being used for clock events
   and clocksource.
2) The timer is the bottom half (32 bits) of the
   64-bit timer (hardware limitation).
3) The the compare register offset and irq are
   not zero.

Since the timer is always running, there is a hardware
race in timer32_config() between reading the current
timer value, and adding the period to the current
timer value and writing the compare register.
Testing on a da830 evm board with the timer clocked
at 24 MHz and the processor clocked at 300 MHz,
showed the number of counter ticks to do this ranged
from 20-53 (~1-2.2 usecs) but usually around 41 ticks.
This includes some artifacts from collecting the
information.  So, the minimum period should be
at least 5 usecs to be safe.

There is also an non-critical lower limit that
the period should be since there is no point in
setting an event that is much shorter than the
time it takes to set the event, and get & handle
the timer interrupt for that event.  There can
also be all sorts of delays from activities
occuring elsewhere in the system (including
hardware activitis like cache & TLB management).
These are virtually impossible to quantify so a
minimum period of 50 usecs was chosen.  That will
certianly be enough to avoid the actual hardware
race but hopefully not large enough to cause
unreasonably course-grained timers.

Signed-off-by: Mark A. Greer <mgreer@mvista.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
2009-05-28 15:17:48 -07:00

76 lines
2.0 KiB
C

/*
* Header for code common to all DaVinci machines.
*
* Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
*
* 2007 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef __ARCH_ARM_MACH_DAVINCI_COMMON_H
#define __ARCH_ARM_MACH_DAVINCI_COMMON_H
struct sys_timer;
extern struct sys_timer davinci_timer;
extern void davinci_irq_init(void);
extern void __iomem *davinci_intc_base;
extern int davinci_intc_type;
/* parameters describe VBUS sourcing for host mode */
extern void setup_usb(unsigned mA, unsigned potpgt_msec);
/* parameters describe VBUS sourcing for host mode */
extern void setup_usb(unsigned mA, unsigned potpgt_msec);
struct davinci_timer_instance {
void __iomem *base;
u32 bottom_irq;
u32 top_irq;
unsigned long cmp_off;
unsigned int cmp_irq;
};
struct davinci_timer_info {
struct davinci_timer_instance *timers;
unsigned int clockevent_id;
unsigned int clocksource_id;
};
/* SoC specific init support */
struct davinci_soc_info {
struct map_desc *io_desc;
unsigned long io_desc_num;
u32 cpu_id;
u32 jtag_id;
void __iomem *jtag_id_base;
struct davinci_id *ids;
unsigned long ids_num;
struct davinci_clk *cpu_clks;
void __iomem **psc_bases;
unsigned long psc_bases_num;
void __iomem *pinmux_base;
const struct mux_config *pinmux_pins;
unsigned long pinmux_pins_num;
void __iomem *intc_base;
int intc_type;
u8 *intc_irq_prios;
unsigned long intc_irq_num;
struct davinci_timer_info *timer_info;
void __iomem *wdt_base;
void __iomem *gpio_base;
unsigned gpio_num;
unsigned gpio_irq;
struct platform_device *serial_dev;
struct emac_platform_data *emac_pdata;
};
extern struct davinci_soc_info davinci_soc_info;
extern void davinci_common_init(struct davinci_soc_info *soc_info);
#endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */