Add support for LPC2468 from NXP Basic startup code Internal flash is supported (for environment storage)
Signed-off-by: Remco Poelstra <remco.poels...@duran-audio.com> --- MAKEALL | 1 + Makefile | 3 + arch/arm/cpu/arm720t/cpu.c | 4 +- arch/arm/cpu/arm720t/interrupts.c | 39 ++- arch/arm/cpu/arm720t/lpc24xx/Makefile | 50 +++ arch/arm/cpu/arm720t/lpc24xx/flash.c | 236 ++++++++++++ arch/arm/cpu/arm720t/lpc24xx/iap_entry.S | 7 + arch/arm/cpu/arm720t/start.S | 12 +- arch/arm/include/asm/arch-lpc24xx/hardware.h | 32 ++ arch/arm/include/asm/arch-lpc24xx/immap.h | 528 ++++++++++++++++++++++++++ arch/arm/include/asm/config.h | 4 + arch/arm/lib/eabi_compat.c | 5 + drivers/serial/Makefile | 1 + drivers/serial/serial_lpc2468.c | 119 ++++++ include/flash.h | 1 + 15 files changed, 1033 insertions(+), 9 deletions(-) create mode 100644 arch/arm/cpu/arm720t/lpc24xx/Makefile create mode 100644 arch/arm/cpu/arm720t/lpc24xx/flash.c create mode 100644 arch/arm/cpu/arm720t/lpc24xx/iap_entry.S create mode 100644 arch/arm/include/asm/arch-lpc24xx/hardware.h create mode 100644 arch/arm/include/asm/arch-lpc24xx/immap.h create mode 100644 drivers/serial/serial_lpc2468.c diff --git a/MAKEALL b/MAKEALL index bb09627..2f747c6 100755 --- a/MAKEALL +++ b/MAKEALL @@ -540,6 +540,7 @@ LIST_ARM7=" \ impa7 \ integratorap \ lpc2292sodimm \ + LPC2468 \ modnet50 \ SMN42 \ " diff --git a/Makefile b/Makefile index 82cbbf4..a4212c8 100644 --- a/Makefile +++ b/Makefile @@ -3148,6 +3148,9 @@ evb4510_config : unconfig lpc2292sodimm_config: unconfig @$(MKCONFIG) $(@:_config=) arm arm720t lpc2292sodimm NULL lpc2292 +LPC2468_config: unconfig + @$(MKCONFIG) $(@:_config=) arm arm720t LPC2468 NULL lpc24xx + SMN42_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm720t SMN42 siemens lpc2292 diff --git a/arch/arm/cpu/arm720t/cpu.c b/arch/arm/cpu/arm720t/cpu.c index 88c71bf..578358c 100644 --- a/arch/arm/cpu/arm720t/cpu.c +++ b/arch/arm/cpu/arm720t/cpu.c @@ -63,7 +63,9 @@ int cleanup_before_linux (void) /* go to high speed */ IO_SYSCON3 = (IO_SYSCON3 & ~CLKCTL) | CLKCTL_73; #endif -#elif defined(CONFIG_NETARM) || defined(CONFIG_S3C4510B) || defined(CONFIG_LPC2292) +#elif defined(CONFIG_NETARM) || defined(CONFIG_S3C4510B) ||\ + defined(CONFIG_LPC2000) + disable_interrupts (); /* Nothing more needed */ #elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) diff --git a/arch/arm/cpu/arm720t/interrupts.c b/arch/arm/cpu/arm720t/interrupts.c index eb8d425..06c4550 100644 --- a/arch/arm/cpu/arm720t/interrupts.c +++ b/arch/arm/cpu/arm720t/interrupts.c @@ -29,17 +29,26 @@ #include <common.h> #include <clps7111.h> #include <asm/proc-armv/ptrace.h> +#if defined(CONFIG_LPC2468) +#include <asm/arch/immap.h> +#include <asm/io.h> +#else #include <asm/hardware.h> +#endif #ifndef CONFIG_NETARM + +#if defined(CONFIG_LPC2292) +#define TIMER_LOAD_VAL 0xffff +#define READ_TIMER (0xFFFFFFFF - GET32(T0TC)) +#elif defined(CONFIG_LPC2468) +#define TIMER_LOAD_VAL 0 +#define READ_TIMER (0xFFFFFFFF - 0xE0004008) +#else /* we always count down the max. */ #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 @@ -80,6 +89,14 @@ void do_irq (struct pt_regs *pt_regs) pfnct = (void (*)(void))VICVectAddr; (*pfnct)(); +#elif defined(CONFIG_LPC2468) + void (*pfnct) (void); + vic_2468_t *vic = &(((immap_t *)CONFIG_SYS_IMMAP)->ahb.vic); + + pfnct = (void (*)(void))(&(vic->vicaddr)); + + (*pfnct) (); + #else #error do_irq() not defined for this CPU type #endif @@ -138,6 +155,10 @@ int arch_interrupt_init (void) int timer_init (void) { +#if defined(CONFIG_LPC2468) + timer_2468_t *timer0=&(((immap_t *)CONFIG_SYS_IMMAP)->apb.timer0); +#endif + #if defined(CONFIG_NETARM) /* disable all interrupts */ IRQEN = 0; @@ -191,6 +212,13 @@ int timer_init (void) PUT32(T0MCR, 0); PUT32(T0TC, 0); PUT32(T0TCR, 1); /* enable timer0 */ +#elif defined(CONFIG_LPC2468) + writel (0, &(timer0->ir)); /*disable all timer0 interupts */ + writel (0, &(timer0->tcr)); /*disable timer0 */ + writel (CFG_SYS_CLK_FREQ / CONFIG_SYS_HZ - 1, &(timer0->pr)); + writel (0, &(timer0->mcr)); + writel (0, &(timer0->tc)); + writel (1, &(timer0->tcr)); #else #error No timer_init() defined for this CPU type @@ -207,7 +235,8 @@ int timer_init (void) */ -#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) || defined(CONFIG_ARMADILLO) || defined(CONFIG_LPC2292) +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) ||\ + defined(CONFIG_ARMADILLO) || defined(CONFIG_LPC2000) void reset_timer (void) { diff --git a/arch/arm/cpu/arm720t/lpc24xx/Makefile b/arch/arm/cpu/arm720t/lpc24xx/Makefile new file mode 100644 index 0000000..f091502 --- /dev/null +++ b/arch/arm/cpu/arm720t/lpc24xx/Makefile @@ -0,0 +1,50 @@ +# +# (C) Copyright 2000-2007 +# Wolfgang Denk, DENX Software Engineering, w...@denx.de. +# +# 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 $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS = flash.o +SOBJS = $(obj)iap_entry.o + +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) + +# this MUST be compiled as thumb code! +$(SOBJS): + $(CC) $(AFLAGS) -march=armv4t -c -o $(SOBJS) iap_entry.S + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm720t/lpc24xx/flash.c b/arch/arm/cpu/arm720t/lpc24xx/flash.c new file mode 100644 index 0000000..963bf6e --- /dev/null +++ b/arch/arm/cpu/arm720t/lpc24xx/flash.c @@ -0,0 +1,236 @@ +/* + * (C) Copyright 2006 Embedded Artists AB <www.embeddedartists.com> + * + * 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 <asm/io.h> +#include <asm/arch/immap.h> + +/* IAP commands use 32 bytes at the top of CPU internal sram, we + * use 512 bytes below that + */ + +#define COPY_BUFFER_LOCATION 0x4000fde0 + +#define IAP_LOCATION 0x7ffffff1 +#define IAP_CMD_PREPARE 50 +#define IAP_CMD_COPY 51 +#define IAP_CMD_ERASE 52 +#define IAP_CMD_CHECK 53 +#define IAP_CMD_ID 54 +#define IAP_CMD_VERSION 55 +#define IAP_CMD_COMPARE 56 + +#define IAP_RET_CMD_SUCCESS 0 + +static unsigned long command[5]; +static unsigned long result[2]; + +extern void iap_entry (unsigned long *command, unsigned long *result); + +/*----------------------------------------------------------------------- + * + */ +int get_flash_sector (flash_info_t * info, ulong flash_addr) +{ + int i; + + for (i = 1; i < (info->sector_count); i++) { + if (flash_addr < (info->start[i])) + break; + } + + return (i - 1); +} + +/*----------------------------------------------------------------------- + * This function assumes that flash_addr is aligned on 512 bytes boundary + * in flash. This function also assumes that prepare have been called + * for the sector in question. + */ +int lpc24xx_copy_buffer_to_flash (flash_info_t * info, ulong flash_addr) +{ + int first_sector; + int last_sector; + + first_sector = get_flash_sector (info, flash_addr); + last_sector = get_flash_sector (info, flash_addr + 512 - 1); + + /* prepare sectors for write */ + command[0] = IAP_CMD_PREPARE; + command[1] = first_sector; + command[2] = last_sector; + iap_entry (command, result); + if (result[0] != IAP_RET_CMD_SUCCESS) { + printf ("IAP prepare failed\n"); + return ERR_PROG_ERROR; + } + + command[0] = IAP_CMD_COPY; + command[1] = flash_addr; + command[2] = COPY_BUFFER_LOCATION; + command[3] = 512; + command[4] = CFG_SYS_CLK_FREQ >> 10; + iap_entry (command, result); + if (result[0] != IAP_RET_CMD_SUCCESS) { + printf ("IAP copy failed\n"); + return 1; + } + + return 0; +} + +int lpc24xx_flash_erase (flash_info_t * info, int s_first, int s_last) +{ + int flag; + int prot; + int sect; + + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + if (prot) + return ERR_PROTECTED; + + flag = disable_interrupts (); + + printf ("Erasing %d sectors starting at sector %2d.\n" + "This make take some time ... ", s_last - s_first + 1, s_first); + + command[0] = IAP_CMD_PREPARE; + command[1] = s_first; + command[2] = s_last; + iap_entry (command, result); + if (result[0] != IAP_RET_CMD_SUCCESS) { + printf ("IAP prepare failed\n"); + return ERR_PROTECTED; + } + + command[0] = IAP_CMD_ERASE; + command[1] = s_first; + command[2] = s_last; + command[3] = CFG_SYS_CLK_FREQ >> 10; + iap_entry (command, result); + if (result[0] != IAP_RET_CMD_SUCCESS) { + printf ("IAP erase failed\n"); + return ERR_PROTECTED; + } + + if (flag) + enable_interrupts (); + + return ERR_OK; +} + +int lpc24xx_write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ + int first_copy_size; + int last_copy_size; + int first_block; + int last_block; + int nbr_mid_blocks; + sys_con_2468_t *sys_con=&(((immap_t *)CONFIG_SYS_IMMAP)->apb.sys_con); + uchar memmap_value; + ulong i; + uchar *src_org; + uchar *dst_org; + int ret = ERR_OK; + + src_org = src; + dst_org = (uchar *) addr; + + first_block = addr / 512; + last_block = (addr + cnt) / 512; + nbr_mid_blocks = last_block - first_block - 1; + + first_copy_size = 512 - (addr % 512); + last_copy_size = (addr + cnt) % 512; + + debug ("\ncopy first block: (1) %lX -> %lX 0x200 bytes, " + "(2) %lX -> %lX 0x%X bytes, (3) %lX -> %lX 0x200 bytes\n", + (ulong) (first_block * 512), + (ulong) COPY_BUFFER_LOCATION, + (ulong) src, + (ulong) (COPY_BUFFER_LOCATION + 512 - first_copy_size), + first_copy_size, + (ulong) COPY_BUFFER_LOCATION, (ulong) (first_block * 512)); + + /* copy first block */ + memcpy ((void *)COPY_BUFFER_LOCATION, (void *)(first_block * 512), 512); + memcpy ((void *)(COPY_BUFFER_LOCATION + 512 - first_copy_size), + src, first_copy_size); + lpc24xx_copy_buffer_to_flash (info, first_block * 512); + src += first_copy_size; + addr += first_copy_size; + + /* copy middle blocks */ + for (i = 0; i < nbr_mid_blocks; i++) { + debug ("copy middle block: %lX -> %lX 512 bytes, " + "%lX -> %lX 512 bytes\n", + (ulong) src, + (ulong) COPY_BUFFER_LOCATION, + (ulong) COPY_BUFFER_LOCATION, (ulong) addr); + memcpy ((void *)COPY_BUFFER_LOCATION, src, 512); + lpc24xx_copy_buffer_to_flash (info, addr); + src += 512; + addr += 512; + } + + if (last_copy_size > 0) { + debug ("copy last block: (1) %lX -> %lX 0x200 bytes, " + "(2) %lX -> %lX 0x%X bytes, (3) %lX -> %lX x200 bytes\n", + (ulong) (last_block * 512), + (ulong) COPY_BUFFER_LOCATION, + (ulong) src, + (ulong) (COPY_BUFFER_LOCATION), + last_copy_size, + (ulong) COPY_BUFFER_LOCATION, (ulong) addr); + /* copy last block */ + memcpy ((void *)COPY_BUFFER_LOCATION, + (void *)(last_block * 512), 512); + memcpy ((void *)COPY_BUFFER_LOCATION, src, last_copy_size); + lpc24xx_copy_buffer_to_flash (info, addr); + } + + /* verify write */ + memmap_value = readl(&(sys_con->memmap)); + + disable_interrupts (); + + writel(01, &(sys_con->memmap)); /* we must make sure that initial 64 + bytes are taken from flash when we + do the compare */ + + for (i = 0; i < cnt; i++) { + if (*dst_org != *src_org) { + printf ("Write failed. Byte %lX differs\n", i); + ret = ERR_PROG_ERROR; + break; + } + dst_org++; + src_org++; + } + + writel(memmap_value, &(sys_con->memmap)); + enable_interrupts (); + + return ret; +} diff --git a/arch/arm/cpu/arm720t/lpc24xx/iap_entry.S b/arch/arm/cpu/arm720t/lpc24xx/iap_entry.S new file mode 100644 index 0000000..c31d519 --- /dev/null +++ b/arch/arm/cpu/arm720t/lpc24xx/iap_entry.S @@ -0,0 +1,7 @@ +IAP_ADDRESS: .word 0x7FFFFFF1 + +.globl iap_entry +iap_entry: + ldr r2, IAP_ADDRESS + bx r2 + mov pc, lr diff --git a/arch/arm/cpu/arm720t/start.S b/arch/arm/cpu/arm720t/start.S index 022b873..1b2e4bf 100644 --- a/arch/arm/cpu/arm720t/start.S +++ b/arch/arm/cpu/arm720t/start.S @@ -127,7 +127,7 @@ reset: bl cpu_init_crit #endif -#ifdef CONFIG_LPC2292 +#if defined(CONFIG_LPC2000) bl lowlevel_init #endif @@ -368,6 +368,12 @@ lock_loop: ldr r0, VPBDIV_ADR mov r1, #0x01 /* VPB clock is same as process clock */ str r1, [r0] +#elif defined(CONFIG_LPC2468) + ldr r0, =0x40008000 /* 0x40000000 is internal SRAM, + * 0x4000FFFF is end of SRAM + */ + mov sp,r0 + sub sl,sp,#0x2000 #else #error No cpu_init_crit() defined for current CPU type #endif @@ -383,7 +389,7 @@ lock_loop: str r1, [r0] #endif -#ifndef CONFIG_LPC2292 +#if !defined(CONFIG_LPC2000) mov ip, lr /* * before relocating, we have to setup RAM timing @@ -601,7 +607,7 @@ 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) +#elif defined(CONFIG_LPC2000) .align 5 .globl reset_cpu reset_cpu: diff --git a/arch/arm/include/asm/arch-lpc24xx/hardware.h b/arch/arm/include/asm/arch-lpc24xx/hardware.h new file mode 100644 index 0000000..b42746e --- /dev/null +++ b/arch/arm/include/asm/arch-lpc24xx/hardware.h @@ -0,0 +1,32 @@ +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +/* + * Copyright (c) 2004 Cucy Systems (http://www.cucy.com) + * Curt Brune <c...@cucy.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 + */ + +#if defined(CONFIG_LPC2468) +#else +#error No hardware file defined for this configuration +#endif + +#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/include/asm/arch-lpc24xx/immap.h b/arch/arm/include/asm/arch-lpc24xx/immap.h new file mode 100644 index 0000000..0841230 --- /dev/null +++ b/arch/arm/include/asm/arch-lpc24xx/immap.h @@ -0,0 +1,528 @@ +/* + * (C) Copyright 2009 Duran Audio B.V. + * + * LPC2468 Internal Memory Map + * + * 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 + * + */ + +#ifndef __LPC24XX_IMMAP_H +#define __LPC24XX_IMMAP_H + +#include <asm/types.h> +#include <config.h> + +typedef struct watchdog_2468 { + u8 fixme[0x4000]; +} watchdog2468_t; + +typedef struct timer_2468 { + u32 ir; /* Interrupt register */ + u32 tcr; /* Timer control register */ + u32 tc; /* Timer counter */ + u32 pr; /* Prescale register */ + u32 pc; /* Prescale counter */ + u32 mcr; /* Match control register */ + u32 mr0; /* Match register 0 */ + u32 mr1; /* Match register 1 */ + u32 mr2; /* Match register 2 */ + u32 mr3; /* Match register 3 */ + u32 ccr; /* Capture control register */ + u32 cr0; /* Capture register 0 */ + u32 cr1; /* Capture register 1 */ + u32 cr2; /* Capture register 2 */ + u32 cr3; /* Capture register 3 */ + u32 emr; /* External match register */ + u32 ctcr; /* Count control register */ + u8 notused[0x3fbc]; +} timer_2468_t; + +/*These two UART structs can probably be combined*/ +typedef struct uart_2468 { + u32 rbr_thr_dll; /*Receive buffer/transmit holding/divisor latch lsb register */ + u32 ier_dlm; /*Interrupt enable/divisor latch msb register */ + u32 iir_fcr; /*Interrupt ID/FIFO control register */ + u32 lcr; /* Line control register */ + u32 notused1; + u32 lsr; /*Line status register */ + u32 notused2; + u32 scr; /*Scratch pad register */ + u32 acr; /*Auto-baud control register */ + u32 icr; /*IrDA control register */ + u32 fdr; /*Fractional division register */ + u32 notused3; + u32 ter; /* Transmit enable register */ + u8 notused[0x3fcc]; +} uart_2468_t; + +typedef struct uart1_2468 { + u8 fixme[0x4000]; +} uart1_2468_t; + +typedef struct pwm0_2468 { + u8 fixme[0x4000]; +} pwm0_2468_t; + +typedef struct pwm1_2468 { + u8 fixme[0x4000]; +} pwm1_2468_t; + +typedef struct i2c0_2468 { + u8 fixme[0x4000]; +} i2c0_2468_t; + +typedef struct spi_2468 { + u8 fixme[0x4000]; +} spi_2468_t; + +typedef struct rtc_2468 { + u8 fixme[0x4000]; +} rtc_2468_t; + +typedef struct gpio_2468 { + u32 iopin0; + u32 ioset0; + u32 iodir0; + u32 ioclr0; + u32 iopin1; + u32 ioset1; + u32 iodir1; + u32 ioclr1; + u8 notused[0x3fe0]; +} gpio_2468_t; + +typedef struct pin_connect_2468 { + u32 pinsel0; /*Pin function select register*/ + u32 pinsel1; + u32 pinsel2; + u32 pinsel3; + u32 pinsel4; + u32 pinsel5; + u32 pinsel6; + u32 pinsel7; + u32 pinsel8; + u32 pinsel9; + u32 pinsel10; + u32 pinsel11; + u32 pinmode0; /*Pin mode select register*/ + u32 pinmode1; + u32 pinmode2; + u32 pinmode3; + u32 pinmode4; + u32 pinmode5; + u32 pinmode6; + u32 pinmode7; + u32 pinmode8; + u32 pinmode9; + u8 notused[0x3fa8]; +} pin_connect_2468_t; + +typedef struct ssp1_2468 { + u8 fixme[0x4000]; +} ssp1_2468_t; + +typedef struct adc_2468 { + u8 fixme[0x4000]; +} adc_2468_t; + +typedef struct can_accept_ram_2468 { + u8 fixme[0x4000]; +} can_accept_ram_2468_t; + +typedef struct can_accept_filter_2468 { + u8 fixme[0x4000]; +} can_accept_filter_2468_t; + +typedef struct can_common_2468 { + u8 fixme[0x4000]; +} can_common_2468_t; + +typedef struct can1_2468 { + u8 fixme[0x4000]; +} can1_2468_t; + +typedef struct can2_2468 { + u8 fixme[0x4000]; +} can2_2468_t; + +typedef struct i2c1_2468 { + u8 fixme[0x4000]; +} i2c1_2468_t; + +typedef struct ssp0_2468 { + u8 fixme[0x4000]; +} ssp0_2468_t; + +typedef struct dac_2468 { + u8 fixme[0x4000]; +} dac_2468_t; + +typedef struct i2c2_2468 { + u8 fixme[0x4000]; +} i2c2_2468_t; + +typedef struct batt_ram_2468 { + u8 fixme[0x4000]; +} batt_ram_2468_t; + +typedef struct i2s_2468 { + u8 fixme[0x4000]; +} i2s_2468_t; + +typedef struct mmc_2468 { + u8 fixme[0x4000]; +} mmc_2468_t; + +typedef struct sys_con_2468 { // c000 + u32 mamcr; /*Memory Accelerator configuration register*/ + u32 mamtim; /*Memory Accelerator timing register*/ + u8 notused1[0x38]; + u32 memmap; /*Memory mapping control register c040*/ + u8 notused2[0x3c]; + u32 pllcon; /*PLL control register c080*/ + u32 pllcfg; /*PLL configuration register c084*/ + u32 pllstat; /*PLL status register c088*/ + u32 pllfeed; /*PLL feed register c08c*/ + u8 notused3[0x30]; + u32 pcon; /*Power control register c0c0*/ + u32 pconp; /*Power control for peripherals register c0c4*/ + u8 notused4[0x3c]; + u32 cclkcfg; /*CPU clock configuration register c104*/ + u32 usbclkcfg; /*USB clock configuration register c108*/ + u32 clksrcsel; /*Clock source select register c10c*/ + u8 notused5[0x30]; + u32 extint; /*External interrupt flag register c140*/ + u32 intwake; /*Interrupt wakeup register c144*/ + u32 extmode; /*External interrupt mode resgister c148*/ + u32 extpolar; /*External interrupt polarity register c14c*/ + u8 notused6[0x30]; + u32 rsid; /*Reset source identification register c180*/ + u32 cspr; /*Code security protection register c184*/ + u8 notused7[0x18]; + u32 scs; /*System control and status register c1a0*/ + u32 irctrim; /*IRC trim register c1a4*/ + u32 pclksel0; /*Peripheral clock selection register 0 c1a8*/ + u32 pclksel1; /*Peripheral clock selection register 1 c1ac*/ + u8 notused8[0x3e50]; +} sys_con_2468_t; + + +typedef struct mac_2468 { + u32 mac1; /* MAC configuration register 1 */ + u32 mac2; /* MAC configuration register 2 */ + u32 ipgt; /* Back-to-back Inter-Packet-Gap register */ + u32 ipgr; /* Non Back-to-back Inter-Packet-Gap register */ + u32 clrt; /* Collision window/Retry register */ + u32 maxf; /* Maximum frame register */ + u32 supp; /* PHY support register */ + u32 test; /* Test register */ + u32 mcfg; /* MII mgmt Configuration register */ + u32 mcmd; /* MII mgmt Command register */ + u32 madr; /* MII mgmt Address register */ + u32 mwtd; /* MII mgmt Write data register */ + u32 mrdd; /* MII mgmt Read data register */ + u32 mind; /* MII mgmt Indicators register */ + u8 reserved1[0x8]; + u32 sa0; /* Station Address 0 register */ + u32 sa1; /* Station Address 1 register */ + u32 sa2; /* Station Address 2 register */ + u8 reserved2[0xb4]; + u32 command; /* Command register */ + u32 status; /* Status register */ + u32 rxdescriptor; /* Receive descriptor base address register */ + u32 rxstatus; /* Receive status base address register */ + u32 rxdescriptornumber; /* Receive number of descriptors register */ + u32 rxproduceindex; /* Receive produce index register */ + u32 rxconsumeindex; /* Receive consume index register */ + u32 txdescriptor; /* Transmit descriptor base address register */ + u32 txstatus; /* Transmit status base address register */ + u32 txdescriptornumber; /* Transmit number of descriptors register */ + u32 txproduceindex; /* Transmit produce index register */ + u32 txconsumeindex; /* Transmite consume index register */ + u8 reserved3[0x28]; + u32 tsv0; /* Transmit status vector 0 register */ + u32 tsv1; /* Transmit status vector 1 register */ + u32 rsv; /* Receive status vector register */ + u8 reserved4[0xc]; + u32 flowcontrolcounter; /*Flow control counter register */ + u32 flowcontrolstatus; /* Flow control status register */ + u8 reserved5[0x88]; + u32 rxfilterctrl; /* Receive filter control register */ + u32 rxfilterwolstatus; /* Receive filter WoL status register */ + u32 rxfilterwolclear; /* Receive filter WoL clear register */ + u8 reserved6[0x4]; + u32 hashfilterL; /* Hash filter LSBs register */ + u32 hashfilterH; /* Hash filter MSBs register */ + u8 reserved7[0xdc8]; + u32 intstatus; /* Interrupt status register */ + u32 intenable; /* Interrupt enable register */ + u32 intclear; /* Interrupt clear register */ + u32 intset; /* Interrupt set register */ + u8 reserved8[0x4]; + u32 powerdown; /* Powerdown register */ + u8 notused[0x3008]; +} mac_2468_t; + +typedef struct gpdma__2468 { + u8 fixme[0x4000]; +} gpdma_2468_t; + +typedef struct ext_mem_2468 { + u32 control; /*Controls operation of the memory controller*/ + u32 status; /*Provides EMC status*/ + u32 config; /*Configures operation of the memorycontroller*/ + u8 notused1[0x14]; + u32 dyncontrol; /*Controls dynamic memory operation*/ + u32 dynrefresh; /*Configures dynamic refresh operation*/ + u32 dynreadconfig; /*Configures the dynamic memory read strategy*/ + u32 notused2; + u32 dynrp; /*Selects the precharge command period*/ + u32 dynras; /*Selects the active to precharge command period*/ + u32 dynsrex; /*Selects the self-refresh time*/ + u32 dynapr; /*Selects the last-data-out to active command time*/ + u32 dyndal; /*Selects the data-in to active command time*/ + u32 dynwr; /*Selects the write recovery time*/ + u32 dynrc; /*Selects the active to active command period*/ + u32 dynrfc; /*Selects the auto-refresh period*/ + u32 dynxsr; /*Selects the exit self-refresh to active command time*/ + u32 dynrrd; /*Selects the active ank A to active bank B latency*/ + u32 dynmrd; /*Selects the load mode register to active command time*/ + u8 notused3[0xa4]; + u32 dynconfig0; /*Configuration information for dyn memory CS 0*/ + u32 dynrascas0; /*Selects the RAs and CAS latency fos CS 0*/ + u8 notused4[0x18]; + u32 dynconfig1; /*Configuration information for dyn memory CS 1*/ + u32 dynrascas1; /*Selects the RAs and CAS latency fos CS 1*/ + u8 notused5[0x18]; + u32 dynconfig2; /*Configuration information for dyn memory CS 2*/ + u32 dynrascas2; /*Selects the RAs and CAS latency fos CS 2*/ + u8 notused6[0x18]; + u32 dynconfig3; /*Configuration information for dyn memory CS 3*/ + u32 dynrascas3; /*Selects the RAs and CAS latency fos CS 3*/ + u8 notused7[0x98]; + u32 statconfig0; /*Memory configuration for static CS 0*/ + u32 statwaitwen0; /*Selects the delay from CS 0 to WE*/ + u32 statwaitoen0; /*Selects the delay from CS 0 OE*/ + u32 statwaitrd0; /*Selects the delay from CS 0 to a read access*/ + u32 statwaitpage0; /*Selects the delay for async page mode for CS 0*/ + u32 statwaitwr0; /*Selects the delay from CS 0 to a write access*/ + u32 statwaitturn0; /*Selects the # of bus turnaround cycles for CS 0*/ + u8 notused8[0x4]; + u32 statconfig1; /*Memory configuration for static CS 1*/ + u32 statwaitwen1; /*Selects the delay from CS 1 to WE*/ + u32 statwaitoen1; /*Selects the delay from CS 1 OE*/ + u32 statwaitrd1; /*Selects the delay from CS 1 to a read access*/ + u32 statwaitpage1; /*Selects the delay for async page mode for CS 1*/ + u32 statwaitwr1; /*Selects the delay from CS 1 to a write access*/ + u32 statwaitturn1; /*Selects the # of bus turnaround cycles for CS 1*/ + u8 notused9[0x4]; + u32 statconfig2; /*Memory configuration for static CS 2*/ + u32 statwaitwen2; /*Selects the delay from CS 2 to WE*/ + u32 statwaitoen2; /*Selects the delay from CS 2 OE*/ + u32 statwaitrd2; /*Selects the delay from CS 2 to a read access*/ + u32 statwaitpage2; /*Selects the delay for async page mode for CS 2*/ + u32 statwaitwr2; /*Selects the delay from CS 2 to a write access*/ + u32 statwaitturn2; /*Selects the # of bus turnaround cycles for CS 2*/ + u8 notused10[0x4]; + u32 statconfig3; /*Memory configuration for static CS 3*/ + u32 satwaitwen3; /*Selects the delay from CS 3 to WE*/ + u32 statwaitoen3; /*Selects the delay from CS 3 OE*/ + u32 statwaitrd3; /*Selects the delay from CS 3 to a read access*/ + u32 statwaitpage3; /*Selects the delay for async page mode for CS 3*/ + u32 statwaitwr3; /*Selects the delay from CS 3 to a write access*/ + u32 statwaitturn3; /*Selects the # of bus turnaround cycles for CS 3*/ + u8 notused11[0x604]; + u32 extwait; + u8 notused12[0x377c]; +} ext_mem_2468_t; + +typedef struct usb_2468 { + u8 fixme[0x4000]; +} usb_2468_t; + +typedef struct lcd_2468 { + u8 fixme[0x4000]; +} lcd_2468_t; + +typedef struct vic_2468 { + u32 vicirqstat; /*IRQ status register */ + u32 vicfiqstat; /*FIQ status register */ + u32 vicrawintr; /*Raw interrupt status register */ + u32 vicintselect; /*Interrupt select register */ + u32 vicintenable; /*Interrupt enable register */ + u32 vicinenclr; /*Interrupt enable clear register */ + u32 vicsoftint; /*Software interrupt register */ + u32 vicsoftintclr; /*Software interrupt clear register */ + u32 vicprotect; /*Protection enable register */ + u32 vicswpriomask; /*Software Priority Mask Register */ + u8 notused1[0xd8]; + u32 vicvectaddr0; /*Vector address register */ + u32 vicvectaddr1; + u32 vicvectaddr2; + u32 vicvectaddr3; + u32 vicvectaddr4; + u32 vicvectaddr5; + u32 vicvectaddr6; + u32 vicvectaddr7; + u32 vicvectaddr8; + u32 vicvectaddr9; + u32 vicvectaddr10; + u32 vicvectaddr11; + u32 vicvectaddr12; + u32 vicvectaddr13; + u32 vicvectaddr14; + u32 vicvectaddr15; + u32 vicvectaddr16; + u32 vicvectaddr17; + u32 vicvectaddr18; + u32 vicvectaddr19; + u32 vicvectaddr20; + u32 vicvectaddr21; + u32 vicvectaddr22; + u32 vicvectaddr23; + u32 vicvectaddr24; + u32 vicvectaddr25; + u32 vicvectaddr26; + u32 vicvectaddr27; + u32 vicvectaddr28; + u32 vicvectaddr29; + u32 vicvectaddr30; + u32 vicvectaddr31; + u8 notused2[0x7f]; + u32 vicvectprio0; /*Vector priority register */ + u32 vicvectprio1; + u32 vicvectprio2; + u32 vicvectprio3; + u32 vicvectprio4; + u32 vicvectprio5; + u32 vicvectprio6; + u32 vicvectprio7; + u32 vicvectprio8; + u32 vicvectprio9; + u32 vicvectprio10; + u32 vicvectprio11; + u32 vicvectprio12; + u32 vicvectprio13; + u32 vicvectprio14; + u32 vicvectprio15; + u32 vicvectprio16; + u32 vicvectprio17; + u32 vicvectprio18; + u32 vicvectprio19; + u32 vicvectprio20; + u32 vicvectprio21; + u32 vicvectprio22; + u32 vicvectprio23; + u32 vicvectprio24; + u32 vicvectprio25; + u32 vicvectprio26; + u32 vicvectprio27; + u32 vicvectprio28; + u32 vicvectprio29; + u32 vicvectprio30; + u32 vicvectprio31; + u8 notused3[0xc7f]; + u32 vicaddr; /*Vector address register for active interrupt*/ +} vic_2468_t; + +typedef struct fastio_2468 { + u32 fio0dir; /*Fast IO 0 port direction register*/ + u8 notused1[0xc]; + u32 fio0mask; /*Fast IO 0 mask register*/ + u32 fio0pin; /*Fast IO 0 pin value register*/ + u32 fio0set; /*Fast IO 0 output set register*/ + u32 fio0clr; /*Fast IO 0 output clear register*/ + u32 fio1dir; /*Fast IO 1 port direction register*/ + u8 notused2[0xc]; + u32 fio1mask; /*Fast IO 1 mask register*/ + u32 fio1pin; /*Fast IO 1 pin value register*/ + u32 fio1set; /*Fast IO 1 output set register*/ + u32 fio1clr; /*Fast IO 1 output clear register*/ + u32 fio2dir; /*Fast IO 2 port direction register*/ + u8 notused3[0xc]; + u32 fio2mask; /*Fast IO 2 mask register*/ + u32 fio2pin; /*Fast IO 2 pin value register*/ + u32 fio2set; /*Fast IO 2 output set register*/ + u32 fio2clr; /*Fast IO 2 output clear register*/ + u32 fio3dir; /*Fast IO 3 port direction register*/ + u8 notused4[0xc]; + u32 fio3mask; /*Fast IO 3 mask register*/ + u32 fio3pin; /*Fast IO 3 pin value register*/ + u32 fio3set; /*Fast IO 3 output set register*/ + u32 fio3clr; /*Fast IO 3 output clear register*/ + u32 fio4dir; /*Fast IO 4 port direction register*/ + u8 notused5[0xc]; + u32 fio4mask; /*Fast IO 4 mask register*/ + u32 fio4pin; /*Fast IO 4 pin value register*/ + u32 fio4set; /*Fast IO 4 output set register*/ + u32 fio4clr; /*Fast IO 4 output clear register*/ +} fastio_2468_t; + +typedef struct apb_2468 { /*Peripheral bus memory layout*/ + watchdog2468_t watchdog; + timer_2468_t timer0; + timer_2468_t timer1; + uart_2468_t uart0; + uart1_2468_t uart1; + pwm0_2468_t pwm0; + pwm1_2468_t pwm1; + i2c0_2468_t i2c0; + spi_2468_t spi; + rtc_2468_t rtc; + gpio_2468_t gpio; + pin_connect_2468_t pin_connect; + ssp1_2468_t ssp1; + adc_2468_t adc; + can_accept_ram_2468_t can_accept_ram; + can_accept_filter_2468_t can_accept_filter; + can_common_2468_t can_comon; + can1_2468_t can1; + can2_2468_t can2; + u8 not_used1[0x10000]; + i2c1_2468_t i2c1; + u8 notused2[0x8000]; + ssp0_2468_t ssp0; + dac_2468_t dac; + timer_2468_t timer2; + timer_2468_t timer3; + uart_2468_t uart2; + uart_2468_t uart3; + i2c2_2468_t i2c2; + batt_ram_2468_t batt_ram; + i2s_2468_t i2s; + mmc_2468_t mmc; + u8 not_used3[0x16c000]; + sys_con_2468_t sys_con; +} apb_2468_t; + +typedef struct ahb_2468 { /*High-speed bus memory layout*/ + mac_2468_t mac; + gpdma_2468_t gpdma; + ext_mem_2468_t ext_mem; + usb_2468_t usb; + lcd_2468_t lcd; + u8 notused1[0x1eb000]; + vic_2468_t vic; +} ahb_2468_t; + +typedef struct immap { /*LPC24xx memory layout*/ + apb_2468_t apb; /*Peripheral bus*/ + u8 res1[0x1fc00000]; + ahb_2468_t ahb; /*High-speed bus*/ +} immap_t; + +#endif diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index b76fd8e..d462d20 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -24,4 +24,8 @@ /* Relocation to SDRAM works on all ARM boards */ #define CONFIG_RELOC_FIXUP_WORKS +#if defined(CONFIG_LPC2292) || defined(CONFIG_LPC2468) +#define CONFIG_LPC2000 +#endif + #endif diff --git a/arch/arm/lib/eabi_compat.c b/arch/arm/lib/eabi_compat.c index 86eacf1..eb3e26d 100644 --- a/arch/arm/lib/eabi_compat.c +++ b/arch/arm/lib/eabi_compat.c @@ -16,3 +16,8 @@ int raise (int signum) printf("raise: Signal # %d caught\n", signum); return 0; } + +/* Dummy function to avoid linker complaints */ +void __aeabi_unwind_cpp_pr0(void) +{ +}; diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index c731bfb..05fd6c9 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -43,6 +43,7 @@ COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o COBJS-$(CONFIG_IXP_SERIAL) += serial_ixp.o COBJS-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o COBJS-$(CONFIG_LPC2292_SERIAL) += serial_lpc2292.o +COBJS-$(CONFIG_LPC2468_SERIAL) += serial_lpc2468.o COBJS-$(CONFIG_LH7A40X_SERIAL) += serial_lh7a40x.o COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o COBJS-$(CONFIG_MXC_UART) += serial_mxc.o diff --git a/drivers/serial/serial_lpc2468.c b/drivers/serial/serial_lpc2468.c new file mode 100644 index 0000000..4b8f241 --- /dev/null +++ b/drivers/serial/serial_lpc2468.c @@ -0,0 +1,119 @@ +/* + * (C) Copyright 2002-2004 + * Wolfgang Denk, DENX Software Engineering, <w...@denx.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroe...@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <a...@sysgo.de> + * + * Copyright (C) 1999 2000 2001 Erik Mouw (j.a.k.m...@its.tudelft.nl) + * + * 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 <asm/arch/immap.h> +#include <asm/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +void serial_setbrg (void) +{ + unsigned short divisor; + uart_2468_t *uart0=&(((immap_t *)CONFIG_SYS_IMMAP)->apb.uart0); + + switch (gd->baudrate) { + case 1200: + case 9600: + case 19200: + case 38400: + case 57600: + case 115200: + divisor = CFG_SYS_CLK_FREQ / (gd->baudrate * 16); + break; + default: + hang (); + break; + } + + /* init serial UART0 */ + writeb (0, &(uart0->iir_fcr)); /* Disable RX and TX FIFOs */ + writeb (0, &(uart0->lcr)); + writeb (0, &(uart0->ier_dlm)); + writeb (0x80, &(uart0->lcr)); /* DLAB=1 */ + writeb ((unsigned char)(divisor & 0x00FF), &(uart0->rbr_thr_dll)); + writeb ((unsigned char)(divisor >> 8),&(uart0->ier_dlm)); + writeb (0x03, &(uart0->lcr)); /* 8N1, DLAB=0 */ + writeb (0x7, &(uart0->iir_fcr)); /* Enable RX and TX FIFOs */ +} + +int serial_init (void) +{ + unsigned long pinsel0; + pin_connect_2468_t *pin_connect= + &(((immap_t *)CONFIG_SYS_IMMAP)->apb.pin_connect); + + /*enable uart #0 pins in GPIO (P0.2 = TxD0, P0.3 = RxD0) */ + pinsel0 = readl (&(pin_connect->pinsel0)); + pinsel0 &= ~(0x000000f0); + pinsel0 |= 0x00000050; + writel (pinsel0, &(pin_connect->pinsel0)); + + serial_setbrg (); + + return (0); +} + +void serial_putc (const char c) +{ + uart_2468_t *uart0=&(((immap_t *)CONFIG_SYS_IMMAP)->apb.uart0); + + if (c == '\n') { + /* Wait for empty U0THR */ + while ((readb (&(uart0->lsr)) & (1 << 5)) == 0) ; + writeb ('\r', &(uart0->rbr_thr_dll)); + } + /* Wait for empty U0THR */ + while ((readb (&(uart0->lsr)) & (1 << 5)) == 0) ; + writeb (c, &(uart0->rbr_thr_dll)); +} + +int serial_getc (void) +{ + uart_2468_t *uart0=&(((immap_t *)CONFIG_SYS_IMMAP)->apb.uart0); + + while ((readb (&(uart0->lsr)) & 1) == 0) ; + return readb (&(uart0->rbr_thr_dll)); +} + +void serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} + +/* Test if there is a byte to read */ +int serial_tstc (void) +{ + uart_2468_t *uart0=&(((immap_t *)CONFIG_SYS_IMMAP)->apb.uart0); + + return (readb (&(uart0->lsr)) & 1); +} diff --git a/include/flash.h b/include/flash.h index 8feca1b..dde60e9 100644 --- a/include/flash.h +++ b/include/flash.h @@ -345,6 +345,7 @@ extern flash_info_t *flash_get_info(ulong base); #define TOSH_ID_FVT160 0xC2 /* TC58FVT160 ID (16 M, top ) */ #define TOSH_ID_FVB160 0x43 /* TC58FVT160 ID (16 M, bottom ) */ #define PHILIPS_LPC2292 0x0401FF13 /* LPC2292 internal FLASH */ +#define PHILIPS_LPC2468 0x0603FF35 /* LPC2468 internal flash */ /*----------------------------------------------------------------------- * Internal FLASH identification codes -- 1.7.0.4 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot