diff options
| -rwxr-xr-x | MAKEALL | 2 | ||||
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | board/lpc2292sodimm/Makefile | 58 | ||||
| -rw-r--r-- | board/lpc2292sodimm/config.mk | 31 | ||||
| -rw-r--r-- | board/lpc2292sodimm/eth.c | 884 | ||||
| -rw-r--r-- | board/lpc2292sodimm/flash.c | 477 | ||||
| -rw-r--r-- | board/lpc2292sodimm/iap_entry.S | 7 | ||||
| -rw-r--r-- | board/lpc2292sodimm/lowlevel_init.S | 87 | ||||
| -rw-r--r-- | board/lpc2292sodimm/lpc2292sodimm.c | 62 | ||||
| -rw-r--r-- | board/lpc2292sodimm/mmc.c | 154 | ||||
| -rw-r--r-- | board/lpc2292sodimm/mmc_hw.c | 233 | ||||
| -rw-r--r-- | board/lpc2292sodimm/mmc_hw.h | 29 | ||||
| -rw-r--r-- | board/lpc2292sodimm/spi.c | 40 | ||||
| -rw-r--r-- | board/lpc2292sodimm/spi.h | 84 | ||||
| -rw-r--r-- | board/lpc2292sodimm/u-boot.lds | 55 | ||||
| -rw-r--r-- | cpu/arm720t/cpu.c | 3 | ||||
| -rw-r--r-- | cpu/arm720t/interrupts.c | 27 | ||||
| -rw-r--r-- | cpu/arm720t/serial.c | 78 | ||||
| -rw-r--r-- | cpu/arm720t/start.S | 69 | ||||
| -rw-r--r-- | include/asm-arm/arch-arm720t/hardware.h | 2 | ||||
| -rw-r--r-- | include/asm-arm/arch-arm720t/lpc2292_registers.h | 225 | ||||
| -rw-r--r-- | include/asm-arm/arch-arm720t/mmc.h | 22 | ||||
| -rw-r--r-- | include/configs/lpc2292sodimm.h | 158 | ||||
| -rw-r--r-- | include/flash.h | 1 | 
24 files changed, 2787 insertions, 4 deletions
| @@ -181,7 +181,7 @@ LIST_SA="assabet dnp1110 gcplus lart shannon"  LIST_ARM7="	\  	armadillo	B2		ep7312		evb4510		\  	impa7		integratorap	ap7		ap720t		\ -	modnet50							\ +	lpc2292sodimm	modnet50					\  "  ######################################################################### @@ -2029,6 +2029,9 @@ modnet50_config :	unconfig  evb4510_config :	unconfig  	@$(MKCONFIG) $(@:_config=) arm arm720t evb4510 +lpc2292sodimm_config:	unconfig +	@$(MKCONFIG) $(@:_config=) arm arm720t lpc2292sodimm +  #########################################################################  ## XScale Systems  ######################################################################### diff --git a/board/lpc2292sodimm/Makefile b/board/lpc2292sodimm/Makefile new file mode 100644 index 000000000..5a30198e2 --- /dev/null +++ b/board/lpc2292sodimm/Makefile @@ -0,0 +1,58 @@ +# +# (C) Copyright 2002 +# Sysgo Real-Time Solutions, GmbH <www.elinos.com> +# Marius Groeger <mgroeger@sysgo.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	= lib$(BOARD).a + +OBJS	:= lpc2292sodimm.o flash.o mmc.o spi.o mmc_hw.o eth.o +SOBJS	:= lowlevel_init.o iap_entry.o + +$(LIB):	$(OBJS) $(SOBJS) +	$(AR) crv $@ $(OBJS) $(SOBJS) + +# this MUST be compiled as thumb code! +iap_entry.o: +	arm-linux-gcc  -D__ASSEMBLY__ -g  -Os   -fno-strict-aliasing  \ +	-fno-common -ffixed-r8 -msoft-float  -D__KERNEL__ \ +	-DTEXT_BASE=0x81500000  -I/home/garyj/proj/LPC/u-boot/include \ +	-fno-builtin -ffreestanding -nostdinc -isystem \ +	/opt/eldk/arm/usr/bin/../lib/gcc/arm-linux/4.0.0/include -pipe  \ +	-DCONFIG_ARM -D__ARM__ -march=armv4t -mtune=arm7tdmi -mabi=apcs-gnu \ +	-c -o iap_entry.o iap_entry.S + +clean: +	rm -f $(SOBJS) $(OBJS) + +distclean:	clean +	rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) +		$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/board/lpc2292sodimm/config.mk b/board/lpc2292sodimm/config.mk new file mode 100644 index 000000000..4146dac9c --- /dev/null +++ b/board/lpc2292sodimm/config.mk @@ -0,0 +1,31 @@ +# +# (C) Copyright 2000 +# Sysgo Real-Time Solutions, GmbH <www.elinos.com> +# Marius Groeger <mgroeger@sysgo.de> +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, wd@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 +# + +#address where u-boot will be relocated +#TEXT_BASE = 0x0 +TEXT_BASE = 0x81500000 + diff --git a/board/lpc2292sodimm/eth.c b/board/lpc2292sodimm/eth.c new file mode 100644 index 000000000..14bec19ce --- /dev/null +++ b/board/lpc2292sodimm/eth.c @@ -0,0 +1,884 @@ +/* + * 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 <config.h> +#include <common.h> +#include <net.h> +#include <asm/arch/hardware.h> +#include "spi.h" + +/* + * Control Registers in Bank 0 + */ + +#define CTL_REG_ERDPTL   0x00 +#define CTL_REG_ERDPTH   0x01 +#define CTL_REG_EWRPTL   0x02 +#define CTL_REG_EWRPTH   0x03 +#define CTL_REG_ETXSTL   0x04 +#define CTL_REG_ETXSTH   0x05 +#define CTL_REG_ETXNDL   0x06 +#define CTL_REG_ETXNDH   0x07 +#define CTL_REG_ERXSTL   0x08 +#define CTL_REG_ERXSTH   0x09 +#define CTL_REG_ERXNDL   0x0A +#define CTL_REG_ERXNDA   0x0B +#define CTL_REG_ERXRDPTL 0x0C +#define CTL_REG_ERXRDPTH 0x0D +#define CTL_REG_ERXWRPTL 0x0E +#define CTL_REG_ERXWRPTH 0x0F +#define CTL_REG_EDMASTL  0x10 +#define CTL_REG_EDMASTH  0x11 +#define CTL_REG_EDMANDL  0x12 +#define CTL_REG_EDMANDH  0x13 +#define CTL_REG_EDMADSTL 0x14 +#define CTL_REG_EDMADSTH 0x15 +#define CTL_REG_EDMACSL  0x16 +#define CTL_REG_EDMACSH  0x17 +/* these are common in all banks */ +#define CTL_REG_EIE      0x1B +#define CTL_REG_EIR      0x1C +#define CTL_REG_ESTAT    0x1D +#define CTL_REG_ECON2    0x1E +#define CTL_REG_ECON1    0x1F + +/* + * Control Registers in Bank 1 + */ + +#define CTL_REG_EHT0    0x00 +#define CTL_REG_EHT1    0x01 +#define CTL_REG_EHT2    0x02 +#define CTL_REG_EHT3    0x03 +#define CTL_REG_EHT4    0x04 +#define CTL_REG_EHT5    0x05 +#define CTL_REG_EHT6    0x06 +#define CTL_REG_EHT7    0x07 +#define CTL_REG_EPMM0   0x08 +#define CTL_REG_EPMM1   0x09 +#define CTL_REG_EPMM2   0x0A +#define CTL_REG_EPMM3   0x0B +#define CTL_REG_EPMM4   0x0C +#define CTL_REG_EPMM5   0x0D +#define CTL_REG_EPMM6   0x0E +#define CTL_REG_EPMM7   0x0F +#define CTL_REG_EPMCSL  0x10 +#define CTL_REG_EPMCSH  0x11 +#define CTL_REG_EPMOL   0x14 +#define CTL_REG_EPMOH   0x15 +#define CTL_REG_EWOLIE  0x16 +#define CTL_REG_EWOLIR  0x17 +#define CTL_REG_ERXFCON 0x18 +#define CTL_REG_EPKTCNT 0x19 + +/* + * Control Registers in Bank 2 + */ + +#define CTL_REG_MACON1   0x00 +#define CTL_REG_MACON2   0x01 +#define CTL_REG_MACON3   0x02 +#define CTL_REG_MACON4   0x03 +#define CTL_REG_MABBIPG  0x04 +#define CTL_REG_MAIPGL   0x06 +#define CTL_REG_MAIPGH   0x07 +#define CTL_REG_MACLCON1 0x08 +#define CTL_REG_MACLCON2 0x09 +#define CTL_REG_MAMXFLL  0x0A +#define CTL_REG_MAMXFLH  0x0B +#define CTL_REG_MAPHSUP  0x0D +#define CTL_REG_MICON    0x11 +#define CTL_REG_MICMD    0x12 +#define CTL_REG_MIREGADR 0x14 +#define CTL_REG_MIWRL    0x16 +#define CTL_REG_MIWRH    0x17 +#define CTL_REG_MIRDL    0x18 +#define CTL_REG_MIRDH    0x19 + +/* + * Control Registers in Bank 3 + */ + +#define CTL_REG_MAADR1  0x00 +#define CTL_REG_MAADR0  0x01 +#define CTL_REG_MAADR3  0x02 +#define CTL_REG_MAADR2  0x03 +#define CTL_REG_MAADR5  0x04 +#define CTL_REG_MAADR4  0x05 +#define CTL_REG_EBSTSD  0x06 +#define CTL_REG_EBSTCON 0x07 +#define CTL_REG_EBSTCSL 0x08 +#define CTL_REG_EBSTCSH 0x09 +#define CTL_REG_MISTAT  0x0A +#define CTL_REG_EREVID  0x12 +#define CTL_REG_ECOCON  0x15 +#define CTL_REG_EFLOCON 0x17 +#define CTL_REG_EPAUSL  0x18 +#define CTL_REG_EPAUSH  0x19 + + +/* + * PHY Register + */ + +#define PHY_REG_PHID1 0x02 +#define PHY_REG_PHID2 0x03 + + +/* + * Receive Filter Register (ERXFCON) bits + */ + +#define ENC_RFR_UCEN  0x80 +#define ENC_RFR_ANDOR 0x40 +#define ENC_RFR_CRCEN 0x20 +#define ENC_RFR_PMEN  0x10 +#define ENC_RFR_MPEN  0x08 +#define ENC_RFR_HTEN  0x04 +#define ENC_RFR_MCEN  0x02 +#define ENC_RFR_BCEN  0x01 + +/* + * ECON1 Register Bits + */ + +#define ENC_ECON1_TXRST  0x80 +#define ENC_ECON1_RXRST  0x40 +#define ENC_ECON1_DMAST  0x20 +#define ENC_ECON1_CSUMEN 0x10 +#define ENC_ECON1_TXRTS  0x08 +#define ENC_ECON1_RXEN   0x04 +#define ENC_ECON1_BSEL1  0x02 +#define ENC_ECON1_BSEL0  0x01 + +/* + * ECON2 Register Bits + */ +#define ENC_ECON2_AUTOINC 0x80 +#define ENC_ECON2_PKTDEC  0x40 +#define ENC_ECON2_PWRSV   0x20 +#define ENC_ECON2_VRPS    0x08 + +/* + * EIR Register Bits + */ +#define ENC_EIR_PKTIF  0x40 +#define ENC_EIR_DMAIF  0x20 +#define ENC_EIR_LINKIF 0x10 +#define ENC_EIR_TXIF   0x08 +#define ENC_EIR_WOLIF  0x04 +#define ENC_EIR_TXERIF 0x02 +#define ENC_EIR_RXERIF 0x01 + +/* + * ESTAT Register Bits + */ + +#define ENC_ESTAT_INT     0x80 +#define ENC_ESTAT_LATECOL 0x10 +#define ENC_ESTAT_RXBUSY  0x04 +#define ENC_ESTAT_TXABRT  0x02 +#define ENC_ESTAT_CLKRDY  0x01 + +/* + * EIE Register Bits + */ + +#define ENC_EIE_INTIE  0x80 +#define ENC_EIE_PKTIE  0x40 +#define ENC_EIE_DMAIE  0x20 +#define ENC_EIE_LINKIE 0x10 +#define ENC_EIE_TXIE   0x08 +#define ENC_EIE_WOLIE  0x04 +#define ENC_EIE_TXERIE 0x02 +#define ENC_EIE_RXERIE 0x01 + +/* + * MACON1 Register Bits + */ +#define ENC_MACON1_LOOPBK  0x10 +#define ENC_MACON1_TXPAUS  0x08 +#define ENC_MACON1_RXPAUS  0x04 +#define ENC_MACON1_PASSALL 0x02 +#define ENC_MACON1_MARXEN  0x01 + + +/* + * MACON2 Register Bits + */ +#define ENC_MACON2_MARST   0x80 +#define ENC_MACON2_RNDRST  0x40 +#define ENC_MACON2_MARXRST 0x08 +#define ENC_MACON2_RFUNRST 0x04 +#define ENC_MACON2_MATXRST 0x02 +#define ENC_MACON2_TFUNRST 0x01 + +/* + * MACON3 Register Bits + */ +#define ENC_MACON3_PADCFG2 0x80 +#define ENC_MACON3_PADCFG1 0x40 +#define ENC_MACON3_PADCFG0 0x20 +#define ENC_MACON3_TXCRCEN 0x10 +#define ENC_MACON3_PHDRLEN 0x08 +#define ENC_MACON3_HFRMEN  0x04 +#define ENC_MACON3_FRMLNEN 0x02 +#define ENC_MACON3_FULDPX  0x01 + +/* + * MICMD Register Bits + */ +#define ENC_MICMD_MIISCAN 0x02 +#define ENC_MICMD_MIIRD   0x01 + +/* + * MISTAT Register Bits + */ +#define ENC_MISTAT_NVALID 0x04 +#define ENC_MISTAT_SCAN   0x02 +#define ENC_MISTAT_BUSY   0x01 + +/* + * PHID1 and PHID2 values + */ +#define ENC_PHID1_VALUE 0x0083 +#define ENC_PHID2_VALUE 0x1400 +#define ENC_PHID2_MASK  0xFC00 + + +#define ENC_SPI_SLAVE_CS 0x00010000  /* pin P1.16 */ +#define ENC_RESET        0x00020000  /* pin P1.17 */ + +#define FAILSAFE_VALUE 5000 + +/* + * Controller memory layout: + * + * 0x0000 - 0x17ff  6k bytes receive buffer + * 0x1800 - 0x1fff  2k bytes transmit buffer + */ +/* Use the lower memory for receiver buffer. See errata pt. 5 */ +#define ENC_RX_BUF_START 0x0000 +#define ENC_TX_BUF_START 0x1800 + +/* maximum frame length */ +#define ENC_MAX_FRM_LEN 1518 + +#define enc_enable() PUT32(IO1CLR, ENC_SPI_SLAVE_CS) +#define enc_disable() PUT32(IO1SET, ENC_SPI_SLAVE_CS) +#define enc_cfg_spi() spi_set_cfg(0, 0, 0); spi_set_clock(8);  + + +static unsigned char encReadReg(unsigned char regNo); +static void encWriteReg(unsigned char regNo, unsigned char data); +static void encWriteRegRetry(unsigned char regNo, unsigned char data, int c); +static void encReadBuff(unsigned short length, unsigned char *pBuff); +static void encWriteBuff(unsigned short length, unsigned char *pBuff); +static void encBitSet(unsigned char regNo, unsigned char data); +static void encBitClr(unsigned char regNo, unsigned char data); +static void encReset(void); +static void encInit(unsigned char *pEthAddr); +static unsigned short phyRead(unsigned char addr); +static void encPoll(void); +static void encRx(void); + +#define m_nic_read(reg) encReadReg(reg) +#define m_nic_write(reg, data) encWriteReg(reg, data) +#define m_nic_write_retry(reg, data, count) encWriteRegRetry(reg, data, count) +#define m_nic_read_data(len, buf) encReadBuff((len), (buf)) +#define m_nic_write_data(len, buf) encWriteBuff((len), (buf)) + +/* bit field set */ +#define m_nic_bfs(reg, data) encBitSet(reg, data) + +/* bit field clear */ +#define m_nic_bfc(reg, data) encBitClr(reg, data) + +static unsigned char bank = 0;  /* current bank in enc28j60 */ +static unsigned char next_pointer_lsb; +static unsigned char next_pointer_msb; + +static unsigned char buffer[ENC_MAX_FRM_LEN]; +static int rxResetCounter = 0; +#define RX_RESET_COUNTER 1000; + +/*----------------------------------------------------------------------------- + * Returns 0 when failes otherwize 1 + */ +int eth_init(bd_t *bis) +{ +	/* configure GPIO */ +	(*((volatile unsigned long *) IO1DIR)) |= ENC_SPI_SLAVE_CS; +	(*((volatile unsigned long *) IO1DIR)) |= ENC_RESET; + +	/* CS and RESET active low */ +	PUT32(IO1SET, ENC_SPI_SLAVE_CS); +	PUT32(IO1SET, ENC_RESET); + +	spi_init(); + +	/* initialize controller */ +	encReset(); +	encInit(bis->bi_enetaddr); + +	m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_RXEN); /* enable receive */   + +	return 0; +} + +int eth_send(volatile void *packet, int length) +{ +	/* check frame length, etc. */ +	/* TODO: */ + +	/* switch to bank 0 */ +	m_nic_bfc(CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));   + +	/* set EWRPT */ +	m_nic_write(CTL_REG_EWRPTL, (ENC_TX_BUF_START & 0xff)); +	m_nic_write(CTL_REG_EWRPTH, (ENC_TX_BUF_START >> 8)); + +	/* set ETXST */ +	m_nic_write(CTL_REG_ETXSTL, ENC_TX_BUF_START & 0xFF); +	m_nic_write(CTL_REG_ETXSTH, ENC_TX_BUF_START >> 8); + +	/* write packet */ +	m_nic_write_data(length, (unsigned char*)packet); + +	/* set ETXND */ +	m_nic_write(CTL_REG_ETXNDL, (length + ENC_TX_BUF_START) & 0xFF); +	m_nic_write(CTL_REG_ETXNDH, (length + ENC_TX_BUF_START) >> 8); + +	/* set ECON1.TXRTS */ +	m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_TXRTS); + +	return 0; +} + + +/***************************************************************************** + * This function resets the receiver only. This function may be called from + * interrupt-context. + */ +static void encReceiverReset(void) +{ +	unsigned char econ1; + +	econ1 = m_nic_read(CTL_REG_ECON1); +	if((econ1 & ENC_ECON1_RXRST) == 0) { +		m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_RXRST); +		rxResetCounter = RX_RESET_COUNTER; +	} +} + +/***************************************************************************** + * receiver reset timer + */ +static void encReceiverResetCallback(void) +{ +	m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_RXRST); +	m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_RXEN); /* enable receive */ +} + +/*----------------------------------------------------------------------------- + * Check for received packets. Call NetReceive for each packet. The return + * value is ignored by the caller. + */ +int eth_rx(void) +{ +	if(rxResetCounter > 0 && --rxResetCounter == 0) +	{ +		encReceiverResetCallback(); +	} + +	encPoll(); + +	return 0; +} + +void eth_halt(void) +{ +	m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_RXEN); /* disable receive */ +} + +/*****************************************************************************/ + +static void encPoll(void)  +{ +	unsigned char eir_reg; +	volatile unsigned char estat_reg; +	unsigned char pkt_cnt; + +	/* clear global interrupt enable bit in enc28j60 */ +	m_nic_bfc(CTL_REG_EIE, ENC_EIE_INTIE); +	estat_reg = m_nic_read(CTL_REG_ESTAT); + +	eir_reg = m_nic_read(CTL_REG_EIR); + +	if (eir_reg & ENC_EIR_TXIF){ +		/* clear TXIF bit in EIR */ +		m_nic_bfc(CTL_REG_EIR, ENC_EIR_TXIF); +	} + +	/* We have to use pktcnt and not pktif bit, see errata pt. 6 */ + +	/* move to bank 1 */ +	m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_BSEL1); +	m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL0); + +	/* read pktcnt */ +	pkt_cnt = m_nic_read(CTL_REG_EPKTCNT); + +	if (pkt_cnt > 0) { +		if ((eir_reg & ENC_EIR_PKTIF) == 0) { +		  /*printf("encPoll: pkt cnt > 0, but pktif not set\n"); */ +		} +		encRx(); +		/* clear PKTIF bit in EIR, this should not need to be done but it +		   seems like we get problems if we do not */ +		m_nic_bfc(CTL_REG_EIR, ENC_EIR_PKTIF); +	} + +	if (eir_reg & ENC_EIR_RXERIF) { +		printf("encPoll: rx error\n"); +		m_nic_bfc(CTL_REG_EIR, ENC_EIR_RXERIF); +	} +	if (eir_reg & ENC_EIR_TXERIF) { +		printf("encPoll: tx error\n"); +		m_nic_bfc(CTL_REG_EIR, ENC_EIR_TXERIF); +	} + +	/* set global interrupt enable bit in enc28j60 */ +	m_nic_bfs(CTL_REG_EIE, ENC_EIE_INTIE); +} + +static void encRx(void) +{ +	unsigned short pkt_len; +	unsigned short copy_len; +	unsigned short status; +	unsigned char eir_reg; +	unsigned char pkt_cnt = 0; + +	/* switch to bank 0 */ +	m_nic_bfc(CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0)); + +	m_nic_write(CTL_REG_ERDPTL, next_pointer_lsb); +	m_nic_write(CTL_REG_ERDPTH, next_pointer_msb); + +	do { +		m_nic_read_data(6, buffer); +		next_pointer_lsb = buffer[0]; +		next_pointer_msb = buffer[1]; +		pkt_len = buffer[2]; +		pkt_len |= (unsigned short)buffer[3] << 8; +		status = buffer[4]; +		status |= (unsigned short)buffer[5] << 8; + +		if (pkt_len <= ENC_MAX_FRM_LEN) { +			copy_len = pkt_len; +		} else { +			copy_len = 0; +			/*      p_priv->stats.rx_dropped++; */ +			/* we will drop this packet */ +		} + +		if ((status & (1L << 7)) == 0) { /* check Received Ok bit */ +			copy_len = 0; +			/*      p_priv->stats.rx_errors++; */ +		} + +		if (copy_len > 0) {  +			m_nic_read_data(copy_len, buffer); +		}     + +		/* advance read pointer to next pointer */ +		m_nic_write(CTL_REG_ERDPTL, next_pointer_lsb); +		m_nic_write(CTL_REG_ERDPTH, next_pointer_msb); + +		/* decrease packet counter */ +		m_nic_bfs(CTL_REG_ECON2, ENC_ECON2_PKTDEC); + +		/* move to bank 1 */ +		m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_BSEL1); +		m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL0); + +		/* read pktcnt */ +		pkt_cnt = m_nic_read(CTL_REG_EPKTCNT); + +		/* switch to bank 0 */ +		m_nic_bfc(CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));     + +		if (copy_len == 0) { +			eir_reg = m_nic_read(CTL_REG_EIR); +			encReceiverReset(); +			printf("eth_rx: copy_len=0\n"); +			continue; +		} + +		NetReceive((unsigned char *)buffer, pkt_len); + +		eir_reg = m_nic_read(CTL_REG_EIR); +	} while (pkt_cnt); /* Use EPKTCNT not EIR.PKTIF flag, see errata pt. 6 */ +	m_nic_write(CTL_REG_ERXRDPTL, next_pointer_lsb); +	m_nic_write(CTL_REG_ERXRDPTH, next_pointer_msb); +} + +static void encWriteReg(unsigned char regNo, unsigned char data) +{ +	spi_lock(); +	enc_cfg_spi(); +	enc_enable(); + +	spi_write(0x40 | regNo);  /* write in regNo */ +	spi_write(data); + +	enc_disable(); +	enc_enable(); + +	spi_write(0x1f);      /* write reg 0x1f */ + +	enc_disable(); +	spi_unlock(); +} + +static void encWriteRegRetry(unsigned char regNo, unsigned char data, int c) +{ +	unsigned char readback; +	int i; + +	spi_lock(); + +	for (i = 0; i < c; i++) { +		enc_cfg_spi(); +		enc_enable(); + +		spi_write(0x40 | regNo);    /* write in regNo */ +		spi_write(data); + +		enc_disable(); +		enc_enable(); + +		spi_write(0x1f);        /* write reg 0x1f */ + +		enc_disable(); + +		spi_unlock();       /* we must unlock spi first */ + +		readback = encReadReg(regNo); + +		spi_lock(); + +		if (readback == data) +			break; +	} +	spi_unlock(); + +	if (i == c) { +		printf("enc28j60: write reg %d failed\n", regNo); +	} +} + +static unsigned char encReadReg(unsigned char regNo) +{ +	unsigned char rxByte; + +	spi_lock(); +	enc_cfg_spi(); +	enc_enable(); + +	spi_write(0x1f);      /* read reg 0x1f */ + +	bank = spi_read() & 0x3; + +	enc_disable(); +	enc_enable(); + +	spi_write(regNo); +	rxByte = spi_read(); + +	/* check if MAC or MII register */ +	if (((bank == 2) && (regNo <= 0x1a)) || +			((bank == 3) && (regNo <= 0x05 || regNo == 0x0a))) { +		/* ignore first byte and read another byte */ +		rxByte = spi_read(); +	} + +	enc_disable(); +	spi_unlock(); + +	return rxByte; +} + +static void encReadBuff(unsigned short length, unsigned char *pBuff) +{ +	spi_lock(); +	enc_cfg_spi(); +	enc_enable(); + +	spi_write(0x20 | 0x1a);         /* read buffer memory */ + +	while(length--) { +		if(pBuff != NULL) +			*pBuff++ = spi_read(); +		else +			spi_write(0); +	} + +	enc_disable(); +	spi_unlock(); +} + +static void encWriteBuff(unsigned short length,  +             unsigned char *pBuff) +{ +	spi_lock(); +	enc_cfg_spi(); +	enc_enable(); + +	spi_write(0x60 | 0x1a);         /* write buffer memory */ + +	spi_write(0x00);      /* control byte */ + +	while(length--) +		spi_write(*pBuff++); + +	enc_disable(); +	spi_unlock(); +} + +static void encBitSet(unsigned char regNo, unsigned char data) +{ +	spi_lock(); +	enc_cfg_spi(); +	enc_enable(); + +	spi_write(0x80 | regNo);  /* bit field set */ +	spi_write(data); + +	enc_disable(); +	spi_unlock(); +} + +static void encBitClr(unsigned char regNo, unsigned char data) +{ +	spi_lock(); +	enc_cfg_spi(); +	enc_enable(); + +	spi_write(0xA0 | regNo);  /* bit field clear */ +	spi_write(data); + +	enc_disable(); +	spi_unlock(); +} + +static void encReset(void) +{ +	spi_lock(); +	enc_cfg_spi(); +	enc_enable(); + +	spi_write(0xff);      /* soft reset */ + +	enc_disable(); +	spi_unlock(); + +	/* sleep 1 ms. See errata pt. 2 */ +	udelay(1000); + +#if 0 +	(*((volatile unsigned long*)IO1CLR)) &= ENC_RESET; +	mdelay(5); +	(*((volatile unsigned long*)IO1SET)) &= ENC_RESET; +#endif +} + +static void encInit(unsigned char *pEthAddr) +{ +	unsigned short phid1 = 0; +	unsigned short phid2 = 0; + +	/* switch to bank 0 */ +	m_nic_bfc(CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0)); + +	/*  +	* Setup the buffer space. The reset values are valid for the +	* other pointers.  +	*/   +#if 0 +	/* We shall not write to ERXST, see errata pt. 5. Instead we  +	 have to make sure that ENC_RX_BUS_START is 0. */ +	m_nic_write_retry(CTL_REG_ERXSTL, (ENC_RX_BUF_START & 0xFF), 1); +	m_nic_write_retry(CTL_REG_ERXSTH, (ENC_RX_BUF_START >> 8), 1); +#endif +	m_nic_write_retry(CTL_REG_ERDPTL, (ENC_RX_BUF_START & 0xFF), 1); +	m_nic_write_retry(CTL_REG_ERDPTH, (ENC_RX_BUF_START >> 8), 1); + +	next_pointer_lsb = (ENC_RX_BUF_START & 0xFF); +	next_pointer_msb = (ENC_RX_BUF_START >> 8); + +	/* +	* For tracking purposes, the ERXRDPT registers should be programmed with  +	* the same value. This is the read pointer. +	*/ +	m_nic_write(CTL_REG_ERXRDPTL, (ENC_RX_BUF_START & 0xFF)); +	m_nic_write_retry(CTL_REG_ERXRDPTH, (ENC_RX_BUF_START >> 8), 1); + +	/* Setup receive filters. */ + +	/* move to bank 1 */ +	m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_BSEL1); +	m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL0); + +	/* OR-filtering, Unicast, CRC-check and broadcast */ +	m_nic_write_retry(CTL_REG_ERXFCON,  +			(ENC_RFR_UCEN|ENC_RFR_CRCEN|ENC_RFR_BCEN), 1); + +	/* Wait for Oscillator Start-up Timer (OST). */ +	while((m_nic_read(CTL_REG_ESTAT) & ENC_ESTAT_CLKRDY) == 0) { +		static int cnt = 0; +		if(cnt++ >= 1000){ +		  cnt = 0; +		} +	} + +	/* verify identification */ +	phid1 = phyRead(PHY_REG_PHID1); +	phid2 = phyRead(PHY_REG_PHID2); + +	if(phid1 != ENC_PHID1_VALUE  +	 || (phid2 & ENC_PHID2_MASK) != ENC_PHID2_VALUE) { +		printf("ERROR: failed to identify controller\n"); +		printf("phid1 = %x, phid2 = %x\n",  +			phid1, (phid2&ENC_PHID2_MASK)); +		printf("should be phid1 = %x, phid2 = %x\n",  +			ENC_PHID1_VALUE, ENC_PHID2_VALUE); +	} + +	/* +	* --- MAC Initialization --- +	*/ + +	/* Pull MAC out of Reset */ + +	/* switch to bank 2 */ +	m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_BSEL0); +	m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL1); +	/* clear MAC reset bits */ +	m_nic_write_retry(CTL_REG_MACON2, 0, 1); + +	/* enable MAC to receive frames */ +	m_nic_write_retry(CTL_REG_MACON1, ENC_MACON1_MARXEN, 10); + +	/* configure pad, tx-crc and duplex */  +	/* TODO maybe enable FRMLNEN */ +	m_nic_write_retry(CTL_REG_MACON3, (ENC_MACON3_PADCFG0|ENC_MACON3_TXCRCEN),  +			10); + +	/* set maximum frame length */ +	m_nic_write_retry(CTL_REG_MAMXFLL, (ENC_MAX_FRM_LEN & 0xff), 10); +	m_nic_write_retry(CTL_REG_MAMXFLH, (ENC_MAX_FRM_LEN >> 8), 10); + +	/*  +	* Set MAC back-to-back inter-packet gap. Recommended 0x12 for half duplex +	* and 0x15 for full duplex. +	*/ +	m_nic_write_retry(CTL_REG_MABBIPG, 0x12, 10); + +	/* Set (low byte) Non-Back-to_Back Inter-Packet Gap. Recommended 0x12 */ +	m_nic_write_retry(CTL_REG_MAIPGL, 0x12, 10); + +	/*  +	* Set (high byte) Non-Back-to_Back Inter-Packet Gap. Recommended  +	* 0x0c for half-duplex. Nothing for full-duplex +	*/ +	m_nic_write_retry(CTL_REG_MAIPGH, 0x0C, 10); + +	/* set MAC address */ + +	/* switch to bank 3 */ +	m_nic_bfs(CTL_REG_ECON1, (ENC_ECON1_BSEL0|ENC_ECON1_BSEL1)); + +	m_nic_write_retry(CTL_REG_MAADR0, pEthAddr[5], 1); +	m_nic_write_retry(CTL_REG_MAADR1, pEthAddr[4], 1); +	m_nic_write_retry(CTL_REG_MAADR2, pEthAddr[3], 1); +	m_nic_write_retry(CTL_REG_MAADR3, pEthAddr[2], 1); +	m_nic_write_retry(CTL_REG_MAADR4, pEthAddr[1], 1); +	m_nic_write_retry(CTL_REG_MAADR5, pEthAddr[0], 1); + +	/* +	* Receive settings +	*/ + +	/* auto-increment RX-pointer when reading a received packet */ +	m_nic_bfs(CTL_REG_ECON2, ENC_ECON2_AUTOINC); + +	/* enable interrupts */ +	m_nic_bfs(CTL_REG_EIE, ENC_EIE_PKTIE); +	m_nic_bfs(CTL_REG_EIE, ENC_EIE_TXIE); +	m_nic_bfs(CTL_REG_EIE, ENC_EIE_RXERIE); +	m_nic_bfs(CTL_REG_EIE, ENC_EIE_TXERIE); +	m_nic_bfs(CTL_REG_EIE, ENC_EIE_INTIE); +} + +/***************************************************************************** + * + * Description: + *    Read PHY registers. + * + *    NOTE! This function will change to Bank 2. + * + * Params: + *    [in] addr address of the register to read + * + * Returns: + *    The value in the register + */ +static unsigned short phyRead(unsigned char addr) +{ +	unsigned short ret = 0; + +	/* move to bank 2 */ +	m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_BSEL0); +	m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL1); + +	/* write address to MIREGADR */ +	m_nic_write(CTL_REG_MIREGADR, addr); + +	/* set MICMD.MIIRD */ +	m_nic_write(CTL_REG_MICMD, ENC_MICMD_MIIRD); + +	/* poll MISTAT.BUSY bit until operation is complete */ +	while((m_nic_read(CTL_REG_MISTAT) & ENC_MISTAT_BUSY) != 0) { +		static int cnt = 0; + +		if(cnt++ >= 1000) { +			/* GJ - this seems extremely dangerous! */ +			/* printf("#"); */ +			cnt = 0; +		} +	} + +	/* clear MICMD.MIIRD */ +	m_nic_write(CTL_REG_MICMD, 0); + +	ret  = (m_nic_read(CTL_REG_MIRDH) << 8); +	ret |= (m_nic_read(CTL_REG_MIRDL) & 0xFF); + +	return ret; +} diff --git a/board/lpc2292sodimm/flash.c b/board/lpc2292sodimm/flash.c new file mode 100644 index 000000000..dcef7ddba --- /dev/null +++ b/board/lpc2292sodimm/flash.c @@ -0,0 +1,477 @@ +/* + * (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/arch/hardware.h> + +/* IAP commands use 32 bytes at the top of CPU internal sram, we +   use 512 bytes below that */ +#define COPY_BUFFER_LOCATION 0x40003de0 + +#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 + +#define SST_BASEADDR 0x80000000 +#define SST_ADDR1 ((volatile ushort*)(SST_BASEADDR + (0x5555 << 1))) +#define SST_ADDR2 ((volatile ushort*)(SST_BASEADDR + (0x2AAA << 1))) + + +static unsigned long command[5]; +static unsigned long result[2]; + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + +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 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; +} + +/*----------------------------------------------------------------------- + * + */ +void write_word_sst(ulong addr, ushort data) +{ +	ushort tmp; + +	*SST_ADDR1 = 0x00AA; +	*SST_ADDR2 = 0x0055; +	*SST_ADDR1 = 0x00A0; +	*((volatile ushort*)addr) = data; +	/* do data polling */ +	do { +		tmp = *((volatile ushort*)addr); +	} while (tmp != data); +} + +/*----------------------------------------------------------------------- + */ + +ulong flash_init (void) +{ +	int j, k; +	ulong size = 0; +	ulong flashbase = 0; + +	flash_info[0].flash_id = (PHILIPS_LPC2292 & FLASH_VENDMASK); +	flash_info[0].size = 0x003E000;	/* 256 - 8 KB */ +	flash_info[0].sector_count = 17; +	memset (flash_info[0].protect, 0, 17); +	flashbase = 0x00000000; +	for (j = 0, k = 0; j < 8; j++, k++) { +		flash_info[0].start[k] = flashbase; +		flashbase += 0x00002000; +	} +	for (j = 0; j < 2; j++, k++) { +		flash_info[0].start[k] = flashbase; +		flashbase += 0x00010000; +	} +	for (j = 0; j < 7; j++, k++) { +		flash_info[0].start[k] = flashbase; +		flashbase += 0x00002000; +	}		 +	size += flash_info[0].size; + +	flash_info[1].flash_id = (SST_MANUFACT & FLASH_VENDMASK); +	flash_info[1].size = 0x00200000; /* 2 MB */ +	flash_info[1].sector_count = 512; +	memset (flash_info[1].protect, 0, 512); +	flashbase = SST_BASEADDR; +	for (j=0; j<512; j++) { +		flash_info[1].start[j] = flashbase; +		flashbase += 0x1000;	/* 4 KB sectors */ +	} +	size += flash_info[1].size; + +	/* Protect monitor and environment sectors */ +	flash_protect (FLAG_PROTECT_SET, +		 0x0, +		 0x0 + monitor_flash_len - 1, +		 &flash_info[0]); + +	flash_protect (FLAG_PROTECT_SET, +		 CFG_ENV_ADDR, +		 CFG_ENV_ADDR + CFG_ENV_SIZE - 1,  +		 &flash_info[0]); + +	return size; +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t * info) +{ +	int i; +	int erased = 0; +	unsigned long j; +	unsigned long count; +	unsigned char *p; + +	switch (info->flash_id & FLASH_VENDMASK) { +	case (SST_MANUFACT & FLASH_VENDMASK): +		printf("SST: "); +		break; +	case (PHILIPS_LPC2292 & FLASH_VENDMASK): +		printf("Philips: "); +		break; +	default: +		printf ("Unknown Vendor "); +		break; +	} + +	printf ("  Size: %ld KB in %d Sectors\n", +	  info->size >> 10, info->sector_count); + +	printf ("  Sector Start Addresses:"); +	for (i = 0; i < info->sector_count; i++) { +		if ((i % 5) == 0) { +			printf ("\n   "); +		} +		if (i < (info->sector_count - 1)) { +			count = info->start[i+1] - info->start[i]; +		} +		else { +			count = info->start[0] + info->size - info->start[i]; +		} +		p = (unsigned char*)(info->start[i]); +		erased = 1; +		for (j = 0; j < count; j++) { +			if (*p != 0xFF) { +				erased = 0; +				break; +			} +			p++; +		} +		printf (" %08lX%s%s", info->start[i], info->protect[i] ? " RO" : "   ", +			erased ? " E" : "  "); +	} +	printf ("\n"); +} + +/*----------------------------------------------------------------------- + */ + +int flash_erase_philips (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 flash_erase_sst (flash_info_t * info, int s_first, int s_last) +{ +	int i; + +	for (i = s_first; i <= s_last; i++) { +		*SST_ADDR1 = 0x00AA; +		*SST_ADDR2 = 0x0055; +		*SST_ADDR1 = 0x0080; +		*SST_ADDR1 = 0x00AA; +		*SST_ADDR2 = 0x0055; +		*((volatile ushort*)(info->start[i])) = 0x0030; +		/* wait for erase to finish */ +		udelay(25000); +	} + +	return ERR_OK; +} + +int flash_erase (flash_info_t * info, int s_first, int s_last) +{ +	switch (info->flash_id & FLASH_VENDMASK) { +		case (SST_MANUFACT & FLASH_VENDMASK): +			return flash_erase_sst(info, s_first, s_last);   +		case (PHILIPS_LPC2292 & FLASH_VENDMASK): +			return flash_erase_philips(info, s_first, s_last);   +		default: +			return ERR_PROTECTED; +	} +	return ERR_PROTECTED; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash. + * + * cnt is in bytes + */ + +int write_buff_sst (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ +	ushort tmp; +	ulong i; +	uchar* src_org; +	uchar* dst_org; +	ulong cnt_org = cnt; +	int ret = ERR_OK; + +	src_org = src; +	dst_org = (uchar*)addr; + +	if (addr & 1) {		/* if odd address */ +		tmp = *((uchar*)(addr - 1)); /* little endian */ +		tmp |= (*src << 8); +		write_word_sst(addr - 1, tmp); +		addr += 1; +		cnt -= 1; +		src++; +	} +	while (cnt > 1) { +		tmp = ((*(src+1)) << 8) + (*src); /* little endian */ +		write_word_sst(addr, tmp); +		addr += 2; +		src += 2; +		cnt -= 2; +	} +	if (cnt > 0) { +		tmp = (*((uchar*)(addr + 1))) << 8; +		tmp |= *src; +		write_word_sst(addr, tmp); +	} + +	for (i = 0; i < cnt_org; i++) { +		if (*dst_org != *src_org) { +			printf("Write failed. Byte %lX differs\n", i); +			ret = ERR_PROG_ERROR; +			break; +		} +		dst_org++; +		src_org++; +	} + + +	return ret; +} + +int write_buff_philips (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; +	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; + +#if 0 +	printf("\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)); +#endif + +	/* 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); +	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++) { +#if 0 +		printf("copy middle block: %lX -> %lX 512 bytes, " +		"%lX -> %lX 512 bytes\n", +		(ulong)src, +		(ulong)COPY_BUFFER_LOCATION, +		(ulong)COPY_BUFFER_LOCATION, +		(ulong)addr); +#endif +		memcpy((void*)COPY_BUFFER_LOCATION, src, 512); +		copy_buffer_to_flash(info, addr); +		src += 512; +		addr += 512;     +	} + + +	if (last_copy_size > 0) { +#if 0 +		printf("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); +#endif +		/* copy last block */ +		memcpy((void*)COPY_BUFFER_LOCATION,  +			(void*)(last_block * 512), 512); +		memcpy((void*)COPY_BUFFER_LOCATION,  +			src, last_copy_size); +		copy_buffer_to_flash(info, addr); +	} + +	/* verify write */ +	memmap_value = GET8(MEMMAP); + +	disable_interrupts(); + +	PUT8(MEMMAP, 01);		/* 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++; +	} + +	PUT8(MEMMAP, memmap_value); +	enable_interrupts(); + +	return ret; +} + +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ +	switch (info->flash_id & FLASH_VENDMASK) { +		case (SST_MANUFACT & FLASH_VENDMASK): +			return write_buff_sst(info, src, addr, cnt);   +		case (PHILIPS_LPC2292 & FLASH_VENDMASK): +			return write_buff_philips(info, src, addr, cnt);   +		default: +			return ERR_PROG_ERROR; +	} +	return ERR_PROG_ERROR; +} diff --git a/board/lpc2292sodimm/iap_entry.S b/board/lpc2292sodimm/iap_entry.S new file mode 100644 index 000000000..28ed80577 --- /dev/null +++ b/board/lpc2292sodimm/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/board/lpc2292sodimm/lowlevel_init.S b/board/lpc2292sodimm/lowlevel_init.S new file mode 100644 index 000000000..a91e678d8 --- /dev/null +++ b/board/lpc2292sodimm/lowlevel_init.S @@ -0,0 +1,87 @@ +/* + * (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 <config.h> +#include <version.h> +#include <asm/arch/hardware.h> + +/* some parameters for the board */ +/* setting up the memory */ +#define 	SRAM_START 	0x40000000 +#define 	SRAM_SIZE	0x00004000 +#define   BCFG0_VALUE 0x1000ffef +#define   BCFG1_VALUE 0x10001C61 +	 +_TEXT_BASE: +	.word	TEXT_BASE +MEMMAP_ADR:	 +	.word	MEMMAP +BCFG0_ADR: +  .word BCFG0 +_BCFG0_VALUE: +  .word BCFG0_VALUE +BCFG1_ADR: +	.word	BCFG1 +_BCFG1_VALUE: +	.word	BCFG1_VALUE +PINSEL2_ADR: +	.word	PINSEL2 +PINSEL2_MASK: +	.word	0x00000000 +PINSEL2_VALUE: +	.word	0x0F800914 + +.extern _start + +.globl lowlevel_init +lowlevel_init: +	/* set up memory control register for bank 0 */ +	ldr r0, _BCFG0_VALUE +	ldr r1, BCFG0_ADR +	str r0, [r1] + +	/* set up memory control register for bank 1 */ +	ldr	r0, _BCFG1_VALUE +	ldr	r1, BCFG1_ADR +	str	r0, [r1] + +	/* set up PINSEL2 for bus-pins */ +	ldr	r0, PINSEL2_ADR +	ldr	r1, [r0] +	ldr	r2, PINSEL2_MASK +	ldr	r3, PINSEL2_VALUE +	and	r1, r1, r2 +	orr	r1, r1, r3 +	str	r1, [r0] +		 +	/* move vectors to beginning of SRAM */ +	mov	r2, #SRAM_START		 +	mov	r0, #0 /*_start*/ +	ldmneia r0!, {r3-r10}		 +	stmneia r2!, {r3-r10}		 +	ldmneia r0, {r3-r9} +	stmneia r2, {r3-r9} + +        /* Set-up MEMMAP register, so vectors are taken from SRAM */ +	ldr	r0, MEMMAP_ADR +	mov	r1, #0x02	/* vectors re-mapped to static RAM */ +	str	r1, [r0] +			 +	/* everything is fine now */ +	mov	pc, lr diff --git a/board/lpc2292sodimm/lpc2292sodimm.c b/board/lpc2292sodimm/lpc2292sodimm.c new file mode 100644 index 000000000..de04c6638 --- /dev/null +++ b/board/lpc2292sodimm/lpc2292sodimm.c @@ -0,0 +1,62 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2005 Rowel Atienza <rowel@diwalabs.com> + * Armadillo board HT1070 + * + * 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 <clps7111.h> + +/* ------------------------------------------------------------------------- */ + + +/* + * Miscelaneous platform dependent initialisations + */ + +int board_init (void) +{ +	DECLARE_GLOBAL_DATA_PTR; + +	/* Activate LED flasher */ +	IO_LEDFLSH = 0x40; + +	/* arch number MACH_TYPE_ARMADILLO - not official*/ +	gd->bd->bi_arch_number = 83; + +	/* location of boot parameters */ +	gd->bd->bi_boot_params = 0xc0000100; + +	return 0; +} + +int dram_init (void) +{ +	DECLARE_GLOBAL_DATA_PTR; + +	gd->bd->bi_dram[0].start = PHYS_SDRAM_1; +	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + +	return (0); +} diff --git a/board/lpc2292sodimm/mmc.c b/board/lpc2292sodimm/mmc.c new file mode 100644 index 000000000..e361db186 --- /dev/null +++ b/board/lpc2292sodimm/mmc.c @@ -0,0 +1,154 @@ +/* + * 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 <config.h> +#include <common.h> +#include <mmc.h> +#include <asm/errno.h> +#include <asm/arch/hardware.h> +#include <part.h> +#include <fat.h> +#include "mmc_hw.h" +#include "spi.h" + +#ifdef CONFIG_MMC + +#undef MMC_DEBUG + +static block_dev_desc_t mmc_dev; + +/* these are filled out by a call to mmc_hw_get_parameters */ +static int hw_size;		/* in kbytes */ +static int hw_nr_sects; +static int hw_sect_size;	/* in bytes */ + +block_dev_desc_t * mmc_get_dev(int dev) +{ +	return (block_dev_desc_t *)(&mmc_dev); +} + +unsigned long mmc_block_read(int dev,  +			     unsigned long start,  +			     lbaint_t blkcnt, +			     unsigned long *buffer) +{ +	unsigned long rc = 0; +	unsigned char *p = (unsigned char *)buffer; +	unsigned long i; +	unsigned long addr = start; + +#ifdef MMC_DEBUG +	printf("mmc_block_read: start=%lu, blkcnt=%lu\n", start,  +		 (unsigned long)blkcnt); +#endif + +	for(i = 0; i < (unsigned long)blkcnt; i++) { +#ifdef MMC_DEBUG +		printf("mmc_read_sector: addr=%lu, buffer=%p\n", addr, p); +#endif +		(void)mmc_read_sector(addr, p); +		rc++; +		addr++; +		p += hw_sect_size; +	}  + +	return rc; +} + +/*----------------------------------------------------------------------------- + * Read hardware paramterers (sector size, size, number of sectors) + */ +static int mmc_hw_get_parameters(void) +{ +	unsigned char csddata[16]; +	unsigned int sizemult; +	unsigned int size; + +	mmc_read_csd(csddata); +	hw_sect_size = 1<<(csddata[5] & 0x0f); +	size = ((csddata[6]&0x03)<<10)+(csddata[7]<<2)+(csddata[8]&0xc0); +	sizemult = ((csddata[10] & 0x80)>>7)+((csddata[9] & 0x03)<<1); +	hw_nr_sects = (size+1)*(1<<(sizemult+2)); +	hw_size = hw_nr_sects*hw_sect_size/1024; + +#ifdef MMC_DEBUG +	printf("mmc_hw_get_parameters: hw_sect_size=%d, hw_nr_sects=%d, " +		 "hw_size=%d\n", hw_sect_size, hw_nr_sects, hw_size); +#endif + +	return 0; +} + +int mmc_init(int verbose) +{ +	int ret = -ENODEV; + +	if (verbose) +		printf("mmc_init\n"); + +	spi_init(); +	mmc_hw_init(); + +	mmc_hw_get_parameters(); + +	mmc_dev.if_type = IF_TYPE_MMC; +	mmc_dev.part_type = PART_TYPE_DOS; +	mmc_dev.dev = 0; +	mmc_dev.lun = 0; +	mmc_dev.type = 0; +	mmc_dev.blksz = hw_sect_size; +	mmc_dev.lba = hw_nr_sects; +	sprintf((char*)mmc_dev.vendor, "Unknown vendor"); +	sprintf((char*)mmc_dev.product, "Unknown product"); +	sprintf((char*)mmc_dev.revision, "N/A"); +	mmc_dev.removable = 0;	/* should be true??? */ +	mmc_dev.block_read = mmc_block_read; + +	fat_register_device(&mmc_dev, 1); + +	ret = 0; + +	return ret; +} + +int mmc_write(uchar * src, ulong dst, int size) +{ +#ifdef MMC_DEBUG +	printf("mmc_write: src=%p, dst=%lu, size=%u\n", src, dst, size); +#endif +	/* Since mmc2info always returns 0 this function will never be called */ +	return 0; +} + +int mmc_read(ulong src, uchar * dst, int size) +{ +#ifdef MMC_DEBUG +	printf("mmc_read: src=%lu, dst=%p, size=%u\n", src, dst, size); +#endif +	/* Since mmc2info always returns 0 this function will never be called */ +	return 0; +} + +int mmc2info(ulong addr) +{ +	/* This function is used by cmd_cp to determine if source or destination +	 address resides on MMC-card or not. We do not support copy to and from +	 MMC-card so we always return 0. */ +	return 0; +} + +#endif /* CONFIG_MMC */ diff --git a/board/lpc2292sodimm/mmc_hw.c b/board/lpc2292sodimm/mmc_hw.c new file mode 100644 index 000000000..0b5ddf961 --- /dev/null +++ b/board/lpc2292sodimm/mmc_hw.c @@ -0,0 +1,233 @@ +/* +    This code was original written by Ulrich Radig and modified by +    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 <config.h> +#include <common.h> +#include <asm/arch/hardware.h> +#include "spi.h" + +#define MMC_Enable() PUT32(IO1CLR, 1l << 22) +#define MMC_Disable() PUT32(IO1SET, 1l << 22) +#define mmc_spi_cfg() spi_set_clock(8); spi_set_cfg(0, 1, 0);  + +static unsigned char Write_Command_MMC (unsigned char *CMD); +static void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer, +		    unsigned short int Bytes); + +/* initialize the hardware */ +int mmc_hw_init(void) +{ +	unsigned long a; +	unsigned short int Timeout = 0; +	unsigned char b; +	unsigned char CMD[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95}; + +	/* set-up GPIO and SPI */ +	(*((volatile unsigned long *)PINSEL2)) &= ~(1l << 3); /* clear bit 3 */ +	(*((volatile unsigned long *)IO1DIR)) |= (1l << 22); /* set bit 22 (output) */ + +	MMC_Disable(); + +	spi_lock(); +	spi_set_clock(248); +	spi_set_cfg(0, 1, 0); +	MMC_Enable(); + +	/* waste some time */ +	for(a=0; a < 20000; a++) +		asm("nop"); + +	/* Put the MMC/SD-card into SPI-mode */ +	for (b = 0; b < 10; b++) /* Sends min 74+ clocks to the MMC/SD-card */ +		spi_write(0xff); + +	/* Sends command CMD0 to MMC/SD-card */ +	while (Write_Command_MMC(CMD) != 1) { +		if (Timeout++ > 200) { +			MMC_Disable(); +			spi_unlock(); +			return(1); /* Abort with command 1 (return 1) */ +		} +	} +	/* Sends Command CMD1 an MMC/SD-card */ +	Timeout = 0; +	CMD[0] = 0x41;/* Command 1 */ +	CMD[5] = 0xFF; + +	while (Write_Command_MMC(CMD) != 0) { +		if (Timeout++ > 200) { +			MMC_Disable(); +			spi_unlock(); +			return (2); /* Abort with command 2 (return 2) */ +		} +	} + +	MMC_Disable(); +	spi_unlock(); + +	return 0; +} + +/* ############################################################################ +   Sends a command to the MMC/SD-card +   ######################################################################### */ +static unsigned char Write_Command_MMC (unsigned char *CMD) +{ +	unsigned char a, tmp = 0xff; +	unsigned short int Timeout = 0; + +	MMC_Disable(); +	spi_write(0xFF); +	MMC_Enable(); + +	for (a = 0; a < 0x06; a++) +		spi_write(*CMD++); + +	while (tmp == 0xff) { +		tmp = spi_read(); +		if (Timeout++ > 5000) +		  break; +	} + +	return (tmp); +} + +/* ############################################################################ +   Routine to read the CID register from the MMC/SD-card (16 bytes) +   ######################################################################### */ +void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer, unsigned short +	int Bytes) +{ +	unsigned short int a; + +	spi_lock(); +	mmc_spi_cfg(); +	MMC_Enable(); + +	if (Write_Command_MMC(CMD) != 0) { +		MMC_Disable(); +		spi_unlock(); +		return; +	}	 + +	while (spi_read() != 0xfe) {}; +	for (a = 0; a < Bytes; a++) +		*Buffer++ = spi_read(); + +	/* Read the CRC-byte */ +	spi_read(); /* CRC - byte is discarded */ +	spi_read(); /* CRC - byte is discarded */ +	/* set MMC_Chip_Select to high (MMC/SD-card Inaktiv) */ +	MMC_Disable(); +	spi_unlock(); + +	return; +} + +/* ############################################################################ +   Routine to read a block (512 bytes) from the MMC/SD-card +   ######################################################################### */ +unsigned char mmc_read_sector (unsigned long addr,unsigned char *Buffer) +{ +	/* Command 16 to read aBlocks from the MMC/SD - caed */ +	unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};  + +	/* The addres on the MMC/SD-card is in bytes, +	addr is transformed from blocks to bytes and the result is +	placed into the command */ + +	addr = addr << 9; /* addr = addr * 512 */ + +	CMD[1] = ((addr & 0xFF000000) >> 24); +	CMD[2] = ((addr & 0x00FF0000) >> 16); +	CMD[3] = ((addr & 0x0000FF00) >> 8 ); + +	MMC_Read_Block(CMD, Buffer, 512); + +	return (0); +} + +/* ############################################################################ +   Routine to write a block (512 byte) to the MMC/SD-card +   ######################################################################### */ +unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer) +{ +	unsigned char tmp, a; +	unsigned short int b; +	/* Command 24 to write a block to the MMC/SD - card */ +	unsigned char CMD[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF};  + +	/* The addres on the MMC/SD-card is in bytes, +	addr is transformed from blocks to bytes and the result is +	placed into the command */ + +	addr = addr << 9; /* addr = addr * 512 */ + +	CMD[1] = ((addr & 0xFF000000) >> 24); +	CMD[2] = ((addr & 0x00FF0000) >> 16); +	CMD[3] = ((addr & 0x0000FF00) >> 8 ); + +	spi_lock(); +	mmc_spi_cfg(); +	MMC_Enable(); + +	/* Send command CMD24 to the MMC/SD-card (Write 1 Block/512 Bytes) */ +	tmp = Write_Command_MMC(CMD); +	if (tmp != 0) { +		MMC_Disable(); +		spi_unlock(); +		return(tmp); +	}	 + +	/* Do a short delay and send a clock-pulse to the MMC/SD-card */ +	for (a = 0; a < 100; a++) +		spi_read(); + +	/* Send a start byte to the MMC/SD-card */ +	spi_write(0xFE);	 + +	/* Write the block (512 bytes) to the MMC/SD-card */ +	for (b = 0; b < 512; b++) +		spi_write(*Buffer++); + +	/* write the CRC-Byte */ +	spi_write(0xFF); /* write a dummy CRC */ +	spi_write(0xFF); /* CRC code is not used */ + +	/* Wait for MMC/SD-card busy */ +	while (spi_read() != 0xff) {}; + +	/* set MMC_Chip_Select to high (MMC/SD-card inactive) */ +	MMC_Disable(); +	spi_unlock(); +	return (0); +} + +/* ######################################################################### +   Routine to read the CSD register from the MMC/SD-card (16 bytes) +   ######################################################################### */ +unsigned char mmc_read_csd (unsigned char *Buffer) +{ +	/* Command to read the CSD register */ +	unsigned char CMD[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0xFF}; + +	MMC_Read_Block(CMD, Buffer, 16); + +	return (0); +} diff --git a/board/lpc2292sodimm/mmc_hw.h b/board/lpc2292sodimm/mmc_hw.h new file mode 100644 index 000000000..3687dbf69 --- /dev/null +++ b/board/lpc2292sodimm/mmc_hw.h @@ -0,0 +1,29 @@ +/* +    This module implements a linux character device driver for the 24c256 chip. +    Copyright (C) 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 +*/ + +#ifndef _MMC_HW_ +#define _MMC_HW_ + +unsigned char mmc_read_csd(unsigned char *Buffer); +unsigned char mmc_read_sector (unsigned long addr, +			       unsigned char *Buffer); +unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer); +int mmc_hw_init(void); + +#endif /* _MMC_HW_ */ diff --git a/board/lpc2292sodimm/spi.c b/board/lpc2292sodimm/spi.c new file mode 100644 index 000000000..4ba1468f3 --- /dev/null +++ b/board/lpc2292sodimm/spi.c @@ -0,0 +1,40 @@ +/* +    This module implements an interface to the SPI on the lpc22xx. +    Copyright (C) 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 <config.h> +#include <common.h> +#include <asm/errno.h> +#include <asm/arch/hardware.h> +#include "spi.h" + +unsigned long spi_flags; +unsigned char spi_idle = 0x00; + +int spi_init(void) +{ +	unsigned long pinsel0_value; + +	/* activate spi pins */ +	pinsel0_value = GET32(PINSEL0); +	pinsel0_value &= ~(0xFFl << 8); +	pinsel0_value |= (0x55l << 8); +	PUT32(PINSEL0, pinsel0_value); + +	return 0; +} diff --git a/board/lpc2292sodimm/spi.h b/board/lpc2292sodimm/spi.h new file mode 100644 index 000000000..64f088cc9 --- /dev/null +++ b/board/lpc2292sodimm/spi.h @@ -0,0 +1,84 @@ +/* +    This file defines the interface to the lpc22xx SPI module. +    Copyright (C) 2006  Embedded Artists AB (www.embeddedartists.com) + +    This file may be included in software not adhering to the GPL. + +    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 SPI_H +#define SPI_H + +#include <config.h> +#include <common.h> +#include <asm/errno.h> +#include <asm/arch/hardware.h> + +#define SPIF 0x80 + +#define spi_lock() disable_interrupts(); +#define spi_unlock() enable_interrupts(); + +extern unsigned long spi_flags; +extern unsigned char spi_idle; + +int spi_init(void); + +static inline unsigned char spi_read(void) +{ +	unsigned char b; + +	PUT8(S0SPDR, spi_idle); +	while (!(GET8(S0SPSR) & SPIF)); +	b = GET8(S0SPDR); + +	return b; +} + +static inline void spi_write(unsigned char b) +{ +	PUT8(S0SPDR, b); +	while (!(GET8(S0SPSR) & SPIF)); +	GET8(S0SPDR);		/* this will clear the SPIF bit */ +} + +static inline void spi_set_clock(unsigned char clk_value) +{ +	PUT8(S0SPCCR, clk_value); +} + +static inline void spi_set_cfg(unsigned char phase, +			       unsigned char polarity, +			       unsigned char lsbf) +{ +	unsigned char v = 0x20;	/* master bit set */ + +	if (phase) +		v |= 0x08;			/* set phase bit */ +	if (polarity) { +		v |= 0x10;			/* set polarity bit */ +		spi_idle = 0xFF; +	} else { +		spi_idle = 0x00; +	} +	if (lsbf) +		v |= 0x40;			/* set lsbf bit */ + +	PUT8(S0SPCR, v); +} + +#endif + diff --git a/board/lpc2292sodimm/u-boot.lds b/board/lpc2292sodimm/u-boot.lds new file mode 100644 index 000000000..64d946c43 --- /dev/null +++ b/board/lpc2292sodimm/u-boot.lds @@ -0,0 +1,55 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@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 + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ +	. = 0x00000000; + +	. = ALIGN(4); +	.text      : +	{ +	  cpu/arm720t/start.o	(.text) +	  *(.text) +	} + +	. = ALIGN(4); +	.rodata : { *(.rodata) } + +	. = ALIGN(4); +	.data : { *(.data) } + +	. = ALIGN(4); +	.got : { *(.got) } + +	__u_boot_cmd_start = .; +	.u_boot_cmd : { *(.u_boot_cmd) } +	__u_boot_cmd_end = .; + +	. = ALIGN(4); +	__bss_start = .; +	.bss : { *(.bss) } +	_end = .; +} diff --git a/cpu/arm720t/cpu.c b/cpu/arm720t/cpu.c index a5b6de760..60c1aa90b 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 da62502d6..8f32124d3 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 054bab981..15c54af08 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 e66d10944..96d5f54ba 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 diff --git a/include/asm-arm/arch-arm720t/hardware.h b/include/asm-arm/arch-arm720t/hardware.h index 3056ca7f6..1e9cd4116 100644 --- a/include/asm-arm/arch-arm720t/hardware.h +++ b/include/asm-arm/arch-arm720t/hardware.h @@ -36,6 +36,8 @@  /* include armadillo specific hardware file if there was one */  #elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)  /* include IntegratorCP/CM720T specific hardware file if there was one */ +#elif defined(CONFIG_LPC2292) +#include <asm-arm/arch-arm720t/lpc2292_registers.h>  #else  #error No hardware file defined for this configuration  #endif diff --git a/include/asm-arm/arch-arm720t/lpc2292_registers.h b/include/asm-arm/arch-arm720t/lpc2292_registers.h new file mode 100644 index 000000000..5715f3ef7 --- /dev/null +++ b/include/asm-arm/arch-arm720t/lpc2292_registers.h @@ -0,0 +1,225 @@ +#ifndef __LPC2292_REGISTERS_H +#define __LPC2292_REGISTERS_H + +#include <config.h> + +/* Macros for reading/writing registers */ +#define PUT8(reg, value) (*(volatile unsigned char*)(reg) = (value)) +#define PUT16(reg, value) (*(volatile unsigned short*)(reg) = (value)) +#define PUT32(reg, value) (*(volatile unsigned int*)(reg) = (value)) +#define GET8(reg) (*(volatile unsigned char*)(reg)) +#define GET16(reg) (*(volatile unsigned short*)(reg)) +#define GET32(reg) (*(volatile unsigned int*)(reg)) + +/* External Memory Controller */ + +#define BCFG0 0xFFE00000	/* 32-bits */ +#define BCFG1 0xFFE00004	/* 32-bits */ +#define BCFG2 0xFFE00008	/* 32-bits */ +#define BCFG3 0xFFE0000c	/* 32-bits */ + +/* System Control Block */ + +#define EXTINT   0xE01FC140 +#define EXTWAKE  0xE01FC144 +#define EXTMODE  0xE01FC148 +#define EXTPOLAR 0xE01FC14C +#define MEMMAP   0xE01FC040 +#define PLLCON   0xE01FC080 +#define PLLCFG   0xE01FC084 +#define PLLSTAT  0xE01FC088 +#define PLLFEED  0xE01FC08C +#define PCON     0xE01FC0C0 +#define PCONP    0xE01FC0C4 +#define VPBDIV   0xE01FC100 + +/* Memory Acceleration Module */ + +#define MAMCR  0xE01FC000 +#define MAMTIM 0xE01FC004 + +/* Vectored Interrupt Controller */ + +#define VICIRQStatus    0xFFFFF000 +#define VICFIQStatus    0xFFFFF004 +#define VICRawIntr      0xFFFFF008 +#define VICIntSelect    0xFFFFF00C +#define VICIntEnable    0xFFFFF010 +#define VICIntEnClr     0xFFFFF014 +#define VICSoftInt      0xFFFFF018 +#define VICSoftIntClear 0xFFFFF01C +#define VICProtection   0xFFFFF020 +#define VICVectAddr     0xFFFFF030 +#define VICDefVectAddr  0xFFFFF034 +#define VICVectAddr0    0xFFFFF100 +#define VICVectAddr1    0xFFFFF104 +#define VICVectAddr2    0xFFFFF108 +#define VICVectAddr3    0xFFFFF10C +#define VICVectAddr4    0xFFFFF110 +#define VICVectAddr5    0xFFFFF114 +#define VICVectAddr6    0xFFFFF118 +#define VICVectAddr7    0xFFFFF11C +#define VICVectAddr8    0xFFFFF120 +#define VICVectAddr9    0xFFFFF124 +#define VICVectAddr10   0xFFFFF128 +#define VICVectAddr11   0xFFFFF12C +#define VICVectAddr12   0xFFFFF130 +#define VICVectAddr13   0xFFFFF134 +#define VICVectAddr14   0xFFFFF138 +#define VICVectAddr15   0xFFFFF13C +#define VICVectCntl0    0xFFFFF200 +#define VICVectCntl1	0xFFFFF204 +#define VICVectCntl2	0xFFFFF208 +#define VICVectCntl3	0xFFFFF20C +#define VICVectCntl4	0xFFFFF210 +#define VICVectCntl5	0xFFFFF214 +#define VICVectCntl6	0xFFFFF218 +#define VICVectCntl7	0xFFFFF21C +#define VICVectCntl8	0xFFFFF220 +#define VICVectCntl9	0xFFFFF224 +#define VICVectCntl10	0xFFFFF228 +#define VICVectCntl11	0xFFFFF22C +#define VICVectCntl12	0xFFFFF230 +#define VICVectCntl13	0xFFFFF234 +#define VICVectCntl14	0xFFFFF238 +#define VICVectCntl15	0xFFFFF23C + +/* Pin connect block */ + +#define PINSEL0 0xE002C000	/* 32 bits */ +#define PINSEL1 0xE002C004	/* 32 bits */ +#define PINSEL2 0xE002C014	/* 32 bits */ + +/* GPIO */ + +#define IO0PIN 0xE0028000 +#define IO0SET 0xE0028004 +#define IO0DIR 0xE0028008 +#define IO0CLR 0xE002800C +#define IO1PIN 0xE0028010 +#define IO1SET 0xE0028014 +#define IO1DIR 0xE0028018 +#define IO1CLR 0xE002801C +#define IO2PIN 0xE0028020 +#define IO2SET 0xE0028024 +#define IO2DIR 0xE0028028 +#define IO2CLR 0xE002802C +#define IO3PIN 0xE0028030 +#define IO3SET 0xE0028034 +#define IO3DIR 0xE0028038 +#define IO3CLR 0xE002803C + +/* Uarts */ + +#define U0RBR 0xE000C000 +#define U0THR 0xE000C000 +#define U0IER 0xE000C004 +#define U0IIR 0xE000C008 +#define U0FCR 0xE000C008 +#define U0LCR 0xE000C00C +#define U0LSR 0xE000C014 +#define U0SCR 0xE000C01C +#define U0DLL 0xE000C000 +#define U0DLM 0xE000C004 + +#define U1RBR 0xE0010000 +#define U1THR 0xE0010000 +#define U1IER 0xE0010004 +#define U1IIR 0xE0010008 +#define U1FCR 0xE0010008 +#define U1LCR 0xE001000C +#define U1MCR 0xE0010010 +#define U1LSR 0xE0010014 +#define U1MSR 0xE0010018 +#define U1SCR 0xE001001C +#define U1DLL 0xE0010000 +#define U1DLM 0xE0010004 + +/* I2C */ + +#define I2CONSET 0xE001C000 +#define I2STAT   0xE001C004 +#define I2DAT    0xE001C008 +#define I2ADR    0xE001C00C +#define I2SCLH   0xE001C010 +#define I2SCLL   0xE001C014 +#define I2CONCLR 0xE001C018 + +/* SPI */ + +#define S0SPCR  0xE0020000 +#define S0SPSR  0xE0020004 +#define S0SPDR  0xE0020008 +#define S0SPCCR 0xE002000C +#define S0SPINT 0xE002001C + +#define S1SPCR  0xE0030000 +#define S1SPSR  0xE0030004 +#define S1SPDR  0xE0030008 +#define S1SPCCR 0xE003000C +#define S1SPINT 0xE003001C + +/* CAN controller */ + +/* skip for now */ + +/* Timers */ + +#define T0IR  0xE0004000 +#define T0TCR 0xE0004004 +#define T0TC  0xE0004008 +#define T0PR  0xE000400C +#define T0PC  0xE0004010 +#define T0MCR 0xE0004014 +#define T0MR0 0xE0004018 +#define T0MR1 0xE000401C +#define T0MR2 0xE0004020 +#define T0MR3 0xE0004024 +#define T0CCR 0xE0004028 +#define T0CR0 0xE000402C +#define T0CR1 0xE0004030 +#define T0CR2 0xE0004034 +#define T0CR3 0xE0004038 +#define T0EMR 0xE000403C + +#define T1IR  0xE0008000 +#define T1TCR 0xE0008004 +#define T1TC  0xE0008008 +#define T1PR  0xE000800C +#define T1PC  0xE0008010 +#define T1MCR 0xE0008014 +#define T1MR0 0xE0008018 +#define T1MR1 0xE000801C +#define T1MR2 0xE0008020 +#define T1MR3 0xE0008024 +#define T1CCR 0xE0008028 +#define T1CR0 0xE000802C +#define T1CR1 0xE0008030 +#define T1CR2 0xE0008034 +#define T1CR3 0xE0008038 +#define T1EMR 0xE000803C + +/* PWM */ + +/* skip for now */ + +/* A/D converter */ + +/* skip for now */ + +/* Real Time Clock */ + +/* skip for now */ + +/* Watchdog */ + +#define WDMOD  0xE0000000 +#define WDTC   0xE0000004 +#define WDFEED 0xE0000008 +#define WDTV   0xE000000C + +/* EmbeddedICE LOGIC */ + +/* skip for now */ + +#endif diff --git a/include/asm-arm/arch-arm720t/mmc.h b/include/asm-arm/arch-arm720t/mmc.h new file mode 100644 index 000000000..e664a5f67 --- /dev/null +++ b/include/asm-arm/arch-arm720t/mmc.h @@ -0,0 +1,22 @@ +/* + * A dummy header file for use with the LPC2292 port to keep the + * compiler happy. + * + * 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 _MMC_ARM_TDM_H_ +#define _MMC_ARM_TDM_H_ +#endif /* _MMC_ARM_TDM_H_ */ diff --git a/include/configs/lpc2292sodimm.h b/include/configs/lpc2292sodimm.h new file mode 100644 index 000000000..7e515230a --- /dev/null +++ b/include/configs/lpc2292sodimm.h @@ -0,0 +1,158 @@ +/* + * (C) Copyright 2000 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * Configuation settings for the EP7312 board. + * + * Modified to work on Armadillo HT1070 ARM720T board + * (C) Copyright 2005 Rowel Atienza rowel@diwalabs.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 + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * If we are developing, we might want to start armboot from ram + * so we MUST NOT initialize critical regs like mem-timing ... + */ +#undef CONFIG_INIT_CRITICAL		/* undef for developing */ + +#undef CONFIG_SKIP_LOWLEVEL_INIT +#undef CONFIG_SKIP_RELOCATE_UBOOT + +/* + * High Level Configuration Options + * (easy to change) + */ +#define CONFIG_ARM7		1	/* This is a ARM7 CPU	*/ +#define CONFIG_ARM_THUMB	1	/* this is an ARM720TDMI */ +#define CONFIG_LPC2292 +#undef  CONFIG_ARM7_REVD	 	/* disable ARM720 REV.D Workarounds */ + +#undef CONFIG_USE_IRQ			/* don't need them anymore */ + +/* + * Size of malloc() pool + */ +#define CFG_MALLOC_LEN		(CFG_ENV_SIZE + 128*1024) +#define CFG_GBL_DATA_SIZE	128	/* size in bytes reserved for initial data */ + +/* + * Hardware drivers + */ + +/* + * select serial console configuration + */ +#define CONFIG_SERIAL1		1	/* we use Serial line 1 */ + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_BAUDRATE		115200 + +#define CONFIG_BOOTP_MASK       (CONFIG_BOOTP_DEFAULT|CONFIG_BOOTP_BOOTFILESIZE) + +/* + * Supported commands + */ +#define CONFIG_COMMANDS	       (CONFIG_CMD_DFL	| \ +				CFG_CMD_DHCP	| \ +				CFG_CMD_FAT	| \ +				CFG_CMD_MMC	| \ +				CFG_CMD_NET	| \ +				CFG_CMD_PING) + +#define CONFIG_MAC_PARTITION +#define CONFIG_DOS_PARTITION + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> + +#define CONFIG_BOOTDELAY	5 + +/* + * Miscellaneous configurable options + */ +#define	CFG_LONGHELP				/* undef to save memory		*/ +#define	CFG_PROMPT		"LPC2292SODIMM # " /* Monitor Command Prompt	*/ +#define	CFG_CBSIZE		256		/* Console I/O Buffer Size	*/ +#define	CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define	CFG_MAXARGS		16		/* max number of command args	*/ +#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size	*/ + +#define CFG_MEMTEST_START	0x40000000	/* memtest works on	*/ +#define CFG_MEMTEST_END		0x40000000	/* 4 ... 8 MB in DRAM	*/ + +#undef  CFG_CLKS_IN_HZ		/* everything, incl board info, in Hz */ + +#define	CFG_LOAD_ADDR		0x00040000	/* default load address	for armadillo: kernel img is here*/ + +#define CFG_SYS_CLK_FREQ        58982400        /* Hz */ +#define	CFG_HZ			2048		/* decrementer freq in Hz */ + +						/* valid baudrates */ +#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 } + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE	(128*1024)	/* regular stack */ +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ	(4*1024)	/* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ	(4*1024)	/* FIQ stack */ +#endif + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS	1	   /* we have 1 bank of DRAM */ +#define PHYS_SDRAM_1		0x81000000 /* SDRAM Bank #1 */ +#define PHYS_SDRAM_1_SIZE	0x00800000 /* 8 MB SDRAM */ + +#define PHYS_FLASH_1		0x80000000 /* Flash Bank #1 */ +#define PHYS_FLASH_SIZE		0x00200000 /* 2 MB */ + +#define CFG_FLASH_BASE		PHYS_FLASH_1 + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ +#define CFG_MAX_FLASH_BANKS	2	/* max number of memory banks		*/ +#define CFG_MAX_FLASH_SECT	1024	/* max number of sectors on one chip	*/ + +/* timeout values are in ticks */ +#define CFG_FLASH_ERASE_TOUT	(2*CFG_HZ) /* Timeout for Flash Erase */ +#define CFG_FLASH_WRITE_TOUT	(2*CFG_HZ) /* Timeout for Flash Write */ + +#define	CFG_ENV_IS_IN_FLASH	1 +#define CFG_ENV_ADDR		(0x0 + 0x3C000)	/* Addr of Environment Sector	*/ +#define CFG_ENV_SIZE		0x2000 /* Total Size of Environment Sector	*/ + +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_INITRD_TAG +#define CONFIG_MMC 1 + +#endif	/* __CONFIG_H */ diff --git a/include/flash.h b/include/flash.h index 8b7e824cc..55b6d8f38 100644 --- a/include/flash.h +++ b/include/flash.h @@ -304,6 +304,7 @@ extern void flash_read_factory_serial(flash_info_t * info, void * buffer, int of  #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			*/  /*-----------------------------------------------------------------------   * Internal FLASH identification codes |