Example board for LPC2468 support Signed-off-by: Remco Poelstra <remco.poelstra+u-b...@duran-audio.com> --- diff -upNr u-boot-orig/board/LPC2468/config.mk u-boot/board/LPC2468/config.mk --- u-boot-orig/board/LPC2468/config.mk 1970-01-01 01:00:00.000000000 +0100 +++ u-boot/board/LPC2468/config.mk 2009-03-18 09:30:20.000000000 +0100 @@ -0,0 +1,29 @@ +# +# (C) Copyright 2000 +# Sysgo Real-Time Solutions, GmbH <www.elinos.com> +# Marius Groeger <mgroe...@sysgo.de> +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, w...@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +#address where u-boot will be relocated +TEXT_BASE = 0xA1f80000 diff -upNr u-boot-orig/board/LPC2468/eth.c u-boot/board/LPC2468/eth.c --- u-boot-orig/board/LPC2468/eth.c 1970-01-01 01:00:00.000000000 +0100 +++ u-boot/board/LPC2468/eth.c 2009-03-18 15:33:31.000000000 +0100 @@ -0,0 +1,694 @@ +/* + * (C) Copyright 2009 Duran Audio B.V. <www.duran-audio.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 + * + * 18-03-2009 Updated for U-boot 2009.3 by Remco Poelstra <remco.poelstra+u-b...@duran-audio.com> + * Based on sample code from NXP + */ + +#include <config.h> +#include <common.h> +#include <net.h> +#include <asm/arch/hardware.h> + +/****************************************************************************** + * Typedefs and defines + *****************************************************************************/ +#define MAX_PHY_INIT_RETRY 10 + +/* EMAC MODULE ID */ +#define OLD_EMAC_MODULE_ID ((0x3902 << 16) | 0x2000) + +/* MAC registers and parameters */ +#define PCONP_EMAC_CLOCK 0x40000000 + +#define SPEED_100 1 +#define SPEED_10 0 +#define FULL_DUPLEX 1 +#define HALF_DUPLEX 0 + +#define EMAC_RAM_ADDR 0x7FE00000 +#define EMAC_RAM_SIZE 0x00004000 + +//#define EMAC_TX_DESCRIPTOR_COUNT 0x0010 +//#define EMAC_RX_DESCRIPTOR_COUNT 0x0010 + +#define EMAC_TX_DESCRIPTOR_COUNT 5 +#define EMAC_RX_DESCRIPTOR_COUNT 4 + +/* + * (Rx|Tx)Descriptor :: + * [4] packet - base address of the buffer containing the data + * [4] control - control information + */ +#define TX_DESCRIPTOR_SIZE (EMAC_TX_DESCRIPTOR_COUNT * 8) +#define RX_DESCRIPTOR_SIZE (EMAC_RX_DESCRIPTOR_COUNT * 8) + +/* + * TxStatus :: + * [4] status + */ +#define TX_STATUS_SIZE (EMAC_TX_DESCRIPTOR_COUNT * 4) + +/* + * RxStatus :: + * [4] status - receive status flags + * [4] statusHashCRC - concat of dest addr hash CRC and src addr CRC + */ +#define RX_STATUS_SIZE (EMAC_RX_DESCRIPTOR_COUNT * 8) + +#define TOTAL_DESCRIPTOR_SIZE (TX_DESCRIPTOR_SIZE + RX_DESCRIPTOR_SIZE + TX_STATUS_SIZE + RX_STATUS_SIZE) + +/* descriptors are placed at the end of the emac address space */ +#define EMAC_DESCRIPTOR_ADDR (EMAC_RAM_ADDR + EMAC_RAM_SIZE - TOTAL_DESCRIPTOR_SIZE) + +#define TX_DESCRIPTOR_ADDR EMAC_DESCRIPTOR_ADDR +#define TX_STATUS_ADDR (EMAC_DESCRIPTOR_ADDR + TX_DESCRIPTOR_SIZE) +#define RX_DESCRIPTOR_ADDR (TX_STATUS_ADDR + TX_STATUS_SIZE) +#define RX_STATUS_ADDR (RX_DESCRIPTOR_ADDR + RX_DESCRIPTOR_SIZE) + +#define EMAC_DMA_ADDR EMAC_RAM_ADDR +#define EMAC_DMA_SIZE EMAC_RAM_ADDR + EMAC_RAM_END - TOTAL_DESCRIPTOR_SIZE + +#define EMAC_BLOCK_SIZE 0x600 +#define EMAC_TX_BLOCK_NUM 5 +#define EMAC_RX_BLOCK_NUM 5 +#define TOTAL_EMAC_BLOCK_NUM 10 + +#define EMAC_BUFFER_SIZE (EMAC_BLOCK_SIZE * (EMAC_TX_BLOCK_NUM + EMAC_RX_BLOCK_NUM )) +#define EMAC_TX_BUFFER_ADDR EMAC_RAM_ADDR +#define EMAC_RX_BUFFER_ADDR (EMAC_RAM_ADDR + EMAC_BLOCK_SIZE * EMAC_TX_BLOCK_NUM) + +/* EMAC Descriptor TX and RX Control fields */ +#define EMAC_TX_DESC_INT 0x80000000 +#define EMAC_TX_DESC_LAST 0x40000000 +#define EMAC_TX_DESC_CRC 0x20000000 +#define EMAC_TX_DESC_PAD 0x10000000 +#define EMAC_TX_DESC_HUGE 0x08000000 +#define EMAC_TX_DESC_OVERRIDE 0x04000000 + +#define EMAC_RX_DESC_INT 0x80000000 + +/* EMAC Descriptor status related definition */ +#define TX_DESC_STATUS_ERR 0x80000000 +#define TX_DESC_STATUS_NODESC 0x40000000 +#define TX_DESC_STATUS_UNDERRUN 0x20000000 +#define TX_DESC_STATUS_LCOL 0x10000000 +#define TX_DESC_STATUS_ECOL 0x08000000 +#define TX_DESC_STATUS_EDEFER 0x04000000 +#define TX_DESC_STATUS_DEFER 0x02000000 +#define TX_DESC_STATUS_COLCNT 0x01E00000 /* four bits, it's a mask, not exact count */ + +#define RX_DESC_STATUS_ERR 0x80000000 +#define RX_DESC_STATUS_LAST 0x40000000 +#define RX_DESC_STATUS_NODESC 0x20000000 +#define RX_DESC_STATUS_OVERRUN 0x10000000 +#define RX_DESC_STATUS_ALGNERR 0x08000000 +#define RX_DESC_STATUS_RNGERR 0x04000000 +#define RX_DESC_STATUS_LENERR 0x02000000 +#define RX_DESC_STATUS_SYMERR 0x01000000 +#define RX_DESC_STATUS_CRCERR 0x00800000 +#define RX_DESC_STATUS_BCAST 0x00400000 +#define RX_DESC_STATUS_MCAST 0x00200000 +#define RX_DESC_STATUS_FAILFLT 0x00100000 +#define RX_DESC_STATUS_VLAN 0x00080000 +#define RX_DESC_STATUS_CTLFRAM 0x00040000 + +#define DESC_SIZE_MASK 0x000007FF /* 11 bits for both TX and RX */ + +/* EMAC interrupt controller related definition */ +#define EMAC_INT_RXOVERRUN 0x01 << 0 +#define EMAC_INT_RXERROR 0x01 << 1 +#define EMAC_INT_RXFINISHED 0x01 << 2 +#define EMAC_INT_RXDONE 0x01 << 3 +#define EMAC_INT_TXUNDERRUN 0x01 << 4 +#define EMAC_INT_TXERROR 0x01 << 5 +#define EMAC_INT_TXFINISHED 0x01 << 6 +#define EMAC_INT_TXDONE 0x01 << 7 +#define EMAC_INT_SOFTINT 0x01 << 12 +#define EMAC_INT_WOL 0x01 << 13 + +/* Micrel KSZ8001 PHY related registers */ + +/* PHY_ADDR, by default, AD0 has pull-up, AD1~4 have pull-downs, +so, the default address is 0x0001 */ +//#define PHY_ADDR (0x0000 << 8) /* in MAC_MADR, bit 8~12 */ + +static volatile int phyAddr = 0x1000; +#define NATIONAL_PHY 0 +#define MICREL_PHY 1 +static volatile int phyType = MICREL_PHY; + +#define PHY_BMCR 0x0000 +#define PHY_BMSR 0x0001 +#define PHY_PHYIDR1 0x0002 +#define PHY_PHYIDR2 0x0003 +#define PHY_ANAR 0x0004 +#define PHY_ANLPAR 0x0005 +#define PHY_ANLPARNP 0x0005 +#define PHY_ANER 0x0006 +#define PHY_ANNPTR 0x0007 + +/* BMCR setting */ +#define BMCR_RESET 0x8000 +#define BMCR_LOOPBACK 0x4000 +#define BMCR_SPEED_100 0x2000 +#define BMCR_AN 0x1000 +#define BMCR_POWERDOWN 0x0800 +#define BMCR_ISOLATE 0x0400 +#define BMCR_RE_AN 0x0200 +#define BMCR_DUPLEX 0x0100 + +/* BMSR setting */ +#define BMSR_100BE_T4 0x8000 +#define BMSR_100TX_FULL 0x4000 +#define BMSR_100TX_HALF 0x2000 +#define BMSR_10BE_FULL 0x1000 +#define BMSR_10BE_HALF 0x0800 +#define BMSR_AUTO_DONE 0x0020 +#define BMSR_REMOTE_FAULT 0x0010 +#define BMSR_NO_AUTO 0x0008 +#define BMSR_LINK_ESTABLISHED 0x0004 + +#define MII_BMSR_TIMEOUT 0x1000000 + +#define CMD_RX_ENABLE 0x01 +#define CMD_TX_ENABLE 0x02 +#define CMD_PASS_RX_FILTER 0x80 + +#ifndef IRQ_EXT3 +#define IRQ_EXT3 LPC2294_INTERRUPT_EINT3 +#endif + +#define m_nic_bfs(reg, data) reg |= (data) +#define m_nic_bfc(reg, data) reg &= ~(data) + +#define printk printf + +#define m_nic_read(reg) (*(volatile unsigned long *)(reg)) +#define m_nic_write(reg, data) ((*(volatile unsigned long *)(reg)) = (volatile unsigned long)(data)) + +/****************************************************************************** + * Local variables + *****************************************************************************/ + +//static struct eth_device _dev_emac; +static volatile u32 emacDuplex; +static volatile u32 emacSpeed; +static unsigned char macAddr[6]; +static int opened = 0; + +/****************************************************************************** + * Local functions + *****************************************************************************/ + +static void writePhy(u32 phyReg, u32 phyData) +{ + + // write command + MAC_MCMD = 0x0000; + + // [12:8] == PHY addr, [4:0]=0x00(BMCR) register addr + MAC_MADR = (phyAddr | phyReg); + MAC_MWTD = phyData; + while (MAC_MIND != 0) ; +} + +static u32 readPhy(u32 phyReg) +{ + + // read command + MAC_MCMD = 0x0001; + + // [12:8] == PHY addr, [4:0]=0x00(BMCR) register addr + MAC_MADR = (phyAddr | phyReg); + + while (MAC_MIND != 0) ; + + MAC_MCMD = 0x0000; + + return MAC_MRDD; +} + +static int emac_start_xmit(volatile void *buf, int length) +{ + + u32 txProduceIndex = 0; + u32 txConsumeIndex = 0; + u8 *pData = 0; + u32 len = length; //skb->len; + u32 sendLen = 0; + u32 *tx_desc_addr = NULL; + + txProduceIndex = MAC_TXPRODUCEINDEX; + txConsumeIndex = MAC_TXCONSUMEINDEX; + +// printf("emac_start_xmit: pIdx = %d, cIdx=%d\n", +// txProduceIndex, txConsumeIndex); + + if (txConsumeIndex != txProduceIndex) { + // TODO why return here? This just means that the transmit array isn't empty + printk("emac: emac_tx transmit array isn't empty\n"); + return -1; + } + + if (txProduceIndex == EMAC_TX_DESCRIPTOR_COUNT) { + // should never happen + // TODO remove + printk("emac: emac_tx produce index == count\n"); + } + + if (len > 0) { + pData = (u8 *) EMAC_TX_BUFFER_ADDR; + memcpy(pData, (void *)buf, length); + + do { + tx_desc_addr = + (u32 *) (TX_DESCRIPTOR_ADDR + txProduceIndex * 8); + + sendLen = len; + if (sendLen > EMAC_BLOCK_SIZE) { + sendLen = EMAC_BLOCK_SIZE; + } else { + // last fragment + sendLen |= EMAC_TX_DESC_LAST; + } + + m_nic_write(tx_desc_addr, (u32) pData); + tx_desc_addr++; + m_nic_write(tx_desc_addr, + (u32) (EMAC_TX_DESC_INT | (sendLen - 1))); + + txProduceIndex++; + if (txProduceIndex == EMAC_TX_DESCRIPTOR_COUNT) { + txProduceIndex = 0; + } + + MAC_TXPRODUCEINDEX = txProduceIndex; + + len -= (sendLen & ~EMAC_TX_DESC_LAST); + pData += (sendLen & ~EMAC_TX_DESC_LAST); + } while (len > 0); + } + + return 0; +} + +static void emac_rx(void) +{ + u32 rxProduceIndex = 0; + u32 rxConsumeIndex = 0; + u32 *rxStatusAddr = 0; + u32 recvSize = 0; + u32 *recvAddr = 0; + + /* the input parameter, EMCBuf, needs to be word aligned */ + + rxProduceIndex = MAC_RXPRODUCEINDEX; + rxConsumeIndex = MAC_RXCONSUMEINDEX; + + // consume the received packets + while (rxConsumeIndex != rxProduceIndex) { + + rxStatusAddr = (u32 *) (RX_STATUS_ADDR + rxConsumeIndex * 8); + + recvSize = m_nic_read(rxStatusAddr); + + if ((recvSize & RX_DESC_STATUS_LAST) == 0) { + // TODO: could this occur when EMAC_BLOCK_SIZE == 0x0600? + printk("emac_rx: NOT LAST fragment\n"); + } + + recvSize = (recvSize & DESC_SIZE_MASK) + 1; + + recvAddr = (u32 *) (RX_DESCRIPTOR_ADDR + rxConsumeIndex * 8); + + // TODO: allocate buffer? + NetReceive((uchar *) (m_nic_read(recvAddr) /*inBuf */ ), + recvSize); + + rxConsumeIndex++; + if (rxConsumeIndex == EMAC_RX_DESCRIPTOR_COUNT) { + rxConsumeIndex = 0; + } + + MAC_RXCONSUMEINDEX = rxConsumeIndex; + + } + +} + +static void emac_interrupt(void) +{ + //struct net_device *dev = dev_id; +// struct eth_device* dev = &_dev_emac; + + volatile u32 regValue = 0; + + regValue = MAC_INTSTATUS; + + do { + if (regValue == 0) { + break; + } + + if (regValue & EMAC_INT_RXOVERRUN) { + MAC_INTCLEAR = EMAC_INT_RXOVERRUN; + printk("rxOverrun\n"); + break; + } + + if (regValue & EMAC_INT_RXERROR) { + MAC_INTCLEAR = EMAC_INT_RXERROR; + +/* + { + u32 rxConsumeIndex = m_nic_read(EMAC_RXCONSUMEINDEX); + u32* rxStatusAddr = (tU32*)(RX_STATUS_ADDR + rxConsumeIndex * 8); + u32 val = m_nic_read(rxStatusAddr); + + printf("val = %x\n", val); + } +*/ + + //break; + } + + if (regValue & EMAC_INT_RXFINISHED) { + MAC_INTCLEAR = EMAC_INT_RXFINISHED; + } + + if (regValue & EMAC_INT_RXDONE) { + MAC_INTCLEAR = EMAC_INT_RXDONE; + emac_rx(); + } + + if (regValue & EMAC_INT_TXUNDERRUN) { + printf("TX underrun\n"); + MAC_INTCLEAR = EMAC_INT_TXUNDERRUN; + break; + } + + if (regValue & EMAC_INT_TXERROR) { + printf("TX err\n"); + MAC_INTCLEAR = EMAC_INT_TXERROR; + + break; + } + + if (regValue & EMAC_INT_TXFINISHED) { + MAC_INTCLEAR = EMAC_INT_TXFINISHED; + } + + if (regValue & EMAC_INT_TXDONE) { + MAC_INTCLEAR = EMAC_INT_TXDONE; + } + + } while (0); +} + +static int emac_open(void) +{ + + opened = 1; + + // enable Rx & Tx + m_nic_bfs(MAC_COMMAND, CMD_RX_ENABLE); + m_nic_bfs(MAC_COMMAND, CMD_TX_ENABLE); + m_nic_bfs(MAC_COMMAND, CMD_PASS_RX_FILTER); + m_nic_bfs(MAC_MAC1, 0x01); + + return 0; +} + +//static int emac_close(struct net_device *dev) +static void emac_close(void) +{ + opened = 0; + + // disable Rx6 Tx + m_nic_bfc(MAC_COMMAND, CMD_RX_ENABLE); + m_nic_bfc(MAC_COMMAND, CMD_TX_ENABLE); + m_nic_bfc(MAC_MAC1, 0x01); +} + +static int phyInit(void) +{ + int i = 0; + u32 regValue = 0; + u32 timeout = 0; + + MAC_MCFG = 0x801C; /* host clock divided by 28, no suppress preamble, no scan increment */ + for (i = 0; i < 0x40; i++) + asm volatile (" nop"); + + // MII Mgmt. Divided by 28. + MAC_MCFG = 0x001C; + MAC_MCMD = 0; + + for (i = 0; i < 0x100; i++) + asm volatile (" nop"); + + /*Reset the PHY */ + writePhy(PHY_BMCR, BMCR_RESET); + udelay(100); + + timeout = MII_BMSR_TIMEOUT * 4; + while (timeout != 0) { + regValue = readPhy(PHY_BMCR); + if ((regValue & BMCR_RESET) == 0x0000) { + // reset bit has been cleared + break; + } + timeout--; + } + + if (timeout == 0) { + printk(" Error: phyInit failed to reset PHY\n"); + return -1; + } + // check PHY IDs. + phyAddr = 0x1000; + +// writePhy(PHY_BMCR,BMCR_POWERDOWN); +// printf("BMCR: %x\n",readPhy(PHY_BMCR)); + return 0; +} + +static void emacTxDescriptorInit(void) +{ + int i = 0; + u32 *txDescAddr = NULL; + u32 *txStatusAddr = NULL; + + // base address of tx descriptor array + MAC_TXDESCRIPTOR = TX_DESCRIPTOR_ADDR; + + // base address of tx status + MAC_TXSTATUS = TX_STATUS_ADDR; + + // number of tx descriptors + MAC_TXDESCRIPTORNUM = EMAC_TX_DESCRIPTOR_COUNT - 1; + + for (i = 0; i < EMAC_TX_DESCRIPTOR_COUNT; i++) { + txDescAddr = (u32 *) (TX_DESCRIPTOR_ADDR + i * 8); + m_nic_write(txDescAddr, + (EMAC_TX_BUFFER_ADDR + i * EMAC_BLOCK_SIZE)); + + // control field in descriptor + txDescAddr++; + m_nic_write(txDescAddr, + (EMAC_TX_DESC_INT | (EMAC_BLOCK_SIZE - 1))); + } + + for (i = 0; i < EMAC_TX_DESCRIPTOR_COUNT; i++) { + + txStatusAddr = (u32 *) (TX_STATUS_ADDR + i * 4); + + // set status info to 0 + m_nic_write(txStatusAddr, 0); + } + + MAC_TXPRODUCEINDEX = 0; +} + +static void emacRxDescriptorInit(void) +{ + int i; + u32 *rxDescAddr = NULL; + u32 *rxStatusAddr = NULL; + + // base address of rx descriptor array + MAC_RXDESCRIPTOR = RX_DESCRIPTOR_ADDR; + + // base address of rx status + MAC_RXSTATUS = RX_STATUS_ADDR; + + // number of rx descriptors + MAC_RXDESCRIPTORNUM = EMAC_RX_DESCRIPTOR_COUNT - 1; + + for (i = 0; i < EMAC_RX_DESCRIPTOR_COUNT; i++) { + rxDescAddr = (u32 *) (RX_DESCRIPTOR_ADDR + i * 8); + m_nic_write(rxDescAddr, + (EMAC_RX_BUFFER_ADDR + i * EMAC_BLOCK_SIZE)); + rxDescAddr++; + m_nic_write(rxDescAddr, + (EMAC_RX_DESC_INT | + ((EMAC_BLOCK_SIZE - 1) & DESC_SIZE_MASK))); + } + + for (i = 0; i < EMAC_RX_DESCRIPTOR_COUNT; i++) { + // RX status, two words, status info. and status hash CRC. + rxStatusAddr = (u32 *) (RX_STATUS_ADDR + i * 8); + m_nic_write(rxStatusAddr, 0); + rxStatusAddr++; + m_nic_write(rxStatusAddr, 0); + } + + MAC_RXCONSUMEINDEX = 0; +} + +static int emacInit(void) +{ + int i = 0; + + // turn on the ethernet MAC clock in PCONP, bit 30 + m_nic_bfs(PCONP, PCONP_EMAC_CLOCK); + + /*------------------------------------------------------------------------------ + * write to PINSEL2/3 to select the PHY functions on P1[17:0] + *-----------------------------------------------------------------------------*/ + /* documentation needs to be updated */ + PINSEL2 = 0x55555555; /* selects P1[0,1,4,8,9,10,14,15] */ + PINSEL3 = 0x00000005; /* selects P1[17:16] */ + + // reset MAC modules, tx, mcs_tx, rx, mcs_rx, simulation and soft reset + MAC_MAC1 = 0xCF00; + + // reset datapaths and host registers + MAC_COMMAND = 0x0038; + + // short delay after reset + for (i = 0; i < 0x40; i++) + asm volatile (" nop"); + + //Remove reset conditions + MAC_MAC1 = 0x0; + + // disable Tx + m_nic_bfc(MAC_COMMAND, CMD_TX_ENABLE); + // disable Rx + m_nic_bfc(MAC_COMMAND, CMD_RX_ENABLE); + + // initialize MAC2 to default value + // TODO don't thinkt this is necessary?? m_nic_write(EMAC_MAC2, 0x0); + MAC_MAC2 = 0x030; + // non back-to-back Inter-Packet-Gap register + // The manual recommends the value 0x12 + MAC_IPGR = 0x12; + + // collision window/retry register. Using recommended value from manual. + MAC_CLRT = 0x370F; + + // intialize PHY. emacSpeed and emacDuplex will be set in phyInit + if (phyInit() < 0) + return -1; + + // write the mac address + MAC_SA0 = (macAddr[5] << 8 | macAddr[4]); + MAC_SA1 = (macAddr[3] << 8 | macAddr[2]); + MAC_SA2 = (macAddr[1] << 8 | macAddr[0]); + + printk("emac: MAC address = %2x:%2x:%2x:%2x:%2x:%2x\n", macAddr[0], + macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]); + + emacTxDescriptorInit(); + emacRxDescriptorInit(); + + // pass all receive frames + m_nic_bfs(MAC_MAC1, 0x002); + + // set up the Rx filter + // [0]-AllUnicast, [1]-AllBroadCast, [2]-AllMulticast, [3]-UnicastHash + // [4]-MulticastHash, [5]-Perfect, [12]-MagicPacketEnWoL, [13]-RxFilterEnWoL +// MAC_RXFILTERCTRL=0x0022; + MAC_RXFILTERCTRL = 0x003F; //Pass everything + + // clear all interrupts + MAC_INTCLEAR = 0xFFFF; + + // TODO the irq is installed here in sample code !! + + // enable interrupts (not SoftInt and WoL) + MAC_INTENABLE = 0x00FF; + + return 0; +} + +/* ############################## + * u-boot interface + * ############################## + */ +static int eth_initialized = 0; +/*----------------------------------------------------------------------------- + * Returns 0 when failes otherwise 1 + */ +int eth_init(bd_t * bis) +{ + int ret; + + if (!eth_initialized) { + if (!eth_getenv_enetaddr("ethaddr", macAddr)) { + printf("Failed to get MAC address from environment\n"); + return 1; + } + + ret = emacInit(); + if (ret != 0) { + return ret; + } + + eth_initialized = 1; + } + + emac_open(); + + return 0; +} + +int eth_send(volatile void *packet, int length) +{ + emac_start_xmit(packet, length); + + return 0; +} + +/*----------------------------------------------------------------------------- + * Check for received packets. Call NetReceive for each packet. The return + * value is ignored by the caller. + */ +int eth_rx(void) +{ + emac_interrupt(); + + return 0; +} + +void eth_halt(void) +{ + emac_close(); +} diff -upNr u-boot-orig/board/LPC2468/flash.c u-boot/board/LPC2468/flash.c --- u-boot-orig/board/LPC2468/flash.c 1970-01-01 01:00:00.000000000 +0100 +++ u-boot/board/LPC2468/flash.c 2009-03-18 15:32:37.000000000 +0100 @@ -0,0 +1,253 @@ +/* + * (C) Copyright 2006 Embedded Artists AB <www.embeddedartists.com> + * + * (C) Copyright 2009 Duran Audio B.V. <www.duran-audio.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 + * + * 18-03-2009 Updated for U-boot 2009.3 by Remco Poelstra <remco.poelstra+u-b...@duran-audio.com> + */ + +#include <common.h> +#include <asm/arch/hardware.h> + +#define SST_BASEADDR 0x80000000 +#define SST_ADDR1 ((volatile ushort*)(SST_BASEADDR + (0x5555<<1))) +#define SST_ADDR2 ((volatile ushort*)(SST_BASEADDR + (0x2AAA<<1))) + +flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; + +extern void iap_entry(unsigned long *command, unsigned long *result); + +extern int lpc24xx_copy_buffer_to_flash(flash_info_t *, ulong); +extern int lpc24xx_flash_erase(flash_info_t *, int, int); +extern int lpc24xx_write_buff(flash_info_t *, uchar *, ulong, ulong); + +/*----------------------------------------------------------------------- + * + */ + +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_LPC2468 & FLASH_VENDMASK); + flash_info[0].size = 0x007D000; /* 512 - 12 KB */ + flash_info[0].sector_count = 27; + memset(flash_info[0].protect, 0, 27); + flashbase = 0x00000000; + for (j = 0, k = 0; j < 8; j++, k++) { + flash_info[0].start[k] = flashbase; + flashbase += 0x00001000; + } + for (j = 0; j < 14; j++, k++) { + flash_info[0].start[k] = flashbase; + flashbase += 0x00008000; + } + for (j = 0; j < 5; j++, k++) { + flash_info[0].start[k] = flashbase; + flashbase += 0x00001000; + } + size += flash_info[0].size; + + flash_info[1].flash_id = (SST_MANUFACT & FLASH_VENDMASK); + flash_info[1].size = 0x00400000; /* 4 MB */ + flash_info[1].sector_count = 1024; + memset(flash_info[1].protect, 0, 1024); + flashbase = SST_BASEADDR; + for (j = 0; j < 1024; 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]); + +#ifdef CFG_ENV_IS_IN_FLASH + flash_protect(FLAG_PROTECT_SET, + CONFIG_ENV_ADDR, + CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]); +#endif + + 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_LPC2468 & 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_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_LPC2468 & FLASH_VENDMASK): + return lpc24xx_flash_erase(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(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_LPC2468 & FLASH_VENDMASK): + return lpc24xx_write_buff(info, src, addr, cnt); + default: + return ERR_PROG_ERROR; + } + return ERR_PROG_ERROR; +} diff -upNr u-boot-orig/board/LPC2468/lowlevel_init.c u-boot/board/LPC2468/lowlevel_init.c --- u-boot-orig/board/LPC2468/lowlevel_init.c 1970-01-01 01:00:00.000000000 +0100 +++ u-boot/board/LPC2468/lowlevel_init.c 2009-03-18 15:35:21.000000000 +0100 @@ -0,0 +1,436 @@ +/* + * (C) Copyright 2006-2007 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 <exports.h> +#include <asm/arch/hardware.h> +#include <asm/hardware.h> + +/****************************************************************************** + * Defines, macros, and typedefs + *****************************************************************************/ + +#define USE_USB 1 + +#define PLL_MValue (CONFIG_PLL_MVALUE-1) +#define PLL_NValue (CONFIG_PLL_NVALUE-1) +#define CCLKDivValue (CONFIG_PLL_CLKDIV-1) +#define USBCLKDivValue (CONFIG_PLL_USBCLKDIV-1) + +#define Fcco ((2*CONFIG_PLL_MVALUE*CONFIG_FOSC) / CONFIG_PLL_NVALUE) +#define Fcclk (Fcco / CONFIG_PLL_CLKDIV) +#define Fpclk (Fcclk / CONFIG_FPCLK_DIV) +#define MAM_SETTING 1 /* 0=disabled, + 1=partly enabled (enabled for code prefetch, but not for data), + 2=fully enabled */ +#define MEM_MAP 2 /* When executing from RAM, MAM_MAP should always be 2 */ +#define SDRAM_BASE_ADDR 0xA0000000 +#define m_reg_write(reg,data) ((*(volatile unsigned long *)(reg)) = (volatile unsigned long)(data)) +/***************************************************************************** + * + * Description: + * Delay execution by a specified number of milliseconds by using + * timer #1. A polled implementation. + * + * Params: + * [in] delayInMs - the number of milliseconds to delay. + * + ****************************************************************************/ +void delayMs(unsigned short delayInMs) +{ + /* + * setup timer #1 for delay + */ + T1TCR = 0x02; //stop and reset timer + T1PR = 0x00; //set prescaler to zero + T1MR0 = delayInMs * (Fpclk / 1000); + + T1IR = 0xff; //reset all interrrupt flags + T1MCR = 0x04; //stop timer on match + T1TCR = 0x01; //start timer + + //wait until delay time has elapsed + while (T1TCR & 0x01) + ; + +} + +/****************************************************************************** +** Function name: GPIOinit +** +** Descriptions: Sets all GPIO ports to a known state +** parameters: None +** Returned value: None +** +******************************************************************************/ +static void GPIOinit(void) +{ + PINSEL0 = 0; + PINSEL1 = 0; + PINSEL2 = 0; + PINSEL3 = 0; + PINSEL4 = 0; + PINSEL5 = 0; + PINSEL6 = 0; + PINSEL7 = 0; + PINSEL8 = 0; + PINSEL9 = 0; + PINSEL10 = 0; + + IODIR0 = 0; + IODIR1 = 0; + IOSET0 = 0xffffffff; + IOSET1 = 0xffffffff; + + FIO0DIR = 0; + FIO1DIR = 0; + FIO2DIR = 0; + FIO3DIR = 0; + FIO4DIR = 0; + + FIO0SET = 0xffffffff; + FIO1SET = 0xffffffff; + FIO2SET = 0xffffffff; + FIO3SET = 0x0; + FIO4SET = 0xffffffff; +} + +/****************************************************************************** +** Function name: VICinit +** +** Descriptions: Initialize the VIC to a known state +** parameters: None +** Returned value: None +** +******************************************************************************/ +static void VICinit(void) +{ + //initialize VIC + VICIntEnClr = 0xFFFFFFFF; /* Disable ALL interrupts */ + + VICProtection = 0; /* Setup interrupt controller */ + VICVectAddr = 0; + VICIntSelect = 0; + + VICVectAddr0 = (unsigned int)0; /* Set the vector address */ + VICVectAddr1 = (unsigned int)0; /* Set the vector address */ + VICVectAddr2 = (unsigned int)0; /* Set the vector address */ + VICVectAddr3 = (unsigned int)0; /* Set the vector address */ + VICVectAddr4 = (unsigned int)0; /* Set the vector address */ + VICVectAddr5 = (unsigned int)0; /* Set the vector address */ + VICVectAddr6 = (unsigned int)0; /* Set the vector address */ + VICVectAddr7 = (unsigned int)0; /* Set the vector address */ + VICVectAddr8 = (unsigned int)0; /* Set the vector address */ + VICVectAddr9 = (unsigned int)0; /* Set the vector address */ + VICVectAddr10 = (unsigned int)0; /* Set the vector address */ + VICVectAddr11 = (unsigned int)0; /* Set the vector address */ + VICVectAddr12 = (unsigned int)0; /* Set the vector address */ + VICVectAddr13 = (unsigned int)0; /* Set the vector address */ + VICVectAddr14 = (unsigned int)0; /* Set the vector address */ + VICVectAddr15 = (unsigned int)0; /* Set the vector address */ + VICVectAddr16 = (unsigned int)0; /* Set the vector address */ + VICVectAddr17 = (unsigned int)0; /* Set the vector address */ + VICVectAddr18 = (unsigned int)0; /* Set the vector address */ + VICVectAddr19 = (unsigned int)0; /* Set the vector address */ + VICVectAddr20 = (unsigned int)0; /* Set the vector address */ + VICVectAddr21 = (unsigned int)0; /* Set the vector address */ + VICVectAddr22 = (unsigned int)0; /* Set the vector address */ + VICVectAddr23 = (unsigned int)0; /* Set the vector address */ + VICVectAddr24 = (unsigned int)0; /* Set the vector address */ + VICVectAddr25 = (unsigned int)0; /* Set the vector address */ + VICVectAddr26 = (unsigned int)0; /* Set the vector address */ + VICVectAddr27 = (unsigned int)0; /* Set the vector address */ + VICVectAddr28 = (unsigned int)0; /* Set the vector address */ + VICVectAddr29 = (unsigned int)0; /* Set the vector address */ + VICVectAddr30 = (unsigned int)0; /* Set the vector address */ + VICVectAddr31 = (unsigned int)0; /* Set the vector address */ + + VICVectCntl0 = (unsigned int)0xf; + VICVectCntl1 = (unsigned int)0xf; + VICVectCntl2 = (unsigned int)0xf; + VICVectCntl3 = (unsigned int)0xf; + VICVectCntl4 = (unsigned int)0xf; + VICVectCntl5 = (unsigned int)0xf; + VICVectCntl6 = (unsigned int)0xf; + VICVectCntl7 = (unsigned int)0xf; + VICVectCntl8 = (unsigned int)0xf; + VICVectCntl9 = (unsigned int)0xf; + VICVectCntl10 = (unsigned int)0xf; + VICVectCntl11 = (unsigned int)0xf; + VICVectCntl12 = (unsigned int)0xf; + VICVectCntl13 = (unsigned int)0xf; + VICVectCntl14 = (unsigned int)0xf; + VICVectCntl15 = (unsigned int)0xf; + VICVectCntl16 = (unsigned int)0xf; + VICVectCntl17 = (unsigned int)0xf; + VICVectCntl18 = (unsigned int)0xf; + VICVectCntl19 = (unsigned int)0xf; + VICVectCntl20 = (unsigned int)0xf; + VICVectCntl21 = (unsigned int)0xf; + VICVectCntl22 = (unsigned int)0xf; + VICVectCntl23 = (unsigned int)0xf; + VICVectCntl24 = (unsigned int)0xf; + VICVectCntl25 = (unsigned int)0xf; + VICVectCntl26 = (unsigned int)0xf; + VICVectCntl27 = (unsigned int)0xf; + VICVectCntl28 = (unsigned int)0xf; + VICVectCntl29 = (unsigned int)0xf; + VICVectCntl30 = (unsigned int)0xf; + VICVectCntl31 = (unsigned int)0xf; +} + +/****************************************************************************** +** Function name: ConfigurePLL +** +** Descriptions: Configure the PLL +** parameters: None +** Returned value: None +** +******************************************************************************/ +void ConfigurePLL(void) +{ + + volatile unsigned long MValue; + volatile unsigned long NValue; + + if (PLLSTAT & (1 << 25)) + { + + PLLCON = 1; /* Enable PLL, disconnected */ + + PLLFEED = 0xaa; + + PLLFEED = 0x55; + + } + + PLLCON = 0; /* Disable PLL, disconnected */ + PLLFEED = 0xaa; + PLLFEED = 0x55; + SCS |= 0x20; /* Enable main OSC */ + + while (!(SCS & 0x40)) ; /* Wait until main OSC is usable */ + + CLKSRCSEL = 0x1; /* select main OSC, 12MHz, as the PLL clock source */ + PLLCFG = PLL_MValue | (PLL_NValue << 16); + PLLFEED = 0xaa; + PLLFEED = 0x55; + PLLCON = 1; /* Enable PLL, disconnected */ + PLLFEED = 0xaa; + PLLFEED = 0x55; + CCLKCFG = CCLKDivValue; /* Set clock divider */ + +#if USE_USB + USBCLKCFG = USBCLKDivValue; /* usbclk = 288 MHz/6 = 48 MHz */ + +#endif /* + */ + + while (((PLLSTAT & (1 << 26)) == 0)) ; /* Check lock bit status */ + + MValue = PLLSTAT & 0x00007FFF; + NValue = (PLLSTAT & 0x00FF0000) >> 16; + + while ((MValue != PLL_MValue) && (NValue != PLL_NValue)) ; + + PLLCON = 3; /* enable and connect */ + PLLFEED = 0xaa; + PLLFEED = 0x55; + + while (((PLLSTAT & (1 << 25)) == 0)) ; /* Check connect bit status */ + +} + +/****************************************************************************** +** Function name: ConfigureEMC +** +** Descriptions: Configure EMC for external SDRAM, NAND and NOR FLASH +** parameters: None +** Returned value: None +** +******************************************************************************/ +void ConfigureEMC(void) +{ + + volatile unsigned int i, dummy = dummy; + + EMC_CTRL = 0x00000001; + PCONP |= 0x00000800; /* Turn on EMC PCLK */ + + // CS2 & CS3 not used PINSEL4 = 0x50000000; + PINSEL5 = 0x05050555; + PINSEL6 = 0x55555555; + PINSEL8 = 0x55555555; + PINSEL9 = 0x50555555; + + //all registers... + EMC_DYN_RP = 2; //>20ns = 2 clk + EMC_DYN_RAS = 3; //>45ns = 3 clk + EMC_DYN_SREX = 7; //>80-100ns = 6 clk + EMC_DYN_APR = 2; // + EMC_DYN_DAL = 5; //2 clk + EMC_DYN_WR = 1; //2 clk + EMC_DYN_RC = 5; //>65ns = 4 clk + EMC_DYN_RFC = 5; //>80-100ns = 6 clk + EMC_DYN_XSR = 7; //>80-100ns = 6 clk + EMC_DYN_RRD = 1; //>15ns = 1-2 clk + EMC_DYN_MRD = 2; //2 clk + EMC_DYN_RD_CFG = 1; //or 1,2,3 + + // + EMC_DYN_RASCAS0 = 0x00000303; + + // + EMC_DYN_CFG0 = 0x00000680; + + //wait 100mS + delayMs(100); + + //Send command: NOP + EMC_DYN_CTRL = 0x00000183; + + //wait 200mS + delayMs(200); + + //Send command: PRECHARGE-ALL, shortest possible refresh period + EMC_DYN_CTRL = 0x00000103; + + EMC_DYN_RFSH = 0x00000002; + + //wait 128 ABH clock cycles + for (i = 0; i < 0x40; i++) + asm volatile (" nop"); + + //Set correct refresh period + EMC_DYN_RFSH = 28; + + //Send command: MODE + EMC_DYN_CTRL = 0x00000083; + + //Set mode register in SDRAM + dummy = *((volatile unsigned int *)(SDRAM_BASE_ADDR | (0x33 << 12))); + + //Send command: NORMAL + EMC_DYN_CTRL = 0x00000000; + + //Enable buffer + EMC_DYN_CFG0 |= 0x00080000; + + //initial system delay + delayMs(1); + + EMC_STA_WAITWEN0 = 0x2; + EMC_STA_WAITOEN0 = 0x2; + EMC_STA_WAITRD0 = 0x1f; + EMC_STA_WAITPAGE0 = 0x1f; + EMC_STA_WAITWR0 = 0x1f; + EMC_STA_WAITTURN0 = 0xf; + EMC_STA_CFG0 = 0x00000081; + EMC_STA_WAITWEN1 = 0x2; + EMC_STA_WAITOEN1 = 0x2; + EMC_STA_WAITRD1 = 0x8; + EMC_STA_WAITPAGE1 = 0x1f; + EMC_STA_WAITWR1 = 0x8; + EMC_STA_WAITTURN1 = 0xf; + EMC_STA_CFG1 = 0x00000080; +} + +/***************************************************************************** + * + * Description: + * Initialize system functions and GPIO + * + ****************************************************************************/ +void lowlevel_init(void) +{ + + /******************************************************************************************** + * Remap vectors for RAM execution + ********************************************************************************************/ + MEMMAP = 1; + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + /* move vectors to beginning of SRAM */ + asm volatile (" mov r2, #0x40000000 \n" + " mov r0, #0x00000000 \n" + " ldmneia r0!, {r3-r10} \n" + " stmneia r2!, {r3-r10} \n" + " ldmneia r0, {r3-r9} \n" + " stmneia r2, {r3-r9} \n"::: + "r0", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10"); +#else + /* move vectors to beginning of SRAM */ + asm volatile (" mov r2, #0x40000000 \n" + " mov r0, #0xa1000000 \n" + " ldmneia r0!, {r3-r10} \n" + " stmneia r2!, {r3-r10} \n" + " ldmneia r0, {r3-r9} \n" + " stmneia r2, {r3-r9} \n"::: + "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10"); +#endif + + //initialize the exception vector mapping + MEMMAP = MEM_MAP; + +#if USE_USB + PCONP |= 0x80000000; /* Turn On USB PCLK */ + +#endif + ConfigurePLL(); + + /* Set system timers for each component */ +#if (Fpclk / (Fcclk / 4)) == 1 + PCLKSEL0 = 0x00000000; /* PCLK is 1/4 CCLK */ + PCLKSEL1 = 0x00000000; +#endif +#if (Fpclk / (Fcclk / 4)) == 2 + PCLKSEL0 = 0xAAAAAAAA; /* PCLK is 1/2 CCLK */ + PCLKSEL1 = 0xAAAAAAAA; + +#endif +#if (Fpclk / (Fcclk / 4)) == 4 + PCLKSEL0 = 0x55555555; /* PCLK is the same as CCLK */ + PCLKSEL1 = 0x55555555; +#endif + /* Set memory accelerater module */ + MAMCR = 0; + + MAMTIM = 4; + +// MAMCR = 2; + //Init GPIO + GPIOinit(); + + //initialize VIC + VICinit(); + + //short delay + delayMs(10); + + /******************************************************************************************** + * Initialize external memory interface (EMC) + ********************************************************************************************/ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + ConfigureEMC(); +#endif /* + */ +} diff -upNr u-boot-orig/board/LPC2468/LPC2468.c u-boot/board/LPC2468/LPC2468.c --- u-boot-orig/board/LPC2468/LPC2468.c 1970-01-01 01:00:00.000000000 +0100 +++ u-boot/board/LPC2468/LPC2468.c 2009-03-18 13:25:15.000000000 +0100 @@ -0,0 +1,66 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroe...@sysgo.de> + * + * (C) Copyright 2005 Rowel Atienza <ro...@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; + + /* arch number MACH_TYPE_ARMADILLO - not official*/ + gd->bd->bi_arch_number = 1339; + + /* location of boot parameters */ + gd->bd->bi_boot_params = 0xA0000100; + + return 0; +} + +int print_cpuinfo(void) +{ + printf("CPU: LPC2468 (ARM7tdmi-s from NXP)\n" + " running at 57.6 MHz (12 MHz crystal)\n"); + 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 -upNr u-boot-orig/board/LPC2468/Makefile u-boot/board/LPC2468/Makefile --- u-boot-orig/board/LPC2468/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ u-boot/board/LPC2468/Makefile 2009-03-18 09:30:20.000000000 +0100 @@ -0,0 +1,55 @@ + +####################################################################### +# +# Copyright (C) 2000, 2001, 2002, 2003 +# The LEOX team <t...@leox.org>, http://www.leox.org +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, w...@denx.de. +# +# LEOX.org is about the development of free hardware and software resources +# for system on chip. +# +# Description: U-Boot port on the LEOX's ELPT860 CPU board +# ~~~~~~~~~~~ +# +####################################################################### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +####################################################################### + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS = $(BOARD).o eth.o nand.o flash.o lowlevel_init.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff -upNr u-boot-orig/board/LPC2468/nand.c u-boot/board/LPC2468/nand.c --- u-boot-orig/board/LPC2468/nand.c 1970-01-01 01:00:00.000000000 +0100 +++ u-boot/board/LPC2468/nand.c 2009-03-18 13:38:15.000000000 +0100 @@ -0,0 +1,62 @@ +/* + * (C) Copyright 2009 Duran Audio B.V. <www.duran-audio.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 + * + * 18-03-2009 Updated for U-boot 2009.3 by Remco Poelstra <remco.poelstra+u-b...@duran-audio.com> + */ + +#include <common.h> +#include <nand.h> +#include <asm/io.h> + +/* + * CLE at A20 + * ALE at A19 + */ +#define MASK_CLE (1l<<20) +#define MASK_ALE (1l<<19) + +static void cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + + ulong IO_ADDR_W = (ulong) this->IO_ADDR_W; + + if (ctrl & NAND_CTRL_CHANGE) { + IO_ADDR_W &= ~(MASK_ALE | MASK_CLE); + if (ctrl & NAND_CLE) + IO_ADDR_W |= MASK_CLE; + if (ctrl & NAND_ALE) + IO_ADDR_W |= MASK_ALE; + this->IO_ADDR_W = (void *)IO_ADDR_W; + } + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); +} + +int board_nand_init(struct nand_chip *nand) +{ + /* IO_ADDR_R and IO_ADDR_W set by nand-driver using CFG_NAND_BASE */ + nand->dev_ready = 0; + nand->cmd_ctrl = cmd_ctrl; + nand->ecc.mode = NAND_ECC_SOFT; + nand->chip_delay = 25; /* us */ + nand->options = NAND_SAMSUNG_LP_OPTIONS; + + return 0; +} diff -upNr u-boot-orig/board/LPC2468/u-boot.lds u-boot/board/LPC2468/u-boot.lds --- u-boot-orig/board/LPC2468/u-boot.lds 1970-01-01 01:00:00.000000000 +0100 +++ u-boot/board/LPC2468/u-boot.lds 2009-03-18 09:30:20.000000000 +0100 @@ -0,0 +1,55 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, w...@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +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 -upNr u-boot-orig/include/configs/LPC2468.h u-boot/include/configs/LPC2468.h --- u-boot-orig/include/configs/LPC2468.h 1970-01-01 01:00:00.000000000 +0100 +++ u-boot/include/configs/LPC2468.h 2009-03-18 10:34:25.000000000 +0100 @@ -0,0 +1,213 @@ +/* + * (C) Copyright 2008 + * Embedded Artists AB, Sweden <www.EmbeddedArtists.com> + * + * Configuation settings for the LPC2468 OEM Board, 16 bit databus. + * + * 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 + +#define CONFIG_LPC2468 + +/* + * If we are developing, we might want to start armboot from ram + * so we MUST NOT initialize critical regs like mem-timing ... + */ +#if 0 +#define CONFIG_INIT_CRITICAL /* undef for developing */ +#endif + +#undef CONFIG_SKIP_LOWLEVEL_INIT + +/* + * 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 */ +#undef CONFIG_ARM7_REVD /* disable ARM720 REV.D Workarounds */ + +/* Clock settings */ + +/* Crystal frequency */ +#define CONFIG_FOSC 12000000 + +/* + * Fcco = 2*M*Fosc / N + * + * Fcco = 288000000 -> M = 12, N = 1 + * + * PLLCFG (MSEL) = (M-1) + * PLLCFG (NSEL) = (N-1) + */ +#define CONFIG_PLL_MVALUE 12 +#define CONFIG_PLL_NVALUE 1 + +/* + * Fcclk = Fcco / CLKDIV + * CLKDIV must be an even number + * + * CCLKCFG = CLKDIV-1 (odd number must be written to register) + * CLKDIV = 4 -> Fcclk = 72 MHz (if Fcco = 288 MHz) + * CLKDIV = 6 -> Fcclk = 48 MHz (if Fcco = 288 MHz) + */ +#define CONFIG_PLL_CLKDIV 4 + +/* + * The USB clock must be 48 MHz + * Fusb = Fcco / USBCLKDIV + * USBCLKCFG = (USBCLKDIV-1) + */ +#define CONFIG_PLL_USBCLKDIV 6 + +/* + * Periperhal clock divider, i.e. Fpclk = Fcclk / divider + * Valid values are 1, 2, or 4 + */ +#define CONFIG_FPCLK_DIV 1 + +#define CONFIG_USE_IRQ /* use irq for mci interface */ + +/* + * Size of malloc() pool + */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128*1024) +#define CONFIG_SYS_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) + +#include <config_cmd_default.h> +#undef CONFIG_CMD_NFS +#undef CONFIG_CMD_FPGA +#undef CONFIG_CMD_BOOTD +#define CONFIG_CMD_NAND + +#define CONFIG_BOOTARGS "root=/dev/ram initrd=0xa1800000,4000k console=ttyS0,115200N8" + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CONFIG_SYS_MEMTEST_START 0xA0000000 /* memtest works on */ +#define CONFIG_SYS_MEMTEST_END 0xA1F80000 /* 31.5 MB in DRAM, U-boot is relocated after this location */ +#define CONFIG_SYS_ALT_MEMTEST + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +#define CONFIG_SYS_LOAD_ADDR 0xA0008000 /* default load address for kernel img is here*/ + + +#define CLK_FCCO ((2*CONFIG_PLL_MVALUE*CONFIG_FOSC) / CONFIG_PLL_NVALUE) + +#define CFG_SYS_CLK_FREQ (CLK_FCCO / CONFIG_PLL_CLKDIV)/* Hz */ +#define CONFIG_SYS_HZ 200000 /* decrementer freq in Hz */ + + /* valid baudrates */ +#define CONFIG_SYS_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 (8*1024) /* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ (8*1024) /* FIQ stack */ +#endif + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */ +#define PHYS_SDRAM_1 0xA0000000 /* SDRAM Bank #1 */ +#define PHYS_SDRAM_1_SIZE 0x02000000 /* 32 MB SDRAM */ + +#define PHYS_FLASH_1 0x80000000 /* Flash Bank #1 */ +#define PHYS_FLASH_SIZE 0x00400000 /* 4 MB */ + +#define CFG_FLASH_BASE PHYS_FLASH_1 + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ +#define CONFIG_SYS_MAX_FLASH_BANKS 2 /* max number of memory banks */ +#define CONFIG_SYS_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 */ + +/* + * Linux tags + */ +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_INITRD_TAG + +/* + * NAND Flash + */ +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define NAND_MAX_CHIPS 1 +#define CONFIG_SYS_NAND_BASE 0x81000000 + + +/* + * Default environment settings + */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "ipaddr=192.168.3.2" \ + "netmask=255.255.255.0" \ + "serverip=192.168.3.1" \ + "ethaddr=00:1a:f1:00:00:00" + +/* + * Control where environment is stored + */ +#define CONFIG_ENV_IS_IN_FLASH 1 +#define CONFIG_ENV_ADDR (0x0 + 0x7C000) /* Addr of Environment Sector */ +#define CONFIG_ENV_SIZE 0x1000 /* Total Size of Environment Sector(4k) */ + +/* Monitor Command Prompt */ +#define CONFIG_SYS_PROMPT "LPC2468 # " + +#endif /* __CONFIG_H */ diff -upNr u-boot-orig/MAKEALL u-boot/MAKEALL --- u-boot-orig/MAKEALL 2009-03-18 00:42:12.000000000 +0100 +++ u-boot/MAKEALL 2009-03-18 13:51:02.000000000 +0100 @@ -481,6 +481,7 @@ LIST_ARM7=" \ impa7 \ integratorap \ lpc2292sodimm \ + LPC2468 \ modnet50 \ SMN42 \ " diff -upNr u-boot-orig/Makefile u-boot/Makefile --- u-boot-orig/Makefile 2009-03-18 00:42:12.000000000 +0100 +++ u-boot/Makefile 2009-03-18 09:29:58.000000000 +0100 @@ -2899,6 +2899,9 @@ B2_config : unconfig ## ARM720T Systems #########################################################################
+LPC2468_config: unconfig + @$(MKCONFIG) $(@:_config=) arm arm720t LPC2468 NULL lpc24xx + armadillo_config: unconfig @$(MKCONFIG) $(@:_config=) arm arm720t armadillo _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot