From fea7f3aa3e5644b702be15d9076fe7b4b73db668 Mon Sep 17 00:00:00 2001 From: Thomas Chou Date: Thu, 8 Oct 2015 21:17:42 +0800 Subject: [PATCH] nios2: Switch to generic timer Zap almost all of the ad-hoc timer code from interrupts.c and use the code in lib/time.c instead. Signed-off-by: Marek Vasut Signed-off-by: Thomas Chou --- arch/nios2/cpu/interrupts.c | 132 +++++++++----------------------- arch/nios2/lib/Makefile | 1 - arch/nios2/lib/time.c | 22 ------ common/board_f.c | 3 +- include/configs/nios2-generic.h | 8 +- 5 files changed, 42 insertions(+), 124 deletions(-) delete mode 100644 arch/nios2/lib/time.c diff --git a/arch/nios2/cpu/interrupts.c b/arch/nios2/cpu/interrupts.c index 9d7e193e28..36d3ef7541 100644 --- a/arch/nios2/cpu/interrupts.c +++ b/arch/nios2/cpu/interrupts.c @@ -8,7 +8,6 @@ * SPDX-License-Identifier: GPL-2.0+ */ - #include #include #include @@ -20,14 +19,14 @@ #include #endif -typedef volatile struct { - unsigned status; /* Timer status reg */ - unsigned control; /* Timer control reg */ - unsigned periodl; /* Timeout period low */ - unsigned periodh; /* Timeout period high */ - unsigned snapl; /* Snapshot low */ - unsigned snaph; /* Snapshot high */ -} nios_timer_t; +struct nios_timer { + u32 status; /* Timer status reg */ + u32 control; /* Timer control reg */ + u32 periodl; /* Timeout period low */ + u32 periodh; /* Timeout period high */ + u32 snapl; /* Snapshot low */ + u32 snaph; /* Snapshot high */ +}; /* status register */ #define NIOS_TIMER_TO (1 << 0) /* Timeout */ @@ -39,8 +38,8 @@ typedef volatile struct { #define NIOS_TIMER_START (1 << 2) /* Start timer */ #define NIOS_TIMER_STOP (1 << 3) /* Stop timer */ -#if defined(CONFIG_SYS_NIOS_TMRBASE) && !defined(CONFIG_SYS_NIOS_TMRIRQ) -#error CONFIG_SYS_NIOS_TMRIRQ not defined (see documentation) +#if defined(CONFIG_SYS_TIMER_BASE) && !defined(CONFIG_SYS_TIMER_IRQ) +#error CONFIG_SYS_TIMER_IRQ not defined (see documentation) #endif /****************************************************************************/ @@ -54,80 +53,15 @@ struct irq_action { static struct irq_action vecs[32]; /*************************************************************************/ -volatile ulong timestamp = 0; - -void reset_timer (void) -{ - nios_timer_t *tmr =(nios_timer_t *)CONFIG_SYS_NIOS_TMRBASE; - - /* From Embedded Peripherals Handbook: - * - * "When the hardware is configured with Writeable period - * disabled, writing to one of the period_n registers causes - * the counter to reset to the fixed Timeout Period specified - * at system generation time." - * - * Here we force a reload to prevent early timeouts from - * get_timer() when the interrupt period is greater than - * than 1 msec. - * - * Simply write to periodl with its own value to force an - * internal counter reload, THEN reset the timestamp. - */ - writel (readl (&tmr->periodl), &tmr->periodl); - timestamp = 0; - - /* From Embedded Peripherals Handbook: - * - * "Writing to one of the period_n registers stops the internal - * counter, except when the hardware is configured with Start/Stop - * control bits off. If Start/Stop control bits is off, writing - * either register does not stop the counter." - * - * In order to accomodate either configuration, the control - * register is re-written. If the counter is stopped, it will - * be restarted. If it is running, the write is essentially - * a nop. - */ - writel (NIOS_TIMER_ITO | NIOS_TIMER_CONT | NIOS_TIMER_START, - &tmr->control); - -} - -ulong get_timer (ulong base) -{ - WATCHDOG_RESET (); - return (timestamp - base); -} - -/* - * This function is derived from Blackfin code (read timebase as long long). - * On Nios2 it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} +static volatile ulong timestamp; /* - * This function is derived from Blackfin code. - * On Nios2 it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - ulong tbclk; - - tbclk = CONFIG_SYS_HZ; - return tbclk; -} - -/* The board must handle this interrupt if a timer is not + * The board must handle this interrupt if a timer is not * provided. */ -#if defined(CONFIG_SYS_NIOS_TMRBASE) void tmr_isr (void *arg) { - nios_timer_t *tmr = (nios_timer_t *)arg; + struct nios_timer *tmr = (struct nios_timer *)arg; /* Interrupt is cleared by writing anything to the * status register. */ @@ -138,24 +72,38 @@ void tmr_isr (void *arg) #endif } -static void tmr_init (void) +unsigned long notrace timer_read_counter(void) +{ + struct nios_timer *tmr = (struct nios_timer *)CONFIG_SYS_TIMER_BASE; + u32 val; + + /* Trigger update */ + writel(0x0, &tmr->snapl); + + /* Read timer value */ + val = readl(&tmr->snapl) & 0xffff; + val |= (readl(&tmr->snaph) & 0xffff) << 16; + + return ~val; +} + +int timer_init(void) { - nios_timer_t *tmr =(nios_timer_t *)CONFIG_SYS_NIOS_TMRBASE; + struct nios_timer *tmr = (struct nios_timer *)CONFIG_SYS_TIMER_BASE; writel (0, &tmr->status); writel (0, &tmr->control); writel (NIOS_TIMER_STOP, &tmr->control); -#if defined(CONFIG_SYS_NIOS_TMRCNT) - writel (CONFIG_SYS_NIOS_TMRCNT & 0xffff, &tmr->periodl); - writel ((CONFIG_SYS_NIOS_TMRCNT >> 16) & 0xffff, &tmr->periodh); -#endif - writel (NIOS_TIMER_ITO | NIOS_TIMER_CONT | NIOS_TIMER_START, - &tmr->control); - irq_install_handler (CONFIG_SYS_NIOS_TMRIRQ, tmr_isr, (void *)tmr); -} + writel (0xffff, &tmr->periodl); + writel (0xffff, &tmr->periodh); -#endif /* CONFIG_SYS_NIOS_TMRBASE */ + writel (NIOS_TIMER_CONT | NIOS_TIMER_START, &tmr->control); + /* FIXME */ + irq_install_handler(CONFIG_SYS_TIMER_IRQ, tmr_isr, (void *)tmr); + + return 0; +} /*************************************************************************/ int disable_interrupts (void) @@ -245,10 +193,6 @@ int interrupt_init (void) vecs[i].count = 0; } -#if defined(CONFIG_SYS_NIOS_TMRBASE) - tmr_init (); -#endif - enable_interrupts (); return (0); } diff --git a/arch/nios2/lib/Makefile b/arch/nios2/lib/Makefile index 079378a905..e35d2e92a2 100644 --- a/arch/nios2/lib/Makefile +++ b/arch/nios2/lib/Makefile @@ -8,4 +8,3 @@ obj-y += cache.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-y += libgcc.o -obj-y += time.o diff --git a/arch/nios2/lib/time.c b/arch/nios2/lib/time.c deleted file mode 100644 index d39604579c..0000000000 --- a/arch/nios2/lib/time.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * (C) Copyright 2003, Psyent Corporation - * Scott McNutt - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - - -extern void dly_clks( unsigned long ticks ); - -void __udelay(unsigned long usec) -{ - /* The Nios core doesn't have a timebase, so we do our - * best for now and call a low-level loop that counts - * cpu clocks. - */ - unsigned long cnt = (CONFIG_SYS_CLK_FREQ/1000000) * usec; - dly_clks (cnt); -} diff --git a/common/board_f.c b/common/board_f.c index 613332e1dc..8bb8ded50e 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -795,7 +795,8 @@ static init_fnc_t init_sequence_f[] = { init_timebase, #endif #if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || \ - defined(CONFIG_BLACKFIN) || defined(CONFIG_NDS32) + defined(CONFIG_BLACKFIN) || defined(CONFIG_NDS32) || \ + defined(CONFIG_NIOS2) timer_init, /* initialize timer */ #endif #ifdef CONFIG_SYS_ALLOC_DPRAM diff --git a/include/configs/nios2-generic.h b/include/configs/nios2-generic.h index 293acaef57..6e6cd8cd62 100644 --- a/include/configs/nios2-generic.h +++ b/include/configs/nios2-generic.h @@ -39,12 +39,8 @@ /* * TIMER */ -#define CONFIG_SYS_LOW_RES_TIMER -#define CONFIG_SYS_NIOS_TMRBASE CONFIG_SYS_TIMER_BASE -#define CONFIG_SYS_NIOS_TMRIRQ CONFIG_SYS_TIMER_IRQ -#define CONFIG_SYS_NIOS_TMRMS 10 /* Desired period (msec)*/ -#define CONFIG_SYS_NIOS_TMRCNT \ - (CONFIG_SYS_NIOS_TMRMS * (CONFIG_SYS_TIMER_FREQ / 1000) - 1) +#define CONFIG_SYS_TIMER_RATE CONFIG_SYS_TIMER_FREQ +#define CONFIG_SYS_NIOS_TMRMS 10 /* FIXME: Desired period (msec)*/ /* * STATUS LED -- 2.39.5