mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-12 22:49:43 +03:00
Compare commits
14 Commits
LABEL_2003
...
LABEL_2003
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a0e21a3a8 | ||
|
|
592c5cabe7 | ||
|
|
72755c7137 | ||
|
|
0332990b85 | ||
|
|
0b97ab144f | ||
|
|
6dd652fa4d | ||
|
|
52f52c1494 | ||
|
|
48b42616e9 | ||
|
|
15ef8a5d17 | ||
|
|
2abbe07547 | ||
|
|
71f9511803 | ||
|
|
487778b781 | ||
|
|
8b601449e8 | ||
|
|
e58dc13283 |
106
CHANGELOG
106
CHANGELOG
@@ -2,6 +2,110 @@
|
||||
Changes since U-Boot 0.3.1:
|
||||
======================================================================
|
||||
|
||||
* Patch by Murray Jensen, 20 Jun 2003:
|
||||
- hymod update
|
||||
- cleanup (especially for gcc-3.x compilers)
|
||||
|
||||
* Patch by Tom Guilliams, 20 Jun 2003:
|
||||
added CONFIG_750FX support for IBM 750FX processors
|
||||
|
||||
* Patch by Devin Crumb, 02 Apr 2003:
|
||||
Fix clock divider rounding problem in drivers/serial.c
|
||||
|
||||
* Patch by Richard Woodruff, 19 June 03:
|
||||
- Fixed smc91c111 driver to sync with the u-boot environment
|
||||
(driver/smc91c111.c).
|
||||
- Added eth_init error return check in NetLoop (net/net.c).
|
||||
|
||||
* Patch by Ken Chou, 19 June 2003:
|
||||
Added support for A3000 SBC board (Artis Microsystems Inc.)
|
||||
|
||||
* Patches by Murray Jensen, 17 Jun 2003:
|
||||
- Hymod board database mods: add "who" field and new xilinx chip types
|
||||
- provide new "init_cmd_timeout()" function so code external to
|
||||
"common/main.c" can use the "reset_cmd_timeout()" function before
|
||||
entering the main loop
|
||||
- add DTT support for adm1021 (new file dtt/adm1021.c; config
|
||||
slightly different. see include/configs/hymod.h for an example
|
||||
(requires CONFIG_DTT_ADM1021, CONFIG_DTT_SENSORS, and
|
||||
CFG_DTT_ADM1021 defined)
|
||||
- add new "eeprom_probe()" function which has similar args and
|
||||
behaves in a similar way to "eeprom_read()" etc.
|
||||
- add 8260 FCC ethernet loopback code (new "eth_loopback_test()"
|
||||
function which is enabled by defining CONFIG_ETHER_LOOPBACK_TEST)
|
||||
- gdbtools copyright update
|
||||
- ensure that set_msr() executes the "sync" and "isync" instructions
|
||||
after the "mtmsr" instruction in cpu/mpc8260/interrupts.c
|
||||
- 8260 I/O ports fix: Open Drain should be set last when configuring
|
||||
- add SIU IRQ defines for 8260
|
||||
- allow LDSCRIPT override and OBJCFLAGS initialization: change to
|
||||
config.mk to allow board configurations to override the GNU
|
||||
linker script, selected via the LDSCRIPT, make variable, and to
|
||||
give an initial value to the OBJCFLAGS make variable
|
||||
- 8260 i2c enhancement:
|
||||
o correctly extends the timeout depending on the size of all
|
||||
queued messages for both transmit and receive
|
||||
o will not continue with receive if transmit times out
|
||||
o ensures that the error callback is done for all queued tx
|
||||
and rx messages
|
||||
o correctly detects both tx and rx timeouts, only delivers one to
|
||||
the callback, and does not overwrite an earlier error
|
||||
o logic in i2c_probe now correct
|
||||
- add "vprintf()" function so that "panic()" function can be
|
||||
technically correct
|
||||
- many Hymod board changes
|
||||
|
||||
* Patches by Robert Schwebel, 14 Jun 2003:
|
||||
- add support for Logotronic DL datalogger board
|
||||
- cleanup serial line after kermit binary download
|
||||
- add debugX macro (debug level support)
|
||||
- update mach-types.h to latest arm.linux.org.uk master list.
|
||||
|
||||
* Patches by David Müller, 12 Jun 2003:
|
||||
- rewrite of the S3C24X0 register definitions stuff
|
||||
- "driver" for the built-in S3C24X0 RTC
|
||||
|
||||
* Patches by Yuli Barcohen, 12 Jun 2003:
|
||||
- Add MII support and Ethernet PHY initialization for MPC8260ADS board
|
||||
- Fix incorrect SIUMCR initialisation caused by wrong Hard Reset
|
||||
configuration word supplied by FPGA on some MPC8260ADS boards
|
||||
|
||||
* Patch by Pantelis Antoniou, 10 Jun 2003:
|
||||
Unify status LED interface
|
||||
|
||||
* Add support for DS12887 RTC; add RTC support for ATC board
|
||||
|
||||
* Patch by Nicolas Lacressonniere, 11 Jun 2003:
|
||||
Modifications for Atmel AT91RM9200DK ARM920T based development kit
|
||||
- Add Atmel DataFlash support for reading and writing.
|
||||
- Add possibility to boot a Linux from DataFlash with BOOTM command.
|
||||
- Add Flash detection on Atmel AT91RM9200DK
|
||||
(between Atmel AT49BV1614 and AT49BV1614A flashes)
|
||||
- Replace old Ethernet PHY layer functions
|
||||
- Change link address
|
||||
|
||||
* Patch by Frank Smith, 9 Jun 2003:
|
||||
use CRIT_EXCEPTION for machine check on 4xx
|
||||
|
||||
* Patch by Detlev Zundel, 13 Jun 2003:
|
||||
added implementation of the "carinfo" command in cmd_immap.c
|
||||
|
||||
* Fix CONFIG_NET_MULTI support in include/net.h
|
||||
|
||||
* Patches by Kyle Harris, 13 Mar 2003:
|
||||
- Add FAT partition support
|
||||
- Add command support for FAT
|
||||
- Add command support for MMC
|
||||
----
|
||||
- Add Intel PXA support for video
|
||||
- Add Intel PXA support for MMC
|
||||
----
|
||||
- Enable MMC and FAT for lubbock board
|
||||
- Other misc changes for lubbock board
|
||||
|
||||
* Patch by Robert Schwebel, April 02, 2003:
|
||||
fix for SMSC91111 driver
|
||||
|
||||
* Patch by Vladimir Gurevich, 04 Jun 2003:
|
||||
make ppc405 ethernet driver compatible with CONFIG_NET_MULTI option
|
||||
|
||||
@@ -388,7 +492,7 @@ Changes for U-Boot 0.3.0:
|
||||
|
||||
* TRAB fixes / extensions:
|
||||
- Restore VFD brightness as saved in environment
|
||||
- add support for FGujitsu flashes
|
||||
- add support for Fujitsu flashes
|
||||
- make sure both buzzers are turned off (drive low level)
|
||||
|
||||
* Patches by Robert Schwebel, 06 Mar 2003:
|
||||
|
||||
4
CREDITS
4
CREDITS
@@ -66,6 +66,10 @@ N: Jonathan De Bruyne
|
||||
E: jonathan.debruyne@siemens.atea.be
|
||||
D: Port to Siemens IAD210 board
|
||||
|
||||
N: Ken Chou
|
||||
E: kchou@ieee.org
|
||||
D: Support for A3000 SBC board
|
||||
|
||||
N: Conn Clark
|
||||
E: clark@esteem.com
|
||||
D: ESTEEM192E support
|
||||
|
||||
6
MAKEALL
6
MAKEALL
@@ -58,9 +58,9 @@ LIST_4xx=" \
|
||||
#########################################################################
|
||||
|
||||
LIST_824x=" \
|
||||
BMW CPC45 CU824 MOUSSE \
|
||||
MUSENKI OXC PN62 Sandpoint8240 \
|
||||
Sandpoint8245 utx8245 \
|
||||
A3000 BMW CPC45 CU824 \
|
||||
MOUSSE MUSENKI OXC PN62 \
|
||||
Sandpoint8240 Sandpoint8245 utx8245 \
|
||||
"
|
||||
|
||||
#########################################################################
|
||||
|
||||
10
Makefile
10
Makefile
@@ -106,7 +106,7 @@ endif
|
||||
LIBS = board/$(BOARDDIR)/lib$(BOARD).a
|
||||
LIBS += cpu/$(CPU)/lib$(CPU).a
|
||||
LIBS += lib_$(ARCH)/lib$(ARCH).a
|
||||
LIBS += fs/jffs2/libjffs2.a fs/fdos/libfdos.a
|
||||
LIBS += fs/jffs2/libjffs2.a fs/fdos/libfdos.a fs/fat/libfat.a
|
||||
LIBS += net/libnet.a
|
||||
LIBS += disk/libdisk.a
|
||||
LIBS += rtc/librtc.a
|
||||
@@ -377,7 +377,7 @@ TQM860L_80MHz_config \
|
||||
TQM862L_config \
|
||||
TQM862L_66MHz_config \
|
||||
TQM862L_80MHz_config \
|
||||
TQM862L_100MHz_config: unconfig
|
||||
TQM862M_100MHz_config: unconfig
|
||||
@ >include/config.h
|
||||
@[ -z "$(findstring _66MHz,$@)" ] || \
|
||||
{ echo "#define CONFIG_66MHz" >>include/config.h ; \
|
||||
@@ -490,6 +490,9 @@ WALNUT405_config:unconfig
|
||||
#########################################################################
|
||||
xtract_82xx = $(subst _ROMBOOT,,$(subst _L2,,$(subst _266MHz,,$(subst _300MHz,,$(subst _config,,$1)))))
|
||||
|
||||
A3000_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc mpc824x a3000
|
||||
|
||||
BMW_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc mpc824x bmw
|
||||
|
||||
@@ -737,6 +740,9 @@ innokom_config : unconfig
|
||||
lubbock_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm pxa lubbock
|
||||
|
||||
logodl_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm pxa logodl
|
||||
|
||||
wepep250_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm pxa wepep250
|
||||
|
||||
|
||||
37
README
37
README
@@ -151,6 +151,7 @@ Directory Hierarchy:
|
||||
- board/RPXClassic
|
||||
Files specific to RPXClassic boards
|
||||
- board/RPXlite Files specific to RPXlite boards
|
||||
- board/at91rm9200dk Files specific to AT91RM9200DK boards
|
||||
- board/c2mon Files specific to c2mon boards
|
||||
- board/cmi Files specific to cmi boards
|
||||
- board/cogent Files specific to Cogent boards
|
||||
@@ -300,6 +301,7 @@ The following options need to be configured:
|
||||
or CONFIG_405GP
|
||||
or CONFIG_440
|
||||
or CONFIG_MPC74xx
|
||||
or CONFIG_750FX
|
||||
|
||||
ARM based CPUs:
|
||||
---------------
|
||||
@@ -352,7 +354,7 @@ The following options need to be configured:
|
||||
CONFIG_HHP_CRADLE, CONFIG_DNP1110, CONFIG_EP7312,
|
||||
CONFIG_IMPA7, CONFIG_LART, CONFIG_LUBBOCK,
|
||||
CONFIG_SHANNON, CONFIG_SMDK2400, CONFIG_SMDK2410,
|
||||
CONFIG_TRAB
|
||||
CONFIG_TRAB, CONFIG_AT91RM9200DK
|
||||
|
||||
|
||||
- CPU Module Type: (if CONFIG_COGENT is defined)
|
||||
@@ -565,6 +567,7 @@ The following options need to be configured:
|
||||
CFG_CMD_ELF bootelf, bootvx
|
||||
CFG_CMD_ENV saveenv
|
||||
CFG_CMD_FDC * Floppy Disk Support
|
||||
CFG_CMD_FAT FAT partition support
|
||||
CFG_CMD_FDOS * Dos diskette Support
|
||||
CFG_CMD_FLASH flinfo, erase, protect
|
||||
CFG_CMD_FPGA FPGA device initialization support
|
||||
@@ -578,6 +581,7 @@ The following options need to be configured:
|
||||
CFG_CMD_LOADS loads
|
||||
CFG_CMD_MEMORY md, mm, nm, mw, cp, cmp, crc, base,
|
||||
loop, mtest
|
||||
CFG_CMD_MMC MMC memory mapped support
|
||||
CFG_CMD_MII MII utility commands
|
||||
CFG_CMD_NET bootp, tftpboot, rarpboot
|
||||
CFG_CMD_PCI * pciinfo
|
||||
@@ -730,6 +734,14 @@ The following options need to be configured:
|
||||
Supported are USB Keyboards and USB Floppy drives
|
||||
(TEAC FD-05PUB).
|
||||
|
||||
- MMC Support:
|
||||
The MMC controller on the Intel PXA is supported. To
|
||||
enable this define CONFIG_MMC. The MMC can be
|
||||
accessed from the boot prompt by mapping the device
|
||||
to physical memory similar to flash. Command line is
|
||||
enabled with CFG_CMD_MMC. The MMC driver also works with
|
||||
the FAT fs. This is enabled with CFG_CMD_FAT.
|
||||
|
||||
- Keyboard Support:
|
||||
CONFIG_ISA_KEYBOARD
|
||||
|
||||
@@ -1238,6 +1250,13 @@ The following options need to be configured:
|
||||
the environment like the autoscript function or the
|
||||
boot command first.
|
||||
|
||||
- DataFlash Support
|
||||
CONFIG_HAS_DATAFLASH
|
||||
|
||||
Defining this option enables DataFlash features and
|
||||
allows to read/write in Dataflash via the standard
|
||||
commands cp, md...
|
||||
|
||||
- Show boot progress
|
||||
CONFIG_SHOW_BOOT_PROGRESS
|
||||
|
||||
@@ -1791,6 +1810,7 @@ configurations; the following names are supported:
|
||||
GENIETV_config TQM823L_config PIP405_config
|
||||
GEN860T_config EBONY_config FPS860L_config
|
||||
ELPT860_config cmi_mpc5xx_config NETVIA_config
|
||||
at91rm9200dk_config
|
||||
|
||||
Note: for some board special configuration names may exist; check if
|
||||
additional information is available from the board vendor; for
|
||||
@@ -2632,6 +2652,14 @@ Unix, I recommend to use C-Kermit for general purpose use (and
|
||||
especially for kermit binary protocol download ("loadb" command), and
|
||||
use "cu" for S-Record download ("loads" command).
|
||||
|
||||
Nevertheless, if you absolutely want to use it try adding this
|
||||
configuration to your "File transfer protocols" section:
|
||||
|
||||
Name Program Name U/D FullScr IO-Red. Multi
|
||||
X kermit /usr/bin/kermit -i -l %l -s Y U Y N N
|
||||
Y kermit /usr/bin/kermit -i -l %l -r N D Y N N
|
||||
|
||||
|
||||
NetBSD Notes:
|
||||
=============
|
||||
|
||||
@@ -2983,6 +3011,13 @@ it:
|
||||
We accept patches as plain text, MIME attachments or as uuencoded
|
||||
gzipped text.
|
||||
|
||||
* If one logical set of modifications affects or creates several
|
||||
files, all these changes shall be submitted in a SINGLE patch file.
|
||||
|
||||
* Changesets that contain different, unrelated modifications shall be
|
||||
submitted as SEPARATE patches, one patch per changeset.
|
||||
|
||||
|
||||
Notes:
|
||||
|
||||
* Before sending the patch, run the MAKEALL script on your patched
|
||||
|
||||
40
board/a3000/Makefile
Normal file
40
board/a3000/Makefile
Normal file
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# (C) Copyright 2001
|
||||
# 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
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS = $(BOARD).o flash.o
|
||||
|
||||
$(LIB): .depend $(OBJS)
|
||||
$(AR) crv $@ $^
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(OBJS:.o=.c)
|
||||
$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
|
||||
|
||||
sinclude .depend
|
||||
|
||||
#########################################################################
|
||||
18
board/a3000/README
Normal file
18
board/a3000/README
Normal file
@@ -0,0 +1,18 @@
|
||||
U-Boot for Artis SBC-A3000
|
||||
---------------------------
|
||||
|
||||
Artis SBC-A3000 has one flash socket that the user uses Intel 28F128J3A (16MB)
|
||||
or 28F064J3A (8MB) chips.
|
||||
|
||||
In board's notation, bank 0 is the one at the address of 0xFF000000.
|
||||
bank 1 is the one at the address of 0xFF800000
|
||||
|
||||
On power-up the processor jumps to the address of 0xFFF00100, the last
|
||||
megabyte of the bank 0 of flash.
|
||||
|
||||
Thus, U-Boot is configured to reside in flash starting at the address of
|
||||
0xFFF00000. The environment space is located in flash separately from
|
||||
U-Boot, at the address of 0xFFFE0000.
|
||||
|
||||
There is a National ns83815 10/100M ethernet controller on-board.
|
||||
|
||||
144
board/a3000/a3000.c
Normal file
144
board/a3000/a3000.c
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* (C) Copyright 2001
|
||||
* Rob Taylor, Flying Pig Systems. robt@flyingpig.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
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc824x.h>
|
||||
#include <pci.h>
|
||||
|
||||
int checkboard (void)
|
||||
{
|
||||
ulong busfreq = get_bus_freq(0);
|
||||
char buf[32];
|
||||
|
||||
printf("Board: A3000 Local Bus at %s MHz\n", strmhz(buf, busfreq));
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
long int initdram (int board_type)
|
||||
{
|
||||
int i, cnt;
|
||||
volatile uchar * base= CFG_SDRAM_BASE;
|
||||
volatile ulong * addr;
|
||||
ulong save[32];
|
||||
ulong val, ret = 0;
|
||||
|
||||
for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
|
||||
addr = (volatile ulong *)base + cnt;
|
||||
save[i++] = *addr;
|
||||
*addr = ~cnt;
|
||||
}
|
||||
|
||||
addr = (volatile ulong *)base;
|
||||
save[i] = *addr;
|
||||
*addr = 0;
|
||||
|
||||
if (*addr != 0) {
|
||||
*addr = save[i];
|
||||
goto Done;
|
||||
}
|
||||
|
||||
for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1) {
|
||||
addr = (volatile ulong *)base + cnt;
|
||||
val = *addr;
|
||||
*addr = save[--i];
|
||||
if (val != ~cnt) {
|
||||
ulong new_bank0_end = cnt * sizeof(long) - 1;
|
||||
ulong mear1 = mpc824x_mpc107_getreg(MEAR1);
|
||||
ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
|
||||
mear1 = (mear1 & 0xFFFFFF00) |
|
||||
((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
|
||||
emear1 = (emear1 & 0xFFFFFF00) |
|
||||
((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
|
||||
mpc824x_mpc107_setreg(MEAR1, mear1);
|
||||
mpc824x_mpc107_setreg(EMEAR1, emear1);
|
||||
|
||||
ret = cnt * sizeof(long);
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
|
||||
ret = CFG_MAX_RAM_SIZE;
|
||||
Done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize PCI Devices
|
||||
*/
|
||||
#if 1
|
||||
#ifndef CONFIG_PCI_PNP
|
||||
static struct pci_config_table pci_a3000_config_table[] = {
|
||||
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
||||
0x0, 0x0, 0x0, /* unknown eth0 divice */
|
||||
pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
|
||||
PCI_ENET0_MEMADDR,
|
||||
PCI_COMMAND_IO |
|
||||
PCI_COMMAND_MEMORY |
|
||||
PCI_COMMAND_MASTER }},
|
||||
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
||||
0x0, 0x0, 0x0, /* unknown eth1 device */
|
||||
pci_cfgfunc_config_device, { PCI_ENET1_IOADDR,
|
||||
PCI_ENET1_MEMADDR,
|
||||
PCI_COMMAND_IO |
|
||||
PCI_COMMAND_MEMORY |
|
||||
PCI_COMMAND_MASTER }},
|
||||
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
||||
0x0, 0x0, 0x0, /* unknown eth1 device */
|
||||
pci_cfgfunc_config_device, { PCI_ENET2_IOADDR,
|
||||
PCI_ENET2_MEMADDR,
|
||||
PCI_COMMAND_IO |
|
||||
PCI_COMMAND_MEMORY |
|
||||
PCI_COMMAND_MASTER }},
|
||||
{ }
|
||||
};
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifndef CONFIG_PCI_PNP
|
||||
static struct pci_config_table pci_a3000_config_table[] = {
|
||||
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0f, PCI_ANY_ID,
|
||||
pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
|
||||
PCI_ENET0_MEMADDR,
|
||||
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
|
||||
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x10, PCI_ANY_ID,
|
||||
pci_cfgfunc_config_device, { PCI_ENET1_IOADDR,
|
||||
PCI_ENET1_MEMADDR,
|
||||
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
|
||||
{ }
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
struct pci_controller hose = {
|
||||
#ifndef CONFIG_PCI_PNP
|
||||
config_table: pci_a3000_config_table,
|
||||
#endif
|
||||
};
|
||||
|
||||
void pci_init_board(void)
|
||||
{
|
||||
pci_mpc824x_init(&hose);
|
||||
}
|
||||
30
board/a3000/config.mk
Normal file
30
board/a3000/config.mk
Normal file
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# (C) Copyright 2000, 2001
|
||||
# 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
|
||||
#
|
||||
|
||||
#
|
||||
# Artis A-3000 boards
|
||||
#
|
||||
|
||||
TEXT_BASE = 0xFFF00000
|
||||
|
||||
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
|
||||
454
board/a3000/flash.c
Normal file
454
board/a3000/flash.c
Normal file
@@ -0,0 +1,454 @@
|
||||
/*
|
||||
* (C) Copyright 2001
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc824x.h>
|
||||
|
||||
#if defined(CFG_ENV_IS_IN_FLASH)
|
||||
# ifndef CFG_ENV_ADDR
|
||||
# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
|
||||
# endif
|
||||
# ifndef CFG_ENV_SIZE
|
||||
# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
|
||||
# endif
|
||||
# ifndef CFG_ENV_SECT_SIZE
|
||||
# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define DEBUG_FLASH
|
||||
|
||||
#ifdef DEBUG_FLASH
|
||||
#define DEBUGF(fmt,args...) printf(fmt ,##args)
|
||||
#else
|
||||
#define DEBUGF(fmt,args...)
|
||||
#endif
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static ulong flash_get_size (vu_char *addr, flash_info_t *info);
|
||||
static int write_data (flash_info_t *info, uchar *dest, uchar data);
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info);
|
||||
|
||||
#define BS(b) (b)
|
||||
#define BYTEME(x) ((x) & 0xFF)
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
unsigned long flash_banks[CFG_MAX_FLASH_BANKS] = CFG_FLASH_BANKS;
|
||||
unsigned long size, size_b[CFG_MAX_FLASH_BANKS];
|
||||
|
||||
int i;
|
||||
|
||||
/* Init: no FLASHes known */
|
||||
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i)
|
||||
{
|
||||
flash_info[i].flash_id = FLASH_UNKNOWN;
|
||||
|
||||
DEBUGF("Get flash bank %d @ 0x%08lx\n", i, flash_banks[i]);
|
||||
/*
|
||||
size_b[i] = flash_get_size((vu_char *)flash_banks[i], &flash_info[i]);
|
||||
*/
|
||||
size_b[i] = flash_get_size((vu_char *) 0xff800000 , &flash_info[i]);
|
||||
|
||||
if (flash_info[i].flash_id == FLASH_UNKNOWN)
|
||||
{
|
||||
printf ("## Unknown FLASH on Bank %d: "
|
||||
"ID 0x%lx, Size = 0x%08lx = %ld MB\n",
|
||||
i, flash_info[i].flash_id,
|
||||
size_b[i], size_b[i]<<20);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUGF("## Flash bank %d at 0x%08lx sizes: 0x%08lx \n",
|
||||
i, flash_banks[i], size_b[i]);
|
||||
|
||||
flash_get_offsets (flash_banks[i], &flash_info[i]);
|
||||
flash_info[i].size = size_b[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
|
||||
DEBUGF("protect monitor %x @ %x\n", CFG_MONITOR_BASE, CFG_MONITOR_LEN);
|
||||
/* monitor protection ON by default */
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_MONITOR_BASE,
|
||||
CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
|
||||
&flash_info[0]);
|
||||
#endif
|
||||
|
||||
#ifdef CFG_ENV_IS_IN_FLASH
|
||||
/* ENV protection ON by default */
|
||||
DEBUGF("protect environtment %x @ %x\n", CFG_ENV_ADDR, CFG_ENV_SECT_SIZE);
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR+CFG_ENV_SECT_SIZE-1,
|
||||
&flash_info[0]);
|
||||
#endif
|
||||
|
||||
size = 0;
|
||||
DEBUGF("## Final Flash bank sizes: ");
|
||||
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i)
|
||||
{
|
||||
DEBUGF("%08lx ", size_b[i]);
|
||||
size += size_b[i];
|
||||
}
|
||||
DEBUGF("\n");
|
||||
return (size);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_INTEL:
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
info->start[i] = base;
|
||||
base += 0x00020000; /* 128k per bank */
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
printf ("Don't know sector ofsets for flash type 0x%lx\n", info->flash_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
void flash_print_info (flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("missing or unknown FLASH type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_AMD: printf ("AMD "); break;
|
||||
case FLASH_MAN_FUJ: printf ("Fujitsu "); break;
|
||||
case FLASH_MAN_SST: printf ("SST "); break;
|
||||
case FLASH_MAN_STM: printf ("STM "); break;
|
||||
case FLASH_MAN_INTEL: printf ("Intel "); break;
|
||||
case FLASH_MAN_MT: printf ("MT "); break;
|
||||
default: printf ("Unknown Vendor "); break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_28F320J3A:
|
||||
printf ("28F320J3A (32Mbit = 128K x 32)\n");
|
||||
break;
|
||||
case FLASH_28F640J3A:
|
||||
printf ("28F640J3A (64Mbit = 128K x 64)\n");
|
||||
break;
|
||||
case FLASH_28F128J3A:
|
||||
printf ("28F128J3A (128Mbit = 128K x 128)\n");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Chip Type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (info->size >= (1 << 20)) {
|
||||
i = 20;
|
||||
} else {
|
||||
i = 10;
|
||||
}
|
||||
printf (" Size: %ld %cB in %d Sectors\n",
|
||||
info->size >> i,
|
||||
(i == 20) ? 'M' : 'k',
|
||||
info->sector_count);
|
||||
|
||||
printf (" Sector Start Addresses:");
|
||||
for (i=0; i<info->sector_count; ++i) {
|
||||
if ((i % 5) == 0)
|
||||
printf ("\n ");
|
||||
printf (" %08lX%s",
|
||||
info->start[i],
|
||||
info->protect[i] ? " (RO)" : " "
|
||||
);
|
||||
}
|
||||
printf ("\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
static ulong flash_get_size (vu_char *addr, flash_info_t *info)
|
||||
{
|
||||
vu_char manuf, device;
|
||||
|
||||
addr[0] = BS(0x90);
|
||||
manuf = BS(addr[0]);
|
||||
DEBUGF("Manuf. ID @ 0x%08lx: 0x%08x\n", (ulong)addr, manuf);
|
||||
|
||||
switch (manuf) {
|
||||
case BYTEME(AMD_MANUFACT):
|
||||
info->flash_id = FLASH_MAN_AMD;
|
||||
break;
|
||||
case BYTEME(FUJ_MANUFACT):
|
||||
info->flash_id = FLASH_MAN_FUJ;
|
||||
break;
|
||||
case BYTEME(SST_MANUFACT):
|
||||
info->flash_id = FLASH_MAN_SST;
|
||||
break;
|
||||
case BYTEME(STM_MANUFACT):
|
||||
info->flash_id = FLASH_MAN_STM;
|
||||
break;
|
||||
case BYTEME(INTEL_MANUFACT):
|
||||
info->flash_id = FLASH_MAN_INTEL;
|
||||
break;
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
addr[0] = BS(0xFF); /* restore read mode, (yes, BS is a NOP) */
|
||||
return 0; /* no or unknown flash */
|
||||
}
|
||||
|
||||
device = BS(addr[2]); /* device ID */
|
||||
|
||||
DEBUGF("Device ID @ 0x%08lx: 0x%08x\n", (ulong)(&addr[1]), device);
|
||||
|
||||
switch (device) {
|
||||
case BYTEME(INTEL_ID_28F320J3A):
|
||||
info->flash_id += FLASH_28F320J3A;
|
||||
info->sector_count = 32;
|
||||
info->size = 0x00400000;
|
||||
break; /* => 4 MB */
|
||||
|
||||
case BYTEME(INTEL_ID_28F640J3A):
|
||||
info->flash_id += FLASH_28F640J3A;
|
||||
info->sector_count = 64;
|
||||
info->size = 0x00800000;
|
||||
break; /* => 8 MB */
|
||||
|
||||
case BYTEME(INTEL_ID_28F128J3A):
|
||||
info->flash_id += FLASH_28F128J3A;
|
||||
info->sector_count = 128;
|
||||
info->size = 0x01000000;
|
||||
break; /* => 16 MB */
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
addr[0] = BS(0xFF); /* restore read mode (yes, a NOP) */
|
||||
return 0; /* => no or unknown flash */
|
||||
|
||||
}
|
||||
|
||||
if (info->sector_count > CFG_MAX_FLASH_SECT) {
|
||||
printf ("** ERROR: sector count %d > max (%d) **\n",
|
||||
info->sector_count, CFG_MAX_FLASH_SECT);
|
||||
info->sector_count = CFG_MAX_FLASH_SECT;
|
||||
}
|
||||
|
||||
addr[0] = BS(0xFF); /* restore read mode */
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
{
|
||||
int flag, prot, sect;
|
||||
ulong start, now, last;
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("- missing\n");
|
||||
} else {
|
||||
printf ("- no sectors to erase\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
|
||||
printf ("Can erase only Intel flash types - aborted\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
for (sect=s_first; sect<=s_last; ++sect) {
|
||||
if (info->protect[sect]) {
|
||||
prot++;
|
||||
}
|
||||
}
|
||||
|
||||
if (prot) {
|
||||
printf ("- Warning: %d protected sectors will not be erased!\n", prot);
|
||||
} else {
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
start = get_timer (0);
|
||||
last = start;
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect<=s_last; sect++) {
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
vu_char *addr = (vu_char *)(info->start[sect]);
|
||||
unsigned long status;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
*addr = BS(0x50); /* clear status register */
|
||||
*addr = BS(0x20); /* erase setup */
|
||||
*addr = BS(0xD0); /* erase confirm */
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag) {
|
||||
enable_interrupts();
|
||||
}
|
||||
|
||||
/* wait at least 80us - let's wait 1 ms */
|
||||
udelay (1000);
|
||||
|
||||
while (((status = BS(*addr)) & BYTEME(0x00800080)) != BYTEME(0x00800080)) {
|
||||
if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout\n");
|
||||
*addr = BS(0xB0); /* suspend erase */
|
||||
*addr = BS(0xFF); /* reset to read mode */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* show that we're waiting */
|
||||
if ((now - last) > 1000) { /* every second */
|
||||
putc ('.');
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
|
||||
*addr = BS(0xFF); /* reset to read mode */
|
||||
}
|
||||
}
|
||||
printf (" done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
* 4 - Flash not identified
|
||||
*/
|
||||
|
||||
#define FLASH_WIDTH 1 /* flash bus width in bytes */
|
||||
|
||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
{
|
||||
uchar *wp = (uchar *)addr;
|
||||
int rc;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
while (cnt > 0) {
|
||||
if ((rc = write_data(info, wp, *src)) != 0) {
|
||||
return rc;
|
||||
}
|
||||
wp++;
|
||||
src++;
|
||||
cnt--;
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word to Flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
static int write_data (flash_info_t *info, uchar *dest, uchar data)
|
||||
{
|
||||
vu_char *addr = (vu_char *)dest;
|
||||
ulong status;
|
||||
ulong start;
|
||||
int flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((BS(*addr) & data) != data) {
|
||||
return 2;
|
||||
}
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
*addr = BS(0x40); /* write setup */
|
||||
*addr = data;
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag) {
|
||||
enable_interrupts();
|
||||
}
|
||||
|
||||
start = get_timer (0);
|
||||
|
||||
while (((status = BS(*addr)) & BYTEME(0x00800080)) != BYTEME(0x00800080)) {
|
||||
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
|
||||
*addr = BS(0xFF); /* restore read mode */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
*addr = BS(0xFF); /* restore read mode */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
128
board/a3000/u-boot.lds
Normal file
128
board/a3000/u-boot.lds
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* (C) Copyright 2001
|
||||
* 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_ARCH(powerpc)
|
||||
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
|
||||
/* Do we need any of these for elf?
|
||||
__DYNAMIC = 0; */
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
. = + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.rel.text : { *(.rel.text) }
|
||||
.rela.text : { *(.rela.text) }
|
||||
.rel.data : { *(.rel.data) }
|
||||
.rela.data : { *(.rela.data) }
|
||||
.rel.rodata : { *(.rel.rodata) }
|
||||
.rela.rodata : { *(.rela.rodata) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.bss : { *(.rel.bss) }
|
||||
.rela.bss : { *(.rela.bss) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
.init : { *(.init) }
|
||||
.plt : { *(.plt) }
|
||||
.text :
|
||||
{
|
||||
cpu/mpc824x/start.o (.text)
|
||||
lib_ppc/board.o (.text)
|
||||
lib_ppc/ppcstring.o (.text)
|
||||
lib_generic/vsprintf.o (.text)
|
||||
lib_generic/crc32.o (.text)
|
||||
lib_generic/zlib.o (.text)
|
||||
|
||||
. = DEFINED(env_offset) ? env_offset : .;
|
||||
common/environment.o (.text)
|
||||
|
||||
*(.text)
|
||||
|
||||
*(.fixup)
|
||||
*(.got1)
|
||||
. = ALIGN(16);
|
||||
*(.rodata)
|
||||
*(.rodata1)
|
||||
}
|
||||
.fini : { *(.fini) } =0
|
||||
.ctors : { *(.ctors) }
|
||||
.dtors : { *(.dtors) }
|
||||
|
||||
/* Read-write section, merged into data segment: */
|
||||
. = (. + 0x0FFF) & 0xFFFFF000;
|
||||
_erotext = .;
|
||||
PROVIDE (erotext = .);
|
||||
.reloc :
|
||||
{
|
||||
*(.got)
|
||||
_GOT2_TABLE_ = .;
|
||||
*(.got2)
|
||||
_FIXUP_TABLE_ = .;
|
||||
*(.fixup)
|
||||
}
|
||||
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
|
||||
__fixup_entries = (. - _FIXUP_TABLE_) >> 2;
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata2)
|
||||
*(.dynamic)
|
||||
CONSTRUCTORS
|
||||
}
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
__start___ex_table = .;
|
||||
__ex_table : { *(__ex_table) }
|
||||
__stop___ex_table = .;
|
||||
|
||||
. = ALIGN(4096);
|
||||
__init_begin = .;
|
||||
.text.init : { *(.text.init) }
|
||||
.data.init : { *(.data.init) }
|
||||
. = ALIGN(4096);
|
||||
__init_end = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.sbss) *(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
|
||||
_end = . ;
|
||||
PROVIDE (end = .);
|
||||
}
|
||||
|
||||
@@ -30,28 +30,35 @@
|
||||
* Miscelaneous platform dependent initialisations
|
||||
*/
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
int board_init (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* memory and cpu-speed are setup before relocation */
|
||||
/* so we do _nothing_ here */
|
||||
/* Enable Ctrlc */
|
||||
console_init_f ();
|
||||
|
||||
/* arch number of AT91RM9200DK-Board */
|
||||
gd->bd->bi_arch_number = 251;
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
|
||||
/* Correct IRDA resistor problem */
|
||||
/* Set PA23_TXD in Output */
|
||||
(AT91PS_PIO) AT91C_BASE_PIOA->PIO_OER = AT91C_PA23_TXD2;
|
||||
|
||||
return 0;
|
||||
/* memory and cpu-speed are setup before relocation */
|
||||
/* so we do _nothing_ here */
|
||||
|
||||
/* arch number of AT91RM9200DK-Board */
|
||||
gd->bd->bi_arch_number = 251;
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
int dram_init (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM;
|
||||
gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE;
|
||||
return 0;
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM;
|
||||
gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -59,47 +66,47 @@ int dram_init(void)
|
||||
* The NAND lives in the CS2* space
|
||||
*/
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
|
||||
extern void
|
||||
nand_probe(ulong physadr);
|
||||
extern void nand_probe (ulong physadr);
|
||||
|
||||
#define AT91_SMARTMEDIA_BASE 0x40000000 /* physical address to access memory on NCS3 */
|
||||
void
|
||||
nand_init(void)
|
||||
#define AT91_SMARTMEDIA_BASE 0x40000000 /* physical address to access memory on NCS3 */
|
||||
void nand_init (void)
|
||||
{
|
||||
/* Setup Smart Media, fitst enable the address range of CS3 */
|
||||
*AT91C_EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia;
|
||||
/* set the bus interface characteristics based on
|
||||
tDS Data Set up Time 30 - ns
|
||||
tDH Data Hold Time 20 - ns
|
||||
tALS ALE Set up Time 20 - ns
|
||||
16ns at 60 MHz ~= 3 */
|
||||
*AT91C_EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia;
|
||||
/* set the bus interface characteristics based on
|
||||
tDS Data Set up Time 30 - ns
|
||||
tDH Data Hold Time 20 - ns
|
||||
tALS ALE Set up Time 20 - ns
|
||||
16ns at 60 MHz ~= 3 */
|
||||
/*memory mapping structures */
|
||||
#define SM_ID_RWH (5 << 28)
|
||||
#define SM_RWH (1 << 28)
|
||||
#define SM_RWS (0 << 24)
|
||||
#define SM_TDF (1 << 8)
|
||||
#define SM_NWS (3)
|
||||
AT91C_BASE_SMC2->SMC2_CSR[3] = ( SM_RWH|SM_RWS | AT91C_SMC2_ACSS_STANDARD |
|
||||
AT91C_SMC2_DBW_8 | SM_TDF |
|
||||
AT91C_SMC2_WSEN | SM_NWS);
|
||||
AT91C_BASE_SMC2->SMC2_CSR[3] = (SM_RWH | SM_RWS |
|
||||
AT91C_SMC2_ACSS_STANDARD | AT91C_SMC2_DBW_8 |
|
||||
SM_TDF | AT91C_SMC2_WSEN | SM_NWS);
|
||||
|
||||
/* enable the SMOE line PC0=SMCE, A21=CLE, A22=ALE */
|
||||
*AT91C_PIOC_ASR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE;
|
||||
*AT91C_PIOC_PDR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE;
|
||||
/* enable the SMOE line PC0=SMCE, A21=CLE, A22=ALE */
|
||||
*AT91C_PIOC_ASR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE |
|
||||
AT91C_PC3_BFBAA_SMWE;
|
||||
*AT91C_PIOC_PDR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE |
|
||||
AT91C_PC3_BFBAA_SMWE;
|
||||
|
||||
/* Configure PC2 as input (signal READY of the SmartMedia) */
|
||||
*AT91C_PIOC_PER = AT91C_PC2_BFAVD; /* enable direct output enable */
|
||||
*AT91C_PIOC_ODR = AT91C_PC2_BFAVD; /* disable output */
|
||||
*AT91C_PIOC_PER = AT91C_PC2_BFAVD; /* enable direct output enable */
|
||||
*AT91C_PIOC_ODR = AT91C_PC2_BFAVD; /* disable output */
|
||||
|
||||
/* Configure PB1 as input (signal Card Detect of the SmartMedia) */
|
||||
*AT91C_PIOB_PER = AT91C_PIO_PB1; /* enable direct output enable */
|
||||
*AT91C_PIOB_ODR = AT91C_PIO_PB1; /* disable output */
|
||||
*AT91C_PIOB_PER = AT91C_PIO_PB1; /* enable direct output enable */
|
||||
*AT91C_PIOB_ODR = AT91C_PIO_PB1; /* disable output */
|
||||
|
||||
if (*AT91C_PIOB_PDSR & AT91C_PIO_PB1)
|
||||
printf ("No ");
|
||||
printf ("SmartMedia card inserted\n");
|
||||
if (*AT91C_PIOB_PDSR & AT91C_PIO_PB1)
|
||||
printf ("No ");
|
||||
printf ("SmartMedia card inserted\n");
|
||||
|
||||
printf("Probing at 0x%.8x\n", AT91_SMARTMEDIA_BASE);
|
||||
nand_probe(AT91_SMARTMEDIA_BASE);
|
||||
printf ("Probing at 0x%.8x\n", AT91_SMARTMEDIA_BASE);
|
||||
nand_probe (AT91_SMARTMEDIA_BASE);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
TEXT_BASE = 0x21fa0000
|
||||
TEXT_BASE = 0x21f00000
|
||||
|
||||
|
||||
@@ -31,11 +31,40 @@
|
||||
ulong myflush(void);
|
||||
|
||||
|
||||
/* Flash Organization Structure */
|
||||
typedef struct OrgDef
|
||||
{
|
||||
unsigned int sector_number;
|
||||
unsigned int sector_size;
|
||||
} OrgDef;
|
||||
|
||||
|
||||
/* Flash Organizations */
|
||||
OrgDef OrgAT49BV16x4[] =
|
||||
{
|
||||
{ 8, 8*1024 }, /* 8 * 8kBytes sectors */
|
||||
{ 2, 32*1024 }, /* 2 * 32kBytes sectors */
|
||||
{ 30, 64*1024 } /* 30 * 64kBytes sectors */
|
||||
};
|
||||
|
||||
OrgDef OrgAT49BV16x4A[] =
|
||||
{
|
||||
{ 8, 8*1024 }, /* 8 * 8kBytes sectors */
|
||||
{ 31, 64*1024 } /* 31 * 64kBytes sectors */
|
||||
};
|
||||
|
||||
|
||||
#define FLASH_BANK_SIZE 0x200000 /* 2 MB */
|
||||
#define MAIN_SECT_SIZE 0x10000 /* 64 KB */
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
|
||||
|
||||
/* AT49BV1614A Codes */
|
||||
#define FLASH_CODE1 0xAA
|
||||
#define FLASH_CODE2 0x55
|
||||
#define ID_IN_CODE 0x90
|
||||
#define ID_OUT_CODE 0xF0
|
||||
|
||||
|
||||
#define CMD_READ_ARRAY 0x00F0
|
||||
#define CMD_UNLOCK1 0x00AA
|
||||
@@ -48,6 +77,9 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
|
||||
#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00005555<<1)))
|
||||
#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00002AAA<<1)))
|
||||
|
||||
#define IDENT_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x0000555<<1)))
|
||||
#define IDENT_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x0000AAA<<1)))
|
||||
|
||||
#define BIT_ERASE_DONE 0x0080
|
||||
#define BIT_RDY_MASK 0x0080
|
||||
#define BIT_PROGRAM_ERROR 0x0020
|
||||
@@ -59,339 +91,375 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
ulong flash_init(void)
|
||||
void flash_identification (flash_info_t * info)
|
||||
{
|
||||
int i, j;
|
||||
ulong size = 0;
|
||||
volatile u16 manuf_code, device_code, add_device_code;
|
||||
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
|
||||
{
|
||||
ulong flashbase = 0;
|
||||
flash_info[i].flash_id =
|
||||
(ATM_MANUFACT & FLASH_VENDMASK) |
|
||||
(ATM_ID_BV1614 & FLASH_TYPEMASK);
|
||||
flash_info[i].size = FLASH_BANK_SIZE;
|
||||
flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
|
||||
memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
|
||||
if (i == 0)
|
||||
flashbase = PHYS_FLASH_1;
|
||||
else
|
||||
panic("configured to many flash banks!\n");
|
||||
for (j = 0; j < flash_info[i].sector_count; j++)
|
||||
{
|
||||
IDENT_FLASH_ADDR1 = FLASH_CODE1;
|
||||
IDENT_FLASH_ADDR2 = FLASH_CODE2;
|
||||
IDENT_FLASH_ADDR1 = ID_IN_CODE;
|
||||
|
||||
if (j <= 9)
|
||||
{
|
||||
/* 1st to 8th are 8 KB */
|
||||
if (j <= 7)
|
||||
{
|
||||
flash_info[i].start[j] = flashbase + j*0x2000;
|
||||
manuf_code = *(volatile u16 *) CFG_FLASH_BASE;
|
||||
device_code = *(volatile u16 *) (CFG_FLASH_BASE + 2);
|
||||
add_device_code = *(volatile u16 *) (CFG_FLASH_BASE + (3 << 1));
|
||||
|
||||
IDENT_FLASH_ADDR1 = FLASH_CODE1;
|
||||
IDENT_FLASH_ADDR2 = FLASH_CODE2;
|
||||
IDENT_FLASH_ADDR1 = ID_OUT_CODE;
|
||||
|
||||
/* Vendor type */
|
||||
info->flash_id = ATM_MANUFACT & FLASH_VENDMASK;
|
||||
printf ("Atmel: ");
|
||||
|
||||
if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV1614 & FLASH_TYPEMASK)) {
|
||||
|
||||
if ((add_device_code & FLASH_TYPEMASK) ==
|
||||
(ATM_ID_BV1614A & FLASH_TYPEMASK)) {
|
||||
info->flash_id |= ATM_ID_BV1614A & FLASH_TYPEMASK;
|
||||
printf ("AT49BV1614A (16Mbit)\n");
|
||||
}
|
||||
|
||||
/* 9th and 10th are both 32 KB */
|
||||
if ((j == 8) || (j == 9))
|
||||
{
|
||||
flash_info[i].start[j] = flashbase + 0x10000 + (j-8)*0x8000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flash_info[i].start[j] = flashbase + (j-8)*MAIN_SECT_SIZE;
|
||||
}
|
||||
} else { /* AT49BV1614 Flash */
|
||||
info->flash_id |= ATM_ID_BV1614 & FLASH_TYPEMASK;
|
||||
printf ("AT49BV1614 (16Mbit)\n");
|
||||
}
|
||||
size += flash_info[i].size;
|
||||
}
|
||||
}
|
||||
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_FLASH_BASE,
|
||||
CFG_ENV_ADDR - 1,
|
||||
&flash_info[0]);
|
||||
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
|
||||
&flash_info[0]);
|
||||
ulong flash_init (void)
|
||||
{
|
||||
int i, j, k;
|
||||
unsigned int flash_nb_blocks, sector;
|
||||
unsigned int start_address;
|
||||
OrgDef *pOrgDef;
|
||||
|
||||
return size;
|
||||
ulong size = 0;
|
||||
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
|
||||
ulong flashbase = 0;
|
||||
|
||||
flash_identification (&flash_info[i]);
|
||||
|
||||
flash_info[i].size = FLASH_BANK_SIZE;
|
||||
|
||||
if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
|
||||
(ATM_ID_BV1614 & FLASH_TYPEMASK)) {
|
||||
flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
|
||||
memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
|
||||
|
||||
pOrgDef = OrgAT49BV16x4;
|
||||
flash_nb_blocks = sizeof (OrgAT49BV16x4) / sizeof (OrgDef);
|
||||
} else { /* AT49BV1614A Flash */
|
||||
flash_info[i].sector_count = CFG_MAX_FLASH_SECT - 1;
|
||||
memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT - 1);
|
||||
|
||||
pOrgDef = OrgAT49BV16x4A;
|
||||
flash_nb_blocks = sizeof (OrgAT49BV16x4A) / sizeof (OrgDef);
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
flashbase = PHYS_FLASH_1;
|
||||
else
|
||||
panic ("configured to many flash banks!\n");
|
||||
|
||||
sector = 0;
|
||||
start_address = flashbase;
|
||||
|
||||
for (j = 0; j < flash_nb_blocks; j++) {
|
||||
for (k = 0; k < pOrgDef[j].sector_number; k++) {
|
||||
flash_info[i].start[sector++] = start_address;
|
||||
start_address += pOrgDef[j].sector_size;
|
||||
}
|
||||
}
|
||||
|
||||
size += flash_info[i].size;
|
||||
}
|
||||
|
||||
/* Protect binary boot image */
|
||||
flash_protect (FLAG_PROTECT_SET,
|
||||
CFG_FLASH_BASE,
|
||||
CFG_FLASH_BASE + CFG_BOOT_SIZE - 1, &flash_info[0]);
|
||||
|
||||
/* Protect environment variables */
|
||||
flash_protect (FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
|
||||
|
||||
/* Protect U-Boot gzipped image */
|
||||
flash_protect (FLAG_PROTECT_SET,
|
||||
CFG_U_BOOT_BASE,
|
||||
CFG_U_BOOT_BASE + CFG_U_BOOT_SIZE - 1, &flash_info[0]);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
void flash_print_info (flash_info_t *info)
|
||||
void flash_print_info (flash_info_t * info)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK)
|
||||
{
|
||||
case (ATM_MANUFACT & FLASH_VENDMASK):
|
||||
printf("Atmel: ");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown Vendor ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK)
|
||||
{
|
||||
case (ATM_ID_BV1614 & FLASH_TYPEMASK):
|
||||
printf("AT49BV1614 (16Mbit)\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown Chip Type\n");
|
||||
goto Done;
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" Size: %ld MB in %d Sectors\n",
|
||||
info->size >> 20, info->sector_count);
|
||||
|
||||
printf(" Sector Start Addresses:");
|
||||
for (i = 0; i < info->sector_count; i++)
|
||||
{
|
||||
if ((i % 5) == 0)
|
||||
{
|
||||
printf ("\n ");
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case (ATM_MANUFACT & FLASH_VENDMASK):
|
||||
printf ("Atmel: ");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Vendor ");
|
||||
break;
|
||||
}
|
||||
printf (" %08lX%s", info->start[i],
|
||||
info->protect[i] ? " (RO)" : " ");
|
||||
}
|
||||
printf ("\n");
|
||||
|
||||
Done:
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case (ATM_ID_BV1614 & FLASH_TYPEMASK):
|
||||
printf ("AT49BV1614 (16Mbit)\n");
|
||||
break;
|
||||
case (ATM_ID_BV1614A & FLASH_TYPEMASK):
|
||||
printf ("AT49BV1614A (16Mbit)\n");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Chip Type\n");
|
||||
goto Done;
|
||||
break;
|
||||
}
|
||||
|
||||
printf (" Size: %ld MB in %d Sectors\n",
|
||||
info->size >> 20, info->sector_count);
|
||||
|
||||
printf (" Sector Start Addresses:");
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
if ((i % 5) == 0) {
|
||||
printf ("\n ");
|
||||
}
|
||||
printf (" %08lX%s", info->start[i],
|
||||
info->protect[i] ? " (RO)" : " ");
|
||||
}
|
||||
printf ("\n");
|
||||
|
||||
Done:
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
int flash_erase (flash_info_t * info, int s_first, int s_last)
|
||||
{
|
||||
ulong result;
|
||||
int iflag, cflag, prot, sect;
|
||||
int rc = ERR_OK;
|
||||
int chip1;
|
||||
ulong result;
|
||||
int iflag, cflag, prot, sect;
|
||||
int rc = ERR_OK;
|
||||
int chip1;
|
||||
|
||||
/* first look for protection bits */
|
||||
/* first look for protection bits */
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN)
|
||||
return ERR_UNKNOWN_FLASH_TYPE;
|
||||
if (info->flash_id == FLASH_UNKNOWN)
|
||||
return ERR_UNKNOWN_FLASH_TYPE;
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
return ERR_INVAL;
|
||||
}
|
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) !=
|
||||
(ATM_MANUFACT & FLASH_VENDMASK)) {
|
||||
return ERR_UNKNOWN_FLASH_VENDOR;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
for (sect=s_first; sect<=s_last; ++sect) {
|
||||
if (info->protect[sect]) {
|
||||
prot++;
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
return ERR_INVAL;
|
||||
}
|
||||
}
|
||||
if (prot)
|
||||
return ERR_PROTECTED;
|
||||
|
||||
/*
|
||||
* Disable interrupts which might cause a timeout
|
||||
* here. Remember that our exception vectors are
|
||||
* at address 0 in the flash, and we don't want a
|
||||
* (ticker) exception to happen while the flash
|
||||
* chip is in programming mode.
|
||||
*/
|
||||
cflag = icache_status();
|
||||
icache_disable();
|
||||
iflag = disable_interrupts();
|
||||
if ((info->flash_id & FLASH_VENDMASK) !=
|
||||
(ATM_MANUFACT & FLASH_VENDMASK)) {
|
||||
return ERR_UNKNOWN_FLASH_VENDOR;
|
||||
}
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect<=s_last && !ctrlc(); sect++)
|
||||
{
|
||||
printf("Erasing sector %2d ... ", sect);
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked();
|
||||
|
||||
if (info->protect[sect] == 0)
|
||||
{ /* not protected */
|
||||
volatile u16 *addr = (volatile u16 *)(info->start[sect]);
|
||||
|
||||
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
|
||||
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
|
||||
MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
|
||||
|
||||
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
|
||||
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
|
||||
*addr = CMD_ERASE_CONFIRM;
|
||||
|
||||
/* wait until flash is ready */
|
||||
chip1 = 0;
|
||||
|
||||
do
|
||||
{
|
||||
result = *addr;
|
||||
|
||||
/* check timeout */
|
||||
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
|
||||
{
|
||||
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
|
||||
chip1 = TMO;
|
||||
break;
|
||||
prot = 0;
|
||||
for (sect = s_first; sect <= s_last; ++sect) {
|
||||
if (info->protect[sect]) {
|
||||
prot++;
|
||||
}
|
||||
|
||||
if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE)
|
||||
chip1 = READY;
|
||||
|
||||
} while (!chip1);
|
||||
|
||||
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
|
||||
|
||||
if (chip1 == ERR)
|
||||
{
|
||||
rc = ERR_PROG_ERROR;
|
||||
goto outahere;
|
||||
}
|
||||
if (chip1 == TMO)
|
||||
{
|
||||
rc = ERR_TIMOUT;
|
||||
goto outahere;
|
||||
}
|
||||
|
||||
printf("ok.\n");
|
||||
}
|
||||
else /* it was protected */
|
||||
{
|
||||
printf("protected!\n");
|
||||
}
|
||||
}
|
||||
if (prot)
|
||||
return ERR_PROTECTED;
|
||||
|
||||
if (ctrlc())
|
||||
printf("User Interrupt!\n");
|
||||
/*
|
||||
* Disable interrupts which might cause a timeout
|
||||
* here. Remember that our exception vectors are
|
||||
* at address 0 in the flash, and we don't want a
|
||||
* (ticker) exception to happen while the flash
|
||||
* chip is in programming mode.
|
||||
*/
|
||||
cflag = icache_status ();
|
||||
icache_disable ();
|
||||
iflag = disable_interrupts ();
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
|
||||
printf ("Erasing sector %2d ... ", sect);
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked ();
|
||||
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
volatile u16 *addr = (volatile u16 *) (info->start[sect]);
|
||||
|
||||
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
|
||||
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
|
||||
MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
|
||||
|
||||
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
|
||||
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
|
||||
*addr = CMD_ERASE_CONFIRM;
|
||||
|
||||
/* wait until flash is ready */
|
||||
chip1 = 0;
|
||||
|
||||
do {
|
||||
result = *addr;
|
||||
|
||||
/* check timeout */
|
||||
if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
|
||||
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
|
||||
chip1 = TMO;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE)
|
||||
chip1 = READY;
|
||||
|
||||
} while (!chip1);
|
||||
|
||||
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
|
||||
|
||||
if (chip1 == ERR) {
|
||||
rc = ERR_PROG_ERROR;
|
||||
goto outahere;
|
||||
}
|
||||
if (chip1 == TMO) {
|
||||
rc = ERR_TIMOUT;
|
||||
goto outahere;
|
||||
}
|
||||
|
||||
printf ("ok.\n");
|
||||
} else { /* it was protected */
|
||||
printf ("protected!\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (ctrlc ())
|
||||
printf ("User Interrupt!\n");
|
||||
|
||||
outahere:
|
||||
/* allow flash to settle - wait 10 ms */
|
||||
udelay_masked(10000);
|
||||
/* allow flash to settle - wait 10 ms */
|
||||
udelay_masked (10000);
|
||||
|
||||
if (iflag)
|
||||
enable_interrupts();
|
||||
if (iflag)
|
||||
enable_interrupts ();
|
||||
|
||||
if (cflag)
|
||||
icache_enable();
|
||||
if (cflag)
|
||||
icache_enable ();
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash
|
||||
*/
|
||||
|
||||
volatile static int write_word (flash_info_t *info, ulong dest, ulong data)
|
||||
volatile static int write_word (flash_info_t * info, ulong dest,
|
||||
ulong data)
|
||||
{
|
||||
volatile u16 *addr = (volatile u16 *)dest;
|
||||
ulong result;
|
||||
int rc = ERR_OK;
|
||||
int cflag, iflag;
|
||||
int chip1;
|
||||
volatile u16 *addr = (volatile u16 *) dest;
|
||||
ulong result;
|
||||
int rc = ERR_OK;
|
||||
int cflag, iflag;
|
||||
int chip1;
|
||||
|
||||
/*
|
||||
* Check if Flash is (sufficiently) erased
|
||||
*/
|
||||
result = *addr;
|
||||
if ((result & data) != data)
|
||||
return ERR_NOT_ERASED;
|
||||
|
||||
|
||||
/*
|
||||
* Disable interrupts which might cause a timeout
|
||||
* here. Remember that our exception vectors are
|
||||
* at address 0 in the flash, and we don't want a
|
||||
* (ticker) exception to happen while the flash
|
||||
* chip is in programming mode.
|
||||
*/
|
||||
cflag = icache_status();
|
||||
icache_disable();
|
||||
iflag = disable_interrupts();
|
||||
|
||||
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
|
||||
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
|
||||
MEM_FLASH_ADDR1 = CMD_PROGRAM;
|
||||
*addr = data;
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked();
|
||||
|
||||
/* wait until flash is ready */
|
||||
chip1 = 0;
|
||||
do
|
||||
{
|
||||
/*
|
||||
* Check if Flash is (sufficiently) erased
|
||||
*/
|
||||
result = *addr;
|
||||
if ((result & data) != data)
|
||||
return ERR_NOT_ERASED;
|
||||
|
||||
/* check timeout */
|
||||
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
|
||||
{
|
||||
chip1 = ERR | TMO;
|
||||
break;
|
||||
}
|
||||
if (!chip1 && ((result & 0x80) == (data & 0x80)))
|
||||
chip1 = READY;
|
||||
|
||||
} while (!chip1);
|
||||
/*
|
||||
* Disable interrupts which might cause a timeout
|
||||
* here. Remember that our exception vectors are
|
||||
* at address 0 in the flash, and we don't want a
|
||||
* (ticker) exception to happen while the flash
|
||||
* chip is in programming mode.
|
||||
*/
|
||||
cflag = icache_status ();
|
||||
icache_disable ();
|
||||
iflag = disable_interrupts ();
|
||||
|
||||
*addr = CMD_READ_ARRAY;
|
||||
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
|
||||
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
|
||||
MEM_FLASH_ADDR1 = CMD_PROGRAM;
|
||||
*addr = data;
|
||||
|
||||
if (chip1 == ERR || *addr != data)
|
||||
rc = ERR_PROG_ERROR;
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked ();
|
||||
|
||||
if (iflag)
|
||||
enable_interrupts();
|
||||
/* wait until flash is ready */
|
||||
chip1 = 0;
|
||||
do {
|
||||
result = *addr;
|
||||
|
||||
if (cflag)
|
||||
icache_enable();
|
||||
/* check timeout */
|
||||
if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
|
||||
chip1 = ERR | TMO;
|
||||
break;
|
||||
}
|
||||
if (!chip1 && ((result & 0x80) == (data & 0x80)))
|
||||
chip1 = READY;
|
||||
|
||||
return rc;
|
||||
} while (!chip1);
|
||||
|
||||
*addr = CMD_READ_ARRAY;
|
||||
|
||||
if (chip1 == ERR || *addr != data)
|
||||
rc = ERR_PROG_ERROR;
|
||||
|
||||
if (iflag)
|
||||
enable_interrupts ();
|
||||
|
||||
if (cflag)
|
||||
icache_enable ();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash.
|
||||
*/
|
||||
|
||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong wp, data;
|
||||
int rc;
|
||||
ulong wp, data;
|
||||
int rc;
|
||||
|
||||
if(addr & 1) {
|
||||
printf("unaligned destination not supported\n");
|
||||
return ERR_ALIGN;
|
||||
};
|
||||
if (addr & 1) {
|
||||
printf ("unaligned destination not supported\n");
|
||||
return ERR_ALIGN;
|
||||
};
|
||||
|
||||
if((int)src & 1) {
|
||||
printf("unaligned source not supported\n");
|
||||
return ERR_ALIGN;
|
||||
};
|
||||
if ((int) src & 1) {
|
||||
printf ("unaligned source not supported\n");
|
||||
return ERR_ALIGN;
|
||||
};
|
||||
|
||||
wp = addr;
|
||||
wp = addr;
|
||||
|
||||
while (cnt >= 2) {
|
||||
data = *((volatile u16*)src);
|
||||
if ((rc = write_word(info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
while (cnt >= 2) {
|
||||
data = *((volatile u16 *) src);
|
||||
if ((rc = write_word (info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
src += 2;
|
||||
wp += 2;
|
||||
cnt -= 2;
|
||||
}
|
||||
src += 2;
|
||||
wp += 2;
|
||||
cnt -= 2;
|
||||
}
|
||||
|
||||
if(cnt == 1) {
|
||||
data = (*((volatile u8*)src)) | (*((volatile u8*)(wp+1)) << 8);
|
||||
if ((rc = write_word(info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
src += 1;
|
||||
wp += 1;
|
||||
cnt -= 1;
|
||||
};
|
||||
if (cnt == 1) {
|
||||
data = (*((volatile u8 *) src)) | (*((volatile u8 *) (wp + 1)) <<
|
||||
8);
|
||||
if ((rc = write_word (info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
src += 1;
|
||||
wp += 1;
|
||||
cnt -= 1;
|
||||
};
|
||||
|
||||
return ERR_OK;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
@@ -203,6 +203,49 @@ const iop_conf_t iop_conf_tab[4][32] = {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* UPMB initialization table
|
||||
*/
|
||||
#define _NOT_USED_ 0xFFFFFFFF
|
||||
|
||||
static const uint rtc_table[] =
|
||||
{
|
||||
/*
|
||||
* Single Read. (Offset 0 in UPMA RAM)
|
||||
*/
|
||||
0xfffec00, 0xfffac00, 0xfff2d00, 0xfef2800,
|
||||
0xfaf2080, 0xfaf2080, 0xfff2400, 0x1fff6c05, /* last */
|
||||
/*
|
||||
* Burst Read. (Offset 8 in UPMA RAM)
|
||||
*/
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
/*
|
||||
* Single Write. (Offset 18 in UPMA RAM)
|
||||
*/
|
||||
0xfffec00, 0xfffac00, 0xfff2d00, 0xfef2800,
|
||||
0xfaf2080, 0xfaf2080, 0xfaf2400, 0x1fbf6c05, /* last */
|
||||
/*
|
||||
* Burst Write. (Offset 20 in UPMA RAM)
|
||||
*/
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
/*
|
||||
* Refresh (Offset 30 in UPMA RAM)
|
||||
*/
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
/*
|
||||
* Exception. (Offset 3c in UPMA RAM)
|
||||
*/
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Check Board Identity:
|
||||
@@ -319,6 +362,17 @@ static long int try_init (volatile memctl8260_t * memctl, ulong sdmr,
|
||||
return (maxsize);
|
||||
}
|
||||
|
||||
int misc_init_r(void)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
volatile memctl8260_t *memctl = &immap->im_memctl;
|
||||
|
||||
upmconfig(UPMA, (uint *)rtc_table, sizeof(rtc_table) / sizeof(uint));
|
||||
memctl->memc_mamr = MxMR_RLFx_6X | MxMR_WLFx_6X | MxMR_OP_NORM;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
long int initdram (int board_type)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
|
||||
@@ -30,12 +30,7 @@
|
||||
# in RAM where U-Boot is loaded at for debugging.
|
||||
#
|
||||
|
||||
ifeq ($(CONFIG_BOOT_ROM),y)
|
||||
TEXT_BASE := 0xFF800000
|
||||
PLATFORM_CPPFLAGS += -DCONFIG_BOOT_ROM
|
||||
else
|
||||
TEXT_BASE := 0xFF000000
|
||||
endif
|
||||
TEXT_BASE := 0xFF000000
|
||||
|
||||
# RAM version
|
||||
#TEXT_BASE := 0x100000
|
||||
|
||||
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS = $(BOARD).o flash.o bsp.o eeprom.o fetch.o
|
||||
OBJS = $(BOARD).o flash.o bsp.o eeprom.o fetch.o input.o env.o
|
||||
|
||||
$(LIB): .depend $(OBJS)
|
||||
$(AR) crv $@ $^
|
||||
|
||||
@@ -20,13 +20,12 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
* hacked for Hymod FPGA support by Murray.Jensen@cmst.csiro.au, 29-Jan-01
|
||||
* hacked for Hymod FPGA support by Murray.Jensen@csiro.au, 29-Jan-01
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <net.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/iopin_8260.h>
|
||||
#include <cmd_bsp.h>
|
||||
|
||||
@@ -74,28 +73,29 @@
|
||||
* has not worked (wait several ms?)
|
||||
*/
|
||||
|
||||
int fpga_load (int mezz, uchar * addr, ulong size)
|
||||
int
|
||||
fpga_load (int mezz, uchar *addr, ulong size)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
hymod_conf_t *cp = &gd->bd->bi_hymod_conf;
|
||||
xlx_info_t *fp;
|
||||
xlx_iopins_t *fpgaio;
|
||||
volatile uchar *fpgabase;
|
||||
volatile uint cnt;
|
||||
uchar *eaddr = addr + size;
|
||||
int result;
|
||||
|
||||
if (mezz) {
|
||||
if (!cp->mezz.mmap[0].prog.exists)
|
||||
return (LOAD_FAIL_NOCONF);
|
||||
fpgabase = (uchar *) cp->mezz.mmap[0].prog.base;
|
||||
fpgaio = &cp->mezz.iopins[0];
|
||||
} else {
|
||||
if (!cp->main.mmap[0].prog.exists)
|
||||
return (LOAD_FAIL_NOCONF);
|
||||
fpgabase = (uchar *) cp->main.mmap[0].prog.base;
|
||||
fpgaio = &cp->main.iopins[0];
|
||||
}
|
||||
if (mezz)
|
||||
fp = &cp->mezz.xlx[0];
|
||||
else
|
||||
fp = &cp->main.xlx[0];
|
||||
|
||||
if (!fp->mmap.prog.exists)
|
||||
return (LOAD_FAIL_NOCONF);
|
||||
|
||||
fpgabase = (uchar *)fp->mmap.prog.base;
|
||||
fpgaio = &fp->iopins;
|
||||
|
||||
/* set enable HIGH if required */
|
||||
if (fpgaio->enable_pin.flag)
|
||||
@@ -106,7 +106,7 @@ int fpga_load (int mezz, uchar * addr, ulong size)
|
||||
|
||||
/* toggle PROG Low then High (will already be Low after Power-On) */
|
||||
iopin_set_low (&fpgaio->prog_pin);
|
||||
udelay (1); /* minimum 300ns - 1usec should do it */
|
||||
udelay (1); /* minimum 300ns - 1usec should do it */
|
||||
iopin_set_high (&fpgaio->prog_pin);
|
||||
|
||||
/* wait for INIT High */
|
||||
@@ -157,15 +157,15 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
case 2:
|
||||
if (strcmp (argv[1], "info") == 0) {
|
||||
printf ("\nHymod FPGA Info...\n");
|
||||
printf (" Address Size\n");
|
||||
printf (" Main Configuration: 0x%08x %d\n",
|
||||
FPGA_MAIN_CFG_BASE, FPGA_MAIN_CFG_SIZE);
|
||||
printf (" Main Register: 0x%08x %d\n",
|
||||
FPGA_MAIN_REG_BASE, FPGA_MAIN_REG_SIZE);
|
||||
printf (" Main Port: 0x%08x %d\n",
|
||||
FPGA_MAIN_PORT_BASE, FPGA_MAIN_PORT_SIZE);
|
||||
printf (" Mezz Configuration: 0x%08x %d\n",
|
||||
FPGA_MEZZ_CFG_BASE, FPGA_MEZZ_CFG_SIZE);
|
||||
printf ("\t\t\t\tAddress\t\tSize\n");
|
||||
printf ("\tMain Configuration:\t0x%08x\t%d\n",
|
||||
FPGA_MAIN_CFG_BASE, FPGA_MAIN_CFG_SIZE);
|
||||
printf ("\tMain Register:\t\t0x%08x\t%d\n",
|
||||
FPGA_MAIN_REG_BASE, FPGA_MAIN_REG_SIZE);
|
||||
printf ("\tMain Port:\t\t0x%08x\t%d\n",
|
||||
FPGA_MAIN_PORT_BASE, FPGA_MAIN_PORT_SIZE);
|
||||
printf ("\tMezz Configuration:\t0x%08x\t%d\n",
|
||||
FPGA_MEZZ_CFG_BASE, FPGA_MEZZ_CFG_SIZE);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
@@ -176,18 +176,21 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
|
||||
save_addr = addr;
|
||||
#if 0
|
||||
/* reading config data unimplemented */
|
||||
while VM
|
||||
:more config data * addr++ = *fpga;
|
||||
result = VM:? ? ?
|
||||
/* fpga readback unimplemented */
|
||||
while (more readback data)
|
||||
*addr++ = *fpga;
|
||||
result = error ? STORE_FAIL_XXX : STORE_SUCCESS;
|
||||
#else
|
||||
result = 0;
|
||||
result = STORE_SUCCESS;
|
||||
#endif
|
||||
|
||||
if (result == STORE_SUCCESS) {
|
||||
printf ("SUCCEEDED (%d bytes)\n", addr - save_addr);
|
||||
printf ("SUCCEEDED (%d bytes)\n",
|
||||
addr - save_addr);
|
||||
return 0;
|
||||
} else
|
||||
printf ("FAILED (%d bytes)\n", addr - save_addr);
|
||||
printf ("FAILED (%d bytes)\n",
|
||||
addr - save_addr);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@@ -196,25 +199,32 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
if (strcmp (argv[1], "tftp") == 0) {
|
||||
copy_filename (BootFile, argv[2], sizeof (BootFile));
|
||||
load_addr = simple_strtoul (argv[3], NULL, 16);
|
||||
NetBootFileXferSize = 0;
|
||||
|
||||
if (NetLoop (TFTP) <= 0) {
|
||||
printf ("tftp transfer failed - aborting fgpa load\n");
|
||||
printf ("tftp transfer failed - aborting "
|
||||
"fgpa load\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (NetBootFileXferSize == 0) {
|
||||
printf ("can't determine file size - aborting fpga load\n");
|
||||
printf ("can't determine file size - "
|
||||
"aborting fpga load\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("File transfer succeeded - beginning fpga load...");
|
||||
printf ("File transfer succeeded - "
|
||||
"beginning fpga load...");
|
||||
|
||||
result = fpga_load (0, (uchar *) load_addr,
|
||||
NetBootFileXferSize);
|
||||
NetBootFileXferSize);
|
||||
|
||||
if (result == LOAD_SUCCESS) {
|
||||
printf ("SUCCEEDED\n");
|
||||
return 0;
|
||||
} else if (result == LOAD_FAIL_NOINIT)
|
||||
} else if (result == LOAD_FAIL_NOCONF)
|
||||
printf ("FAILED (no CONF)\n");
|
||||
else if (result == LOAD_FAIL_NOINIT)
|
||||
printf ("FAILED (no INIT)\n");
|
||||
else
|
||||
printf ("FAILED (no DONE)\n");
|
||||
@@ -231,7 +241,8 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
else if (strcmp (argv[2], "mezz") == 0)
|
||||
mezz = 1;
|
||||
else {
|
||||
printf ("FPGA type must be either `main' or `mezz'\n");
|
||||
printf ("FPGA type must be either "
|
||||
"`main' or `mezz'\n");
|
||||
return 1;
|
||||
}
|
||||
arg = 3;
|
||||
@@ -239,14 +250,18 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
mezz = 0;
|
||||
arg = 2;
|
||||
}
|
||||
|
||||
addr = (uchar *) simple_strtoul (argv[arg++], NULL, 16);
|
||||
size = (ulong) simple_strtoul (argv[arg], NULL, 16);
|
||||
|
||||
result = fpga_load (mezz, addr, size);
|
||||
|
||||
if (result == LOAD_SUCCESS) {
|
||||
printf ("SUCCEEDED\n");
|
||||
return 0;
|
||||
} else if (result == LOAD_FAIL_NOINIT)
|
||||
} else if (result == LOAD_FAIL_NOCONF)
|
||||
printf ("FAILED (no CONF)\n");
|
||||
else if (result == LOAD_FAIL_NOINIT)
|
||||
printf ("FAILED (no INIT)\n");
|
||||
else
|
||||
printf ("FAILED (no DONE)\n");
|
||||
@@ -267,22 +282,21 @@ int
|
||||
do_eecl (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
uchar data[HYMOD_EEPROM_SIZE];
|
||||
uint offset;
|
||||
int rcode = 0;
|
||||
uint addr = CFG_I2C_EEPROM_ADDR;
|
||||
|
||||
switch (argc) {
|
||||
|
||||
case 1:
|
||||
offset = HYMOD_EEOFF_MAIN;
|
||||
addr |= HYMOD_EEOFF_MAIN;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (strcmp (argv[1], "main") == 0) {
|
||||
offset = HYMOD_EEOFF_MAIN;
|
||||
addr |= HYMOD_EEOFF_MAIN;
|
||||
break;
|
||||
}
|
||||
if (strcmp (argv[1], "mezz") == 0) {
|
||||
offset = HYMOD_EEOFF_MEZZ;
|
||||
addr |= HYMOD_EEOFF_MEZZ;
|
||||
break;
|
||||
}
|
||||
/* fall through ... */
|
||||
@@ -293,15 +307,77 @@ do_eecl (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
}
|
||||
|
||||
memset (data, 0, HYMOD_EEPROM_SIZE);
|
||||
if (i2c_write
|
||||
(CFG_I2C_EEPROM_ADDR | offset, 0, CFG_I2C_EEPROM_ADDR_LEN, data,
|
||||
HYMOD_EEPROM_SIZE)) {
|
||||
rcode = 1;
|
||||
}
|
||||
|
||||
return rcode;
|
||||
eeprom_write (addr, 0, data, HYMOD_EEPROM_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CFG_CMD_BSP */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#if 0
|
||||
static uchar test_bitfile[] = {
|
||||
/* one day ... */
|
||||
};
|
||||
#endif
|
||||
|
||||
int
|
||||
do_htest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
#if 0
|
||||
int rc;
|
||||
#endif
|
||||
#ifdef CONFIG_ETHER_LOOPBACK_TEST
|
||||
extern void eth_loopback_test (void);
|
||||
#endif /* CONFIG_ETHER_LOOPBACK_TEST */
|
||||
|
||||
printf ("HYMOD tests - ensure loopbacks etc. are connected\n\n");
|
||||
|
||||
#if 0
|
||||
/* Load FPGA with test program */
|
||||
|
||||
printf ("Loading test FPGA program ...");
|
||||
|
||||
rc = fpga_load (0, test_bitfile, sizeof (test_bitfile));
|
||||
|
||||
switch (rc) {
|
||||
|
||||
case LOAD_SUCCESS:
|
||||
printf (" SUCCEEDED\n");
|
||||
break;
|
||||
|
||||
case LOAD_FAIL_NOCONF:
|
||||
printf (" FAILED (no configuration space defined)\n");
|
||||
return 1;
|
||||
|
||||
case LOAD_FAIL_NOINIT:
|
||||
printf (" FAILED (timeout - no INIT signal seen)\n");
|
||||
return 1;
|
||||
|
||||
case LOAD_FAIL_NODONE:
|
||||
printf (" FAILED (timeout - no DONE signal seen)\n");
|
||||
return 1;
|
||||
|
||||
default:
|
||||
printf (" FAILED (unknown return code from fpga_load\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* run Local Bus <=> Xilinx tests */
|
||||
|
||||
/* tell Xilinx to run ZBT Ram, High Speed serial and Mezzanine tests */
|
||||
|
||||
/* run SDRAM test */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ETHER_LOOPBACK_TEST
|
||||
/* run Ethernet test */
|
||||
eth_loopback_test ();
|
||||
#endif /* CONFIG_ETHER_LOOPBACK_TEST */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CFG_CMD_BSP */
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
@@ -27,6 +27,6 @@
|
||||
|
||||
TEXT_BASE = 0x40000000
|
||||
|
||||
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)
|
||||
PLATFORM_CPPFLAGS += -I$(TOPDIR)
|
||||
|
||||
OBJCFLAGS = --set-section-flags=.ppcenv=contents,alloc,load,data
|
||||
OBJCFLAGS = --remove-section=.ppcenv
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
236
board/hymod/env.c
Normal file
236
board/hymod/env.c
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
|
||||
*
|
||||
* 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>
|
||||
|
||||
/* imports from fetch.c */
|
||||
extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *));
|
||||
|
||||
/* this is relative to the root of the server's tftp directory */
|
||||
static char *def_global_env_path = "/hymod/global_env";
|
||||
|
||||
static int
|
||||
env_callback (uchar *name, uchar *value)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
hymod_conf_t *cp = &gd->bd->bi_hymod_conf;
|
||||
char ov[CFG_CBSIZE], nv[CFG_CBSIZE], *p, *q, *nn, c, *curver, *newver;
|
||||
int override = 1, append = 0, remove = 0, nnl, ovl, nvl;
|
||||
|
||||
nn = name;
|
||||
|
||||
if (*nn == '-') {
|
||||
override = 0;
|
||||
nn++;
|
||||
}
|
||||
|
||||
while (*nn == ' ' || *nn == '\t')
|
||||
nn++;
|
||||
|
||||
if ((nnl = strlen (nn)) == 0) {
|
||||
printf ("Empty name in global env file\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
if ((c = nn[nnl - 1]) == '+' || c == '-') {
|
||||
if (c == '+')
|
||||
append = 1;
|
||||
else
|
||||
remove = 1;
|
||||
nn[--nnl] = '\0';
|
||||
}
|
||||
|
||||
while (nnl > 0 && ((c = nn[nnl - 1]) == ' ' || c == '\t'))
|
||||
nn[--nnl] = '\0';
|
||||
if (nnl == 0) {
|
||||
printf ("Empty name in global env file\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
p = value;
|
||||
q = nv;
|
||||
|
||||
while ((c = *p) == ' ' || c == '\t')
|
||||
p++;
|
||||
|
||||
nvl = strlen (p);
|
||||
while (nvl > 0 && ((c = p[nvl - 1]) == ' ' || c == '\t'))
|
||||
p[--nvl] = '\0';
|
||||
|
||||
while ((*q = *p++) != '\0') {
|
||||
if (*q == '%') {
|
||||
switch (*p++) {
|
||||
|
||||
case '\0': /* whoops - back up */
|
||||
p--;
|
||||
break;
|
||||
|
||||
case '%': /* a single percent character */
|
||||
q++;
|
||||
break;
|
||||
|
||||
case 's': /* main board serial number as string */
|
||||
q += sprintf (q, "%010lu",
|
||||
cp->main.eeprom.serno);
|
||||
break;
|
||||
|
||||
case 'S': /* main board serial number as number */
|
||||
q += sprintf (q, "%lu", cp->main.eeprom.serno);
|
||||
break;
|
||||
|
||||
default: /* ignore any others */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
q++;
|
||||
}
|
||||
|
||||
if ((nvl = q - nv) == 0) {
|
||||
setenv (nn, NULL);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if ((curver = getenv ("global_env_version")) == NULL)
|
||||
curver = "unknown";
|
||||
|
||||
if ((newver = getenv ("new_genv_version")) == NULL || \
|
||||
strcmp (curver, newver) == 0) {
|
||||
if (strcmp (nn, "version") == 0)
|
||||
setenv ("new_genv_version", nv);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if ((p = getenv (nn)) != NULL) {
|
||||
|
||||
strcpy (ov, p);
|
||||
ovl = strlen (ov);
|
||||
|
||||
if (append) {
|
||||
|
||||
if (strstr (ov, nv) == NULL) {
|
||||
|
||||
printf ("Appending '%s' to env var '%s'\n",
|
||||
nv, nn);
|
||||
|
||||
while (nvl >= 0) {
|
||||
nv[ovl + 1 + nvl] = nv[nvl];
|
||||
nvl--;
|
||||
}
|
||||
|
||||
nv[ovl] = ' ';
|
||||
|
||||
while (--ovl >= 0)
|
||||
nv[ovl] = ov[ovl];
|
||||
|
||||
setenv (nn, nv);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (remove) {
|
||||
|
||||
if (strstr (ov, nv) != NULL) {
|
||||
|
||||
printf ("Removing '%s' from env var '%s'\n",
|
||||
nv, nn);
|
||||
|
||||
while ((p = strstr (ov, nv)) != NULL) {
|
||||
q = p + nvl;
|
||||
if (*q == ' ')
|
||||
q++;
|
||||
strcpy(p, q);
|
||||
}
|
||||
|
||||
setenv (nn, ov);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (!override || strcmp (ov, nv) == 0)
|
||||
return (1);
|
||||
|
||||
printf ("Re-setting env cmd '%s' from '%s' to '%s'\n",
|
||||
nn, ov, nv);
|
||||
}
|
||||
else
|
||||
printf ("Setting env cmd '%s' to '%s'\n", nn, nv);
|
||||
|
||||
setenv (nn, nv);
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
hymod_check_env (void)
|
||||
{
|
||||
char *p, *path, *curver, *newver;
|
||||
int firsttime = 0, needsave = 0;
|
||||
|
||||
if (getenv ("global_env_loaded") == NULL) {
|
||||
puts ("*** global environment has never been loaded\n");
|
||||
puts ("*** fetching from server");
|
||||
firsttime = 1;
|
||||
}
|
||||
else if ((p = getenv ("always_check_env")) != NULL &&
|
||||
strcmp (p, "yes") == 0)
|
||||
puts ("*** checking for updated global environment");
|
||||
else
|
||||
return;
|
||||
|
||||
puts (" (Control-C to Abort)\n");
|
||||
|
||||
if ((path = getenv ("global_env_path")) == NULL || *path == '\0')
|
||||
path = def_global_env_path;
|
||||
|
||||
if (fetch_and_parse (path, CFG_LOAD_ADDR, env_callback) == 0) {
|
||||
puts ("*** Fetch of global environment failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((newver = getenv ("new_genv_version")) == NULL) {
|
||||
puts ("*** Version number not set - contents ignored!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((curver = getenv ("global_env_version")) == NULL || \
|
||||
strcmp (curver, newver) != 0) {
|
||||
setenv ("global_env_version", newver);
|
||||
needsave = 1;
|
||||
}
|
||||
else
|
||||
printf ("*** Global environment up-to-date (ver %s)\n", curver);
|
||||
|
||||
setenv ("new_genv_version", NULL);
|
||||
|
||||
if (firsttime) {
|
||||
setenv ("global_env_loaded", "yes");
|
||||
needsave = 1;
|
||||
}
|
||||
|
||||
if (needsave)
|
||||
puts ("\n*** Remember to run the 'saveenv' "
|
||||
"command to save the changes\n\n");
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* (C) Copyright 2001
|
||||
* Murray Jensen, CSIRO Manufacturing Science and Technology,
|
||||
* <Murray.Jensen@cmst.csiro.au>
|
||||
* Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
@@ -25,118 +24,84 @@
|
||||
#include <common.h>
|
||||
#include <net.h>
|
||||
|
||||
/* imports from common/main.c */
|
||||
extern char console_buffer[CFG_CBSIZE];
|
||||
/* imports from input.c */
|
||||
extern int hymod_get_ethaddr (void);
|
||||
|
||||
int
|
||||
fetch_and_parse(bd_t *bd, char *fn, ulong addr, int (*cback)(uchar *, uchar *))
|
||||
fetch_and_parse (char *fn, ulong addr, int (*cback)(uchar *, uchar *))
|
||||
{
|
||||
char *ethaddr;
|
||||
uchar *fp, *efp;
|
||||
char *ethaddr;
|
||||
uchar *fp, *efp;
|
||||
int rc, count = 0;
|
||||
|
||||
while ((ethaddr = getenv("ethaddr")) == NULL || *ethaddr == '\0') {
|
||||
while ((ethaddr = getenv ("ethaddr")) == NULL || *ethaddr == '\0') {
|
||||
|
||||
puts("*** Ethernet address is not set\n");
|
||||
printf ("*** Ethernet address is%s not set\n",
|
||||
count == 0 ? "" : " STILL");
|
||||
|
||||
for (;;) {
|
||||
int n;
|
||||
if ((rc = hymod_get_ethaddr ()) < 0) {
|
||||
if (rc == -1)
|
||||
puts ("\n*** interrupted!");
|
||||
else
|
||||
puts ("\n*** timeout!");
|
||||
printf (" - fetch of '%s' aborted\n", fn);
|
||||
return (0);
|
||||
}
|
||||
|
||||
n = readline("Enter board ethernet address: ");
|
||||
count++;
|
||||
}
|
||||
|
||||
if (n < 0) {
|
||||
puts("\n");
|
||||
copy_filename (BootFile, fn, sizeof (BootFile));
|
||||
load_addr = addr;
|
||||
NetBootFileXferSize = 0;
|
||||
|
||||
if (NetLoop (TFTP) == 0) {
|
||||
printf ("tftp transfer of file '%s' failed\n", fn);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
continue;
|
||||
|
||||
if (n == 17) {
|
||||
int i;
|
||||
char *p, *q;
|
||||
uchar ea[6];
|
||||
|
||||
/* see if it looks like an ethernet address */
|
||||
|
||||
p = console_buffer;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
char term = (i == 5 ? '\0' : ':');
|
||||
|
||||
ea[i] = simple_strtol(p, &q, 16);
|
||||
|
||||
if ((q - p) != 2 || *q++ != term)
|
||||
break;
|
||||
|
||||
p = q;
|
||||
}
|
||||
|
||||
if (i == 6) {
|
||||
/* it looks ok - set it */
|
||||
printf("Setting ethernet address to %s\n", console_buffer);
|
||||
setenv("ethaddr", console_buffer);
|
||||
|
||||
puts("Remember to do a 'saveenv' to make it permanent\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Invalid ethernet address (%s) - please re-enter\n",
|
||||
console_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
copy_filename(BootFile, fn, sizeof (BootFile));
|
||||
load_addr = addr;
|
||||
|
||||
if (NetLoop(TFTP) <= 0) {
|
||||
printf("tftp transfer of file '%s' failed\n", fn);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (NetBootFileXferSize == 0) {
|
||||
printf("can't determine size of file '%s'\n", fn);
|
||||
return (0);
|
||||
}
|
||||
|
||||
fp = (uchar *)load_addr;
|
||||
efp = fp + NetBootFileXferSize;
|
||||
|
||||
do {
|
||||
uchar *name, *value;
|
||||
|
||||
if (*fp == '#' || *fp == '\n') {
|
||||
while (fp < efp && *fp++ != '\n')
|
||||
;
|
||||
continue;
|
||||
}
|
||||
|
||||
name = fp;
|
||||
if (NetBootFileXferSize == 0) {
|
||||
printf ("can't determine size of file '%s'\n", fn);
|
||||
return (0);
|
||||
}
|
||||
|
||||
fp = (uchar *)load_addr;
|
||||
efp = fp + NetBootFileXferSize;
|
||||
|
||||
do {
|
||||
uchar *name, *value;
|
||||
|
||||
if (*fp == '#' || *fp == '\n') {
|
||||
/* skip this line */
|
||||
while (fp < efp && *fp++ != '\n')
|
||||
;
|
||||
continue;
|
||||
}
|
||||
|
||||
while (fp < efp && *fp != '=')
|
||||
if (*fp++ == '\n')
|
||||
name = fp;
|
||||
|
||||
if (fp >= efp)
|
||||
break;
|
||||
while (fp < efp && *fp != '=' && *fp != '\n')
|
||||
fp++;
|
||||
if (fp >= efp)
|
||||
break;
|
||||
if (*fp == '\n') {
|
||||
fp++;
|
||||
continue;
|
||||
}
|
||||
*fp++ = '\0';
|
||||
|
||||
*fp++ = '\0';
|
||||
value = fp;
|
||||
|
||||
value = fp;
|
||||
while (fp < efp && *fp != '\n')
|
||||
fp++;
|
||||
if (fp[-1] == '\r')
|
||||
fp[-1] = '\0';
|
||||
*fp++ = '\0'; /* ok if we go off the end here */
|
||||
|
||||
while (fp < efp && *fp != '\n')
|
||||
fp++;
|
||||
if ((*cback)(name, value) == 0)
|
||||
return (0);
|
||||
|
||||
/* ok if we go off the end here */
|
||||
} while (fp < efp);
|
||||
|
||||
if (fp[-1] == '\r')
|
||||
fp[-1] = '\0';
|
||||
*fp++ = '\0';
|
||||
|
||||
if ((*cback)(name, value) == 0)
|
||||
return (0);
|
||||
|
||||
} while (fp < efp);
|
||||
|
||||
return (1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
* Hacked for the Hymod board by Murray.Jensen@cmst.csiro.au, 20-Oct-00
|
||||
* Hacked for the Hymod board by Murray.Jensen@csiro.au, 20-Oct-00
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
@@ -35,235 +35,155 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
#define FLAG_PROTECT_SET 0x01
|
||||
#define FLAG_PROTECT_CLEAR 0x02
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
#if 0
|
||||
static ulong flash_get_size (vu_long *addr, flash_info_t *info);
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info);
|
||||
#endif
|
||||
static int write_word (flash_info_t *info, ulong dest, ulong data);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* probe for the existence of flash at bank word address "addr"
|
||||
* 0 = yes, 1 = bad Manufacturer's Id, 2 = bad Device Id
|
||||
* probe for flash bank at address "base" and store info about it
|
||||
* in the flash_info entry "fip". Fatal error if nothing there.
|
||||
*/
|
||||
static int
|
||||
bank_probe_word(bank_addr_t addr)
|
||||
static void
|
||||
bank_probe (flash_info_t *fip, volatile bank_addr_t base)
|
||||
{
|
||||
int retval;
|
||||
volatile bank_addr_t addr;
|
||||
bank_word_t word;
|
||||
int i;
|
||||
|
||||
/* reset the flash */
|
||||
*addr = BANK_CMD_RST;
|
||||
*base = BANK_CMD_RST;
|
||||
|
||||
/* check the manufacturer id */
|
||||
*addr = BANK_CMD_RD_ID;
|
||||
if (*BANK_ADDR_REG_MAN(addr) != BANK_RD_ID_MAN) {
|
||||
retval = -1;
|
||||
goto out;
|
||||
}
|
||||
/* put flash into read id mode */
|
||||
*base = BANK_CMD_RD_ID;
|
||||
|
||||
/* check the manufacturer id - must be intel */
|
||||
word = *BANK_REG_MAN_CODE (base);
|
||||
if (word != BANK_FILL_WORD (INTEL_MANUFACT&0xff))
|
||||
panic ("\nbad manufacturer's code (0x%08lx) at addr 0x%08lx",
|
||||
(unsigned long)word, (unsigned long)base);
|
||||
|
||||
/* check the device id */
|
||||
*addr = BANK_CMD_RD_ID;
|
||||
if (*BANK_ADDR_REG_DEV(addr) != BANK_RD_ID_DEV) {
|
||||
retval = -2;
|
||||
goto out;
|
||||
word = *BANK_REG_DEV_CODE (base);
|
||||
switch (word) {
|
||||
|
||||
case BANK_FILL_WORD (INTEL_ID_28F320J5&0xff):
|
||||
fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J5;
|
||||
fip->sector_count = 32;
|
||||
break;
|
||||
|
||||
case BANK_FILL_WORD (INTEL_ID_28F640J5&0xff):
|
||||
fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J5;
|
||||
fip->sector_count = 64;
|
||||
break;
|
||||
|
||||
case BANK_FILL_WORD (INTEL_ID_28F320J3A&0xff):
|
||||
fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J3A;
|
||||
fip->sector_count = 32;
|
||||
break;
|
||||
|
||||
case BANK_FILL_WORD (INTEL_ID_28F640J3A&0xff):
|
||||
fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J3A;
|
||||
fip->sector_count = 64;
|
||||
break;
|
||||
|
||||
case BANK_FILL_WORD (INTEL_ID_28F128J3A&0xff):
|
||||
fip->flash_id = FLASH_MAN_INTEL | FLASH_28F128J3A;
|
||||
fip->sector_count = 128;
|
||||
break;
|
||||
|
||||
default:
|
||||
panic ("\nbad device code (0x%08lx) at addr 0x%08lx",
|
||||
(unsigned long)word, (unsigned long)base);
|
||||
}
|
||||
|
||||
retval = CFG_FLASH_TYPE;
|
||||
|
||||
out:
|
||||
/* reset the flash again */
|
||||
*addr = BANK_CMD_RST;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* probe for flash banks at address "base" and store info for any found
|
||||
* into flash_info entry "fip". Must find at least one bank.
|
||||
*/
|
||||
static void
|
||||
bank_probe(flash_info_t *fip, bank_addr_t base)
|
||||
{
|
||||
bank_addr_t addr, eaddr;
|
||||
int nbanks;
|
||||
|
||||
fip->flash_id = FLASH_UNKNOWN;
|
||||
fip->size = 0L;
|
||||
fip->sector_count = 0;
|
||||
if (fip->sector_count >= CFG_MAX_FLASH_SECT)
|
||||
panic ("\ntoo many sectors (%d) in flash at address 0x%08lx",
|
||||
fip->sector_count, (unsigned long)base);
|
||||
|
||||
addr = base;
|
||||
eaddr = BANK_ADDR_BASE(addr, MAX_BANKS);
|
||||
nbanks = 0;
|
||||
|
||||
while (addr < eaddr) {
|
||||
bank_addr_t addrw, eaddrw, addrb;
|
||||
int i, osc, nsc, curtype = -1;
|
||||
|
||||
addrw = addr;
|
||||
eaddrw = BANK_ADDR_NEXT_WORD(addrw);
|
||||
|
||||
while (addrw < eaddrw) {
|
||||
int thistype;
|
||||
|
||||
#ifdef FLASH_DEBUG
|
||||
printf(" probing for flash at addr 0x%08lx\n",
|
||||
(unsigned long)addrw);
|
||||
#endif
|
||||
if ((thistype = bank_probe_word(addrw++)) < 0)
|
||||
goto out;
|
||||
|
||||
if (curtype < 0)
|
||||
curtype = thistype;
|
||||
else {
|
||||
if (thistype != curtype) {
|
||||
printf("Differing flash type found!\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (curtype < 0)
|
||||
goto out;
|
||||
|
||||
/* bank exists - append info for this bank to *fip */
|
||||
fip->flash_id = FLASH_MAN_INTEL|curtype;
|
||||
fip->size += BANK_SIZE;
|
||||
osc = fip->sector_count;
|
||||
fip->sector_count += BANK_NBLOCKS;
|
||||
if ((nsc = fip->sector_count) >= CFG_MAX_FLASH_SECT)
|
||||
panic("Too many sectors in flash at address 0x%08lx\n",
|
||||
(unsigned long)base);
|
||||
|
||||
addrb = addr;
|
||||
for (i = osc; i < nsc; i++) {
|
||||
fip->start[i] = (ulong)addrb;
|
||||
fip->protect[i] = 0;
|
||||
addrb = BANK_ADDR_NEXT_BLK(addrb);
|
||||
}
|
||||
|
||||
addr = BANK_ADDR_NEXT_BANK(addr);
|
||||
nbanks++;
|
||||
for (i = 0; i < fip->sector_count; i++) {
|
||||
fip->start[i] = (unsigned long)addr;
|
||||
fip->protect[i] = 0;
|
||||
addr = BANK_ADDR_NEXT_BLK (addr);
|
||||
}
|
||||
|
||||
out:
|
||||
if (nbanks == 0)
|
||||
panic("ERROR: no flash found at address 0x%08lx\n",
|
||||
(unsigned long)base);
|
||||
fip->size = (bank_size_t)addr - (bank_size_t)base;
|
||||
|
||||
/* reset the flash */
|
||||
*base = BANK_CMD_RST;
|
||||
}
|
||||
|
||||
static void
|
||||
bank_reset(flash_info_t *info, int sect)
|
||||
bank_reset (flash_info_t *info, int sect)
|
||||
{
|
||||
bank_addr_t addrw, eaddrw;
|
||||
volatile bank_addr_t addr = (bank_addr_t)info->start[sect];
|
||||
|
||||
addrw = (bank_addr_t)info->start[sect];
|
||||
eaddrw = BANK_ADDR_NEXT_WORD(addrw);
|
||||
|
||||
while (addrw < eaddrw) {
|
||||
#ifdef FLASH_DEBUG
|
||||
printf(" writing reset cmd to addr 0x%08lx\n",
|
||||
(unsigned long)addrw);
|
||||
printf ("writing reset cmd to addr 0x%08lx\n", (unsigned long)addr);
|
||||
#endif
|
||||
*addrw = BANK_CMD_RST;
|
||||
addrw++;
|
||||
}
|
||||
|
||||
*addr = BANK_CMD_RST;
|
||||
}
|
||||
|
||||
static void
|
||||
bank_erase_init(flash_info_t *info, int sect)
|
||||
bank_erase_init (flash_info_t *info, int sect)
|
||||
{
|
||||
bank_addr_t addrw, saddrw, eaddrw;
|
||||
volatile bank_addr_t addr = (bank_addr_t)info->start[sect];
|
||||
int flag;
|
||||
|
||||
#ifdef FLASH_DEBUG
|
||||
printf("0x%08lx BANK_CMD_PROG\n", BANK_CMD_PROG);
|
||||
printf("0x%08lx BANK_CMD_ERASE1\n", BANK_CMD_ERASE1);
|
||||
printf("0x%08lx BANK_CMD_ERASE2\n", BANK_CMD_ERASE2);
|
||||
printf("0x%08lx BANK_CMD_CLR_STAT\n", BANK_CMD_CLR_STAT);
|
||||
printf("0x%08lx BANK_CMD_RST\n", BANK_CMD_RST);
|
||||
printf("0x%08lx BANK_STAT_RDY\n", BANK_STAT_RDY);
|
||||
printf("0x%08lx BANK_STAT_ERR\n", BANK_STAT_ERR);
|
||||
#endif
|
||||
|
||||
saddrw = (bank_addr_t)info->start[sect];
|
||||
eaddrw = BANK_ADDR_NEXT_WORD(saddrw);
|
||||
|
||||
#ifdef FLASH_DEBUG
|
||||
printf("erasing sector %d, start addr = 0x%08lx "
|
||||
"(bank next word addr = 0x%08lx)\n", sect,
|
||||
(unsigned long)saddrw, (unsigned long)eaddrw);
|
||||
printf ("erasing sector %d, addr = 0x%08lx\n",
|
||||
sect, (unsigned long)addr);
|
||||
#endif
|
||||
|
||||
/* Disable intrs which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
flag = disable_interrupts ();
|
||||
|
||||
for (addrw = saddrw; addrw < eaddrw; addrw++) {
|
||||
#ifdef FLASH_DEBUG
|
||||
printf(" writing erase cmd to addr 0x%08lx\n",
|
||||
(unsigned long)addrw);
|
||||
printf ("writing erase cmd to addr 0x%08lx\n", (unsigned long)addr);
|
||||
#endif
|
||||
*addrw = BANK_CMD_ERASE1;
|
||||
*addrw = BANK_CMD_ERASE2;
|
||||
}
|
||||
*addr = BANK_CMD_ERASE1;
|
||||
*addr = BANK_CMD_ERASE2;
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
enable_interrupts ();
|
||||
}
|
||||
|
||||
static int
|
||||
bank_erase_poll(flash_info_t *info, int sect)
|
||||
bank_erase_poll (flash_info_t *info, int sect)
|
||||
{
|
||||
bank_addr_t addrw, saddrw, eaddrw;
|
||||
int sectdone, haderr;
|
||||
|
||||
saddrw = (bank_addr_t)info->start[sect];
|
||||
eaddrw = BANK_ADDR_NEXT_WORD(saddrw);
|
||||
|
||||
sectdone = 1;
|
||||
haderr = 0;
|
||||
|
||||
for (addrw = saddrw; addrw < eaddrw; addrw++) {
|
||||
bank_word_t stat = *addrw;
|
||||
volatile bank_addr_t addr = (bank_addr_t)info->start[sect];
|
||||
bank_word_t stat = *addr;
|
||||
|
||||
#ifdef FLASH_DEBUG
|
||||
printf(" checking status at addr "
|
||||
"0x%08lx [0x%08lx]\n",
|
||||
(unsigned long)addrw, stat);
|
||||
printf ("checking status at addr 0x%08lx [0x%08lx]\n",
|
||||
(unsigned long)addr, (unsigned long)stat);
|
||||
#endif
|
||||
if ((stat & BANK_STAT_RDY) != BANK_STAT_RDY)
|
||||
sectdone = 0;
|
||||
else if ((stat & BANK_STAT_ERR) != 0) {
|
||||
printf(" failed on sector %d "
|
||||
"(stat = 0x%08lx) at "
|
||||
"address 0x%08lx\n",
|
||||
sect, stat,
|
||||
(unsigned long)addrw);
|
||||
*addrw = BANK_CMD_CLR_STAT;
|
||||
haderr = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (haderr)
|
||||
return (-1);
|
||||
if ((stat & BANK_STAT_RDY) == BANK_STAT_RDY) {
|
||||
if ((stat & BANK_STAT_ERR) != 0) {
|
||||
printf ("failed on sector %d [0x%08lx] at "
|
||||
"address 0x%08lx\n", sect,
|
||||
(unsigned long)stat, (unsigned long)addr);
|
||||
*addr = BANK_CMD_CLR_STAT;
|
||||
return (-1);
|
||||
}
|
||||
else
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
return (sectdone);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
bank_write_word(bank_addr_t addr, bank_word_t value)
|
||||
bank_write_word (volatile bank_addr_t addr, bank_word_t value)
|
||||
{
|
||||
bank_word_t stat;
|
||||
ulong start;
|
||||
int flag, retval;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
flag = disable_interrupts ();
|
||||
|
||||
*addr = BANK_CMD_PROG;
|
||||
|
||||
@@ -271,14 +191,14 @@ bank_write_word(bank_addr_t addr, bank_word_t value)
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
enable_interrupts ();
|
||||
|
||||
retval = 0;
|
||||
|
||||
/* data polling for D7 */
|
||||
start = get_timer (0);
|
||||
do {
|
||||
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
|
||||
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
|
||||
retval = 1;
|
||||
goto done;
|
||||
}
|
||||
@@ -286,8 +206,8 @@ bank_write_word(bank_addr_t addr, bank_word_t value)
|
||||
} while ((stat & BANK_STAT_RDY) != BANK_STAT_RDY);
|
||||
|
||||
if ((stat & BANK_STAT_ERR) != 0) {
|
||||
printf("flash program failed (stat = 0x%08lx) "
|
||||
"at address 0x%08lx\n", (ulong)stat, (ulong)addr);
|
||||
printf ("flash program failed [0x%08lx] at address 0x%08lx\n",
|
||||
(unsigned long)stat, (unsigned long)addr);
|
||||
*addr = BANK_CMD_CLR_STAT;
|
||||
retval = 3;
|
||||
}
|
||||
@@ -303,7 +223,7 @@ done:
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
flash_init(void)
|
||||
flash_init (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -312,21 +232,21 @@ flash_init(void)
|
||||
flash_info[i].flash_id = FLASH_UNKNOWN;
|
||||
}
|
||||
|
||||
bank_probe(&flash_info[0], (bank_addr_t)CFG_FLASH_BASE);
|
||||
bank_probe (&flash_info[0], (bank_addr_t)CFG_FLASH_BASE);
|
||||
|
||||
/*
|
||||
* protect monitor and environment sectors
|
||||
*/
|
||||
|
||||
#if CFG_MONITOR_BASE == CFG_FLASH_BASE
|
||||
(void)flash_protect(FLAG_PROTECT_SET,
|
||||
(void)flash_protect (FLAG_PROTECT_SET,
|
||||
CFG_MONITOR_BASE,
|
||||
CFG_MONITOR_BASE+monitor_flash_len-1,
|
||||
&flash_info[0]);
|
||||
#endif
|
||||
|
||||
#if defined(CFG_FLASH_ENV_ADDR)
|
||||
(void)flash_protect(FLAG_PROTECT_SET,
|
||||
(void)flash_protect (FLAG_PROTECT_SET,
|
||||
CFG_FLASH_ENV_ADDR,
|
||||
#if defined(CFG_FLASH_ENV_BUF)
|
||||
CFG_FLASH_ENV_ADDR + CFG_FLASH_ENV_BUF - 1,
|
||||
@@ -339,42 +259,10 @@ flash_init(void)
|
||||
return flash_info[0].size;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
#if 0
|
||||
static void
|
||||
flash_get_offsets(ulong base, flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* set up sector start adress table */
|
||||
if (info->flash_id & FLASH_BTYPE) {
|
||||
/* set sector offsets for bottom boot block type */
|
||||
info->start[0] = base + 0x00000000;
|
||||
info->start[1] = base + 0x00008000;
|
||||
info->start[2] = base + 0x0000C000;
|
||||
info->start[3] = base + 0x00010000;
|
||||
for (i = 4; i < info->sector_count; i++) {
|
||||
info->start[i] = base + (i * 0x00020000) - 0x00060000;
|
||||
}
|
||||
} else {
|
||||
/* set sector offsets for top boot block type */
|
||||
i = info->sector_count - 1;
|
||||
info->start[i--] = base + info->size - 0x00008000;
|
||||
info->start[i--] = base + info->size - 0x0000C000;
|
||||
info->start[i--] = base + info->size - 0x00010000;
|
||||
for (; i >= 0; i--) {
|
||||
info->start[i] = base + i * 0x00020000;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
flash_print_info(flash_info_t *info)
|
||||
flash_print_info (flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -391,6 +279,14 @@ flash_print_info(flash_info_t *info)
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_28F320J5: printf ("28F320J5 (32 Mbit, 2 x 16bit)\n");
|
||||
break;
|
||||
case FLASH_28F640J5: printf ("28F640J5 (64 Mbit, 2 x 16bit)\n");
|
||||
break;
|
||||
case FLASH_28F320J3A: printf ("28F320J3A (32 Mbit, 2 x 16bit)\n");
|
||||
break;
|
||||
case FLASH_28F640J3A: printf ("28F640J3A (64 Mbit, 2 x 16bit)\n");
|
||||
break;
|
||||
case FLASH_28F128J3A: printf ("28F320J3A (128 Mbit, 2 x 16bit)\n");
|
||||
break;
|
||||
default: printf ("Unknown Chip Type\n");
|
||||
break;
|
||||
}
|
||||
@@ -411,157 +307,25 @@ flash_print_info(flash_info_t *info)
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
#if 0
|
||||
static ulong
|
||||
flash_get_size(vu_long *addr, flash_info_t *info)
|
||||
{
|
||||
short i;
|
||||
ulong value;
|
||||
ulong base = (ulong)addr;
|
||||
|
||||
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
addr[0x0555] = 0x00AA00AA;
|
||||
addr[0x02AA] = 0x00550055;
|
||||
addr[0x0555] = 0x00900090;
|
||||
|
||||
value = addr[0];
|
||||
|
||||
switch (value) {
|
||||
case AMD_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_AMD;
|
||||
break;
|
||||
case FUJ_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_FUJ;
|
||||
break;
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
value = addr[1]; /* device ID */
|
||||
|
||||
switch (value) {
|
||||
case AMD_ID_LV400T:
|
||||
info->flash_id += FLASH_AM400T;
|
||||
info->sector_count = 11;
|
||||
info->size = 0x00100000;
|
||||
break; /* => 1 MB */
|
||||
|
||||
case AMD_ID_LV400B:
|
||||
info->flash_id += FLASH_AM400B;
|
||||
info->sector_count = 11;
|
||||
info->size = 0x00100000;
|
||||
break; /* => 1 MB */
|
||||
|
||||
case AMD_ID_LV800T:
|
||||
info->flash_id += FLASH_AM800T;
|
||||
info->sector_count = 19;
|
||||
info->size = 0x00200000;
|
||||
break; /* => 2 MB */
|
||||
|
||||
case AMD_ID_LV800B:
|
||||
info->flash_id += FLASH_AM800B;
|
||||
info->sector_count = 19;
|
||||
info->size = 0x00200000;
|
||||
break; /* => 2 MB */
|
||||
|
||||
case AMD_ID_LV160T:
|
||||
info->flash_id += FLASH_AM160T;
|
||||
info->sector_count = 35;
|
||||
info->size = 0x00400000;
|
||||
break; /* => 4 MB */
|
||||
|
||||
case AMD_ID_LV160B:
|
||||
info->flash_id += FLASH_AM160B;
|
||||
info->sector_count = 35;
|
||||
info->size = 0x00400000;
|
||||
break; /* => 4 MB */
|
||||
#if 0 /* enable when device IDs are available */
|
||||
case AMD_ID_LV320T:
|
||||
info->flash_id += FLASH_AM320T;
|
||||
info->sector_count = 67;
|
||||
info->size = 0x00800000;
|
||||
break; /* => 8 MB */
|
||||
|
||||
case AMD_ID_LV320B:
|
||||
info->flash_id += FLASH_AM320B;
|
||||
info->sector_count = 67;
|
||||
info->size = 0x00800000;
|
||||
break; /* => 8 MB */
|
||||
#endif
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
return (0); /* => no or unknown flash */
|
||||
|
||||
}
|
||||
|
||||
/* set up sector start adress table */
|
||||
if (info->flash_id & FLASH_BTYPE) {
|
||||
/* set sector offsets for bottom boot block type */
|
||||
info->start[0] = base + 0x00000000;
|
||||
info->start[1] = base + 0x00008000;
|
||||
info->start[2] = base + 0x0000C000;
|
||||
info->start[3] = base + 0x00010000;
|
||||
for (i = 4; i < info->sector_count; i++) {
|
||||
info->start[i] = base + (i * 0x00020000) - 0x00060000;
|
||||
}
|
||||
} else {
|
||||
/* set sector offsets for top boot block type */
|
||||
i = info->sector_count - 1;
|
||||
info->start[i--] = base + info->size - 0x00008000;
|
||||
info->start[i--] = base + info->size - 0x0000C000;
|
||||
info->start[i--] = base + info->size - 0x00010000;
|
||||
for (; i >= 0; i--) {
|
||||
info->start[i] = base + i * 0x00020000;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for protected sectors */
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
|
||||
/* D0 = 1 if protected */
|
||||
addr = (volatile unsigned long *)(info->start[i]);
|
||||
info->protect[i] = addr[2] & 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevent writes to uninitialized FLASH.
|
||||
*/
|
||||
if (info->flash_id != FLASH_UNKNOWN) {
|
||||
addr = (volatile unsigned long *)info->start[0];
|
||||
|
||||
*addr = 0x00F000F0; /* reset bank */
|
||||
}
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
flash_erase(flash_info_t *info, int s_first, int s_last)
|
||||
flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
{
|
||||
int prot, sect, haderr;
|
||||
ulong start, now, last;
|
||||
int rcode = 0;
|
||||
|
||||
#ifdef FLASH_DEBUG
|
||||
printf("\nflash_erase: erase %d sectors (%d to %d incl.) from\n"
|
||||
printf ("\nflash_erase: erase %d sectors (%d to %d incl.) from\n"
|
||||
" Bank # %d: ", s_last - s_first + 1, s_first, s_last,
|
||||
(info - flash_info) + 1);
|
||||
flash_print_info(info);
|
||||
flash_print_info (info);
|
||||
#endif
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
@@ -574,14 +338,14 @@ flash_erase(flash_info_t *info, int s_first, int s_last)
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
for (sect=s_first; sect<=s_last; ++sect) {
|
||||
for (sect = s_first; sect <= s_last; ++sect) {
|
||||
if (info->protect[sect]) {
|
||||
prot++;
|
||||
}
|
||||
}
|
||||
|
||||
if (prot) {
|
||||
printf("- Warning: %d protected sector%s will not be erased!\n",
|
||||
printf ("- Warning: %d protected sector%s will not be erased\n",
|
||||
prot, (prot > 1 ? "s" : ""));
|
||||
}
|
||||
|
||||
@@ -594,15 +358,15 @@ flash_erase(flash_info_t *info, int s_first, int s_last)
|
||||
ulong estart;
|
||||
int sectdone;
|
||||
|
||||
bank_erase_init(info, sect);
|
||||
bank_erase_init (info, sect);
|
||||
|
||||
/* wait at least 80us - let's wait 1 ms */
|
||||
udelay (1000);
|
||||
|
||||
estart = get_timer(start);
|
||||
estart = get_timer (start);
|
||||
|
||||
do {
|
||||
now = get_timer(start);
|
||||
now = get_timer (start);
|
||||
|
||||
if (now - estart > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout (sect %d)\n", sect);
|
||||
@@ -619,7 +383,7 @@ flash_erase(flash_info_t *info, int s_first, int s_last)
|
||||
}
|
||||
#endif
|
||||
|
||||
sectdone = bank_erase_poll(info, sect);
|
||||
sectdone = bank_erase_poll (info, sect);
|
||||
|
||||
if (sectdone < 0) {
|
||||
haderr = 1;
|
||||
@@ -642,21 +406,39 @@ flash_erase(flash_info_t *info, int s_first, int s_last)
|
||||
/* reset to read mode */
|
||||
for (sect = s_first; sect <= s_last; sect++) {
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
bank_reset(info, sect);
|
||||
bank_reset (info, sect);
|
||||
}
|
||||
}
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word to Flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
* 3 - Program failed
|
||||
*/
|
||||
static int
|
||||
write_word (flash_info_t *info, ulong dest, ulong data)
|
||||
{
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*(ulong *)dest & data) != data)
|
||||
return (2);
|
||||
|
||||
return (bank_write_word ((bank_addr_t)dest, (bank_word_t)data));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
* 3 - Program failed
|
||||
*/
|
||||
|
||||
int
|
||||
write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong cp, wp, data;
|
||||
int i, l, rc;
|
||||
@@ -680,7 +462,7 @@ write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
}
|
||||
|
||||
if ((rc = write_word(info, wp, data)) != 0) {
|
||||
if ((rc = write_word (info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += 4;
|
||||
@@ -694,7 +476,7 @@ write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
for (i=0; i<4; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
}
|
||||
if ((rc = write_word(info, wp, data)) != 0) {
|
||||
if ((rc = write_word (info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += 4;
|
||||
@@ -717,28 +499,7 @@ write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
}
|
||||
|
||||
return (write_word(info, wp, data));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word to Flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
static int
|
||||
write_word(flash_info_t *info, ulong dest, ulong data)
|
||||
{
|
||||
int retval;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*(ulong *)dest & data) != data) {
|
||||
return (2);
|
||||
}
|
||||
|
||||
retval = bank_write_word((bank_addr_t)dest, (bank_word_t)data);
|
||||
|
||||
return (retval);
|
||||
return (write_word (info, wp, data));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
|
||||
@@ -1,163 +1,156 @@
|
||||
/*************** DEFINES for Intel StrataFlash FLASH chip ********************/
|
||||
|
||||
/*
|
||||
* acceptable chips types are:
|
||||
* (C) Copyright 2000
|
||||
* Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
|
||||
*
|
||||
* 28F320J5, 28F640J5, 28F320J3A, 28F640J3A and 28F128J3A
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* register addresses, valid only following an CHIP_CMD_RD_ID command */
|
||||
#define CHIP_ADDR_REG_MAN 0x000000 /* manufacturer's id */
|
||||
#define CHIP_ADDR_REG_DEV 0x000001 /* device id */
|
||||
#define CHIP_ADDR_REG_CFGM 0x000003 /* master lock config */
|
||||
#define CHIP_ADDR_REG_CFG(b) (((b)<<16)|2) /* lock config for block b */
|
||||
/*************** DEFINES for Intel StrataFlash FLASH chip ********************/
|
||||
|
||||
/* Commands */
|
||||
#define CHIP_CMD_RST 0xFF /* reset flash */
|
||||
#define CHIP_CMD_RD_ID 0x90 /* read the id and lock bits */
|
||||
#define CHIP_CMD_RD_QUERY 0x98 /* read device capabilities */
|
||||
#define CHIP_CMD_RD_STAT 0x70 /* read the status register */
|
||||
#define CHIP_CMD_CLR_STAT 0x50 /* clear the staus register */
|
||||
#define CHIP_CMD_WR_BUF 0xE8 /* clear the staus register */
|
||||
#define CHIP_CMD_PROG 0x40 /* program word command */
|
||||
#define CHIP_CMD_ERASE1 0x20 /* 1st word for block erase */
|
||||
#define CHIP_CMD_ERASE2 0xD0 /* 2nd word for block erase */
|
||||
#define CHIP_CMD_ERASE_SUSP 0xB0 /* suspend block erase */
|
||||
#define CHIP_CMD_LOCK 0x60 /* 1st word for all lock cmds */
|
||||
#define CHIP_CMD_SET_LOCK_BLK 0x01 /* 2nd wrd set block lock bit */
|
||||
#define CHIP_CMD_SET_LOCK_MSTR 0xF1 /* 2nd wrd set master lck bit */
|
||||
#define CHIP_CMD_CLR_LOCK_BLK 0xD0 /* 2nd wrd clear blk lck bit */
|
||||
#define ISF_CMD_RST 0xFF /* reset flash */
|
||||
#define ISF_CMD_RD_ID 0x90 /* read the id and lock bits */
|
||||
#define ISF_CMD_RD_QUERY 0x98 /* read device capabilities */
|
||||
#define ISF_CMD_RD_STAT 0x70 /* read the status register */
|
||||
#define ISF_CMD_CLR_STAT 0x50 /* clear the staus register */
|
||||
#define ISF_CMD_WR_BUF 0xE8 /* clear the staus register */
|
||||
#define ISF_CMD_PROG 0x40 /* program word command */
|
||||
#define ISF_CMD_ERASE1 0x20 /* 1st word for block erase */
|
||||
#define ISF_CMD_ERASE2 0xD0 /* 2nd word for block erase */
|
||||
#define ISF_CMD_ERASE_SUSP 0xB0 /* suspend block erase */
|
||||
#define ISF_CMD_LOCK 0x60 /* 1st word for all lock cmds */
|
||||
#define ISF_CMD_SET_LOCK_BLK 0x01 /* 2nd wrd set block lock bit */
|
||||
#define ISF_CMD_SET_LOCK_MSTR 0xF1 /* 2nd wrd set master lck bit */
|
||||
#define ISF_CMD_CLR_LOCK_BLK 0xD0 /* 2nd wrd clear blk lck bit */
|
||||
|
||||
/* status register bits */
|
||||
#define CHIP_STAT_DPS 0x02 /* Device Protect Status */
|
||||
#define CHIP_STAT_VPPS 0x08 /* VPP Status */
|
||||
#define CHIP_STAT_PSLBS 0x10 /* Program+Set Lock Bit Stat */
|
||||
#define CHIP_STAT_ECLBS 0x20 /* Erase+Clr Lock Bit Stat */
|
||||
#define CHIP_STAT_ESS 0x40 /* Erase Suspend Status */
|
||||
#define CHIP_STAT_RDY 0x80 /* WSM Mach Status, 1=rdy */
|
||||
#define ISF_STAT_DPS 0x02 /* Device Protect Status */
|
||||
#define ISF_STAT_VPPS 0x08 /* VPP Status */
|
||||
#define ISF_STAT_PSLBS 0x10 /* Program+Set Lock Bit Stat */
|
||||
#define ISF_STAT_ECLBS 0x20 /* Erase+Clr Lock Bit Stat */
|
||||
#define ISF_STAT_ESS 0x40 /* Erase Suspend Status */
|
||||
#define ISF_STAT_RDY 0x80 /* WSM Mach Status, 1=rdy */
|
||||
|
||||
#define CHIP_STAT_ERR (CHIP_STAT_VPPS | CHIP_STAT_DPS | \
|
||||
CHIP_STAT_ECLBS | CHIP_STAT_PSLBS)
|
||||
#define ISF_STAT_ERR (ISF_STAT_VPPS | ISF_STAT_DPS | \
|
||||
ISF_STAT_ECLBS | ISF_STAT_PSLBS)
|
||||
|
||||
/* ID and Lock Configuration */
|
||||
#define CHIP_RD_ID_LOCK 0x01 /* Bit 0 of each byte */
|
||||
#define CHIP_RD_ID_MAN 0x89 /* Manufacturer code = 0x89 */
|
||||
#define CHIP_RD_ID_DEV CFG_FLASH_ID
|
||||
|
||||
/* dimensions */
|
||||
#define CHIP_WIDTH 2 /* chips are in 16 bit mode */
|
||||
#define CHIP_WSHIFT 1 /* (log2 of CHIP_WIDTH) */
|
||||
#define CHIP_NBLOCKS CFG_FLASH_NBLOCKS
|
||||
#define CHIP_BLKSZ (128 * 1024) /* of 128Kbytes each */
|
||||
#define CHIP_SIZE (CHIP_BLKSZ * CHIP_NBLOCKS)
|
||||
/* register addresses, valid only following an ISF_CMD_RD_ID command */
|
||||
#define ISF_REG_MAN_CODE 0x00 /* manufacturer code */
|
||||
#define ISF_REG_DEV_CODE 0x01 /* device code */
|
||||
#define ISF_REG_BLK_LCK 0x02 /* block lock configuration */
|
||||
#define ISF_REG_MST_LCK 0x03 /* master lock configuration */
|
||||
|
||||
/********************** DEFINES for Hymod Flash ******************************/
|
||||
|
||||
/*
|
||||
* The hymod board has 2 x 28F320J5 chips running in
|
||||
* 16 bit mode, for a 32 bit wide bank.
|
||||
* this code requires that the flash on any Hymod board appear as a bank
|
||||
* of two (identical) 16bit Intel StrataFlash chips with 64Kword erase
|
||||
* sectors (or blocks), running in x16 bit mode and connected side-by-side
|
||||
* to make a 32-bit wide bus.
|
||||
*/
|
||||
|
||||
typedef unsigned long bank_word_t; /* 8/16/32/64bit unsigned int */
|
||||
typedef volatile bank_word_t *bank_addr_t;
|
||||
typedef unsigned long bank_size_t; /* want this big - >= 32 bit */
|
||||
typedef unsigned long bank_word_t;
|
||||
typedef bank_word_t bank_blk_t[64 * 1024];
|
||||
|
||||
#define BANK_CHIP_WIDTH 2 /* each bank is 2 chips wide */
|
||||
#define BANK_CHIP_WSHIFT 1 /* (log2 of BANK_CHIP_WIDTH) */
|
||||
#define BANK_FILL_WORD(b) (((bank_word_t)(b) << 16) | (bank_word_t)(b))
|
||||
|
||||
#define BANK_WIDTH (CHIP_WIDTH * BANK_CHIP_WIDTH)
|
||||
#define BANK_WSHIFT (CHIP_WSHIFT + BANK_CHIP_WSHIFT)
|
||||
#define BANK_NBLOCKS CHIP_NBLOCKS
|
||||
#define BANK_BLKSZ (CHIP_BLKSZ * BANK_CHIP_WIDTH)
|
||||
#define BANK_SIZE (CHIP_SIZE * BANK_CHIP_WIDTH)
|
||||
#ifdef EXAMPLE
|
||||
|
||||
#define MAX_BANKS 1 /* only one bank possible */
|
||||
/* theoretically the following examples should also work */
|
||||
|
||||
/* one flash chip in x8 mode with 128Kword sectors and 8bit bus */
|
||||
typedef unsigned char bank_word_t;
|
||||
typedef bank_word_t bank_blk_t[128 * 1024];
|
||||
#define BANK_FILL_WORD(b) ((bank_word_t)(b))
|
||||
|
||||
/* four flash chips in x16 mode with 32Kword sectors and 64bit bus */
|
||||
typedef unsigned long long bank_word_t;
|
||||
typedef bank_word_t bank_blk_t[32 * 1024];
|
||||
#define BANK_FILL_WORD(b) ( \
|
||||
((bank_word_t)(b) << 48) \
|
||||
((bank_word_t)(b) << 32) \
|
||||
((bank_word_t)(b) << 16) \
|
||||
((bank_word_t)(b) << 0) \
|
||||
)
|
||||
|
||||
#endif /* EXAMPLE */
|
||||
|
||||
/* the sizes of these two types should probably be the same */
|
||||
typedef bank_word_t *bank_addr_t;
|
||||
typedef unsigned long bank_size_t;
|
||||
|
||||
/* align bank addresses and sizes to bank word boundaries */
|
||||
#define BANK_ADDR_WORD_ALIGN(a) ((bank_addr_t)((bank_size_t)(a) \
|
||||
& ~(BANK_WIDTH - 1)))
|
||||
#define BANK_SIZE_WORD_ALIGN(s) ((bank_size_t)BANK_ADDR_WORD_ALIGN( \
|
||||
(bank_size_t)(s) + (BANK_WIDTH - 1)))
|
||||
& ~(sizeof (bank_word_t) - 1)))
|
||||
#define BANK_SIZE_WORD_ALIGN(s) (((bank_size_t)(s) + sizeof (bank_word_t) - 1) \
|
||||
& ~(sizeof (bank_word_t) - 1))
|
||||
|
||||
/* align bank addresses and sizes to bank block boundaries */
|
||||
#define BANK_ADDR_BLK_ALIGN(a) ((bank_addr_t)((bank_size_t)(a) \
|
||||
& ~(BANK_BLKSZ - 1)))
|
||||
#define BANK_SIZE_BLK_ALIGN(s) ((bank_size_t)BANK_ADDR_BLK_ALIGN( \
|
||||
(bank_size_t)(s) + (BANK_BLKSZ - 1)))
|
||||
|
||||
/* align bank addresses and sizes to bank boundaries */
|
||||
#define BANK_ADDR_BANK_ALIGN(a) ((bank_addr_t)((bank_size_t)(a) \
|
||||
& ~(BANK_SIZE - 1)))
|
||||
#define BANK_SIZE_BANK_ALIGN(s) ((bank_size_t)BANK_ADDR_BANK_ALIGN( \
|
||||
(bank_size_t)(s) + (BANK_SIZE - 1)))
|
||||
& ~(sizeof (bank_blk_t) - 1)))
|
||||
#define BANK_SIZE_BLK_ALIGN(s) (((bank_size_t)(s) + sizeof (bank_blk_t) - 1) \
|
||||
& ~(sizeof (bank_blk_t) - 1))
|
||||
|
||||
/* add an offset to a bank address */
|
||||
#define BANK_ADDR_OFFSET(a, o) (bank_addr_t)((bank_size_t)(a) + \
|
||||
(bank_size_t)(o))
|
||||
|
||||
/* get base address of bank b, given flash base address a */
|
||||
#define BANK_ADDR_BASE(a, b) BANK_ADDR_OFFSET(BANK_ADDR_BANK_ALIGN(a), \
|
||||
(bank_size_t)(b) * BANK_SIZE)
|
||||
#define BANK_ADDR_OFFSET(a, o) ((bank_addr_t)((bank_size_t)(a) + \
|
||||
(bank_size_t)(o)))
|
||||
|
||||
/* adjust a bank address to start of next word, block or bank */
|
||||
#define BANK_ADDR_NEXT_WORD(a) BANK_ADDR_OFFSET(BANK_ADDR_WORD_ALIGN(a), \
|
||||
BANK_WIDTH)
|
||||
sizeof (bank_word_t))
|
||||
#define BANK_ADDR_NEXT_BLK(a) BANK_ADDR_OFFSET(BANK_ADDR_BLK_ALIGN(a), \
|
||||
BANK_BLKSZ)
|
||||
#define BANK_ADDR_NEXT_BANK(a) BANK_ADDR_OFFSET(BANK_ADDR_BANK_ALIGN(a), \
|
||||
BANK_SIZE)
|
||||
sizeof (bank_blk_t))
|
||||
|
||||
/* get bank address of chip register r given a bank base address a */
|
||||
#define BANK_ADDR_REG(a, r) BANK_ADDR_OFFSET(BANK_ADDR_BANK_ALIGN(a), \
|
||||
((bank_size_t)(r) << BANK_WSHIFT))
|
||||
/* get bank address of register r given a bank base address a and block num b */
|
||||
#define BANK_ADDR_REG(a, b, r) BANK_ADDR_OFFSET(BANK_ADDR_OFFSET((a), \
|
||||
(bank_size_t)(b) * sizeof (bank_blk_t)), \
|
||||
(bank_size_t)(r) * sizeof (bank_word_t))
|
||||
|
||||
/* make a bank address for each chip register address */
|
||||
|
||||
#define BANK_ADDR_REG_MAN(a) BANK_ADDR_REG((a), CHIP_ADDR_REG_MAN)
|
||||
#define BANK_ADDR_REG_DEV(a) BANK_ADDR_REG((a), CHIP_ADDR_REG_DEV)
|
||||
#define BANK_ADDR_REG_CFGM(a) BANK_ADDR_REG((a), CHIP_ADDR_REG_CFGM)
|
||||
#define BANK_ADDR_REG_CFG(b,a) BANK_ADDR_REG((a), CHIP_ADDR_REG_CFG(b))
|
||||
|
||||
/*
|
||||
* replicate a chip cmd/stat/rd value into each byte position within a word
|
||||
* so that multiple chips are accessed in a single word i/o operation
|
||||
*
|
||||
* this must be as wide as the bank_word_t type, and take into account the
|
||||
* chip width and bank layout
|
||||
*/
|
||||
|
||||
#define BANK_FILL_WORD(o) ((bank_word_t)( \
|
||||
((unsigned long)(o) << 16) | \
|
||||
((unsigned long)(o) << 0) \
|
||||
))
|
||||
|
||||
/* make a bank word value for each chip cmd/stat/rd value */
|
||||
/* make a bank word value for each StrataFlash value */
|
||||
|
||||
/* Commands */
|
||||
#define BANK_CMD_RST BANK_FILL_WORD(CHIP_CMD_RST)
|
||||
#define BANK_CMD_RD_ID BANK_FILL_WORD(CHIP_CMD_RD_ID)
|
||||
#define BANK_CMD_RD_STAT BANK_FILL_WORD(CHIP_CMD_RD_STAT)
|
||||
#define BANK_CMD_CLR_STAT BANK_FILL_WORD(CHIP_CMD_CLR_STAT)
|
||||
#define BANK_CMD_ERASE1 BANK_FILL_WORD(CHIP_CMD_ERASE1)
|
||||
#define BANK_CMD_ERASE2 BANK_FILL_WORD(CHIP_CMD_ERASE2)
|
||||
#define BANK_CMD_PROG BANK_FILL_WORD(CHIP_CMD_PROG)
|
||||
#define BANK_CMD_LOCK BANK_FILL_WORD(CHIP_CMD_LOCK)
|
||||
#define BANK_CMD_SET_LOCK_BLK BANK_FILL_WORD(CHIP_CMD_SET_LOCK_BLK)
|
||||
#define BANK_CMD_SET_LOCK_MSTR BANK_FILL_WORD(CHIP_CMD_SET_LOCK_MSTR)
|
||||
#define BANK_CMD_CLR_LOCK_BLK BANK_FILL_WORD(CHIP_CMD_CLR_LOCK_BLK)
|
||||
#define BANK_CMD_RST BANK_FILL_WORD(ISF_CMD_RST)
|
||||
#define BANK_CMD_RD_ID BANK_FILL_WORD(ISF_CMD_RD_ID)
|
||||
#define BANK_CMD_RD_STAT BANK_FILL_WORD(ISF_CMD_RD_STAT)
|
||||
#define BANK_CMD_CLR_STAT BANK_FILL_WORD(ISF_CMD_CLR_STAT)
|
||||
#define BANK_CMD_ERASE1 BANK_FILL_WORD(ISF_CMD_ERASE1)
|
||||
#define BANK_CMD_ERASE2 BANK_FILL_WORD(ISF_CMD_ERASE2)
|
||||
#define BANK_CMD_PROG BANK_FILL_WORD(ISF_CMD_PROG)
|
||||
#define BANK_CMD_LOCK BANK_FILL_WORD(ISF_CMD_LOCK)
|
||||
#define BANK_CMD_SET_LOCK_BLK BANK_FILL_WORD(ISF_CMD_SET_LOCK_BLK)
|
||||
#define BANK_CMD_SET_LOCK_MSTR BANK_FILL_WORD(ISF_CMD_SET_LOCK_MSTR)
|
||||
#define BANK_CMD_CLR_LOCK_BLK BANK_FILL_WORD(ISF_CMD_CLR_LOCK_BLK)
|
||||
|
||||
/* status register bits */
|
||||
#define BANK_STAT_DPS BANK_FILL_WORD(CHIP_STAT_DPS)
|
||||
#define BANK_STAT_PSS BANK_FILL_WORD(CHIP_STAT_PSS)
|
||||
#define BANK_STAT_VPPS BANK_FILL_WORD(CHIP_STAT_VPPS)
|
||||
#define BANK_STAT_PSLBS BANK_FILL_WORD(CHIP_STAT_PSLBS)
|
||||
#define BANK_STAT_ECLBS BANK_FILL_WORD(CHIP_STAT_ECLBS)
|
||||
#define BANK_STAT_ESS BANK_FILL_WORD(CHIP_STAT_ESS)
|
||||
#define BANK_STAT_RDY BANK_FILL_WORD(CHIP_STAT_RDY)
|
||||
#define BANK_STAT_DPS BANK_FILL_WORD(ISF_STAT_DPS)
|
||||
#define BANK_STAT_PSS BANK_FILL_WORD(ISF_STAT_PSS)
|
||||
#define BANK_STAT_VPPS BANK_FILL_WORD(ISF_STAT_VPPS)
|
||||
#define BANK_STAT_PSLBS BANK_FILL_WORD(ISF_STAT_PSLBS)
|
||||
#define BANK_STAT_ECLBS BANK_FILL_WORD(ISF_STAT_ECLBS)
|
||||
#define BANK_STAT_ESS BANK_FILL_WORD(ISF_STAT_ESS)
|
||||
#define BANK_STAT_RDY BANK_FILL_WORD(ISF_STAT_RDY)
|
||||
|
||||
#define BANK_STAT_ERR BANK_FILL_WORD(CHIP_STAT_ERR)
|
||||
#define BANK_STAT_ERR BANK_FILL_WORD(ISF_STAT_ERR)
|
||||
|
||||
/* ID and Lock Configuration */
|
||||
#define BANK_RD_ID_LOCK BANK_FILL_WORD(CHIP_RD_ID_LOCK)
|
||||
#define BANK_RD_ID_MAN BANK_FILL_WORD(CHIP_RD_ID_MAN)
|
||||
#define BANK_RD_ID_DEV BANK_FILL_WORD(CHIP_RD_ID_DEV)
|
||||
/* make a bank register address for each StrataFlash register address */
|
||||
|
||||
#define BANK_REG_MAN_CODE(a) BANK_ADDR_REG((a), 0, ISF_REG_MAN_CODE)
|
||||
#define BANK_REG_DEV_CODE(a) BANK_ADDR_REG((a), 0, ISF_REG_DEV_CODE)
|
||||
#define BANK_REG_BLK_LCK(a, b) BANK_ADDR_REG((a), (b), ISF_REG_BLK_LCK)
|
||||
#define BANK_REG_MST_LCK(a) BANK_ADDR_REG((a), 0, ISF_REG_MST_LCK)
|
||||
|
||||
@@ -1,3 +1,33 @@
|
||||
# DONT FORGET TO CHANGE THE "version" VAR BELOW IF YOU MAKE CHANGES TO THIS FILE
|
||||
|
||||
# (C) Copyright 2001
|
||||
# Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
|
||||
#
|
||||
# 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
|
||||
|
||||
#
|
||||
# global_env
|
||||
#
|
||||
# file used by Hymod boards to initialise the u-boot non-volatile
|
||||
# environment when u-boot is first run (it determines this by the
|
||||
# absence of the environment variable "global_env_loaded")
|
||||
#
|
||||
# format of this file is:
|
||||
#
|
||||
# 1. blank lines and lines beginning with '#' are ignored
|
||||
@@ -7,32 +37,94 @@
|
||||
# %s serial number of the main board (10 digit zero filled)
|
||||
# %S serial number of the main board (plain number)
|
||||
# %% a percentage character
|
||||
#
|
||||
# no whitespace is removed in either <name> or <value>
|
||||
# ... otherwise the %x is discarded
|
||||
#
|
||||
# if first character in <name> is a dash ('-'), then an existing env var
|
||||
# will not be overwritten (the dash is removed).
|
||||
# will not be overwritten (the dash is removed). i.e. it is only set if
|
||||
# it does not exist
|
||||
#
|
||||
# if last character in <name> is a plus ('+'), then <value> will be appended
|
||||
# to any existing env var (the plus is removed). Duplicates of <value> are
|
||||
# to any existing env var (the plus is ignored). Duplicates of <value> are
|
||||
# removed.
|
||||
#
|
||||
# similarly, if the last character in <name> is a minus ('-'), then any
|
||||
# occurences of <value> in the current value of <name> will removed (the
|
||||
# minus is ignored).
|
||||
#
|
||||
# leading and trailing whitespace is removed in both <name> and <value>
|
||||
# (after processing any initial or final plus/minus in <name>).
|
||||
#
|
||||
|
||||
# MISCELLANEOUS PARAMETERS
|
||||
|
||||
# version must always come first
|
||||
version=4
|
||||
|
||||
# set the ip address based on the main board serial number
|
||||
ipaddr=192.168.1.%S
|
||||
serverip=192.168.1.254
|
||||
|
||||
# stop auto execute after tftp
|
||||
# stop auto execute after tftp (not a very good name really)
|
||||
autostart=no
|
||||
|
||||
# setting this to "yes" forces the global_env file to be loaded and processed
|
||||
# if the current version is different to the version in the file
|
||||
always_check_env=no
|
||||
|
||||
# BOOTING COMMANDS AND PARAMETERS
|
||||
|
||||
# command to run when "auto-booting"
|
||||
bootcmd=bootm 40080000
|
||||
|
||||
# how long the "countdown" to automatically running "bootcmd" is
|
||||
bootdelay=2
|
||||
|
||||
# how long before it "times out" console input and attempts to run "bootcmd"
|
||||
bootretry=5
|
||||
|
||||
# arguments passed to the boot program (i.e. linux kernel) via register 6
|
||||
# the linux kernel (v2.4) uses the following registers:
|
||||
# r3 - address of board information structure
|
||||
# r4 - address of initial ramdisk image (0 means no initrd)
|
||||
# r5 - size of initial ramdisk image
|
||||
# r6 - address of command line string
|
||||
-bootargs=root=/dev/mtdblock5 rootfstype=squashfs ro
|
||||
|
||||
# these four are for hymod linux integrated into our Sun network
|
||||
bootargs+=serialno=%S
|
||||
bootargs+=nisclient nisdomain=mlb.dmt.csiro.au nissrvadr=138.194.112.4
|
||||
bootargs+=nfsclient
|
||||
bootargs+=automount
|
||||
|
||||
# start a web server by default
|
||||
bootargs+=webserver
|
||||
|
||||
# give negotiation time to finish
|
||||
bootargs+=netsleep=5
|
||||
|
||||
# then our ciscos don't pass packets for 25-30 secs after that, so
|
||||
# pinging the server until it responds prevents network connections
|
||||
# from failing...
|
||||
bootargs+=netping
|
||||
|
||||
# these are old bootargs - we don't need them anymore
|
||||
bootargs-=preload=unix,i2c-cpm,i2c-dev
|
||||
bootargs-=ramdisk_size=32768
|
||||
bootargs-=ramdisk_size=24576
|
||||
|
||||
# FLASH MANIPULATION COMMANDS
|
||||
|
||||
#
|
||||
# 16M flash map, 64 x 256K sectors, mapped at address 0x40000000
|
||||
# 16M flash, 64 x 256K sectors, mapped at address 0x40000000
|
||||
#
|
||||
# sector 0: boot
|
||||
# sector 1: non volatile environment
|
||||
# sectors 2-4: linux kernel image
|
||||
# sectors 5-7: alternate linux kernel image
|
||||
# sectors 8-63: linux initial ramdisk image
|
||||
# Sector(s) Address Size Description
|
||||
#
|
||||
# 0 - 0 0x40000000 256K boot code
|
||||
# 1 - 1 0x40040000 256K non volatile environment
|
||||
# 2 - 4 0x40080000 768K linux kernel image
|
||||
# 5 - 7 0x40140000 768K alternate linux kernel image
|
||||
# 8 - 47 0x40200000 10M linux initial ramdisk image
|
||||
# 48 - 63 0x40c00000 4M ramdisk image for applications
|
||||
#
|
||||
|
||||
fetchboot=tftp 100000 /hymod/u-boot.bin
|
||||
@@ -49,21 +141,21 @@ newlinux=run fetchlinux eraselinux copylinux cmplinux
|
||||
|
||||
fetchaltlinux=tftp 100000 /hymod/altlinux.bin
|
||||
erasealtlinux=erase 1:5-7
|
||||
copyaltlinux=cp.b 100000 40080000 $(filesize)
|
||||
cmpaltlinux=cmp.b 100000 40080000 $(filesize)
|
||||
copyaltlinux=cp.b 100000 40140000 $(filesize)
|
||||
cmpaltlinux=cmp.b 100000 40140000 $(filesize)
|
||||
newaltlinux=run fetchaltlinux erasealtlinux copyaltlinux cmpaltlinux
|
||||
|
||||
fetchird=tftp 100000 /hymod/initrd.bin
|
||||
eraseird=erase 1:8-63
|
||||
copyird=cp.b 100000 40200000 $(filesize)
|
||||
cmpird=cmp.b 100000 40200000 $(filesize)
|
||||
newinitrd=run fetchird eraseird copyird cmpird
|
||||
fetchroot=tftp 100000 /hymod/root.bin
|
||||
eraseroot=erase 1:8-47
|
||||
copyroot=cp.b 100000 40200000 $(filesize)
|
||||
cmproot=cmp.b 100000 40200000 $(filesize)
|
||||
newroot=run fetchroot eraseroot copyroot cmproot
|
||||
|
||||
bootcmd=bootm 40080000 40200000
|
||||
-bootargs=root=/dev/ram rw
|
||||
# these are for hymod linux
|
||||
bootargs+=preload=unix,i2c-cpm,i2c-dev
|
||||
bootargs+=serialno=%S
|
||||
bootargs+=ramdisk_size=32768
|
||||
bootargs+=automount nisclient nisdomain=mlb.dmt.csiro.au nissrvadr=138.194.112.4
|
||||
bootdelay=2
|
||||
fetchard=tftp 100000 /hymod/apprd.bin
|
||||
eraseard=erase 1:48-63
|
||||
copyard=cp.b 100000 40c00000 $(filesize)
|
||||
cmpard=cmp.b 100000 40c00000 $(filesize)
|
||||
newapprd=run fetchard eraseard copyard cmpard
|
||||
|
||||
# pass above map to linux mtd driver
|
||||
bootargs+=mtdparts=phys:256k(u-boot),256k(u-boot-env),768k(linux),768k(altlinux),10m(root),4m(hymod)
|
||||
|
||||
@@ -20,11 +20,12 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
* Hacked for the Hymod board by Murray.Jensen@cmst.csiro.au, 20-Oct-00
|
||||
* Hacked for the Hymod board by Murray.Jensen@csiro.au, 20-Oct-00
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc8260.h>
|
||||
#include <mpc8260_irq.h>
|
||||
#include <ioports.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/iopin_8260.h>
|
||||
@@ -32,15 +33,11 @@
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* imports from eeprom.c */
|
||||
extern int eeprom_load (unsigned, hymod_eeprom_t *);
|
||||
extern int eeprom_fetch (unsigned, char *, ulong);
|
||||
extern void eeprom_print (hymod_eeprom_t *);
|
||||
extern int hymod_eeprom_read (int, hymod_eeprom_t *);
|
||||
extern void hymod_eeprom_print (hymod_eeprom_t *);
|
||||
|
||||
/* imports from fetch.c */
|
||||
extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *));
|
||||
|
||||
/* imports from common/main.c */
|
||||
extern char console_buffer[CFG_CBSIZE];
|
||||
/* imports from env.c */
|
||||
extern void hymod_check_env (void);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
@@ -54,274 +51,152 @@ extern char console_buffer[CFG_CBSIZE];
|
||||
const iop_conf_t iop_conf_tab[4][32] = {
|
||||
|
||||
/* Port A configuration */
|
||||
{ /* conf ppar psor pdir podr pdat */
|
||||
/* PA31 */ {1, 1, 1, 0, 0, 0},
|
||||
/* FCC1 MII COL */
|
||||
/* PA30 */ {1, 1, 1, 0, 0, 0},
|
||||
/* FCC1 MII CRS */
|
||||
/* PA29 */ {1, 1, 1, 1, 0, 0},
|
||||
/* FCC1 MII TX_ER */
|
||||
/* PA28 */ {1, 1, 1, 1, 0, 0},
|
||||
/* FCC1 MII TX_EN */
|
||||
/* PA27 */ {1, 1, 1, 0, 0, 0},
|
||||
/* FCC1 MII RX_DV */
|
||||
/* PA26 */ {1, 1, 1, 0, 0, 0},
|
||||
/* FCC1 MII RX_ER */
|
||||
/* PA25 */ {1, 0, 0, 1, 0, 0},
|
||||
/* FCC2 MII MDIO */
|
||||
/* PA24 */ {1, 0, 0, 1, 0, 0},
|
||||
/* FCC2 MII MDC */
|
||||
/* PA23 */ {1, 0, 0, 1, 0, 0},
|
||||
/* FCC3 MII MDIO */
|
||||
/* PA22 */ {1, 0, 0, 1, 0, 0},
|
||||
/* FCC3 MII MDC */
|
||||
/* PA21 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC1 MII TxD[3] */
|
||||
/* PA20 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC1 MII TxD[2] */
|
||||
/* PA19 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC1 MII TxD[1] */
|
||||
/* PA18 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC1 MII TxD[0] */
|
||||
/* PA17 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC1 MII RxD[3] */
|
||||
/* PA16 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC1 MII RxD[2] */
|
||||
/* PA15 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC1 MII RxD[1] */
|
||||
/* PA14 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC1 MII RxD[0] */
|
||||
/* PA13 */ {1, 0, 0, 1, 0, 0},
|
||||
/* FCC1 MII MDIO */
|
||||
/* PA12 */ {1, 0, 0, 1, 0, 0},
|
||||
/* FCC1 MII MDC */
|
||||
/* PA11 */ {1, 0, 0, 1, 0, 0},
|
||||
/* SEL_CD */
|
||||
/* PA10 */ {1, 0, 0, 0, 0, 0},
|
||||
/* FLASH STS1 */
|
||||
/* PA9 */ {1, 0, 0, 0, 0, 0},
|
||||
/* FLASH STS0 */
|
||||
/* PA8 */ {1, 0, 0, 0, 0, 0},
|
||||
/* FLASH ~PE */
|
||||
/* PA7 */ {1, 0, 0, 0, 0, 0},
|
||||
/* WATCH ~HRESET */
|
||||
/* PA6 */ {1, 0, 0, 0, 1, 0},
|
||||
/* VC DONE */
|
||||
/* PA5 */ {1, 0, 0, 1, 1, 0},
|
||||
/* VC INIT */
|
||||
/* PA4 */ {1, 0, 0, 1, 0, 0},
|
||||
/* VC ~PROG */
|
||||
/* PA3 */ {1, 0, 0, 1, 0, 0},
|
||||
/* VM ENABLE */
|
||||
/* PA2 */ {1, 0, 0, 0, 1, 0},
|
||||
/* VM DONE */
|
||||
/* PA1 */ {1, 0, 0, 1, 1, 0},
|
||||
/* VM INIT */
|
||||
/* PA0 */ {1, 0, 0, 1, 0, 0}
|
||||
/* VM ~PROG */
|
||||
},
|
||||
{
|
||||
/* cnf par sor dir odr dat */
|
||||
{ 1, 1, 1, 0, 0, 0 }, /* PA31: FCC1 MII COL */
|
||||
{ 1, 1, 1, 0, 0, 0 }, /* PA30: FCC1 MII CRS */
|
||||
{ 1, 1, 1, 1, 0, 0 }, /* PA29: FCC1 MII TX_ER */
|
||||
{ 1, 1, 1, 1, 0, 0 }, /* PA28: FCC1 MII TX_EN */
|
||||
{ 1, 1, 1, 0, 0, 0 }, /* PA27: FCC1 MII RX_DV */
|
||||
{ 1, 1, 1, 0, 0, 0 }, /* PA26: FCC1 MII RX_ER */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PA25: FCC2 MII MDIO */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PA24: FCC2 MII MDC */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PA23: FCC3 MII MDIO */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PA22: FCC3 MII MDC */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PA21: FCC1 MII TxD[3] */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PA20: FCC1 MII TxD[2] */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PA19: FCC1 MII TxD[1] */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PA18: FCC1 MII TxD[0] */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PA17: FCC1 MII RxD[3] */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PA16: FCC1 MII RxD[2] */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PA15: FCC1 MII RxD[1] */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PA14: FCC1 MII RxD[0] */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PA13: FCC1 MII MDIO */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PA12: FCC1 MII MDC */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PA11: SEL_CD */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PA10: FLASH STS1 */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PA09: FLASH STS0 */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PA08: FLASH ~PE */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PA07: WATCH ~HRESET */
|
||||
{ 1, 0, 0, 0, 1, 0 }, /* PA06: VC DONE */
|
||||
{ 1, 0, 0, 1, 1, 0 }, /* PA05: VC INIT */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PA04: VC ~PROG */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PA03: VM ENABLE */
|
||||
{ 1, 0, 0, 0, 1, 0 }, /* PA02: VM DONE */
|
||||
{ 1, 0, 0, 1, 1, 0 }, /* PA01: VM INIT */
|
||||
{ 1, 0, 0, 1, 0, 0 } /* PA00: VM ~PROG */
|
||||
},
|
||||
|
||||
/* Port B configuration */
|
||||
{ /* conf ppar psor pdir podr pdat */
|
||||
/* PB31 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC2 MII TX_ER */
|
||||
/* PB30 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC2 MII RX_DV */
|
||||
/* PB29 */ {1, 1, 1, 1, 0, 0},
|
||||
/* FCC2 MII TX_EN */
|
||||
/* PB28 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC2 MII RX_ER */
|
||||
/* PB27 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC2 MII COL */
|
||||
/* PB26 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC2 MII CRS */
|
||||
/* PB25 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC2 MII TxD[3] */
|
||||
/* PB24 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC2 MII TxD[2] */
|
||||
/* PB23 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC2 MII TxD[1] */
|
||||
/* PB22 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC2 MII TxD[0] */
|
||||
/* PB21 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC2 MII RxD[0] */
|
||||
/* PB20 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC2 MII RxD[1] */
|
||||
/* PB19 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC2 MII RxD[2] */
|
||||
/* PB18 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC2 MII RxD[3] */
|
||||
/* PB17 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC3 MII RX_DV */
|
||||
/* PB16 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC3 MII RX_ER */
|
||||
/* PB15 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC3 MII TX_ER */
|
||||
/* PB14 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC3 MII TX_EN */
|
||||
/* PB13 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC3 MII COL */
|
||||
/* PB12 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC3 MII CRS */
|
||||
/* PB11 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC3 MII RxD[3] */
|
||||
/* PB10 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC3 MII RxD[2] */
|
||||
/* PB9 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC3 MII RxD[1] */
|
||||
/* PB8 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC3 MII RxD[0] */
|
||||
/* PB7 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC3 MII TxD[3] */
|
||||
/* PB6 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC3 MII TxD[2] */
|
||||
/* PB5 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC3 MII TxD[1] */
|
||||
/* PB4 */ {1, 1, 0, 1, 0, 0},
|
||||
/* FCC3 MII TxD[0] */
|
||||
/* PB3 */ {0, 0, 0, 0, 0, 0},
|
||||
/* pin doesn't exist */
|
||||
/* PB2 */ {0, 0, 0, 0, 0, 0},
|
||||
/* pin doesn't exist */
|
||||
/* PB1 */ {0, 0, 0, 0, 0, 0},
|
||||
/* pin doesn't exist */
|
||||
/* PB0 */ {0, 0, 0, 0, 0, 0}
|
||||
/* pin doesn't exist */
|
||||
},
|
||||
{
|
||||
/* cnf par sor dir odr dat */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PB31: FCC2 MII TX_ER */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB30: FCC2 MII RX_DV */
|
||||
{ 1, 1, 1, 1, 0, 0 }, /* PB29: FCC2 MII TX_EN */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB28: FCC2 MII RX_ER */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB27: FCC2 MII COL */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB26: FCC2 MII CRS */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PB25: FCC2 MII TxD[3] */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PB24: FCC2 MII TxD[2] */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PB23: FCC2 MII TxD[1] */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PB22: FCC2 MII TxD[0] */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB21: FCC2 MII RxD[0] */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB20: FCC2 MII RxD[1] */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB19: FCC2 MII RxD[2] */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB18: FCC2 MII RxD[3] */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB17: FCC3 MII RX_DV */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB16: FCC3 MII RX_ER */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PB15: FCC3 MII TX_ER */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PB14: FCC3 MII TX_EN */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB13: FCC3 MII COL */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB12: FCC3 MII CRS */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB11: FCC3 MII RxD[3] */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB10: FCC3 MII RxD[2] */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB09: FCC3 MII RxD[1] */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PB08: FCC3 MII RxD[0] */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PB07: FCC3 MII TxD[3] */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PB06: FCC3 MII TxD[2] */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PB05: FCC3 MII TxD[1] */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PB04: FCC3 MII TxD[0] */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* PB03: pin doesn't exist */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* PB02: pin doesn't exist */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* PB01: pin doesn't exist */
|
||||
{ 0, 0, 0, 0, 0, 0 } /* PB00: pin doesn't exist */
|
||||
},
|
||||
|
||||
/* Port C */
|
||||
{ /* conf ppar psor pdir podr pdat */
|
||||
/* PC31 */ {1, 0, 0, 0, 0, 0},
|
||||
/* MEZ ~IACK */
|
||||
/* PC30 */ {0, 0, 0, 0, 0, 0},
|
||||
/* PC29 */ {1, 1, 0, 0, 0, 0},
|
||||
/* CLK SCCx */
|
||||
/* PC28 */ {1, 1, 0, 0, 0, 0},
|
||||
/* CLK4 */
|
||||
/* PC27 */ {1, 1, 0, 0, 0, 0},
|
||||
/* CLK SCCF */
|
||||
/* PC26 */ {1, 1, 0, 0, 0, 0},
|
||||
/* CLK 32K */
|
||||
/* PC25 */ {1, 1, 0, 0, 0, 0},
|
||||
/* BRG4/CLK7 */
|
||||
/* PC24 */ {0, 0, 0, 0, 0, 0},
|
||||
/* PC23 */ {1, 1, 0, 0, 0, 0},
|
||||
/* CLK SCCx */
|
||||
/* PC22 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC1 MII RX_CLK */
|
||||
/* PC21 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC1 MII TX_CLK */
|
||||
/* PC20 */ {1, 1, 0, 0, 0, 0},
|
||||
/* CLK SCCF */
|
||||
/* PC19 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC2 MII RX_CLK */
|
||||
/* PC18 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC2 MII TX_CLK */
|
||||
/* PC17 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC3 MII RX_CLK */
|
||||
/* PC16 */ {1, 1, 0, 0, 0, 0},
|
||||
/* FCC3 MII TX_CLK */
|
||||
/* PC15 */ {1, 0, 0, 0, 0, 0},
|
||||
/* SCC1 UART ~CTS */
|
||||
/* PC14 */ {1, 0, 0, 0, 0, 0},
|
||||
/* SCC1 UART ~CD */
|
||||
/* PC13 */ {1, 0, 0, 0, 0, 0},
|
||||
/* SCC2 UART ~CTS */
|
||||
/* PC12 */ {1, 0, 0, 0, 0, 0},
|
||||
/* SCC2 UART ~CD */
|
||||
/* PC11 */ {1, 0, 0, 1, 0, 0},
|
||||
/* SCC1 UART ~DTR */
|
||||
/* PC10 */ {1, 0, 0, 1, 0, 0},
|
||||
/* SCC1 UART ~DSR */
|
||||
/* PC9 */ {1, 0, 0, 1, 0, 0},
|
||||
/* SCC2 UART ~DTR */
|
||||
/* PC8 */ {1, 0, 0, 1, 0, 0},
|
||||
/* SCC2 UART ~DSR */
|
||||
/* PC7 */ {1, 0, 0, 0, 0, 0},
|
||||
/* TEMP ~ALERT */
|
||||
/* PC6 */ {1, 0, 0, 0, 0, 0},
|
||||
/* FCC3 INT */
|
||||
/* PC5 */ {1, 0, 0, 0, 0, 0},
|
||||
/* FCC2 INT */
|
||||
/* PC4 */ {1, 0, 0, 0, 0, 0},
|
||||
/* FCC1 INT */
|
||||
/* PC3 */ {1, 1, 1, 1, 0, 0},
|
||||
/* SDMA IDMA2 ~DACK */
|
||||
/* PC2 */ {1, 1, 1, 0, 0, 0},
|
||||
/* SDMA IDMA2 ~DONE */
|
||||
/* PC1 */ {1, 1, 0, 0, 0, 0},
|
||||
/* SDMA IDMA2 ~DREQ */
|
||||
/* PC0 */ {1, 1, 0, 1, 0, 0}
|
||||
/* BRG7 */
|
||||
},
|
||||
/* Port C configuration */
|
||||
{
|
||||
/* cnf par sor dir odr dat */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PC31: MEZ ~IACK */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* PC30: ? */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PC29: CLK SCCx */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PC28: CLK4 */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PC27: CLK SCCF */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PC26: CLK 32K */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PC25: BRG4/CLK7 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* PC24: ? */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PC23: CLK SCCx */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PC22: FCC1 MII RX_CLK */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PC21: FCC1 MII TX_CLK */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PC20: CLK SCCF */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PC19: FCC2 MII RX_CLK */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PC18: FCC2 MII TX_CLK */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PC17: FCC3 MII RX_CLK */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PC16: FCC3 MII TX_CLK */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PC15: SCC1 UART ~CTS */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PC14: SCC1 UART ~CD */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PC13: SCC2 UART ~CTS */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PC12: SCC2 UART ~CD */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PC11: SCC1 UART ~DTR */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PC10: SCC1 UART ~DSR */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PC09: SCC2 UART ~DTR */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PC08: SCC2 UART ~DSR */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PC07: TEMP ~ALERT */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PC06: FCC3 INT */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PC05: FCC2 INT */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PC04: FCC1 INT */
|
||||
{ 0, 1, 1, 1, 0, 0 }, /* PC03: SDMA IDMA2 ~DACK */
|
||||
{ 0, 1, 1, 0, 0, 0 }, /* PC02: SDMA IDMA2 ~DONE */
|
||||
{ 0, 1, 0, 0, 0, 0 }, /* PC01: SDMA IDMA2 ~DREQ */
|
||||
{ 1, 1, 0, 1, 0, 0 } /* PC00: BRG7 */
|
||||
},
|
||||
|
||||
/* Port D */
|
||||
{ /* conf ppar psor pdir podr pdat */
|
||||
/* PD31 */ {1, 1, 0, 0, 0, 0},
|
||||
/* SCC1 UART RxD */
|
||||
/* PD30 */ {1, 1, 1, 1, 0, 0},
|
||||
/* SCC1 UART TxD */
|
||||
/* PD29 */ {1, 0, 0, 1, 0, 0},
|
||||
/* SCC1 UART ~RTS */
|
||||
/* PD28 */ {1, 1, 0, 0, 0, 0},
|
||||
/* SCC2 UART RxD */
|
||||
/* PD27 */ {1, 1, 0, 1, 0, 0},
|
||||
/* SCC2 UART TxD */
|
||||
/* PD26 */ {1, 0, 0, 1, 0, 0},
|
||||
/* SCC2 UART ~RTS */
|
||||
/* PD25 */ {1, 0, 0, 0, 0, 0},
|
||||
/* SCC1 UART ~RI */
|
||||
/* PD24 */ {1, 0, 0, 0, 0, 0},
|
||||
/* SCC2 UART ~RI */
|
||||
/* PD23 */ {1, 0, 0, 1, 0, 0},
|
||||
/* CLKGEN PD */
|
||||
/* PD22 */ {1, 0, 0, 0, 0, 0},
|
||||
/* USER3 */
|
||||
/* PD21 */ {1, 0, 0, 0, 0, 0},
|
||||
/* USER2 */
|
||||
/* PD20 */ {1, 0, 0, 0, 0, 0},
|
||||
/* USER1 */
|
||||
/* PD19 */ {1, 1, 1, 0, 0, 0},
|
||||
/* SPI ~SEL */
|
||||
/* PD18 */ {1, 1, 1, 0, 0, 0},
|
||||
/* SPI CLK */
|
||||
/* PD17 */ {1, 1, 1, 0, 0, 0},
|
||||
/* SPI MOSI */
|
||||
/* PD16 */ {1, 1, 1, 0, 0, 0},
|
||||
/* SPI MISO */
|
||||
/* PD15 */ {1, 1, 1, 0, 1, 0},
|
||||
/* I2C SDA */
|
||||
/* PD14 */ {1, 1, 1, 0, 1, 0},
|
||||
/* I2C SCL */
|
||||
/* PD13 */ {1, 0, 0, 1, 0, 1},
|
||||
/* TEMP ~STDBY */
|
||||
/* PD12 */ {1, 0, 0, 1, 0, 1},
|
||||
/* FCC3 ~RESET */
|
||||
/* PD11 */ {1, 0, 0, 1, 0, 1},
|
||||
/* FCC2 ~RESET */
|
||||
/* PD10 */ {1, 0, 0, 1, 0, 1},
|
||||
/* FCC1 ~RESET */
|
||||
/* PD9 */ {1, 0, 0, 0, 0, 0},
|
||||
/* PD9 */
|
||||
/* PD8 */ {1, 0, 0, 0, 0, 0},
|
||||
/* PD8 */
|
||||
/* PD7 */ {1, 0, 0, 1, 0, 1},
|
||||
/* PD7 */
|
||||
/* PD6 */ {1, 0, 0, 1, 0, 1},
|
||||
/* PD6 */
|
||||
/* PD5 */ {1, 0, 0, 1, 0, 1},
|
||||
/* PD5 */
|
||||
/* PD4 */ {1, 0, 0, 1, 0, 1},
|
||||
/* PD4 */
|
||||
/* PD3 */ {0, 0, 0, 0, 0, 0},
|
||||
/* pin doesn't exist */
|
||||
/* PD2 */ {0, 0, 0, 0, 0, 0},
|
||||
/* pin doesn't exist */
|
||||
/* PD1 */ {0, 0, 0, 0, 0, 0},
|
||||
/* pin doesn't exist */
|
||||
/* PD0 */ {0, 0, 0, 0, 0, 0}
|
||||
/* pin doesn't exist */
|
||||
}
|
||||
/* Port D configuration */
|
||||
{
|
||||
/* cnf par sor dir odr dat */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PD31: SCC1 UART RxD */
|
||||
{ 1, 1, 1, 1, 0, 0 }, /* PD30: SCC1 UART TxD */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PD29: SCC1 UART ~RTS */
|
||||
{ 1, 1, 0, 0, 0, 0 }, /* PD28: SCC2 UART RxD */
|
||||
{ 1, 1, 0, 1, 0, 0 }, /* PD27: SCC2 UART TxD */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PD26: SCC2 UART ~RTS */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PD25: SCC1 UART ~RI */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PD24: SCC2 UART ~RI */
|
||||
{ 1, 0, 0, 1, 0, 0 }, /* PD23: CLKGEN PD */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PD22: USER3 */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PD21: USER2 */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PD20: USER1 */
|
||||
{ 1, 1, 1, 0, 0, 0 }, /* PD19: SPI ~SEL */
|
||||
{ 1, 1, 1, 0, 0, 0 }, /* PD18: SPI CLK */
|
||||
{ 1, 1, 1, 0, 0, 0 }, /* PD17: SPI MOSI */
|
||||
{ 1, 1, 1, 0, 0, 0 }, /* PD16: SPI MISO */
|
||||
{ 1, 1, 1, 0, 1, 0 }, /* PD15: I2C SDA */
|
||||
{ 1, 1, 1, 0, 1, 0 }, /* PD14: I2C SCL */
|
||||
{ 1, 0, 0, 1, 0, 1 }, /* PD13: TEMP ~STDBY */
|
||||
{ 1, 0, 0, 1, 0, 1 }, /* PD12: FCC3 ~RESET */
|
||||
{ 1, 0, 0, 1, 0, 1 }, /* PD11: FCC2 ~RESET */
|
||||
{ 1, 0, 0, 1, 0, 1 }, /* PD10: FCC1 ~RESET */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PD09: PD9 */
|
||||
{ 1, 0, 0, 0, 0, 0 }, /* PD08: PD8 */
|
||||
{ 1, 0, 0, 1, 0, 1 }, /* PD07: PD7 */
|
||||
{ 1, 0, 0, 1, 0, 1 }, /* PD06: PD6 */
|
||||
{ 1, 0, 0, 1, 0, 1 }, /* PD05: PD5 */
|
||||
{ 1, 0, 0, 1, 0, 1 }, /* PD04: PD4 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* PD03: pin doesn't exist */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* PD02: pin doesn't exist */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* PD01: pin doesn't exist */
|
||||
{ 0, 0, 0, 0, 0, 0 } /* PD00: pin doesn't exist */
|
||||
}
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -334,17 +209,36 @@ const iop_conf_t iop_conf_tab[4][32] = {
|
||||
*
|
||||
* the data is written to the FS6377 via the i2c bus using address in
|
||||
* "fs6377_addr" (address is 7 bits - R/W bit not included).
|
||||
*
|
||||
* The fs6377 has four clock outputs: A, B, C and D.
|
||||
*
|
||||
* Outputs C and D can each provide two different clock outputs C1/D1 or
|
||||
* C2/D2 depending on the state of the SEL_CD input which is connected to
|
||||
* the MPC8260 I/O port pin PA11. PA11 output (SEL_CD input) low (or 0)
|
||||
* selects C1/D1 and PA11 output (SEL_CD input) high (or 1) selects C2/D2.
|
||||
*
|
||||
* PA11 defaults to output low (or 0) in the i/o port config table above.
|
||||
*
|
||||
* Output A provides a 100MHz for the High Speed Serial chips. Output B
|
||||
* provides a 3.6864MHz clock for more accurate asynchronous serial bit
|
||||
* rates. Output C is routed to the mezzanine connector but is currently
|
||||
* unused - both C1 and C2 are set to 16MHz. Output D is used by both the
|
||||
* alt-input and display mezzanine boards for their video chips. The
|
||||
* alt-input board requires a clock of 24.576MHz and this is available on
|
||||
* D1 (PA11=SEL_CD=0). The display board requires a clock of 27MHz and this
|
||||
* is available on D2 (PA11=SEL_CD=1).
|
||||
*
|
||||
* So the default is a clock suitable for the alt-input board. PA11 is toggled
|
||||
* later in misc_init_r(), if a display board is detected.
|
||||
*/
|
||||
|
||||
uchar fs6377_addr = 0x5c;
|
||||
|
||||
uchar fs6377_regs[16] = {
|
||||
12, 75, 64, 25, 144, 128, 25, 192,
|
||||
0, 16, 135, 192, 224, 64, 64, 192
|
||||
12, 75, 64, 25, 144, 128, 25, 192,
|
||||
0, 16, 135, 192, 224, 64, 64, 192
|
||||
};
|
||||
|
||||
iopin_t pa11 = { IOPIN_PORTA, 11, 0 };
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
@@ -356,7 +250,8 @@ iopin_t pa11 = { IOPIN_PORTA, 11, 0 };
|
||||
* the timebase, for udelay())
|
||||
*/
|
||||
|
||||
int board_postclk_init (void)
|
||||
int
|
||||
board_postclk_init (void)
|
||||
{
|
||||
i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
|
||||
|
||||
@@ -371,7 +266,7 @@ int board_postclk_init (void)
|
||||
* if this doesn't work
|
||||
*/
|
||||
(void) i2c_write (fs6377_addr, 0, 1, fs6377_regs,
|
||||
sizeof (fs6377_regs));
|
||||
sizeof (fs6377_regs));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -382,7 +277,8 @@ int board_postclk_init (void)
|
||||
* Check Board Identity: Hardwired to HYMOD
|
||||
*/
|
||||
|
||||
int checkboard (void)
|
||||
int
|
||||
checkboard (void)
|
||||
{
|
||||
puts ("Board: HYMOD\n");
|
||||
return (0);
|
||||
@@ -446,7 +342,8 @@ uint upmc_table[] = {
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_
|
||||
};
|
||||
|
||||
int misc_init_f (void)
|
||||
int
|
||||
misc_init_f (void)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
volatile memctl8260_t *memctl = &immap->im_memctl;
|
||||
@@ -465,7 +362,8 @@ int misc_init_f (void)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
long initdram (int board_type)
|
||||
long
|
||||
initdram (int board_type)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
volatile memctl8260_t *memctl = &immap->im_memctl;
|
||||
@@ -523,280 +421,95 @@ long initdram (int board_type)
|
||||
/* containing information to be stored in the eeprom from the tftp server */
|
||||
/* (the file name is based on the serial number and a built-in path) */
|
||||
|
||||
/* these are relative to the root of the server's tftp directory */
|
||||
static char *bddb_cfgdir = "/hymod/bddb";
|
||||
static char *global_env_path = "/hymod/global_env";
|
||||
|
||||
static ulong get_serno (const char *prompt)
|
||||
{
|
||||
for (;;) {
|
||||
int n;
|
||||
char *p;
|
||||
ulong serno;
|
||||
|
||||
n = readline (prompt);
|
||||
|
||||
if (n < 0)
|
||||
return (0);
|
||||
|
||||
if (n == 0)
|
||||
continue;
|
||||
|
||||
serno = simple_strtol (console_buffer, &p, 10);
|
||||
|
||||
if (p > console_buffer && *p == '\0')
|
||||
return (serno);
|
||||
|
||||
printf ("Invalid number (%s) - please re-enter\n", console_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static int read_eeprom (char *label, unsigned offset, hymod_eeprom_t * ep)
|
||||
{
|
||||
char filename[50], prompt[50];
|
||||
ulong serno;
|
||||
int count = 0;
|
||||
|
||||
sprintf (prompt, "Enter %s board serial number: ", label);
|
||||
|
||||
for (;;) {
|
||||
|
||||
if (eeprom_load (offset, ep))
|
||||
return (1);
|
||||
|
||||
printf ("*** %s board EEPROM contents are %sinvalid\n",
|
||||
label, count == 0 ? "" : "STILL ");
|
||||
|
||||
puts ("*** will attempt to fetch from server (Ctrl-C to abort)\n");
|
||||
|
||||
if ((serno = get_serno (prompt)) == 0) {
|
||||
puts ("\n*** interrupted! - ignoring eeprom contents\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
sprintf (filename, "%s/%010lu.cfg", bddb_cfgdir, serno);
|
||||
|
||||
printf ("*** fetching %s board EEPROM contents from server\n",
|
||||
label);
|
||||
|
||||
if (eeprom_fetch (offset, filename, 0x100000) == 0) {
|
||||
puts ("*** fetch failed - ignoring eeprom contents\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
static ulong main_serno;
|
||||
|
||||
static int env_fetch_callback (uchar * name, uchar * value)
|
||||
{
|
||||
char *ov, nv[CFG_CBSIZE], *p, *q, *nn;
|
||||
int override = 1, append = 0, nl;
|
||||
|
||||
nn = name;
|
||||
if (*nn == '-') {
|
||||
override = 0;
|
||||
nn++;
|
||||
}
|
||||
|
||||
if ((nl = strlen (nn)) > 0 && nn[nl - 1] == '+') {
|
||||
append = 1;
|
||||
nn[--nl] = '\0';
|
||||
}
|
||||
|
||||
p = value;
|
||||
q = nv;
|
||||
|
||||
while ((*q = *p++) != '\0')
|
||||
if (*q == '%') {
|
||||
switch (*p++) {
|
||||
|
||||
case '\0': /* whoops - back up */
|
||||
p--;
|
||||
break;
|
||||
|
||||
case '%': /* a single percent character */
|
||||
q++;
|
||||
break;
|
||||
|
||||
case 's': /* main board serial number as string */
|
||||
q += sprintf (q, "%010lu", main_serno);
|
||||
break;
|
||||
|
||||
case 'S': /* main board serial number as number */
|
||||
q += sprintf (q, "%lu", main_serno);
|
||||
break;
|
||||
|
||||
default: /* ignore any others */
|
||||
break;
|
||||
}
|
||||
} else
|
||||
q++;
|
||||
|
||||
if ((ov = getenv (nn)) != NULL) {
|
||||
|
||||
if (append) {
|
||||
|
||||
if (strstr (ov, nv) == NULL) {
|
||||
int ovl, nvl;
|
||||
|
||||
printf ("Appending '%s' to env cmd '%s'\n", nv, nn);
|
||||
|
||||
ovl = strlen (ov);
|
||||
nvl = strlen (nv);
|
||||
|
||||
while (nvl >= 0) {
|
||||
nv[ovl + 1 + nvl] = nv[nvl];
|
||||
nvl--;
|
||||
}
|
||||
|
||||
nv[ovl] = ' ';
|
||||
|
||||
while (--ovl >= 0)
|
||||
nv[ovl] = ov[ovl];
|
||||
|
||||
setenv (nn, nv);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (!override || strcmp (ov, nv) == 0)
|
||||
return (1);
|
||||
|
||||
printf ("Re-setting env cmd '%s' from '%s' to '%s'\n", nn, ov, nv);
|
||||
} else
|
||||
printf ("Setting env cmd '%s' to '%s'\n", nn, nv);
|
||||
|
||||
setenv (nn, nv);
|
||||
return (1);
|
||||
}
|
||||
|
||||
int misc_init_r (void)
|
||||
int
|
||||
last_stage_init (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
hymod_conf_t *cp = &gd->bd->bi_hymod_conf;
|
||||
int rc;
|
||||
|
||||
#ifdef CONFIG_BOOT_RETRY_TIME
|
||||
/*
|
||||
* we use the readline () function, but we also want
|
||||
* command timeout enabled
|
||||
*/
|
||||
init_cmd_timeout ();
|
||||
#endif
|
||||
|
||||
memset ((void *) cp, 0, sizeof (*cp));
|
||||
|
||||
/* set up main board config info */
|
||||
|
||||
if (i2c_probe (CFG_I2C_EEPROM_ADDR | HYMOD_EEOFF_MAIN)) {
|
||||
rc = hymod_eeprom_read (0, &cp->main.eeprom);
|
||||
|
||||
if (read_eeprom
|
||||
("main", HYMOD_EEOFF_MAIN << 8, &cp->main.eeprom))
|
||||
cp->main.eeprom_valid = 1;
|
||||
puts ("EEPROM:main...");
|
||||
if (rc < 0)
|
||||
puts ("NOT PRESENT\n");
|
||||
else if (rc == 0)
|
||||
puts ("INVALID\n");
|
||||
else {
|
||||
cp->main.eeprom.valid = 1;
|
||||
|
||||
puts ("EEPROM:main...");
|
||||
printf ("OK (ver %u)\n", cp->main.eeprom.ver);
|
||||
hymod_eeprom_print (&cp->main.eeprom);
|
||||
|
||||
if (cp->main.eeprom_valid) {
|
||||
printf ("OK (ver %u)\n", cp->main.eeprom.ver);
|
||||
eeprom_print (&cp->main.eeprom);
|
||||
main_serno = cp->main.eeprom.serno;
|
||||
} else
|
||||
puts ("BAD\n");
|
||||
/*
|
||||
* hard-wired assumption here: all hymod main boards will have
|
||||
* one xilinx fpga, with the interrupt line connected to IRQ2
|
||||
*
|
||||
* One day, this might be based on the board type
|
||||
*/
|
||||
|
||||
cp->main.mmap[0].prog.exists = 1;
|
||||
cp->main.mmap[0].prog.size = FPGA_MAIN_CFG_SIZE;
|
||||
cp->main.mmap[0].prog.base = FPGA_MAIN_CFG_BASE;
|
||||
cp->main.xlx[0].mmap.prog.exists = 1;
|
||||
cp->main.xlx[0].mmap.prog.size = FPGA_MAIN_CFG_SIZE;
|
||||
cp->main.xlx[0].mmap.prog.base = FPGA_MAIN_CFG_BASE;
|
||||
|
||||
cp->main.mmap[0].reg.exists = 1;
|
||||
cp->main.mmap[0].reg.size = FPGA_MAIN_REG_SIZE;
|
||||
cp->main.mmap[0].reg.base = FPGA_MAIN_REG_BASE;
|
||||
cp->main.xlx[0].mmap.reg.exists = 1;
|
||||
cp->main.xlx[0].mmap.reg.size = FPGA_MAIN_REG_SIZE;
|
||||
cp->main.xlx[0].mmap.reg.base = FPGA_MAIN_REG_BASE;
|
||||
|
||||
cp->main.mmap[0].port.exists = 1;
|
||||
cp->main.mmap[0].port.size = FPGA_MAIN_PORT_SIZE;
|
||||
cp->main.mmap[0].port.base = FPGA_MAIN_PORT_BASE;
|
||||
cp->main.xlx[0].mmap.port.exists = 1;
|
||||
cp->main.xlx[0].mmap.port.size = FPGA_MAIN_PORT_SIZE;
|
||||
cp->main.xlx[0].mmap.port.base = FPGA_MAIN_PORT_BASE;
|
||||
|
||||
cp->main.iopins[0].prog_pin.port = FPGA_MAIN_PROG_PORT;
|
||||
cp->main.iopins[0].prog_pin.pin = FPGA_MAIN_PROG_PIN;
|
||||
cp->main.iopins[0].prog_pin.flag = 1;
|
||||
cp->main.iopins[0].init_pin.port = FPGA_MAIN_INIT_PORT;
|
||||
cp->main.iopins[0].init_pin.pin = FPGA_MAIN_INIT_PIN;
|
||||
cp->main.iopins[0].init_pin.flag = 1;
|
||||
cp->main.iopins[0].done_pin.port = FPGA_MAIN_DONE_PORT;
|
||||
cp->main.iopins[0].done_pin.pin = FPGA_MAIN_DONE_PIN;
|
||||
cp->main.iopins[0].done_pin.flag = 1;
|
||||
cp->main.xlx[0].iopins.prog_pin.port = FPGA_MAIN_PROG_PORT;
|
||||
cp->main.xlx[0].iopins.prog_pin.pin = FPGA_MAIN_PROG_PIN;
|
||||
cp->main.xlx[0].iopins.prog_pin.flag = 1;
|
||||
cp->main.xlx[0].iopins.init_pin.port = FPGA_MAIN_INIT_PORT;
|
||||
cp->main.xlx[0].iopins.init_pin.pin = FPGA_MAIN_INIT_PIN;
|
||||
cp->main.xlx[0].iopins.init_pin.flag = 1;
|
||||
cp->main.xlx[0].iopins.done_pin.port = FPGA_MAIN_DONE_PORT;
|
||||
cp->main.xlx[0].iopins.done_pin.pin = FPGA_MAIN_DONE_PIN;
|
||||
cp->main.xlx[0].iopins.done_pin.flag = 1;
|
||||
#ifdef FPGA_MAIN_ENABLE_PORT
|
||||
cp->main.iopins[0].enable_pin.port = FPGA_MAIN_ENABLE_PORT;
|
||||
cp->main.iopins[0].enable_pin.pin = FPGA_MAIN_ENABLE_PIN;
|
||||
cp->main.iopins[0].enable_pin.flag = 1;
|
||||
cp->main.xlx[0].iopins.enable_pin.port = FPGA_MAIN_ENABLE_PORT;
|
||||
cp->main.xlx[0].iopins.enable_pin.pin = FPGA_MAIN_ENABLE_PIN;
|
||||
cp->main.xlx[0].iopins.enable_pin.flag = 1;
|
||||
#endif
|
||||
} else
|
||||
puts ("EEPROM:main...NOT PRESENT\n");
|
||||
|
||||
cp->main.xlx[0].irq = FPGA_MAIN_IRQ;
|
||||
}
|
||||
|
||||
/* set up mezzanine board config info */
|
||||
|
||||
if (i2c_probe (CFG_I2C_EEPROM_ADDR | HYMOD_EEOFF_MEZZ)) {
|
||||
rc = hymod_eeprom_read (1, &cp->mezz.eeprom);
|
||||
|
||||
if (read_eeprom
|
||||
("mezz", HYMOD_EEOFF_MEZZ << 8, &cp->mezz.eeprom))
|
||||
cp->mezz.eeprom_valid = 1;
|
||||
puts ("EEPROM:mezz...");
|
||||
if (rc < 0)
|
||||
puts ("NOT PRESENT\n");
|
||||
else if (rc == 0)
|
||||
puts ("INVALID\n");
|
||||
else {
|
||||
cp->main.eeprom.valid = 1;
|
||||
|
||||
puts ("EEPROM:mezz...");
|
||||
|
||||
if (cp->mezz.eeprom_valid) {
|
||||
printf ("OK (ver %u)\n", cp->mezz.eeprom.ver);
|
||||
eeprom_print (&cp->mezz.eeprom);
|
||||
} else
|
||||
puts ("BAD\n");
|
||||
|
||||
cp->mezz.mmap[0].prog.exists = 1;
|
||||
cp->mezz.mmap[0].prog.size = FPGA_MEZZ_CFG_SIZE;
|
||||
cp->mezz.mmap[0].prog.base = FPGA_MEZZ_CFG_BASE;
|
||||
|
||||
cp->mezz.mmap[0].reg.exists = 0;
|
||||
|
||||
cp->mezz.mmap[0].port.exists = 0;
|
||||
|
||||
cp->mezz.iopins[0].prog_pin.port = FPGA_MEZZ_PROG_PORT;
|
||||
cp->mezz.iopins[0].prog_pin.pin = FPGA_MEZZ_PROG_PIN;
|
||||
cp->mezz.iopins[0].prog_pin.flag = 1;
|
||||
cp->mezz.iopins[0].init_pin.port = FPGA_MEZZ_INIT_PORT;
|
||||
cp->mezz.iopins[0].init_pin.pin = FPGA_MEZZ_INIT_PIN;
|
||||
cp->mezz.iopins[0].init_pin.flag = 1;
|
||||
cp->mezz.iopins[0].done_pin.port = FPGA_MEZZ_DONE_PORT;
|
||||
cp->mezz.iopins[0].done_pin.pin = FPGA_MEZZ_DONE_PIN;
|
||||
cp->mezz.iopins[0].done_pin.flag = 1;
|
||||
#ifdef FPGA_MEZZ_ENABLE_PORT
|
||||
cp->mezz.iopins[0].enable_pin.port = FPGA_MEZZ_ENABLE_PORT;
|
||||
cp->mezz.iopins[0].enable_pin.pin = FPGA_MEZZ_ENABLE_PIN;
|
||||
cp->mezz.iopins[0].enable_pin.flag = 1;
|
||||
#endif
|
||||
|
||||
if (cp->mezz.eeprom_valid &&
|
||||
cp->mezz.eeprom.bdtype == HYMOD_BDTYPE_DISPLAY) {
|
||||
/*
|
||||
* mezzanine board is a display board - switch the SEL_CD
|
||||
* input of the FS6377 clock generator (via I/O Port Pin PA11) to
|
||||
* high (or 1) to select the 27MHz required by the display board
|
||||
*/
|
||||
iopin_set_high (&pa11);
|
||||
|
||||
puts ("SEL_CD:toggled for display board\n");
|
||||
}
|
||||
} else
|
||||
puts ("EEPROM:mezz...NOT PRESENT\n");
|
||||
|
||||
cp->crc =
|
||||
crc32 (0, (unsigned char *) cp, offsetof (hymod_conf_t, crc));
|
||||
|
||||
if (getenv ("global_env_loaded") == NULL) {
|
||||
|
||||
puts ("*** global environment has not been loaded\n");
|
||||
puts ("*** fetching from server (Control-C to Abort)\n");
|
||||
|
||||
rc = fetch_and_parse (global_env_path, 0x100000,
|
||||
env_fetch_callback);
|
||||
|
||||
if (rc == 0)
|
||||
puts ("*** Fetch of environment failed!\n");
|
||||
else
|
||||
setenv ("global_env_loaded", "yes");
|
||||
printf ("OK (ver %u)\n", cp->mezz.eeprom.ver);
|
||||
hymod_eeprom_print (&cp->mezz.eeprom);
|
||||
}
|
||||
|
||||
cp->crc = crc32 (0, (unsigned char *)cp, offsetof (hymod_conf_t, crc));
|
||||
|
||||
hymod_check_env ();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
322
board/hymod/hymod.h
Normal file
322
board/hymod/hymod.h
Normal file
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* (C) Copyright 2001
|
||||
* Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
|
||||
*
|
||||
* 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 _HYMOD_H_
|
||||
#define _HYMOD_H_
|
||||
|
||||
#include <linux/config.h>
|
||||
#ifdef CONFIG_8260
|
||||
#include <asm/iopin_8260.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* hymod configuration data - passed by boot code via the board information
|
||||
* structure (only U-Boot has support for this at the moment)
|
||||
*
|
||||
* there are three types of data passed up from the boot monitor. the first
|
||||
* (type hymod_eeprom_t) is the eeprom data that was read off both the main
|
||||
* (or mother) board and the mezzanine board (if any). this data defines how
|
||||
* many Xilinx fpgas are on each board, and their types (among other things).
|
||||
* the second type of data (type xlx_mmap_t, one per Xilinx fpga) defines where
|
||||
* in the physical address space the various Xilinx fpga access regions have
|
||||
* been mapped by the boot rom. the third type of data (type xlx_iopins_t,
|
||||
* one per Xilinx fpga) defines which io port pins are connected to the various
|
||||
* signals required to program a Xilinx fpga.
|
||||
*
|
||||
* A ram/flash "bank" refers to memory controlled by the same chip select.
|
||||
*
|
||||
* the eeprom contents are defined as in technical note #2 - basically,
|
||||
* a header, zero or more records in no particular order, and a 32 bit crc
|
||||
* a record is 1 or more type bytes, a length byte and "length" bytes.
|
||||
*/
|
||||
|
||||
#define HYMOD_EEPROM_ID 0xAA /* eeprom id byte */
|
||||
#define HYMOD_EEPROM_VER 1 /* eeprom contents version (0-127) */
|
||||
#define HYMOD_EEPROM_SIZE 256 /* number of bytes in the eeprom */
|
||||
|
||||
/* eeprom header */
|
||||
typedef
|
||||
struct {
|
||||
unsigned char id; /* eeprom id byte */
|
||||
unsigned char :1;
|
||||
unsigned char ver:7; /* eeprom contents version number */
|
||||
unsigned long len; /* total # of bytes btw hdr and crc */
|
||||
}
|
||||
hymod_eehdr_t;
|
||||
|
||||
/* maximum number of bytes available for eeprom data records */
|
||||
#define HYMOD_EEPROM_MAXLEN (HYMOD_EEPROM_SIZE \
|
||||
- sizeof (hymod_eehdr_t) \
|
||||
- sizeof (unsigned long))
|
||||
|
||||
/* eeprom data record */
|
||||
typedef
|
||||
union {
|
||||
struct {
|
||||
unsigned char topbit:1;
|
||||
unsigned char type:7;
|
||||
unsigned char len;
|
||||
unsigned char data[1]; /* variable length */
|
||||
} small;
|
||||
struct {
|
||||
unsigned short topbit:1;
|
||||
unsigned short nxtbit:1;
|
||||
unsigned short type:14;
|
||||
unsigned short len;
|
||||
unsigned char data[1]; /* variable length */
|
||||
} medium;
|
||||
struct {
|
||||
unsigned long topbit:1;
|
||||
unsigned long nxtbit:1;
|
||||
unsigned long type:30;
|
||||
unsigned long len;
|
||||
unsigned char data[1]; /* variable length */
|
||||
} large;
|
||||
}
|
||||
hymod_eerec_t;
|
||||
|
||||
#define HYMOD_EEOFF_MAIN 0x00 /* i2c addr offset for main eeprom */
|
||||
#define HYMOD_EEOFF_MEZZ 0x04 /* i2c addr offset for mezz eepomr */
|
||||
|
||||
/* eeprom record types */
|
||||
#define HYMOD_EEREC_SERNO 1 /* serial number */
|
||||
#define HYMOD_EEREC_DATE 2 /* date */
|
||||
#define HYMOD_EEREC_BATCH 3 /* batch id */
|
||||
#define HYMOD_EEREC_TYPE 4 /* board type */
|
||||
#define HYMOD_EEREC_REV 5 /* revision number */
|
||||
#define HYMOD_EEREC_SDRAM 6 /* sdram sizes */
|
||||
#define HYMOD_EEREC_FLASH 7 /* flash sizes */
|
||||
#define HYMOD_EEREC_ZBT 8 /* zbt ram sizes */
|
||||
#define HYMOD_EEREC_XLXTYP 9 /* Xilinx fpga types */
|
||||
#define HYMOD_EEREC_XLXSPD 10 /* Xilinx fpga speeds */
|
||||
#define HYMOD_EEREC_XLXTMP 11 /* Xilinx fpga temperatures */
|
||||
#define HYMOD_EEREC_XLXGRD 12 /* Xilinx fpga grades */
|
||||
#define HYMOD_EEREC_CPUTYP 13 /* Motorola CPU type */
|
||||
#define HYMOD_EEREC_CPUSPD 14 /* CPU speed */
|
||||
#define HYMOD_EEREC_BUSSPD 15 /* bus speed */
|
||||
#define HYMOD_EEREC_CPMSPD 16 /* CPM speed */
|
||||
#define HYMOD_EEREC_HSTYPE 17 /* high-speed serial chip type */
|
||||
#define HYMOD_EEREC_HSCHIN 18 /* high-speed serial input channels */
|
||||
#define HYMOD_EEREC_HSCHOUT 19 /* high-speed serial output channels */
|
||||
|
||||
/* some dimensions */
|
||||
#define HYMOD_MAX_BATCH 32 /* max no. of bytes in batch id */
|
||||
#define HYMOD_MAX_SDRAM 4 /* max sdram "banks" on any board */
|
||||
#define HYMOD_MAX_FLASH 4 /* max flash "banks" on any board */
|
||||
#define HYMOD_MAX_ZBT 16 /* max ZBT rams on any board */
|
||||
#define HYMOD_MAX_XLX 4 /* max Xilinx fpgas on any board */
|
||||
|
||||
#define HYMOD_MAX_BYTES 16 /* enough to store any bytes array */
|
||||
|
||||
/* board types */
|
||||
#define HYMOD_BDTYPE_NONE 0 /* information not present */
|
||||
#define HYMOD_BDTYPE_IO 1 /* I/O main board */
|
||||
#define HYMOD_BDTYPE_CLP 2 /* CLP main board */
|
||||
#define HYMOD_BDTYPE_DSP 3 /* DSP main board */
|
||||
#define HYMOD_BDTYPE_INPUT 4 /* video input mezzanine board */
|
||||
#define HYMOD_BDTYPE_ALTINPUT 5 /* video input mezzanine board */
|
||||
#define HYMOD_BDTYPE_DISPLAY 6 /* video display mezzanine board */
|
||||
#define HYMOD_BDTYPE_MAX 7 /* first invalid value */
|
||||
|
||||
/* Xilinx fpga types */
|
||||
#define HYMOD_XTYP_NONE 0 /* information not present */
|
||||
#define HYMOD_XTYP_XCV300E 1 /* Xilinx Virtex 300 */
|
||||
#define HYMOD_XTYP_XCV400E 2 /* Xilinx Virtex 400 */
|
||||
#define HYMOD_XTYP_XCV600E 3 /* Xilinx Virtex 600 */
|
||||
#define HYMOD_XTYP_MAX 4 /* first invalid value */
|
||||
|
||||
/* Xilinx fpga speeds */
|
||||
#define HYMOD_XSPD_NONE 0 /* information not present */
|
||||
#define HYMOD_XSPD_SIX 1
|
||||
#define HYMOD_XSPD_SEVEN 2
|
||||
#define HYMOD_XSPD_EIGHT 3
|
||||
#define HYMOD_XSPD_MAX 4 /* first invalid value */
|
||||
|
||||
/* Xilinx fpga temperatures */
|
||||
#define HYMOD_XTMP_NONE 0 /* information not present */
|
||||
#define HYMOD_XTMP_COM 1
|
||||
#define HYMOD_XTMP_IND 2
|
||||
#define HYMOD_XTMP_MAX 3 /* first invalid value */
|
||||
|
||||
/* Xilinx fpga grades */
|
||||
#define HYMOD_XTMP_NONE 0 /* information not present */
|
||||
#define HYMOD_XTMP_NORMAL 1
|
||||
#define HYMOD_XTMP_ENGSAMP 2
|
||||
#define HYMOD_XTMP_MAX 3 /* first invalid value */
|
||||
|
||||
/* CPU types */
|
||||
#define HYMOD_CPUTYPE_NONE 0 /* information not present */
|
||||
#define HYMOD_CPUTYPE_MPC8260 1 /* Motorola MPC8260 embedded powerpc */
|
||||
#define HYMOD_CPUTYPE_MAX 2 /* first invalid value */
|
||||
|
||||
/* CPU/BUS/CPM clock speeds */
|
||||
#define HYMOD_CLKSPD_NONE 0 /* information not present */
|
||||
#define HYMOD_CLKSPD_33MHZ 1
|
||||
#define HYMOD_CLKSPD_66MHZ 2
|
||||
#define HYMOD_CLKSPD_100MHZ 3
|
||||
#define HYMOD_CLKSPD_133MHZ 4
|
||||
#define HYMOD_CLKSPD_166MHZ 5
|
||||
#define HYMOD_CLKSPD_200MHZ 6
|
||||
#define HYMOD_CLKSPD_MAX 7 /* first invalid value */
|
||||
|
||||
/* high speed serial chip types */
|
||||
#define HYMOD_HSSTYPE_NONE 0 /* information not present */
|
||||
#define HYMOD_HSSTYPE_AMCC52064 1
|
||||
#define HYMOD_HSSTYPE_MAX 2 /* first invalid value */
|
||||
|
||||
/* a date (yyyy-mm-dd) */
|
||||
typedef
|
||||
struct {
|
||||
unsigned short year;
|
||||
unsigned char month;
|
||||
unsigned char day;
|
||||
}
|
||||
hymod_date_t;
|
||||
|
||||
/* describes a Xilinx fpga */
|
||||
typedef
|
||||
struct {
|
||||
unsigned char type; /* chip type */
|
||||
unsigned char speed; /* chip speed rating */
|
||||
unsigned char temp; /* chip temperature rating */
|
||||
unsigned char grade; /* chip grade */
|
||||
}
|
||||
hymod_xlx_t;
|
||||
|
||||
/* describes a Motorola embedded processor */
|
||||
typedef
|
||||
struct {
|
||||
unsigned char type; /* CPU type */
|
||||
unsigned char cpuspd; /* speed of the PowerPC core */
|
||||
unsigned char busspd; /* speed of the system and 60x bus */
|
||||
unsigned char cpmspd; /* speed of the CPM co-processor */
|
||||
}
|
||||
hymod_mpc_t;
|
||||
|
||||
/* info about high-speed (1Gbit) serial interface */
|
||||
typedef
|
||||
struct {
|
||||
unsigned char type; /* high-speed serial chip type */
|
||||
unsigned char nchin; /* number of input channels mounted */
|
||||
unsigned char nchout; /* number of output channels mounted */
|
||||
}
|
||||
hymod_hss_t;
|
||||
|
||||
/*
|
||||
* this defines the contents of the serial eeprom that exists on every
|
||||
* hymod board, including mezzanine boards (the serial eeprom will be
|
||||
* faked for early development boards that don't have one)
|
||||
*/
|
||||
|
||||
typedef
|
||||
struct {
|
||||
unsigned char valid:1; /* contents of this struct is valid */
|
||||
unsigned char ver:7; /* eeprom contents version */
|
||||
unsigned char bdtype; /* board type */
|
||||
unsigned char bdrev; /* board revision */
|
||||
unsigned char batchlen; /* length of batch string below */
|
||||
unsigned long serno; /* serial number */
|
||||
hymod_date_t date; /* manufacture date */
|
||||
unsigned char batch[32]; /* manufacturer specific batch id */
|
||||
unsigned char nsdram; /* # of ram "banks" */
|
||||
unsigned char nflash; /* # of flash "banks" */
|
||||
unsigned char nzbt; /* # of ZBT rams */
|
||||
unsigned char nxlx; /* # of Xilinx fpgas */
|
||||
unsigned char sdramsz[HYMOD_MAX_SDRAM]; /* log2 of sdram size */
|
||||
unsigned char flashsz[HYMOD_MAX_FLASH]; /* log2 of flash size */
|
||||
unsigned char zbtsz[HYMOD_MAX_ZBT]; /* log2 of ZBT ram size */
|
||||
hymod_xlx_t xlx[HYMOD_MAX_XLX]; /* Xilinx fpga info */
|
||||
hymod_mpc_t mpc; /* Motorola MPC CPU info */
|
||||
hymod_hss_t hss; /* high-speed serial info */
|
||||
}
|
||||
hymod_eeprom_t;
|
||||
|
||||
/*
|
||||
* this defines a region in the processor's physical address space
|
||||
*/
|
||||
typedef
|
||||
struct {
|
||||
unsigned long exists:1; /* 1 if the region exists, 0 if not */
|
||||
unsigned long size:31; /* size in bytes */
|
||||
unsigned long base; /* base address */
|
||||
}
|
||||
xlx_prgn_t;
|
||||
|
||||
/*
|
||||
* this defines where the various Xilinx fpga access regions are mapped
|
||||
* into the physical address space of the processor
|
||||
*/
|
||||
typedef
|
||||
struct {
|
||||
xlx_prgn_t prog; /* program access region */
|
||||
xlx_prgn_t reg; /* register access region */
|
||||
xlx_prgn_t port; /* port access region */
|
||||
}
|
||||
xlx_mmap_t;
|
||||
|
||||
/*
|
||||
* this defines which 8260 i/o port pins are connected to the various
|
||||
* signals required for programming a Xilinx fpga
|
||||
*/
|
||||
typedef
|
||||
struct {
|
||||
iopin_t prog_pin; /* assert for >= 300ns to program */
|
||||
iopin_t init_pin; /* goes high when fpga is cleared */
|
||||
iopin_t done_pin; /* goes high when program is done */
|
||||
iopin_t enable_pin; /* some fpgas need enabling */
|
||||
}
|
||||
xlx_iopins_t;
|
||||
|
||||
/* all info about one Xilinx chip */
|
||||
typedef
|
||||
struct {
|
||||
xlx_mmap_t mmap;
|
||||
xlx_iopins_t iopins;
|
||||
unsigned long irq:8; /* h/w intr req number for this fpga */
|
||||
}
|
||||
xlx_info_t;
|
||||
|
||||
/* all info about one hymod board */
|
||||
typedef
|
||||
struct {
|
||||
hymod_eeprom_t eeprom;
|
||||
xlx_info_t xlx[HYMOD_MAX_XLX];
|
||||
}
|
||||
hymod_board_t;
|
||||
|
||||
/*
|
||||
* this defines the configuration information of a hymod board-set
|
||||
* (main board + possible mezzanine board). In future, there may be
|
||||
* more than one mezzanine board (stackable?) - if so, add a "mezz2"
|
||||
* field, and so on... or make mezz an array?
|
||||
*/
|
||||
typedef
|
||||
struct {
|
||||
unsigned long ver:8; /* version control */
|
||||
hymod_board_t main; /* main board info */
|
||||
hymod_board_t mezz; /* mezzanine board info */
|
||||
unsigned long crc; /* ensures kernel and boot prom agree */
|
||||
}
|
||||
hymod_conf_t;
|
||||
|
||||
#endif /* _HYMOD_H_ */
|
||||
113
board/hymod/input.c
Normal file
113
board/hymod/input.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
|
||||
*
|
||||
* 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>
|
||||
|
||||
/* imports from common/main.c */
|
||||
extern char console_buffer[CFG_CBSIZE];
|
||||
|
||||
int
|
||||
hymod_get_serno (const char *prompt)
|
||||
{
|
||||
for (;;) {
|
||||
int n, serno;
|
||||
char *p;
|
||||
|
||||
#ifdef CONFIG_BOOT_RETRY_TIME
|
||||
reset_cmd_timeout ();
|
||||
#endif
|
||||
|
||||
n = readline (prompt);
|
||||
|
||||
if (n < 0)
|
||||
return (n);
|
||||
|
||||
if (n == 0)
|
||||
continue;
|
||||
|
||||
serno = (int) simple_strtol (console_buffer, &p, 10);
|
||||
|
||||
if (p > console_buffer && *p == '\0' && serno > 0)
|
||||
return (serno);
|
||||
|
||||
printf ("Invalid number (%s) - please re-enter\n",
|
||||
console_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
hymod_get_ethaddr (void)
|
||||
{
|
||||
for (;;) {
|
||||
int n;
|
||||
|
||||
#ifdef CONFIG_BOOT_RETRY_TIME
|
||||
reset_cmd_timeout ();
|
||||
#endif
|
||||
|
||||
n = readline ("Enter board ethernet address: ");
|
||||
|
||||
if (n < 0)
|
||||
return (n);
|
||||
|
||||
if (n == 0)
|
||||
continue;
|
||||
|
||||
if (n == 17) {
|
||||
int i;
|
||||
char *p, *q;
|
||||
uchar ea[6];
|
||||
|
||||
/* see if it looks like an ethernet address */
|
||||
|
||||
p = console_buffer;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
char term = (i == 5 ? '\0' : ':');
|
||||
|
||||
ea[i] = simple_strtol (p, &q, 16);
|
||||
|
||||
if ((q - p) != 2 || *q++ != term)
|
||||
break;
|
||||
|
||||
p = q;
|
||||
}
|
||||
|
||||
if (i == 6) {
|
||||
/* it looks ok - set it */
|
||||
printf ("Setting ethernet addr to %s\n",
|
||||
console_buffer);
|
||||
|
||||
setenv ("ethaddr", console_buffer);
|
||||
|
||||
puts ("Remember to do a 'saveenv' to "
|
||||
"make it permanent\n");
|
||||
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
printf ("Invalid ethernet addr (%s) - please re-enter\n",
|
||||
console_buffer);
|
||||
}
|
||||
}
|
||||
@@ -299,12 +299,6 @@ int misc_init_r (void)
|
||||
|
||||
void lcd_logo (bd_t * bd)
|
||||
{
|
||||
|
||||
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
|
||||
|
||||
|
||||
FB_INFO_S1D13xxx fb_info;
|
||||
S1D_INDEX s1dReg;
|
||||
S1D_VALUE s1dValue;
|
||||
@@ -328,8 +322,8 @@ void lcd_logo (bd_t * bd)
|
||||
/**/
|
||||
/*----------------------------------------------------------------------------- */
|
||||
memctl = &immr->im_memctl;
|
||||
/* memctl->memc_or5 = 0xFFC007F0; / * 4 MB 17 WS or externel TA */
|
||||
/* memctl->memc_br5 = 0x80000801; / * Start at 0x80000000 */
|
||||
/* memctl->memc_or5 = 0xFFC007F0; / * 4 MB 17 WS or externel TA */
|
||||
/* memctl->memc_br5 = 0x80000801; / * Start at 0x80000000 */
|
||||
|
||||
memctl->memc_or5 = 0xFFC00708; /* 4 MB 17 WS or externel TA */
|
||||
memctl->memc_br5 = 0x80080801; /* Start at 0x80080000 */
|
||||
|
||||
47
board/logodl/Makefile
Normal file
47
board/logodl/Makefile
Normal file
@@ -0,0 +1,47 @@
|
||||
#
|
||||
# (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
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS := logodl.o flash.o
|
||||
SOBJS := memsetup.o
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS)
|
||||
$(AR) crv $@ $^
|
||||
|
||||
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
|
||||
|
||||
#########################################################################
|
||||
15
board/logodl/config.mk
Normal file
15
board/logodl/config.mk
Normal file
@@ -0,0 +1,15 @@
|
||||
#
|
||||
# Linux-Kernel is expected to be at c000'8000, entry c000'8000
|
||||
#
|
||||
# we load ourself to c170'0000, the upper 1 MB of second bank
|
||||
#
|
||||
# download areas is c800'0000
|
||||
#
|
||||
|
||||
#TEXT_BASE = 0
|
||||
|
||||
# FIXME: armboot does only work correctly when being compiled
|
||||
# # for the addresses _after_ relocation to RAM!! Otherwhise the
|
||||
# # .bss segment is assumed in flash...
|
||||
#
|
||||
TEXT_BASE = 0x083E0000
|
||||
844
board/logodl/flash.c
Normal file
844
board/logodl/flash.c
Normal file
@@ -0,0 +1,844 @@
|
||||
/*
|
||||
* (C) 2000 Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
* (C) 2003 August Hoeraendl, Logotronic GmbH
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#undef CONFIG_FLASH_16BIT
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#define FLASH_BANK_SIZE 0x1000000
|
||||
#define MAIN_SECT_SIZE 0x20000 /* 2x64k = 128k per sector */
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
/* NOTE - CONFIG_FLASH_16BIT means the CPU interface is 16-bit, it
|
||||
* has nothing to do with the flash chip being 8-bit or 16-bit.
|
||||
*/
|
||||
#ifdef CONFIG_FLASH_16BIT
|
||||
typedef unsigned short FLASH_PORT_WIDTH;
|
||||
typedef volatile unsigned short FLASH_PORT_WIDTHV;
|
||||
|
||||
#define FLASH_ID_MASK 0xFFFF
|
||||
#else
|
||||
typedef unsigned long FLASH_PORT_WIDTH;
|
||||
typedef volatile unsigned long FLASH_PORT_WIDTHV;
|
||||
|
||||
#define FLASH_ID_MASK 0xFFFFFFFF
|
||||
#endif
|
||||
|
||||
#define FPW FLASH_PORT_WIDTH
|
||||
#define FPWV FLASH_PORT_WIDTHV
|
||||
|
||||
#define ORMASK(size) ((-size) & OR_AM_MSK)
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static ulong flash_get_size (FPWV * addr, flash_info_t * info);
|
||||
static void flash_reset (flash_info_t * info);
|
||||
static int write_word_intel (flash_info_t * info, FPWV * dest, FPW data);
|
||||
static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data);
|
||||
|
||||
#define write_word(in, de, da) write_word_amd(in, de, da)
|
||||
static void flash_get_offsets (ulong base, flash_info_t * info);
|
||||
|
||||
#ifdef CFG_FLASH_PROTECTION
|
||||
static void flash_sync_real_protect (flash_info_t * info);
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* flash_init()
|
||||
*
|
||||
* sets up flash_info and returns size of FLASH (bytes)
|
||||
*/
|
||||
ulong flash_init (void)
|
||||
{
|
||||
int i, j;
|
||||
ulong size = 0;
|
||||
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
|
||||
ulong flashbase = 0;
|
||||
|
||||
flash_info[i].flash_id =
|
||||
(FLASH_MAN_AMD & FLASH_VENDMASK) |
|
||||
(FLASH_AM640U & FLASH_TYPEMASK);
|
||||
flash_info[i].size = FLASH_BANK_SIZE;
|
||||
flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
|
||||
memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
|
||||
switch (i) {
|
||||
case 0:
|
||||
flashbase = PHYS_FLASH_1;
|
||||
break;
|
||||
case 1:
|
||||
flashbase = PHYS_FLASH_2;
|
||||
break;
|
||||
default:
|
||||
panic ("configured to many flash banks!\n");
|
||||
break;
|
||||
}
|
||||
for (j = 0; j < flash_info[i].sector_count; j++) {
|
||||
flash_info[i].start[j] = flashbase + j * MAIN_SECT_SIZE;
|
||||
}
|
||||
size += flash_info[i].size;
|
||||
}
|
||||
|
||||
/* Protect monitor and environment sectors
|
||||
*/
|
||||
flash_protect (FLAG_PROTECT_SET,
|
||||
CFG_FLASH_BASE,
|
||||
CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
|
||||
&flash_info[0]);
|
||||
|
||||
flash_protect (FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void flash_reset (flash_info_t * info)
|
||||
{
|
||||
FPWV *base = (FPWV *) (info->start[0]);
|
||||
|
||||
/* Put FLASH back in read mode */
|
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
|
||||
*base = (FPW) 0x00FF00FF; /* Intel Read Mode */
|
||||
else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
|
||||
*base = (FPW) 0x00F000F0; /* AMD Read Mode */
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void flash_get_offsets (ulong base, flash_info_t * info)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* set up sector start address table */
|
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL
|
||||
&& (info->flash_id & FLASH_BTYPE)) {
|
||||
int bootsect_size; /* number of bytes/boot sector */
|
||||
int sect_size; /* number of bytes/regular sector */
|
||||
|
||||
bootsect_size = 0x00002000 * (sizeof (FPW) / 2);
|
||||
sect_size = 0x00010000 * (sizeof (FPW) / 2);
|
||||
|
||||
/* set sector offsets for bottom boot block type */
|
||||
for (i = 0; i < 8; ++i) {
|
||||
info->start[i] = base + (i * bootsect_size);
|
||||
}
|
||||
for (i = 8; i < info->sector_count; i++) {
|
||||
info->start[i] = base + ((i - 7) * sect_size);
|
||||
}
|
||||
} else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
|
||||
&& (info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U) {
|
||||
|
||||
int sect_size; /* number of bytes/sector */
|
||||
|
||||
sect_size = 0x00010000 * (sizeof (FPW) / 2);
|
||||
|
||||
/* set up sector start address table (uniform sector type) */
|
||||
for (i = 0; i < info->sector_count; i++)
|
||||
info->start[i] = base + (i * sect_size);
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void flash_print_info (flash_info_t * info)
|
||||
{
|
||||
int i;
|
||||
uchar *boottype;
|
||||
uchar *bootletter;
|
||||
uchar *fmt;
|
||||
uchar botbootletter[] = "B";
|
||||
uchar topbootletter[] = "T";
|
||||
uchar botboottype[] = "bottom boot sector";
|
||||
uchar topboottype[] = "top boot sector";
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("missing or unknown FLASH type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_AMD:
|
||||
printf ("AMD ");
|
||||
break;
|
||||
case FLASH_MAN_BM:
|
||||
printf ("BRIGHT MICRO ");
|
||||
break;
|
||||
case FLASH_MAN_FUJ:
|
||||
printf ("FUJITSU ");
|
||||
break;
|
||||
case FLASH_MAN_SST:
|
||||
printf ("SST ");
|
||||
break;
|
||||
case FLASH_MAN_STM:
|
||||
printf ("STM ");
|
||||
break;
|
||||
case FLASH_MAN_INTEL:
|
||||
printf ("INTEL ");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Vendor ");
|
||||
break;
|
||||
}
|
||||
|
||||
/* check for top or bottom boot, if it applies */
|
||||
if (info->flash_id & FLASH_BTYPE) {
|
||||
boottype = botboottype;
|
||||
bootletter = botbootletter;
|
||||
} else {
|
||||
boottype = topboottype;
|
||||
bootletter = topbootletter;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_AM640U:
|
||||
fmt = "29LV641D (64 Mbit, uniform sectors)\n";
|
||||
break;
|
||||
case FLASH_28F800C3B:
|
||||
case FLASH_28F800C3T:
|
||||
fmt = "28F800C3%s (8 Mbit, %s)\n";
|
||||
break;
|
||||
case FLASH_INTEL800B:
|
||||
case FLASH_INTEL800T:
|
||||
fmt = "28F800B3%s (8 Mbit, %s)\n";
|
||||
break;
|
||||
case FLASH_28F160C3B:
|
||||
case FLASH_28F160C3T:
|
||||
fmt = "28F160C3%s (16 Mbit, %s)\n";
|
||||
break;
|
||||
case FLASH_INTEL160B:
|
||||
case FLASH_INTEL160T:
|
||||
fmt = "28F160B3%s (16 Mbit, %s)\n";
|
||||
break;
|
||||
case FLASH_28F320C3B:
|
||||
case FLASH_28F320C3T:
|
||||
fmt = "28F320C3%s (32 Mbit, %s)\n";
|
||||
break;
|
||||
case FLASH_INTEL320B:
|
||||
case FLASH_INTEL320T:
|
||||
fmt = "28F320B3%s (32 Mbit, %s)\n";
|
||||
break;
|
||||
case FLASH_28F640C3B:
|
||||
case FLASH_28F640C3T:
|
||||
fmt = "28F640C3%s (64 Mbit, %s)\n";
|
||||
break;
|
||||
case FLASH_INTEL640B:
|
||||
case FLASH_INTEL640T:
|
||||
fmt = "28F640B3%s (64 Mbit, %s)\n";
|
||||
break;
|
||||
default:
|
||||
fmt = "Unknown Chip Type\n";
|
||||
break;
|
||||
}
|
||||
|
||||
printf (fmt, bootletter, boottype);
|
||||
|
||||
printf (" Size: %ld MB in %d Sectors\n",
|
||||
info->size >> 20, info->sector_count);
|
||||
|
||||
printf (" Sector Start Addresses:");
|
||||
|
||||
for (i = 0; i < info->sector_count; ++i) {
|
||||
if ((i % 5) == 0) {
|
||||
printf ("\n ");
|
||||
}
|
||||
|
||||
printf (" %08lX%s", info->start[i],
|
||||
info->protect[i] ? " (RO)" : " ");
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
|
||||
ulong flash_get_size (FPWV * addr, flash_info_t * info)
|
||||
{
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
|
||||
/* Write auto select command sequence and test FLASH answer */
|
||||
addr[0x0555] = (FPW) 0x00AA00AA; /* for AMD, Intel ignores this */
|
||||
addr[0x02AA] = (FPW) 0x00550055; /* for AMD, Intel ignores this */
|
||||
addr[0x0555] = (FPW) 0x00900090; /* selects Intel or AMD */
|
||||
|
||||
/* The manufacturer codes are only 1 byte, so just use 1 byte.
|
||||
* This works for any bus width and any FLASH device width.
|
||||
*/
|
||||
switch (addr[0] & 0xff) {
|
||||
|
||||
case (uchar) AMD_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_AMD;
|
||||
break;
|
||||
|
||||
case (uchar) INTEL_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_INTEL;
|
||||
break;
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
|
||||
if (info->flash_id != FLASH_UNKNOWN)
|
||||
switch (addr[1]) {
|
||||
|
||||
case (FPW) AMD_ID_LV640U: /* 29LV640 and 29LV641 have same ID */
|
||||
info->flash_id += FLASH_AM640U;
|
||||
info->sector_count = 128;
|
||||
info->size = 0x00800000 * (sizeof (FPW) / 2);
|
||||
break; /* => 8 or 16 MB */
|
||||
|
||||
case (FPW) INTEL_ID_28F800C3B:
|
||||
info->flash_id += FLASH_28F800C3B;
|
||||
info->sector_count = 23;
|
||||
info->size = 0x00100000 * (sizeof (FPW) / 2);
|
||||
break; /* => 1 or 2 MB */
|
||||
|
||||
case (FPW) INTEL_ID_28F800B3B:
|
||||
info->flash_id += FLASH_INTEL800B;
|
||||
info->sector_count = 23;
|
||||
info->size = 0x00100000 * (sizeof (FPW) / 2);
|
||||
break; /* => 1 or 2 MB */
|
||||
|
||||
case (FPW) INTEL_ID_28F160C3B:
|
||||
info->flash_id += FLASH_28F160C3B;
|
||||
info->sector_count = 39;
|
||||
info->size = 0x00200000 * (sizeof (FPW) / 2);
|
||||
break; /* => 2 or 4 MB */
|
||||
|
||||
case (FPW) INTEL_ID_28F160B3B:
|
||||
info->flash_id += FLASH_INTEL160B;
|
||||
info->sector_count = 39;
|
||||
info->size = 0x00200000 * (sizeof (FPW) / 2);
|
||||
break; /* => 2 or 4 MB */
|
||||
|
||||
case (FPW) INTEL_ID_28F320C3B:
|
||||
info->flash_id += FLASH_28F320C3B;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000 * (sizeof (FPW) / 2);
|
||||
break; /* => 4 or 8 MB */
|
||||
|
||||
case (FPW) INTEL_ID_28F320B3B:
|
||||
info->flash_id += FLASH_INTEL320B;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000 * (sizeof (FPW) / 2);
|
||||
break; /* => 4 or 8 MB */
|
||||
|
||||
case (FPW) INTEL_ID_28F640C3B:
|
||||
info->flash_id += FLASH_28F640C3B;
|
||||
info->sector_count = 135;
|
||||
info->size = 0x00800000 * (sizeof (FPW) / 2);
|
||||
break; /* => 8 or 16 MB */
|
||||
|
||||
case (FPW) INTEL_ID_28F640B3B:
|
||||
info->flash_id += FLASH_INTEL640B;
|
||||
info->sector_count = 135;
|
||||
info->size = 0x00800000 * (sizeof (FPW) / 2);
|
||||
break; /* => 8 or 16 MB */
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
return (0); /* => no or unknown flash */
|
||||
}
|
||||
|
||||
flash_get_offsets ((ulong) addr, info);
|
||||
|
||||
/* Put FLASH back in read mode */
|
||||
flash_reset (info);
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
#ifdef CFG_FLASH_PROTECTION
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void flash_sync_real_protect (flash_info_t * info)
|
||||
{
|
||||
FPWV *addr = (FPWV *) (info->start[0]);
|
||||
FPWV *sect;
|
||||
int i;
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_28F800C3B:
|
||||
case FLASH_28F800C3T:
|
||||
case FLASH_28F160C3B:
|
||||
case FLASH_28F160C3T:
|
||||
case FLASH_28F320C3B:
|
||||
case FLASH_28F320C3T:
|
||||
case FLASH_28F640C3B:
|
||||
case FLASH_28F640C3T:
|
||||
/* check for protected sectors */
|
||||
*addr = (FPW) 0x00900090;
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
/* read sector protection at sector address, (A7 .. A0) = 0x02.
|
||||
* D0 = 1 for each device if protected.
|
||||
* If at least one device is protected the sector is marked
|
||||
* protected, but mixed protected and unprotected devices
|
||||
* within a sector should never happen.
|
||||
*/
|
||||
sect = (FPWV *) (info->start[i]);
|
||||
info->protect[i] = (sect[2] & (FPW) (0x00010001)) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Put FLASH back in read mode */
|
||||
flash_reset (info);
|
||||
break;
|
||||
|
||||
case FLASH_AM640U:
|
||||
default:
|
||||
/* no hardware protect that we support */
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int flash_erase (flash_info_t * info, int s_first, int s_last)
|
||||
{
|
||||
FPWV *addr;
|
||||
int flag, prot, sect;
|
||||
int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
|
||||
ulong start, now, last;
|
||||
int rcode = 0;
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("- missing\n");
|
||||
} else {
|
||||
printf ("- no sectors to erase\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_INTEL800B:
|
||||
case FLASH_INTEL160B:
|
||||
case FLASH_INTEL320B:
|
||||
case FLASH_INTEL640B:
|
||||
case FLASH_28F800C3B:
|
||||
case FLASH_28F160C3B:
|
||||
case FLASH_28F320C3B:
|
||||
case FLASH_28F640C3B:
|
||||
case FLASH_AM640U:
|
||||
break;
|
||||
case FLASH_UNKNOWN:
|
||||
default:
|
||||
printf ("Can't erase unknown flash type %08lx - aborted\n",
|
||||
info->flash_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
for (sect = s_first; sect <= s_last; ++sect) {
|
||||
if (info->protect[sect]) {
|
||||
prot++;
|
||||
}
|
||||
}
|
||||
|
||||
if (prot) {
|
||||
printf ("- Warning: %d protected sectors will not be erased!\n",
|
||||
prot);
|
||||
} else {
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
start = get_timer (0);
|
||||
last = start;
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect <= s_last && rcode == 0; sect++) {
|
||||
|
||||
if (info->protect[sect] != 0) /* protected, skip it */
|
||||
continue;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
|
||||
addr = (FPWV *) (info->start[sect]);
|
||||
if (intel) {
|
||||
*addr = (FPW) 0x00500050; /* clear status register */
|
||||
*addr = (FPW) 0x00200020; /* erase setup */
|
||||
*addr = (FPW) 0x00D000D0; /* erase confirm */
|
||||
} else {
|
||||
/* must be AMD style if not Intel */
|
||||
FPWV *base; /* first address in bank */
|
||||
|
||||
base = (FPWV *) (info->start[0]);
|
||||
base[0x0555] = (FPW) 0x00AA00AA; /* unlock */
|
||||
base[0x02AA] = (FPW) 0x00550055; /* unlock */
|
||||
base[0x0555] = (FPW) 0x00800080; /* erase mode */
|
||||
base[0x0555] = (FPW) 0x00AA00AA; /* unlock */
|
||||
base[0x02AA] = (FPW) 0x00550055; /* unlock */
|
||||
*addr = (FPW) 0x00300030; /* erase sector */
|
||||
}
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts ();
|
||||
|
||||
/* wait at least 50us for AMD, 80us for Intel.
|
||||
* Let's wait 1 ms.
|
||||
*/
|
||||
udelay (1000);
|
||||
|
||||
while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) {
|
||||
if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout\n");
|
||||
|
||||
if (intel) {
|
||||
/* suspend erase */
|
||||
*addr = (FPW) 0x00B000B0;
|
||||
}
|
||||
|
||||
flash_reset (info); /* reset to read mode */
|
||||
rcode = 1; /* failed */
|
||||
break;
|
||||
}
|
||||
|
||||
/* show that we're waiting */
|
||||
if ((now - last) > 1000) { /* every second */
|
||||
putc ('.');
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
|
||||
flash_reset (info); /* reset to read mode */
|
||||
}
|
||||
|
||||
printf (" done\n");
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
int bad_write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
{
|
||||
FPW data = 0; /* 16 or 32 bit word, matches flash bus width */
|
||||
int bytes; /* number of bytes to program in current word */
|
||||
int left; /* number of bytes left to program */
|
||||
int i, res;
|
||||
|
||||
/* printf("write_buff: src: %8p addr %08lx count: %ld\n", src, addr, cnt); */
|
||||
|
||||
for (left = cnt, res = 0;
|
||||
left > 0 && res == 0;
|
||||
addr += sizeof (data), left -= sizeof (data) - bytes) {
|
||||
|
||||
bytes = addr & (sizeof (data) - 1);
|
||||
addr &= ~(sizeof (data) - 1);
|
||||
|
||||
/* combine source and destination data so can program
|
||||
* an entire word of 16 or 32 bits
|
||||
*/
|
||||
for (i = 0; i < sizeof (data); i++) {
|
||||
data <<= 8;
|
||||
if (i < bytes || i - bytes >= left)
|
||||
data += *((uchar *) addr + i);
|
||||
else
|
||||
data += *src++;
|
||||
}
|
||||
|
||||
/* write one word to the flash */
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_AMD:
|
||||
res = write_word_amd (info, (FPWV *) addr, data);
|
||||
break;
|
||||
case FLASH_MAN_INTEL:
|
||||
res = write_word_intel (info, (FPWV *) addr, data);
|
||||
break;
|
||||
default:
|
||||
/* unknown flash type, error! */
|
||||
printf ("missing or unknown FLASH type\n");
|
||||
res = 1; /* not really a timeout, but gives error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
/**
|
||||
* write_buf: - Copy memory to flash.
|
||||
*
|
||||
* @param info:
|
||||
* @param src: source of copy transaction
|
||||
* @param addr: where to copy to
|
||||
* @param cnt: number of bytes to copy
|
||||
*
|
||||
* @return error code
|
||||
*/
|
||||
|
||||
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong cp, wp;
|
||||
FPW data;
|
||||
int l;
|
||||
int i, rc;
|
||||
|
||||
wp = (addr & ~1); /* get lower word aligned address */
|
||||
|
||||
/*
|
||||
* handle unaligned start bytes
|
||||
*/
|
||||
if ((l = addr - wp) != 0) {
|
||||
data = 0;
|
||||
for (i = 0, cp = wp; i < l; ++i, ++cp) {
|
||||
data = (data >> 8) | (*(uchar *) cp << 8);
|
||||
}
|
||||
for (; i < 2 && cnt > 0; ++i) {
|
||||
data = (data >> 8) | (*src++ << 8);
|
||||
--cnt;
|
||||
++cp;
|
||||
}
|
||||
for (; cnt == 0 && i < 2; ++i, ++cp) {
|
||||
data = (data >> 8) | (*(uchar *) cp << 8);
|
||||
}
|
||||
|
||||
if ((rc = write_word (info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle word aligned part
|
||||
*/
|
||||
while (cnt >= 2) {
|
||||
/* data = *((vushort*)src); */
|
||||
data = *((FPW *) src);
|
||||
if ((rc = write_word (info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
src += sizeof (FPW);
|
||||
wp += sizeof (FPW);
|
||||
cnt -= sizeof (FPW);
|
||||
}
|
||||
|
||||
if (cnt == 0)
|
||||
return ERR_OK;
|
||||
|
||||
/*
|
||||
* handle unaligned tail bytes
|
||||
*/
|
||||
data = 0;
|
||||
for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
|
||||
data = (data >> 8) | (*src++ << 8);
|
||||
--cnt;
|
||||
}
|
||||
for (; i < 2; ++i, ++cp) {
|
||||
data = (data >> 8) | (*(uchar *) cp << 8);
|
||||
}
|
||||
|
||||
return write_word (info, wp, data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word to Flash for AMD FLASH
|
||||
* A word is 16 or 32 bits, whichever the bus width of the flash bank
|
||||
* (not an individual chip) is.
|
||||
*
|
||||
* returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data)
|
||||
{
|
||||
ulong start;
|
||||
int flag;
|
||||
int res = 0; /* result, assume success */
|
||||
FPWV *base; /* first address in flash bank */
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*dest & data) != data) {
|
||||
return (2);
|
||||
}
|
||||
|
||||
|
||||
base = (FPWV *) (info->start[0]);
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
|
||||
base[0x0555] = (FPW) 0x00AA00AA; /* unlock */
|
||||
base[0x02AA] = (FPW) 0x00550055; /* unlock */
|
||||
base[0x0555] = (FPW) 0x00A000A0; /* selects program mode */
|
||||
|
||||
*dest = data; /* start programming the data */
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts ();
|
||||
|
||||
start = get_timer (0);
|
||||
|
||||
/* data polling for D7 */
|
||||
while (res == 0
|
||||
&& (*dest & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) {
|
||||
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
|
||||
*dest = (FPW) 0x00F000F0; /* reset bank */
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word to Flash for Intel FLASH
|
||||
* A word is 16 or 32 bits, whichever the bus width of the flash bank
|
||||
* (not an individual chip) is.
|
||||
*
|
||||
* returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
static int write_word_intel (flash_info_t * info, FPWV * dest, FPW data)
|
||||
{
|
||||
ulong start;
|
||||
int flag;
|
||||
int res = 0; /* result, assume success */
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*dest & data) != data) {
|
||||
return (2);
|
||||
}
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
|
||||
*dest = (FPW) 0x00500050; /* clear status register */
|
||||
*dest = (FPW) 0x00FF00FF; /* make sure in read mode */
|
||||
*dest = (FPW) 0x00400040; /* program setup */
|
||||
|
||||
*dest = data; /* start programming the data */
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts ();
|
||||
|
||||
start = get_timer (0);
|
||||
|
||||
while (res == 0 && (*dest & (FPW) 0x00800080) != (FPW) 0x00800080) {
|
||||
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
|
||||
*dest = (FPW) 0x00B000B0; /* Suspend program */
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (res == 0 && (*dest & (FPW) 0x00100010))
|
||||
res = 1; /* write failed, time out error is close enough */
|
||||
|
||||
*dest = (FPW) 0x00500050; /* clear status register */
|
||||
*dest = (FPW) 0x00FF00FF; /* make sure in read mode */
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
#ifdef CFG_FLASH_PROTECTION
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
int flash_real_protect (flash_info_t * info, long sector, int prot)
|
||||
{
|
||||
int rcode = 0; /* assume success */
|
||||
FPWV *addr; /* address of sector */
|
||||
FPW value;
|
||||
|
||||
addr = (FPWV *) (info->start[sector]);
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_28F800C3B:
|
||||
case FLASH_28F800C3T:
|
||||
case FLASH_28F160C3B:
|
||||
case FLASH_28F160C3T:
|
||||
case FLASH_28F320C3B:
|
||||
case FLASH_28F320C3T:
|
||||
case FLASH_28F640C3B:
|
||||
case FLASH_28F640C3T:
|
||||
flash_reset (info); /* make sure in read mode */
|
||||
*addr = (FPW) 0x00600060L; /* lock command setup */
|
||||
if (prot)
|
||||
*addr = (FPW) 0x00010001L; /* lock sector */
|
||||
else
|
||||
*addr = (FPW) 0x00D000D0L; /* unlock sector */
|
||||
flash_reset (info); /* reset to read mode */
|
||||
|
||||
/* now see if it really is locked/unlocked as requested */
|
||||
*addr = (FPW) 0x00900090;
|
||||
/* read sector protection at sector address, (A7 .. A0) = 0x02.
|
||||
* D0 = 1 for each device if protected.
|
||||
* If at least one device is protected the sector is marked
|
||||
* protected, but return failure. Mixed protected and
|
||||
* unprotected devices within a sector should never happen.
|
||||
*/
|
||||
value = addr[2] & (FPW) 0x00010001;
|
||||
if (value == 0)
|
||||
info->protect[sector] = 0;
|
||||
else if (value == (FPW) 0x00010001)
|
||||
info->protect[sector] = 1;
|
||||
else {
|
||||
/* error, mixed protected and unprotected */
|
||||
rcode = 1;
|
||||
info->protect[sector] = 1;
|
||||
}
|
||||
if (info->protect[sector] != prot)
|
||||
rcode = 1; /* failed to protect/unprotect as requested */
|
||||
|
||||
/* reload all protection bits from hardware for now */
|
||||
flash_sync_real_protect (info);
|
||||
break;
|
||||
|
||||
case FLASH_AM640U:
|
||||
default:
|
||||
/* no hardware protect that we support */
|
||||
info->protect[sector] = prot;
|
||||
break;
|
||||
}
|
||||
|
||||
return rcode;
|
||||
}
|
||||
#endif
|
||||
123
board/logodl/logodl.c
Normal file
123
board/logodl/logodl.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* (C) 2002 Kyle Harris <kharris@nexus-tech.net>, Nexus Technologies, Inc.
|
||||
* (C) 2002 Marius Groeger <mgroeger@sysgo.de>, Sysgo GmbH
|
||||
* (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
|
||||
*
|
||||
* 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 <asm/arch/pxa-regs.h>
|
||||
|
||||
/**
|
||||
* board_init: - setup some data structures
|
||||
*
|
||||
* @return: 0 in case of success
|
||||
*/
|
||||
|
||||
int board_init (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* memory and cpu-speed are setup before relocation */
|
||||
/* so we do _nothing_ here */
|
||||
|
||||
gd->bd->bi_arch_number = MACH_TYPE_LOGODL;
|
||||
gd->bd->bi_boot_params = 0x08000100;
|
||||
gd->bd->bi_baudrate = CONFIG_BAUDRATE;
|
||||
|
||||
(*((volatile short*)0x14800000)) = 0xff; /* power on eth0 */
|
||||
(*((volatile short*)0x14000000)) = 0xff; /* power on uart */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* dram_init: - setup dynamic RAM
|
||||
*
|
||||
* @return: 0 in case of success
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* logodl_set_led: - switch LEDs on or off
|
||||
*
|
||||
* @param led: LED to switch (0,1)
|
||||
* @param state: switch on (1) or off (0)
|
||||
*/
|
||||
|
||||
void logodl_set_led(int led, int state)
|
||||
{
|
||||
switch(led) {
|
||||
|
||||
case 0:
|
||||
if (state==1) {
|
||||
CFG_LED_A_CR = CFG_LED_A_BIT;
|
||||
} else if (state==0) {
|
||||
CFG_LED_A_SR = CFG_LED_A_BIT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (state==1) {
|
||||
CFG_LED_B_CR = CFG_LED_B_BIT;
|
||||
} else if (state==0) {
|
||||
CFG_LED_B_SR = CFG_LED_B_BIT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* show_boot_progress: - indicate state of the boot process
|
||||
*
|
||||
* @param status: Status number - see README for details.
|
||||
*
|
||||
* The LOGOTRONIC does only have 2 LEDs, so we switch them on at the most
|
||||
* important states (1, 5, 15).
|
||||
*/
|
||||
|
||||
void show_boot_progress (int status)
|
||||
{
|
||||
/*
|
||||
switch(status) {
|
||||
case 1: logodl_set_led(0,1); break;
|
||||
case 5: logodl_set_led(1,1); break;
|
||||
case 15: logodl_set_led(2,1); break;
|
||||
}
|
||||
*/
|
||||
logodl_set_led(0, (status & 1)==1);
|
||||
logodl_set_led(1, (status & 2)==2);
|
||||
|
||||
return;
|
||||
}
|
||||
438
board/logodl/memsetup.S
Normal file
438
board/logodl/memsetup.S
Normal file
@@ -0,0 +1,438 @@
|
||||
/*
|
||||
* Most of this taken from Redboot hal_platform_setup.h with cleanup
|
||||
*
|
||||
* NOTE: I haven't clean this up considerably, just enough to get it
|
||||
* running. See hal_platform_setup.h for the source. See
|
||||
* board/cradle/memsetup.S for another PXA250 setup that is
|
||||
* much cleaner.
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include <version.h>
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
|
||||
DRAM_SIZE: .long CFG_DRAM_SIZE
|
||||
|
||||
/* wait for coprocessor write complete */
|
||||
.macro CPWAIT reg
|
||||
mrc p15,0,\reg,c2,c0,0
|
||||
mov \reg,\reg
|
||||
sub pc,pc,#4
|
||||
.endm
|
||||
|
||||
_TEXT_BASE:
|
||||
.word TEXT_BASE
|
||||
|
||||
|
||||
/*
|
||||
* Memory setup
|
||||
*/
|
||||
|
||||
.globl memsetup
|
||||
memsetup:
|
||||
|
||||
mov r10, lr
|
||||
|
||||
/* Set up GPIO pins first ----------------------------------------- */
|
||||
|
||||
ldr r0, =GPSR0
|
||||
ldr r1, =CFG_GPSR0_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPSR1
|
||||
ldr r1, =CFG_GPSR1_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPSR2
|
||||
ldr r1, =CFG_GPSR2_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPCR0
|
||||
ldr r1, =CFG_GPCR0_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPCR1
|
||||
ldr r1, =CFG_GPCR1_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPCR2
|
||||
ldr r1, =CFG_GPCR2_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPDR0
|
||||
ldr r1, =CFG_GPDR0_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPDR1
|
||||
ldr r1, =CFG_GPDR1_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPDR2
|
||||
ldr r1, =CFG_GPDR2_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GAFR0_L
|
||||
ldr r1, =CFG_GAFR0_L_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GAFR0_U
|
||||
ldr r1, =CFG_GAFR0_U_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GAFR1_L
|
||||
ldr r1, =CFG_GAFR1_L_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GAFR1_U
|
||||
ldr r1, =CFG_GAFR1_U_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GAFR2_L
|
||||
ldr r1, =CFG_GAFR2_L_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GAFR2_U
|
||||
ldr r1, =CFG_GAFR2_U_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =PSSR /* enable GPIO pins */
|
||||
ldr r1, =CFG_PSSR_VAL
|
||||
str r1, [r0]
|
||||
|
||||
/* ldr r3, =MSC1 / low - bank 2 Lubbock Registers / SRAM */
|
||||
/* ldr r2, =CFG_MSC1_VAL / high - bank 3 Ethernet Controller */
|
||||
/* str r2, [r3] / need to set MSC1 before trying to write to the HEX LEDs */
|
||||
/* ldr r2, [r3] / need to read it back to make sure the value latches (see MSC section of manual) */
|
||||
/* */
|
||||
/* ldr r1, =LED_BLANK */
|
||||
/* mov r0, #0xFF */
|
||||
/* str r0, [r1] / turn on hex leds */
|
||||
/* */
|
||||
/*loop: */
|
||||
/* */
|
||||
/* ldr r0, =0xB0070001 */
|
||||
/* ldr r1, =_LED */
|
||||
/* str r0, [r1] / hex display */
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Enable memory interface */
|
||||
/* */
|
||||
/* The sequence below is based on the recommended init steps */
|
||||
/* detailed in the Intel PXA250 Operating Systems Developers Guide, */
|
||||
/* Chapter 10. */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Step 1: Wait for at least 200 microsedonds to allow internal */
|
||||
/* clocks to settle. Only necessary after hard reset... */
|
||||
/* FIXME: can be optimized later */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
ldr r3, =OSCR /* reset the OS Timer Count to zero */
|
||||
mov r2, #0
|
||||
str r2, [r3]
|
||||
ldr r4, =0x300 /* really 0x2E1 is about 200usec, */
|
||||
/* so 0x300 should be plenty */
|
||||
1:
|
||||
ldr r2, [r3]
|
||||
cmp r4, r2
|
||||
bgt 1b
|
||||
|
||||
mem_init:
|
||||
|
||||
ldr r1, =MEMC_BASE /* get memory controller base addr. */
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Step 2a: Initialize Asynchronous static memory controller */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* MSC registers: timing, bus width, mem type */
|
||||
|
||||
/* MSC0: nCS(0,1) */
|
||||
ldr r2, =CFG_MSC0_VAL
|
||||
str r2, [r1, #MSC0_OFFSET]
|
||||
ldr r2, [r1, #MSC0_OFFSET] /* read back to ensure */
|
||||
/* that data latches */
|
||||
/* MSC1: nCS(2,3) */
|
||||
ldr r2, =CFG_MSC1_VAL
|
||||
str r2, [r1, #MSC1_OFFSET]
|
||||
ldr r2, [r1, #MSC1_OFFSET]
|
||||
|
||||
/* MSC2: nCS(4,5) */
|
||||
ldr r2, =CFG_MSC2_VAL
|
||||
str r2, [r1, #MSC2_OFFSET]
|
||||
ldr r2, [r1, #MSC2_OFFSET]
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Step 2b: Initialize Card Interface */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* MECR: Memory Expansion Card Register */
|
||||
ldr r2, =CFG_MECR_VAL
|
||||
str r2, [r1, #MECR_OFFSET]
|
||||
ldr r2, [r1, #MECR_OFFSET]
|
||||
|
||||
/* MCMEM0: Card Interface slot 0 timing */
|
||||
ldr r2, =CFG_MCMEM0_VAL
|
||||
str r2, [r1, #MCMEM0_OFFSET]
|
||||
ldr r2, [r1, #MCMEM0_OFFSET]
|
||||
|
||||
/* MCMEM1: Card Interface slot 1 timing */
|
||||
ldr r2, =CFG_MCMEM1_VAL
|
||||
str r2, [r1, #MCMEM1_OFFSET]
|
||||
ldr r2, [r1, #MCMEM1_OFFSET]
|
||||
|
||||
/* MCATT0: Card Interface Attribute Space Timing, slot 0 */
|
||||
ldr r2, =CFG_MCATT0_VAL
|
||||
str r2, [r1, #MCATT0_OFFSET]
|
||||
ldr r2, [r1, #MCATT0_OFFSET]
|
||||
|
||||
/* MCATT1: Card Interface Attribute Space Timing, slot 1 */
|
||||
ldr r2, =CFG_MCATT1_VAL
|
||||
str r2, [r1, #MCATT1_OFFSET]
|
||||
ldr r2, [r1, #MCATT1_OFFSET]
|
||||
|
||||
/* MCIO0: Card Interface I/O Space Timing, slot 0 */
|
||||
ldr r2, =CFG_MCIO0_VAL
|
||||
str r2, [r1, #MCIO0_OFFSET]
|
||||
ldr r2, [r1, #MCIO0_OFFSET]
|
||||
|
||||
/* MCIO1: Card Interface I/O Space Timing, slot 1 */
|
||||
ldr r2, =CFG_MCIO1_VAL
|
||||
str r2, [r1, #MCIO1_OFFSET]
|
||||
ldr r2, [r1, #MCIO1_OFFSET]
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Step 2c: Write FLYCNFG FIXME: what's that??? */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* test if we run from flash or RAM - RAM/BDI: don't setup RAM */
|
||||
adr r3, mem_init /* r0 <- current position of code */
|
||||
ldr r2, =mem_init
|
||||
cmp r3, r2 /* skip init if in place */
|
||||
beq initirqs
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Step 2d: Initialize Timing for Sync Memory (SDCLK0) */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Before accessing MDREFR we need a valid DRI field, so we set */
|
||||
/* this to power on defaults + DRI field. */
|
||||
|
||||
ldr r3, =CFG_MDREFR_VAL
|
||||
ldr r2, =0xFFF
|
||||
and r3, r3, r2
|
||||
ldr r4, =0x03ca4000
|
||||
orr r4, r4, r3
|
||||
|
||||
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
|
||||
ldr r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Step 3: Initialize Synchronous Static Memory (Flash/Peripherals) */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Initialize SXCNFG register. Assert the enable bits */
|
||||
|
||||
/* Write SXMRS to cause an MRS command to all enabled banks of */
|
||||
/* synchronous static memory. Note that SXLCR need not be written */
|
||||
/* at this time. */
|
||||
|
||||
/* FIXME: we use async mode for now */
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Step 4: Initialize SDRAM */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Step 4a: assert MDREFR:K?RUN and configure */
|
||||
/* MDREFR:K1DB2 and MDREFR:K2DB2 as desired. */
|
||||
|
||||
ldr r4, =CFG_MDREFR_VAL
|
||||
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
|
||||
ldr r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
/* Step 4b: de-assert MDREFR:SLFRSH. */
|
||||
|
||||
bic r4, r4, #(MDREFR_SLFRSH)
|
||||
|
||||
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
|
||||
ldr r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
|
||||
/* Step 4c: assert MDREFR:E1PIN and E0PIO */
|
||||
|
||||
orr r4, r4, #(MDREFR_E1PIN|MDREFR_E0PIN)
|
||||
|
||||
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
|
||||
ldr r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
|
||||
/* Step 4d: write MDCNFG with MDCNFG:DEx deasserted (set to 0), to */
|
||||
/* configure but not enable each SDRAM partition pair. */
|
||||
|
||||
ldr r4, =CFG_MDCNFG_VAL
|
||||
bic r4, r4, #(MDCNFG_DE0|MDCNFG_DE1)
|
||||
|
||||
str r4, [r1, #MDCNFG_OFFSET] /* write back MDCNFG */
|
||||
ldr r4, [r1, #MDCNFG_OFFSET]
|
||||
|
||||
|
||||
/* Step 4e: Wait for the clock to the SDRAMs to stabilize, */
|
||||
/* 100..200 µsec. */
|
||||
|
||||
ldr r3, =OSCR /* reset the OS Timer Count to zero */
|
||||
mov r2, #0
|
||||
str r2, [r3]
|
||||
ldr r4, =0x300 /* really 0x2E1 is about 200usec, */
|
||||
/* so 0x300 should be plenty */
|
||||
1:
|
||||
ldr r2, [r3]
|
||||
cmp r4, r2
|
||||
bgt 1b
|
||||
|
||||
|
||||
/* Step 4f: Trigger a number (usually 8) refresh cycles by */
|
||||
/* attempting non-burst read or write accesses to disabled */
|
||||
/* SDRAM, as commonly specified in the power up sequence */
|
||||
/* documented in SDRAM data sheets. The address(es) used */
|
||||
/* for this purpose must not be cacheable. */
|
||||
|
||||
/* There should 9 writes, since the first write doesn't */
|
||||
/* trigger a refresh cycle on PXA250. See Intel PXA250 and */
|
||||
/* PXA210 Processors Specification Update, */
|
||||
/* Jan 2003, Errata #116, page 30. */
|
||||
|
||||
|
||||
ldr r3, =CFG_DRAM_BASE
|
||||
str r2, [r3]
|
||||
str r2, [r3]
|
||||
str r2, [r3]
|
||||
str r2, [r3]
|
||||
str r2, [r3]
|
||||
str r2, [r3]
|
||||
str r2, [r3]
|
||||
str r2, [r3]
|
||||
str r2, [r3]
|
||||
|
||||
/* Step 4g: Write MDCNFG with enable bits asserted */
|
||||
/* (MDCNFG:DEx set to 1). */
|
||||
|
||||
ldr r3, [r1, #MDCNFG_OFFSET]
|
||||
orr r3, r3, #(MDCNFG_DE0|MDCNFG_DE1)
|
||||
str r3, [r1, #MDCNFG_OFFSET]
|
||||
|
||||
/* Step 4h: Write MDMRS. */
|
||||
|
||||
ldr r2, =CFG_MDMRS_VAL
|
||||
str r2, [r1, #MDMRS_OFFSET]
|
||||
|
||||
|
||||
/* We are finished with Intel's memory controller initialisation */
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Disable (mask) all interrupts at interrupt controller */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
initirqs:
|
||||
|
||||
mov r1, #0 /* clear int. level register (IRQ, not FIQ) */
|
||||
ldr r2, =ICLR
|
||||
str r1, [r2]
|
||||
|
||||
ldr r2, =ICMR /* mask all interrupts at the controller */
|
||||
str r1, [r2]
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Clock initialisation */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
initclks:
|
||||
|
||||
/* Disable the peripheral clocks, and set the core clock frequency */
|
||||
/* (hard-coding at 398.12MHz for now). */
|
||||
|
||||
/* Turn Off ALL on-chip peripheral clocks for re-configuration */
|
||||
/* Note: See label 'ENABLECLKS' for the re-enabling */
|
||||
ldr r1, =CKEN
|
||||
mov r2, #0
|
||||
str r2, [r1]
|
||||
|
||||
|
||||
/* default value in case no valid rotary switch setting is found */
|
||||
ldr r2, =(CCCR_L27|CCCR_M2|CCCR_N10) /* DEFAULT: {200/200/100} */
|
||||
|
||||
/* ... and write the core clock config register */
|
||||
ldr r1, =CCCR
|
||||
str r2, [r1]
|
||||
|
||||
/* enable the 32Khz oscillator for RTC and PowerManager */
|
||||
/*
|
||||
ldr r1, =OSCC
|
||||
mov r2, #OSCC_OON
|
||||
str r2, [r1]
|
||||
*/
|
||||
/* NOTE: spin here until OSCC.OOK get set, meaning the PLL */
|
||||
/* has settled. */
|
||||
60:
|
||||
ldr r2, [r1]
|
||||
ands r2, r2, #1
|
||||
beq 60b
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Save SDRAM size */
|
||||
ldr r1, =DRAM_SIZE
|
||||
str r8, [r1]
|
||||
|
||||
/* Interrupt init: Mask all interrupts */
|
||||
ldr r0, =ICMR /* enable no sources */
|
||||
mov r1, #0
|
||||
str r1, [r0]
|
||||
|
||||
/* FIXME */
|
||||
|
||||
#ifndef DEBUG
|
||||
/*Disable software and data breakpoints */
|
||||
mov r0,#0
|
||||
mcr p15,0,r0,c14,c8,0 /* ibcr0 */
|
||||
mcr p15,0,r0,c14,c9,0 /* ibcr1 */
|
||||
mcr p15,0,r0,c14,c4,0 /* dbcon */
|
||||
|
||||
/*Enable all debug functionality */
|
||||
mov r0,#0x80000000
|
||||
mcr p14,0,r0,c10,c0,0 /* dcsr */
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* End memsetup */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
endmemsetup:
|
||||
|
||||
mov pc, lr
|
||||
|
||||
55
board/logodl/u-boot.lds
Normal file
55
board/logodl/u-boot.lds
Normal file
@@ -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/pxa/start.o (.text)
|
||||
*(.text)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(.rodata) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : { *(.data) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.got : { *(.got) }
|
||||
|
||||
armboot_end_data = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
bss_start = .;
|
||||
.bss : { *(.bss) }
|
||||
bss_end = .;
|
||||
|
||||
armboot_end = .;
|
||||
}
|
||||
@@ -50,6 +50,14 @@ int board_init (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_post_init(void)
|
||||
{
|
||||
setenv("stdout", "serial");
|
||||
setenv("stderr", "serial");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int dram_init (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
* (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com
|
||||
* Added support for the 16M dram simm on the 8260ads boards
|
||||
*
|
||||
* (C) Copyright 2003 Arabella Software Ltd.
|
||||
* Yuli Barcohen <yuli@arabellasw.com>
|
||||
* Added support for SDRAM DIMMs SPD EEPROM, MII, Ethernet PHY init.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
|
||||
@@ -45,7 +45,11 @@ extern int gunzip (void *, int, unsigned char *, int *);
|
||||
extern int mem_test(unsigned long start, unsigned long ramsize, int quiet);
|
||||
|
||||
#define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */
|
||||
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
|
||||
#define IMAGE_SIZE 0x80000
|
||||
#elif defined(CONFIG_VCMA9)
|
||||
#define IMAGE_SIZE 0x40000 /* ugly, but it works for now */
|
||||
#endif
|
||||
|
||||
extern flash_info_t flash_info[]; /* info for FLASH chips */
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
|
||||
# optionally with a ramdisk at 3080'0000
|
||||
#
|
||||
# we load ourself to 33F0'0000
|
||||
# we load ourself to 33F8'0000
|
||||
#
|
||||
# download area is 3300'0000
|
||||
#
|
||||
|
||||
|
||||
TEXT_BASE = 0x33F00000
|
||||
TEXT_BASE = 0x33F80000
|
||||
|
||||
@@ -54,8 +54,10 @@
|
||||
|
||||
/* BANK0CON */
|
||||
#define B0_Tacs 0x0 /* 0clk */
|
||||
#define B0_Tcos 0x0 /* 0clk */
|
||||
#define B0_Tacc 0x5 /* 8clk */
|
||||
#define B0_Tcos 0x1 /* 1clk */
|
||||
/*#define B0_Tcos 0x0 0clk */
|
||||
#define B0_Tacc 0x7 /* 14clk */
|
||||
/*#define B0_Tacc 0x5 8clk */
|
||||
#define B0_Tcoh 0x0 /* 0clk */
|
||||
#define B0_Tah 0x0 /* 0clk */
|
||||
#define B0_Tacp 0x0 /* page mode is not used */
|
||||
@@ -63,8 +65,10 @@
|
||||
|
||||
/* BANK1CON */
|
||||
#define B1_Tacs 0x0 /* 0clk */
|
||||
#define B1_Tcos 0x0 /* 0clk */
|
||||
#define B1_Tacc 0x5 /* 8clk */
|
||||
#define B1_Tcos 0x1 /* 1clk */
|
||||
/*#define B1_Tcos 0x0 0clk */
|
||||
#define B1_Tacc 0x7 /* 14clk */
|
||||
/*#define B1_Tacc 0x5 8clk */
|
||||
#define B1_Tcoh 0x0 /* 0clk */
|
||||
#define B1_Tah 0x0 /* 0clk */
|
||||
#define B1_Tacp 0x0 /* page mode is not used */
|
||||
|
||||
@@ -72,41 +72,46 @@ static inline void delay(unsigned long loops)
|
||||
int board_init(void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
/* to reduce PLL lock time, adjust the LOCKTIME register */
|
||||
rLOCKTIME = 0xFFFFFF;
|
||||
clk_power->LOCKTIME = 0xFFFFFF;
|
||||
|
||||
/* configure MPLL */
|
||||
rMPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
|
||||
clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
|
||||
|
||||
/* some delay between MPLL and UPLL */
|
||||
delay (4000);
|
||||
|
||||
/* configure UPLL */
|
||||
rUPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
|
||||
clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
|
||||
|
||||
/* some delay between MPLL and UPLL */
|
||||
delay (8000);
|
||||
|
||||
/* set up the I/O ports */
|
||||
rGPACON = 0x007FFFFF;
|
||||
rGPBCON = 0x002AAAAA;
|
||||
rGPBUP = 0x000002BF;
|
||||
rGPCCON = 0xAAAAAAAA;
|
||||
rGPCUP = 0x0000FFFF;
|
||||
rGPDCON = 0xAAAAAAAA;
|
||||
rGPDUP = 0x0000FFFF;
|
||||
rGPECON = 0xAAAAAAAA;
|
||||
rGPEUP = 0x000037F7;
|
||||
rGPFCON = 0x00000000;
|
||||
rGPFUP = 0x00000000;
|
||||
rGPGCON = 0xFFEAFF5A;
|
||||
rGPGUP = 0x0000F0DC;
|
||||
rGPHCON = 0x0028AAAA;
|
||||
rGPHUP = 0x00000656;
|
||||
gpio->GPACON = 0x007FFFFF;
|
||||
gpio->GPBCON = 0x002AAAAA;
|
||||
gpio->GPBUP = 0x000002BF;
|
||||
gpio->GPCCON = 0xAAAAAAAA;
|
||||
gpio->GPCUP = 0x0000FFFF;
|
||||
gpio->GPDCON = 0xAAAAAAAA;
|
||||
gpio->GPDUP = 0x0000FFFF;
|
||||
gpio->GPECON = 0xAAAAAAAA;
|
||||
gpio->GPEUP = 0x000037F7;
|
||||
gpio->GPFCON = 0x00000000;
|
||||
gpio->GPFUP = 0x00000000;
|
||||
gpio->GPGCON = 0xFFEAFF5A;
|
||||
gpio->GPGUP = 0x0000F0DC;
|
||||
gpio->GPHCON = 0x0028AAAA;
|
||||
gpio->GPHUP = 0x00000656;
|
||||
|
||||
/* setup correct IRQ modes for NIC */
|
||||
rEXTINT2 = (rEXTINT2 & ~(7<<8)) | (4<<8); /* rising edge mode */
|
||||
gpio->EXTINT2 = (gpio->EXTINT2 & ~(7<<8)) | (4<<8); /* rising edge mode */
|
||||
|
||||
/* select USB port 2 to be host or device (fix to host for now) */
|
||||
gpio->MISCCR |= 0x08;
|
||||
|
||||
/* init serial */
|
||||
gd->baudrate = CONFIG_BAUDRATE;
|
||||
@@ -135,6 +140,50 @@ int dram_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NAND flash initialization.
|
||||
*/
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
|
||||
extern void
|
||||
nand_probe(ulong physadr);
|
||||
|
||||
|
||||
static inline void NF_Reset(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
NF_SetCE(NFCE_LOW);
|
||||
NF_Cmd(0xFF); /* reset command */
|
||||
for(i = 0; i < 10; i++); /* tWB = 100ns. */
|
||||
NF_WaitRB(); /* wait 200~500us; */
|
||||
NF_SetCE(NFCE_HIGH);
|
||||
}
|
||||
|
||||
|
||||
static inline void NF_Init(void)
|
||||
{
|
||||
#define TACLS 0
|
||||
#define TWRPH0 3
|
||||
#define TWRPH1 0
|
||||
NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
|
||||
//nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
|
||||
// 1 1 1 1, 1 xxx, r xxx, r xxx
|
||||
// En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1
|
||||
|
||||
NF_Reset();
|
||||
}
|
||||
|
||||
void
|
||||
nand_init(void)
|
||||
{
|
||||
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
|
||||
|
||||
NF_Init();
|
||||
printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
|
||||
nand_probe((ulong)nand);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get some Board/PLD Info
|
||||
*/
|
||||
@@ -195,12 +244,12 @@ int checkboard(void)
|
||||
puts ("### No HW ID - assuming VCMA9");
|
||||
} else {
|
||||
b->serial_name[5] = 0;
|
||||
printf ("%s-%d Rev %c SN: %s", b->serial_name, Get_Board_Config(),
|
||||
printf ("%s-%d PCB Rev %c SN: %s", b->serial_name, Get_Board_Config(),
|
||||
Get_Board_PCB(), &b->serial_name[6]);
|
||||
}
|
||||
} else {
|
||||
s[5] = 0;
|
||||
printf ("%s-%d Rev %c SN: %s", s, Get_Board_Config(), Get_Board_PCB(),
|
||||
printf ("%s-%d PCB Rev %c SN: %s", s, Get_Board_Config(), Get_Board_PCB(),
|
||||
&s[6]);
|
||||
}
|
||||
printf("\n");
|
||||
@@ -211,7 +260,7 @@ int checkboard(void)
|
||||
|
||||
void print_vcma9_rev(void)
|
||||
{
|
||||
printf("Board: VCMA9-%d Rev: %c (PLD Ver: %d, Rev: %d)\n",
|
||||
printf("Board: VCMA9-%d PCB Rev: %c (PLD Ver: %d, Rev: %d)\n",
|
||||
Get_Board_Config(), Get_Board_PCB(),
|
||||
Get_PLD_Version(), Get_PLD_Revision());
|
||||
}
|
||||
@@ -245,5 +294,3 @@ void print_vcma9_info(void)
|
||||
{
|
||||
print_vcma9_rev();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,11 +25,97 @@
|
||||
* Global routines used for VCMA9
|
||||
*****************************************************************************/
|
||||
|
||||
#include <s3c2410.h>
|
||||
|
||||
extern int mem_test(unsigned long start, unsigned long ramsize,int mode);
|
||||
|
||||
void print_vcma9_info(void);
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
|
||||
typedef enum {
|
||||
NFCE_LOW,
|
||||
NFCE_HIGH
|
||||
} NFCE_STATE;
|
||||
|
||||
static inline void NF_Conf(u16 conf)
|
||||
{
|
||||
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
|
||||
|
||||
nand->NFCONF = conf;
|
||||
}
|
||||
|
||||
static inline void NF_Cmd(u8 cmd)
|
||||
{
|
||||
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
|
||||
|
||||
nand->NFCMD = cmd;
|
||||
}
|
||||
|
||||
static inline void NF_CmdW(u8 cmd)
|
||||
{
|
||||
NF_Cmd(cmd);
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
static inline void NF_Addr(u8 addr)
|
||||
{
|
||||
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
|
||||
|
||||
nand->NFADDR = addr;
|
||||
}
|
||||
|
||||
static inline void NF_SetCE(NFCE_STATE s)
|
||||
{
|
||||
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
|
||||
|
||||
switch (s) {
|
||||
case NFCE_LOW:
|
||||
nand->NFCONF &= ~(1<<11);
|
||||
break;
|
||||
|
||||
case NFCE_HIGH:
|
||||
nand->NFCONF |= (1<<11);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void NF_WaitRB(void)
|
||||
{
|
||||
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
|
||||
|
||||
while (!(nand->NFSTAT & (1<<0)));
|
||||
}
|
||||
|
||||
static inline void NF_Write(u8 data)
|
||||
{
|
||||
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
|
||||
|
||||
nand->NFDATA = data;
|
||||
}
|
||||
|
||||
static inline u8 NF_Read(void)
|
||||
{
|
||||
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
|
||||
|
||||
return(nand->NFDATA);
|
||||
}
|
||||
|
||||
static inline void NF_Init_ECC(void)
|
||||
{
|
||||
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
|
||||
|
||||
nand->NFCONF |= (1<<12);
|
||||
}
|
||||
|
||||
static inline u32 NF_Read_ECC(void)
|
||||
{
|
||||
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
|
||||
|
||||
return(nand->NFECC);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define PLD_BASE_ADDRESS 0x2C000100
|
||||
#define PLD_ID_REG (PLD_BASE_ADDRESS + 0)
|
||||
@@ -39,5 +125,3 @@ void print_vcma9_info(void);
|
||||
#define PLD_GPCD_REG (PLD_BASE_ADDRESS + 4)
|
||||
#define PLD_BOARD_REG (PLD_BASE_ADDRESS + 5)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -46,33 +46,35 @@ extern int do_mdm_init; /* defined in common/main.c */
|
||||
int board_init (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
/* memory and cpu-speed are setup before relocation */
|
||||
/* change the clock to be 50 MHz 1:1:1 */
|
||||
rMPLLCON = 0x5c042;
|
||||
rCLKDIVN = 0;
|
||||
clk_power->MPLLCON = 0x5c042;
|
||||
clk_power->CLKDIVN = 0;
|
||||
/* set up the I/O ports */
|
||||
rPACON = 0x3ffff;
|
||||
rPBCON = 0xaaaaaaaa;
|
||||
rPBUP = 0xffff;
|
||||
rPECON = 0x0;
|
||||
rPEUP = 0x0;
|
||||
gpio->PACON = 0x3ffff;
|
||||
gpio->PBCON = 0xaaaaaaaa;
|
||||
gpio->PBUP = 0xffff;
|
||||
gpio->PECON = 0x0;
|
||||
gpio->PEUP = 0x0;
|
||||
#ifdef CONFIG_HWFLOW
|
||||
/*CTS[0] RTS[0] INPUT INPUT TXD[0] INPUT RXD[0] */
|
||||
/* 10, 10, 00, 00, 10, 00, 10 */
|
||||
rPFCON=0xa22;
|
||||
gpio->PFCON=0xa22;
|
||||
/* Disable pull-up on Rx, Tx, CTS and RTS pins */
|
||||
rPFUP=0x35;
|
||||
gpio->PFUP=0x35;
|
||||
#else
|
||||
/*INPUT INPUT INPUT INPUT TXD[0] INPUT RXD[0] */
|
||||
/* 00, 00, 00, 00, 10, 00, 10 */
|
||||
rPFCON = 0x22;
|
||||
gpio->PFCON = 0x22;
|
||||
/* Disable pull-up on Rx and Tx pins */
|
||||
rPFUP = 0x5;
|
||||
gpio->PFUP = 0x5;
|
||||
#endif /* CONFIG_HWFLOW */
|
||||
rPGCON = 0x0;
|
||||
rPGUP = 0x0;
|
||||
rOPENCR = 0x0;
|
||||
gpio->PGCON = 0x0;
|
||||
gpio->PGUP = 0x0;
|
||||
gpio->OPENCR = 0x0;
|
||||
|
||||
/* arch number of SAMSUNG-Board to MACH_TYPE_SMDK2400 */
|
||||
gd->bd->bi_arch_number = 145;
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
|
||||
# optionally with a ramdisk at 3080'0000
|
||||
#
|
||||
# we load ourself to 33F0'0000
|
||||
# we load ourself to 33F8'0000
|
||||
#
|
||||
# download area is 3300'0000
|
||||
#
|
||||
|
||||
|
||||
TEXT_BASE = 0x33F00000
|
||||
TEXT_BASE = 0x33F80000
|
||||
|
||||
@@ -68,38 +68,40 @@ static inline void delay (unsigned long loops)
|
||||
int board_init (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
/* to reduce PLL lock time, adjust the LOCKTIME register */
|
||||
rLOCKTIME = 0xFFFFFF;
|
||||
clk_power->LOCKTIME = 0xFFFFFF;
|
||||
|
||||
/* configure MPLL */
|
||||
rMPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
|
||||
clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
|
||||
|
||||
/* some delay between MPLL and UPLL */
|
||||
delay (4000);
|
||||
|
||||
/* configure UPLL */
|
||||
rUPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
|
||||
clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
|
||||
|
||||
/* some delay between MPLL and UPLL */
|
||||
delay (8000);
|
||||
|
||||
/* set up the I/O ports */
|
||||
rGPACON = 0x007FFFFF;
|
||||
rGPBCON = 0x00044555;
|
||||
rGPBUP = 0x000007FF;
|
||||
rGPCCON = 0xAAAAAAAA;
|
||||
rGPCUP = 0x0000FFFF;
|
||||
rGPDCON = 0xAAAAAAAA;
|
||||
rGPDUP = 0x0000FFFF;
|
||||
rGPECON = 0xAAAAAAAA;
|
||||
rGPEUP = 0x0000FFFF;
|
||||
rGPFCON = 0x000055AA;
|
||||
rGPFUP = 0x000000FF;
|
||||
rGPGCON = 0xFF95FFBA;
|
||||
rGPGUP = 0x0000FFFF;
|
||||
rGPHCON = 0x002AFAAA;
|
||||
rGPHUP = 0x000007FF;
|
||||
gpio->GPACON = 0x007FFFFF;
|
||||
gpio->GPBCON = 0x00044555;
|
||||
gpio->GPBUP = 0x000007FF;
|
||||
gpio->GPCCON = 0xAAAAAAAA;
|
||||
gpio->GPCUP = 0x0000FFFF;
|
||||
gpio->GPDCON = 0xAAAAAAAA;
|
||||
gpio->GPDUP = 0x0000FFFF;
|
||||
gpio->GPECON = 0xAAAAAAAA;
|
||||
gpio->GPEUP = 0x0000FFFF;
|
||||
gpio->GPFCON = 0x000055AA;
|
||||
gpio->GPFUP = 0x000000FF;
|
||||
gpio->GPGCON = 0xFF95FFBA;
|
||||
gpio->GPGUP = 0x0000FFFF;
|
||||
gpio->GPHCON = 0x002AFAAA;
|
||||
gpio->GPHUP = 0x000007FF;
|
||||
|
||||
/* arch number of SMDK2410-Board */
|
||||
gd->bd->bi_arch_number = 193;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc8xx.h>
|
||||
#include <environment.h>
|
||||
|
||||
#ifndef CFG_ENV_ADDR
|
||||
#define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
|
||||
@@ -103,17 +104,41 @@ unsigned long flash_init (void)
|
||||
|
||||
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
|
||||
/* monitor protection ON by default */
|
||||
debug ("Protect monitor: %08lx ... %08lx\n",
|
||||
(ulong)CFG_MONITOR_BASE,
|
||||
(ulong)CFG_MONITOR_BASE + monitor_flash_len - 1);
|
||||
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_MONITOR_BASE,
|
||||
CFG_MONITOR_BASE+monitor_flash_len-1,
|
||||
CFG_MONITOR_BASE + monitor_flash_len - 1,
|
||||
&flash_info[0]);
|
||||
#endif
|
||||
|
||||
#ifdef CFG_ENV_IS_IN_FLASH
|
||||
/* ENV protection ON by default */
|
||||
debug ("Protect %senvironment: %08lx ... %08lx\n",
|
||||
# ifdef CFG_ENV_ADDR_REDUND
|
||||
"primary ",
|
||||
# else
|
||||
"",
|
||||
# endif
|
||||
(ulong)CFG_ENV_ADDR,
|
||||
(ulong)CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1);
|
||||
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR+CFG_ENV_SIZE-1,
|
||||
CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
|
||||
&flash_info[0]);
|
||||
#endif
|
||||
|
||||
#ifdef CFG_ENV_ADDR_REDUND
|
||||
debug ("Protect redundand environment: %08lx ... %08lx\n",
|
||||
(ulong)CFG_ENV_ADDR_REDUND,
|
||||
(ulong)CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - 1);
|
||||
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR_REDUND,
|
||||
CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - 1,
|
||||
&flash_info[0]);
|
||||
#endif
|
||||
|
||||
@@ -181,6 +206,10 @@ void flash_print_info (flash_info_t *info)
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
#ifdef CONFIG_TQM8xxM /* mirror bit flash */
|
||||
case FLASH_AMLV128U: printf ("AM29LV128ML (128Mbit, uniform sector size)\n");
|
||||
break;
|
||||
# else /* ! TQM8xxM */
|
||||
case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
|
||||
break;
|
||||
case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
|
||||
@@ -197,6 +226,7 @@ void flash_print_info (flash_info_t *info)
|
||||
break;
|
||||
case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
|
||||
break;
|
||||
#endif /* TQM8xxM */
|
||||
default: printf ("Unknown Chip Type\n");
|
||||
break;
|
||||
}
|
||||
@@ -262,6 +292,25 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
|
||||
debug ("Device ID @ 0x%08lx: 0x%08lx\n", (ulong)(&addr[1]), value);
|
||||
|
||||
switch (value) {
|
||||
#ifdef CONFIG_TQM8xxM /* mirror bit flash */
|
||||
case AMD_ID_MIRROR:
|
||||
switch(addr[14]) {
|
||||
case AMD_ID_LV128U_2:
|
||||
if (addr[15] != AMD_ID_LV128U_3) {
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
}
|
||||
else {
|
||||
info->flash_id += FLASH_AMLV128U;
|
||||
info->sector_count = 256;
|
||||
info->size = 0x02000000;
|
||||
}
|
||||
break; /* => 32 MB */
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
# else /* ! TQM8xxM */
|
||||
case AMD_ID_LV400T:
|
||||
info->flash_id += FLASH_AM400T;
|
||||
info->sector_count = 11;
|
||||
@@ -297,6 +346,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
|
||||
info->sector_count = 35;
|
||||
info->size = 0x00400000;
|
||||
break; /* => 4 MB */
|
||||
|
||||
case AMD_ID_LV320T:
|
||||
info->flash_id += FLASH_AM320T;
|
||||
info->sector_count = 71;
|
||||
@@ -308,12 +358,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00800000;
|
||||
break; /* => 8 MB */
|
||||
case AMD_ID_DL640:
|
||||
debug ("## oops - same ID used for AM29LV128ML/H mirror bit flash ???\n");
|
||||
info->flash_id += FLASH_AMDL640;
|
||||
info->sector_count = 142;
|
||||
info->size = 0x00800000;
|
||||
break;
|
||||
#endif /* TQM8xxM */
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
return (0); /* => no or unknown flash */
|
||||
@@ -321,6 +366,19 @@ debug ("## oops - same ID used for AM29LV128ML/H mirror bit flash ???\n");
|
||||
|
||||
/* set up sector start address table */
|
||||
switch (value) {
|
||||
#ifdef CONFIG_TQM8xxM /* mirror bit flash */
|
||||
case AMD_ID_MIRROR:
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
/* only known types here - no default */
|
||||
case FLASH_AMLV128U:
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
info->start[i] = base;
|
||||
base += 0x20000;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
# else /* ! TQM8xxM */
|
||||
case AMD_ID_LV400B:
|
||||
case AMD_ID_LV800B:
|
||||
case AMD_ID_LV160B:
|
||||
@@ -369,6 +427,7 @@ debug ("## oops - same ID used for AM29LV128ML/H mirror bit flash ???\n");
|
||||
: 2 * ( 8 << 10);
|
||||
}
|
||||
break;
|
||||
#endif /* TQM8xxM */
|
||||
default:
|
||||
return (0);
|
||||
break;
|
||||
|
||||
@@ -66,7 +66,7 @@ SECTIONS
|
||||
lib_ppc/cache.o (.text)
|
||||
lib_ppc/time.o (.text)
|
||||
|
||||
. = env_offset;
|
||||
. = DEFINED(env_offset) ? env_offset : .;
|
||||
common/environment.o (.ppcenv)
|
||||
|
||||
*(.text)
|
||||
|
||||
@@ -71,37 +71,39 @@ int board_init ()
|
||||
extern int vfd_init_clocks(void);
|
||||
#endif
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
/* memory and cpu-speed are setup before relocation */
|
||||
#ifdef CONFIG_TRAB_50MHZ
|
||||
/* change the clock to be 50 MHz 1:1:1 */
|
||||
/* MDIV:0x5c PDIV:4 SDIV:2 */
|
||||
rMPLLCON = 0x5c042;
|
||||
rCLKDIVN = 0;
|
||||
clk_power->MPLLCON = 0x5c042;
|
||||
clk_power->CLKDIVN = 0;
|
||||
#else
|
||||
/* change the clock to be 133 MHz 1:2:4 */
|
||||
/* MDIV:0x7d PDIV:4 SDIV:1 */
|
||||
rMPLLCON = 0x7d041;
|
||||
rCLKDIVN = 3;
|
||||
clk_power->MPLLCON = 0x7d041;
|
||||
clk_power->CLKDIVN = 3;
|
||||
#endif
|
||||
|
||||
/* set up the I/O ports */
|
||||
rPACON = 0x3ffff;
|
||||
rPBCON = 0xaaaaaaaa;
|
||||
rPBUP = 0xffff;
|
||||
gpio->PACON = 0x3ffff;
|
||||
gpio->PBCON = 0xaaaaaaaa;
|
||||
gpio->PBUP = 0xffff;
|
||||
/* INPUT nCTS0 nRTS0 TXD[1] TXD[0] RXD[1] RXD[0] */
|
||||
/* 00, 10, 10, 10, 10, 10, 10 */
|
||||
rPFCON = (2<<0) | (2<<2) | (2<<4) | (2<<6) | (2<<8) | (2<<10);
|
||||
gpio->PFCON = (2<<0) | (2<<2) | (2<<4) | (2<<6) | (2<<8) | (2<<10);
|
||||
#ifdef CONFIG_HWFLOW
|
||||
/* do not pull up RXD0, RXD1, TXD0, TXD1, CTS0, RTS0 */
|
||||
rPFUP = (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5);
|
||||
gpio->PFUP = (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5);
|
||||
#else
|
||||
/* do not pull up RXD0, RXD1, TXD0, TXD1 */
|
||||
rPFUP = (1<<0) | (1<<1) | (1<<2) | (1<<3);
|
||||
gpio->PFUP = (1<<0) | (1<<1) | (1<<2) | (1<<3);
|
||||
#endif
|
||||
rPGCON = 0x0;
|
||||
rPGUP = 0x0;
|
||||
rOPENCR= 0x0;
|
||||
gpio->PGCON = 0x0;
|
||||
gpio->PGUP = 0x0;
|
||||
gpio->OPENCR= 0x0;
|
||||
|
||||
/* arch number of SAMSUNG-Board */
|
||||
/* MACH_TYPE_SMDK2400 */
|
||||
@@ -112,8 +114,8 @@ int board_init ()
|
||||
gd->bd->bi_boot_params = 0x0c000100;
|
||||
|
||||
/* Make sure both buzzers are turned off */
|
||||
rPDCON |= 0x5400;
|
||||
rPDDAT &= ~0xE0;
|
||||
gpio->PDCON |= 0x5400;
|
||||
gpio->PDDAT &= ~0xE0;
|
||||
|
||||
#ifdef CONFIG_VFD
|
||||
vfd_init_clocks();
|
||||
@@ -305,57 +307,73 @@ static int key_pressed(void)
|
||||
|
||||
#ifdef CFG_BRIGHTNESS
|
||||
|
||||
#define SET_CS_TOUCH (rPDDAT &= 0x5FF)
|
||||
#define CLR_CS_TOUCH (rPDDAT |= 0x200)
|
||||
static inline void SET_CS_TOUCH(void)
|
||||
{
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
gpio->PDDAT &= 0x5FF;
|
||||
}
|
||||
|
||||
static inline void CLR_CS_TOUCH(void)
|
||||
{
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
gpio->PDDAT |= 0x200;
|
||||
}
|
||||
|
||||
static void spi_init(void)
|
||||
{
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
|
||||
int i;
|
||||
|
||||
/* Configure I/O ports. */
|
||||
rPDCON = (rPDCON & 0xF3FFFF) | 0x040000;
|
||||
rPGCON = (rPGCON & 0x0F3FFF) | 0x008000;
|
||||
rPGCON = (rPGCON & 0x0CFFFF) | 0x020000;
|
||||
rPGCON = (rPGCON & 0x03FFFF) | 0x080000;
|
||||
gpio->PDCON = (gpio->PDCON & 0xF3FFFF) | 0x040000;
|
||||
gpio->PGCON = (gpio->PGCON & 0x0F3FFF) | 0x008000;
|
||||
gpio->PGCON = (gpio->PGCON & 0x0CFFFF) | 0x020000;
|
||||
gpio->PGCON = (gpio->PGCON & 0x03FFFF) | 0x080000;
|
||||
|
||||
CLR_CS_TOUCH;
|
||||
CLR_CS_TOUCH();
|
||||
|
||||
rSPPRE = 0x1F; /* Baudrate ca. 514kHz */
|
||||
rSPPIN = 0x01; /* SPI-MOSI holds Level after last bit */
|
||||
rSPCON = 0x1A; /* Polling, Prescaler, Master, CPOL=0, CPHA=1 */
|
||||
spi->ch[0].SPPRE = 0x1F; /* Baudrate ca. 514kHz */
|
||||
spi->ch[0].SPPIN = 0x01; /* SPI-MOSI holds Level after last bit */
|
||||
spi->ch[0].SPCON = 0x1A; /* Polling, Prescaler, Master, CPOL=0, CPHA=1 */
|
||||
|
||||
/* Dummy byte ensures clock to be low. */
|
||||
for (i = 0; i < 10; i++) {
|
||||
rSPTDAT = 0xFF;
|
||||
spi->ch[0].SPTDAT = 0xFF;
|
||||
}
|
||||
wait_transmit_done();
|
||||
}
|
||||
|
||||
static void wait_transmit_done(void)
|
||||
{
|
||||
while (!(rSPSTA & 0x01)); /* wait until transfer is done */
|
||||
S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
|
||||
|
||||
while (!(spi->ch[0].SPSTA & 0x01)); /* wait until transfer is done */
|
||||
}
|
||||
|
||||
static void tsc2000_write(unsigned int page, unsigned int reg,
|
||||
unsigned int data)
|
||||
{
|
||||
S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
|
||||
unsigned int command;
|
||||
|
||||
SET_CS_TOUCH;
|
||||
SET_CS_TOUCH();
|
||||
command = 0x0000;
|
||||
command |= (page << 11);
|
||||
command |= (reg << 5);
|
||||
|
||||
rSPTDAT = (command & 0xFF00) >> 8;
|
||||
spi->ch[0].SPTDAT = (command & 0xFF00) >> 8;
|
||||
wait_transmit_done();
|
||||
rSPTDAT = (command & 0x00FF);
|
||||
spi->ch[0].SPTDAT = (command & 0x00FF);
|
||||
wait_transmit_done();
|
||||
rSPTDAT = (data & 0xFF00) >> 8;
|
||||
spi->ch[0].SPTDAT = (data & 0xFF00) >> 8;
|
||||
wait_transmit_done();
|
||||
rSPTDAT = (data & 0x00FF);
|
||||
spi->ch[0].SPTDAT = (data & 0x00FF);
|
||||
wait_transmit_done();
|
||||
|
||||
CLR_CS_TOUCH;
|
||||
CLR_CS_TOUCH();
|
||||
}
|
||||
|
||||
static void tsc2000_set_brightness(void)
|
||||
|
||||
@@ -359,14 +359,17 @@ void transfer_pic(int display, unsigned char *adr, int height, int width)
|
||||
*/
|
||||
int vfd_init_clocks (void)
|
||||
{
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
|
||||
S3C24X0_LCD * const lcd = S3C24X0_GetBase_LCD();
|
||||
|
||||
/* try to determine display type from the value
|
||||
* defined by pull-ups
|
||||
*/
|
||||
rPCUP = (rPCUP & 0xFFF0); /* activate GPC0...GPC3 pullups */
|
||||
rPCCON = (rPCCON & 0xFFFFFF00); /* configure GPC0...GPC3 as inputs */
|
||||
gpio->PCUP = (gpio->PCUP & 0xFFF0); /* activate GPC0...GPC3 pullups */
|
||||
gpio->PCCON = (gpio->PCCON & 0xFFFFFF00); /* configure GPC0...GPC3 as inputs */
|
||||
udelay (10); /* allow signals to settle */
|
||||
vfd_board_id = (~rPCDAT) & 0x000F; /* read GPC0...GPC3 port pins */
|
||||
vfd_board_id = (~gpio->PCDAT) & 0x000F; /* read GPC0...GPC3 port pins */
|
||||
|
||||
VFD_DISABLE; /* activate blank for the vfd */
|
||||
|
||||
@@ -377,39 +380,39 @@ int vfd_init_clocks (void)
|
||||
/* If new board revision, then use PWM 3 as cpld-clock */
|
||||
/* Enable 500 Hz timer for fill level sensor to operate properly */
|
||||
/* Configure TOUT3 as functional pin, disable pull-up */
|
||||
rPDCON &= ~0x30000;
|
||||
rPDCON |= 0x20000;
|
||||
rPDUP |= (1 << 8);
|
||||
gpio->PDCON &= ~0x30000;
|
||||
gpio->PDCON |= 0x20000;
|
||||
gpio->PDUP |= (1 << 8);
|
||||
|
||||
/* Configure the prescaler */
|
||||
rTCFG0 &= ~0xff00;
|
||||
rTCFG0 |= 0x0f00;
|
||||
timers->TCFG0 &= ~0xff00;
|
||||
timers->TCFG0 |= 0x0f00;
|
||||
|
||||
/* Select MUX input (divider) for timer3 (1/16) */
|
||||
rTCFG1 &= ~0xf000;
|
||||
rTCFG1 |= 0x3000;
|
||||
timers->TCFG1 &= ~0xf000;
|
||||
timers->TCFG1 |= 0x3000;
|
||||
|
||||
/* Enable autoreload and set the counter and compare
|
||||
* registers to values for the 500 Hz clock
|
||||
* (for a given prescaler (15) and divider (16)):
|
||||
* counter = (66000000 / 500) >> 9;
|
||||
*/
|
||||
rTCNTB3 = 0x101;
|
||||
rTCMPB3 = 0x101 / 2;
|
||||
timers->ch[3].TCNTB = 0x101;
|
||||
timers->ch[3].TCMPB = 0x101 / 2;
|
||||
|
||||
/* Start timer */
|
||||
rTCON = (rTCON | UPDATE3 | RELOAD3) & ~INVERT3;
|
||||
rTCON = (rTCON | START3) & ~UPDATE3;
|
||||
timers->TCON = (timers->TCON | UPDATE3 | RELOAD3) & ~INVERT3;
|
||||
timers->TCON = (timers->TCON | START3) & ~UPDATE3;
|
||||
}
|
||||
#endif
|
||||
/* If old board revision, then use vm-signal as cpld-clock */
|
||||
rLCDCON2 = 0x00FFC000;
|
||||
rLCDCON3 = 0x0007FF00;
|
||||
rLCDCON4 = 0x00000000;
|
||||
rLCDCON5 = 0x00000400;
|
||||
rLCDCON1 = 0x00000B75;
|
||||
lcd->LCDCON2 = 0x00FFC000;
|
||||
lcd->LCDCON3 = 0x0007FF00;
|
||||
lcd->LCDCON4 = 0x00000000;
|
||||
lcd->LCDCON5 = 0x00000400;
|
||||
lcd->LCDCON1 = 0x00000B75;
|
||||
/* VM (GPD1) is used as clock for the CPLD */
|
||||
rPDCON = (rPDCON & 0xFFFFFFF3) | 0x00000008;
|
||||
gpio->PDCON = (gpio->PDCON & 0xFFFFFFF3) | 0x00000008;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -425,6 +428,8 @@ int vfd_init_clocks (void)
|
||||
*/
|
||||
int drv_vfd_init(void)
|
||||
{
|
||||
S3C24X0_LCD * const lcd = S3C24X0_GetBase_LCD();
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
char *tmp;
|
||||
ulong palette;
|
||||
static int vfd_init_done = 0;
|
||||
@@ -481,40 +486,40 @@ int drv_vfd_init(void)
|
||||
* see manual S3C2400
|
||||
*/
|
||||
/* Stopp LCD-Controller */
|
||||
rLCDCON1 = 0x00000000;
|
||||
lcd->LCDCON1 = 0x00000000;
|
||||
/* frame buffer startadr */
|
||||
rLCDSADDR1 = gd->fb_base >> 1;
|
||||
lcd->LCDSADDR1 = gd->fb_base >> 1;
|
||||
/* frame buffer endadr */
|
||||
rLCDSADDR2 = (gd->fb_base + FRAME_BUF_SIZE) >> 1;
|
||||
rLCDSADDR3 = ((256/4));
|
||||
rLCDCON2 = 0x000DC000;
|
||||
lcd->LCDSADDR2 = (gd->fb_base + FRAME_BUF_SIZE) >> 1;
|
||||
lcd->LCDSADDR3 = ((256/4));
|
||||
lcd->LCDCON2 = 0x000DC000;
|
||||
if(gd->vfd_type == VFD_TYPE_MN11236)
|
||||
rLCDCON2 = 37 << 14; /* MN11236: 38 lines */
|
||||
lcd->LCDCON2 = 37 << 14; /* MN11236: 38 lines */
|
||||
else
|
||||
rLCDCON2 = 55 << 14; /* T119C: 56 lines */
|
||||
rLCDCON3 = 0x0051000A;
|
||||
rLCDCON4 = 0x00000001;
|
||||
lcd->LCDCON2 = 55 << 14; /* T119C: 56 lines */
|
||||
lcd->LCDCON3 = 0x0051000A;
|
||||
lcd->LCDCON4 = 0x00000001;
|
||||
if (gd->vfd_type && vfd_inv_data)
|
||||
rLCDCON5 = 0x000004C0;
|
||||
lcd->LCDCON5 = 0x000004C0;
|
||||
else
|
||||
rLCDCON5 = 0x00000440;
|
||||
lcd->LCDCON5 = 0x00000440;
|
||||
|
||||
/* Port pins as LCD output */
|
||||
rPCCON = (rPCCON & 0xFFFFFF00)| 0x000000AA;
|
||||
rPDCON = (rPDCON & 0xFFFFFF03)| 0x000000A8;
|
||||
gpio->PCCON = (gpio->PCCON & 0xFFFFFF00)| 0x000000AA;
|
||||
gpio->PDCON = (gpio->PDCON & 0xFFFFFF03)| 0x000000A8;
|
||||
|
||||
/* Synchronize VFD enable with LCD controller to avoid flicker */
|
||||
rLCDCON1 = 0x00000B75; /* Start LCD-Controller */
|
||||
while((rLCDCON5 & 0x180000)!=0x100000); /* Wait for end of VSYNC */
|
||||
while((rLCDCON5 & 0x060000)!=0x040000); /* Wait for next HSYNC */
|
||||
while((rLCDCON5 & 0x060000)==0x040000);
|
||||
while((rLCDCON5 & 0x060000)!=0x000000);
|
||||
lcd->LCDCON1 = 0x00000B75; /* Start LCD-Controller */
|
||||
while((lcd->LCDCON5 & 0x180000)!=0x100000); /* Wait for end of VSYNC */
|
||||
while((lcd->LCDCON5 & 0x060000)!=0x040000); /* Wait for next HSYNC */
|
||||
while((lcd->LCDCON5 & 0x060000)==0x040000);
|
||||
while((lcd->LCDCON5 & 0x060000)!=0x000000);
|
||||
if(gd->vfd_type)
|
||||
VFD_ENABLE;
|
||||
|
||||
debug ("LCDSADDR1: %lX\n", rLCDSADDR1);
|
||||
debug ("LCDSADDR2: %lX\n", rLCDSADDR2);
|
||||
debug ("LCDSADDR3: %lX\n", rLCDSADDR3);
|
||||
debug ("LCDSADDR1: %lX\n", lcd->LCDSADDR1);
|
||||
debug ("LCDSADDR2: %lX\n", lcd->LCDSADDR2);
|
||||
debug ("LCDSADDR3: %lX\n", lcd->LCDSADDR3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -525,9 +530,11 @@ rLCDCON2 = 0x000DC000;
|
||||
*/
|
||||
void disable_vfd (void)
|
||||
{
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
VFD_DISABLE;
|
||||
rPDCON &= ~0xC;
|
||||
rPDUP &= ~0x2;
|
||||
gpio->PDCON &= ~0xC;
|
||||
gpio->PDUP &= ~0x2;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
@@ -31,10 +31,11 @@ COBJS = main.o altera.o bedbug.o \
|
||||
cmd_autoscript.o cmd_bedbug.o cmd_bmp.o cmd_boot.o \
|
||||
cmd_bootm.o cmd_cache.o cmd_console.o cmd_date.o \
|
||||
cmd_dcr.o cmd_diag.o cmd_doc.o cmd_nand.o cmd_dtt.o \
|
||||
cmd_eeprom.o cmd_elf.o cmd_fdc.o cmd_fdos.o cmd_flash.o \
|
||||
cmd_eeprom.o cmd_elf.o \
|
||||
cmd_fat.o cmd_fdc.o cmd_fdos.o cmd_flash.o \
|
||||
cmd_fpga.o cmd_i2c.o cmd_ide.o cmd_immap.o \
|
||||
cmd_jffs2.o cmd_log.o cmd_mem.o cmd_mii.o cmd_misc.o \
|
||||
cmd_net.o cmd_nvedit.o env_common.o \
|
||||
cmd_mmc.o cmd_net.o cmd_nvedit.o env_common.o \
|
||||
env_flash.o env_eeprom.o env_nvram.o env_nowhere.o \
|
||||
cmd_pci.o cmd_pcmcia.o cmd_portio.o \
|
||||
cmd_reginfo.o cmd_scsi.o cmd_vfd.o cmd_usb.o \
|
||||
|
||||
@@ -406,12 +406,13 @@ read_record (char *buf, ulong len)
|
||||
}
|
||||
|
||||
/* Check for the console hangup (if any different from serial) */
|
||||
|
||||
#ifdef CONFIG_PPC /* we don't have syscall_tbl anywhere else */
|
||||
if (syscall_tbl[SYSCALL_GETC] != serial_getc) {
|
||||
if (ctrlc()) {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* line too long - truncate */
|
||||
@@ -691,11 +692,24 @@ int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
|
||||
static ulong load_serial_bin (ulong offset)
|
||||
{
|
||||
int size;
|
||||
int size, i;
|
||||
char buf[32];
|
||||
|
||||
set_kerm_bin_mode ((ulong *) offset);
|
||||
size = k_recv ();
|
||||
|
||||
/*
|
||||
* Gather any trailing characters (for instance, the ^D which
|
||||
* is sent by 'cu' after sending a file), and give the
|
||||
* box some time (100 * 1 ms)
|
||||
*/
|
||||
for (i=0; i<100; ++i) {
|
||||
if (serial_tstc()) {
|
||||
(void) serial_getc();
|
||||
}
|
||||
udelay(1000);
|
||||
}
|
||||
|
||||
flush_cache (offset, size);
|
||||
|
||||
printf("## Total Size = 0x%08x = %d Bytes\n", size, size);
|
||||
|
||||
@@ -56,6 +56,10 @@
|
||||
#include <logbuff.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
#include <dataflash.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some systems (for example LWMON) have very short watchdog periods;
|
||||
* we must make sure to split long operations like memmove() or
|
||||
@@ -138,6 +142,11 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
printf ("## Booting image at %08lx ...\n", addr);
|
||||
|
||||
/* Copy header so we can blank CRC field for re-calculation */
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
if (addr_dataflash(addr)){
|
||||
read_dataflash(addr, sizeof(image_header_t), (char *)&header);
|
||||
} else
|
||||
#endif
|
||||
memmove (&header, (char *)addr, sizeof(image_header_t));
|
||||
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
@@ -178,6 +187,13 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
data = addr + sizeof(image_header_t);
|
||||
len = ntohl(hdr->ih_size);
|
||||
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
if (addr_dataflash(addr)){
|
||||
read_dataflash(data, len, (char *)CFG_LOAD_ADDR);
|
||||
data = CFG_LOAD_ADDR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (verify) {
|
||||
printf (" Verifying Checksum ... ");
|
||||
if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
|
||||
|
||||
@@ -327,6 +327,26 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn
|
||||
return rcode;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SPI
|
||||
int
|
||||
eeprom_probe (unsigned dev_addr, unsigned offset)
|
||||
{
|
||||
unsigned char chip;
|
||||
|
||||
/* Probe the chip address
|
||||
*/
|
||||
#if CFG_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X)
|
||||
chip = offset >> 8; /* block number */
|
||||
#else
|
||||
chip = offset >> 16; /* block number */
|
||||
#endif /* CFG_I2C_EEPROM_ADDR_LEN, CONFIG_SPI_X */
|
||||
|
||||
chip |= dev_addr; /* insert device address */
|
||||
|
||||
return (i2c_probe (chip));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Set default values
|
||||
*/
|
||||
|
||||
231
common/cmd_fat.c
Normal file
231
common/cmd_fat.c
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* (C) Copyright 2002
|
||||
* Richard Jones, rjones@nexus-tech.net
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Boot support
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <cmd_boot.h>
|
||||
#include <cmd_autoscript.h>
|
||||
#include <s_record.h>
|
||||
#include <net.h>
|
||||
#include <ata.h>
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_FAT)
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#include <fat.h>
|
||||
|
||||
extern block_dev_desc_t *ide_get_dev (int dev);
|
||||
|
||||
int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
long size;
|
||||
unsigned long offset;
|
||||
unsigned long count;
|
||||
|
||||
if (argc < 3) {
|
||||
printf ("usage:fatload <filename> <addr> [bytes]\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
offset = simple_strtoul (argv[2], NULL, 16);
|
||||
if (argc == 4)
|
||||
count = simple_strtoul (argv[3], NULL, 16);
|
||||
else
|
||||
count = 0;
|
||||
|
||||
size = file_fat_read (argv[1], (unsigned char *) offset, count);
|
||||
|
||||
printf ("%ld bytes read\n", size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
char *filename = "/";
|
||||
int ret;
|
||||
|
||||
if (argc == 2)
|
||||
ret = file_fat_ls (argv[1]);
|
||||
else
|
||||
ret = file_fat_ls (filename);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = 0;
|
||||
|
||||
printf ("FAT info: %d\n", file_fat_detectfs ());
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#ifdef NOT_IMPLEMENTED_YET
|
||||
/* find first device whose first partition is a DOS filesystem */
|
||||
int find_fat_partition (void)
|
||||
{
|
||||
int i, j;
|
||||
block_dev_desc_t *dev_desc;
|
||||
unsigned char *part_table;
|
||||
unsigned char buffer[ATA_BLOCKSIZE];
|
||||
|
||||
for (i = 0; i < CFG_IDE_MAXDEVICE; i++) {
|
||||
dev_desc = ide_get_dev (i);
|
||||
if (!dev_desc) {
|
||||
debug ("couldn't get ide device!\n");
|
||||
return (-1);
|
||||
}
|
||||
if (dev_desc->part_type == PART_TYPE_DOS) {
|
||||
if (dev_desc->
|
||||
block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) {
|
||||
debug ("can't perform block_read!\n");
|
||||
return (-1);
|
||||
}
|
||||
part_table = &buffer[0x1be]; /* start with partition #4 */
|
||||
for (j = 0; j < 4; j++) {
|
||||
if ((part_table[4] == 1 || /* 12-bit FAT */
|
||||
part_table[4] == 4 || /* 16-bit FAT */
|
||||
part_table[4] == 6) && /* > 32Meg part */
|
||||
part_table[0] == 0x80) { /* bootable? */
|
||||
curr_dev = i;
|
||||
part_offset = part_table[11];
|
||||
part_offset <<= 8;
|
||||
part_offset |= part_table[10];
|
||||
part_offset <<= 8;
|
||||
part_offset |= part_table[9];
|
||||
part_offset <<= 8;
|
||||
part_offset |= part_table[8];
|
||||
debug ("found partition start at %ld\n", part_offset);
|
||||
return (0);
|
||||
}
|
||||
part_table += 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug ("no valid devices found!\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
do_fat_dump (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
|
||||
{
|
||||
__u8 block[1024];
|
||||
int ret;
|
||||
int bknum;
|
||||
|
||||
ret = 0;
|
||||
|
||||
if (argc != 2) {
|
||||
printf ("needs an argument!\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
bknum = simple_strtoul (argv[1], NULL, 10);
|
||||
|
||||
if (disk_read (0, bknum, block) != 0) {
|
||||
printf ("Error: reading block\n");
|
||||
return -1;
|
||||
}
|
||||
printf ("FAT dump: %d\n", bknum);
|
||||
hexdump (512, block);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int disk_read (__u32 startblock, __u32 getsize, __u8 *bufptr)
|
||||
{
|
||||
ulong tot;
|
||||
block_dev_desc_t *dev_desc;
|
||||
|
||||
if (curr_dev < 0) {
|
||||
if (find_fat_partition () != 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
dev_desc = ide_get_dev (curr_dev);
|
||||
if (!dev_desc) {
|
||||
debug ("couldn't get ide device\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
tot = dev_desc->block_read (0, startblock + part_offset,
|
||||
getsize, (ulong *) bufptr);
|
||||
|
||||
/* should we do this here?
|
||||
flush_cache ((ulong)buf, cnt*ide_dev_desc[device].blksz);
|
||||
*/
|
||||
|
||||
if (tot == getsize)
|
||||
return (0);
|
||||
|
||||
debug ("unable to read from device!\n");
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
static int isprint (unsigned char ch)
|
||||
{
|
||||
if (ch >= 32 && ch < 127)
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
void hexdump (int cnt, unsigned char *data)
|
||||
{
|
||||
int i;
|
||||
int run;
|
||||
int offset;
|
||||
|
||||
offset = 0;
|
||||
while (cnt) {
|
||||
printf ("%04X : ", offset);
|
||||
if (cnt >= 16)
|
||||
run = 16;
|
||||
else
|
||||
run = cnt;
|
||||
cnt -= run;
|
||||
for (i = 0; i < run; i++)
|
||||
printf ("%02X ", (unsigned int) data[i]);
|
||||
printf (": ");
|
||||
for (i = 0; i < run; i++)
|
||||
printf ("%c", isprint (data[i]) ? data[i] : '.');
|
||||
printf ("\n");
|
||||
data = &data[16];
|
||||
offset += run;
|
||||
}
|
||||
}
|
||||
#endif /* NOT_IMPLEMENTED_YET */
|
||||
|
||||
#endif /* CFG_CMD_FAT */
|
||||
@@ -29,6 +29,10 @@
|
||||
#include <cmd_boot.h>
|
||||
#include <flash.h>
|
||||
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
#include <dataflash.h>
|
||||
#endif
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_FLASH)
|
||||
|
||||
extern flash_info_t flash_info[]; /* info for FLASH chips */
|
||||
@@ -96,6 +100,10 @@ int do_flinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
ulong bank;
|
||||
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
dataflash_print_info();
|
||||
#endif
|
||||
|
||||
if (argc == 1) { /* print info for all FLASH banks */
|
||||
for (bank=0; bank <CFG_MAX_FLASH_BANKS; ++bank) {
|
||||
printf ("\nBank # %ld: ", bank+1);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (C) Copyright 2000
|
||||
* (C) Copyright 2000-2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
@@ -150,7 +150,24 @@ do_icinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
int
|
||||
do_carinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
unimplemented (cmdtp, flag, argc, argv);
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
|
||||
#if defined(CONFIG_8xx)
|
||||
volatile car8xx_t *car = &immap->im_clkrst;
|
||||
#elif defined(CONFIG_8260)
|
||||
volatile car8260_t *car = &immap->im_clkrst;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_8xx)
|
||||
printf ("SCCR = %08x\n", car->car_sccr);
|
||||
printf ("PLPRCR= %08x\n", car->car_plprcr);
|
||||
printf ("RSR = %08x\n", car->car_rsr);
|
||||
#elif defined(CONFIG_8260)
|
||||
printf ("SCCR = %08x\n", car->car_sccr);
|
||||
printf ("SCMR = %08x\n", car->car_scmr);
|
||||
printf ("RSR = %08x\n", car->car_rsr);
|
||||
printf ("RMR = %08x\n", car->car_rmr);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -168,7 +185,7 @@ header(void)
|
||||
int i;
|
||||
|
||||
if (counter % 2)
|
||||
putc('\n');
|
||||
putc('\n');
|
||||
counter = 0;
|
||||
|
||||
for (i = 0; i < 4; i++, data += 79)
|
||||
|
||||
138
common/cmd_mem.c
138
common/cmd_mem.c
@@ -30,6 +30,12 @@
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <cmd_mem.h>
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_MMC)
|
||||
#include <mmc.h>
|
||||
#endif
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
#include <dataflash.h>
|
||||
#endif
|
||||
|
||||
#if (CONFIG_COMMANDS & (CFG_CMD_MEMORY | CFG_CMD_PCI | CFG_CMD_I2C\
|
||||
| CMD_CMD_PORTIO))
|
||||
@@ -128,6 +134,23 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
|
||||
printf("%08lx:", addr);
|
||||
linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
|
||||
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
if (read_dataflash(addr, (linebytes/size)*size, linebuf) != -1){
|
||||
|
||||
for (i=0; i<linebytes; i+= size) {
|
||||
if (size == 4) {
|
||||
printf(" %08x", *uip++);
|
||||
} else if (size == 2) {
|
||||
printf(" %04x", *usp++);
|
||||
} else {
|
||||
printf(" %02x", *ucp++);
|
||||
}
|
||||
addr += size;
|
||||
}
|
||||
|
||||
} else { /* addr does not correspond to DataFlash */
|
||||
#endif
|
||||
for (i=0; i<linebytes; i+= size) {
|
||||
if (size == 4) {
|
||||
printf(" %08x", (*uip++ = *((uint *)addr)));
|
||||
@@ -138,6 +161,9 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
}
|
||||
addr += size;
|
||||
}
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
}
|
||||
#endif
|
||||
printf(" ");
|
||||
cp = linebuf;
|
||||
for (i=0; i<linebytes; i++) {
|
||||
@@ -233,6 +259,13 @@ int do_mem_cmp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
|
||||
count = simple_strtoul(argv[3], NULL, 16);
|
||||
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
if (addr_dataflash(addr1) | addr_dataflash(addr2)){
|
||||
printf("Comparison with DataFlash space not supported.\n\r");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
ngood = 0;
|
||||
|
||||
while (count-- > 0) {
|
||||
@@ -308,7 +341,11 @@ int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
|
||||
#ifndef CFG_NO_FLASH
|
||||
/* check if we are copying to Flash */
|
||||
if (addr2info(dest) != NULL) {
|
||||
if ( (addr2info(dest) != NULL)
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
&& (!addr_dataflash(addr))
|
||||
#endif
|
||||
) {
|
||||
int rc;
|
||||
|
||||
printf ("Copy to Flash... ");
|
||||
@@ -323,6 +360,75 @@ int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_MMC)
|
||||
if (mmc2info(dest)) {
|
||||
int rc;
|
||||
|
||||
printf ("Copy to MMC... ");
|
||||
switch (rc = mmc_write ((uchar *)addr, dest, count*size)) {
|
||||
case 0:
|
||||
printf ("\n");
|
||||
return 1;
|
||||
case -1:
|
||||
printf("failed\n");
|
||||
return 1;
|
||||
default:
|
||||
printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc);
|
||||
return 1;
|
||||
}
|
||||
puts ("done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mmc2info(addr)) {
|
||||
int rc;
|
||||
|
||||
printf ("Copy from MMC... ");
|
||||
switch (rc = mmc_read (addr, (uchar *)dest, count*size)) {
|
||||
case 0:
|
||||
printf ("\n");
|
||||
return 1;
|
||||
case -1:
|
||||
printf("failed\n");
|
||||
return 1;
|
||||
default:
|
||||
printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc);
|
||||
return 1;
|
||||
}
|
||||
puts ("done\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
/* Check if we are copying from RAM or Flash to DataFlash */
|
||||
if (addr_dataflash(dest) && !addr_dataflash(addr)){
|
||||
int rc;
|
||||
|
||||
printf ("Copy to DataFlash... ");
|
||||
|
||||
rc = write_dataflash (dest, addr, count*size);
|
||||
|
||||
if (rc != 1) {
|
||||
dataflash_perror (rc);
|
||||
return (1);
|
||||
}
|
||||
puts ("done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if we are copying from DataFlash to RAM */
|
||||
if (addr_dataflash(addr) && !addr_dataflash(dest) && (addr2info(dest)==NULL) ){
|
||||
read_dataflash(addr, count * size, (char *) dest);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (addr_dataflash(addr) && addr_dataflash(dest)){
|
||||
printf("Unsupported combination of source/destination.\n\r");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
while (count-- > 0) {
|
||||
if (size == 4)
|
||||
*((ulong *)dest) = *((ulong *)addr);
|
||||
@@ -762,6 +868,13 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])
|
||||
addr += base_address;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
if (addr_dataflash(addr)){
|
||||
printf("Can't modify DataFlash in place. Use cp instead.\n\r");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Print the address, followed by value. Then accept input for
|
||||
* the next value. A non-converted value exits.
|
||||
*/
|
||||
@@ -820,30 +933,29 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])
|
||||
|
||||
int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
ulong addr, length;
|
||||
ulong crc;
|
||||
ulong *ptr;
|
||||
ulong addr, length;
|
||||
ulong crc;
|
||||
ulong *ptr;
|
||||
|
||||
if (argc < 3) {
|
||||
printf ("Usage:\n%s\n", cmdtp->usage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
addr = simple_strtoul(argv[1], NULL, 16);
|
||||
addr = simple_strtoul (argv[1], NULL, 16);
|
||||
addr += base_address;
|
||||
|
||||
length = simple_strtoul(argv[2], NULL, 16);
|
||||
length = simple_strtoul (argv[2], NULL, 16);
|
||||
|
||||
crc = crc32 (0, (const uchar *)addr, length);
|
||||
crc = crc32 (0, (const uchar *) addr, length);
|
||||
|
||||
printf ("CRC32 for %08lx ... %08lx ==> %08lx\n",
|
||||
addr, addr + length -1, crc);
|
||||
addr, addr + length - 1, crc);
|
||||
|
||||
if (argc > 3)
|
||||
{
|
||||
ptr = (ulong *)simple_strtoul(argv[3], NULL, 16);
|
||||
*ptr = crc;
|
||||
}
|
||||
if (argc > 3) {
|
||||
ptr = (ulong *) simple_strtoul (argv[3], NULL, 16);
|
||||
*ptr = crc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
40
common/cmd_mmc.c
Normal file
40
common/cmd_mmc.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Kyle Harris, kharris@nexus-tech.net
|
||||
*
|
||||
* 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 <command.h>
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_MMC)
|
||||
|
||||
#include <mmc.h>
|
||||
|
||||
int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
if (mmc_init (1) != 0) {
|
||||
printf ("No MMC card found\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CFG_CMD_MMC */
|
||||
@@ -74,6 +74,8 @@
|
||||
#include <cmd_fdos.h>
|
||||
#include <cmd_bmp.h>
|
||||
#include <cmd_portio.h>
|
||||
#include <cmd_mmc.h>
|
||||
#include <cmd_fat.h>
|
||||
|
||||
#ifdef CONFIG_AMIGAONEG3SE
|
||||
#include <cmd_menu.h>
|
||||
@@ -131,13 +133,14 @@ do_echo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
|
||||
if (i > 1)
|
||||
putc(' ');
|
||||
while ((c = *p++) != '\0')
|
||||
while ((c = *p++) != '\0') {
|
||||
if (c == '\\' && *p == 'c') {
|
||||
putnl = 0;
|
||||
p++;
|
||||
}
|
||||
else
|
||||
} else {
|
||||
putc(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (putnl)
|
||||
@@ -190,8 +193,7 @@ do_help (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
if (cmdtp->usage)
|
||||
puts (cmdtp->usage);
|
||||
#endif /* CFG_LONGHELP */
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
printf ("Unknown command '%s' - try 'help'"
|
||||
" without arguments for list of all"
|
||||
" known commands\n\n",
|
||||
@@ -263,6 +265,7 @@ cmd_tbl_t cmd_tbl[] = {
|
||||
CMD_TBL_DTT
|
||||
CMD_TBL_ECHO
|
||||
CMD_TBL_EEPROM
|
||||
CMD_TBL_FAT
|
||||
CMD_TBL_FCCINFO
|
||||
CMD_TBL_FLERASE
|
||||
CMD_TBL_FDC
|
||||
@@ -302,6 +305,7 @@ cmd_tbl_t cmd_tbl[] = {
|
||||
CMD_TBL_LOOP
|
||||
CMD_TBL_JFFS2_LS
|
||||
CMD_TBL_MCCINFO
|
||||
CMD_TBL_MMC
|
||||
CMD_TBL_MD
|
||||
CMD_TBL_MEMCINFO
|
||||
#ifdef CONFIG_AMIGAONEG3SE
|
||||
|
||||
@@ -232,6 +232,20 @@ void printf (const char *fmt, ...)
|
||||
puts (printbuffer);
|
||||
}
|
||||
|
||||
void vprintf (const char *fmt, va_list args)
|
||||
{
|
||||
uint i;
|
||||
char printbuffer[CFG_PBSIZE];
|
||||
|
||||
/* For this to work, printbuffer must be larger than
|
||||
* anything we ever want to print.
|
||||
*/
|
||||
i = vsprintf (printbuffer, fmt, args);
|
||||
|
||||
/* Print the string */
|
||||
puts (printbuffer);
|
||||
}
|
||||
|
||||
/* test if ctrl-c was pressed */
|
||||
static int ctrlc_disabled = 0; /* see disable_ctrl() */
|
||||
static int ctrlc_was_pressed = 0;
|
||||
|
||||
@@ -319,13 +319,7 @@ void main_loop (void)
|
||||
debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
|
||||
|
||||
# ifdef CONFIG_BOOT_RETRY_TIME
|
||||
s = getenv ("bootretry");
|
||||
if (s != NULL)
|
||||
retry_time = (int)simple_strtoul(s, NULL, 10);
|
||||
else
|
||||
retry_time = CONFIG_BOOT_RETRY_TIME;
|
||||
if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN)
|
||||
retry_time = CONFIG_BOOT_RETRY_MIN;
|
||||
init_cmd_timeout ();
|
||||
# endif /* CONFIG_BOOT_RETRY_TIME */
|
||||
|
||||
s = getenv ("bootcmd");
|
||||
@@ -422,10 +416,26 @@ void main_loop (void)
|
||||
#endif /*CFG_HUSH_PARSER*/
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BOOT_RETRY_TIME
|
||||
/***************************************************************************
|
||||
* initialise command line timeout
|
||||
*/
|
||||
void init_cmd_timeout(void)
|
||||
{
|
||||
char *s = getenv ("bootretry");
|
||||
|
||||
if (s != NULL)
|
||||
retry_time = (int)simple_strtoul(s, NULL, 10);
|
||||
else
|
||||
retry_time = CONFIG_BOOT_RETRY_TIME;
|
||||
|
||||
if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN)
|
||||
retry_time = CONFIG_BOOT_RETRY_MIN;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* reset command line timeout to retry_time seconds
|
||||
*/
|
||||
#ifdef CONFIG_BOOT_RETRY_TIME
|
||||
void reset_cmd_timeout(void)
|
||||
{
|
||||
endtime = endtick(retry_time);
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
|
||||
#########################################################################
|
||||
|
||||
# clean the slate ...
|
||||
PLATFORM_RELFLAGS =
|
||||
PLATFORM_CPPFLAGS =
|
||||
PLATFORM_LDFLAGS =
|
||||
|
||||
#
|
||||
# When cross-compiling on NetBSD, we have to define __PPC__ or else we
|
||||
# will pick up a va_list declaration that is incompatible with the
|
||||
@@ -96,9 +101,11 @@ RANLIB = $(CROSS_COMPILE)RANLIB
|
||||
RELFLAGS= $(PLATFORM_RELFLAGS)
|
||||
DBGFLAGS= -g #-DDEBUG
|
||||
OPTFLAGS= -Os #-fomit-frame-pointer
|
||||
ifndef LDSCRIPT
|
||||
#LDSCRIPT := board/$(BOARDDIR)/u-boot.lds.debug
|
||||
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
|
||||
OBJCFLAGS := --gap-fill=0xff
|
||||
endif
|
||||
OBJCFLAGS += --gap-fill=0xff
|
||||
|
||||
CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \
|
||||
-D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE) \
|
||||
|
||||
@@ -64,7 +64,7 @@ get_cpu_type(void)
|
||||
case 0x0008:
|
||||
type = CPU_750;
|
||||
|
||||
if (((pvr >> 8) & 0xff) == 0x01) {
|
||||
if (((pvr >> 8) & 0xff) == 0x01) {
|
||||
type = CPU_750CX; /* old CX (80100 and 8010x?)*/
|
||||
} else if (((pvr >> 8) & 0xff) == 0x22) {
|
||||
type = CPU_750CX; /* CX (82201,82202) and CXe (82214) */
|
||||
@@ -72,14 +72,18 @@ get_cpu_type(void)
|
||||
type = CPU_750CX; /* CXe (83311) */
|
||||
} else if (((pvr >> 12) & 0xF) == 0x3) {
|
||||
type = CPU_755;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x7000:
|
||||
type = CPU_750FX;
|
||||
break;
|
||||
|
||||
case 0x800C:
|
||||
type = CPU_7410;
|
||||
break;
|
||||
|
||||
case 0x8000:
|
||||
case 0x8000:
|
||||
type = CPU_7450;
|
||||
break;
|
||||
|
||||
@@ -116,6 +120,10 @@ int checkcpu (void)
|
||||
str = "750";
|
||||
break;
|
||||
|
||||
case CPU_750FX:
|
||||
str = "750FX";
|
||||
break;
|
||||
|
||||
case CPU_755:
|
||||
str = "755";
|
||||
break;
|
||||
@@ -124,16 +132,16 @@ int checkcpu (void)
|
||||
str = "MPC7400";
|
||||
break;
|
||||
|
||||
case CPU_7410:
|
||||
str = "MPC7410";
|
||||
case CPU_7410:
|
||||
str = "MPC7410";
|
||||
break;
|
||||
|
||||
case CPU_7450:
|
||||
str = "MPC7450";
|
||||
case CPU_7450:
|
||||
str = "MPC7450";
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown CPU -- PVR: 0x%08x\n", pvr);
|
||||
printf("Unknown CPU -- PVR: 0x%08x\n", pvr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -146,8 +154,8 @@ PR_CLK:
|
||||
#endif
|
||||
/* these two functions are unimplemented currently [josh] */
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* L1 i-cache */
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* L1 i-cache */
|
||||
|
||||
int
|
||||
checkicache(void)
|
||||
@@ -155,8 +163,8 @@ checkicache(void)
|
||||
return 0; /* XXX */
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* L1 d-cache */
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* L1 d-cache */
|
||||
|
||||
int
|
||||
checkdcache(void)
|
||||
@@ -164,7 +172,7 @@ checkdcache(void)
|
||||
return 0; /* XXX */
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static inline void
|
||||
soft_restart(unsigned long addr)
|
||||
|
||||
@@ -48,6 +48,33 @@ static const int hid1_multipliers_x_10[] = {
|
||||
0 /* 1111 - off */
|
||||
};
|
||||
|
||||
static const int hid1_fx_multipliers_x_10[] = {
|
||||
00, /* 0000 - off */
|
||||
00, /* 0001 - off */
|
||||
10, /* 0010 - bypass */
|
||||
10, /* 0011 - bypass */
|
||||
20, /* 0100 - 2x */
|
||||
25, /* 0101 - 2.5x */
|
||||
30, /* 0110 - 3x */
|
||||
35, /* 0111 - 3.5x */
|
||||
40, /* 1000 - 4x */
|
||||
45, /* 1001 - 4.5x */
|
||||
50, /* 1010 - 5x */
|
||||
55, /* 1011 - 5.5x */
|
||||
60, /* 1100 - 6x */
|
||||
65, /* 1101 - 6.5x */
|
||||
70, /* 1110 - 7x */
|
||||
75, /* 1111 - 7.5 */
|
||||
80, /* 10000 - 8x */
|
||||
85, /* 10001 - 8.5x */
|
||||
90, /* 10010 - 9x */
|
||||
95, /* 10011 - 9.5x */
|
||||
100, /* 10100 - 10x */
|
||||
110, /* 10101 - 11x */
|
||||
120, /* 10110 - 12x */
|
||||
};
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
@@ -59,9 +86,13 @@ static const int hid1_multipliers_x_10[] = {
|
||||
int get_clocks (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#ifdef CONFIG_750FX
|
||||
ulong clock = CFG_BUS_CLK * \
|
||||
hid1_fx_multipliers_x_10[get_hid1 () >> 27] / 10;
|
||||
#else
|
||||
ulong clock = CFG_BUS_CLK * \
|
||||
hid1_multipliers_x_10[get_hid1 () >> 28] / 10;
|
||||
#endif
|
||||
gd->cpu_clk = clock;
|
||||
gd->bus_clk = CFG_BUS_CLK;
|
||||
|
||||
|
||||
@@ -379,11 +379,23 @@ invalidate_bats:
|
||||
mtspr IBAT1U, r0
|
||||
mtspr IBAT2U, r0
|
||||
mtspr IBAT3U, r0
|
||||
#ifdef CONFIG_750FX
|
||||
mtspr IBAT4U, r0
|
||||
mtspr IBAT5U, r0
|
||||
mtspr IBAT6U, r0
|
||||
mtspr IBAT7U, r0
|
||||
#endif
|
||||
isync
|
||||
mtspr DBAT0U, r0
|
||||
mtspr DBAT1U, r0
|
||||
mtspr DBAT2U, r0
|
||||
mtspr DBAT3U, r0
|
||||
#ifdef CONFIG_750FX
|
||||
mtspr DBAT4U, r0
|
||||
mtspr DBAT5U, r0
|
||||
mtspr DBAT6U, r0
|
||||
mtspr DBAT7U, r0
|
||||
#endif
|
||||
isync
|
||||
sync
|
||||
blr
|
||||
@@ -465,6 +477,80 @@ setup_bats:
|
||||
mtspr DBAT3U, r3
|
||||
isync
|
||||
|
||||
#ifdef CONFIG_750FX
|
||||
/* IBAT 4 */
|
||||
addis r4, r0, CFG_IBAT4L@h
|
||||
ori r4, r4, CFG_IBAT4L@l
|
||||
addis r3, r0, CFG_IBAT4U@h
|
||||
ori r3, r3, CFG_IBAT4U@l
|
||||
mtspr IBAT4L, r4
|
||||
mtspr IBAT4U, r3
|
||||
isync
|
||||
|
||||
/* DBAT 4 */
|
||||
addis r4, r0, CFG_DBAT4L@h
|
||||
ori r4, r4, CFG_DBAT4L@l
|
||||
addis r3, r0, CFG_DBAT4U@h
|
||||
ori r3, r3, CFG_DBAT4U@l
|
||||
mtspr DBAT4L, r4
|
||||
mtspr DBAT4U, r3
|
||||
isync
|
||||
|
||||
/* IBAT 5 */
|
||||
addis r4, r0, CFG_IBAT5L@h
|
||||
ori r4, r4, CFG_IBAT5L@l
|
||||
addis r3, r0, CFG_IBAT5U@h
|
||||
ori r3, r3, CFG_IBAT5U@l
|
||||
mtspr IBAT5L, r4
|
||||
mtspr IBAT5U, r3
|
||||
isync
|
||||
|
||||
/* DBAT 5 */
|
||||
addis r4, r0, CFG_DBAT5L@h
|
||||
ori r4, r4, CFG_DBAT5L@l
|
||||
addis r3, r0, CFG_DBAT5U@h
|
||||
ori r3, r3, CFG_DBAT5U@l
|
||||
mtspr DBAT5L, r4
|
||||
mtspr DBAT5U, r3
|
||||
isync
|
||||
|
||||
/* IBAT 6 */
|
||||
addis r4, r0, CFG_IBAT6L@h
|
||||
ori r4, r4, CFG_IBAT6L@l
|
||||
addis r3, r0, CFG_IBAT6U@h
|
||||
ori r3, r3, CFG_IBAT6U@l
|
||||
mtspr IBAT6L, r4
|
||||
mtspr IBAT6U, r3
|
||||
isync
|
||||
|
||||
/* DBAT 6 */
|
||||
addis r4, r0, CFG_DBAT6L@h
|
||||
ori r4, r4, CFG_DBAT6L@l
|
||||
addis r3, r0, CFG_DBAT6U@h
|
||||
ori r3, r3, CFG_DBAT6U@l
|
||||
mtspr DBAT6L, r4
|
||||
mtspr DBAT6U, r3
|
||||
isync
|
||||
|
||||
/* IBAT 7 */
|
||||
addis r4, r0, CFG_IBAT7L@h
|
||||
ori r4, r4, CFG_IBAT7L@l
|
||||
addis r3, r0, CFG_IBAT7U@h
|
||||
ori r3, r3, CFG_IBAT7U@l
|
||||
mtspr IBAT7L, r4
|
||||
mtspr IBAT7U, r3
|
||||
isync
|
||||
|
||||
/* DBAT 7 */
|
||||
addis r4, r0, CFG_DBAT7L@h
|
||||
ori r4, r4, CFG_DBAT7L@l
|
||||
addis r3, r0, CFG_DBAT7U@h
|
||||
ori r3, r3, CFG_DBAT7U@l
|
||||
mtspr DBAT7L, r4
|
||||
mtspr DBAT7U, r3
|
||||
isync
|
||||
#endif
|
||||
|
||||
/* bats are done, now invalidate the TLBs */
|
||||
|
||||
addis r3, 0, 0x0000
|
||||
|
||||
@@ -43,7 +43,12 @@ extern void reset_cpu(ulong addr);
|
||||
int timer_load_val = 0;
|
||||
|
||||
/* macro to read the 16 bit timer */
|
||||
#define READ_TIMER (rTCNTO4 & 0xffff)
|
||||
static inline ulong READ_TIMER(void)
|
||||
{
|
||||
S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
|
||||
|
||||
return (timers->TCNTO4 & 0xffff);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
/* enable IRQ interrupts */
|
||||
@@ -184,9 +189,11 @@ static ulong lastdec;
|
||||
|
||||
int interrupt_init (void)
|
||||
{
|
||||
S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
|
||||
|
||||
/* use PWM Timer 4 because it has no output */
|
||||
/* prescaler for Timer 4 is 16 */
|
||||
rTCFG0 = 0x0f00;
|
||||
timers->TCFG0 = 0x0f00;
|
||||
if (timer_load_val == 0)
|
||||
{
|
||||
/*
|
||||
@@ -197,11 +204,11 @@ int interrupt_init (void)
|
||||
timer_load_val = get_PCLK()/(2 * 16 * 100);
|
||||
}
|
||||
/* load value for 10 ms timeout */
|
||||
lastdec = rTCNTB4 = timer_load_val;
|
||||
lastdec = timers->TCNTB4 = timer_load_val;
|
||||
/* auto load, manual update of Timer 4 */
|
||||
rTCON = (rTCON & ~0x0700000) | 0x600000;
|
||||
timers->TCON = (timers->TCON & ~0x0700000) | 0x600000;
|
||||
/* auto load, start Timer 4 */
|
||||
rTCON = (rTCON & ~0x0700000) | 0x500000;
|
||||
timers->TCON = (timers->TCON & ~0x0700000) | 0x500000;
|
||||
timestamp = 0;
|
||||
|
||||
return (0);
|
||||
@@ -243,13 +250,13 @@ void udelay (unsigned long usec)
|
||||
void reset_timer_masked (void)
|
||||
{
|
||||
/* reset time */
|
||||
lastdec = READ_TIMER;
|
||||
lastdec = READ_TIMER();
|
||||
timestamp = 0;
|
||||
}
|
||||
|
||||
ulong get_timer_masked (void)
|
||||
{
|
||||
ulong now = READ_TIMER;
|
||||
ulong now = READ_TIMER();
|
||||
|
||||
if (lastdec >= now) {
|
||||
/* normal mode */
|
||||
|
||||
@@ -25,57 +25,51 @@
|
||||
#include <s3c2410.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL1
|
||||
#define UART_NR S3C24X0_UART0
|
||||
|
||||
#elif CONFIG_SERIAL2
|
||||
# if defined(CONFIG_TRAB)
|
||||
# #error "TRAB supports only CONFIG_SERIAL1"
|
||||
# endif
|
||||
#define UART_NR S3C24X0_UART1
|
||||
|
||||
#elif CONFIG_SERIAL3
|
||||
# if defined(CONFIG_TRAB)
|
||||
# #error "TRAB supports only CONFIG_SERIAL1"
|
||||
# endif
|
||||
#define UART_NR S3C24X0_UART2
|
||||
|
||||
#else
|
||||
#error "Bad: you didn't configure serial ..."
|
||||
#endif
|
||||
|
||||
void serial_setbrg (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
|
||||
int i;
|
||||
unsigned int reg = 0;
|
||||
|
||||
/* value is calculated so : (int)(PCLK/16./baudrate) -1 */
|
||||
reg = get_PCLK() / (16 * gd->baudrate) - 1;
|
||||
|
||||
#ifdef CONFIG_SERIAL1
|
||||
/* FIFO enable, Tx/Rx FIFO clear */
|
||||
rUFCON0 = 0x07;
|
||||
rUMCON0 = 0x0;
|
||||
uart->UFCON = 0x07;
|
||||
uart->UMCON = 0x0;
|
||||
/* Normal,No parity,1 stop,8 bit */
|
||||
rULCON0 = 0x3;
|
||||
uart->ULCON = 0x3;
|
||||
/*
|
||||
* tx=level,rx=edge,disable timeout int.,enable rx error int.,
|
||||
* normal,interrupt or polling
|
||||
*/
|
||||
rUCON0 = 0x245;
|
||||
rUBRDIV0 = reg;
|
||||
uart->UCON = 0x245;
|
||||
uart->UBRDIV = reg;
|
||||
|
||||
#ifdef CONFIG_HWFLOW
|
||||
rUMCON0 = 0x1; /* RTS up */
|
||||
uart->UMCON = 0x1; /* RTS up */
|
||||
#endif
|
||||
for (i = 0; i < 100; i++);
|
||||
#elif CONFIG_SERIAL2
|
||||
# if defined(CONFIG_TRAB)
|
||||
# #error "TRAB supports only CONFIG_SERIAL1"
|
||||
# endif
|
||||
/* FIFO enable, Tx/Rx FIFO clear */
|
||||
rUFCON1 = 0x06;
|
||||
rUMCON1 = 0x0;
|
||||
/* Normal,No parity,1 stop,8 bit */
|
||||
rULCON1 = 0x3;
|
||||
/*
|
||||
* tx=level,rx=edge,disable timeout int.,enable rx error int.,
|
||||
* normal,interrupt or polling
|
||||
*/
|
||||
rUCON1 = 0x245;
|
||||
rUBRDIV1 = reg;
|
||||
|
||||
#ifdef CONFIG_HWFLOW
|
||||
rUMCON1 = 0x1; /* RTS up */
|
||||
#endif
|
||||
for (i = 0; i < 100; i++);
|
||||
#else
|
||||
#error "Bad: you didn't configure serial ..."
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -97,15 +91,12 @@ int serial_init (void)
|
||||
*/
|
||||
int serial_getc (void)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL1
|
||||
while (!(rUTRSTAT0 & 0x1));
|
||||
S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
|
||||
|
||||
/* wait for character to arrive */
|
||||
while (!(uart->UTRSTAT & 0x1));
|
||||
|
||||
return rURXH0 & 0xff;
|
||||
#elif CONFIG_SERIAL2
|
||||
while (!(rUTRSTAT1 & 0x1));
|
||||
|
||||
return rURXH1 & 0xff;
|
||||
#endif
|
||||
return uart->URXH & 0xff;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HWFLOW
|
||||
@@ -146,33 +137,22 @@ void enable_putc(void)
|
||||
*/
|
||||
void serial_putc (const char c)
|
||||
{
|
||||
S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
|
||||
#ifdef CONFIG_MODEM_SUPPORT
|
||||
if (be_quiet)
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL1
|
||||
/* wait for room in the tx FIFO on SERIAL1 */
|
||||
while (!(rUTRSTAT0 & 0x2));
|
||||
/* wait for room in the tx FIFO */
|
||||
while (!(uart->UTRSTAT & 0x2));
|
||||
|
||||
#ifdef CONFIG_HWFLOW
|
||||
/* Wait for CTS up */
|
||||
while(hwflow && !(rUMSTAT0 & 0x1))
|
||||
while(hwflow && !(uart->UMSTAT & 0x1))
|
||||
;
|
||||
#endif
|
||||
|
||||
rUTXH0 = c;
|
||||
#elif CONFIG_SERIAL2
|
||||
/* wait for room in the tx FIFO on SERIAL2 */
|
||||
while (!(rUTRSTAT1 & 0x2));
|
||||
|
||||
#ifdef CONFIG_HWFLOW
|
||||
/* Wait for CTS up */
|
||||
while(hwflow && !(rUMSTAT1 & 0x1))
|
||||
;
|
||||
#endif
|
||||
rUTXH1 = c;
|
||||
#endif
|
||||
uart->UTXH = c;
|
||||
|
||||
/* If \n, also do \r */
|
||||
if (c == '\n')
|
||||
@@ -184,11 +164,9 @@ void serial_putc (const char c)
|
||||
*/
|
||||
int serial_tstc (void)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL1
|
||||
return rUTRSTAT0 & 0x1;
|
||||
#elif CONFIG_SERIAL2
|
||||
return rUTRSTAT1 & 0x1;
|
||||
#endif
|
||||
S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
|
||||
|
||||
return uart->UTRSTAT & 0x1;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -51,12 +51,13 @@
|
||||
|
||||
static ulong get_PLLCLK(int pllreg)
|
||||
{
|
||||
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
|
||||
ulong r, m, p, s;
|
||||
|
||||
if (pllreg == MPLL)
|
||||
r = rMPLLCON;
|
||||
r = clk_power->MPLLCON;
|
||||
else if (pllreg == UPLL)
|
||||
r = rUPLLCON;
|
||||
r = clk_power->UPLLCON;
|
||||
else
|
||||
hang();
|
||||
|
||||
@@ -76,17 +77,17 @@ ulong get_FCLK(void)
|
||||
/* return HCLK frequency */
|
||||
ulong get_HCLK(void)
|
||||
{
|
||||
ulong clkdiv = rCLKDIVN;
|
||||
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
|
||||
|
||||
return((clkdiv & 0x2) ? get_FCLK()/2 : get_FCLK());
|
||||
return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
|
||||
}
|
||||
|
||||
/* return PCLK frequency */
|
||||
ulong get_PCLK(void)
|
||||
{
|
||||
ulong clkdiv = rCLKDIVN;
|
||||
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
|
||||
|
||||
return((clkdiv & 0x1) ? get_HCLK()/2 : get_HCLK());
|
||||
return((clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 : get_HCLK());
|
||||
}
|
||||
|
||||
/* return UCLK frequency */
|
||||
|
||||
@@ -26,7 +26,8 @@ include $(TOPDIR)/config.mk
|
||||
LIB = lib$(CPU).a
|
||||
|
||||
START = start.o
|
||||
OBJS = serial.o interrupts.o cpu.o
|
||||
OBJS = serial.o interrupts.o cpu.o \
|
||||
at91rm9200_ether.o at45.o
|
||||
|
||||
all: .depend $(START) $(LIB)
|
||||
|
||||
|
||||
521
cpu/at91rm9200/at45.c
Normal file
521
cpu/at91rm9200/at45.c
Normal file
@@ -0,0 +1,521 @@
|
||||
/* Driver for ATMEL DataFlash support
|
||||
* Author : Hamid Ikdoumi (Atmel)
|
||||
*
|
||||
* 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/hardware.h>
|
||||
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
#include <dataflash.h>
|
||||
|
||||
#define SPI_CLK 5000000
|
||||
#define AT91C_SPI_PCS0_SERIAL_DATAFLASH 0xE /* Chip Select 0 : NPCS0 %1110 */
|
||||
#define AT91C_SPI_PCS3_DATAFLASH_CARD 0x7 /* Chip Select 3 : NPCS3 %0111 */
|
||||
|
||||
void AT91F_SpiInit(void) {
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* SPI DataFlash Init */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* Configure PIOs */
|
||||
AT91C_BASE_PIOA->PIO_ASR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
|
||||
AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK;
|
||||
AT91C_BASE_PIOA->PIO_PDR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
|
||||
AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK;
|
||||
/* Enable CLock */
|
||||
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI;
|
||||
|
||||
/* Reset the SPI */
|
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
|
||||
|
||||
/* Configure SPI in Master Mode with No CS selected !!! */
|
||||
AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS;
|
||||
|
||||
/* Configure CS0 and CS3 */
|
||||
*(AT91C_SPI_CSR + 0) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*SPI_CLK)) << 8);
|
||||
|
||||
*(AT91C_SPI_CSR + 3) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*SPI_CLK)) << 8);
|
||||
|
||||
}
|
||||
|
||||
void AT91F_SpiEnable(int cs) {
|
||||
switch(cs) {
|
||||
case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */
|
||||
AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
|
||||
AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS0_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS);
|
||||
break;
|
||||
case 3: /* Configure SPI CS3 for Serial DataFlash Card */
|
||||
/* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard */
|
||||
AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB7; /* Set in PIO mode */
|
||||
AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB7; /* Configure in output */
|
||||
/* Clear Output */
|
||||
AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7;
|
||||
/* Configure PCS */
|
||||
AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
|
||||
AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS);
|
||||
break;
|
||||
}
|
||||
|
||||
/* SPI_Enable */
|
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* \fn AT91F_SpiWrite */
|
||||
/* \brief Set the PDC registers for a transfert */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
unsigned int AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc )
|
||||
{
|
||||
unsigned int timeout;
|
||||
|
||||
pDesc->state = BUSY;
|
||||
|
||||
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
|
||||
|
||||
/* Initialize the Transmit and Receive Pointer */
|
||||
AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ;
|
||||
AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ;
|
||||
|
||||
/* Intialize the Transmit and Receive Counters */
|
||||
AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size;
|
||||
AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size;
|
||||
|
||||
if ( pDesc->tx_data_size != 0 ) {
|
||||
/* Initialize the Next Transmit and Next Receive Pointer */
|
||||
AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ;
|
||||
AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ;
|
||||
|
||||
/* Intialize the Next Transmit and Next Receive Counters */
|
||||
AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ;
|
||||
AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ;
|
||||
}
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked();
|
||||
timeout = 0;
|
||||
|
||||
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN;
|
||||
while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF) && ((timeout = get_timer_masked() ) < CFG_SPI_WRITE_TOUT));
|
||||
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
|
||||
pDesc->state = IDLE;
|
||||
|
||||
if (timeout >= CFG_SPI_WRITE_TOUT){
|
||||
printf("Error Timeout\n\r");
|
||||
return DATAFLASH_ERROR;
|
||||
}
|
||||
|
||||
return DATAFLASH_OK;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* \fn AT91F_DataFlashSendCommand */
|
||||
/* \brief Generic function to send a command to the dataflash */
|
||||
/*----------------------------------------------------------------------*/
|
||||
AT91S_DataFlashStatus AT91F_DataFlashSendCommand(
|
||||
AT91PS_DataFlash pDataFlash,
|
||||
unsigned char OpCode,
|
||||
unsigned int CmdSize,
|
||||
unsigned int DataflashAddress)
|
||||
{
|
||||
unsigned int adr;
|
||||
|
||||
if ( (pDataFlash->pDataFlashDesc->state) != IDLE)
|
||||
return DATAFLASH_BUSY;
|
||||
|
||||
/* process the address to obtain page address and byte address */
|
||||
adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) << pDataFlash->pDevice->page_offset) + (DataflashAddress % (pDataFlash->pDevice->pages_size));
|
||||
|
||||
/* fill the command buffer */
|
||||
pDataFlash->pDataFlashDesc->command[0] = OpCode;
|
||||
pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16);
|
||||
pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8);
|
||||
pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ;
|
||||
pDataFlash->pDataFlashDesc->command[4] = 0;
|
||||
pDataFlash->pDataFlashDesc->command[5] = 0;
|
||||
pDataFlash->pDataFlashDesc->command[6] = 0;
|
||||
pDataFlash->pDataFlashDesc->command[7] = 0;
|
||||
|
||||
/* Initialize the SpiData structure for the spi write fuction */
|
||||
pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
|
||||
pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize ;
|
||||
pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
|
||||
pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize ;
|
||||
|
||||
/* send the command and read the data */
|
||||
return AT91F_SpiWrite (pDataFlash->pDataFlashDesc);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* \fn AT91F_DataFlashGetStatus */
|
||||
/* \brief Read the status register of the dataflash */
|
||||
/*----------------------------------------------------------------------*/
|
||||
AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
|
||||
{
|
||||
AT91S_DataFlashStatus status;
|
||||
|
||||
/* if a transfert is in progress ==> return 0 */
|
||||
if( (pDesc->state) != IDLE)
|
||||
return DATAFLASH_BUSY;
|
||||
|
||||
/* first send the read status command (D7H) */
|
||||
pDesc->command[0] = DB_STATUS;
|
||||
pDesc->command[1] = 0;
|
||||
|
||||
pDesc->DataFlash_state = GET_STATUS;
|
||||
pDesc->tx_data_size = 0 ; /* Transmit the command and receive response */
|
||||
pDesc->tx_cmd_pt = pDesc->command ;
|
||||
pDesc->rx_cmd_pt = pDesc->command ;
|
||||
pDesc->rx_cmd_size = 2 ;
|
||||
pDesc->tx_cmd_size = 2 ;
|
||||
status = AT91F_SpiWrite (pDesc);
|
||||
|
||||
pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* \fn AT91F_DataFlashWaitReady */
|
||||
/* \brief wait for dataflash ready (bit7 of the status register == 1) */
|
||||
/*----------------------------------------------------------------------*/
|
||||
AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc pDataFlashDesc, unsigned int timeout)
|
||||
{
|
||||
pDataFlashDesc->DataFlash_state = IDLE;
|
||||
|
||||
do {
|
||||
AT91F_DataFlashGetStatus(pDataFlashDesc);
|
||||
timeout--;
|
||||
}
|
||||
while( ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout > 0) );
|
||||
|
||||
if((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
|
||||
return DATAFLASH_ERROR;
|
||||
|
||||
return DATAFLASH_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Function Name : AT91F_DataFlashContinuousRead */
|
||||
/* Object : Continuous stream Read */
|
||||
/* Input Parameters : DataFlash Service */
|
||||
/* : <src> = dataflash address */
|
||||
/* : <*dataBuffer> = data buffer pointer */
|
||||
/* : <sizeToRead> = data buffer size */
|
||||
/* Return value : State of the dataflash */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
AT91S_DataFlashStatus AT91F_DataFlashContinuousRead (
|
||||
AT91PS_DataFlash pDataFlash,
|
||||
int src,
|
||||
unsigned char *dataBuffer,
|
||||
int sizeToRead )
|
||||
{
|
||||
/* Test the size to read in the device */
|
||||
if ( (src + sizeToRead) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
|
||||
return DATAFLASH_MEMORY_OVERFLOW;
|
||||
|
||||
pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
|
||||
pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
|
||||
pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
|
||||
pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
|
||||
|
||||
/* Send the command to the dataflash */
|
||||
return(AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Function Name : AT91F_DataFlashPagePgmBuf */
|
||||
/* Object : Main memory page program through buffer 1 or buffer 2 */
|
||||
/* Input Parameters : DataFlash Service */
|
||||
/* : <*src> = Source buffer */
|
||||
/* : <dest> = dataflash destination address */
|
||||
/* : <SizeToWrite> = data buffer size */
|
||||
/* Return value : State of the dataflash */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf(
|
||||
AT91PS_DataFlash pDataFlash,
|
||||
unsigned char *src,
|
||||
unsigned int dest,
|
||||
unsigned int SizeToWrite)
|
||||
{
|
||||
pDataFlash->pDataFlashDesc->tx_data_pt = src ;
|
||||
pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
|
||||
pDataFlash->pDataFlashDesc->rx_data_pt = src;
|
||||
pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
|
||||
|
||||
/* Send the command to the dataflash */
|
||||
return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_PGM_BUF1, 4, dest));
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Function Name : AT91F_MainMemoryToBufferTransfert */
|
||||
/* Object : Read a page in the SRAM Buffer 1 or 2 */
|
||||
/* Input Parameters : DataFlash Service */
|
||||
/* : Page concerned */
|
||||
/* : */
|
||||
/* Return value : State of the dataflash */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
|
||||
AT91PS_DataFlash pDataFlash,
|
||||
unsigned char BufferCommand,
|
||||
unsigned int page)
|
||||
{
|
||||
/* Test if the buffer command is legal */
|
||||
if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && (BufferCommand != DB_PAGE_2_BUF2_TRF))
|
||||
return DATAFLASH_BAD_COMMAND;
|
||||
|
||||
/* no data to transmit or receive */
|
||||
pDataFlash->pDataFlashDesc->tx_data_size = 0;
|
||||
|
||||
return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, page*pDataFlash->pDevice->pages_size));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------- */
|
||||
/* Function Name : AT91F_DataFlashWriteBuffer */
|
||||
/* Object : Write data to the internal sram buffer 1 or 2 */
|
||||
/* Input Parameters : DataFlash Service */
|
||||
/* : <BufferCommand> = command to write buffer1 or buffer2 */
|
||||
/* : <*dataBuffer> = data buffer to write */
|
||||
/* : <bufferAddress> = address in the internal buffer */
|
||||
/* : <SizeToWrite> = data buffer size */
|
||||
/* Return value : State of the dataflash */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer (
|
||||
AT91PS_DataFlash pDataFlash,
|
||||
unsigned char BufferCommand,
|
||||
unsigned char *dataBuffer,
|
||||
unsigned int bufferAddress,
|
||||
int SizeToWrite )
|
||||
{
|
||||
/* Test if the buffer command is legal */
|
||||
if ((BufferCommand != DB_BUF1_WRITE) && (BufferCommand != DB_BUF2_WRITE))
|
||||
return DATAFLASH_BAD_COMMAND;
|
||||
|
||||
/* buffer address must be lower than page size */
|
||||
if (bufferAddress > pDataFlash->pDevice->pages_size)
|
||||
return DATAFLASH_BAD_ADDRESS;
|
||||
|
||||
if ( (pDataFlash->pDataFlashDesc->state) != IDLE)
|
||||
return DATAFLASH_BUSY;
|
||||
|
||||
/* Send first Write Command */
|
||||
pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
|
||||
pDataFlash->pDataFlashDesc->command[1] = 0;
|
||||
pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ;
|
||||
pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ;
|
||||
|
||||
|
||||
pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
|
||||
pDataFlash->pDataFlashDesc->tx_cmd_size = 4 ;
|
||||
pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
|
||||
pDataFlash->pDataFlashDesc->rx_cmd_size = 4 ;
|
||||
|
||||
pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer ;
|
||||
pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer ;
|
||||
pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite ;
|
||||
pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
|
||||
|
||||
return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Function Name : AT91F_WriteBufferToMain */
|
||||
/* Object : Write buffer to the main memory */
|
||||
/* Input Parameters : DataFlash Service */
|
||||
/* : <BufferCommand> = command to send to buffer1 or buffer2 */
|
||||
/* : <dest> = main memory address */
|
||||
/* Return value : State of the dataflash */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
AT91S_DataFlashStatus AT91F_WriteBufferToMain (
|
||||
AT91PS_DataFlash pDataFlash,
|
||||
unsigned char BufferCommand,
|
||||
unsigned int dest )
|
||||
{
|
||||
/* Test if the buffer command is correct */
|
||||
if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
|
||||
(BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
|
||||
(BufferCommand != DB_BUF2_PAGE_PGM) &&
|
||||
(BufferCommand != DB_BUF2_PAGE_ERASE_PGM) )
|
||||
return DATAFLASH_BAD_COMMAND;
|
||||
|
||||
/* no data to transmit or receive */
|
||||
pDataFlash->pDataFlashDesc->tx_data_size = 0;
|
||||
|
||||
/* Send the command to the dataflash */
|
||||
return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, dest));
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Function Name : AT91F_PartialPageWrite */
|
||||
/* Object : Erase partielly a page */
|
||||
/* Input Parameters : <page> = page number */
|
||||
/* : <AdrInpage> = adr to begin the fading */
|
||||
/* : <length> = Number of bytes to erase */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
AT91S_DataFlashStatus AT91F_PartialPageWrite (
|
||||
AT91PS_DataFlash pDataFlash,
|
||||
unsigned char *src,
|
||||
unsigned int dest,
|
||||
unsigned int size)
|
||||
{
|
||||
unsigned int page;
|
||||
unsigned int AdrInPage;
|
||||
|
||||
page = dest / (pDataFlash->pDevice->pages_size);
|
||||
AdrInPage = dest % (pDataFlash->pDevice->pages_size);
|
||||
|
||||
/* Read the contents of the page in the Sram Buffer */
|
||||
AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
|
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
|
||||
/*Update the SRAM buffer */
|
||||
AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size);
|
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
|
||||
|
||||
/* Rewrite the modified Sram Buffer in the main memory */
|
||||
return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM, (page*pDataFlash->pDevice->pages_size)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Function Name : AT91F_DataFlashWrite_Overloaded */
|
||||
/* Object : */
|
||||
/* Input Parameters : <*src> = Source buffer */
|
||||
/* : <dest> = dataflash adress */
|
||||
/* : <size> = data buffer size */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
AT91S_DataFlashStatus AT91F_DataFlashWrite(
|
||||
AT91PS_DataFlash pDataFlash,
|
||||
unsigned char *src,
|
||||
int dest,
|
||||
int size )
|
||||
{
|
||||
unsigned int length;
|
||||
|
||||
AT91F_SpiEnable(pDataFlash->pDevice->cs);
|
||||
|
||||
if ( (dest + size) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
|
||||
return DATAFLASH_MEMORY_OVERFLOW;
|
||||
|
||||
/* If destination does not fit a page start address */
|
||||
if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0 ) {
|
||||
length = pDataFlash->pDevice->pages_size - (dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));
|
||||
|
||||
if (size < length)
|
||||
length = size;
|
||||
|
||||
if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length))
|
||||
return DATAFLASH_ERROR;
|
||||
|
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
|
||||
|
||||
/* Update size, source and destination pointers */
|
||||
size -= length;
|
||||
dest += length;
|
||||
src += length;
|
||||
}
|
||||
|
||||
while (( size - pDataFlash->pDevice->pages_size ) >= 0 ) {
|
||||
/* program dataflash page */
|
||||
if(!AT91F_DataFlashPagePgmBuf(pDataFlash, src, dest, pDataFlash->pDevice->pages_size ))
|
||||
return DATAFLASH_ERROR;
|
||||
|
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
|
||||
|
||||
/* Update size, source and destination pointers */
|
||||
size -= pDataFlash->pDevice->pages_size ;
|
||||
dest += pDataFlash->pDevice->pages_size ;
|
||||
src += pDataFlash->pDevice->pages_size ;
|
||||
}
|
||||
|
||||
/* If still some bytes to read */
|
||||
if ( size > 0 ) {
|
||||
/* program dataflash page */
|
||||
if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) )
|
||||
return DATAFLASH_ERROR;
|
||||
|
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
|
||||
}
|
||||
return DATAFLASH_OK;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Function Name : AT91F_DataFlashRead */
|
||||
/* Object : Read a block in dataflash */
|
||||
/* Input Parameters : */
|
||||
/* Return value : */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
int AT91F_DataFlashRead(
|
||||
AT91PS_DataFlash pDataFlash,
|
||||
unsigned long addr,
|
||||
unsigned long size,
|
||||
char *buffer)
|
||||
{
|
||||
unsigned long SizeToRead;
|
||||
|
||||
AT91F_SpiEnable(pDataFlash->pDevice->cs);
|
||||
|
||||
if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK)
|
||||
return -1;
|
||||
|
||||
while (size) {
|
||||
SizeToRead = (size < 0x8000)? size:0x8000;
|
||||
|
||||
if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK)
|
||||
return -1;
|
||||
|
||||
if (AT91F_DataFlashContinuousRead (pDataFlash, addr, buffer, SizeToRead) != DATAFLASH_OK)
|
||||
return -1;
|
||||
|
||||
size -= SizeToRead;
|
||||
addr += SizeToRead;
|
||||
buffer += SizeToRead;
|
||||
}
|
||||
|
||||
return DATAFLASH_OK;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Function Name : AT91F_DataflashProbe */
|
||||
/* Object : */
|
||||
/* Input Parameters : */
|
||||
/* Return value : Dataflash status register */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
|
||||
{
|
||||
AT91F_SpiEnable(cs);
|
||||
AT91F_DataFlashGetStatus(pDesc);
|
||||
return((pDesc->command[1] == 0xFF)? 0: pDesc->command[1] & 0x3C);
|
||||
}
|
||||
|
||||
#endif
|
||||
468
cpu/at91rm9200/at91rm9200_ether.c
Normal file
468
cpu/at91rm9200/at91rm9200_ether.c
Normal file
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Author : Hamid Ikdoumi (Atmel)
|
||||
*
|
||||
* 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 <at91rm9200_net.h>
|
||||
#include <net.h>
|
||||
|
||||
/* ----- Ethernet Buffer definitions ----- */
|
||||
|
||||
typedef struct {
|
||||
unsigned long addr, size;
|
||||
} rbf_t;
|
||||
|
||||
#define RBF_ADDR 0xfffffffc
|
||||
#define RBF_OWNER (1<<0)
|
||||
#define RBF_WRAP (1<<1)
|
||||
#define RBF_BROADCAST (1<<31)
|
||||
#define RBF_MULTICAST (1<<30)
|
||||
#define RBF_UNICAST (1<<29)
|
||||
#define RBF_EXTERNAL (1<<28)
|
||||
#define RBF_UNKOWN (1<<27)
|
||||
#define RBF_SIZE 0x07ff
|
||||
#define RBF_LOCAL4 (1<<26)
|
||||
#define RBF_LOCAL3 (1<<25)
|
||||
#define RBF_LOCAL2 (1<<24)
|
||||
#define RBF_LOCAL1 (1<<23)
|
||||
|
||||
/* Emac Buffers in last 512KBytes of SDRAM*/
|
||||
/* Be careful, buffer size is limited to 512KBytes !!! */
|
||||
#define RBF_FRAMEMAX 100
|
||||
/*#define RBF_FRAMEMEM 0x200000 */
|
||||
#define RBF_FRAMEMEM 0x21F80000
|
||||
#define RBF_FRAMELEN 0x600
|
||||
|
||||
#define RBF_FRAMEBTD RBF_FRAMEMEM
|
||||
#define RBF_FRAMEBUF (RBF_FRAMEMEM + RBF_FRAMEMAX*sizeof(rbf_t))
|
||||
|
||||
|
||||
#ifdef CONFIG_DRIVER_ETHER
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NET)
|
||||
|
||||
/* structure to interface the PHY */
|
||||
AT91S_PhyOps AT91S_Dm9161Ops;
|
||||
AT91PS_PhyOps pPhyOps;
|
||||
|
||||
AT91PS_EMAC p_mac;
|
||||
|
||||
/*************************** Phy layer functions ************************/
|
||||
/** functions to interface the DAVICOM 10/100Mbps ethernet phy **********/
|
||||
|
||||
/*
|
||||
* Name:
|
||||
* dm9161_IsPhyConnected
|
||||
* Description:
|
||||
* Reads the 2 PHY ID registers
|
||||
* Arguments:
|
||||
* p_mac - pointer to AT91S_EMAC struct
|
||||
* Return value:
|
||||
* TRUE - if id read successfully
|
||||
* FALSE- if error
|
||||
*/
|
||||
static unsigned int dm9161_IsPhyConnected (AT91PS_EMAC p_mac)
|
||||
{
|
||||
unsigned short Id1, Id2;
|
||||
|
||||
at91rm9200_EmacEnableMDIO (p_mac);
|
||||
at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID1, &Id1);
|
||||
at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID2, &Id2);
|
||||
at91rm9200_EmacDisableMDIO (p_mac);
|
||||
|
||||
if ((Id1 == (DM9161_PHYID1_OUI >> 6)) &&
|
||||
((Id2 >> 10) == (DM9161_PHYID1_OUI & DM9161_LSB_MASK)))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Name:
|
||||
* dm9161_GetLinkSpeed
|
||||
* Description:
|
||||
* Link parallel detection status of MAC is checked and set in the
|
||||
* MAC configuration registers
|
||||
* Arguments:
|
||||
* p_mac - pointer to MAC
|
||||
* Return value:
|
||||
* TRUE - if link status set succesfully
|
||||
* FALSE - if link status not set
|
||||
*/
|
||||
static UCHAR dm9161_GetLinkSpeed (AT91PS_EMAC p_mac)
|
||||
{
|
||||
unsigned short stat1, stat2;
|
||||
|
||||
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &stat1))
|
||||
return FALSE;
|
||||
|
||||
if (!(stat1 & DM9161_LINK_STATUS)) /* link status up? */
|
||||
return FALSE;
|
||||
|
||||
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_DSCSR, &stat2))
|
||||
return FALSE;
|
||||
|
||||
if ((stat1 & DM9161_100BASE_TX_FD) && (stat2 & DM9161_100FDX)) {
|
||||
/*set Emac for 100BaseTX and Full Duplex */
|
||||
p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((stat1 & DM9161_10BASE_T_FD) && (stat2 & DM9161_10FDX)) {
|
||||
/*set MII for 10BaseT and Full Duplex */
|
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
|
||||
~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
|
||||
| AT91C_EMAC_FD;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((stat1 & DM9161_100BASE_T4_HD) && (stat2 & DM9161_100HDX)) {
|
||||
/*set MII for 100BaseTX and Half Duplex */
|
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
|
||||
~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
|
||||
| AT91C_EMAC_SPD;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((stat1 & DM9161_10BASE_T_HD) && (stat2 & DM9161_10HDX)) {
|
||||
/*set MII for 10BaseT and Half Duplex */
|
||||
p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Name:
|
||||
* dm9161_InitPhy
|
||||
* Description:
|
||||
* MAC starts checking its link by using parallel detection and
|
||||
* Autonegotiation and the same is set in the MAC configuration registers
|
||||
* Arguments:
|
||||
* p_mac - pointer to struct AT91S_EMAC
|
||||
* Return value:
|
||||
* TRUE - if link status set succesfully
|
||||
* FALSE - if link status not set
|
||||
*/
|
||||
static UCHAR dm9161_InitPhy (AT91PS_EMAC p_mac)
|
||||
{
|
||||
UCHAR ret = TRUE;
|
||||
unsigned short IntValue;
|
||||
|
||||
at91rm9200_EmacEnableMDIO (p_mac);
|
||||
|
||||
if (!dm9161_GetLinkSpeed (p_mac)) {
|
||||
/* Try another time */
|
||||
ret = dm9161_GetLinkSpeed (p_mac);
|
||||
}
|
||||
|
||||
/* Disable PHY Interrupts */
|
||||
at91rm9200_EmacReadPhy (p_mac, DM9161_MDINTR, &IntValue);
|
||||
/* clear FDX, SPD, Link, INTR masks */
|
||||
IntValue &= ~(DM9161_FDX_MASK | DM9161_SPD_MASK |
|
||||
DM9161_LINK_MASK | DM9161_INTR_MASK);
|
||||
at91rm9200_EmacWritePhy (p_mac, DM9161_MDINTR, &IntValue);
|
||||
at91rm9200_EmacDisableMDIO (p_mac);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Name:
|
||||
* dm9161_AutoNegotiate
|
||||
* Description:
|
||||
* MAC Autonegotiates with the partner status of same is set in the
|
||||
* MAC configuration registers
|
||||
* Arguments:
|
||||
* dev - pointer to struct net_device
|
||||
* Return value:
|
||||
* TRUE - if link status set successfully
|
||||
* FALSE - if link status not set
|
||||
*/
|
||||
static UCHAR dm9161_AutoNegotiate (AT91PS_EMAC p_mac, int *status)
|
||||
{
|
||||
unsigned short value;
|
||||
unsigned short PhyAnar;
|
||||
unsigned short PhyAnalpar;
|
||||
|
||||
/* Set dm9161 control register */
|
||||
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value))
|
||||
return FALSE;
|
||||
value &= ~DM9161_AUTONEG; /* remove autonegotiation enable */
|
||||
value |= DM9161_ISOLATE; /* Electrically isolate PHY */
|
||||
if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
|
||||
return FALSE;
|
||||
|
||||
/* Set the Auto_negotiation Advertisement Register */
|
||||
/* MII advertising for Next page, 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */
|
||||
PhyAnar = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX |
|
||||
DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3;
|
||||
if (!at91rm9200_EmacWritePhy (p_mac, DM9161_ANAR, &PhyAnar))
|
||||
return FALSE;
|
||||
|
||||
/* Read the Control Register */
|
||||
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value))
|
||||
return FALSE;
|
||||
|
||||
value |= DM9161_SPEED_SELECT | DM9161_AUTONEG | DM9161_DUPLEX_MODE;
|
||||
if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
|
||||
return FALSE;
|
||||
/* Restart Auto_negotiation */
|
||||
value |= DM9161_RESTART_AUTONEG;
|
||||
if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
|
||||
return FALSE;
|
||||
|
||||
/*check AutoNegotiate complete */
|
||||
udelay (10000);
|
||||
at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &value);
|
||||
if (!(value & DM9161_AUTONEG_COMP))
|
||||
return FALSE;
|
||||
|
||||
/* Get the AutoNeg Link partner base page */
|
||||
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_ANLPAR, &PhyAnalpar))
|
||||
return FALSE;
|
||||
|
||||
if ((PhyAnar & DM9161_TX_FDX) && (PhyAnalpar & DM9161_TX_FDX)) {
|
||||
/*set MII for 100BaseTX and Full Duplex */
|
||||
p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((PhyAnar & DM9161_10_FDX) && (PhyAnalpar & DM9161_10_FDX)) {
|
||||
/*set MII for 10BaseT and Full Duplex */
|
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
|
||||
~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
|
||||
| AT91C_EMAC_FD;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*********** EMAC Phy layer Management functions *************************/
|
||||
/*
|
||||
* Name:
|
||||
* at91rm9200_EmacEnableMDIO
|
||||
* Description:
|
||||
* Enables the MDIO bit in MAC control register
|
||||
* Arguments:
|
||||
* p_mac - pointer to struct AT91S_EMAC
|
||||
* Return value:
|
||||
* none
|
||||
*/
|
||||
static void at91rm9200_EmacEnableMDIO (AT91PS_EMAC p_mac)
|
||||
{
|
||||
/* Mac CTRL reg set for MDIO enable */
|
||||
p_mac->EMAC_CTL |= AT91C_EMAC_MPE; /* Management port enable */
|
||||
}
|
||||
|
||||
/*
|
||||
* Name:
|
||||
* at91rm9200_EmacDisableMDIO
|
||||
* Description:
|
||||
* Disables the MDIO bit in MAC control register
|
||||
* Arguments:
|
||||
* p_mac - pointer to struct AT91S_EMAC
|
||||
* Return value:
|
||||
* none
|
||||
*/
|
||||
static void at91rm9200_EmacDisableMDIO (AT91PS_EMAC p_mac)
|
||||
{
|
||||
/* Mac CTRL reg set for MDIO disable */
|
||||
p_mac->EMAC_CTL &= ~AT91C_EMAC_MPE; /* Management port disable */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Name:
|
||||
* at91rm9200_EmacReadPhy
|
||||
* Description:
|
||||
* Reads data from the PHY register
|
||||
* Arguments:
|
||||
* dev - pointer to struct net_device
|
||||
* RegisterAddress - unsigned char
|
||||
* pInput - pointer to value read from register
|
||||
* Return value:
|
||||
* TRUE - if data read successfully
|
||||
*/
|
||||
static UCHAR at91rm9200_EmacReadPhy (AT91PS_EMAC p_mac,
|
||||
unsigned char RegisterAddress,
|
||||
unsigned short *pInput)
|
||||
{
|
||||
p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) |
|
||||
(AT91C_EMAC_CODE_802_3) | (AT91C_EMAC_RW_R) |
|
||||
(RegisterAddress << 18);
|
||||
|
||||
udelay (10000);
|
||||
|
||||
*pInput = (unsigned short) p_mac->EMAC_MAN;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Name:
|
||||
* at91rm9200_EmacWritePhy
|
||||
* Description:
|
||||
* Writes data to the PHY register
|
||||
* Arguments:
|
||||
* dev - pointer to struct net_device
|
||||
* RegisterAddress - unsigned char
|
||||
* pOutput - pointer to value to be written in the register
|
||||
* Return value:
|
||||
* TRUE - if data read successfully
|
||||
*/
|
||||
static UCHAR at91rm9200_EmacWritePhy (AT91PS_EMAC p_mac,
|
||||
unsigned char RegisterAddress,
|
||||
unsigned short *pOutput)
|
||||
{
|
||||
p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) |
|
||||
AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_W |
|
||||
(RegisterAddress << 18);
|
||||
|
||||
udelay (10000);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Name:
|
||||
* at91rm92000_GetPhyInterface
|
||||
* Description:
|
||||
* Initialise the interface functions to the PHY
|
||||
* Arguments:
|
||||
* None
|
||||
* Return value:
|
||||
* None
|
||||
*/
|
||||
void at91rm92000_GetPhyInterface (void)
|
||||
{
|
||||
AT91S_Dm9161Ops.Init = dm9161_InitPhy;
|
||||
AT91S_Dm9161Ops.IsPhyConnected = dm9161_IsPhyConnected;
|
||||
AT91S_Dm9161Ops.GetLinkSpeed = dm9161_GetLinkSpeed;
|
||||
AT91S_Dm9161Ops.AutoNegotiate = dm9161_AutoNegotiate;
|
||||
|
||||
pPhyOps = (AT91PS_PhyOps) & AT91S_Dm9161Ops;
|
||||
}
|
||||
|
||||
|
||||
rbf_t *rbfdt;
|
||||
rbf_t *rbfp;
|
||||
|
||||
int eth_init (bd_t * bd)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
p_mac = AT91C_BASE_EMAC;
|
||||
|
||||
*AT91C_PIOA_PDR = AT91C_PA16_EMDIO | AT91C_PA15_EMDC | AT91C_PA14_ERXER | AT91C_PA13_ERX1 | AT91C_PA12_ERX0 | AT91C_PA11_ECRS_ECRSDV | AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN | AT91C_PA7_ETXCK_EREFCK; /* PIO Disable Register */
|
||||
|
||||
*AT91C_PIOB_PDR = AT91C_PB25_EF100 |
|
||||
AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV |
|
||||
AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER |
|
||||
AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
|
||||
|
||||
*AT91C_PIOB_BSR = AT91C_PB25_EF100 | AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2; /* Select B Register */
|
||||
|
||||
*AT91C_PMC_PCER = 1 << AT91C_ID_EMAC; /* Peripheral Clock Enable Register */
|
||||
|
||||
p_mac->EMAC_CFG |= AT91C_EMAC_CSR; /* Clear statistics */
|
||||
|
||||
/* Init Ehternet buffers */
|
||||
rbfdt = (rbf_t *) RBF_FRAMEBTD;
|
||||
for (i = 0; i < RBF_FRAMEMAX; i++) {
|
||||
rbfdt[i].addr = RBF_FRAMEBUF + RBF_FRAMELEN * i;
|
||||
rbfdt[i].size = 0;
|
||||
}
|
||||
rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP;
|
||||
rbfp = &rbfdt[0];
|
||||
|
||||
at91rm92000_GetPhyInterface ();
|
||||
|
||||
if (!pPhyOps->IsPhyConnected (p_mac))
|
||||
printf ("PHY not connected!!\n\r");
|
||||
|
||||
/* MII management start from here */
|
||||
if (!(p_mac->EMAC_SR & AT91C_EMAC_LINK)) {
|
||||
if (!(ret = pPhyOps->Init (p_mac))) {
|
||||
printf ("MAC: error during MII initialization\n");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
printf ("No link\n\r");
|
||||
return 0;
|
||||
}
|
||||
|
||||
p_mac->EMAC_SA2L = (bd->bi_enetaddr[3] << 24) | (bd->bi_enetaddr[2] << 16)
|
||||
| (bd->bi_enetaddr[1] << 8) | (bd->bi_enetaddr[0]);
|
||||
p_mac->EMAC_SA2H = (bd->bi_enetaddr[5] << 8) | (bd->bi_enetaddr[4]);
|
||||
|
||||
p_mac->EMAC_RBQP = (long) (&rbfdt[0]);
|
||||
p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
|
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC | AT91C_EMAC_RMII)
|
||||
& ~AT91C_EMAC_CLK;
|
||||
p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eth_send (volatile void *packet, int length)
|
||||
{
|
||||
while (!(p_mac->EMAC_TSR & AT91C_EMAC_BNQ));
|
||||
p_mac->EMAC_TAR = (long) packet;
|
||||
p_mac->EMAC_TCR = length;
|
||||
while (p_mac->EMAC_TCR & 0x7ff);
|
||||
p_mac->EMAC_TSR |= AT91C_EMAC_COMP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eth_rx (void)
|
||||
{
|
||||
int size;
|
||||
|
||||
if (!(rbfp->addr & RBF_OWNER))
|
||||
return 0;
|
||||
|
||||
size = rbfp->size & RBF_SIZE;
|
||||
NetReceive ((volatile uchar *) (rbfp->addr & RBF_ADDR), size);
|
||||
|
||||
rbfp->addr &= ~RBF_OWNER;
|
||||
if (rbfp->addr & RBF_WRAP)
|
||||
rbfp = &rbfdt[0];
|
||||
else
|
||||
rbfp++;
|
||||
|
||||
p_mac->EMAC_RSR |= AT91C_EMAC_REC;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void eth_halt (void)
|
||||
{
|
||||
};
|
||||
#endif /* CONFIG_COMMANDS & CFG_CMD_NET */
|
||||
#endif /* CONFIG_DRIVER_ETHER */
|
||||
@@ -35,7 +35,7 @@ include $(TOPDIR)/config.mk
|
||||
LIB = lib$(CPU).a
|
||||
|
||||
START = start.S
|
||||
OBJS = serial.o cpu.o cpu_init.o interrupts.o traps.o speed.o status_led.o
|
||||
OBJS = serial.o cpu.o cpu_init.o interrupts.o traps.o speed.o
|
||||
|
||||
all: .depend $(START) $(LIB)
|
||||
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2002 Wolfgang Denk, DENX Software Engineering, wd@denx.de
|
||||
* (C) Copyright 2003 Martin Winistoerfer, martinwinistoerfer@gmx.ch.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: status_led.c
|
||||
*
|
||||
* Discription: Blink a board led to show boot progress. Led's
|
||||
* are connected via the MIOS module.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc5xx.h>
|
||||
#include <status_led.h>
|
||||
|
||||
#ifdef CONFIG_STATUS_LED
|
||||
|
||||
typedef struct {
|
||||
ulong mask;
|
||||
int state;
|
||||
int period;
|
||||
int cnt;
|
||||
} led_dev_t;
|
||||
|
||||
led_dev_t led_dev[] = {
|
||||
{ STATUS_LED_BIT,
|
||||
STATUS_LED_STATE,
|
||||
STATUS_LED_PERIOD,
|
||||
0,
|
||||
},
|
||||
#if defined(STATUS_LED_BIT1)
|
||||
{ STATUS_LED_BIT1,
|
||||
STATUS_LED_STATE1,
|
||||
STATUS_LED_PERIOD1,
|
||||
0,
|
||||
},
|
||||
#endif
|
||||
#if defined(STATUS_LED_BIT2)
|
||||
{ STATUS_LED_BIT2,
|
||||
STATUS_LED_STATE2,
|
||||
STATUS_LED_PERIOD2,
|
||||
0,
|
||||
},
|
||||
#endif
|
||||
#if defined(STATUS_LED_BIT3)
|
||||
{ STATUS_LED_BIT3,
|
||||
STATUS_LED_STATE3,
|
||||
STATUS_LED_PERIOD3,
|
||||
0,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
#define MAX_LED_DEV (sizeof(led_dev)/sizeof(led_dev_t))
|
||||
|
||||
static int status_led_init_done = 0;
|
||||
|
||||
static void status_led_init (void)
|
||||
{
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_LED_DEV; ++i) {
|
||||
led_dev_t *ld = &led_dev[i];
|
||||
|
||||
immr->STATUS_LED_DIR = STATUS_LED_BIT;
|
||||
|
||||
#if (STATUS_LED_ACTIVE == 0)
|
||||
if (ld->state == STATUS_LED_ON)
|
||||
immr->STATUS_LED_DAT &= ~(ld->mask);
|
||||
else
|
||||
immr->STATUS_LED_DAT |= ld->mask ;
|
||||
#else
|
||||
if (ld->state == STATUS_LED_ON)
|
||||
immr->STATUS_LED_DAT |= ld->mask ;
|
||||
else
|
||||
immr->STATUS_LED_DAT &= ~(ld->mask);
|
||||
#endif
|
||||
}
|
||||
|
||||
status_led_init_done = 1;
|
||||
}
|
||||
|
||||
void status_led_tick (ulong timestamp)
|
||||
{
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
int i;
|
||||
|
||||
if (!status_led_init_done)
|
||||
status_led_init();
|
||||
|
||||
for (i=0; i<MAX_LED_DEV; ++i) {
|
||||
led_dev_t *ld = &led_dev[i];
|
||||
|
||||
if (ld->state != STATUS_LED_BLINKING)
|
||||
continue;
|
||||
|
||||
if (++(ld->cnt) >= ld->period) {
|
||||
immr->STATUS_LED_DAT ^= ld->mask;
|
||||
ld->cnt -= ld->period;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void status_led_set (int led, int state)
|
||||
{
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
led_dev_t *ld;
|
||||
|
||||
if (led < 0 || led >= MAX_LED_DEV)
|
||||
return;
|
||||
|
||||
if (!status_led_init_done)
|
||||
status_led_init();
|
||||
|
||||
ld = &led_dev[led];
|
||||
|
||||
switch (state) {
|
||||
default:
|
||||
return;
|
||||
case STATUS_LED_BLINKING:
|
||||
ld->cnt = 0; /* always start with full period */
|
||||
/* fall through */ /* always start with LED _ON_ */
|
||||
case STATUS_LED_ON:
|
||||
#if (STATUS_LED_ACTIVE == 0)
|
||||
immr->STATUS_LED_DAT &= ~(ld->mask);
|
||||
#else
|
||||
immr->STATUS_LED_DAT |= ld->mask ;
|
||||
#endif
|
||||
break;
|
||||
case STATUS_LED_OFF:
|
||||
#if (STATUS_LED_ACTIVE == 0)
|
||||
immr->STATUS_LED_DAT |= ld->mask ;
|
||||
#else
|
||||
immr->STATUS_LED_DAT &= ~(ld->mask);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
ld->state = state;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_STATUS_LED */
|
||||
@@ -28,7 +28,7 @@ LIB = lib$(CPU).a
|
||||
START = start.o kgdb.o
|
||||
OBJS = traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \
|
||||
interrupts.o ether_scc.o ether_fcc.o i2c.o commproc.o \
|
||||
bedbug_603e.o status_led.o pci.o spi.o
|
||||
bedbug_603e.o pci.o spi.o
|
||||
|
||||
all: .depend $(START) $(LIB)
|
||||
|
||||
|
||||
@@ -23,5 +23,5 @@
|
||||
|
||||
PLATFORM_RELFLAGS += -mrelocatable -ffixed-r14 -meabi
|
||||
|
||||
PLATFORM_CPPFLAGS += -DCONFIG_8260 -ffixed-r2 -ffixed-r29 -mstring
|
||||
##PLATFORM_CPPFLAGS += -DCONFIG_8260 -ffixed-r2 -mstring
|
||||
PLATFORM_CPPFLAGS += -DCONFIG_8260 -ffixed-r2 -ffixed-r29 \
|
||||
-mstring -mcpu=603e -mmultiple
|
||||
|
||||
@@ -80,9 +80,9 @@ static void config_8260_ioports (volatile immap_t * immr)
|
||||
*/
|
||||
iop->ppar &= tpmsk;
|
||||
iop->psor = (iop->psor & tpmsk) | psor;
|
||||
iop->podr = (iop->podr & tpmsk) | podr;
|
||||
iop->pdat = (iop->pdat & tpmsk) | pdat;
|
||||
iop->pdir = (iop->pdir & tpmsk) | pdir;
|
||||
iop->podr = (iop->podr & tpmsk) | podr;
|
||||
iop->ppar |= ppar;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,4 +391,761 @@ int fec_initialize(bd_t *bis)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ETHER_LOOPBACK_TEST
|
||||
|
||||
#define ELBT_BUFSZ 1024 /* must be multiple of 32 */
|
||||
|
||||
#define ELBT_CRCSZ 4
|
||||
|
||||
#define ELBT_NRXBD 4 /* must be at least 2 */
|
||||
#define ELBT_NTXBD 4
|
||||
|
||||
#define ELBT_MAXRXERR 32
|
||||
#define ELBT_MAXTXERR 32
|
||||
|
||||
#define ELBT_CLSWAIT 1000 /* msec to wait for further input frames */
|
||||
|
||||
typedef
|
||||
struct {
|
||||
uint off;
|
||||
char *lab;
|
||||
}
|
||||
elbt_prdesc;
|
||||
|
||||
typedef
|
||||
struct {
|
||||
uint _l, _f, m, bc, mc, lg, no, sh, cr, ov, cl;
|
||||
uint badsrc, badtyp, badlen, badbit;
|
||||
}
|
||||
elbt_rxeacc;
|
||||
|
||||
static elbt_prdesc rxeacc_descs[] = {
|
||||
{ offsetof(elbt_rxeacc, _l), "Not Last in Frame" },
|
||||
{ offsetof(elbt_rxeacc, _f), "Not First in Frame" },
|
||||
{ offsetof(elbt_rxeacc, m), "Address Miss" },
|
||||
{ offsetof(elbt_rxeacc, bc), "Broadcast Address" },
|
||||
{ offsetof(elbt_rxeacc, mc), "Multicast Address" },
|
||||
{ offsetof(elbt_rxeacc, lg), "Frame Length Violation"},
|
||||
{ offsetof(elbt_rxeacc, no), "Non-Octet Alignment" },
|
||||
{ offsetof(elbt_rxeacc, sh), "Short Frame" },
|
||||
{ offsetof(elbt_rxeacc, cr), "CRC Error" },
|
||||
{ offsetof(elbt_rxeacc, ov), "Overrun" },
|
||||
{ offsetof(elbt_rxeacc, cl), "Collision" },
|
||||
{ offsetof(elbt_rxeacc, badsrc), "Bad Src Address" },
|
||||
{ offsetof(elbt_rxeacc, badtyp), "Bad Frame Type" },
|
||||
{ offsetof(elbt_rxeacc, badlen), "Bad Frame Length" },
|
||||
{ offsetof(elbt_rxeacc, badbit), "Data Compare Errors" },
|
||||
};
|
||||
static int rxeacc_ndesc = sizeof (rxeacc_descs) / sizeof (rxeacc_descs[0]);
|
||||
|
||||
typedef
|
||||
struct {
|
||||
uint def, hb, lc, rl, rc, un, csl;
|
||||
}
|
||||
elbt_txeacc;
|
||||
|
||||
static elbt_prdesc txeacc_descs[] = {
|
||||
{ offsetof(elbt_txeacc, def), "Defer Indication" },
|
||||
{ offsetof(elbt_txeacc, hb), "Heartbeat" },
|
||||
{ offsetof(elbt_txeacc, lc), "Late Collision" },
|
||||
{ offsetof(elbt_txeacc, rl), "Retransmission Limit" },
|
||||
{ offsetof(elbt_txeacc, rc), "Retry Count" },
|
||||
{ offsetof(elbt_txeacc, un), "Underrun" },
|
||||
{ offsetof(elbt_txeacc, csl), "Carrier Sense Lost" },
|
||||
};
|
||||
static int txeacc_ndesc = sizeof (txeacc_descs) / sizeof (txeacc_descs[0]);
|
||||
|
||||
typedef
|
||||
struct {
|
||||
uchar rxbufs[ELBT_NRXBD][ELBT_BUFSZ];
|
||||
uchar txbufs[ELBT_NTXBD][ELBT_BUFSZ];
|
||||
cbd_t rxbd[ELBT_NRXBD];
|
||||
cbd_t txbd[ELBT_NTXBD];
|
||||
enum { Idle, Running, Closing, Closed } state;
|
||||
int proff, page, sblock;
|
||||
uint clstime, nsent, ntxerr, nrcvd, nrxerr;
|
||||
ushort rxerrs[ELBT_MAXRXERR], txerrs[ELBT_MAXTXERR];
|
||||
elbt_rxeacc rxeacc;
|
||||
elbt_txeacc txeacc;
|
||||
} __attribute__ ((aligned(8)))
|
||||
elbt_chan;
|
||||
|
||||
static uchar patbytes[ELBT_NTXBD] = {
|
||||
0xff, 0xaa, 0x55, 0x00
|
||||
};
|
||||
static uint patwords[ELBT_NTXBD] = {
|
||||
0xffffffff, 0xaaaaaaaa, 0x55555555, 0x00000000
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
static elbt_chan elbt_chans[3] __attribute__ ((aligned(8)));
|
||||
#else
|
||||
#error "elbt_chans must be 64-bit aligned"
|
||||
#endif
|
||||
|
||||
#define CPM_CR_GRACEFUL_STOP_TX ((ushort)0x0005)
|
||||
|
||||
static elbt_prdesc epram_descs[] = {
|
||||
{ offsetof(fcc_enet_t, fen_crcec), "CRC Errors" },
|
||||
{ offsetof(fcc_enet_t, fen_alec), "Alignment Errors" },
|
||||
{ offsetof(fcc_enet_t, fen_disfc), "Discarded Frames" },
|
||||
{ offsetof(fcc_enet_t, fen_octc), "Octets" },
|
||||
{ offsetof(fcc_enet_t, fen_colc), "Collisions" },
|
||||
{ offsetof(fcc_enet_t, fen_broc), "Broadcast Frames" },
|
||||
{ offsetof(fcc_enet_t, fen_mulc), "Multicast Frames" },
|
||||
{ offsetof(fcc_enet_t, fen_uspc), "Undersize Frames" },
|
||||
{ offsetof(fcc_enet_t, fen_frgc), "Fragments" },
|
||||
{ offsetof(fcc_enet_t, fen_ospc), "Oversize Frames" },
|
||||
{ offsetof(fcc_enet_t, fen_jbrc), "Jabbers" },
|
||||
{ offsetof(fcc_enet_t, fen_p64c), "64 Octet Frames" },
|
||||
{ offsetof(fcc_enet_t, fen_p65c), "65-127 Octet Frames" },
|
||||
{ offsetof(fcc_enet_t, fen_p128c), "128-255 Octet Frames" },
|
||||
{ offsetof(fcc_enet_t, fen_p256c), "256-511 Octet Frames" },
|
||||
{ offsetof(fcc_enet_t, fen_p512c), "512-1023 Octet Frames" },
|
||||
{ offsetof(fcc_enet_t, fen_p1024c), "1024-1518 Octet Frames"},
|
||||
};
|
||||
static int epram_ndesc = sizeof (epram_descs) / sizeof (epram_descs[0]);
|
||||
|
||||
/*
|
||||
* given an elbt_prdesc array and an array of base addresses, print
|
||||
* each prdesc down the screen with the values fetched from each
|
||||
* base address across the screen
|
||||
*/
|
||||
static void
|
||||
print_desc (elbt_prdesc descs[], int ndesc, uchar *bases[], int nbase)
|
||||
{
|
||||
elbt_prdesc *dp = descs, *edp = dp + ndesc;
|
||||
int i;
|
||||
|
||||
printf ("%32s", "");
|
||||
|
||||
for (i = 0; i < nbase; i++)
|
||||
printf (" Channel %d", i);
|
||||
|
||||
puts ("\n");
|
||||
|
||||
while (dp < edp) {
|
||||
|
||||
printf ("%-32s", dp->lab);
|
||||
|
||||
for (i = 0; i < nbase; i++) {
|
||||
uint val = *(uint *)(bases[i] + dp->off);
|
||||
|
||||
printf (" %10u", val);
|
||||
}
|
||||
|
||||
puts ("\n");
|
||||
|
||||
dp++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* return number of bits that are set in a value; value contains
|
||||
* nbits (right-justified) bits.
|
||||
*/
|
||||
static uint __inline__
|
||||
nbs (uint value, uint nbits)
|
||||
{
|
||||
uint cnt = 0;
|
||||
#if 1
|
||||
uint pos = sizeof (uint) * 8;
|
||||
|
||||
__asm__ __volatile__ ("\
|
||||
mtctr %2\n\
|
||||
1: rlwnm. %2,%1,%4,31,31\n\
|
||||
beq 2f\n\
|
||||
addi %0,%0,1\n\
|
||||
2: subi %4,%4,1\n\
|
||||
bdnz 1b"
|
||||
: "=r"(cnt)
|
||||
: "r"(value), "r"(nbits), "r"(cnt), "r"(pos)
|
||||
: "ctr", "cc" );
|
||||
#else
|
||||
uint mask = 1;
|
||||
|
||||
do {
|
||||
if (value & mask)
|
||||
cnt++;
|
||||
mask <<= 1;
|
||||
} while (--nbits);
|
||||
#endif
|
||||
|
||||
return (cnt);
|
||||
}
|
||||
|
||||
static ulong
|
||||
badbits (uchar *bp, int n, ulong pat)
|
||||
{
|
||||
ulong *lp, cnt = 0;
|
||||
int nl;
|
||||
|
||||
while (n > 0 && ((ulong)bp & (sizeof (ulong) - 1)) != 0) {
|
||||
uchar diff;
|
||||
|
||||
diff = *bp++ ^ (uchar)pat;
|
||||
|
||||
if (diff)
|
||||
cnt += nbs ((ulong)diff, 8);
|
||||
|
||||
n--;
|
||||
}
|
||||
|
||||
lp = (ulong *)bp;
|
||||
nl = n / sizeof (ulong);
|
||||
n -= nl * sizeof (ulong);
|
||||
|
||||
while (nl > 0) {
|
||||
ulong diff;
|
||||
|
||||
diff = *lp++ ^ pat;
|
||||
|
||||
if (diff)
|
||||
cnt += nbs (diff, 32);
|
||||
|
||||
nl--;
|
||||
}
|
||||
|
||||
bp = (uchar *)lp;
|
||||
|
||||
while (n > 0) {
|
||||
uchar diff;
|
||||
|
||||
diff = *bp++ ^ (uchar)pat;
|
||||
|
||||
if (diff)
|
||||
cnt += nbs ((ulong)diff, 8);
|
||||
|
||||
n--;
|
||||
}
|
||||
|
||||
return (cnt);
|
||||
}
|
||||
|
||||
static inline unsigned short
|
||||
swap16 (unsigned short x)
|
||||
{
|
||||
return (((x & 0xff) << 8) | ((x & 0xff00) >> 8));
|
||||
}
|
||||
|
||||
void
|
||||
eth_loopback_test (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
volatile cpm8260_t *cp = &(immr->im_cpm);
|
||||
int c, nclosed;
|
||||
ulong runtime, nmsec;
|
||||
uchar *bases[3];
|
||||
|
||||
puts ("FCC Ethernet External loopback test\n");
|
||||
|
||||
memcpy (NetOurEther, gd->bd->bi_enetaddr, 6);
|
||||
|
||||
/*
|
||||
* global initialisations for all FCC channels
|
||||
*/
|
||||
|
||||
/* 28.9 - (1-2): ioports have been set up already */
|
||||
|
||||
#if defined(CONFIG_HYMOD)
|
||||
/*
|
||||
* Attention: this is board-specific
|
||||
* - FCC1 Rx-CLK is CLK10
|
||||
* - FCC1 Tx-CLK is CLK11
|
||||
* - FCC2 Rx-CLK is CLK13
|
||||
* - FCC2 Tx-CLK is CLK14
|
||||
* - FCC3 Rx-CLK is CLK15
|
||||
* - FCC3 Tx-CLK is CLK16
|
||||
*/
|
||||
|
||||
/* 28.9 - (3): connect FCC's tx and rx clocks */
|
||||
immr->im_cpmux.cmx_uar = 0;
|
||||
immr->im_cpmux.cmx_fcr = CMXFCR_RF1CS_CLK10|CMXFCR_TF1CS_CLK11|\
|
||||
CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14|\
|
||||
CMXFCR_RF3CS_CLK15|CMXFCR_TF3CS_CLK16;
|
||||
#else
|
||||
#error "eth_loopback_test not supported on your board"
|
||||
#endif
|
||||
|
||||
puts ("Initialise FCC channels:");
|
||||
|
||||
for (c = 0; c < 3; c++) {
|
||||
elbt_chan *ecp = &elbt_chans[c];
|
||||
volatile fcc_t *fcp = &immr->im_fcc[c];
|
||||
volatile fcc_enet_t *fpp;
|
||||
int i;
|
||||
ulong addr;
|
||||
|
||||
/*
|
||||
* initialise channel data
|
||||
*/
|
||||
|
||||
printf (" %d", c);
|
||||
|
||||
memset ((void *)ecp, 0, sizeof (*ecp));
|
||||
|
||||
ecp->state = Idle;
|
||||
|
||||
switch (c) {
|
||||
|
||||
case 0: /* FCC1 */
|
||||
ecp->proff = PROFF_FCC1;
|
||||
ecp->page = CPM_CR_FCC1_PAGE;
|
||||
ecp->sblock = CPM_CR_FCC1_SBLOCK;
|
||||
break;
|
||||
|
||||
case 1: /* FCC2 */
|
||||
ecp->proff = PROFF_FCC2;
|
||||
ecp->page = CPM_CR_FCC2_PAGE;
|
||||
ecp->sblock = CPM_CR_FCC2_SBLOCK;
|
||||
break;
|
||||
|
||||
case 2: /* FCC3 */
|
||||
ecp->proff = PROFF_FCC3;
|
||||
ecp->page = CPM_CR_FCC3_PAGE;
|
||||
ecp->sblock = CPM_CR_FCC3_SBLOCK;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* set up tx buffers and bds
|
||||
*/
|
||||
|
||||
for (i = 0; i < ELBT_NTXBD; i++) {
|
||||
cbd_t *bdp = &ecp->txbd[i];
|
||||
uchar *bp = &ecp->txbufs[i][0];
|
||||
|
||||
bdp->cbd_bufaddr = (uint)bp;
|
||||
/* room for crc */
|
||||
bdp->cbd_datlen = ELBT_BUFSZ - ELBT_CRCSZ;
|
||||
bdp->cbd_sc = BD_ENET_TX_READY | BD_ENET_TX_PAD | \
|
||||
BD_ENET_TX_LAST | BD_ENET_TX_TC;
|
||||
|
||||
memset ((void *)bp, patbytes[i], ELBT_BUFSZ);
|
||||
NetSetEther (bp, NetBcastAddr, 0x8000);
|
||||
}
|
||||
ecp->txbd[ELBT_NTXBD - 1].cbd_sc |= BD_ENET_TX_WRAP;
|
||||
|
||||
/*
|
||||
* set up rx buffers and bds
|
||||
*/
|
||||
|
||||
for (i = 0; i < ELBT_NRXBD; i++) {
|
||||
cbd_t *bdp = &ecp->rxbd[i];
|
||||
uchar *bp = &ecp->rxbufs[i][0];
|
||||
|
||||
bdp->cbd_bufaddr = (uint)bp;
|
||||
bdp->cbd_datlen = 0;
|
||||
bdp->cbd_sc = BD_ENET_RX_EMPTY;
|
||||
|
||||
memset ((void *)bp, 0, ELBT_BUFSZ);
|
||||
}
|
||||
ecp->rxbd[ELBT_NRXBD - 1].cbd_sc |= BD_ENET_RX_WRAP;
|
||||
|
||||
/*
|
||||
* set up the FCC channel hardware
|
||||
*/
|
||||
|
||||
/* 28.9 - (4): GFMR: disable tx/rx, CCITT CRC, Mode Ethernet */
|
||||
fcp->fcc_gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
|
||||
|
||||
/* 28.9 - (5): FPSMR: fd, enet CRC, Promis, RMON, Rx SHort */
|
||||
fcp->fcc_fpsmr = FCC_PSMR_FDE | FCC_PSMR_LPB | \
|
||||
FCC_PSMR_ENCRC | FCC_PSMR_PRO | \
|
||||
FCC_PSMR_MON | FCC_PSMR_RSH;
|
||||
|
||||
/* 28.9 - (6): FDSR: Ethernet Syn */
|
||||
fcp->fcc_fdsr = 0xD555;
|
||||
|
||||
/* 29.9 - (7): initialise parameter ram */
|
||||
fpp = (fcc_enet_t *)&(immr->im_dprambase[ecp->proff]);
|
||||
|
||||
/* clear whole struct to make sure all resv fields are zero */
|
||||
memset ((void *)fpp, 0, sizeof (fcc_enet_t));
|
||||
|
||||
/*
|
||||
* common Parameter RAM area
|
||||
*
|
||||
* Allocate space in the reserved FCC area of DPRAM for the
|
||||
* internal buffers. No one uses this space (yet), so we
|
||||
* can do this. Later, we will add resource management for
|
||||
* this area.
|
||||
*/
|
||||
addr = CPM_FCC_SPECIAL_BASE + (c * 64);
|
||||
fpp->fen_genfcc.fcc_riptr = addr;
|
||||
fpp->fen_genfcc.fcc_tiptr = addr + 32;
|
||||
|
||||
/*
|
||||
* Set maximum bytes per receive buffer.
|
||||
* It must be a multiple of 32.
|
||||
* buffers are in 60x bus memory.
|
||||
*/
|
||||
fpp->fen_genfcc.fcc_mrblr = PKT_MAXBLR_SIZE;
|
||||
fpp->fen_genfcc.fcc_rstate = (CPMFCR_GBL | CPMFCR_EB) << 24;
|
||||
fpp->fen_genfcc.fcc_rbase = (unsigned int)(&ecp->rxbd[0]);
|
||||
fpp->fen_genfcc.fcc_tstate = (CPMFCR_GBL | CPMFCR_EB) << 24;
|
||||
fpp->fen_genfcc.fcc_tbase = (unsigned int)(&ecp->txbd[0]);
|
||||
|
||||
/* protocol-specific area */
|
||||
fpp->fen_cmask = 0xdebb20e3; /* CRC mask */
|
||||
fpp->fen_cpres = 0xffffffff; /* CRC preset */
|
||||
fpp->fen_retlim = 15; /* Retry limit threshold */
|
||||
fpp->fen_mflr = PKT_MAXBUF_SIZE;/* max frame length register */
|
||||
|
||||
/*
|
||||
* Set Ethernet station address.
|
||||
*
|
||||
* This is supplied in the board information structure, so we
|
||||
* copy that into the controller.
|
||||
* So, far we have only been given one Ethernet address. We use
|
||||
* the same address for all channels
|
||||
*/
|
||||
#define ea gd->bd->bi_enetaddr
|
||||
fpp->fen_paddrh = (ea[5] << 8) + ea[4];
|
||||
fpp->fen_paddrm = (ea[3] << 8) + ea[2];
|
||||
fpp->fen_paddrl = (ea[1] << 8) + ea[0];
|
||||
#undef ea
|
||||
|
||||
fpp->fen_minflr = PKT_MINBUF_SIZE; /* min frame len register */
|
||||
/*
|
||||
* pad pointer. use tiptr since we don't need
|
||||
* a specific padding char
|
||||
*/
|
||||
fpp->fen_padptr = fpp->fen_genfcc.fcc_tiptr;
|
||||
fpp->fen_maxd1 = PKT_MAXDMA_SIZE; /* max DMA1 length */
|
||||
fpp->fen_maxd2 = PKT_MAXDMA_SIZE; /* max DMA2 length */
|
||||
fpp->fen_rfthr = 1;
|
||||
fpp->fen_rfcnt = 1;
|
||||
|
||||
/* 28.9 - (8): clear out events in FCCE */
|
||||
fcp->fcc_fcce = ~0x0;
|
||||
|
||||
/* 28.9 - (9): FCCM: mask all events */
|
||||
fcp->fcc_fccm = 0;
|
||||
|
||||
/* 28.9 - (10-12): we don't use ethernet interrupts */
|
||||
|
||||
/* 28.9 - (13)
|
||||
*
|
||||
* Let's re-initialize the channel now. We have to do it later
|
||||
* than the manual describes because we have just now finished
|
||||
* the BD initialization.
|
||||
*/
|
||||
cp->cp_cpcr = mk_cr_cmd (ecp->page, ecp->sblock, \
|
||||
0x0c, CPM_CR_INIT_TRX) | CPM_CR_FLG;
|
||||
do {
|
||||
__asm__ __volatile__ ("eieio");
|
||||
} while (cp->cp_cpcr & CPM_CR_FLG);
|
||||
}
|
||||
|
||||
puts (" done\nStarting test... (Ctrl-C to Finish)\n");
|
||||
|
||||
/*
|
||||
* Note: don't want serial output from here until the end of the
|
||||
* test - the delays would probably stuff things up.
|
||||
*/
|
||||
|
||||
clear_ctrlc ();
|
||||
runtime = get_timer (0);
|
||||
|
||||
do {
|
||||
nclosed = 0;
|
||||
|
||||
for (c = 0; c < 3; c++) {
|
||||
volatile fcc_t *fcp = &immr->im_fcc[c];
|
||||
elbt_chan *ecp = &elbt_chans[c];
|
||||
int i;
|
||||
|
||||
switch (ecp->state) {
|
||||
|
||||
case Idle:
|
||||
/*
|
||||
* set the channel Running ...
|
||||
*/
|
||||
|
||||
/* 28.9 - (14): enable tx/rx in gfmr */
|
||||
fcp->fcc_gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
|
||||
|
||||
ecp->state = Running;
|
||||
break;
|
||||
|
||||
case Running:
|
||||
/*
|
||||
* (while Running only) check for
|
||||
* termination of the test
|
||||
*/
|
||||
|
||||
(void)ctrlc ();
|
||||
|
||||
if (had_ctrlc ()) {
|
||||
/*
|
||||
* initiate a "graceful stop transmit"
|
||||
* on the channel
|
||||
*/
|
||||
cp->cp_cpcr = mk_cr_cmd (ecp->page, \
|
||||
ecp->sblock, 0x0c, \
|
||||
CPM_CR_GRACEFUL_STOP_TX) | \
|
||||
CPM_CR_FLG;
|
||||
do {
|
||||
__asm__ __volatile__ ("eieio");
|
||||
} while (cp->cp_cpcr & CPM_CR_FLG);
|
||||
|
||||
ecp->clstime = get_timer (0);
|
||||
ecp->state = Closing;
|
||||
}
|
||||
/* fall through ... */
|
||||
|
||||
case Closing:
|
||||
/*
|
||||
* (while Running or Closing) poll the channel:
|
||||
* - check for any non-READY tx buffers and
|
||||
* make them ready
|
||||
* - check for any non-EMPTY rx buffers and
|
||||
* check that they were received correctly,
|
||||
* adjust counters etc, then make empty
|
||||
*/
|
||||
|
||||
for (i = 0; i < ELBT_NTXBD; i++) {
|
||||
cbd_t *bdp = &ecp->txbd[i];
|
||||
ushort sc = bdp->cbd_sc;
|
||||
|
||||
if ((sc & BD_ENET_TX_READY) != 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* this frame has finished
|
||||
* transmitting
|
||||
*/
|
||||
ecp->nsent++;
|
||||
|
||||
if (sc & BD_ENET_TX_STATS) {
|
||||
ulong n;
|
||||
|
||||
/*
|
||||
* we had an error on
|
||||
* the transmission
|
||||
*/
|
||||
n = ecp->ntxerr++;
|
||||
if (n < ELBT_MAXTXERR)
|
||||
ecp->txerrs[n] = sc;
|
||||
|
||||
if (sc & BD_ENET_TX_DEF)
|
||||
ecp->txeacc.def++;
|
||||
if (sc & BD_ENET_TX_HB)
|
||||
ecp->txeacc.hb++;
|
||||
if (sc & BD_ENET_TX_LC)
|
||||
ecp->txeacc.lc++;
|
||||
if (sc & BD_ENET_TX_RL)
|
||||
ecp->txeacc.rl++;
|
||||
if (sc & BD_ENET_TX_RCMASK)
|
||||
ecp->txeacc.rc++;
|
||||
if (sc & BD_ENET_TX_UN)
|
||||
ecp->txeacc.un++;
|
||||
if (sc & BD_ENET_TX_CSL)
|
||||
ecp->txeacc.csl++;
|
||||
|
||||
bdp->cbd_sc &= \
|
||||
~BD_ENET_TX_STATS;
|
||||
}
|
||||
|
||||
if (ecp->state == Closing)
|
||||
ecp->clstime = get_timer (0);
|
||||
|
||||
/* make it ready again */
|
||||
bdp->cbd_sc |= BD_ENET_TX_READY;
|
||||
}
|
||||
|
||||
for (i = 0; i < ELBT_NRXBD; i++) {
|
||||
cbd_t *bdp = &ecp->rxbd[i];
|
||||
ushort sc = bdp->cbd_sc, mask;
|
||||
|
||||
if ((sc & BD_ENET_RX_EMPTY) != 0)
|
||||
continue;
|
||||
|
||||
/* we have a new frame in this buffer */
|
||||
ecp->nrcvd++;
|
||||
|
||||
mask = BD_ENET_RX_LAST|BD_ENET_RX_FIRST;
|
||||
if ((sc & mask) != mask) {
|
||||
/* somethings wrong here ... */
|
||||
if (!(sc & BD_ENET_RX_LAST))
|
||||
ecp->rxeacc._l++;
|
||||
if (!(sc & BD_ENET_RX_FIRST))
|
||||
ecp->rxeacc._f++;
|
||||
}
|
||||
|
||||
if (sc & BD_ENET_RX_STATS) {
|
||||
ulong n;
|
||||
|
||||
/*
|
||||
* we had some sort of error
|
||||
* on the frame
|
||||
*/
|
||||
n = ecp->nrxerr++;
|
||||
if (n < ELBT_MAXRXERR)
|
||||
ecp->rxerrs[n] = sc;
|
||||
|
||||
if (sc & BD_ENET_RX_MISS)
|
||||
ecp->rxeacc.m++;
|
||||
if (sc & BD_ENET_RX_BC)
|
||||
ecp->rxeacc.bc++;
|
||||
if (sc & BD_ENET_RX_MC)
|
||||
ecp->rxeacc.mc++;
|
||||
if (sc & BD_ENET_RX_LG)
|
||||
ecp->rxeacc.lg++;
|
||||
if (sc & BD_ENET_RX_NO)
|
||||
ecp->rxeacc.no++;
|
||||
if (sc & BD_ENET_RX_SH)
|
||||
ecp->rxeacc.sh++;
|
||||
if (sc & BD_ENET_RX_CR)
|
||||
ecp->rxeacc.cr++;
|
||||
if (sc & BD_ENET_RX_OV)
|
||||
ecp->rxeacc.ov++;
|
||||
if (sc & BD_ENET_RX_CL)
|
||||
ecp->rxeacc.cl++;
|
||||
|
||||
bdp->cbd_sc &= \
|
||||
~BD_ENET_RX_STATS;
|
||||
}
|
||||
else {
|
||||
ushort datlen = bdp->cbd_datlen;
|
||||
Ethernet_t *ehp;
|
||||
ushort prot;
|
||||
int ours, tb, n, nbytes;
|
||||
|
||||
ehp = (Ethernet_t *) \
|
||||
&ecp->rxbufs[i][0];
|
||||
|
||||
ours = memcmp (ehp->et_src, \
|
||||
NetOurEther, 6);
|
||||
|
||||
prot = swap16 (ehp->et_protlen);
|
||||
tb = prot & 0x8000;
|
||||
n = prot & 0x7fff;
|
||||
|
||||
nbytes = ELBT_BUFSZ - \
|
||||
offsetof (Ethernet_t, \
|
||||
et_dsap) - \
|
||||
ELBT_CRCSZ;
|
||||
|
||||
/* check the frame is correct */
|
||||
if (datlen != ELBT_BUFSZ)
|
||||
ecp->rxeacc.badlen++;
|
||||
else if (!ours)
|
||||
ecp->rxeacc.badsrc++;
|
||||
else if (!tb || n >= ELBT_NTXBD)
|
||||
ecp->rxeacc.badtyp++;
|
||||
else {
|
||||
ulong patword = \
|
||||
patwords[n];
|
||||
uint nbb;
|
||||
|
||||
nbb = badbits ( \
|
||||
&ehp->et_dsap, \
|
||||
nbytes, \
|
||||
patword);
|
||||
|
||||
ecp->rxeacc.badbit += \
|
||||
nbb;
|
||||
}
|
||||
}
|
||||
|
||||
if (ecp->state == Closing)
|
||||
ecp->clstime = get_timer (0);
|
||||
|
||||
/* make it empty again */
|
||||
bdp->cbd_sc |= BD_ENET_RX_EMPTY;
|
||||
}
|
||||
|
||||
if (ecp->state != Closing)
|
||||
break;
|
||||
|
||||
/*
|
||||
* (while Closing) check to see if
|
||||
* waited long enough
|
||||
*/
|
||||
|
||||
if (get_timer (ecp->clstime) >= ELBT_CLSWAIT) {
|
||||
/* write GFMR: disable tx/rx */
|
||||
fcp->fcc_gfmr &= \
|
||||
~(FCC_GFMR_ENT | FCC_GFMR_ENR);
|
||||
ecp->state = Closed;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Closed:
|
||||
nclosed++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} while (nclosed < 3);
|
||||
|
||||
runtime = get_timer (runtime);
|
||||
if (runtime <= ELBT_CLSWAIT) {
|
||||
printf ("Whoops! somehow elapsed time (%ld) is wrong (<= %d)\n",
|
||||
runtime, ELBT_CLSWAIT);
|
||||
return;
|
||||
}
|
||||
nmsec = runtime - ELBT_CLSWAIT;
|
||||
|
||||
printf ("Test Finished in %ldms (plus %dms close wait period)!\n\n",
|
||||
nmsec, ELBT_CLSWAIT);
|
||||
|
||||
/*
|
||||
* now print stats
|
||||
*/
|
||||
|
||||
for (c = 0; c < 3; c++) {
|
||||
elbt_chan *ecp = &elbt_chans[c];
|
||||
uint rxpps, txpps, nerr;
|
||||
|
||||
rxpps = (ecp->nrcvd * 1000) / nmsec;
|
||||
txpps = (ecp->nsent * 1000) / nmsec;
|
||||
|
||||
printf ("Channel %d: %d rcvd (%d pps, %d rxerrs), "
|
||||
"%d sent (%d pps, %d txerrs)\n\n", c,
|
||||
ecp->nrcvd, rxpps, ecp->nrxerr,
|
||||
ecp->nsent, txpps, ecp->ntxerr);
|
||||
|
||||
if ((nerr = ecp->nrxerr) > 0) {
|
||||
ulong i;
|
||||
|
||||
printf ("\tFirst %d rx errs:", nerr);
|
||||
for (i = 0; i < nerr; i++)
|
||||
printf (" %04x", ecp->rxerrs[i]);
|
||||
puts ("\n");
|
||||
}
|
||||
|
||||
if ((nerr = ecp->ntxerr) > 0) {
|
||||
ulong i;
|
||||
|
||||
printf ("\tFirst %d tx errs:", nerr);
|
||||
for (i = 0; i < nerr; i++)
|
||||
printf (" %04x", ecp->txerrs[i]);
|
||||
puts ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
puts ("Receive Error Counts:\n");
|
||||
for (c = 0; c < 3; c++)
|
||||
bases[c] = (uchar *)&elbt_chans[c].rxeacc;
|
||||
print_desc (rxeacc_descs, rxeacc_ndesc, bases, 3);
|
||||
|
||||
puts ("\nTransmit Error Counts:\n");
|
||||
for (c = 0; c < 3; c++)
|
||||
bases[c] = (uchar *)&elbt_chans[c].txeacc;
|
||||
print_desc (txeacc_descs, txeacc_ndesc, bases, 3);
|
||||
|
||||
puts ("\nRMON(-like) Counters:\n");
|
||||
for (c = 0; c < 3; c++)
|
||||
bases[c] = (uchar *)&immr->im_dprambase[elbt_chans[c].proff];
|
||||
print_desc (epram_descs, epram_ndesc, bases, 3);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ETHER_LOOPBACK_TEST */
|
||||
|
||||
#endif /* CONFIG_ETHER_ON_FCC && CFG_CMD_NET && CONFIG_NET_MULTI */
|
||||
|
||||
@@ -333,7 +333,7 @@ int eth_init(bd_t *bis)
|
||||
immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl |= (SCC_GSMRL_ENR |
|
||||
SCC_GSMRL_ENT);
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
typedef void (*i2c_ecb_t)(int, int); /* error callback function */
|
||||
typedef void (*i2c_ecb_t)(int, int, void *); /* error callback function */
|
||||
|
||||
/* This structure keeps track of the bd and buffer space usage. */
|
||||
typedef struct i2c_state {
|
||||
@@ -69,6 +69,7 @@ typedef struct i2c_state {
|
||||
int tx_space; /* number of Tx bytes left */
|
||||
unsigned char *tx_buf; /* pointer to free Tx area */
|
||||
i2c_ecb_t err_cb; /* error callback function */
|
||||
void *cb_data; /* private data to be passed */
|
||||
} i2c_state_t;
|
||||
|
||||
/* flags for i2c_send() and i2c_receive() */
|
||||
@@ -77,14 +78,15 @@ typedef struct i2c_state {
|
||||
#define I2CF_STOP_COND 0x04 /* tx: generate stop condition */
|
||||
|
||||
/* return codes */
|
||||
#define I2CERR_NO_BUFFERS 0x01 /* no more BDs or buffer space */
|
||||
#define I2CERR_MSG_TOO_LONG 0x02 /* tried to send/receive to much data */
|
||||
#define I2CERR_TIMEOUT 0x03 /* timeout in i2c_doio() */
|
||||
#define I2CERR_QUEUE_EMPTY 0x04 /* i2c_doio called without send/receive */
|
||||
#define I2CERR_NO_BUFFERS 1 /* no more BDs or buffer space */
|
||||
#define I2CERR_MSG_TOO_LONG 2 /* tried to send/receive to much data */
|
||||
#define I2CERR_TIMEOUT 3 /* timeout in i2c_doio() */
|
||||
#define I2CERR_QUEUE_EMPTY 4 /* i2c_doio called without send/receive */
|
||||
#define I2CERR_IO_ERROR 5 /* had an error during comms */
|
||||
|
||||
/* error callback flags */
|
||||
#define I2CECB_RX_ERR 0x10 /* this is a receive error */
|
||||
#define I2CECB_RX_ERR_OV 0x02 /* receive overrun error */
|
||||
#define I2CECB_RX_OV 0x02 /* receive overrun error */
|
||||
#define I2CECB_RX_MASK 0x0f /* mask for error bits */
|
||||
#define I2CECB_TX_ERR 0x20 /* this is a transmit error */
|
||||
#define I2CECB_TX_CL 0x01 /* transmit collision error */
|
||||
@@ -318,6 +320,7 @@ void i2c_newio(i2c_state_t *state)
|
||||
state->tx_space = MAX_TX_SPACE;
|
||||
state->tx_buf = (uchar*)state->txbd + NUM_TX_BDS * sizeof(I2C_BD);
|
||||
state->err_cb = NULL;
|
||||
state->cb_data = NULL;
|
||||
|
||||
PRINTD(("[I2C] rxbd = %08x\n", (int)state->rxbd));
|
||||
PRINTD(("[I2C] txbd = %08x\n", (int)state->txbd));
|
||||
@@ -491,14 +494,11 @@ int i2c_doio(i2c_state_t *state)
|
||||
volatile iic_t *iip;
|
||||
volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c;
|
||||
volatile I2C_BD *txbd, *rxbd;
|
||||
int j;
|
||||
int timeout;
|
||||
int n, i, b, rxcnt = 0, rxtimeo = 0, txcnt = 0, txtimeo = 0, rc = 0;
|
||||
uint dpaddr;
|
||||
|
||||
PRINTD(("[I2C] i2c_doio\n"));
|
||||
|
||||
timeout = TOUT_LOOP * 256; /* arbitrarily long */
|
||||
|
||||
if (state->tx_idx <= 0 && state->rx_idx <= 0) {
|
||||
PRINTD(("[I2C] No I/O is queued\n"));
|
||||
return I2CERR_QUEUE_EMPTY;
|
||||
@@ -518,14 +518,20 @@ int i2c_doio(i2c_state_t *state)
|
||||
|
||||
/* Loop until transmit & receive completed */
|
||||
|
||||
txbd = ((I2C_BD*)state->txbd) - 1;
|
||||
j = 0;
|
||||
if (state->tx_idx > 0) {
|
||||
timeout = TOUT_LOOP * txbd->length;
|
||||
if ((n = state->tx_idx) > 0) {
|
||||
|
||||
txbd = ((I2C_BD*)state->txbd) - n;
|
||||
for (i = 0; i < n; i++) {
|
||||
txtimeo += TOUT_LOOP * txbd->length;
|
||||
txbd++;
|
||||
}
|
||||
|
||||
txbd--; /* wait until last in list is done */
|
||||
|
||||
PRINTD(("[I2C] Transmitting...(txbd=0x%08lx)\n", (ulong)txbd));
|
||||
|
||||
udelay(START_DELAY_US); /* give it time to start */
|
||||
while((txbd->status & BD_SC_READY) && (j++ < timeout)) {
|
||||
while((txbd->status & BD_SC_READY) && (++txcnt < txtimeo)) {
|
||||
udelay(DELAY_US);
|
||||
if (ctrlc())
|
||||
return (-1);
|
||||
@@ -533,13 +539,20 @@ int i2c_doio(i2c_state_t *state)
|
||||
}
|
||||
}
|
||||
|
||||
rxbd = ((I2C_BD*)state->rxbd) - 1;
|
||||
j = 0;
|
||||
if ((state->rx_idx > 0) && (j < timeout)) {
|
||||
timeout = TOUT_LOOP * rxbd->length;
|
||||
if (txcnt < txtimeo && (n = state->rx_idx) > 0) {
|
||||
|
||||
rxbd = ((I2C_BD*)state->rxbd) - n;
|
||||
for (i = 0; i < n; i++) {
|
||||
rxtimeo += TOUT_LOOP * rxbd->length;
|
||||
rxbd++;
|
||||
}
|
||||
|
||||
rxbd--; /* wait until last in list is done */
|
||||
|
||||
PRINTD(("[I2C] Receiving...(rxbd=0x%08lx)\n", (ulong)rxbd));
|
||||
|
||||
udelay(START_DELAY_US); /* give it time to start */
|
||||
while((rxbd->status & BD_SC_EMPTY) && (j++ < timeout)) {
|
||||
while((rxbd->status & BD_SC_EMPTY) && (++rxcnt < rxtimeo)) {
|
||||
udelay(DELAY_US);
|
||||
if (ctrlc())
|
||||
return (-1);
|
||||
@@ -550,76 +563,91 @@ int i2c_doio(i2c_state_t *state)
|
||||
/* Turn off I2C */
|
||||
i2c->i2c_i2mod &= ~0x01;
|
||||
|
||||
if (state->err_cb != NULL) {
|
||||
int n, i, b;
|
||||
|
||||
/*
|
||||
* if we have an error callback function, look at the
|
||||
* error bits in the bd status and pass them back
|
||||
*/
|
||||
|
||||
if ((n = state->tx_idx) > 0) {
|
||||
for (i = 0; i < n; i++) {
|
||||
txbd = ((I2C_BD*)state->txbd) - (n - i);
|
||||
if ((b = txbd->status & BD_I2C_TX_ERR) != 0)
|
||||
(*state->err_cb)(I2CECB_TX_ERR|b, i);
|
||||
if ((n = state->tx_idx) > 0) {
|
||||
for (i = 0; i < n; i++) {
|
||||
txbd = ((I2C_BD*)state->txbd) - (n - i);
|
||||
if ((b = txbd->status & BD_I2C_TX_ERR) != 0) {
|
||||
if (state->err_cb != NULL)
|
||||
(*state->err_cb)(I2CECB_TX_ERR|b, i,
|
||||
state->cb_data);
|
||||
if (rc == 0)
|
||||
rc = I2CERR_IO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if ((n = state->rx_idx) > 0) {
|
||||
for (i = 0; i < n; i++) {
|
||||
rxbd = ((I2C_BD*)state->rxbd) - (n - i);
|
||||
if ((b = rxbd->status & BD_I2C_RX_ERR) != 0)
|
||||
(*state->err_cb)(I2CECB_RX_ERR|b, i);
|
||||
}
|
||||
}
|
||||
|
||||
if (j >= timeout)
|
||||
(*state->err_cb)(I2CECB_TIMEOUT, 0);
|
||||
}
|
||||
|
||||
/* sort out errors and return appropriate good/error status */
|
||||
if(j >= timeout)
|
||||
return(I2CERR_TIMEOUT);
|
||||
if((txbd->status & BD_I2C_TX_ERR) != 0)
|
||||
return(I2CECB_TX_ERR | (txbd->status & I2CECB_TX_MASK));
|
||||
if((rxbd->status & BD_I2C_RX_ERR) != 0)
|
||||
return(I2CECB_RX_ERR | (rxbd->status & I2CECB_RX_MASK));
|
||||
if ((n = state->rx_idx) > 0) {
|
||||
for (i = 0; i < n; i++) {
|
||||
rxbd = ((I2C_BD*)state->rxbd) - (n - i);
|
||||
if ((b = rxbd->status & BD_I2C_RX_ERR) != 0) {
|
||||
if (state->err_cb != NULL)
|
||||
(*state->err_cb)(I2CECB_RX_ERR|b, i,
|
||||
state->cb_data);
|
||||
if (rc == 0)
|
||||
rc = I2CERR_IO_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
if ((txtimeo > 0 && txcnt >= txtimeo) || \
|
||||
(rxtimeo > 0 && rxcnt >= rxtimeo)) {
|
||||
if (state->err_cb != NULL)
|
||||
(*state->err_cb)(I2CECB_TIMEOUT, -1, state->cb_data);
|
||||
if (rc == 0)
|
||||
rc = I2CERR_TIMEOUT;
|
||||
}
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
static int had_tx_nak;
|
||||
|
||||
static void
|
||||
i2c_test_callback(int flags, int xnum)
|
||||
i2c_probe_callback(int flags, int xnum, void *data)
|
||||
{
|
||||
if ((flags & I2CECB_TX_ERR) && (flags & I2CECB_TX_NAK))
|
||||
had_tx_nak = 1;
|
||||
/*
|
||||
* the only acceptable errors are a transmit NAK or a receive
|
||||
* overrun - tx NAK means the device does not exist, rx OV
|
||||
* means the device must have responded to the slave address
|
||||
* even though the transfer failed
|
||||
*/
|
||||
if (flags == (I2CECB_TX_ERR|I2CECB_TX_NAK))
|
||||
*(int *)data |= 1;
|
||||
if (flags == (I2CECB_RX_ERR|I2CECB_RX_OV))
|
||||
*(int *)data |= 2;
|
||||
}
|
||||
|
||||
int i2c_probe(uchar chip)
|
||||
int
|
||||
i2c_probe(uchar chip)
|
||||
{
|
||||
i2c_state_t state;
|
||||
int rc;
|
||||
int rc, err_flag;
|
||||
uchar buf[1];
|
||||
|
||||
i2c_newio(&state);
|
||||
|
||||
state.err_cb = i2c_test_callback;
|
||||
had_tx_nak = 0;
|
||||
state.err_cb = i2c_probe_callback;
|
||||
state.cb_data = (void *) &err_flag;
|
||||
err_flag = 0;
|
||||
|
||||
rc = i2c_receive(&state, chip, 0, I2CF_START_COND|I2CF_STOP_COND, 1, buf);
|
||||
|
||||
if (rc != 0)
|
||||
return (rc);
|
||||
return (rc); /* probe failed */
|
||||
|
||||
rc = i2c_doio(&state);
|
||||
|
||||
if ((rc != 0) && (rc != I2CERR_TIMEOUT))
|
||||
return (rc);
|
||||
if (rc == 0)
|
||||
return (0); /* device exists - read succeeded */
|
||||
|
||||
return (had_tx_nak);
|
||||
if (rc == I2CERR_TIMEOUT)
|
||||
return (-1); /* device does not exist - timeout */
|
||||
|
||||
if (rc != I2CERR_IO_ERROR || err_flag == 0)
|
||||
return (rc); /* probe failed */
|
||||
|
||||
if (err_flag & 1)
|
||||
return (-1); /* device does not exist - had transmit NAK */
|
||||
|
||||
return (0); /* device exists - had receive overrun */
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ static __inline__ unsigned long get_msr (void)
|
||||
|
||||
static __inline__ void set_msr (unsigned long msr)
|
||||
{
|
||||
__asm__ __volatile__ ("mtmsr %0"::"r" (msr));
|
||||
__asm__ __volatile__ ("mtmsr %0;sync;isync"::"r" (msr));
|
||||
}
|
||||
|
||||
static __inline__ unsigned long get_dec (void)
|
||||
@@ -208,6 +208,14 @@ int interrupt_init (void)
|
||||
immr->im_intctl.ic_sipnrh = 0xffffffff;
|
||||
immr->im_intctl.ic_sipnrl = 0xffffffff;
|
||||
|
||||
#ifdef CONFIG_HYMOD
|
||||
/*
|
||||
* ensure all external interrupt sources default to trigger on
|
||||
* high-to-low transition (i.e. edge triggered active low)
|
||||
*/
|
||||
immr->im_intctl.ic_siexr = -1;
|
||||
#endif
|
||||
|
||||
set_dec (decrementer_count);
|
||||
|
||||
set_msr (get_msr () | MSR_EE);
|
||||
|
||||
@@ -252,7 +252,13 @@ void pci_mpc8250_init(struct pci_controller *hose)
|
||||
* Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]),
|
||||
* and local bus for PCI (SIUMCR [LBPC]).
|
||||
*/
|
||||
immap->im_siu_conf.sc_siumcr = 0x00640000;
|
||||
immap->im_siu_conf.sc_siumcr = (immap->im_siu_conf.sc_siumcr &
|
||||
~SIUMCR_LBPC11 &
|
||||
~SIUMCR_CS10PC11 &
|
||||
~SIUMCR_LBPC11) |
|
||||
SIUMCR_LBPC01 |
|
||||
SIUMCR_CS10PC01 |
|
||||
SIUMCR_LBPC01;
|
||||
#endif
|
||||
|
||||
/* Make PCI lowest priority */
|
||||
|
||||
@@ -161,6 +161,7 @@ _hrcw_table:
|
||||
.globl _start
|
||||
_start:
|
||||
li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH*/
|
||||
nop
|
||||
b boot_cold
|
||||
|
||||
. = EXC_OFF_SYS_RESET + 0x10
|
||||
@@ -171,6 +172,18 @@ _start_warm:
|
||||
b boot_warm
|
||||
|
||||
boot_cold:
|
||||
#if defined(CONFIG_MPC8260ADS)
|
||||
lis r3, CFG_DEFAULT_IMMR@h
|
||||
nop
|
||||
lwz r4, 0(r3)
|
||||
nop
|
||||
rlwinm r4, r4, 0, 8, 5
|
||||
nop
|
||||
oris r4, r4, 0x0200
|
||||
nop
|
||||
stw r4, 0(r3)
|
||||
nop
|
||||
#endif /* CONFIG_MPC8260ADS */
|
||||
boot_warm:
|
||||
mfmsr r5 /* save msr contents */
|
||||
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
* (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
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <status_led.h>
|
||||
|
||||
/*
|
||||
* The purpose of this code is to signal the operational status of a
|
||||
* target which usually boots over the network; while running in
|
||||
* PCBoot, a status LED is blinking. As soon as a valid BOOTP reply
|
||||
* message has been received, the LED is turned off. The Linux
|
||||
* kernel, once it is running, will start blinking the LED again,
|
||||
* with another frequency.
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef CONFIG_STATUS_LED
|
||||
|
||||
typedef struct {
|
||||
ulong mask;
|
||||
int state;
|
||||
int period;
|
||||
int cnt;
|
||||
} led_dev_t;
|
||||
|
||||
led_dev_t led_dev[] = {
|
||||
{ STATUS_LED_BIT,
|
||||
STATUS_LED_STATE,
|
||||
STATUS_LED_PERIOD,
|
||||
0,
|
||||
},
|
||||
#if defined(STATUS_LED_BIT1)
|
||||
{ STATUS_LED_BIT1,
|
||||
STATUS_LED_STATE1,
|
||||
STATUS_LED_PERIOD1,
|
||||
0,
|
||||
},
|
||||
#endif
|
||||
#if defined(STATUS_LED_BIT2)
|
||||
{ STATUS_LED_BIT2,
|
||||
STATUS_LED_STATE2,
|
||||
STATUS_LED_PERIOD2,
|
||||
0,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
#define MAX_LED_DEV (sizeof(led_dev)/sizeof(led_dev_t))
|
||||
|
||||
static int status_led_init_done = 0;
|
||||
|
||||
static void status_led_init (void)
|
||||
{
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_LED_DEV; ++i) {
|
||||
led_dev_t *ld = &led_dev[i];
|
||||
|
||||
immr->STATUS_LED_PAR &= ~(ld->mask);
|
||||
#ifdef STATUS_LED_ODR
|
||||
immr->STATUS_LED_ODR &= ~(ld->mask);
|
||||
#endif
|
||||
#if (STATUS_LED_ACTIVE == 0)
|
||||
if (ld->state == STATUS_LED_ON)
|
||||
immr->STATUS_LED_DAT &= ~(ld->mask);
|
||||
else
|
||||
immr->STATUS_LED_DAT |= ld->mask ;
|
||||
#else
|
||||
if (ld->state == STATUS_LED_ON)
|
||||
immr->STATUS_LED_DAT |= ld->mask ;
|
||||
else
|
||||
immr->STATUS_LED_DAT &= ~(ld->mask);
|
||||
#endif
|
||||
immr->STATUS_LED_DIR |= ld->mask ;
|
||||
}
|
||||
|
||||
status_led_init_done = 1;
|
||||
}
|
||||
|
||||
void status_led_tick (ulong timestamp)
|
||||
{
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
int i;
|
||||
|
||||
if (!status_led_init_done)
|
||||
status_led_init();
|
||||
|
||||
for (i=0; i<MAX_LED_DEV; ++i) {
|
||||
led_dev_t *ld = &led_dev[i];
|
||||
|
||||
if (ld->state != STATUS_LED_BLINKING)
|
||||
continue;
|
||||
|
||||
if (++(ld->cnt) >= ld->period) {
|
||||
immr->STATUS_LED_DAT ^= ld->mask;
|
||||
ld->cnt -= ld->period;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void status_led_set (int led, int state)
|
||||
{
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
led_dev_t *ld;
|
||||
|
||||
if (led < 0 || led >= MAX_LED_DEV)
|
||||
return;
|
||||
|
||||
if (!status_led_init_done)
|
||||
status_led_init();
|
||||
|
||||
ld = &led_dev[led];
|
||||
|
||||
switch (state) {
|
||||
default:
|
||||
return;
|
||||
case STATUS_LED_BLINKING:
|
||||
ld->cnt = 0; /* always start with full period */
|
||||
/* fall through */ /* always start with LED _ON_ */
|
||||
case STATUS_LED_ON:
|
||||
#if (STATUS_LED_ACTIVE == 0)
|
||||
immr->STATUS_LED_DAT &= ~(ld->mask);
|
||||
#else
|
||||
immr->STATUS_LED_DAT |= ld->mask ;
|
||||
#endif
|
||||
break;
|
||||
case STATUS_LED_OFF:
|
||||
#if (STATUS_LED_ACTIVE == 0)
|
||||
immr->STATUS_LED_DAT |= ld->mask ;
|
||||
#else
|
||||
immr->STATUS_LED_DAT &= ~(ld->mask);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
ld->state = state;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_STATUS_LED */
|
||||
@@ -30,7 +30,7 @@ LIB = lib$(CPU).a
|
||||
START = start.o kgdb.o
|
||||
OBJS = bedbug_860.o commproc.o cpu.o cpu_init.o \
|
||||
fec.o i2c.o interrupts.o lcd.o scc.o \
|
||||
serial.o speed.o spi.o status_led.o\
|
||||
serial.o speed.o spi.o \
|
||||
traps.o upatch.o video.o
|
||||
|
||||
all: .depend $(START) $(LIB)
|
||||
|
||||
@@ -716,7 +716,7 @@ _start_of_vectors:
|
||||
#endif
|
||||
|
||||
/* Machine check */
|
||||
STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
|
||||
CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
|
||||
|
||||
/* Data Storage exception. */
|
||||
STD_EXCEPTION(0x300, DataStorage, UnknownException)
|
||||
|
||||
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
|
||||
LIB = lib$(CPU).a
|
||||
|
||||
START = start.o
|
||||
OBJS = serial.o interrupts.o cpu.o i2c.o
|
||||
OBJS = serial.o interrupts.o cpu.o i2c.o pxafb.o mmc.o
|
||||
|
||||
all: .depend $(START) $(LIB)
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
|
||||
int cpu_init (void)
|
||||
{
|
||||
@@ -150,3 +151,21 @@ int dcache_status (void)
|
||||
{
|
||||
return 0; /* always off */
|
||||
}
|
||||
|
||||
void set_GPIO_mode(int gpio_mode)
|
||||
{
|
||||
int gpio = gpio_mode & GPIO_MD_MASK_NR;
|
||||
int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
|
||||
int gafr;
|
||||
|
||||
if (gpio_mode & GPIO_MD_MASK_DIR)
|
||||
{
|
||||
GPDR(gpio) |= GPIO_bit(gpio);
|
||||
}
|
||||
else
|
||||
{
|
||||
GPDR(gpio) &= ~GPIO_bit(gpio);
|
||||
}
|
||||
gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
|
||||
GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
|
||||
}
|
||||
|
||||
483
cpu/pxa/mmc.c
Normal file
483
cpu/pxa/mmc.c
Normal file
@@ -0,0 +1,483 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include <common.h>
|
||||
#include <mmc.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
|
||||
#ifdef CONFIG_MMC
|
||||
|
||||
extern int
|
||||
fat_register_read(int(*block_read)(int device, ulong blknr, ulong blkcnt, uchar *buffer));
|
||||
|
||||
/*
|
||||
* FIXME needs to read cid and csd info to determine block size
|
||||
* and other parameters
|
||||
*/
|
||||
static uchar mmc_buf[MMC_BLOCK_SIZE];
|
||||
static mmc_csd_t mmc_csd;
|
||||
static int mmc_ready = 0;
|
||||
|
||||
|
||||
static uchar *
|
||||
/****************************************************/
|
||||
mmc_cmd(ushort cmd, ushort argh, ushort argl, ushort cmdat)
|
||||
/****************************************************/
|
||||
{
|
||||
static uchar resp[20];
|
||||
ulong status;
|
||||
int words, i;
|
||||
|
||||
debug("mmc_cmd %x %x %x %x\n", cmd, argh, argl, cmdat);
|
||||
MMC_STRPCL = MMC_STRPCL_STOP_CLK;
|
||||
MMC_I_MASK = ~MMC_I_MASK_CLK_IS_OFF;
|
||||
while (!(MMC_I_REG & MMC_I_REG_CLK_IS_OFF));
|
||||
MMC_CMD = cmd;
|
||||
MMC_ARGH = argh;
|
||||
MMC_ARGL = argl;
|
||||
MMC_CMDAT = cmdat;
|
||||
MMC_I_MASK = ~MMC_I_MASK_END_CMD_RES;
|
||||
MMC_STRPCL = MMC_STRPCL_START_CLK;
|
||||
while (!(MMC_I_REG & MMC_I_REG_END_CMD_RES));
|
||||
|
||||
status = MMC_STAT;
|
||||
debug("MMC status %x\n", status);
|
||||
if (status & MMC_STAT_TIME_OUT_RESPONSE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (cmdat & 0x3)
|
||||
{
|
||||
case MMC_CMDAT_R1:
|
||||
case MMC_CMDAT_R3:
|
||||
words = 3;
|
||||
break;
|
||||
|
||||
case MMC_CMDAT_R2:
|
||||
words = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
for (i = words-1; i >= 0; i--)
|
||||
{
|
||||
ulong res_fifo = MMC_RES;
|
||||
int offset = i << 1;
|
||||
|
||||
resp[offset] = ((uchar *)&res_fifo)[0];
|
||||
resp[offset+1] = ((uchar *)&res_fifo)[1];
|
||||
}
|
||||
#ifdef MMC_DEBUG
|
||||
for (i=0; i<words*2; i += 2)
|
||||
{
|
||||
printf("MMC resp[%d] = %02x\n", i, resp[i]);
|
||||
printf("MMC resp[%d] = %02x\n", i+1, resp[i+1]);
|
||||
}
|
||||
#endif
|
||||
return resp;
|
||||
}
|
||||
|
||||
int
|
||||
/****************************************************/
|
||||
mmc_block_read(uchar *dst, ulong src, ulong len)
|
||||
/****************************************************/
|
||||
{
|
||||
uchar *resp;
|
||||
ushort argh, argl;
|
||||
ulong status;
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
debug("mmc_block_rd dst %lx src %lx len %d\n", (ulong)dst, src, len);
|
||||
|
||||
argh = len >> 16;
|
||||
argl = len & 0xffff;
|
||||
|
||||
/* set block len */
|
||||
resp = mmc_cmd(MMC_CMD_SET_BLOCKLEN, argh, argl, MMC_CMDAT_R1);
|
||||
|
||||
/* send read command */
|
||||
argh = src >> 16;
|
||||
argl = src & 0xffff;
|
||||
MMC_STRPCL = MMC_STRPCL_STOP_CLK;
|
||||
MMC_RDTO = 0xffff;
|
||||
MMC_NOB = 1;
|
||||
MMC_BLKLEN = len;
|
||||
resp = mmc_cmd(MMC_CMD_READ_BLOCK, argh, argl,
|
||||
MMC_CMDAT_R1|MMC_CMDAT_READ|MMC_CMDAT_BLOCK|MMC_CMDAT_DATA_EN);
|
||||
|
||||
|
||||
MMC_I_MASK = ~MMC_I_MASK_RXFIFO_RD_REQ;
|
||||
while (len)
|
||||
{
|
||||
if (MMC_I_REG & MMC_I_REG_RXFIFO_RD_REQ)
|
||||
{
|
||||
*dst++ = MMC_RXFIFO;
|
||||
len--;
|
||||
}
|
||||
status = MMC_STAT;
|
||||
if (status & MMC_STAT_ERRORS)
|
||||
{
|
||||
printf("MMC_STAT error %lx\n", status);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
MMC_I_MASK = ~MMC_I_MASK_DATA_TRAN_DONE;
|
||||
while (!(MMC_I_REG & MMC_I_REG_DATA_TRAN_DONE));
|
||||
status = MMC_STAT;
|
||||
if (status & MMC_STAT_ERRORS)
|
||||
{
|
||||
printf("MMC_STAT error %lx\n", status);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
/****************************************************/
|
||||
mmc_block_write(ulong dst, uchar *src, int len)
|
||||
/****************************************************/
|
||||
{
|
||||
uchar *resp;
|
||||
ushort argh, argl;
|
||||
ulong status;
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
debug("mmc_block_wr dst %lx src %lx len %d\n", dst, (ulong)src, len);
|
||||
|
||||
argh = len >> 16;
|
||||
argl = len & 0xffff;
|
||||
|
||||
/* set block len */
|
||||
resp = mmc_cmd(MMC_CMD_SET_BLOCKLEN, argh, argl, MMC_CMDAT_R1);
|
||||
|
||||
/* send write command */
|
||||
argh = dst >> 16;
|
||||
argl = dst & 0xffff;
|
||||
MMC_STRPCL = MMC_STRPCL_STOP_CLK;
|
||||
MMC_NOB = 1;
|
||||
MMC_BLKLEN = len;
|
||||
resp = mmc_cmd(MMC_CMD_WRITE_BLOCK, argh, argl,
|
||||
MMC_CMDAT_R1|MMC_CMDAT_WRITE|MMC_CMDAT_BLOCK|MMC_CMDAT_DATA_EN);
|
||||
|
||||
MMC_I_MASK = ~MMC_I_MASK_TXFIFO_WR_REQ;
|
||||
while (len)
|
||||
{
|
||||
if (MMC_I_REG & MMC_I_REG_TXFIFO_WR_REQ)
|
||||
{
|
||||
int i, bytes = min(32,len);
|
||||
|
||||
for (i=0; i<bytes; i++)
|
||||
{
|
||||
MMC_TXFIFO = *src++;
|
||||
}
|
||||
if (bytes < 32)
|
||||
{
|
||||
MMC_PRTBUF = MMC_PRTBUF_BUF_PART_FULL;
|
||||
}
|
||||
len -= bytes;
|
||||
}
|
||||
status = MMC_STAT;
|
||||
if (status & MMC_STAT_ERRORS)
|
||||
{
|
||||
printf("MMC_STAT error %lx\n", status);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
MMC_I_MASK = ~MMC_I_MASK_DATA_TRAN_DONE;
|
||||
while (!(MMC_I_REG & MMC_I_REG_DATA_TRAN_DONE));
|
||||
MMC_I_MASK = ~MMC_I_MASK_PRG_DONE;
|
||||
while (!(MMC_I_REG & MMC_I_REG_PRG_DONE));
|
||||
status = MMC_STAT;
|
||||
if (status & MMC_STAT_ERRORS)
|
||||
{
|
||||
printf("MMC_STAT error %lx\n", status);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
/****************************************************/
|
||||
mmc_read(ulong src, uchar *dst, int size)
|
||||
/****************************************************/
|
||||
{
|
||||
ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
|
||||
ulong mmc_block_size, mmc_block_address;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!mmc_ready)
|
||||
{
|
||||
printf("Please initial the MMC first\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mmc_block_size = MMC_BLOCK_SIZE;
|
||||
mmc_block_address = ~(mmc_block_size - 1);
|
||||
|
||||
src -= CFG_MMC_BASE;
|
||||
end = src + size;
|
||||
part_start = ~mmc_block_address & src;
|
||||
part_end = ~mmc_block_address & end;
|
||||
aligned_start = mmc_block_address & src;
|
||||
aligned_end = mmc_block_address & end;
|
||||
|
||||
/* all block aligned accesses */
|
||||
debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
|
||||
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
|
||||
if (part_start)
|
||||
{
|
||||
part_len = mmc_block_size - part_start;
|
||||
debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
|
||||
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
|
||||
if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
memcpy(dst, mmc_buf+part_start, part_len);
|
||||
dst += part_len;
|
||||
src += part_len;
|
||||
}
|
||||
debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
|
||||
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
|
||||
for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size)
|
||||
{
|
||||
debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
|
||||
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
|
||||
if ((mmc_block_read((uchar *)(dst), src, mmc_block_size)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
|
||||
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
|
||||
if (part_end && src < end)
|
||||
{
|
||||
debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
|
||||
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
|
||||
if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
memcpy(dst, mmc_buf, part_end);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
/****************************************************/
|
||||
mmc_write(uchar *src, ulong dst, int size)
|
||||
/****************************************************/
|
||||
{
|
||||
ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
|
||||
ulong mmc_block_size, mmc_block_address;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!mmc_ready)
|
||||
{
|
||||
printf("Please initial the MMC first\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mmc_block_size = MMC_BLOCK_SIZE;
|
||||
mmc_block_address = ~(mmc_block_size - 1);
|
||||
|
||||
dst -= CFG_MMC_BASE;
|
||||
end = dst + size;
|
||||
part_start = ~mmc_block_address & dst;
|
||||
part_end = ~mmc_block_address & end;
|
||||
aligned_start = mmc_block_address & dst;
|
||||
aligned_end = mmc_block_address & end;
|
||||
|
||||
/* all block aligned accesses */
|
||||
debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
|
||||
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
|
||||
if (part_start)
|
||||
{
|
||||
part_len = mmc_block_size - part_start;
|
||||
debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
|
||||
(ulong)src, dst, end, part_start, part_end, aligned_start, aligned_end);
|
||||
if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
memcpy(mmc_buf+part_start, src, part_len);
|
||||
if ((mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
dst += part_len;
|
||||
src += part_len;
|
||||
}
|
||||
debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
|
||||
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
|
||||
for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size)
|
||||
{
|
||||
debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
|
||||
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
|
||||
if ((mmc_block_write(dst, (uchar *)src, mmc_block_size)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
|
||||
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
|
||||
if (part_end && dst < end)
|
||||
{
|
||||
debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
|
||||
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
|
||||
if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
memcpy(mmc_buf, src, part_end);
|
||||
if ((mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
/****************************************************/
|
||||
mmc_bread(int dev_num, ulong blknr, ulong blkcnt, uchar *dst)
|
||||
/****************************************************/
|
||||
{
|
||||
int mmc_block_size = MMC_BLOCK_SIZE;
|
||||
ulong src = blknr * mmc_block_size + CFG_MMC_BASE;
|
||||
|
||||
mmc_read(src, (uchar *)dst, blkcnt*mmc_block_size);
|
||||
return blkcnt;
|
||||
}
|
||||
|
||||
int
|
||||
/****************************************************/
|
||||
mmc_init(int verbose)
|
||||
/****************************************************/
|
||||
{
|
||||
int retries, rc = -ENODEV;
|
||||
uchar *resp;
|
||||
|
||||
#ifdef CONFIG_LUBBOCK
|
||||
set_GPIO_mode( GPIO6_MMCCLK_MD );
|
||||
set_GPIO_mode( GPIO8_MMCCS0_MD );
|
||||
#endif
|
||||
CKEN |= CKEN12_MMC; /* enable MMC unit clock */
|
||||
|
||||
mmc_csd.c_size = 0;
|
||||
|
||||
MMC_CLKRT = MMC_CLKRT_0_3125MHZ;
|
||||
MMC_RESTO = MMC_RES_TO_MAX;
|
||||
MMC_SPI = MMC_SPI_DISABLE;
|
||||
|
||||
/* reset */
|
||||
retries = 10;
|
||||
resp = mmc_cmd(0, 0, 0, 0);
|
||||
resp = mmc_cmd(1, 0x00ff, 0xc000, MMC_CMDAT_INIT|MMC_CMDAT_BUSY|MMC_CMDAT_R3);
|
||||
while (retries-- && resp && !(resp[4] & 0x80))
|
||||
{
|
||||
debug("resp %x %x\n", resp[0], resp[1]);
|
||||
udelay(50);
|
||||
resp = mmc_cmd(1, 0x00ff, 0xff00, MMC_CMDAT_BUSY|MMC_CMDAT_R3);
|
||||
}
|
||||
|
||||
/* try to get card id */
|
||||
resp = mmc_cmd(2, 0, 0, MMC_CMDAT_R2);
|
||||
if (resp)
|
||||
{
|
||||
/* TODO configure mmc driver depending on card attributes */
|
||||
mmc_cid_t *cid = (mmc_cid_t *)resp;
|
||||
if (verbose)
|
||||
{
|
||||
printf("MMC found. Card desciption is:\n");
|
||||
printf("Manufacturer ID = %02x%02x%02x\n",
|
||||
cid->id[0], cid->id[1], cid->id[2]);
|
||||
printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev);
|
||||
cid->hwrev = cid->fwrev = 0; /* null terminate string */
|
||||
printf("Product Name = %s\n",cid->name);
|
||||
printf("Serial Number = %02x%02x%02x\n",
|
||||
cid->sn[0], cid->sn[1], cid->sn[2]);
|
||||
printf("Month = %d\n",cid->month);
|
||||
printf("Year = %d\n",1997 + cid->year);
|
||||
}
|
||||
|
||||
/* MMC exists, get CSD too */
|
||||
resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
|
||||
resp = mmc_cmd(MMC_CMD_SEND_CSD, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R2);
|
||||
if (resp)
|
||||
{
|
||||
mmc_csd_t *csd = (mmc_csd_t *)resp;
|
||||
memcpy(&mmc_csd, csd, sizeof(csd));
|
||||
rc = 0;
|
||||
mmc_ready = 1;
|
||||
/* FIXME add verbose printout for csd */
|
||||
}
|
||||
}
|
||||
|
||||
MMC_CLKRT = 0; /* 20 MHz */
|
||||
resp = mmc_cmd(7, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
|
||||
|
||||
fat_register_read(mmc_bread);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
mmc_ident(block_dev_desc_t *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mmc2info(ulong addr)
|
||||
{
|
||||
/* FIXME hard codes to 32 MB device */
|
||||
if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
1089
cpu/pxa/pxafb.c
Normal file
1089
cpu/pxa/pxafb.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -27,9 +27,9 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = libdrivers.a
|
||||
|
||||
OBJS = 3c589.o 5701rls.o ali512x.o at91rm9200_ether.o \
|
||||
OBJS = 3c589.o 5701rls.o ali512x.o \
|
||||
bcm570x.o bcm570x_autoneg.o cfb_console.o \
|
||||
cs8900.o ct69000.o dc2114x.o \
|
||||
cs8900.o ct69000.o dataflash.o dc2114x.o \
|
||||
e1000.o eepro100.o \
|
||||
i8042.o i82365.o inca-ip_sw.o \
|
||||
lan91c96.o natsemi.o \
|
||||
@@ -38,10 +38,11 @@ OBJS = 3c589.o 5701rls.o ali512x.o at91rm9200_ether.o \
|
||||
pcnet.o plb2800_eth.o \
|
||||
s3c24x0_i2c.o sed13806.o serial.o \
|
||||
smc91111.o smiLynxEM.o sym53c8xx.o \
|
||||
ti_pci1410a.o tigon3.o w83c553f.o
|
||||
ti_pci1410a.o tigon3.o w83c553f.o \
|
||||
status_led.o
|
||||
|
||||
## Disabled for now:
|
||||
## cs8900.o ct69000.o dc2114x.o ds1722.o \
|
||||
## cs8900.o ct69000.o dataflash.o dc2114x.o ds1722.o \
|
||||
## lan91c96.o mw_eeprom.o natsemi.o \
|
||||
## smc91111.o smiLynxEM.o spi_eeprom.o sym53c8xx.o \
|
||||
##
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <asm/io.h>
|
||||
#include <net.h>
|
||||
|
||||
/* ----- Ethernet Buffer definitions ----- */
|
||||
|
||||
typedef struct {
|
||||
unsigned long addr,size;
|
||||
} rbf_t;
|
||||
|
||||
#define RBF_ADDR 0xfffffffc
|
||||
#define RBF_OWNER (1<<0)
|
||||
#define RBF_WRAP (1<<1)
|
||||
#define RBF_BROADCAST (1<<31)
|
||||
#define RBF_MULTICAST (1<<30)
|
||||
#define RBF_UNICAST (1<<29)
|
||||
#define RBF_EXTERNAL (1<<28)
|
||||
#define RBF_UNKOWN (1<<27)
|
||||
#define RBF_SIZE 0x07ff
|
||||
#define RBF_LOCAL4 (1<<26)
|
||||
#define RBF_LOCAL3 (1<<25)
|
||||
#define RBF_LOCAL2 (1<<24)
|
||||
#define RBF_LOCAL1 (1<<23)
|
||||
|
||||
#define RBF_FRAMEMAX 10
|
||||
#define RBF_FRAMEMEM 0x200000
|
||||
#define RBF_FRAMELEN 0x600
|
||||
|
||||
#define RBF_FRAMEBTD RBF_FRAMEMEM
|
||||
#define RBF_FRAMEBUF (RBF_FRAMEMEM + RBF_FRAMEMAX*sizeof(rbf_t))
|
||||
|
||||
/* stolen from mii.h */
|
||||
/* Generic MII registers. */
|
||||
|
||||
#define MII_BMCR 0x00 /* Basic mode control register */
|
||||
#define MII_BMSR 0x01 /* Basic mode status register */
|
||||
#define BMSR_JCD 0x0002 /* Jabber detected */
|
||||
#define BMSR_LSTATUS 0x0004 /* Link status */
|
||||
#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
|
||||
#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
|
||||
#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
|
||||
#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
|
||||
|
||||
#define MII_STS2_REG 17 /* Davicom specific */
|
||||
#define MII_MDINTR_REG 21 /* Davicom specific */
|
||||
|
||||
#ifdef CONFIG_DRIVER_ETHER
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NET)
|
||||
|
||||
AT91PS_EMAC p_mac;
|
||||
|
||||
int MII_ReadPhy(unsigned char addr, unsigned short *ret)
|
||||
{
|
||||
|
||||
p_mac->EMAC_MAN = 0x60020000 | (addr << 18);
|
||||
udelay(10000);
|
||||
*ret = (unsigned short)p_mac->EMAC_MAN;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int MII_GetLinkSpeed(void)
|
||||
{
|
||||
unsigned short stat1, stat2;
|
||||
int ret;
|
||||
|
||||
if (!(ret = MII_ReadPhy(MII_BMSR, &stat1)))
|
||||
return 0;
|
||||
|
||||
if (stat1 & BMSR_JCD)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("MII: jabber condition detected\n");
|
||||
#endif /*jabber detected re-read the register*/
|
||||
}
|
||||
if (!(ret = MII_ReadPhy(MII_BMSR, &stat1)))
|
||||
return 0;
|
||||
if (!(stat1 & BMSR_LSTATUS)) /* link status up? */
|
||||
{
|
||||
printf("MII: no Link\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(ret = MII_ReadPhy(MII_STS2_REG, &stat2)))
|
||||
return 0;
|
||||
|
||||
if ((stat1 & BMSR_100FULL) && (stat2 & 0x8000) )
|
||||
{
|
||||
/* set MII for 100BaseTX and Full Duplex */
|
||||
p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
|
||||
#ifdef DEBUG
|
||||
printf("MII: 100BaseTX and Full Duplex detected\n");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
else
|
||||
if ((stat1 & BMSR_10FULL) && (stat2 & 0x2000))
|
||||
{
|
||||
/* set MII for 10BaseT and Full Duplex */
|
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD));
|
||||
#ifdef DEBUG
|
||||
printf("MII: 10BaseT and Full Duplex detected\n");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
if ((stat1 & BMSR_100HALF) && (stat2 & 0x4000))
|
||||
{
|
||||
/* set MII for 100BaseTX and Half Duplex */
|
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD));
|
||||
#ifdef DEBUG
|
||||
printf("MII: 100BaseTX and Hall Duplex detected\n");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
if ((stat1 & BMSR_10HALF) && (stat2 & 0x1000))
|
||||
{
|
||||
/*set MII for 10BaseT and Half Duplex */
|
||||
p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
|
||||
#ifdef DEBUG
|
||||
printf("MII: 10BaseT and Hall Duplex detected\n");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int MDIO_StartupPhy(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(p_mac->EMAC_SR & AT91C_EMAC_LINK)
|
||||
{
|
||||
printf("MDIO_StartupPhy: no link\n");
|
||||
return 0;
|
||||
};
|
||||
|
||||
p_mac->EMAC_CTL |= AT91C_EMAC_MPE;
|
||||
|
||||
ret = MII_GetLinkSpeed();
|
||||
if (ret == 0)
|
||||
{
|
||||
printf("MDIO_StartupPhy: MII_GetLinkSpeed failed\n");
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
p_mac->EMAC_CTL &= ~AT91C_EMAC_MPE;
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
rbf_t* rbfdt;
|
||||
rbf_t* rbfp;
|
||||
|
||||
int eth_init( bd_t *bd )
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
p_mac = AT91C_BASE_EMAC;
|
||||
|
||||
*AT91C_PIOA_PDR = AT91C_PA16_EMDIO |
|
||||
AT91C_PA15_EMDC | AT91C_PA14_ERXER | AT91C_PA13_ERX1 | AT91C_PA12_ERX0 |
|
||||
AT91C_PA11_ECRS_ECRSDV | AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN |
|
||||
AT91C_PA7_ETXCK_EREFCK; /* PIO Disable Register */
|
||||
|
||||
*AT91C_PIOB_PDR = AT91C_PB25_EF100 |
|
||||
AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 |
|
||||
AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
|
||||
|
||||
*AT91C_PIOB_BSR = AT91C_PB25_EF100 |
|
||||
AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 |
|
||||
AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2; /* Select B Register */
|
||||
*AT91C_PMC_PCER = 1 << AT91C_ID_EMAC; /* Peripheral Clock Enable Register */
|
||||
p_mac->EMAC_CFG |= AT91C_EMAC_CSR; /* Clear statistics */
|
||||
|
||||
rbfdt=(rbf_t *)RBF_FRAMEBTD;
|
||||
for(i = 0; i < RBF_FRAMEMAX; i++)
|
||||
{
|
||||
rbfdt[i].addr=RBF_FRAMEBUF+RBF_FRAMELEN*i;
|
||||
rbfdt[i].size=0;
|
||||
}
|
||||
rbfdt[RBF_FRAMEMAX-1].addr|=RBF_WRAP;
|
||||
rbfp=&rbfdt[0];
|
||||
|
||||
if (!(ret = MDIO_StartupPhy()))
|
||||
{
|
||||
printf("MAC: error during MII initialization\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
p_mac->EMAC_SA2L = (bd->bi_enetaddr[3] << 24) | (bd->bi_enetaddr[2] << 16)
|
||||
| (bd->bi_enetaddr[1] << 8) | (bd->bi_enetaddr[0]);
|
||||
p_mac->EMAC_SA2H = (bd->bi_enetaddr[5] << 8) | (bd->bi_enetaddr[4]);
|
||||
|
||||
p_mac->EMAC_RBQP = (long)(&rbfdt[0]);
|
||||
p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
|
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC | AT91C_EMAC_RMII) & ~AT91C_EMAC_CLK;
|
||||
p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eth_send(volatile void *packet, int length)
|
||||
{
|
||||
while(!(p_mac->EMAC_TSR & AT91C_EMAC_BNQ))
|
||||
;
|
||||
p_mac->EMAC_TAR = (long)packet;
|
||||
p_mac->EMAC_TCR = length;
|
||||
while(p_mac->EMAC_TCR & 0x7ff)
|
||||
;
|
||||
p_mac->EMAC_TSR |= AT91C_EMAC_COMP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eth_rx(void)
|
||||
{
|
||||
int size;
|
||||
|
||||
if(!(rbfp->addr & RBF_OWNER))
|
||||
return 0;
|
||||
|
||||
size=rbfp->size & RBF_SIZE;
|
||||
NetReceive((volatile uchar *) (rbfp->addr & RBF_ADDR), size);
|
||||
|
||||
rbfp->addr &= ~RBF_OWNER;
|
||||
if(rbfp->addr & RBF_WRAP)
|
||||
rbfp = &rbfdt[0];
|
||||
else
|
||||
rbfp++;
|
||||
|
||||
p_mac->EMAC_RSR |= AT91C_EMAC_REC;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void eth_halt( void )
|
||||
{};
|
||||
#endif
|
||||
#endif
|
||||
245
drivers/dataflash.c
Normal file
245
drivers/dataflash.c
Normal file
@@ -0,0 +1,245 @@
|
||||
/* LowLevel function for ATMEL DataFlash support
|
||||
* Author : Hamid Ikdoumi (Atmel)
|
||||
*
|
||||
* 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 <config.h>
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
#include <asm/hardware.h>
|
||||
#include <dataflash.h>
|
||||
|
||||
AT91S_DATAFLASH_INFO dataflash_info[CFG_MAX_DATAFLASH_BANKS];
|
||||
static AT91S_DataFlash DataFlashInst;
|
||||
|
||||
int cs[][CFG_MAX_DATAFLASH_BANKS] = {
|
||||
{CFG_DATAFLASH_LOGIC_ADDR_CS0, 0}, /* Logical adress, CS */
|
||||
{CFG_DATAFLASH_LOGIC_ADDR_CS3, 3}
|
||||
};
|
||||
|
||||
extern void AT91F_SpiInit (void);
|
||||
extern int AT91F_DataflashProbe (int i, AT91PS_DataflashDesc pDesc);
|
||||
extern int AT91F_DataFlashRead (AT91PS_DataFlash pDataFlash,
|
||||
unsigned long addr,
|
||||
unsigned long size, char *buffer);
|
||||
|
||||
|
||||
int AT91F_DataflashInit (void)
|
||||
{
|
||||
int i, j;
|
||||
int dfcode;
|
||||
|
||||
AT91F_SpiInit ();
|
||||
|
||||
for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
|
||||
|
||||
dataflash_info[i].id = 0;
|
||||
dataflash_info[i].Device.pages_number = 0;
|
||||
dfcode = AT91F_DataflashProbe (cs[i][1], &dataflash_info[i].Desc);
|
||||
|
||||
switch (dfcode) {
|
||||
case AT45DB161:
|
||||
dataflash_info[i].Device.pages_number = 4096;
|
||||
dataflash_info[i].Device.pages_size = 528;
|
||||
dataflash_info[i].Device.page_offset = 10;
|
||||
dataflash_info[i].Device.byte_mask = 0x300;
|
||||
dataflash_info[i].Device.cs = cs[i][1];
|
||||
dataflash_info[i].Desc.DataFlash_state = IDLE;
|
||||
dataflash_info[i].logical_address = cs[i][0];
|
||||
dataflash_info[i].id = dfcode;
|
||||
break;
|
||||
|
||||
case AT45DB321:
|
||||
dataflash_info[i].Device.pages_number = 8192;
|
||||
dataflash_info[i].Device.pages_size = 528;
|
||||
dataflash_info[i].Device.page_offset = 10;
|
||||
dataflash_info[i].Device.byte_mask = 0x300;
|
||||
dataflash_info[i].Device.cs = cs[i][1];
|
||||
dataflash_info[i].Desc.DataFlash_state = IDLE;
|
||||
dataflash_info[i].logical_address = cs[i][0];
|
||||
dataflash_info[i].id = dfcode;
|
||||
break;
|
||||
|
||||
case AT45DB642:
|
||||
dataflash_info[i].Device.pages_number = 8192;
|
||||
dataflash_info[i].Device.pages_size = 1056;
|
||||
dataflash_info[i].Device.page_offset = 11;
|
||||
dataflash_info[i].Device.byte_mask = 0x700;
|
||||
dataflash_info[i].Device.cs = cs[i][1];
|
||||
dataflash_info[i].Desc.DataFlash_state = IDLE;
|
||||
dataflash_info[i].logical_address = cs[i][0];
|
||||
dataflash_info[i].id = dfcode;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (j = 0; j < dataflash_info[i].Device.pages_number; j++)
|
||||
dataflash_info[i].protect[j] = FLAG_PROTECT_SET;
|
||||
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void dataflash_print_info (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
|
||||
if (dataflash_info[i].id != 0) {
|
||||
printf ("DataFlash:");
|
||||
switch (dataflash_info[i].id) {
|
||||
case AT45DB161:
|
||||
printf ("AT45DB161\n");
|
||||
break;
|
||||
|
||||
case AT45DB321:
|
||||
printf ("AT45DB321\n");
|
||||
break;
|
||||
|
||||
case AT45DB642:
|
||||
printf ("AT45DB642\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf ("Nb pages: %6d\n"
|
||||
"Page Size: %6d\n"
|
||||
"Size=%8d bytes\n"
|
||||
"Logical address: 0x%08X\n",
|
||||
(unsigned int) dataflash_info[i].Device.pages_number,
|
||||
(unsigned int) dataflash_info[i].Device.pages_size,
|
||||
(unsigned int) dataflash_info[i].Device.pages_number *
|
||||
dataflash_info[i].Device.pages_size,
|
||||
(unsigned int) dataflash_info[i].logical_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Function Name : AT91F_DataflashSelect */
|
||||
/* Object : Select the correct device */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
AT91PS_DataFlash AT91F_DataflashSelect (AT91PS_DataFlash pFlash,
|
||||
unsigned int *addr)
|
||||
{
|
||||
char addr_valid = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++)
|
||||
if ((*addr & 0xFF000000) == dataflash_info[i].logical_address) {
|
||||
addr_valid = 1;
|
||||
break;
|
||||
}
|
||||
if (!addr_valid) {
|
||||
pFlash = (AT91PS_DataFlash) 0;
|
||||
return pFlash;
|
||||
}
|
||||
pFlash->pDataFlashDesc = &(dataflash_info[i].Desc);
|
||||
pFlash->pDevice = &(dataflash_info[i].Device);
|
||||
*addr -= dataflash_info[i].logical_address;
|
||||
return (pFlash);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Function Name : addr_dataflash */
|
||||
/* Object : Test if address is valid */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
int addr_dataflash (unsigned long addr)
|
||||
{
|
||||
int addr_valid = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
|
||||
if ((((int) addr) & 0xFF000000) ==
|
||||
dataflash_info[i].logical_address) {
|
||||
addr_valid = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return addr_valid;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Function Name : read_dataflash */
|
||||
/* Object : dataflash memory read */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
int read_dataflash (unsigned long addr, unsigned long size, char *result)
|
||||
{
|
||||
int AddrToRead = addr;
|
||||
AT91PS_DataFlash pFlash = &DataFlashInst;
|
||||
|
||||
pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead);
|
||||
if (pFlash == 0)
|
||||
return -1;
|
||||
|
||||
return (AT91F_DataFlashRead (pFlash, AddrToRead, size, result));
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Function Name : write_dataflash */
|
||||
/* Object : write a block in dataflash */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
int write_dataflash (unsigned long addr_dest, unsigned long addr_src,
|
||||
unsigned long size)
|
||||
{
|
||||
extern AT91S_DataFlashStatus AT91F_DataFlashWrite(
|
||||
AT91PS_DataFlash, uchar *, int, int);
|
||||
int AddrToWrite = addr_dest;
|
||||
AT91PS_DataFlash pFlash = &DataFlashInst;
|
||||
|
||||
pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite);
|
||||
if (AddrToWrite == -1)
|
||||
return -1;
|
||||
|
||||
return AT91F_DataFlashWrite (pFlash, (char *) addr_src, AddrToWrite,
|
||||
size);
|
||||
}
|
||||
|
||||
|
||||
void dataflash_perror (int err)
|
||||
{
|
||||
switch (err) {
|
||||
case ERR_OK:
|
||||
break;
|
||||
case ERR_TIMOUT:
|
||||
printf ("Timeout writing to DataFlash\n");
|
||||
break;
|
||||
case ERR_PROTECTED:
|
||||
printf ("Can't write to protected DataFlash sectors\n");
|
||||
break;
|
||||
case ERR_INVAL:
|
||||
printf ("Outside available DataFlash\n");
|
||||
break;
|
||||
case ERR_UNKNOWN_FLASH_TYPE:
|
||||
printf ("Unknown Type of DataFlash\n");
|
||||
break;
|
||||
case ERR_PROG_ERROR:
|
||||
printf ("General DataFlash Programming Error\n");
|
||||
break;
|
||||
default:
|
||||
printf ("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -39,103 +39,114 @@
|
||||
|
||||
#ifdef CONFIG_HARD_I2C
|
||||
|
||||
#define IIC_WRITE 0
|
||||
#define IIC_READ 1
|
||||
#define I2C_WRITE 0
|
||||
#define I2C_READ 1
|
||||
|
||||
#define IIC_OK 0
|
||||
#define IIC_NOK 1
|
||||
#define IIC_NACK 2
|
||||
#define IIC_NOK_LA 3 /* Lost arbitration */
|
||||
#define IIC_NOK_TOUT 4 /* time out */
|
||||
#define I2C_OK 0
|
||||
#define I2C_NOK 1
|
||||
#define I2C_NACK 2
|
||||
#define I2C_NOK_LA 3 /* Lost arbitration */
|
||||
#define I2C_NOK_TOUT 4 /* time out */
|
||||
|
||||
#define IICSTAT_BSY 0x20 /* Busy bit */
|
||||
#define IICSTAT_NACK 0x01 /* Nack bit */
|
||||
#define IICCON_IRPND 0x10 /* Interrupt pending bit */
|
||||
#define IIC_MODE_MT 0xC0 /* Master Transmit Mode */
|
||||
#define IIC_MODE_MR 0x80 /* Master Receive Mode */
|
||||
#define IIC_START_STOP 0x20 /* START / STOP */
|
||||
#define IIC_TXRX_ENA 0x10 /* I2C Tx/Rx enable */
|
||||
#define I2CSTAT_BSY 0x20 /* Busy bit */
|
||||
#define I2CSTAT_NACK 0x01 /* Nack bit */
|
||||
#define I2CCON_IRPND 0x10 /* Interrupt pending bit */
|
||||
#define I2C_MODE_MT 0xC0 /* Master Transmit Mode */
|
||||
#define I2C_MODE_MR 0x80 /* Master Receive Mode */
|
||||
#define I2C_START_STOP 0x20 /* START / STOP */
|
||||
#define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */
|
||||
|
||||
#define IIC_TIMEOUT 1 /* 1 seconde */
|
||||
#define I2C_TIMEOUT 1 /* 1 seconde */
|
||||
|
||||
|
||||
static int GetIICSDA(void)
|
||||
static int GetI2CSDA(void)
|
||||
{
|
||||
return (rGPEDAT & 0x8000) >> 15;
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
return (gpio->GPEDAT & 0x8000) >> 15;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void SetIICSDA(int x)
|
||||
static void SetI2CSDA(int x)
|
||||
{
|
||||
rGPEDAT = (rGPEDAT & ~0x8000) | (x&1) << 15;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void SetIICSCL(int x)
|
||||
static void SetI2CSCL(int x)
|
||||
{
|
||||
rGPEDAT = (rGPEDAT & ~0x4000) | (x&1) << 14;
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
gpio->GPEDAT = (gpio->GPEDAT & ~0x4000) | (x&1) << 14;
|
||||
}
|
||||
|
||||
|
||||
static int WaitForXfer(void)
|
||||
{
|
||||
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
|
||||
int i, status;
|
||||
|
||||
i = IIC_TIMEOUT * 1000;
|
||||
status = rIICCON;
|
||||
while ((i > 0) && !(status & IICCON_IRPND)) {
|
||||
i = I2C_TIMEOUT * 1000;
|
||||
status = i2c->IICCON;
|
||||
while ((i > 0) && !(status & I2CCON_IRPND)) {
|
||||
udelay(1000);
|
||||
status = rIICCON;
|
||||
status = i2c->IICCON;
|
||||
i--;
|
||||
}
|
||||
|
||||
return(status & IICCON_IRPND) ? IIC_OK : IIC_NOK_TOUT;
|
||||
return(status & I2CCON_IRPND) ? I2C_OK : I2C_NOK_TOUT;
|
||||
}
|
||||
|
||||
static int IsACK(void)
|
||||
{
|
||||
return(!(rIICSTAT & IICSTAT_NACK));
|
||||
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
|
||||
|
||||
return(!(i2c->IICSTAT & I2CSTAT_NACK));
|
||||
}
|
||||
|
||||
static void ReadWriteByte(void)
|
||||
{
|
||||
rIICCON &= ~IICCON_IRPND;
|
||||
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
|
||||
|
||||
i2c->IICCON &= ~I2CCON_IRPND;
|
||||
}
|
||||
|
||||
void i2c_init (int speed, int slaveadd)
|
||||
{
|
||||
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
ulong freq, pres = 16, div;
|
||||
int i, status;
|
||||
|
||||
/* wait for some time to give previous transfer a chance to finish */
|
||||
|
||||
i = IIC_TIMEOUT * 1000;
|
||||
status = rIICSTAT;
|
||||
while ((i > 0) && (status & IICSTAT_BSY)) {
|
||||
i = I2C_TIMEOUT * 1000;
|
||||
status = i2c->IICSTAT;
|
||||
while ((i > 0) && (status & I2CSTAT_BSY)) {
|
||||
udelay(1000);
|
||||
status = rIICSTAT;
|
||||
status = i2c->IICSTAT;
|
||||
i--;
|
||||
}
|
||||
|
||||
if ((status & IICSTAT_BSY) || GetIICSDA() == 0) {
|
||||
ulong old_gpecon = rGPECON;
|
||||
if ((status & I2CSTAT_BSY) || GetI2CSDA() == 0) {
|
||||
ulong old_gpecon = gpio->GPECON;
|
||||
/* bus still busy probably by (most) previously interrupted transfer */
|
||||
|
||||
/* set IICSDA and IICSCL (GPE15, GPE14) to GPIO */
|
||||
rGPECON = (rGPECON & ~0xF0000000) | 0x10000000;
|
||||
/* set I2CSDA and I2CSCL (GPE15, GPE14) to GPIO */
|
||||
gpio->GPECON = (gpio->GPECON & ~0xF0000000) | 0x10000000;
|
||||
|
||||
/* toggle IICSCL until bus idle */
|
||||
SetIICSCL(0); udelay(1000);
|
||||
/* toggle I2CSCL until bus idle */
|
||||
SetI2CSCL(0); udelay(1000);
|
||||
i = 10;
|
||||
while ((i > 0) && (GetIICSDA() != 1)) {
|
||||
SetIICSCL(1); udelay(1000);
|
||||
SetIICSCL(0); udelay(1000);
|
||||
while ((i > 0) && (GetI2CSDA() != 1)) {
|
||||
SetI2CSCL(1); udelay(1000);
|
||||
SetI2CSCL(0); udelay(1000);
|
||||
i--;
|
||||
}
|
||||
SetIICSCL(1); udelay(1000);
|
||||
SetI2CSCL(1); udelay(1000);
|
||||
|
||||
/* restore pin functions */
|
||||
rGPECON = old_gpecon;
|
||||
gpio->GPECON = old_gpecon;
|
||||
}
|
||||
|
||||
/* calculate prescaler and divisor values */
|
||||
@@ -150,13 +161,13 @@ void i2c_init (int speed, int slaveadd)
|
||||
|
||||
/* set prescaler, divisor according to freq, also set
|
||||
ACKGEN, IRQ */
|
||||
rIICCON = (div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0);
|
||||
i2c->IICCON = (div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0);
|
||||
|
||||
/* init to SLAVE REVEIVE and set slaveaddr */
|
||||
rIICSTAT = 0;
|
||||
rIICADD = slaveadd;
|
||||
i2c->IICSTAT = 0;
|
||||
i2c->IICADD = slaveadd;
|
||||
/* program Master Transmit (and implicit STOP) */
|
||||
rIICSTAT = IIC_MODE_MT | IIC_TXRX_ENA;
|
||||
i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA;
|
||||
|
||||
}
|
||||
|
||||
@@ -176,142 +187,143 @@ int i2c_transfer(unsigned char cmd_type,
|
||||
unsigned char data[],
|
||||
unsigned short data_len)
|
||||
{
|
||||
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
|
||||
int i, status, result;
|
||||
|
||||
if (data == 0 || data_len == 0) {
|
||||
/*Don't support data transfer of no length or to address 0*/
|
||||
printf( "i2c_transfer: bad call\n" );
|
||||
return IIC_NOK;
|
||||
return I2C_NOK;
|
||||
}
|
||||
|
||||
//CheckDelay();
|
||||
|
||||
/* Check I2C bus idle */
|
||||
i = IIC_TIMEOUT * 1000;
|
||||
status = rIICSTAT;
|
||||
while ((i > 0) && (status & IICSTAT_BSY)) {
|
||||
i = I2C_TIMEOUT * 1000;
|
||||
status = i2c->IICSTAT;
|
||||
while ((i > 0) && (status & I2CSTAT_BSY)) {
|
||||
udelay(1000);
|
||||
status = rIICSTAT;
|
||||
status = i2c->IICSTAT;
|
||||
i--;
|
||||
}
|
||||
|
||||
|
||||
if (status & IICSTAT_BSY) {
|
||||
result = IIC_NOK_TOUT;
|
||||
if (status & I2CSTAT_BSY) {
|
||||
result = I2C_NOK_TOUT;
|
||||
return(result);
|
||||
}
|
||||
|
||||
rIICCON |= 0x80;
|
||||
i2c->IICCON |= 0x80;
|
||||
|
||||
result = IIC_OK;
|
||||
result = I2C_OK;
|
||||
|
||||
switch (cmd_type) {
|
||||
case IIC_WRITE:
|
||||
case I2C_WRITE:
|
||||
if (addr && addr_len) {
|
||||
rIICDS = chip;
|
||||
i2c->IICDS = chip;
|
||||
/* send START */
|
||||
rIICSTAT = IIC_MODE_MT | IIC_TXRX_ENA | IIC_START_STOP;
|
||||
i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP;
|
||||
i = 0;
|
||||
while ((i < addr_len) && (result == IIC_OK)) {
|
||||
while ((i < addr_len) && (result == I2C_OK)) {
|
||||
result = WaitForXfer();
|
||||
rIICDS = addr[i];
|
||||
i2c->IICDS = addr[i];
|
||||
ReadWriteByte();
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while ((i < data_len) && (result == IIC_OK)) {
|
||||
while ((i < data_len) && (result == I2C_OK)) {
|
||||
result = WaitForXfer();
|
||||
rIICDS = data[i];
|
||||
i2c->IICDS = data[i];
|
||||
ReadWriteByte();
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
rIICDS = chip;
|
||||
i2c->IICDS = chip;
|
||||
/* send START */
|
||||
rIICSTAT = IIC_MODE_MT | IIC_TXRX_ENA | IIC_START_STOP;
|
||||
i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP;
|
||||
i = 0;
|
||||
while ((i < data_len) && (result = IIC_OK)) {
|
||||
while ((i < data_len) && (result = I2C_OK)) {
|
||||
result = WaitForXfer();
|
||||
rIICDS = data[i];
|
||||
i2c->IICDS = data[i];
|
||||
ReadWriteByte();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == IIC_OK)
|
||||
if (result == I2C_OK)
|
||||
result = WaitForXfer();
|
||||
|
||||
/* send STOP */
|
||||
rIICSTAT = IIC_MODE_MR | IIC_TXRX_ENA;
|
||||
i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA;
|
||||
ReadWriteByte();
|
||||
break;
|
||||
|
||||
case IIC_READ:
|
||||
case I2C_READ:
|
||||
if (addr && addr_len) {
|
||||
rIICSTAT = IIC_MODE_MT | IIC_TXRX_ENA;
|
||||
rIICDS = chip;
|
||||
i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA;
|
||||
i2c->IICDS = chip;
|
||||
/* send START */
|
||||
rIICSTAT |= IIC_START_STOP;
|
||||
i2c->IICSTAT |= I2C_START_STOP;
|
||||
result = WaitForXfer();
|
||||
if (IsACK()) {
|
||||
i = 0;
|
||||
while ((i < addr_len) && (result == IIC_OK)) {
|
||||
rIICDS = addr[i];
|
||||
while ((i < addr_len) && (result == I2C_OK)) {
|
||||
i2c->IICDS = addr[i];
|
||||
ReadWriteByte();
|
||||
result = WaitForXfer();
|
||||
i++;
|
||||
}
|
||||
|
||||
rIICDS = chip;
|
||||
i2c->IICDS = chip;
|
||||
/* resend START */
|
||||
rIICSTAT = IIC_MODE_MR | IIC_TXRX_ENA | IIC_START_STOP;
|
||||
i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA | I2C_START_STOP;
|
||||
ReadWriteByte();
|
||||
result = WaitForXfer();
|
||||
i = 0;
|
||||
while ((i < data_len) && (result == IIC_OK)) {
|
||||
while ((i < data_len) && (result == I2C_OK)) {
|
||||
/* disable ACK for final READ */
|
||||
if (i == data_len - 1)
|
||||
rIICCON &= ~0x80;
|
||||
i2c->IICCON &= ~0x80;
|
||||
ReadWriteByte();
|
||||
result = WaitForXfer();
|
||||
data[i] = rIICDS;
|
||||
data[i] = i2c->IICDS;
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
result = IIC_NACK;
|
||||
result = I2C_NACK;
|
||||
}
|
||||
|
||||
} else {
|
||||
rIICSTAT = IIC_MODE_MR | IIC_TXRX_ENA;
|
||||
rIICDS = chip;
|
||||
i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA;
|
||||
i2c->IICDS = chip;
|
||||
/* send START */
|
||||
rIICSTAT |= IIC_START_STOP;
|
||||
i2c->IICSTAT |= I2C_START_STOP;
|
||||
result = WaitForXfer();
|
||||
|
||||
if (IsACK()) {
|
||||
i = 0;
|
||||
while ((i < data_len) && (result == IIC_OK)) {
|
||||
while ((i < data_len) && (result == I2C_OK)) {
|
||||
/* disable ACK for final READ */
|
||||
if (i == data_len - 1)
|
||||
rIICCON &= ~0x80;
|
||||
i2c->IICCON &= ~0x80;
|
||||
ReadWriteByte();
|
||||
result = WaitForXfer();
|
||||
data[i] = rIICDS;
|
||||
data[i] = i2c->IICDS;
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
result = IIC_NACK;
|
||||
result = I2C_NACK;
|
||||
}
|
||||
}
|
||||
|
||||
/* send STOP */
|
||||
rIICSTAT = IIC_MODE_MR | IIC_TXRX_ENA;
|
||||
i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA;
|
||||
ReadWriteByte();
|
||||
break;
|
||||
|
||||
default:
|
||||
printf( "i2c_transfer: bad call\n" );
|
||||
result = IIC_NOK;
|
||||
result = I2C_NOK;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -329,7 +341,7 @@ int i2c_probe (uchar chip)
|
||||
* address was <ACK>ed (i.e. there was a chip at that address which
|
||||
* drove the data line low).
|
||||
*/
|
||||
return(i2c_transfer (IIC_READ, chip << 1, 0, 0, buf, 1) != IIC_OK);
|
||||
return(i2c_transfer (I2C_READ, chip << 1, 0, 0, buf, 1) != I2C_OK);
|
||||
}
|
||||
|
||||
int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
|
||||
@@ -365,7 +377,7 @@ int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
|
||||
if( alen > 0 )
|
||||
chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
|
||||
#endif
|
||||
if( (ret = i2c_transfer(IIC_READ, chip<<1, &xaddr[4-alen], alen, buffer, len )) != 0) {
|
||||
if( (ret = i2c_transfer(I2C_READ, chip<<1, &xaddr[4-alen], alen, buffer, len )) != 0) {
|
||||
printf( "I2c read: failed %d\n", ret);
|
||||
return 1;
|
||||
}
|
||||
@@ -403,7 +415,7 @@ int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
|
||||
if( alen > 0 )
|
||||
chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
|
||||
#endif
|
||||
return (i2c_transfer(IIC_WRITE, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0);
|
||||
return (i2c_transfer(I2C_WRITE, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_HARD_I2C */
|
||||
|
||||
@@ -46,7 +46,8 @@ int serial_init (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
|
||||
int clock_divisor = (CFG_NS16550_CLK + gd->baudrate * 8 )
|
||||
/ (gd->baudrate * 16);
|
||||
|
||||
#ifdef CFG_NS87308
|
||||
initialise_ns87308();
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
. o skeleton.c by Donald Becker ( becker@cesdis.gsfc.nasa.gov )
|
||||
.
|
||||
. History:
|
||||
. 06/19/03 Richard Woodruff Made u-boot environment aware and added mac addr checks.
|
||||
. 10/17/01 Marco Hasewinkel Modify for DNP/1110
|
||||
. 07/25/01 Woojung Huh Modify for ADS Bitsy
|
||||
. 04/25/01 Daris A Nevil Initial public release through SMSC
|
||||
@@ -176,7 +177,7 @@ void smc_destructor(void);
|
||||
. The kernel calls this function when someone wants to use the device,
|
||||
. typically 'ifconfig ethX up'.
|
||||
*/
|
||||
static int smc_open(void);
|
||||
static int smc_open(bd_t *bd);
|
||||
|
||||
|
||||
/*
|
||||
@@ -199,7 +200,12 @@ static void smc_phy_configure(void);
|
||||
*/
|
||||
static int smc_rcv(void);
|
||||
|
||||
|
||||
/* See if a MAC address is defined in the current environment. If so use it. If not
|
||||
. print a warning and set the environment and other globals with the default.
|
||||
. If an EEPROM is present it really should be consulted.
|
||||
*/
|
||||
int smc_get_ethaddr(bd_t *bd);
|
||||
int get_rom_mac(char *v_rom_mac);
|
||||
|
||||
/*
|
||||
------------------------------------------------------------
|
||||
@@ -226,7 +232,7 @@ void smc_set_mac_addr(const char *addr) {
|
||||
|
||||
/*
|
||||
* smc_get_macaddr is no longer used. If you want to override the default
|
||||
* mac address, call smc_get_mac_addr as a part of the board initialisation.
|
||||
* mac address, call smc_get_mac_addr as a part of the board initialization.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
@@ -317,6 +323,17 @@ static int poll4int( byte mask, int timeout ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only one release command at a time, please */
|
||||
static inline void smc_wait_mmu_release_complete(void)
|
||||
{
|
||||
int count = 0;
|
||||
/* assume bank 2 selected */
|
||||
while ( SMC_inw(MMU_CMD_REG) & MC_BUSY ) {
|
||||
udelay(1); // Wait until not busy
|
||||
if( ++count > 200) break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
. Function: smc_reset( void )
|
||||
. Purpose:
|
||||
@@ -374,6 +391,7 @@ static void smc_reset( void )
|
||||
|
||||
/* Reset the MMU */
|
||||
SMC_SELECT_BANK( 2 );
|
||||
smc_wait_mmu_release_complete();
|
||||
SMC_outw( MC_RESET, MMU_CMD_REG );
|
||||
while ( SMC_inw( MMU_CMD_REG ) & MC_BUSY )
|
||||
udelay(1); /* Wait until not busy */
|
||||
@@ -653,14 +671,13 @@ void smc_destructor()
|
||||
* Set up everything, reset the card, etc ..
|
||||
*
|
||||
*/
|
||||
static int smc_open()
|
||||
static int smc_open(bd_t *bd)
|
||||
{
|
||||
int i; /* used to set hw ethernet address */
|
||||
int i, err;
|
||||
|
||||
PRINTK2("%s:smc_open\n", SMC_DEV_NAME);
|
||||
|
||||
/* reset the hardware */
|
||||
|
||||
smc_reset();
|
||||
smc_enable();
|
||||
|
||||
@@ -669,10 +686,16 @@ static int smc_open()
|
||||
smc_phy_configure();
|
||||
#endif
|
||||
|
||||
|
||||
/* conservative setting (10Mbps, HalfDuplex, no AutoNeg.) */
|
||||
/* SMC_SELECT_BANK(0); */
|
||||
/* SMC_outw(0, RPC_REG); */
|
||||
SMC_SELECT_BANK(1);
|
||||
|
||||
err = smc_get_ethaddr(bd); /* set smc_mac_addr, and sync it with u-boot globals */
|
||||
if(err < 0){
|
||||
memset(bd->bi_enetaddr, 0, 6); /* hack to make error stick! upper code will abort if not set*/
|
||||
return(-1); /* upper code ignores this, but NOT bi_enetaddr */
|
||||
}
|
||||
|
||||
#ifdef USE_32_BIT
|
||||
for ( i = 0; i < 6; i += 2 ) {
|
||||
@@ -1371,8 +1394,7 @@ static void print_packet( byte * buf, int length )
|
||||
#endif
|
||||
|
||||
int eth_init(bd_t *bd) {
|
||||
smc_open();
|
||||
return 0;
|
||||
return (smc_open(bd));
|
||||
}
|
||||
|
||||
void eth_halt() {
|
||||
@@ -1387,4 +1409,74 @@ int eth_send(volatile void *packet, int length) {
|
||||
return smc_send_packet(packet, length);
|
||||
}
|
||||
|
||||
int smc_get_ethaddr(bd_t *bd)
|
||||
{
|
||||
int env_size, rom_valid, env_present = 0, reg;
|
||||
char *s = NULL, *e, *v_mac, es[] = "11:22:33:44:55:66";
|
||||
uchar s_env_mac[64], v_env_mac[6], v_rom_mac[6];
|
||||
|
||||
env_size = getenv_r ("ethaddr", s_env_mac, sizeof (s_env_mac));
|
||||
if ((env_size > 0) && (env_size < sizeof(es))) { /* exit if env is bad */
|
||||
printf("\n*** ERROR: ethaddr is not set properly!!\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if(env_size > 0){
|
||||
env_present = 1;
|
||||
s = s_env_mac;
|
||||
}
|
||||
|
||||
for (reg = 0; reg < 6; ++reg) { /* turn string into mac value */
|
||||
v_env_mac[reg] = s ? simple_strtoul (s, &e, 16) : 0;
|
||||
if (s)
|
||||
s = (*e) ? e + 1 : e;
|
||||
}
|
||||
|
||||
rom_valid = get_rom_mac(v_rom_mac); /* get ROM mac value if any */
|
||||
|
||||
if(!env_present){ /* if NO env */
|
||||
if(rom_valid){ /* but ROM is valid */
|
||||
v_mac = v_rom_mac;
|
||||
sprintf (s_env_mac, "%02X:%02X:%02X:%02X:%02X:%02X", v_mac[0],
|
||||
v_mac[1] ,v_mac[2], v_mac[3],v_mac[4], v_mac[5]) ;
|
||||
setenv ("ethaddr", s_env_mac);
|
||||
}else{ /* no env, bad ROM */
|
||||
printf("\n*** ERROR: ethaddr is NOT set !!\n");
|
||||
return(-1);
|
||||
}
|
||||
}else /* good env, don't care ROM */
|
||||
v_mac = v_env_mac; /* always use a good env over a ROM */
|
||||
|
||||
if(env_present && rom_valid) /* if both env and ROM are good */
|
||||
if(memcmp(v_env_mac, v_rom_mac, 6) != 0){
|
||||
printf("\n*** Warning: Environment and ROM MAC addresses don't match\n");
|
||||
printf("*** Using Environment MAC\n");
|
||||
}
|
||||
memcpy (bd->bi_enetaddr, v_mac, 6); /* update global address to match env (allows env changing) */
|
||||
smc_set_mac_addr(v_mac); /* use old function to update smc default */
|
||||
return(0);
|
||||
}
|
||||
|
||||
int get_rom_mac(char *v_rom_mac)
|
||||
{
|
||||
int is_rom_present = 0;
|
||||
#ifdef HARDCODE_MAC /* used for testing or to supress run time warnings */
|
||||
char hw_mac_addr[] = {0x02, 0x80, 0xad, 0x20, 0x31, 0xb8};
|
||||
|
||||
memcpy (v_rom_mac, hw_mac_addr, 6);
|
||||
return(1);
|
||||
#else
|
||||
if(is_rom_present)
|
||||
{
|
||||
/* if eeprom contents are valid
|
||||
* extract mac address into hw_mac_addr, 8 or 16 bit accesses
|
||||
* memcpy (v_rom_mac, hc_mac_addr, 6);
|
||||
* return(1);
|
||||
*/
|
||||
}
|
||||
memset(v_rom_mac, 0, 6);
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DRIVER_SMC91111 */
|
||||
|
||||
@@ -80,7 +80,7 @@ typedef unsigned long int dword;
|
||||
#define SMC_inw(r) (*((volatile word *)(SMC_BASE_ADDRESS+(r))))
|
||||
#define SMC_inb(p) ({ \
|
||||
unsigned int __p = (unsigned int)(SMC_BASE_ADDRESS + (p)); \
|
||||
unsigned int __v = *(volatile unsigned short *)((SMC_BASE_ADDRESS + __p) & ~1); \
|
||||
unsigned int __v = *(volatile unsigned short *)((__p) & ~1); \
|
||||
if (__p & 1) __v >>= 8; \
|
||||
else __v &= 0xff; \
|
||||
__v; })
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (C) Copyright 2000
|
||||
* (C) Copyright 2000-2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
@@ -22,13 +22,12 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc8xx.h>
|
||||
#include <status_led.h>
|
||||
|
||||
/*
|
||||
* The purpose of this code is to signal the operational status of a
|
||||
* target which usually boots over the network; while running in
|
||||
* PCBoot, a status LED is blinking. As soon as a valid BOOTP reply
|
||||
* U-Boot, a status LED is blinking. As soon as a valid BOOTP reply
|
||||
* message has been received, the LED is turned off. The Linux
|
||||
* kernel, once it is running, will start blinking the LED again,
|
||||
* with another frequency.
|
||||
@@ -39,10 +38,10 @@
|
||||
#ifdef CONFIG_STATUS_LED
|
||||
|
||||
typedef struct {
|
||||
ulong mask;
|
||||
int state;
|
||||
int period;
|
||||
int cnt;
|
||||
led_id_t mask;
|
||||
int state;
|
||||
int period;
|
||||
int cnt;
|
||||
} led_dev_t;
|
||||
|
||||
led_dev_t led_dev[] = {
|
||||
@@ -80,89 +79,53 @@ static int status_led_init_done = 0;
|
||||
|
||||
static void status_led_init (void)
|
||||
{
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
int i;
|
||||
led_dev_t *ld;
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_LED_DEV; ++i) {
|
||||
led_dev_t *ld = &led_dev[i];
|
||||
|
||||
immr->STATUS_LED_PAR &= ~(ld->mask);
|
||||
#ifdef STATUS_LED_ODR
|
||||
immr->STATUS_LED_ODR &= ~(ld->mask);
|
||||
#endif
|
||||
#if (STATUS_LED_ACTIVE == 0)
|
||||
if (ld->state == STATUS_LED_ON)
|
||||
immr->STATUS_LED_DAT &= ~(ld->mask);
|
||||
else
|
||||
immr->STATUS_LED_DAT |= ld->mask ;
|
||||
#else
|
||||
if (ld->state == STATUS_LED_ON)
|
||||
immr->STATUS_LED_DAT |= ld->mask ;
|
||||
else
|
||||
immr->STATUS_LED_DAT &= ~(ld->mask);
|
||||
#endif
|
||||
immr->STATUS_LED_DIR |= ld->mask ;
|
||||
}
|
||||
|
||||
status_led_init_done = 1;
|
||||
for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++)
|
||||
__led_init (ld->mask, ld->state);
|
||||
status_led_init_done = 1;
|
||||
}
|
||||
|
||||
void status_led_tick (ulong timestamp)
|
||||
{
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
int i;
|
||||
led_dev_t *ld;
|
||||
int i;
|
||||
|
||||
if (!status_led_init_done)
|
||||
status_led_init();
|
||||
if (!status_led_init_done)
|
||||
status_led_init ();
|
||||
|
||||
for (i=0; i<MAX_LED_DEV; ++i) {
|
||||
led_dev_t *ld = &led_dev[i];
|
||||
for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++) {
|
||||
|
||||
if (ld->state != STATUS_LED_BLINKING)
|
||||
continue;
|
||||
if (ld->state != STATUS_LED_BLINKING)
|
||||
continue;
|
||||
|
||||
if (++ld->cnt >= ld->period) {
|
||||
__led_toggle (ld->mask);
|
||||
ld->cnt -= ld->period;
|
||||
}
|
||||
|
||||
if (++(ld->cnt) >= ld->period) {
|
||||
immr->STATUS_LED_DAT ^= ld->mask;
|
||||
ld->cnt -= ld->period;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void status_led_set (int led, int state)
|
||||
{
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
led_dev_t *ld;
|
||||
led_dev_t *ld;
|
||||
|
||||
if (led < 0 || led >= MAX_LED_DEV)
|
||||
return;
|
||||
if (led < 0 || led >= MAX_LED_DEV)
|
||||
return;
|
||||
|
||||
if (!status_led_init_done)
|
||||
status_led_init();
|
||||
if (!status_led_init_done)
|
||||
status_led_init ();
|
||||
|
||||
ld = &led_dev[led];
|
||||
ld = &led_dev[led];
|
||||
|
||||
switch (state) {
|
||||
default:
|
||||
return;
|
||||
case STATUS_LED_BLINKING:
|
||||
ld->cnt = 0; /* always start with full period */
|
||||
/* fall through */ /* always start with LED _ON_ */
|
||||
case STATUS_LED_ON:
|
||||
#if (STATUS_LED_ACTIVE == 0)
|
||||
immr->STATUS_LED_DAT &= ~(ld->mask);
|
||||
#else
|
||||
immr->STATUS_LED_DAT |= ld->mask ;
|
||||
#endif
|
||||
break;
|
||||
case STATUS_LED_OFF:
|
||||
#if (STATUS_LED_ACTIVE == 0)
|
||||
immr->STATUS_LED_DAT |= ld->mask ;
|
||||
#else
|
||||
immr->STATUS_LED_DAT &= ~(ld->mask);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
ld->state = state;
|
||||
ld->state = state;
|
||||
if (state == STATUS_LED_BLINKING) {
|
||||
ld->cnt = 0; /* always start with full period */
|
||||
state = STATUS_LED_ON; /* always start with LED _ON_ */
|
||||
}
|
||||
__led_set (ld->mask, state);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_STATUS_LED */
|
||||
@@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = libdtt.a
|
||||
|
||||
OBJS = lm75.o ds1621.o
|
||||
OBJS = lm75.o ds1621.o adm1021.o
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
|
||||
171
dtt/adm1021.c
Normal file
171
dtt/adm1021.c
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Murray Jensen, CSIRO-MIT, Murray.Jensen@csiro.au
|
||||
*
|
||||
* based on dtt/lm75.c which is ...
|
||||
*
|
||||
* (C) Copyright 2001
|
||||
* Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Analog Devices's ADM1021
|
||||
* "Low Cost Microprocessor System Temperature Monitor"
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#ifdef CONFIG_DTT_ADM1021
|
||||
|
||||
#include <i2c.h>
|
||||
#include <dtt.h>
|
||||
|
||||
typedef
|
||||
struct {
|
||||
uint i2c_addr:7; /* 7bit i2c chip address */
|
||||
uint conv_rate:3; /* conversion rate */
|
||||
uint enable_alert:1; /* enable alert output pin */
|
||||
uint enable_local:1; /* enable internal temp sensor */
|
||||
uint max_local:8; /* internal temp maximum */
|
||||
uint min_local:8; /* internal temp minimum */
|
||||
uint enable_remote:1; /* enable remote temp sensor */
|
||||
uint max_remote:8; /* remote temp maximum */
|
||||
uint min_remote:8; /* remote temp minimum */
|
||||
}
|
||||
dtt_cfg_t;
|
||||
|
||||
dtt_cfg_t dttcfg[] = CFG_DTT_ADM1021;
|
||||
|
||||
int
|
||||
dtt_read (int sensor, int reg)
|
||||
{
|
||||
dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
|
||||
uchar data;
|
||||
|
||||
if (i2c_read(dcp->i2c_addr, reg, 1, &data, 1) != 0)
|
||||
return -1;
|
||||
|
||||
return (int)data;
|
||||
} /* dtt_read() */
|
||||
|
||||
int
|
||||
dtt_write (int sensor, int reg, int val)
|
||||
{
|
||||
dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
|
||||
uchar data;
|
||||
|
||||
data = (uchar)(val & 0xff);
|
||||
|
||||
if (i2c_write(dcp->i2c_addr, reg, 1, &data, 1) != 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
} /* dtt_write() */
|
||||
|
||||
static int
|
||||
_dtt_init (int sensor)
|
||||
{
|
||||
dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
|
||||
int reg, val;
|
||||
|
||||
if (((sensor & 1) == 0 ? dcp->enable_local : dcp->enable_remote) == 0)
|
||||
return 1; /* sensor is disabled (or rather ignored) */
|
||||
|
||||
/*
|
||||
* Setup High Limit register
|
||||
*/
|
||||
if ((sensor & 1) == 0) {
|
||||
reg = DTT_WRITE_LOC_HIGHLIM;
|
||||
val = dcp->max_local;
|
||||
}
|
||||
else {
|
||||
reg = DTT_WRITE_REM_HIGHLIM;
|
||||
val = dcp->max_remote;
|
||||
}
|
||||
if (dtt_write (sensor, reg, val) != 0)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Setup Low Limit register
|
||||
*/
|
||||
if ((sensor & 1) == 0) {
|
||||
reg = DTT_WRITE_LOC_LOWLIM;
|
||||
val = dcp->min_local;
|
||||
}
|
||||
else {
|
||||
reg = DTT_WRITE_REM_LOWLIM;
|
||||
val = dcp->min_remote;
|
||||
}
|
||||
if (dtt_write (sensor, reg, val) != 0)
|
||||
return 1;
|
||||
|
||||
/* shouldn't hurt if the rest gets done twice */
|
||||
|
||||
/*
|
||||
* Setup Conversion Rate register
|
||||
*/
|
||||
if (dtt_write (sensor, DTT_WRITE_CONVRATE, dcp->conv_rate) != 0)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Setup configuraton register
|
||||
*/
|
||||
val = 0; /* running */
|
||||
if (dcp->enable_alert == 0)
|
||||
val |= DTT_CONFIG_ALERT_MASKED; /* mask ALERT pin */
|
||||
if (dtt_write (sensor, DTT_WRITE_CONFIG, val) != 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
} /* _dtt_init() */
|
||||
|
||||
int
|
||||
dtt_init (void)
|
||||
{
|
||||
int i;
|
||||
unsigned char sensors[] = CONFIG_DTT_SENSORS;
|
||||
const char *const header = "DTT: ";
|
||||
|
||||
for (i = 0; i < sizeof(sensors); i++) {
|
||||
if (_dtt_init(sensors[i]) != 0)
|
||||
printf ("%s%d FAILED INIT\n", header, i+1);
|
||||
else
|
||||
printf ("%s%d is %i C\n", header, i+1,
|
||||
dtt_get_temp(sensors[i]));
|
||||
}
|
||||
|
||||
return (0);
|
||||
} /* dtt_init() */
|
||||
|
||||
int
|
||||
dtt_get_temp (int sensor)
|
||||
{
|
||||
signed char val;
|
||||
|
||||
if ((sensor & 1) == 0)
|
||||
val = dtt_read(sensor, DTT_READ_LOC_VALUE);
|
||||
else
|
||||
val = dtt_read(sensor, DTT_READ_REM_VALUE);
|
||||
|
||||
return (int) val;
|
||||
} /* dtt_get_temp() */
|
||||
|
||||
#endif /* CONFIG_DTT_ADM1021 */
|
||||
@@ -22,7 +22,7 @@
|
||||
#
|
||||
#
|
||||
|
||||
SUBDIRS := jffs2 fdos
|
||||
SUBDIRS := jffs2 fdos fat
|
||||
|
||||
.depend all:
|
||||
@for dir in $(SUBDIRS) ; do \
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user