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