Commit b54384e3 authored by Jean-Christophe PLAGNIOL-VILLARD's avatar Jean-Christophe PLAGNIOL-VILLARD Committed by Wolfgang Denk

arm: timer and interrupt init rework

actually the timer init use the interrupt_init as init callback
which make the interrupt and timer implementation difficult to follow

so now rename it as int timer_init(void) and use interrupt_init for interrupt

btw also remane the corresponding file to the functionnality implemented

as ixp arch implement two timer - one based on interrupt - so all the timer
related code is moved to timer.c
Signed-off-by: default avatarJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
parent 5b4bebe1
......@@ -540,7 +540,7 @@ static ulong div_timer = 1; /* Divisor to convert timer reading
* - the Integrator/AP timer issues an interrupt
* each time it reaches zero
*/
int interrupt_init (void)
int timer_init (void)
{
/* Load timer with initial value */
*(volatile ulong *)(CONFIG_SYS_TIMERBASE + 0) = TIMER_LOAD_VAL;
......
......@@ -163,7 +163,7 @@ static ulong timestamp; /* U-Boot ticks since startup */
/* starts up a counter
* - the Integrator/CP timer can be set up to issue an interrupt */
int interrupt_init (void)
int timer_init (void)
{
/* Load timer with initial value */
*(volatile ulong *)(CONFIG_SYS_TIMERBASE + 0) = TIMER_LOAD_VAL;
......
......@@ -61,7 +61,6 @@ static void at91cap9_slowclock_hw_init(void)
if (at91_sys_read(AT91_PMC_VER) == ARCH_ID_AT91CAP9_REVC) {
unsigned i, tmp = at91_sys_read(AT91_SCKCR);
if ((tmp & AT91CAP9_SCKCR_OSCSEL) == AT91CAP9_SCKCR_OSCSEL_RC) {
extern void timer_init(void);
timer_init();
tmp |= AT91CAP9_SCKCR_OSC32EN;
at91_sys_write(AT91_SCKCR, tmp);
......
......@@ -22,7 +22,6 @@
#ifndef __MISC_H
#define __MISC_H
extern void timer_init(void);
extern int eth_hw_init(void);
void dv_display_clk_infos(void);
......
......@@ -127,7 +127,7 @@ int board_init(void)
m501sk_gpio_init();
/* Do interrupt init here, because flash needs timers */
interrupt_init();
timer_init();
flash_init();
return 0;
......
......@@ -48,7 +48,7 @@ int dram_init(void)
/* Take the Ethernet controller out of reset and wait
* for the EEPROM load to complete. */
*((volatile unsigned short *) GPIO_DATA_OUTPUT_REG) |= 0x80;
udelay(10); /* doesn't work before interrupt_init call */
udelay(10); /* doesn't work before timer_init call */
*((volatile unsigned short *) GPIO_DATA_OUTPUT_REG) &= ~0x80;
udelay(500);
......
......@@ -43,7 +43,7 @@ int dram_init(void)
/* Take the Ethernet controller out of reset and wait
* for the EEPROM load to complete. */
*((volatile unsigned short *) GPIO_DATA_OUTPUT_REG) |= 0x80;
udelay(10); /* doesn't work before interrupt_init call */
udelay(10); /* doesn't work before timer_init call */
*((volatile unsigned short *) GPIO_DATA_OUTPUT_REG) &= ~0x80;
udelay(500);
......
......@@ -25,7 +25,8 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).a
COBJS = interrupts.o generic.o
COBJS += generic.o
COBJS += timer.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
......
......@@ -89,9 +89,8 @@ static inline unsigned long long us_to_tick(unsigned long long us)
}
#endif
/* nothing really to do with interrupts, just starts up a counter. */
/* The 32768Hz 32-bit timer overruns in 131072 seconds */
int interrupt_init (void)
int timer_init (void)
{
int i;
......
......@@ -25,9 +25,10 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).a
COBJS = interrupts.o
SOBJS = start.o
COBJS = timer.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
......
......@@ -42,8 +42,7 @@
static ulong timestamp;
static ulong lastinc;
/* nothing really to do with interrupts, just starts up a counter. */
int interrupt_init (void)
int timer_init (void)
{
int32_t val;
......
......@@ -28,8 +28,8 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).a
COBJS-y = interrupts.o
COBJS-$(CONFIG_S3C6400) += cpu_init.o speed.o
COBJS-y += timer.o
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
......
......@@ -66,7 +66,7 @@ static unsigned long lastdec;
/* Monotonic incrementing timer */
static unsigned long long timestamp;
int interrupt_init(void)
int timer_init(void)
{
s3c64xx_timers *const timers = s3c64xx_get_base_timers();
......
......@@ -110,9 +110,34 @@ static void timer_isr( void *data) {
static ulong timestamp;
static ulong lastdec;
#if defined(CONFIG_USE_IRQ) && defined(CONFIG_S3C4510B)
int interrupt_init (void)
{
int i;
/* install default interrupt handlers */
for ( i = 0; i < N_IRQS; i++) {
IRQ_HANDLER[i].m_data = (void *)i;
IRQ_HANDLER[i].m_func = default_isr;
}
/* configure interrupts for IRQ mode */
PUT_REG( REG_INTMODE, 0x0);
/* clear any pending interrupts */
PUT_REG( REG_INTPEND, 0x1FFFFF);
lastdec = 0;
/* install interrupt handler for timer */
IRQ_HANDLER[INT_TIMER0].m_data = (void *)&timestamp;
IRQ_HANDLER[INT_TIMER0].m_func = timer_isr;
return 0;
}
#endif
int timer_init (void)
{
#if defined(CONFIG_NETARM)
/* disable all interrupts */
IRQEN = 0;
......@@ -137,25 +162,6 @@ int interrupt_init (void)
/* set timer 1 counter */
lastdec = IO_TC1D = TIMER_LOAD_VAL;
#elif defined(CONFIG_S3C4510B)
int i;
/* install default interrupt handlers */
for ( i = 0; i < N_IRQS; i++) {
IRQ_HANDLER[i].m_data = (void *)i;
IRQ_HANDLER[i].m_func = default_isr;
}
/* configure interrupts for IRQ mode */
PUT_REG( REG_INTMODE, 0x0);
/* clear any pending interrupts */
PUT_REG( REG_INTPEND, 0x1FFFFF);
lastdec = 0;
/* install interrupt handler for timer */
IRQ_HANDLER[INT_TIMER0].m_data = (void *)&timestamp;
IRQ_HANDLER[INT_TIMER0].m_func = timer_isr;
/* configure free running timer 0 */
PUT_REG( REG_TMOD, 0x0);
/* Stop timer 0 */
......@@ -187,7 +193,7 @@ int interrupt_init (void)
PUT32(T0TCR, 1); /* enable timer0 */
#else
#error No interrupt_init() defined for this CPU type
#error No timer_init() defined for this CPU type
#endif
timestamp = 0;
......
......@@ -31,10 +31,10 @@ COBJS += bcm5221.o
COBJS += dm9161.o
COBJS += ether.o
COBJS += i2c.o
COBJS += interrupts.o
COBJS += lxt972.o
COBJS += reset.o
COBJS += spi.o
COBJS += timer.o
COBJS += usb.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
......
......@@ -45,7 +45,7 @@ AT91PS_TC tmr;
static ulong timestamp;
static ulong lastinc;
int interrupt_init (void)
int timer_init (void)
{
tmr = AT91C_BASE_TC0;
......
......@@ -25,7 +25,9 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).a
COBJS = generic.o interrupts.o speed.o
COBJS += generic.o
COBJS += speed.o
COBJS += timer.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
......
......@@ -35,7 +35,7 @@
#include <arm920t.h>
#include <asm/arch/imx-regs.h>
int interrupt_init (void)
int timer_init (void)
{
int i;
/* setup GP Timer 1 */
......
......@@ -25,9 +25,10 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).a
COBJS = interrupts.o
SOBJS = lowlevel_init.o
COBJS = timer.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
......
......@@ -29,13 +29,13 @@
#define ks8695_read(a) *((volatile ulong *) (KS8695_IO_BASE + (a)))
#define ks8695_write(a,v) *((volatile ulong *) (KS8695_IO_BASE + (a))) = (v)
int timer_inited;
ulong timer_ticks;
int interrupt_init (void)
int timer_init (void)
{
/* nothing happens here - we don't setup any IRQs */
return (0);
reset_timer();
return 0;
}
/*
......@@ -53,7 +53,6 @@ void reset_timer_masked(void)
ks8695_write(KS8695_TIMER1_PCOUNT, TIMER_PULSE);
ks8695_write(KS8695_TIMER_CTRL, 0x2);
timer_ticks = 0;
timer_inited++;
}
void reset_timer(void)
......@@ -87,9 +86,6 @@ void udelay(ulong usec)
ulong start = get_timer_masked();
ulong end;
if (!timer_inited)
reset_timer();
/* Only 1ms resolution :-( */
end = usec / 1000;
while (get_timer(start) < end)
......
......@@ -25,7 +25,10 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).a
COBJS = interrupts.o speed.o usb.o usb_ohci.o
COBJS += speed.o
COBJS += timer.o
COBJS += usb.o
COBJS += usb_ohci.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
......
......@@ -52,7 +52,7 @@ static inline ulong READ_TIMER(void)
static ulong timestamp;
static ulong lastdec;
int interrupt_init (void)
int timer_init (void)
{
S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
......
......@@ -26,7 +26,10 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START = start.o
COBJS = interrupts.o cpu.o omap925.o
COBJS += cpu.o
COBJS += omap925.o
COBJS += timer.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
......
......@@ -47,7 +47,7 @@ static uint32_t timestamp;
static uint32_t lastdec;
/* nothing really to do with interrupts, just starts up a counter. */
int interrupt_init (void)
int timer_init (void)
{
/* Start the decrementer ticking down from 0xffffffff */
__raw_writel(TIMER_LOAD_VAL, CONFIG_SYS_TIMERBASE + LOAD_TIM);
......
......@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START = start.o
COBJS = interrupts.o cpu.o
COBJS = cpu.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
......
/*
* (C) Copyright 2003
* Texas Instruments <www.ti.com>
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Alex Zuepke <azu@sysgo.de>
*
* (C) Copyright 2002-2004
* Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
*
* (C) Copyright 2004
* Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <arm926ejs.h>
#ifdef CONFIG_INTEGRATOR
/* Timer functionality supplied by Integrator board (AP or CP) */
#else
/* nothing really to do with interrupts, just starts up a counter. */
int interrupt_init (void)
{
extern void timer_init(void);
timer_init();
return 0;
}
#endif /* CONFIG_INTEGRATOR */
......@@ -32,7 +32,7 @@ COBJS += clock.o
COBJS += mem.o
COBJS += syslib.o
COBJS += sys_info.o
COBJS += interrupts.o
COBJS += timer.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
......
......@@ -50,7 +50,7 @@ static gptimer_t *timer_base = (gptimer_t *)CONFIG_SYS_TIMERBASE;
#define TIMER_CLOCK (V_SCLK / (2 << CONFIG_SYS_PTV))
#define TIMER_LOAD_VAL 0xffffffff
int interrupt_init(void)
int timer_init(void)
{
/* start the counter ticking up, reload value on overflow */
writel(TIMER_LOAD_VAL, &timer_base->tldr);
......
......@@ -26,12 +26,10 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START = start.o
COBJS-y += cpu.o
ifndef CONFIG_USE_IRQ
COBJS-$(CONFIG_USE_IRQ) += interrupts.o
COBJS-y += timer.o
else
COBJS-y += interrupts.o
endif
SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
......
......@@ -33,14 +33,6 @@
#include <asm/arch/ixp425.h>
#include <asm/proc-armv/ptrace.h>
/*
* When interrupts are enabled, use timer 2 for time/delay generation...
*/
#define FREQ 66666666
#define CLOCK_TICK_RATE (((FREQ / CONFIG_SYS_HZ & ~IXP425_OST_RELOAD_MASK) + 1) * CONFIG_SYS_HZ)
#define LATCH ((CLOCK_TICK_RATE + CONFIG_SYS_HZ/2) / CONFIG_SYS_HZ) /* For divider */
struct _irq_handler {
void *m_data;
void (*m_func)( void *data);
......@@ -48,8 +40,6 @@ struct _irq_handler {
static struct _irq_handler IRQ_HANDLER[N_IRQS];
static volatile ulong timestamp;
static void default_isr(void *data)
{
printf("default_isr(): called for IRQ %d, Interrupt Status=%x PR=%x\n",
......@@ -61,33 +51,20 @@ static int next_irq(void)
return (((*IXP425_ICIH & 0x000000fc) >> 2) - 1);
}
static void timer_isr(void *data)
{
unsigned int *pTime = (unsigned int *)data;
(*pTime)++;
/*
* Reset IRQ source
*/
*IXP425_OSST = IXP425_OSST_TIMER_2_PEND;
}
ulong get_timer (ulong base)
void do_irq (struct pt_regs *pt_regs)
{
return timestamp - base;
}
int irq = next_irq();
void reset_timer (void)
{
timestamp = 0;
IRQ_HANDLER[irq].m_func(IRQ_HANDLER[irq].m_data);
}
void do_irq (struct pt_regs *pt_regs)
void irq_install_handler (int irq, interrupt_handler_t handle_irq, void *data)
{
int irq = next_irq();
if (irq >= N_IRQS || !handle_irq)
return;
IRQ_HANDLER[irq].m_func(IRQ_HANDLER[irq].m_data);
IRQ_HANDLER[irq].m_data = data;
IRQ_HANDLER[irq].m_func = handle_irq;
}
int interrupt_init (void)
......@@ -95,23 +72,11 @@ int interrupt_init (void)
int i;
/* install default interrupt handlers */
for (i = 0; i < N_IRQS; i++) {
IRQ_HANDLER[i].m_data = (void *)i;
IRQ_HANDLER[i].m_func = default_isr;
}
/* install interrupt handler for timer */
IRQ_HANDLER[IXP425_TIMER_2_IRQ].m_data = (void *)&timestamp;
IRQ_HANDLER[IXP425_TIMER_2_IRQ].m_func = timer_isr;
/* setup the Timer counter value */
*IXP425_OSRT2 = (LATCH & ~IXP425_OST_RELOAD_MASK) | IXP425_OST_ENABLE;
for (i = 0; i < N_IRQS; i++)
irq_install_handler(i, default_isr, (void *)i);
/* configure interrupts for IRQ mode */
*IXP425_ICLR = 0x00000000;
/* enable timer irq */
*IXP425_ICMR = (1 << IXP425_TIMER_2_IRQ);
return (0);
}
......@@ -32,6 +32,54 @@
#include <common.h>
#include <asm/arch/ixp425.h>
#ifdef CONFIG_TIMER_IRQ
#define FREQ 66666666
#define CLOCK_TICK_RATE (((FREQ / CONFIG_SYS_HZ & ~IXP425_OST_RELOAD_MASK) + 1) * CONFIG_SYS_HZ)
#define LATCH ((CLOCK_TICK_RATE + CONFIG_SYS_HZ/2) / CONFIG_SYS_HZ) /* For divider */
/*
* When interrupts are enabled, use timer 2 for time/delay generation...
*/
static volatile ulong timestamp;
static void timer_isr(void *data)
{
unsigned int *pTime = (unsigned int *)data;
(*pTime)++;
/*
* Reset IRQ source
*/
*IXP425_OSST = IXP425_OSST_TIMER_2_PEND;
}
ulong get_timer (ulong base)
{
return timestamp - base;
}
void reset_timer (void)
{
timestamp = 0;
}
int timer_init (void)
{
/* install interrupt handler for timer */
irq_install_handler(IXP425_TIMER_2_IRQ, timer_isr, (void *)&timestamp);
/* setup the Timer counter value */
*IXP425_OSRT2 = (LATCH & ~IXP425_OST_RELOAD_MASK) | IXP425_OST_ENABLE;
/* enable timer irq */
*IXP425_ICMR = (1 << IXP425_TIMER_2_IRQ);
return 0;
}
#else
ulong get_timer (ulong base)
{
return get_timer_masked () - base;
......@@ -79,3 +127,9 @@ ulong get_timer_masked (void)
}
return (reload_constant - current);
}
int timer_init(void)
{
return 0;
}
#endif
......@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START = start.o
COBJS = cpu.o speed.o interrupts.o serial.o
COBJS = cpu.o speed.o serial.o timer.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
......
......@@ -47,7 +47,7 @@ static inline ulong READ_TIMER(void)
static ulong timestamp;
static ulong lastdec;
int interrupt_init (void)
int timer_init (void)
{
lh7a40x_timers_t* timers = LH7A40X_TIMERS_PTR;
lh7a40x_timer_t* timer = &timers->timer1;
......
......@@ -26,7 +26,13 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START = start.o
COBJS = serial.o interrupts.o cpu.o i2c.o pxafb.o usb.o
COBJS += cpu.o
COBJS += i2c.o
COBJS += pxafb.o
COBJS += serial.o
COBJS += timer.o
COBJS += usb.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
......
......@@ -56,10 +56,11 @@ static inline unsigned long long us_to_tick(unsigned long long us)
return us;
}
int interrupt_init (void)
int timer_init (void)
{
/* nothing happens here - we don't setup any IRQs */
return (0);
reset_timer();
return 0;
}
void reset_timer (void)
......
......@@ -26,7 +26,10 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START = start.o
COBJS = cache.o cpu.o interrupts.o
COBJS += cache.o
COBJS += cpu.o
COBJS += timer.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
......
......@@ -40,7 +40,7 @@
static ulong timestamp;
static ulong lastdec;
int interrupt_init (void)
int timer_init (void)
{
TCFG0 = 0x000000E9;
TCFG1 = 0x00000004;
......
......@@ -26,7 +26,9 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START = start.o
COBJS = interrupts.o cpu.o
COBJS += cpu.o
COBJS += timer.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
......
......@@ -29,10 +29,9 @@
#include <common.h>
#include <SA-1100.h>
int interrupt_init (void)
int timer_init (void)
{
/* nothing happens here - we don't setup any IRQs */
return (0);
return 0;
}
void reset_timer (void)
......
......@@ -62,4 +62,7 @@ void reset_timer_masked (void);
ulong get_timer_masked (void);
void udelay_masked (unsigned long usec);
/* cpu/.../timer.c */
int timer_init (void);
#endif /* _U_BOOT_ARM_H_ */
......@@ -55,6 +55,7 @@
*/
#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
#define CONFIG_USE_IRQ 1 /* we need IRQ stuff for timer */
#define CONFIG_TIMER_IRQ
#define CONFIG_BOOTCOUNT_LIMIT /* support for bootcount limit */
#define CONFIG_SYS_BOOTCOUNT_ADDR 0x60003000 /* inside qmrg sram */
......
......@@ -51,6 +51,7 @@
* Misc configuration options
*/
#define CONFIG_USE_IRQ 1 /* we need IRQ stuff for timer */
#define CONFIG_TIMER_IRQ
#define CONFIG_BOOTCOUNT_LIMIT /* support for bootcount limit */
#define CONFIG_SYS_BOOTCOUNT_ADDR 0x60003000 /* inside qmrg sram */
......
......@@ -266,7 +266,10 @@ init_fnc_t *init_sequence[] = {
arch_cpu_init, /* basic arch cpu dependent setup */
#endif
board_init, /* basic board dependent setup */
#if defined(CONFIG_USE_IRQ)
interrupt_init, /* set up exceptions */
#endif
timer_init, /* initialize timer */
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment