From 6bd2447ee47ee23c18d2b3c7ccd5a20f7626f5b3 Mon Sep 17 00:00:00 2001 From: Gary Jennejohn Date: Wed, 24 Jan 2007 12:16:56 +0100 Subject: [PATCH] Add port for the lpc2292sodimm evaluation board from EmbeddedArtists --- MAKEALL | 2 +- Makefile | 3 + board/lpc2292sodimm/Makefile | 58 ++ board/lpc2292sodimm/config.mk | 31 + board/lpc2292sodimm/eth.c | 884 ++++++++++++++++++ board/lpc2292sodimm/flash.c | 477 ++++++++++ board/lpc2292sodimm/iap_entry.S | 7 + board/lpc2292sodimm/lowlevel_init.S | 87 ++ board/lpc2292sodimm/lpc2292sodimm.c | 62 ++ board/lpc2292sodimm/mmc.c | 154 +++ board/lpc2292sodimm/mmc_hw.c | 233 +++++ board/lpc2292sodimm/mmc_hw.h | 29 + board/lpc2292sodimm/spi.c | 40 + board/lpc2292sodimm/spi.h | 84 ++ board/lpc2292sodimm/u-boot.lds | 55 ++ cpu/arm720t/cpu.c | 3 +- cpu/arm720t/interrupts.c | 27 +- cpu/arm720t/serial.c | 78 +- cpu/arm720t/start.S | 69 ++ include/asm-arm/arch-arm720t/hardware.h | 2 + .../asm-arm/arch-arm720t/lpc2292_registers.h | 225 +++++ include/asm-arm/arch-arm720t/mmc.h | 22 + include/configs/lpc2292sodimm.h | 158 ++++ include/flash.h | 1 + 24 files changed, 2787 insertions(+), 4 deletions(-) create mode 100644 board/lpc2292sodimm/Makefile create mode 100644 board/lpc2292sodimm/config.mk create mode 100644 board/lpc2292sodimm/eth.c create mode 100644 board/lpc2292sodimm/flash.c create mode 100644 board/lpc2292sodimm/iap_entry.S create mode 100644 board/lpc2292sodimm/lowlevel_init.S create mode 100644 board/lpc2292sodimm/lpc2292sodimm.c create mode 100644 board/lpc2292sodimm/mmc.c create mode 100644 board/lpc2292sodimm/mmc_hw.c create mode 100644 board/lpc2292sodimm/mmc_hw.h create mode 100644 board/lpc2292sodimm/spi.c create mode 100644 board/lpc2292sodimm/spi.h create mode 100644 board/lpc2292sodimm/u-boot.lds create mode 100644 include/asm-arm/arch-arm720t/lpc2292_registers.h create mode 100644 include/asm-arm/arch-arm720t/mmc.h create mode 100644 include/configs/lpc2292sodimm.h diff --git a/MAKEALL b/MAKEALL index 40a5c773e5..4e4d04b567 100755 --- a/MAKEALL +++ b/MAKEALL @@ -181,7 +181,7 @@ LIST_SA="assabet dnp1110 gcplus lart shannon" LIST_ARM7=" \ armadillo B2 ep7312 evb4510 \ impa7 integratorap ap7 ap720t \ - modnet50 \ + lpc2292sodimm modnet50 \ " ######################################################################### diff --git a/Makefile b/Makefile index b1952edfe7..a44cba0102 100644 --- a/Makefile +++ b/Makefile @@ -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 0000000000..5a30198e21 --- /dev/null +++ b/board/lpc2292sodimm/Makefile @@ -0,0 +1,58 @@ +# +# (C) Copyright 2002 +# Sysgo Real-Time Solutions, GmbH +# Marius Groeger +# +# 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 0000000000..4146dac9ce --- /dev/null +++ b/board/lpc2292sodimm/config.mk @@ -0,0 +1,31 @@ +# +# (C) Copyright 2000 +# Sysgo Real-Time Solutions, GmbH +# Marius Groeger +# +# (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 0000000000..14bec19ce9 --- /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 +#include +#include +#include +#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 0000000000..dcef7ddba8 --- /dev/null +++ b/board/lpc2292sodimm/flash.c @@ -0,0 +1,477 @@ +/* + * (C) Copyright 2006 Embedded Artists AB + * + * 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 +#include + +/* 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 0000000000..28ed805770 --- /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 0000000000..a91e678d81 --- /dev/null +++ b/board/lpc2292sodimm/lowlevel_init.S @@ -0,0 +1,87 @@ +/* + * (C) Copyright 2006 Embedded Artists AB + * + * 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 +#include +#include + +/* 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 0000000000..de04c66385 --- /dev/null +++ b/board/lpc2292sodimm/lpc2292sodimm.c @@ -0,0 +1,62 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2005 Rowel Atienza + * 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 +#include + +/* ------------------------------------------------------------------------- */ + + +/* + * 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 0000000000..e361db1866 --- /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 +#include +#include +#include +#include +#include +#include +#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 0000000000..0b5ddf961a --- /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 +#include +#include +#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 0000000000..3687dbf696 --- /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 0000000000..4ba1468f39 --- /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 +#include +#include +#include +#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 0000000000..64f088cc94 --- /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 +#include +#include +#include + +#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 0000000000..64d946c439 --- /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 a5b6de7605..60c1aa90b6 100644 --- a/cpu/arm720t/cpu.c +++ b/cpu/arm720t/cpu.c @@ -73,7 +73,7 @@ int cleanup_before_linux (void) /* go to high speed */ IO_SYSCON3 = (IO_SYSCON3 & ~CLKCTL) | CLKCTL_73; #endif -#elif defined(CONFIG_NETARM) || defined(CONFIG_S3C4510B) +#elif defined(CONFIG_NETARM) || defined(CONFIG_S3C4510B) || defined(CONFIG_LPC2292) disable_interrupts (); /* Nothing more needed */ #elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) @@ -252,6 +252,7 @@ int dcache_status (void) void icache_enable (void) { } +#elif defined(CONFIG_LPC2292) /* just to satisfy the compiler */ #else #error No icache/dcache enable/disable functions defined for this CPU type #endif diff --git a/cpu/arm720t/interrupts.c b/cpu/arm720t/interrupts.c index da62502d61..8f32124d37 100644 --- a/cpu/arm720t/interrupts.c +++ b/cpu/arm720t/interrupts.c @@ -36,6 +36,12 @@ #define TIMER_LOAD_VAL 0xffff /* macro to read the 16 bit timer */ #define READ_TIMER (IO_TC1D & 0xffff) + +#ifdef CONFIG_LPC2292 +#undef READ_TIMER +#define READ_TIMER (0xFFFFFFFF - GET32(T0TC)) +#endif + #else #define IRQEN (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_INTR_ENABLE)) #define TM2CTRL (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_TIMER2_CONTROL)) @@ -195,6 +201,13 @@ void do_irq (struct pt_regs *pt_regs) } #elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) /* No do_irq() for IntegratorAP/CM720T as yet */ +#elif defined(CONFIG_LPC2292) + + void (*pfnct)(void); + + pfnct = (void (*)(void))VICVectAddr; + + (*pfnct)(); #else #error do_irq() not defined for this CPU type #endif @@ -293,6 +306,13 @@ int interrupt_init (void) /* Start timer */ SET_REG( REG_TMOD, TM0_RUN); +#elif defined(CONFIG_LPC2292) + PUT32(T0IR, 0); /* disable all timer0 interrupts */ + PUT32(T0TCR, 0); /* disable timer0 */ + PUT32(T0PR, CFG_SYS_CLK_FREQ / CFG_HZ); + PUT32(T0MCR, 0); + PUT32(T0TC, 0); + PUT32(T0TCR, 1); /* enable timer0 */ #else #error No interrupt_init() defined for this CPU type @@ -309,7 +329,7 @@ int interrupt_init (void) */ -#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) || defined(CONFIG_ARMADILLO) +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) || defined(CONFIG_ARMADILLO) || defined(CONFIG_LPC2292) void reset_timer (void) { @@ -337,7 +357,12 @@ void udelay (unsigned long usec) tmo += get_timer (0); while (get_timer_masked () < tmo) +#ifdef CONFIG_LPC2292 + /* GJ - not sure whether this is really needed or a misunderstanding */ + __asm__ __volatile__(" nop"); +#else /*NOP*/; +#endif } void reset_timer_masked (void) diff --git a/cpu/arm720t/serial.c b/cpu/arm720t/serial.c index 054bab9811..15c54af08b 100644 --- a/cpu/arm720t/serial.c +++ b/cpu/arm720t/serial.c @@ -123,4 +123,80 @@ serial_puts (const char *s) } } -#endif /* defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) */ +#elif defined(CONFIG_LPC2292) + +#include + +void serial_setbrg (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + unsigned short divisor = 0; + + switch (gd->baudrate) { + case 1200: divisor = 3072; break; + case 9600: divisor = 384; break; + case 19200: divisor = 192; break; + case 38400: divisor = 96; break; + case 57600: divisor = 64; break; + case 115200: divisor = 32; break; + default: hang (); break; + } + + /* init serial UART0 */ + PUT8(U0LCR, 0); + PUT8(U0IER, 0); + PUT8(U0LCR, 0x80); /* DLAB=1 */ + PUT8(U0DLL, (unsigned char)(divisor & 0x00FF)); + PUT8(U0DLM, (unsigned char)(divisor >> 8)); + PUT8(U0LCR, 0x03); /* 8N1, DLAB=0 */ + PUT8(U0FCR, 1); /* Enable RX and TX FIFOs */ +} + +int serial_init (void) +{ + unsigned long pinsel0; + + serial_setbrg (); + + pinsel0 = GET32(PINSEL0); + pinsel0 &= ~(0x00000003); + pinsel0 |= 5; + PUT32(PINSEL0, pinsel0); + + return (0); +} + +void serial_putc (const char c) +{ + if (c == '\n') + { + while((GET8(U0LSR) & (1<<5)) == 0); /* Wait for empty U0THR */ + PUT8(U0THR, '\r'); + } + + while((GET8(U0LSR) & (1<<5)) == 0); /* Wait for empty U0THR */ + PUT8(U0THR, c); +} + +int serial_getc (void) +{ + while((GET8(U0LSR) & 1) == 0); + return GET8(U0RBR); +} + +void +serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} + +/* Test if there is a byte to read */ +int serial_tstc (void) +{ + return (GET8(U0LSR) & 1); +} + +#endif diff --git a/cpu/arm720t/start.S b/cpu/arm720t/start.S index e66d109443..96d5f54bac 100644 --- a/cpu/arm720t/start.S +++ b/cpu/arm720t/start.S @@ -43,7 +43,11 @@ _start: b reset ldr pc, _software_interrupt ldr pc, _prefetch_abort ldr pc, _data_abort +#ifdef CONFIG_LPC2292 + .word 0xB4405F76 /* 2's complement of the checksum of the vectors */ +#else ldr pc, _not_used +#endif ldr pc, _irq ldr pc, _fiq @@ -123,6 +127,10 @@ reset: bl cpu_init_crit #endif +#ifdef CONFIG_LPC2292 + bl lowlevel_init +#endif + #ifndef CONFIG_SKIP_RELOCATE_UBOOT relocate: /* relocate U-Boot to RAM */ adr r0, _start /* r0 <- current position of code */ @@ -131,6 +139,7 @@ relocate: /* relocate U-Boot to RAM */ beq stack_setup #if TEXT_BASE +#ifndef CONFIG_LPC2292 /* already done in lowlevel_init */ ldr r2, =0x0 /* Relocate the exception vectors */ cmp r1, r2 /* and associated data to address */ ldmneia r0!, {r3-r10} /* 0x0. Do nothing if TEXT_BASE is */ @@ -138,6 +147,7 @@ relocate: /* relocate U-Boot to RAM */ ldmneia r0, {r3-r9} stmneia r2, {r3-r9} adrne r0, _start /* restore r0 */ +#endif /* !CONFIG_LPC2292 */ #endif ldr r2, _armboot_start @@ -206,6 +216,14 @@ SYSCON3: .word 0x80002200 #define CLKCTL_49 0x4 /* 49.152 MHz */ #define CLKCTL_73 0x6 /* 73.728 MHz */ +#elif defined(CONFIG_LPC2292) +PLLCFG_ADR: .word PLLCFG +PLLFEED_ADR: .word PLLFEED +PLLCON_ADR: .word PLLCON +PLLSTAT_ADR: .word PLLSTAT +VPBDIV_ADR: .word VPBDIV +MEMMAP_ADR: .word MEMMAP + #endif cpu_init_crit: @@ -306,6 +324,50 @@ cpu_init_crit: #elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) /* No specific initialisation for IntegratorAP/CM720T as yet */ +#elif defined(CONFIG_LPC2292) + /* Set-up PLL */ + mov r3, #0xAA + mov r4, #0x55 + /* First disconnect and disable the PLL */ + ldr r0, PLLCON_ADR + mov r1, #0x00 + str r1, [r0] + ldr r0, PLLFEED_ADR /* start feed sequence */ + str r3, [r0] + str r4, [r0] /* feed sequence done */ + /* Set new M and P values */ + ldr r0, PLLCFG_ADR + mov r1, #0x23 /* M=4 and P=2 */ + str r1, [r0] + ldr r0, PLLFEED_ADR /* start feed sequence */ + str r3, [r0] + str r4, [r0] /* feed sequence done */ + /* Then enable the PLL */ + ldr r0, PLLCON_ADR + mov r1, #0x01 /* PLL enable bit */ + str r1, [r0] + ldr r0, PLLFEED_ADR /* start feed sequence */ + str r3, [r0] + str r4, [r0] /* feed sequence done */ + /* Wait for the lock */ + ldr r0, PLLSTAT_ADR + mov r1, #0x400 /* lock bit */ +lock_loop: + ldr r2, [r0] + and r2, r1, r2 + cmp r2, #0 + beq lock_loop + /* And finally connect the PLL */ + ldr r0, PLLCON_ADR + mov r1, #0x03 /* PLL enable bit and connect bit */ + str r1, [r0] + ldr r0, PLLFEED_ADR /* start feed sequence */ + str r3, [r0] + str r4, [r0] /* feed sequence done */ + /* Set-up VPBDIV register */ + ldr r0, VPBDIV_ADR + mov r1, #0x01 /* VPB clock is same as process clock */ + str r1, [r0] #else #error No cpu_init_crit() defined for current CPU type #endif @@ -321,6 +383,7 @@ cpu_init_crit: str r1, [r0] #endif +#ifndef CONFIG_LPC2292 mov ip, lr /* * before relocating, we have to setup RAM timing @@ -329,6 +392,7 @@ cpu_init_crit: */ bl lowlevel_init mov lr, ip +#endif mov pc, lr @@ -537,6 +601,11 @@ reset_cpu: * on external peripherals such as watchdog timers, etc. */ #elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) /* No specific reset actions for IntegratorAP/CM720T as yet */ +#elif defined(CONFIG_LPC2292) + .align 5 +.globl reset_cpu +reset_cpu: + mov pc, r0 #else #error No reset_cpu() defined for current CPU type #endif diff --git a/include/asm-arm/arch-arm720t/hardware.h b/include/asm-arm/arch-arm720t/hardware.h index 3056ca7f67..1e9cd41169 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 #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 0000000000..5715f3ef74 --- /dev/null +++ b/include/asm-arm/arch-arm720t/lpc2292_registers.h @@ -0,0 +1,225 @@ +#ifndef __LPC2292_REGISTERS_H +#define __LPC2292_REGISTERS_H + +#include + +/* 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 0000000000..e664a5f678 --- /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 0000000000..7e515230a3 --- /dev/null +++ b/include/configs/lpc2292sodimm.h @@ -0,0 +1,158 @@ +/* + * (C) Copyright 2000 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * 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 + +#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 8b7e824cca..55b6d8f388 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 -- 2.25.1