summaryrefslogtreecommitdiffstats
path: root/cpu/arm720t
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/arm720t')
-rw-r--r--cpu/arm720t/cpu.c3
-rw-r--r--cpu/arm720t/interrupts.c27
-rw-r--r--cpu/arm720t/serial.c78
-rw-r--r--cpu/arm720t/start.S69
4 files changed, 174 insertions, 3 deletions
diff --git a/cpu/arm720t/cpu.c b/cpu/arm720t/cpu.c
index a5b6de7605..60c1aa90b6 100644
--- a/cpu/arm720t/cpu.c
+++ b/cpu/arm720t/cpu.c
@@ -73,7 +73,7 @@ int cleanup_before_linux (void)
/* go to high speed */
IO_SYSCON3 = (IO_SYSCON3 & ~CLKCTL) | CLKCTL_73;
#endif
-#elif defined(CONFIG_NETARM) || defined(CONFIG_S3C4510B)
+#elif defined(CONFIG_NETARM) || defined(CONFIG_S3C4510B) || defined(CONFIG_LPC2292)
disable_interrupts ();
/* Nothing more needed */
#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
@@ -252,6 +252,7 @@ int dcache_status (void)
void icache_enable (void)
{
}
+#elif defined(CONFIG_LPC2292) /* just to satisfy the compiler */
#else
#error No icache/dcache enable/disable functions defined for this CPU type
#endif
diff --git a/cpu/arm720t/interrupts.c b/cpu/arm720t/interrupts.c
index da62502d61..8f32124d37 100644
--- a/cpu/arm720t/interrupts.c
+++ b/cpu/arm720t/interrupts.c
@@ -36,6 +36,12 @@
#define TIMER_LOAD_VAL 0xffff
/* macro to read the 16 bit timer */
#define READ_TIMER (IO_TC1D & 0xffff)
+
+#ifdef CONFIG_LPC2292
+#undef READ_TIMER
+#define READ_TIMER (0xFFFFFFFF - GET32(T0TC))
+#endif
+
#else
#define IRQEN (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_INTR_ENABLE))
#define TM2CTRL (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_TIMER2_CONTROL))
@@ -195,6 +201,13 @@ void do_irq (struct pt_regs *pt_regs)
}
#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
/* No do_irq() for IntegratorAP/CM720T as yet */
+#elif defined(CONFIG_LPC2292)
+
+ void (*pfnct)(void);
+
+ pfnct = (void (*)(void))VICVectAddr;
+
+ (*pfnct)();
#else
#error do_irq() not defined for this CPU type
#endif
@@ -293,6 +306,13 @@ int interrupt_init (void)
/* Start timer */
SET_REG( REG_TMOD, TM0_RUN);
+#elif defined(CONFIG_LPC2292)
+ PUT32(T0IR, 0); /* disable all timer0 interrupts */
+ PUT32(T0TCR, 0); /* disable timer0 */
+ PUT32(T0PR, CFG_SYS_CLK_FREQ / CFG_HZ);
+ PUT32(T0MCR, 0);
+ PUT32(T0TC, 0);
+ PUT32(T0TCR, 1); /* enable timer0 */
#else
#error No interrupt_init() defined for this CPU type
@@ -309,7 +329,7 @@ int interrupt_init (void)
*/
-#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) || defined(CONFIG_ARMADILLO)
+#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) || defined(CONFIG_ARMADILLO) || defined(CONFIG_LPC2292)
void reset_timer (void)
{
@@ -337,7 +357,12 @@ void udelay (unsigned long usec)
tmo += get_timer (0);
while (get_timer_masked () < tmo)
+#ifdef CONFIG_LPC2292
+ /* GJ - not sure whether this is really needed or a misunderstanding */
+ __asm__ __volatile__(" nop");
+#else
/*NOP*/;
+#endif
}
void reset_timer_masked (void)
diff --git a/cpu/arm720t/serial.c b/cpu/arm720t/serial.c
index 054bab9811..15c54af08b 100644
--- a/cpu/arm720t/serial.c
+++ b/cpu/arm720t/serial.c
@@ -123,4 +123,80 @@ serial_puts (const char *s)
}
}
-#endif /* defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) */
+#elif defined(CONFIG_LPC2292)
+
+#include <asm/arch/hardware.h>
+
+void serial_setbrg (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ unsigned short divisor = 0;
+
+ switch (gd->baudrate) {
+ case 1200: divisor = 3072; break;
+ case 9600: divisor = 384; break;
+ case 19200: divisor = 192; break;
+ case 38400: divisor = 96; break;
+ case 57600: divisor = 64; break;
+ case 115200: divisor = 32; break;
+ default: hang (); break;
+ }
+
+ /* init serial UART0 */
+ PUT8(U0LCR, 0);
+ PUT8(U0IER, 0);
+ PUT8(U0LCR, 0x80); /* DLAB=1 */
+ PUT8(U0DLL, (unsigned char)(divisor & 0x00FF));
+ PUT8(U0DLM, (unsigned char)(divisor >> 8));
+ PUT8(U0LCR, 0x03); /* 8N1, DLAB=0 */
+ PUT8(U0FCR, 1); /* Enable RX and TX FIFOs */
+}
+
+int serial_init (void)
+{
+ unsigned long pinsel0;
+
+ serial_setbrg ();
+
+ pinsel0 = GET32(PINSEL0);
+ pinsel0 &= ~(0x00000003);
+ pinsel0 |= 5;
+ PUT32(PINSEL0, pinsel0);
+
+ return (0);
+}
+
+void serial_putc (const char c)
+{
+ if (c == '\n')
+ {
+ while((GET8(U0LSR) & (1<<5)) == 0); /* Wait for empty U0THR */
+ PUT8(U0THR, '\r');
+ }
+
+ while((GET8(U0LSR) & (1<<5)) == 0); /* Wait for empty U0THR */
+ PUT8(U0THR, c);
+}
+
+int serial_getc (void)
+{
+ while((GET8(U0LSR) & 1) == 0);
+ return GET8(U0RBR);
+}
+
+void
+serial_puts (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
+
+/* Test if there is a byte to read */
+int serial_tstc (void)
+{
+ return (GET8(U0LSR) & 1);
+}
+
+#endif
diff --git a/cpu/arm720t/start.S b/cpu/arm720t/start.S
index e66d109443..96d5f54bac 100644
--- a/cpu/arm720t/start.S
+++ b/cpu/arm720t/start.S
@@ -43,7 +43,11 @@ _start: b reset
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
+#ifdef CONFIG_LPC2292
+ .word 0xB4405F76 /* 2's complement of the checksum of the vectors */
+#else
ldr pc, _not_used
+#endif
ldr pc, _irq
ldr pc, _fiq
@@ -123,6 +127,10 @@ reset:
bl cpu_init_crit
#endif
+#ifdef CONFIG_LPC2292
+ bl lowlevel_init
+#endif
+
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
@@ -131,6 +139,7 @@ relocate: /* relocate U-Boot to RAM */
beq stack_setup
#if TEXT_BASE
+#ifndef CONFIG_LPC2292 /* already done in lowlevel_init */
ldr r2, =0x0 /* Relocate the exception vectors */
cmp r1, r2 /* and associated data to address */
ldmneia r0!, {r3-r10} /* 0x0. Do nothing if TEXT_BASE is */
@@ -138,6 +147,7 @@ relocate: /* relocate U-Boot to RAM */
ldmneia r0, {r3-r9}
stmneia r2, {r3-r9}
adrne r0, _start /* restore r0 */
+#endif /* !CONFIG_LPC2292 */
#endif
ldr r2, _armboot_start
@@ -206,6 +216,14 @@ SYSCON3: .word 0x80002200
#define CLKCTL_49 0x4 /* 49.152 MHz */
#define CLKCTL_73 0x6 /* 73.728 MHz */
+#elif defined(CONFIG_LPC2292)
+PLLCFG_ADR: .word PLLCFG
+PLLFEED_ADR: .word PLLFEED
+PLLCON_ADR: .word PLLCON
+PLLSTAT_ADR: .word PLLSTAT
+VPBDIV_ADR: .word VPBDIV
+MEMMAP_ADR: .word MEMMAP
+
#endif
cpu_init_crit:
@@ -306,6 +324,50 @@ cpu_init_crit:
#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
/* No specific initialisation for IntegratorAP/CM720T as yet */
+#elif defined(CONFIG_LPC2292)
+ /* Set-up PLL */
+ mov r3, #0xAA
+ mov r4, #0x55
+ /* First disconnect and disable the PLL */
+ ldr r0, PLLCON_ADR
+ mov r1, #0x00
+ str r1, [r0]
+ ldr r0, PLLFEED_ADR /* start feed sequence */
+ str r3, [r0]
+ str r4, [r0] /* feed sequence done */
+ /* Set new M and P values */
+ ldr r0, PLLCFG_ADR
+ mov r1, #0x23 /* M=4 and P=2 */
+ str r1, [r0]
+ ldr r0, PLLFEED_ADR /* start feed sequence */
+ str r3, [r0]
+ str r4, [r0] /* feed sequence done */
+ /* Then enable the PLL */
+ ldr r0, PLLCON_ADR
+ mov r1, #0x01 /* PLL enable bit */
+ str r1, [r0]
+ ldr r0, PLLFEED_ADR /* start feed sequence */
+ str r3, [r0]
+ str r4, [r0] /* feed sequence done */
+ /* Wait for the lock */
+ ldr r0, PLLSTAT_ADR
+ mov r1, #0x400 /* lock bit */
+lock_loop:
+ ldr r2, [r0]
+ and r2, r1, r2
+ cmp r2, #0
+ beq lock_loop
+ /* And finally connect the PLL */
+ ldr r0, PLLCON_ADR
+ mov r1, #0x03 /* PLL enable bit and connect bit */
+ str r1, [r0]
+ ldr r0, PLLFEED_ADR /* start feed sequence */
+ str r3, [r0]
+ str r4, [r0] /* feed sequence done */
+ /* Set-up VPBDIV register */
+ ldr r0, VPBDIV_ADR
+ mov r1, #0x01 /* VPB clock is same as process clock */
+ str r1, [r0]
#else
#error No cpu_init_crit() defined for current CPU type
#endif
@@ -321,6 +383,7 @@ cpu_init_crit:
str r1, [r0]
#endif
+#ifndef CONFIG_LPC2292
mov ip, lr
/*
* before relocating, we have to setup RAM timing
@@ -329,6 +392,7 @@ cpu_init_crit:
*/
bl lowlevel_init
mov lr, ip
+#endif
mov pc, lr
@@ -537,6 +601,11 @@ reset_cpu:
* on external peripherals such as watchdog timers, etc. */
#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
/* No specific reset actions for IntegratorAP/CM720T as yet */
+#elif defined(CONFIG_LPC2292)
+ .align 5
+.globl reset_cpu
+reset_cpu:
+ mov pc, r0
#else
#error No reset_cpu() defined for current CPU type
#endif
OpenPOWER on IntegriCloud