summaryrefslogtreecommitdiff
path: root/lib_m68k
diff options
context:
space:
mode:
authorJohn Rigby <jrigby@freescale.com>2007-08-16 17:40:03 -0600
committerJohn Rigby <jrigby@freescale.com>2007-08-16 17:40:03 -0600
commit81735b2568cf634d601c0d4a1bbc3a3882bc8eda (patch)
tree521d22623e48f6923b4cda08a36cc26a9cc9abde /lib_m68k
parentd35b508a55508535b6e8445b718585d27df733d3 (diff)
parentd61ea14885631e58a25feaa81ee82eb464c62d6a (diff)
downloadu-boot-imx-81735b2568cf634d601c0d4a1bbc3a3882bc8eda.zip
u-boot-imx-81735b2568cf634d601c0d4a1bbc3a3882bc8eda.tar.gz
u-boot-imx-81735b2568cf634d601c0d4a1bbc3a3882bc8eda.tar.bz2
Merge branch 'denx-coldfire' into coldfire-aug2007
Diffstat (limited to 'lib_m68k')
-rw-r--r--lib_m68k/Makefile2
-rw-r--r--lib_m68k/board.c68
-rw-r--r--lib_m68k/interrupts.c117
-rw-r--r--lib_m68k/time.c263
4 files changed, 402 insertions, 48 deletions
diff --git a/lib_m68k/Makefile b/lib_m68k/Makefile
index 82165f0..03784fd 100644
--- a/lib_m68k/Makefile
+++ b/lib_m68k/Makefile
@@ -27,7 +27,7 @@ LIB = $(obj)lib$(ARCH).a
SOBJS =
-COBJS = cache.o traps.o time.o board.o m68k_linux.o
+COBJS = cache.o traps.o time.o interrupts.o board.o m68k_linux.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/lib_m68k/board.c b/lib_m68k/board.c
index 293fd04..395018c 100644
--- a/lib_m68k/board.c
+++ b/lib_m68k/board.c
@@ -221,6 +221,7 @@ static int init_func_i2c (void)
*/
init_fnc_t *init_sequence[] = {
+ get_clocks,
env_init,
init_baudrate,
serial_init,
@@ -371,6 +372,10 @@ board_init_f (ulong bootflag)
*/
bd->bi_memstart = CFG_SDRAM_BASE; /* start of DRAM memory */
bd->bi_memsize = gd->ram_size; /* size of DRAM memory in bytes */
+#ifdef CFG_INIT_RAM_ADDR
+ bd->bi_sramstart = CFG_INIT_RAM_ADDR; /* start of SRAM memory */
+ bd->bi_sramsize = CFG_INIT_RAM_END; /* size of SRAM memory */
+#endif
bd->bi_mbar_base = CFG_MBAR; /* base of internal registers */
bd->bi_bootflags = bootflag; /* boot / reboot flag (for LynxOS) */
@@ -430,6 +435,10 @@ void board_init_r (gd_t *id, ulong dest_addr)
gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
+#ifdef CONFIG_SERIAL_MULTI
+ serial_initialize();
+#endif
+
debug ("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
WATCHDOG_RESET ();
@@ -489,7 +498,7 @@ void board_init_r (gd_t *id, ulong dest_addr)
/*
* Setup trap handlers
*/
- trap_init (0);
+ trap_init (CFG_SDRAM_BASE);
#if !defined(CFG_NO_FLASH)
puts ("FLASH: ");
@@ -562,12 +571,48 @@ void board_init_r (gd_t *id, ulong dest_addr)
if (s)
s = (*e) ? e + 1 : e;
}
+#ifdef CONFIG_HAS_ETH1
+ /* handle the 2nd ethernet address */
+
+ s = getenv ("eth1addr");
+ for (i = 0; i < 6; ++i) {
+ bd->bi_enet1addr[i] = s ? simple_strtoul (s, &e, 16) : 0;
+ if (s)
+ s = (*e) ? e + 1 : e;
+ }
+#endif
+#ifdef CONFIG_HAS_ETH2
+ /* handle the 3rd ethernet address */
+
+ s = getenv ("eth2addr");
+ for (i = 0; i < 6; ++i) {
+ bd->bi_enet2addr[i] = s ? simple_strtoul (s, &e, 16) : 0;
+ if (s)
+ s = (*e) ? e + 1 : e;
+ }
+#endif
+
+#ifdef CONFIG_HAS_ETH3
+ /* handle 4th ethernet address */
+ s = getenv("eth3addr");
+ for (i = 0; i < 6; ++i) {
+ bd->bi_enet3addr[i] = s ? simple_strtoul (s, &e, 16) : 0;
+ if (s)
+ s = (*e) ? e + 1 : e;
+ }
+#endif
/* IP Address */
bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
WATCHDOG_RESET ();
+#if defined(CONFIG_PCI)
+ /*
+ * Do pci configuration
+ */
+ pci_init ();
+#endif
/** leave this here (after malloc(), environment and PCI are working) **/
/* Initialize devices */
@@ -640,15 +685,34 @@ void board_init_r (gd_t *id, ulong dest_addr)
nand_init(); /* go init the NAND */
#endif
-#if defined(CONFIG_CMD_NET) && defined(FEC_ENET)
+#if defined(CONFIG_CMD_NET)
WATCHDOG_RESET();
+#if defined(FEC_ENET)
eth_init(bd);
#endif
+#if defined(CONFIG_NET_MULTI)
+ puts ("Net: ");
+ eth_initialize (bd);
+#endif
+#endif
#ifdef CONFIG_POST
post_run (NULL, POST_RAM | post_bootmode_get(0));
#endif
+#if defined(CONFIG_CMD_PCMCIA) \
+ && !defined(CONFIG_CMD_IDE)
+ WATCHDOG_RESET ();
+ puts ("PCMCIA:");
+ pcmcia_init ();
+#endif
+
+#if defined(CONFIG_CMD_IDE)
+ WATCHDOG_RESET ();
+ puts ("IDE: ");
+ ide_init ();
+#endif
+
#ifdef CONFIG_LAST_STAGE_INIT
WATCHDOG_RESET ();
/*
diff --git a/lib_m68k/interrupts.c b/lib_m68k/interrupts.c
new file mode 100644
index 0000000..8919c0e
--- /dev/null
+++ b/lib_m68k/interrupts.c
@@ -0,0 +1,117 @@
+/*
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2007 Freescale Semiconductor Inc
+ * TsiChung Liew (Tsi-Chung.Liew@freescale.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 <watchdog.h>
+#include <asm/processor.h>
+#include <asm/immap.h>
+
+#define NR_IRQS (CFG_NUM_IRQS)
+
+/*
+ * Interrupt vector functions.
+ */
+struct interrupt_action {
+ interrupt_handler_t *handler;
+ void *arg;
+};
+
+static struct interrupt_action irq_vecs[NR_IRQS];
+
+static __inline__ unsigned short get_sr (void)
+{
+ unsigned short sr;
+
+ asm volatile ("move.w %%sr,%0":"=r" (sr):);
+
+ return sr;
+}
+
+static __inline__ void set_sr (unsigned short sr)
+{
+ asm volatile ("move.w %0,%%sr"::"r" (sr));
+}
+
+/************************************************************************/
+/*
+ * Install and free an interrupt handler
+ */
+void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
+{
+ if ((vec < 0) || (vec > NR_IRQS)) {
+ printf ("irq_install_handler: wrong interrupt vector %d\n",
+ vec);
+ return;
+ }
+
+ irq_vecs[vec].handler = handler;
+ irq_vecs[vec].arg = arg;
+}
+
+void irq_free_handler (int vec)
+{
+ if ((vec < 0) || (vec > NR_IRQS)) {
+ return;
+ }
+
+ irq_vecs[vec].handler = NULL;
+ irq_vecs[vec].arg = NULL;
+}
+
+void enable_interrupts (void)
+{
+ unsigned short sr;
+
+ sr = get_sr ();
+ set_sr (sr & ~0x0700);
+}
+
+int disable_interrupts (void)
+{
+ unsigned short sr;
+
+ sr = get_sr ();
+ set_sr (sr | 0x0700);
+
+ return ((sr & 0x0700) == 0); /* return TRUE, if interrupts were enabled before */
+}
+
+void int_handler (struct pt_regs *fp)
+{
+ int vec;
+
+ vec = (fp->vector >> 2) & 0xff;
+ if (vec > 0x40)
+ vec -= 0x40;
+ else
+ return;
+
+ if (irq_vecs[vec].handler != NULL) {
+ irq_vecs[vec].handler (irq_vecs[vec].arg);
+ } else {
+ printf ("\nBogus External Interrupt Vector %d\n", vec);
+ }
+}
diff --git a/lib_m68k/time.c b/lib_m68k/time.c
index 12e38f0..3dbce07 100644
--- a/lib_m68k/time.c
+++ b/lib_m68k/time.c
@@ -26,6 +26,8 @@
#include <common.h>
#include <asm/mcftimer.h>
+#include <asm/timer.h>
+#include <asm/immap.h>
#ifdef CONFIG_M5271
#include <asm/m5271.h>
@@ -46,13 +48,13 @@
#include <asm/immap_5249.h>
#endif
+DECLARE_GLOBAL_DATA_PTR;
static ulong timestamp;
#if defined(CONFIG_M5282) || defined(CONFIG_M5271)
static unsigned short lastinc;
#endif
-
#if defined(CONFIG_M5272)
/*
* We use timer 3 which is running with a period of 1 us
@@ -73,8 +75,10 @@ void udelay(unsigned long usec)
timerp->timer_tmr = MCFTIMER_TMR_DISABLE;
timerp->timer_tcn = 0;
/* set period to 1 us */
- timerp->timer_tmr = (((CFG_CLK / 1000000) - 1) << 8) | MCFTIMER_TMR_CLK1 |
- MCFTIMER_TMR_FREERUN | MCFTIMER_TMR_ENABLE;
+ timerp->timer_tmr =
+ (((CFG_CLK / 1000000) -
+ 1) << 8) | MCFTIMER_TMR_CLK1 | MCFTIMER_TMR_FREERUN |
+ MCFTIMER_TMR_ENABLE;
start = now = timerp->timer_tcn;
while (now < start + tmp)
@@ -82,7 +86,8 @@ void udelay(unsigned long usec)
}
}
-void mcf_timer_interrupt (void * not_used){
+void mcf_timer_interrupt(void *not_used)
+{
volatile timer_t *timerp = (timer_t *) (CFG_MBAR + MCFTIMER_BASE4);
volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1);
@@ -93,10 +98,11 @@ void mcf_timer_interrupt (void * not_used){
/* reset timer */
timerp->timer_ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
- timestamp ++;
+ timestamp++;
}
-void timer_init (void) {
+void timer_init(void)
+{
volatile timer_t *timerp = (timer_t *) (CFG_MBAR + MCFTIMER_BASE4);
volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1);
@@ -106,27 +112,29 @@ void timer_init (void) {
timerp->timer_tmr = MCFTIMER_TMR_DISABLE;
/* initialize and enable timer 4 interrupt */
- irq_install_handler (72, mcf_timer_interrupt, 0);
+ irq_install_handler(72, mcf_timer_interrupt, 0);
intp->int_icr1 |= 0x0000000d;
timerp->timer_tcn = 0;
timerp->timer_trr = 1000; /* Interrupt every ms */
/* set a period of 1us, set timer mode to restart and enable timer and interrupt */
- timerp->timer_tmr = (((CFG_CLK / 1000000) - 1) << 8) | MCFTIMER_TMR_CLK1 |
- MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENORI | MCFTIMER_TMR_ENABLE;
+ timerp->timer_tmr =
+ (((CFG_CLK / 1000000) -
+ 1) << 8) | MCFTIMER_TMR_CLK1 | MCFTIMER_TMR_RESTART |
+ MCFTIMER_TMR_ENORI | MCFTIMER_TMR_ENABLE;
}
-void reset_timer (void)
+void reset_timer(void)
{
timestamp = 0;
}
-ulong get_timer (ulong base)
+ulong get_timer(ulong base)
{
return (timestamp - base);
}
-void set_timer (ulong t)
+void set_timer(ulong t)
{
timestamp = t;
}
@@ -139,7 +147,7 @@ void udelay(unsigned long usec)
volatile unsigned short *timerp;
uint tmp;
- timerp = (volatile unsigned short *) (CFG_MBAR + MCFTIMER_BASE3);
+ timerp = (volatile unsigned short *)(CFG_MBAR + MCFTIMER_BASE3);
while (usec > 0) {
if (usec > 65000)
@@ -154,21 +162,21 @@ void udelay(unsigned long usec)
/* set period to 1 us */
timerp[MCFTIMER_PCSR] =
#ifdef CONFIG_M5271
- (6 << 8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW;
-#else /* !CONFIG_M5271 */
- (5 << 8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW;
-#endif /* CONFIG_M5271 */
+ (6 << 8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW;
+#else /* !CONFIG_M5271 */
+ (5 << 8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW;
+#endif /* CONFIG_M5271 */
timerp[MCFTIMER_PMR] = tmp;
- while (timerp[MCFTIMER_PCNTR] > 0);
+ while (timerp[MCFTIMER_PCNTR] > 0) ;
}
}
-void timer_init (void)
+void timer_init(void)
{
volatile unsigned short *timerp;
- timerp = (volatile unsigned short *) (CFG_MBAR + MCFTIMER_BASE4);
+ timerp = (volatile unsigned short *)(CFG_MBAR + MCFTIMER_BASE4);
timestamp = 0;
/* Set up TIMER 4 as poll clock */
@@ -176,27 +184,27 @@ void timer_init (void)
timerp[MCFTIMER_PMR] = lastinc = 0;
timerp[MCFTIMER_PCSR] =
#ifdef CONFIG_M5271
- (6 << 8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW;
-#else /* !CONFIG_M5271 */
- (5 << 8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW;
-#endif /* CONFIG_M5271 */
+ (6 << 8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW;
+#else /* !CONFIG_M5271 */
+ (5 << 8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW;
+#endif /* CONFIG_M5271 */
}
-void set_timer (ulong t)
+void set_timer(ulong t)
{
volatile unsigned short *timerp;
- timerp = (volatile unsigned short *) (CFG_MBAR + MCFTIMER_BASE4);
+ timerp = (volatile unsigned short *)(CFG_MBAR + MCFTIMER_BASE4);
timestamp = 0;
timerp[MCFTIMER_PMR] = lastinc = 0;
}
-ulong get_timer (ulong base)
+ulong get_timer(ulong base)
{
unsigned short now, diff;
volatile unsigned short *timerp;
- timerp = (volatile unsigned short *) (CFG_MBAR + MCFTIMER_BASE4);
+ timerp = (volatile unsigned short *)(CFG_MBAR + MCFTIMER_BASE4);
now = timerp[MCFTIMER_PCNTR];
diff = -(now - lastinc);
@@ -205,14 +213,13 @@ ulong get_timer (ulong base)
return timestamp - base;
}
-void wait_ticks (unsigned long ticks)
+void wait_ticks(unsigned long ticks)
{
- set_timer (0);
- while (get_timer (0) < ticks);
+ set_timer(0);
+ while (get_timer(0) < ticks) ;
}
#endif
-
#if defined(CONFIG_M5249)
/*
* We use timer 1 which is running with a period of 1 us
@@ -234,8 +241,10 @@ void udelay(unsigned long usec)
timerp->timer_tcn = 0;
/* set period to 1 us */
/* on m5249 the system clock is (cpu_clk / 2) -> divide by 2000000 */
- timerp->timer_tmr = (((CFG_CLK / 2000000) - 1) << 8) | MCFTIMER_TMR_CLK1 |
- MCFTIMER_TMR_FREERUN | MCFTIMER_TMR_ENABLE;
+ timerp->timer_tmr =
+ (((CFG_CLK / 2000000) -
+ 1) << 8) | MCFTIMER_TMR_CLK1 | MCFTIMER_TMR_FREERUN |
+ MCFTIMER_TMR_ENABLE;
start = now = timerp->timer_tcn;
while (now < start + tmp)
@@ -243,7 +252,8 @@ void udelay(unsigned long usec)
}
}
-void mcf_timer_interrupt (void * not_used){
+void mcf_timer_interrupt(void *not_used)
+{
volatile timer_t *timerp = (timer_t *) (CFG_MBAR + MCFTIMER_BASE2);
/* check for timer 2 interrupts */
@@ -253,10 +263,11 @@ void mcf_timer_interrupt (void * not_used){
/* reset timer */
timerp->timer_ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
- timestamp ++;
+ timestamp++;
}
-void timer_init (void) {
+void timer_init(void)
+{
volatile timer_t *timerp = (timer_t *) (CFG_MBAR + MCFTIMER_BASE2);
timestamp = 0;
@@ -265,34 +276,196 @@ void timer_init (void) {
timerp->timer_tmr = MCFTIMER_TMR_DISABLE;
/* initialize and enable timer 2 interrupt */
- irq_install_handler (31, mcf_timer_interrupt, 0);
+ irq_install_handler(31, mcf_timer_interrupt, 0);
mbar_writeLong(MCFSIM_IMR, mbar_readLong(MCFSIM_IMR) & ~0x00000400);
- mbar_writeByte(MCFSIM_TIMER2ICR, MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3);
+ mbar_writeByte(MCFSIM_TIMER2ICR,
+ MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 |
+ MCFSIM_ICR_PRI3);
timerp->timer_tcn = 0;
timerp->timer_trr = 1000; /* Interrupt every ms */
/* set a period of 1us, set timer mode to restart and enable timer and interrupt */
/* on m5249 the system clock is (cpu_clk / 2) -> divide by 2000000 */
- timerp->timer_tmr = (((CFG_CLK / 2000000) - 1) << 8) | MCFTIMER_TMR_CLK1 |
- MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENORI | MCFTIMER_TMR_ENABLE;
+ timerp->timer_tmr =
+ (((CFG_CLK / 2000000) -
+ 1) << 8) | MCFTIMER_TMR_CLK1 | MCFTIMER_TMR_RESTART |
+ MCFTIMER_TMR_ENORI | MCFTIMER_TMR_ENABLE;
}
-void reset_timer (void)
+void reset_timer(void)
{
timestamp = 0;
}
-ulong get_timer (ulong base)
+ulong get_timer(ulong base)
{
return (timestamp - base);
}
-void set_timer (ulong t)
+void set_timer(ulong t)
{
timestamp = t;
}
#endif
+#if defined(CONFIG_MCFTMR)
+#ifndef CFG_UDELAY_BASE
+# error "uDelay base not defined!"
+#endif
+
+#if !defined(CFG_TMR_BASE) || !defined(CFG_INTR_BASE) || !defined(CFG_TMRINTR_NO) || !defined(CFG_TMRINTR_MASK)
+# error "TMR_BASE, INTR_BASE, TMRINTR_NO or TMRINTR_MASk not defined!"
+#endif
+extern void dtimer_intr_setup(void);
+
+void udelay(unsigned long usec)
+{
+ volatile dtmr_t *timerp = (dtmr_t *) (CFG_UDELAY_BASE);
+ uint start, now, tmp;
+
+ while (usec > 0) {
+ if (usec > 65000)
+ tmp = 65000;
+ else
+ tmp = usec;
+ usec = usec - tmp;
+
+ /* Set up TIMER 3 as timebase clock */
+ timerp->tmr = DTIM_DTMR_RST_RST;
+ timerp->tcn = 0;
+ /* set period to 1 us */
+ timerp->tmr =
+ CFG_TIMER_PRESCALER | DTIM_DTMR_CLK_DIV1 | DTIM_DTMR_FRR |
+ DTIM_DTMR_RST_EN;
+
+ start = now = timerp->tcn;
+ while (now < start + tmp)
+ now = timerp->tcn;
+ }
+}
+
+void dtimer_interrupt(void *not_used)
+{
+ volatile dtmr_t *timerp = (dtmr_t *) (CFG_TMR_BASE);
+ volatile int0_t *intp = (int0_t *) (CFG_INTR_BASE);
+
+ /* check for timer interrupt asserted */
+ if ((intp->iprh0 & CFG_TMRINTR_MASK) == CFG_TMRINTR_MASK) {
+ timerp->ter = (DTIM_DTER_CAP | DTIM_DTER_REF);
+ timestamp++;
+ return;
+ }
+}
+
+void timer_init(void)
+{
+ volatile dtmr_t *timerp = (dtmr_t *) (CFG_TMR_BASE);
+
+ timestamp = 0;
+
+ timerp->tcn = 0;
+ timerp->trr = 0;
+
+ /* Set up TIMER 4 as clock */
+ timerp->tmr = DTIM_DTMR_RST_RST;
+
+ /* initialize and enable timer interrupt */
+ irq_install_handler(CFG_TMRINTR_NO, dtimer_interrupt, 0);
+
+ timerp->tcn = 0;
+ timerp->trr = 1000; /* Interrupt every ms */
+
+ dtimer_intr_setup();
+
+ /* set a period of 1us, set timer mode to restart and enable timer and interrupt */
+ timerp->tmr = CFG_TIMER_PRESCALER | DTIM_DTMR_CLK_DIV1 |
+ DTIM_DTMR_FRR | DTIM_DTMR_ORRI | DTIM_DTMR_RST_EN;
+}
+
+void reset_timer(void)
+{
+ timestamp = 0;
+}
+
+ulong get_timer(ulong base)
+{
+ return (timestamp - base);
+}
+
+void set_timer(ulong t)
+{
+ timestamp = t;
+}
+#endif /* CONFIG_MCFTMR */
+
+#if defined(CONFIG_MCFPIT)
+#if !defined(CFG_PIT_BASE)
+# error "CFG_PIT_BASE not defined!"
+#endif
+
+static unsigned short lastinc;
+
+void udelay(unsigned long usec)
+{
+ volatile pit_t *timerp = (pit_t *) (CFG_UDELAY_BASE);
+ uint tmp;
+
+ while (usec > 0) {
+ if (usec > 65000)
+ tmp = 65000;
+ else
+ tmp = usec;
+ usec = usec - tmp;
+
+ /* Set up TIMER 3 as timebase clock */
+ timerp->pcsr = PIT_PCSR_OVW;
+ timerp->pmr = 0;
+ /* set period to 1 us */
+ timerp->pcsr |= PIT_PCSR_PRE(CFG_PIT_PRESCALE) | PIT_PCSR_EN;
+
+ timerp->pmr = tmp;
+ while (timerp->pcntr > 0) ;
+ }
+}
+
+void timer_init(void)
+{
+ volatile pit_t *timerp = (pit_t *) (CFG_PIT_BASE);
+ timestamp = 0;
+
+ /* Set up TIMER 4 as poll clock */
+ timerp->pcsr = PIT_PCSR_OVW;
+ timerp->pmr = lastinc = 0;
+ timerp->pcsr |= PIT_PCSR_PRE(CFG_PIT_PRESCALE) | PIT_PCSR_EN;
+}
+
+void set_timer(ulong t)
+{
+ volatile pit_t *timerp = (pit_t *) (CFG_PIT_BASE);
+
+ timestamp = 0;
+ timerp->pmr = lastinc = 0;
+}
+
+ulong get_timer(ulong base)
+{
+ unsigned short now, diff;
+ volatile pit_t *timerp = (pit_t *) (CFG_PIT_BASE);
+
+ now = timerp->pcntr;
+ diff = -(now - lastinc);
+
+ timestamp += diff;
+ lastinc = now;
+ return timestamp - base;
+}
+
+void wait_ticks(unsigned long ticks)
+{
+ set_timer(0);
+ while (get_timer(0) < ticks) ;
+}
+#endif /* CONFIG_MCFPIT */
/*
* This function is derived from PowerPC code (read timebase as long long).
@@ -307,7 +480,7 @@ unsigned long long get_ticks(void)
* This function is derived from PowerPC code (timebase clock frequency).
* On M68K it returns the number of timer ticks per second.
*/
-ulong get_tbclk (void)
+ulong get_tbclk(void)
{
ulong tbclk;
tbclk = CFG_HZ;