Compare commits

..

21 Commits

Author SHA1 Message Date
wdenk
9a0e21a3a8 Had to move the RTC area for ATC board to upper addresses
(0xf5000000, to be specific). The reason is that the RTC first gets
accessed before MMU is initialized and, consequently, it needs to be
placed at physical addresses which are later mapped to the same
virtual addresses (like 0xf5000000 physical is mapped to 0xf5000000
virtual).
2003-06-22 10:30:54 +00:00
wdenk
592c5cabe7 Patch by Murray Jensen, 20 Jun 2003:
- hymod update
- cleanup (especially for gcc-3.x compilers)
2003-06-21 00:17:24 +00:00
wdenk
72755c7137 Patch by Tom Guilliams, 20 Jun 2003:
added CONFIG_750FX support for IBM 750FX processors
2003-06-20 23:10:58 +00:00
wdenk
0332990b85 * Patch by Devin Crumb, 02 Apr 2003:
Fix clock divider rounding problem in drivers/serial.c

* Patch by Ken Chou, 19 June 2003:
  Added support for A3000 SBC board (Artis Microsystems Inc.)
2003-06-20 22:36:30 +00:00
wdenk
0b97ab144f * 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).
2003-06-19 23:58:30 +00:00
wdenk
6dd652fa4d 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
2003-06-19 23:40:20 +00:00
wdenk
52f52c1494 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.
2003-06-19 23:04:19 +00:00
wdenk
48b42616e9 * Patches by David Mller, 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
2003-06-19 23:01:32 +00:00
wdenk
15ef8a5d17 Add support for DS12887 RTC; add RTC support for ATC board 2003-06-18 20:22:24 +00:00
wdenk
2abbe07547 * 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
2003-06-16 23:50:08 +00:00
wdenk
71f9511803 * 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
2003-06-15 22:40:42 +00:00
wdenk
487778b781 Patch by Robert Schwebel, April 02, 2003:
fix for SMSC91111 driver
2003-06-06 11:20:01 +00:00
stroese
8b601449e8 - Update new fpga file. 2003-06-06 09:44:40 +00:00
stroese
e58dc13283 - Fix compile bug (PPC4xx). 2003-06-06 09:43:42 +00:00
wdenk
a3ed3996cd * Patch by Vladimir Gurevich, 04 Jun 2003:
make ppc405 ethernet driver compatible with CONFIG_NET_MULTI option
2003-06-05 19:37:36 +00:00
wdenk
73a8b27c57 * Add support for RMU board
* Add support for TQM862L at 100/50 MHz

* Patch by Pantelis Antoniou, 02 Jun 2003:
  major reconstruction of networking code;
  add "ping" support (outgoing only!)
2003-06-05 19:27:42 +00:00
stroese
08eaea9c9f Patch from Stefan Roese. 2003-06-05 15:44:37 +00:00
stroese
53cf9435cc - CFG_RX_ETH_BUFFER added. 2003-06-05 15:39:44 +00:00
stroese
c602883592 - CFG_ETH_RX_BUFFER added. 2003-06-05 15:38:29 +00:00
stroese
3720878599 - Fix bug for initial stack in data cache as pointed out by Thomas Schaefer (tschaefer@giga-stream.de). Now inital stack in data cache can be used even if the chip select is in use. 2003-06-05 15:35:20 +00:00
wdenk
f3e0de60a6 * Patch by Denis Peter, 04 June 2003:
add support for the MIP405T board
2003-06-04 15:05:30 +00:00
213 changed files with 20068 additions and 4306 deletions

129
CHANGELOG
View File

@@ -2,6 +2,133 @@
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
* Patch by Stefan Roese, 05 Jun 2003:
- PPC4xx: Fix bug for initial stack in data cache as pointed out by
Thomas Schaefer (tschaefer@giga-stream.de). Now inital stack in
data cache can be used even if the chip select is in use.
- CFG_RX_ETH_BUFFER added to set the ethernet receive buffer count
(see README for further description).
- Changed config files of CONFIG_EEPRO100 boards to use the
CFG_RX_ETH_BUFFER define.
* Add support for RMU board
* Add support for TQM862L at 100/50 MHz
* Patch by Pantelis Antoniou, 02 Jun 2003:
major reconstruction of networking code;
add "ping" support (outgoing only!)
* Patch by Denis Peter, 04 June 2003:
add support for the MIP405T board
* Patches by Udi Finkelstein, 2 June 2003:
- Added support for custom keyboards, initialized by defining a
board-specific drv_keyboard_init as well as defining CONFIG_KEYBOARD .
@@ -365,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:

View File

@@ -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

View File

@@ -63,6 +63,9 @@ Wolfgang Denk <wd@denx.de>
IVMS8_128 MPC860
IVMS8_256 MPC860
LANTEC MPC850
LWMON MPC823
R360MPI MPC823
RMU MPC850
RRvision MPC823
SM850 MPC850
SPD823TS MPC823
@@ -72,6 +75,7 @@ Wolfgang Denk <wd@denx.de>
TQM855L MPC855
TQM860L MPC860
TQM860L_FEC MPC860
TTTech MPC823
c2mon MPC855
hermes MPC860
lwmon MPC823

22
MAKEALL
View File

@@ -32,11 +32,11 @@ LIST_8xx=" \
IVMS8 IVMS8_128 IVMS8_256 KUP4K \
LANTEC lwmon MBX MBX860T \
MHPC MVS1 NETVIA NX823 \
pcu_e R360MPI RBC823 RPXClassic \
RPXlite RRvision SM850 SPD823TS \
svm_sc8xx SXNI855T TOP860 TQM823L \
TQM823L_LCD TQM850L TQM855L TQM860L \
TTTech v37 \
pcu_e R360MPI RBC823 rmu \
RPXClassic RPXlite RRvision SM850 \
SPD823TS svm_sc8xx SXNI855T TOP860 \
TQM823L TQM823L_LCD TQM850L TQM855L \
TQM860L TTTech v37 \
"
#########################################################################
@@ -48,9 +48,9 @@ LIST_4xx=" \
CANBT CPCI405 CPCI4052 CPCI405AB \
CPCI440 CPCIISER4 CRAYL1 DASA_SIM \
DU405 EBONY ERIC MIP405 \
ML2 OCRTC ORSG PCI405 \
PIP405 PMC405 W7OLMC W7OLMG \
WALNUT405 \
MIP405T ML2 OCRTC ORSG \
PCI405 PIP405 PMC405 W7OLMC \
W7OLMG WALNUT405 \
"
#########################################################################
@@ -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 \
"
#########################################################################

View File

@@ -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
@@ -323,6 +323,9 @@ RPXClassic_config: unconfig
RPXlite_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8xx RPXlite
rmu_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8xx rmu
RRvision_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8xx RRvision
@@ -349,10 +352,10 @@ TOP860_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8xx top860 emk
# Play some tricks for configuration selection
# All boards can come with 50 MHz (default), 66MHz or 80MHz clock,
# All boards can come with 50 MHz (default), 66MHz, 80MHz or 100 MHz clock,
# but only 855 and 860 boards may come with FEC
# and 823 boards may have LCD support
xtract_8xx = $(subst _66MHz,,$(subst _80MHz,,$(subst _LCD,,$(subst _config,,$1))))
xtract_8xx = $(subst _66MHz,,$(subst _80MHz,,$(subst _100MHz,,$(subst _LCD,,$(subst _config,,$1)))))
FPS850L_config \
FPS860L_config \
@@ -373,7 +376,8 @@ TQM860L_66MHz_config \
TQM860L_80MHz_config \
TQM862L_config \
TQM862L_66MHz_config \
TQM862L_80MHz_config: unconfig
TQM862L_80MHz_config \
TQM862M_100MHz_config: unconfig
@ >include/config.h
@[ -z "$(findstring _66MHz,$@)" ] || \
{ echo "#define CONFIG_66MHz" >>include/config.h ; \
@@ -383,6 +387,10 @@ TQM862L_80MHz_config: unconfig
{ echo "#define CONFIG_80MHz" >>include/config.h ; \
echo "... with 80MHz system clock" ; \
}
@[ -z "$(findstring _100MHz,$@)" ] || \
{ echo "#define CONFIG_100MHz" >>include/config.h ; \
echo "... with 100MHz system clock" ; \
}
@[ -z "$(findstring _LCD,$@)" ] || \
{ echo "#define CONFIG_LCD" >>include/config.h ; \
echo "#define CONFIG_NEC_NL6648BC20" >>include/config.h ; \
@@ -449,6 +457,11 @@ ERIC_config:unconfig
MIP405_config:unconfig
@./mkconfig $(@:_config=) ppc ppc4xx mip405 mpl
MIP405T_config:unconfig
@echo "#define CONFIG_MIP405T" >include/config.h
@echo "Enable subset config for MIP405T"
@./mkconfig -a MIP405 ppc ppc4xx mip405 mpl
ML2_config:unconfig
@./mkconfig $(@:_config=) ppc ppc4xx ml2
@@ -477,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
@@ -724,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

47
README
View File

@@ -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
@@ -690,7 +694,7 @@ The following options need to be configured:
- NETWORK Support (PCI):
CONFIG_E1000
Support for Intel 8254x gigabit chips.
CONFIG_EEPRO100
Support for Intel 82557/82559/82559ER chips.
Optional CONFIG_EEPRO100_SROM_WRITE enables eeprom
@@ -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
@@ -1442,6 +1461,14 @@ Configuration Settings:
Define if the flash driver uses extra elements in the
common flash structure for storing flash geometry
- CFG_RX_ETH_BUFFER:
Defines the number of ethernet receive buffers. On some
ethernet controllers it is recommended to set this value
to 8 or even higher (EEPRO100 or 405 EMAC), since all
buffers can be full shortly after enabling the interface
on high ethernet traffic.
Defaults to 4 if not defined.
The following definitions that deal with the placement and management
of environment data (variable area); in general, we support the
following configurations:
@@ -1783,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
@@ -2624,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:
=============
@@ -2975,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
View 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
View 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
View 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
View 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
View 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
View 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 = .);
}

View File

@@ -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

View File

@@ -1,2 +1,2 @@
TEXT_BASE = 0x21fa0000
TEXT_BASE = 0x21f00000

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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 $@ $^

View File

@@ -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 */
/* ------------------------------------------------------------------------- */

View File

@@ -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
View 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");
}

View File

@@ -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);
}

View File

@@ -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));
}
/*-----------------------------------------------------------------------

View File

@@ -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)

View File

@@ -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)

View File

@@ -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
View 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
View 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);
}
}

View File

@@ -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
View 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
View 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
View 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
View 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
View 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
View 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 = .;
}

View File

@@ -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;

View File

@@ -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.
*

View File

@@ -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 */
@@ -59,6 +63,7 @@ int mpl_prg(unsigned long src,unsigned long size)
flash_info_t *info;
int i,rc;
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
char *copystr = (char *)src;
unsigned long *magic = (unsigned long *)src;
#endif
@@ -69,8 +74,25 @@ int mpl_prg(unsigned long src,unsigned long size)
printf("Bad Magic number\n");
return -1;
}
start = 0 - size;
/* some more checks before we delete the Flash... */
/* Checking the ISO_STRING prevents to program a
* wrong Firmware Image into the flash.
*/
i=4; /* skip Magic number */
while(1) {
if(strncmp(&copystr[i],"MEV-",4)==0)
break;
if(i++>=0x100) {
printf("Firmware Image for unknown Target\n");
return -1;
}
}
/* we have the ISO STRING, check */
if(strncmp(&copystr[i],CONFIG_ISO_STRING,sizeof(CONFIG_ISO_STRING)-1)!=0) {
printf("Wrong Firmware Image: %s\n",&copystr[i]);
return -1;
}
start = 0 - size;
for(i=info->sector_count-1;i>0;i--)
{
info->protect[i] = 0; /* unprotect this sector */

View File

@@ -108,17 +108,23 @@ static struct pci_pip405_config_entry piix4_isa_bridge_f0[] = {
/* PIIX4 IDE Controller Function 1 */
static struct pci_pip405_config_entry piix4_ide_cntrl_f1[] = {
{PCI_COMMAND, 0x0001, 2}, /* enable IO access */
#if !defined(CONFIG_MIP405T)
{PCI_CFG_PIIX4_IDETIM, 0x80008000, 4}, /* enable Both IDE channels */
#else
{PCI_CFG_PIIX4_IDETIM, 0x80000000, 4}, /* enable IDE channel0 */
#endif
{ } /* end of device table */
};
/* PIIX4 USB Controller Function 2 */
static struct pci_pip405_config_entry piix4_usb_cntrl_f2[] = {
#if !defined(CONFIG_MIP405T)
{PCI_INTERRUPT_LINE, 31, 1}, /* Int vector = 31 */
{PCI_BASE_ADDRESS_4, 0x0000E001, 4}, /* Set IO Address to 0xe000 to 0xe01F */
{PCI_LATENCY_TIMER, 0x80, 1}, /* Latency Timer 0x80 */
{0xC0, 0x2000, 2}, /* Legacy support */
{PCI_COMMAND, 0x0005, 2}, /* enable IO access and Master */
#endif
{ } /* end of device table */
};

View File

@@ -50,9 +50,13 @@
#include "mip405.h"
.globl ext_bus_cntlr_init
.globl ext_bus_cntlr_init
ext_bus_cntlr_init:
mflr r4 /* save link register */
mflr r4 /* save link register */
mfdcr r3,strap /* get strapping reg */
andi. r0, r3, PSR_ROM_LOC /* mask out irrelevant bits */
bnelr /* jump back if PCI boot */
bl ..getAddr
..getAddr:
mflr r3 /* get address of ..getAddr */
@@ -200,3 +204,45 @@ sdram_init:
blr
#if defined(CONFIG_BOOT_PCI)
.section .bootpg,"ax"
.globl _start_pci
/*******************************************
*/
_start_pci:
/* first handle errata #68 / PCI_18 */
iccci r0, r0 /* invalidate I-cache */
lis r31, 0
mticcr r31 /* ICCR = 0 (all uncachable) */
isync
mfccr0 r28 /* set CCR0[24] = 1 */
ori r28, r28, 0x0080
mtccr0 r28
/* setup PMM0MA (0xEF400004) and PMM0PCIHA (0xEF40000C) */
lis r28, 0xEF40
addi r28, r28, 0x0004
stw r31, 0x0C(r28) /* clear PMM0PCIHA */
lis r29, 0xFFF8 /* open 512 kByte */
addi r29, r29, 0x0001/* and enable this region */
stwbrx r29, r0, r28 /* write PMM0MA */
lis r28, 0xEEC0 /* address of PCIC0_CFGADDR */
addi r29, r28, 4 /* add 4 to r29 -> PCIC0_CFGDATA */
lis r31, 0x8000 /* set en bit bus 0 */
ori r31, r31, 0x304C/* device 6 func 0 reg 4C (XBCS register) */
stwbrx r31, r0, r28 /* write it */
lwbrx r31, r0, r29 /* load XBCS register */
oris r31, r31, 0x02C4/* clear BIOSCS WPE, set lower, extended and 1M extended BIOS enable */
stwbrx r31, r0, r29 /* write back XBCS register */
nop
nop
b _start /* normal start */
#endif

View File

@@ -73,7 +73,7 @@ extern block_dev_desc_t * scsi_get_dev(int dev);
extern block_dev_desc_t * ide_get_dev(int dev);
#undef SDRAM_DEBUG
#define ENABLE_ECC /* for ecc boards */
#define FALSE 0
#define TRUE 1
@@ -108,7 +108,27 @@ typedef struct {
unsigned char sz; /* log binary => Size = (4MByte<<sz) 5 = 128, 4 = 64, 3 = 32, 2 = 16, 1=8 */
unsigned char ecc; /* if true, ecc is enabled */
} sdram_t;
#if defined(CONFIG_MIP405T)
const sdram_t sdram_table[] = {
{ 0x01, /* MIP405T Rev A, 64MByte -1 Board */
3, /* Case Latenty = 3 */
3, /* trp 20ns / 7.5 ns datain[27] */
3, /* trcd 20ns /7.5 ns (datain[29]) */
6, /* tras 44ns /7.5 ns (datain[30]) */
4, /* tcpt 44 - 20ns = 24ns */
3, /* Address Mode = 3 (13x9x4) */
4, /* size value (64MByte) */
0}, /* ECC disabled */
{ 0xff, /* terminator */
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff }
};
#else
const sdram_t sdram_table[] = {
{ 0x0f, /* Rev A, 128MByte -1 Board */
3, /* Case Latenty = 3 */
@@ -155,7 +175,7 @@ const sdram_t sdram_table[] = {
0xff,
0xff }
};
#endif /*CONFIG_MIP405T */
void SDRAM_err (const char *s)
{
#ifndef SDRAM_DEBUG
@@ -222,17 +242,54 @@ int init_sdram (void)
tctp_clocks;
unsigned char cal_val;
unsigned char bc;
unsigned long pbcr, sdram_tim, sdram_bank;
unsigned long *p;
unsigned long sdram_tim, sdram_bank;
i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
/*i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);*/
(void) get_clocks ();
gd->baudrate = 9600;
serial_init ();
/* set up the pld */
mtdcr (ebccfga, pb7ap);
mtdcr (ebccfgd, PLD_AP);
mtdcr (ebccfga, pb7cr);
mtdcr (ebccfgd, PLD_CR);
/* THIS IS OBSOLETE */
/* set up the board rev reg*/
mtdcr (ebccfga, pb5ap);
mtdcr (ebccfgd, BOARD_AP);
mtdcr (ebccfga, pb5cr);
mtdcr (ebccfgd, BOARD_CR);
#ifdef SDRAM_DEBUG
/* get all informations from PLD */
serial_puts ("\nPLD Part 0x");
bc = in8 (PLD_PART_REG);
write_hex (bc);
serial_puts ("\nPLD Vers 0x");
bc = in8 (PLD_VERS_REG);
write_hex (bc);
serial_puts ("\nBoard Rev 0x");
bc = in8 (PLD_BOARD_CFG_REG);
write_hex (bc);
serial_puts ("\n");
#endif
/* check board */
bc = in8 (PLD_PART_REG);
#if defined(CONFIG_MIP405T)
if((bc & 0x80)==0)
SDRAM_err ("U-Boot configured for a MIP405T not for a MIP405!!!\n");
#else
if((bc & 0x80)==0x80)
SDRAM_err ("U-Boot configured for a MIP405 not for a MIP405T!!!\n");
#endif
#if !defined(CONFIG_MIP405T)
/* since the ECC initialisation needs some time,
* we show that we're alive
*/
serial_puts ("\nInitializing SDRAM, Please stand by");
/* set-up the chipselect machine */
mtdcr (ebccfga, pb0cr); /* get cs0 config reg */
pbcr = mfdcr (ebccfgd);
if ((pbcr & 0x00002000) == 0) {
tmp = mfdcr (ebccfgd);
if ((tmp & 0x00002000) == 0) {
/* MPS Boot, set up the flash */
mtdcr (ebccfga, pb1ap);
mtdcr (ebccfgd, FLASH_AP);
@@ -254,30 +311,8 @@ int init_sdram (void)
mtdcr (ebccfgd, UART1_AP);
mtdcr (ebccfga, pb3cr);
mtdcr (ebccfgd, UART1_CR);
/* set up the pld */
mtdcr (ebccfga, pb7ap);
mtdcr (ebccfgd, PLD_AP);
mtdcr (ebccfga, pb7cr);
mtdcr (ebccfgd, PLD_CR);
/* set up the board rev reg */
mtdcr (ebccfga, pb5ap);
mtdcr (ebccfgd, BOARD_AP);
mtdcr (ebccfga, pb5cr);
mtdcr (ebccfgd, BOARD_CR);
#ifdef SDRAM_DEBUG
out8 (PER_BOARD_ADDR, 0);
bc = in8 (PER_BOARD_ADDR);
serial_puts ("\nBoard Rev: ");
write_hex (bc);
serial_puts (" (PLD=");
bc = in8 (PLD_BOARD_CFG_REG);
write_hex (bc);
serial_puts (")\n");
#endif
bc = get_board_revcfg ();
bc = in8 (PLD_BOARD_CFG_REG);
#ifdef SDRAM_DEBUG
serial_puts ("\nstart SDRAM Setup\n");
serial_puts ("\nBoard Rev: ");
@@ -367,9 +402,10 @@ int init_sdram (void)
mtdcr (memcfga, mem_rtr);
mtdcr (memcfgd, tmp);
/* enable ECC if used */
#if 1
#if defined(ENABLE_ECC) && !defined(CONFIG_BOOT_PCI)
if (sdram_table[i].ecc) {
/* disable checking for all banks */
unsigned long *p;
#ifdef SDRAM_DEBUG
serial_puts ("disable ECC.. ");
#endif
@@ -398,8 +434,6 @@ int init_sdram (void)
*p++ = 0L;
if (!((unsigned long) p % 0x00800000)) /* every 8MByte */
serial_puts (".");
}
/* enable bank 0 */
serial_puts (".");
@@ -501,47 +535,69 @@ void ide_set_reset (int idereset)
/* ------------------------------------------------------------------------- */
/*
* Check Board Identity:
*/
int checkboard (void)
void get_pcbrev_var(unsigned char *pcbrev, unsigned char *var)
{
unsigned char s[50];
unsigned char bc, var, rc;
#if !defined(CONFIG_MIP405T)
unsigned char bc,rc,tmp;
int i;
backup_t *b = (backup_t *) s;
puts ("Board: ");
bc = get_board_revcfg ();
var = ~bc;
var &= 0xf;
bc = in8 (PLD_BOARD_CFG_REG);
tmp = ~bc;
tmp &= 0xf;
rc = 0;
for (i = 0; i < 4; i++) {
rc <<= 1;
rc += (var & 0x1);
var >>= 1;
rc += (tmp & 0x1);
tmp >>= 1;
}
rc++;
if((((bc>>4) & 0xf)==0x1) /* Rev B PCB with */
&& (rc==0x1)) /* Population Option 1 is a -3 */
rc=3;
*pcbrev=(bc >> 4) & 0xf;
*var=rc;
#else
unsigned char bc;
bc = in8 (PLD_BOARD_CFG_REG);
*pcbrev=(bc >> 4) & 0xf;
*var=bc & 0xf ;
#endif
}
/*
* Check Board Identity:
*/
/* serial String: "MIP405_1000" OR "MIP405T_1000" */
#if !defined(CONFIG_MIP405T)
#define BOARD_NAME "MIP405"
#else
#define BOARD_NAME "MIP405T"
#endif
int checkboard (void)
{
unsigned char s[50];
unsigned char bc, var;
int i;
backup_t *b = (backup_t *) s;
puts ("Board: ");
get_pcbrev_var(&bc,&var);
i = getenv_r ("serial#", s, 32);
if ((i == 0) || strncmp (s, "MIP405", 6)) {
if ((i == 0) || strncmp (s, BOARD_NAME,sizeof(BOARD_NAME))) {
get_backup_values (b);
if (strncmp (b->signature, "MPL\0", 4) != 0) {
puts ("### No HW ID - assuming MIP405");
printf ("-%d Rev %c", rc, 'A' + ((bc >> 4) & 0xf));
puts ("### No HW ID - assuming " BOARD_NAME);
printf ("-%d Rev %c", var, 'A' + bc);
} else {
b->serial_name[6] = 0;
printf ("%s-%d Rev %c SN: %s", b->serial_name, rc,
'A' + ((bc >> 4) & 0xf), &b->serial_name[7]);
b->serial_name[sizeof(BOARD_NAME)-1] = 0;
printf ("%s-%d Rev %c SN: %s", b->serial_name, var,
'A' + bc, &b->serial_name[sizeof(BOARD_NAME)]);
}
} else {
s[6] = 0;
printf ("%s-%d Rev %c SN: %s", s, rc, 'A' + ((bc >> 4) & 0xf),
&s[7]);
s[sizeof(BOARD_NAME)-1] = 0;
printf ("%s-%d Rev %c SN: %s", s, var,'A' + bc,
&s[sizeof(BOARD_NAME)]);
}
bc = in8 (PLD_EXT_CONF_REG);
printf (" Boot Config: 0x%x\n", bc);
@@ -613,30 +669,23 @@ static int test_dram (unsigned long ramsize)
int misc_init_r (void)
{
/* if MIP405 has booted from PCI, reset CCR0[24] as described in errata PCI_18 */
if (mfdcr(strap) & PSR_ROM_LOC)
mtspr(ccr0, (mfspr(ccr0) & ~0x80));
return (0);
}
void print_mip405_rev (void)
{
unsigned char part, vers, cfg, rev;
unsigned char part, vers, pcbrev, var;
cfg = get_board_revcfg ();
vers = cfg;
vers &= 0xf;
rev = (((vers & 0x1) ? 0x8 : 0) |
((vers & 0x2) ? 0x4 : 0) |
((vers & 0x4) ? 0x2 : 0) |
((vers & 0x8) ? 0x1 : 0));
vers=16-rev;
rev=vers;
if((rev==1) && ((cfg >> 4)==1)) /* Rev B PCB and -1 is a -3 */
rev=3;
get_pcbrev_var(&pcbrev,&var);
part = in8 (PLD_PART_REG);
vers = in8 (PLD_VERS_REG);
printf ("Rev: MIP405-%d Rev %c PLD%d Vers %d\n",
rev, ((cfg >> 4) & 0xf) + 'A', part, vers);
printf ("Rev: " BOARD_NAME "-%d Rev %c PLD %d Vers %d\n",
var, pcbrev + 'A', part & 0x7F, vers);
}
extern void mem_test_reloc(void);
@@ -683,24 +732,32 @@ void print_mip405_info (void)
com_mode = in8 (PLD_COM_MODE_REG);
ext = in8 (PLD_EXT_CONF_REG);
printf ("PLD Part %d version %d\n", part, vers);
printf ("PLD Part %d version %d\n", part & 0x7F, vers);
printf ("Board Revision %c\n", ((cfg >> 4) & 0xf) + 'A');
printf ("Population Options %d %d %d %d\n", (cfg) & 0x1,
(cfg >> 1) & 0x1, (cfg >> 2) & 0x1, (cfg >> 3) & 0x1);
printf ("User LED %s\n", (com_mode & 0x4) ? "on" : "off");
printf ("UART Clocks %d\n", (com_mode >> 4) & 0x3);
printf ("Test ist %x\n", com_mode);
#if !defined(CONFIG_MIP405T)
printf ("User Config Switch %d %d %d %d %d %d %d %d\n",
(ext) & 0x1, (ext >> 1) & 0x1, (ext >> 2) & 0x1,
(ext >> 3) & 0x1, (ext >> 4) & 0x1, (ext >> 5) & 0x1,
(ext >> 6) & 0x1, (ext >> 7) & 0x1);
printf ("SER1 uses handshakes %s\n",
(ext & 0x80) ? "DTR/DSR" : "RTS/CTS");
#else
printf ("User Config Switch %d %d %d %d %d %d %d %d %d\n",
(ext) & 0x1, (ext >> 1) & 0x1, (ext >> 2) & 0x1,
(ext >> 3) & 0x1, (ext >> 4) & 0x1, (ext >> 5) & 0x1,
(ext >> 6) & 0x1,(ext >> 7) & 0x1,(ext >> 8) & 0x1);
#endif
printf ("IDE Reset %s\n", (ext & 0x01) ? "asserted" : "not asserted");
printf ("IRQs:\n");
printf (" PIIX INTR: %s\n", (irq_reg & 0x80) ? "inactive" : "active");
#if !defined(CONFIG_MIP405T)
printf (" UART0 IRQ: %s\n", (irq_reg & 0x40) ? "inactive" : "active");
printf (" UART1 IRQ: %s\n", (irq_reg & 0x20) ? "inactive" : "active");
#endif
printf (" PIIX SMI: %s\n", (irq_reg & 0x10) ? "inactive" : "active");
printf (" PIIX INIT: %s\n", (irq_reg & 0x8) ? "inactive" : "active");
printf (" PIIX NMI: %s\n", (irq_reg & 0x4) ? "inactive" : "active");

View File

@@ -31,6 +31,10 @@ SECTIONS
{
*(.resetvec)
} = 0xffff
.bootpg 0xFFFFF000 :
{
board/mpl/mip405/init.o (.bootpg)
} = 0xffff
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;

View File

@@ -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

View File

@@ -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 */

View File

@@ -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();
}

View File

@@ -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)

40
board/rmu/Makefile Normal file
View File

@@ -0,0 +1,40 @@
#
# (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 = $(BOARD).o flash.o
$(LIB): .depend $(OBJS)
$(AR) crv $@ $^
#########################################################################
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
sinclude .depend
#########################################################################

28
board/rmu/config.mk Normal file
View File

@@ -0,0 +1,28 @@
#
# (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
#
#
# RMU boards
#
TEXT_BASE = 0xfff00000

515
board/rmu/flash.c Normal file
View File

@@ -0,0 +1,515 @@
/*
* (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 <mpc8xx.h>
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*-----------------------------------------------------------------------
* Functions
*/
static ulong flash_get_size (vu_long *addr, flash_info_t *info);
static int write_word (flash_info_t *info, ulong dest, ulong data);
static void flash_get_offsets (ulong base, flash_info_t *info);
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
unsigned long size_b0 ;
int i;
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
}
/* Static FLASH Bank configuration here - FIXME XXX */
size_b0 = flash_get_size((vu_long *)FLASH_BASE_PRELIM, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
size_b0, size_b0<<20);
}
/* Remap FLASH according to real size */
memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & 0xFFFF8000);
memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
/* Re-do sizing to get full correct info */
size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
/* monitor protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+monitor_flash_len-1,
&flash_info[0]);
#endif
#ifdef CFG_ENV_IS_IN_FLASH
/* ENV protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR+CFG_ENV_SIZE-1,
&flash_info[0]);
#endif
flash_info[0].size = size_b0;
return (size_b0);
}
/*-----------------------------------------------------------------------
*/
static void flash_get_offsets (ulong base, flash_info_t *info)
{
int i;
/* set up sector start address table */
if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00010000;
info->start[2] = base + 0x00018000;
info->start[3] = base + 0x00020000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + ((i-3) * 0x00040000) ;
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00010000;
info->start[i--] = base + info->size - 0x00018000;
info->start[i--] = base + info->size - 0x00020000;
for (; i >= 0; i--) {
info->start[i] = base + i * 0x00040000;
}
}
}
/*-----------------------------------------------------------------------
*/
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;
default: printf ("Unknown Vendor "); break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
break;
case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
break;
case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
break;
case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
break;
case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
break;
case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
break;
case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
break;
case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
break;
default: printf ("Unknown Chip Type\n");
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");
return;
}
/*-----------------------------------------------------------------------
*/
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
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[0xAAA] = 0xAAAAAAAA ;
addr[0x555] = 0x55555555 ;
addr[0xAAA] = 0x90909090 ;
value = addr[0] ;
switch (value & 0x00FF00FF) {
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[2] ; /* device ID */
switch (value & 0x00FF00FF) {
case (AMD_ID_LV400T & 0x00FF00FF):
info->flash_id += FLASH_AM400T;
info->sector_count = 11;
info->size = 0x00100000;
break; /* => 1 MB */
case (AMD_ID_LV400B & 0x00FF00FF):
info->flash_id += FLASH_AM400B;
info->sector_count = 11;
info->size = 0x00100000;
break; /* => 1 MB */
case (AMD_ID_LV800T & 0x00FF00FF):
info->flash_id += FLASH_AM800T;
info->sector_count = 19;
info->size = 0x00200000;
break; /* => 2 MB */
case (AMD_ID_LV800B & 0x00FF00FF):
info->flash_id += FLASH_AM800B;
info->sector_count = 19;
info->size = 0x00400000; /*%%% Size doubled by yooth */
break; /* => 4 MB */
case (AMD_ID_LV160T & 0x00FF00FF):
info->flash_id += FLASH_AM160T;
info->sector_count = 35;
info->size = 0x00400000;
break; /* => 4 MB */
case (AMD_ID_LV160B & 0x00FF00FF):
info->flash_id += FLASH_AM160B;
info->sector_count = 35;
info->size = 0x00800000;
break; /* => 8 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 = 0x01000000;
break; /* => 16 MB */
#endif
default:
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
}
/*%%% sector start address modified */
/* set up sector start address table */
if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00010000;
info->start[2] = base + 0x00018000;
info->start[3] = base + 0x00020000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + ((i-3) * 0x00040000) ;
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00010000;
info->start[i--] = base + info->size - 0x00018000;
info->start[i--] = base + info->size - 0x00020000;
for (; i >= 0; i--) {
info->start[i] = base + i * 0x00040000;
}
}
/* 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[4] & 1 ;
}
/*
* Prevent writes to uninitialized FLASH.
*/
if (info->flash_id != FLASH_UNKNOWN) {
addr = (volatile unsigned long *)info->start[0];
*addr = 0xF0F0F0F0; /* reset bank */
}
return (info->size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
vu_long *addr = (vu_long*)(info->start[0]);
int flag, prot, sect, l_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_UNKNOWN) ||
(info->flash_id > FLASH_AMD_COMP)) {
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");
}
l_sect = -1;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[0xAAA] = 0xAAAAAAAA;
addr[0x555] = 0x55555555;
addr[0xAAA] = 0x80808080;
addr[0xAAA] = 0xAAAAAAAA;
addr[0x555] = 0x55555555;
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
addr = (vu_long *)(info->start[sect]) ;
addr[0] = 0x30303030 ;
l_sect = sect;
}
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
/*
* We wait for the last triggered sector
*/
if (l_sect < 0)
goto DONE;
start = get_timer (0);
last = start;
addr = (vu_long *)(info->start[l_sect]);
while ((addr[0] & 0x80808080) != 0x80808080) {
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
return 1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc ('.');
last = now;
}
}
DONE:
/* reset to read mode */
addr = (vu_long *)info->start[0];
addr[0] = 0xF0F0F0F0; /* reset bank */
printf (" done\n");
return 0;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong cp, wp, data;
int i, l, rc;
wp = (addr & ~3); /* 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);
}
for (; i<4 && cnt>0; ++i) {
data = (data << 8) | *src++;
--cnt;
++cp;
}
for (; cnt==0 && i<4; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
wp += 4;
}
/*
* handle word aligned part
*/
while (cnt >= 4) {
data = 0;
for (i=0; i<4; ++i) {
data = (data << 8) | *src++;
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
wp += 4;
cnt -= 4;
}
if (cnt == 0) {
return (0);
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
for (; i<4; ++i, ++cp) {
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)
{
vu_long *addr = (vu_long *)(info->start[0]);
ulong start;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((*((vu_long *)dest) & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[0xAAA] = 0xAAAAAAAA;
addr[0x555] = 0x55555555;
addr[0xAAA] = 0xA0A0A0A0;
*((vu_long *)dest) = data;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
while ((*((vu_long *)dest) & 0x80808080) != (data & 0x80808080)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
return (1);
}
}
return (0);
}
/*-----------------------------------------------------------------------
*/

184
board/rmu/rmu.c Normal file
View File

@@ -0,0 +1,184 @@
/*
* (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 <mpc8xx.h>
/* ------------------------------------------------------------------------- */
static long int dram_size (long int, long int *, long int);
/* ------------------------------------------------------------------------- */
#define _NOT_USED_ 0xFFFFCC25
const uint sdram_table[] =
{
/*
* Single Read. (Offset 00h in UPMA RAM)
*/
0x0F03CC04, 0x00ACCC24, 0x1FF74C20, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/*
* Burst Read. (Offset 08h in UPMA RAM)
*/
0x0F03CC04, 0x00ACCC24, 0x00FFCC20, 0x00FFCC20,
0x01FFCC20, 0x1FF74C20, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/*
* Single Write. (Offset 18h in UPMA RAM)
*/
0x0F03CC02, 0x00AC0C24, 0x1FF74C25, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/*
* Burst Write. (Offset 20h in UPMA RAM)
*/
0x0F03CC00, 0x00AC0C20, 0x00FFFC20, 0x00FFFC22,
0x01FFFC24, 0x1FF74C25, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/*
* Refresh. (Offset 30h in UPMA RAM)
* (Initialization code at 0x36)
*/
0x0FF0CC24, 0xFFFFCC24, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, 0xEFFB8C34, 0x0FF74C34,
0x0FFACCB4, 0x0FF5CC34, 0x0FFCC34, 0x0FFFCCB4,
/*
* Exception. (Offset 3Ch in UPMA RAM)
*/
0x0FEA8C34, 0x1FB54C34, 0xFFFFCC34, _NOT_USED_
};
/* ------------------------------------------------------------------------- */
/*
* Check Board Identity:
*/
int checkboard (void)
{
puts ("Board: RMU\n") ;
return (0) ;
}
/* ------------------------------------------------------------------------- */
long int initdram (int board_type)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
long int size10 ;
upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
/* Refresh clock prescalar */
memctl->memc_mptpr = CFG_MPTPR ;
memctl->memc_mar = 0x00000088;
/* Map controller banks 1 to the SDRAM bank */
memctl->memc_or1 = CFG_OR1_PRELIM;
memctl->memc_br1 = CFG_BR1_PRELIM;
memctl->memc_mamr = CFG_MAMR_10COL & (~(MAMR_PTAE)); /* no refresh yet */
udelay(200);
/* perform SDRAM initializsation sequence */
memctl->memc_mcr = 0x80002136 ; /* SDRAM bank 0 */
udelay(1);
memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
udelay (1000);
/* Check Bank 0 Memory Size
* try 10 column mode
*/
size10 = dram_size (CFG_MAMR_10COL, (ulong *)SDRAM_BASE_PRELIM, SDRAM_MAX_SIZE) ;
return (size10);
}
/* ------------------------------------------------------------------------- */
/*
* Check memory range for valid RAM. A simple memory test determines
* the actually available RAM size between addresses `base' and
* `base + maxsize'. Some (not all) hardware errors are detected:
* - short between address lines
* - short between data lines
*/
static long int dram_size (long int mamr_value, long int *base, long int maxsize)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
volatile long int *addr;
ulong cnt, val;
ulong save[32]; /* to make test non-destructive */
unsigned char i = 0;
memctl->memc_mamr = mamr_value;
for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) {
addr = base + cnt; /* pointer arith! */
save[i++] = *addr;
*addr = ~cnt;
}
/* write 0 to base address */
addr = base;
save[i] = *addr;
*addr = 0;
/* check at base address */
if ((val = *addr) != 0) {
*addr = save[i];
return (0);
}
for (cnt = 1; cnt <= maxsize/sizeof(long); cnt <<= 1) {
addr = base + cnt; /* pointer arith! */
val = *addr;
*addr = save[--i];
if (val != (~cnt)) {
return (cnt * sizeof(long));
}
}
return (maxsize);
}

134
board/rmu/u-boot.lds Normal file
View File

@@ -0,0 +1,134 @@
/*
* (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_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 :
{
/* WARNING - the following is hand-optimized to fit within */
/* the sector layout of our flash chips! XXX FIXME XXX */
cpu/mpc8xx/start.o (.text)
common/dlmalloc.o (.text)
lib_ppc/ppcstring.o (.text)
lib_generic/vsprintf.o (.text)
lib_generic/crc32.o (.text)
lib_generic/zlib.o (.text)
/* XXX ?
. = env_offset;
*/
common/environment.o(.text)
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x00FF) & 0xFFFFFF00;
_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(256);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(256);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

131
board/rmu/u-boot.lds.debug Normal file
View File

@@ -0,0 +1,131 @@
/*
* (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_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 :
{
/* WARNING - the following is hand-optimized to fit within */
/* the sector layout of our flash chips! XXX FIXME XXX */
cpu/mpc8xx/start.o (.text)
common/dlmalloc.o (.text)
lib_generic/vsprintf.o (.text)
lib_generic/crc32.o (.text)
. = env_offset;
common/environment.o(.text)
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.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 = .);
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -21,8 +21,11 @@
* MA 02111-1307 USA
*/
/* #define DEBUG */
#include <common.h>
#include <mpc8xx.h>
#include <environment.h>
#ifndef CFG_ENV_ADDR
#define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
@@ -53,8 +56,12 @@ unsigned long flash_init (void)
/* Static FLASH Bank configuration here - FIXME XXX */
debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_PRELIM);
size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
debug ("## Get flash bank 2 size @ 0x%08x\n",FLASH_BASE1_PRELIM);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
size_b0, size_b0<<20);
@@ -62,6 +69,8 @@ unsigned long flash_init (void)
size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
debug ("## Prelim. Flash bank sizes: %08lx + 0x%08lx\n",size_b0,size_b1);
if (size_b1 > size_b0) {
printf ("## ERROR: "
"Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
@@ -77,26 +86,59 @@ unsigned long flash_init (void)
return (0);
}
debug ("## Before remap: "
"BR0: 0x%08x OR0: 0x%08x "
"BR1: 0x%08x OR1: 0x%08x\n",
memctl->memc_br0, memctl->memc_or0,
memctl->memc_br1, memctl->memc_or1);
/* Remap FLASH according to real size */
memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & OR_AM_MSK);
memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
debug ("## BR0: 0x%08x OR0: 0x%08x\n",
memctl->memc_br0, memctl->memc_or0);
/* Re-do sizing to get full correct info */
size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
#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
@@ -105,6 +147,9 @@ unsigned long flash_init (void)
memctl->memc_br1 = ((CFG_FLASH_BASE + size_b0) & BR_BA_MSK) |
BR_MS_GPCM | BR_V;
debug ("## BR1: 0x%08x OR1: 0x%08x\n",
memctl->memc_br1, memctl->memc_or1);
/* Re-do sizing to get full correct info */
size_b1 = flash_get_size((vu_long *)(CFG_FLASH_BASE + size_b0),
&flash_info[1]);
@@ -129,8 +174,14 @@ unsigned long flash_init (void)
flash_info[1].flash_id = FLASH_UNKNOWN;
flash_info[1].sector_count = -1;
flash_info[1].size = 0;
debug ("## DISABLE BR1: 0x%08x OR1: 0x%08x\n",
memctl->memc_br1, memctl->memc_or1);
}
debug ("## Final Flash bank sizes: %08lx + 0x%08lx\n",size_b0,size_b1);
flash_info[0].size = size_b0;
flash_info[1].size = size_b1;
@@ -155,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");
@@ -171,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;
}
@@ -215,6 +271,8 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
value = addr[0];
debug ("Manuf. ID @ 0x%08lx: 0x%08lx\n", (ulong)addr, value);
switch (value) {
case AMD_MANUFACT:
info->flash_id = FLASH_MAN_AMD;
@@ -231,7 +289,28 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
value = addr[1]; /* device ID */
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;
@@ -267,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;
@@ -278,6 +358,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
info->sector_count = 71;
info->size = 0x00800000;
break; /* => 8 MB */
#endif /* TQM8xxM */
default:
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
@@ -285,6 +366,19 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
/* 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:
@@ -333,6 +427,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
: 2 * ( 8 << 10);
}
break;
#endif /* TQM8xxM */
default:
return (0);
break;
@@ -368,6 +463,8 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
int flag, prot, sect, l_sect;
ulong start, now, last;
debug ("flash_erase: first: %d last: %d\n", s_first, s_last);
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");

View File

@@ -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)

View File

@@ -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)

View File

@@ -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;
}
/************************************************************************/

View File

@@ -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 \

View File

@@ -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);

View File

@@ -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)) {

View File

@@ -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
View 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 */

View File

@@ -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);

View File

@@ -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)

View File

@@ -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
View 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 */

View File

@@ -95,6 +95,10 @@ static void netboot_update_env(void)
ip_to_string (NetOurDNSIP, tmp);
setenv("dnsip", tmp);
}
if (NetOurNISDomain[0])
setenv("domain", NetOurNISDomain);
}
static int
netboot_common (int proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
@@ -165,4 +169,27 @@ netboot_common (int proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
return rcode;
}
#if (CONFIG_COMMANDS & CFG_CMD_PING)
int do_ping (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
if (argc < 2)
return -1;
NetPingIP = string_to_ip(argv[1]);
if (NetPingIP == 0) {
printf ("Usage:\n%s\n", cmdtp->usage);
return -1;
}
if (NetLoop(PING) < 0) {
printf("ping failed; host %s is not alive\n", argv[1]);
return 1;
}
printf("host %s is alive\n", argv[1]);
return 0;
}
#endif /* CFG_CMD_PING */
#endif /* CFG_CMD_NET */

View File

@@ -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
@@ -316,6 +320,7 @@ cmd_tbl_t cmd_tbl[] = {
CMD_TBL_NANDBOOT
CMD_TBL_NEXT
CMD_TBL_NM
CMD_TBL_PING
CMD_TBL_PORTIO_OUT
CMD_TBL_PCI
CMD_TBL_PRINTENV

View File

@@ -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;

View File

@@ -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);

View File

@@ -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) \

View File

@@ -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)

View File

@@ -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;

View File

@@ -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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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 */

View File

@@ -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
View 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

View 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 */

View File

@@ -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)

View File

@@ -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 */

View File

@@ -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)

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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 */
}

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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)

View File

@@ -173,17 +173,16 @@ static bd_t *bis_save = NULL; /* for eth_init upon mal error */
static int is_receiving = 0; /* sync with eth interrupt */
static int print_speed = 1; /* print speed message upon start */
static void enet_rcv (unsigned long malisr);
/*-----------------------------------------------------------------------------+
* Prototypes and externals.
*-----------------------------------------------------------------------------*/
void mal_err (unsigned long isr, unsigned long uic, unsigned long mal_def,
static void enet_rcv (unsigned long malisr);
static int enetInt(void);
static void mal_err (unsigned long isr, unsigned long uic, unsigned long mal_def,
unsigned long mal_errr);
void emac_err (unsigned long isr);
static void emac_err (unsigned long isr);
void eth_halt (void)
static void ppc_4xx_eth_halt (struct eth_device *dev)
{
mtdcr (malier, 0x00000000); /* disable mal interrupts */
out32 (EMAC_IER, 0x00000000); /* disable emac interrupts */
@@ -202,7 +201,7 @@ void eth_halt (void)
}
int eth_init (bd_t * bis)
static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
{
int i;
unsigned long reg;
@@ -478,11 +477,11 @@ int eth_init (bd_t * bis)
bis_save = bis;
first_init = 1;
return (0);
return (1);
}
int eth_send (volatile void *ptr, int len)
static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr, int len)
{
struct enet_frame *ef_ptr;
ulong time_start, time_now;
@@ -539,7 +538,7 @@ int eth_send (volatile void *ptr, int len)
return (-1);
}
} else {
return (0);
return (len);
}
}
}
@@ -696,7 +695,7 @@ int enetInt ()
/*-----------------------------------------------------------------------------+
* MAL Error Routine
*-----------------------------------------------------------------------------*/
void mal_err (unsigned long isr, unsigned long uic, unsigned long maldef,
static void mal_err (unsigned long isr, unsigned long uic, unsigned long maldef,
unsigned long mal_errr)
{
mtdcr (malesr, isr); /* clear interrupt */
@@ -724,7 +723,7 @@ void mal_err (unsigned long isr, unsigned long uic, unsigned long maldef,
/*-----------------------------------------------------------------------------+
* EMAC Error Routine
*-----------------------------------------------------------------------------*/
void emac_err (unsigned long isr)
static void emac_err (unsigned long isr)
{
printf ("EMAC error occured.... ISR = %lx\n", isr);
out32 (EMAC_ISR, isr);
@@ -816,7 +815,7 @@ static void enet_rcv (unsigned long malisr)
}
int eth_rx (void)
static int ppc_4xx_eth_rx (struct eth_device *dev)
{
int length;
int user_index;
@@ -864,4 +863,46 @@ int eth_rx (void)
return length;
}
#if defined(CONFIG_NET_MULTI)
int ppc_4xx_eth_initialize(bd_t *bis)
{
struct eth_device *dev;
int eth_num = 0;
dev = malloc (sizeof *dev);
if (dev == NULL) {
printf(__FUNCTION__ ": Cannot allocate eth_device\n");
return (-1);
}
sprintf(dev->name, "ppc_4xx_eth%d", eth_num);
dev->priv = (void *) eth_num;
dev->init = ppc_4xx_eth_init;
dev->halt = ppc_4xx_eth_halt;
dev->send = ppc_4xx_eth_send;
dev->recv = ppc_4xx_eth_rx;
eth_register (dev);
}
#else /* !defined(CONFIG_NET_MULTI) */
void eth_halt (void)
{
ppc_4xx_eth_halt(NULL);
}
int eth_init (bd_t *bis)
{
return (ppc_4xx_eth_init(NULL, bis));
}
int eth_send(volatile void *packet, int length)
{
return (ppc_4xx_eth_send(NULL, packet, length));
}
int eth_rx(void)
{
return (ppc_4xx_eth_rx(NULL));
}
#endif /* !defined(CONFIG_NET_MULTI) */
#endif /* CONFIG_405GP */

View File

@@ -177,7 +177,7 @@ void pci_405gp_init(struct pci_controller *hose)
* PLB address 0x80000000-0xBFFFFFFF ==> PCI address 0x80000000-0xBFFFFFFF
* Use byte reversed out routines to handle endianess.
*--------------------------------------------------------------------------*/
out32r(PMM0MA, pmmma[0]); /* ensure disabled b4 setting PMM0LA */
out32r(PMM0MA, (pmmma[0]&~0x1)); /* disable, configure PMMxLA, PMMxPCILA first */
out32r(PMM0LA, pmmla[0]);
out32r(PMM0PCILA, pmmpcila[0]);
out32r(PMM0PCIHA, pmmpciha[0]);
@@ -186,7 +186,7 @@ void pci_405gp_init(struct pci_controller *hose)
/*--------------------------------------------------------------------------+
* PMM1 is not used. Initialize them to zero.
*--------------------------------------------------------------------------*/
out32r(PMM1MA, pmmma[1]); /* ensure disabled b4 setting PMM2LA */
out32r(PMM1MA, (pmmma[1]&~0x1));
out32r(PMM1LA, pmmla[1]);
out32r(PMM1PCILA, pmmpcila[1]);
out32r(PMM1PCIHA, pmmpciha[1]);
@@ -195,7 +195,7 @@ void pci_405gp_init(struct pci_controller *hose)
/*--------------------------------------------------------------------------+
* PMM2 is not used. Initialize them to zero.
*--------------------------------------------------------------------------*/
out32r(PMM2MA, pmmma[2]); /* ensure disabled b4 setting PMM2LA */
out32r(PMM2MA, (pmmma[2]&~0x1));
out32r(PMM2LA, pmmla[2]);
out32r(PMM2PCILA, pmmpcila[2]);
out32r(PMM2PCIHA, pmmpciha[2]);

View File

@@ -30,6 +30,73 @@
#define mtebc(reg, data) mtdcr(ebccfga,reg);mtdcr(ebccfgd,data)
#ifdef CFG_INIT_DCACHE_CS
# if (CFG_INIT_DCACHE_CS == 0)
# define PBxAP pb0ap
# define PBxCR pb0cr
# if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
# define PBxAP_VAL CFG_EBC_PB0AP
# define PBxCR_VAL CFG_EBC_PB0CR
# endif
# endif
# if (CFG_INIT_DCACHE_CS == 1)
# define PBxAP pb1ap
# define PBxCR pb1cr
# if (defined(CFG_EBC_PB1AP) && defined(CFG_EBC_PB1CR))
# define PBxAP_VAL CFG_EBC_PB1AP
# define PBxCR_VAL CFG_EBC_PB1CR
# endif
# endif
# if (CFG_INIT_DCACHE_CS == 2)
# define PBxAP pb2ap
# define PBxCR pb2cr
# if (defined(CFG_EBC_PB2AP) && defined(CFG_EBC_PB2CR))
# define PBxAP_VAL CFG_EBC_PB2AP
# define PBxCR_VAL CFG_EBC_PB2CR
# endif
# endif
# if (CFG_INIT_DCACHE_CS == 3)
# define PBxAP pb3ap
# define PBxCR pb3cr
# if (defined(CFG_EBC_PB3AP) && defined(CFG_EBC_PB3CR))
# define PBxAP_VAL CFG_EBC_PB3AP
# define PBxCR_VAL CFG_EBC_PB3CR
# endif
# endif
# if (CFG_INIT_DCACHE_CS == 4)
# define PBxAP pb4ap
# define PBxCR pb4cr
# if (defined(CFG_EBC_PB4AP) && defined(CFG_EBC_PB4CR))
# define PBxAP_VAL CFG_EBC_PB4AP
# define PBxCR_VAL CFG_EBC_PB4CR
# endif
# endif
# if (CFG_INIT_DCACHE_CS == 5)
# define PBxAP pb5ap
# define PBxCR pb5cr
# if (defined(CFG_EBC_PB5AP) && defined(CFG_EBC_PB5CR))
# define PBxAP_VAL CFG_EBC_PB5AP
# define PBxCR_VAL CFG_EBC_PB5CR
# endif
# endif
# if (CFG_INIT_DCACHE_CS == 6)
# define PBxAP pb6ap
# define PBxCR pb6cr
# if (defined(CFG_EBC_PB6AP) && defined(CFG_EBC_PB6CR))
# define PBxAP_VAL CFG_EBC_PB6AP
# define PBxCR_VAL CFG_EBC_PB6CR
# endif
# endif
# if (CFG_INIT_DCACHE_CS == 7)
# define PBxAP pb7ap
# define PBxCR pb7cr
# if (defined(CFG_EBC_PB7AP) && defined(CFG_EBC_PB7CR))
# define PBxAP_VAL CFG_EBC_PB7AP
# define PBxCR_VAL CFG_EBC_PB7CR
# endif
# endif
#endif /* CFG_INIT_DCACHE_CS */
/*
* Breath some life into the CPU...
@@ -82,37 +149,37 @@ cpu_init_f (void)
mtebc(pb0cr, CFG_EBC_PB0CR);
#endif
#if (defined(CFG_EBC_PB1AP) && defined(CFG_EBC_PB1CR))
#if (defined(CFG_EBC_PB1AP) && defined(CFG_EBC_PB1CR) && !(CFG_INIT_DCACHE_CS == 1))
mtebc(pb1ap, CFG_EBC_PB1AP);
mtebc(pb1cr, CFG_EBC_PB1CR);
#endif
#if (defined(CFG_EBC_PB2AP) && defined(CFG_EBC_PB2CR))
#if (defined(CFG_EBC_PB2AP) && defined(CFG_EBC_PB2CR) && !(CFG_INIT_DCACHE_CS == 2))
mtebc(pb2ap, CFG_EBC_PB2AP);
mtebc(pb2cr, CFG_EBC_PB2CR);
#endif
#if (defined(CFG_EBC_PB3AP) && defined(CFG_EBC_PB3CR))
#if (defined(CFG_EBC_PB3AP) && defined(CFG_EBC_PB3CR) && !(CFG_INIT_DCACHE_CS == 3))
mtebc(pb3ap, CFG_EBC_PB3AP);
mtebc(pb3cr, CFG_EBC_PB3CR);
#endif
#if (defined(CFG_EBC_PB4AP) && defined(CFG_EBC_PB4CR))
#if (defined(CFG_EBC_PB4AP) && defined(CFG_EBC_PB4CR) && !(CFG_INIT_DCACHE_CS == 4))
mtebc(pb4ap, CFG_EBC_PB4AP);
mtebc(pb4cr, CFG_EBC_PB4CR);
#endif
#if (defined(CFG_EBC_PB5AP) && defined(CFG_EBC_PB5CR))
#if (defined(CFG_EBC_PB5AP) && defined(CFG_EBC_PB5CR) && !(CFG_INIT_DCACHE_CS == 5))
mtebc(pb5ap, CFG_EBC_PB5AP);
mtebc(pb5cr, CFG_EBC_PB5CR);
#endif
#if (defined(CFG_EBC_PB6AP) && defined(CFG_EBC_PB6CR))
#if (defined(CFG_EBC_PB6AP) && defined(CFG_EBC_PB6CR) && !(CFG_INIT_DCACHE_CS == 6))
mtebc(pb6ap, CFG_EBC_PB6AP);
mtebc(pb6cr, CFG_EBC_PB6CR);
#endif
#if (defined(CFG_EBC_PB7AP) && defined(CFG_EBC_PB7CR))
#if (defined(CFG_EBC_PB7AP) && defined(CFG_EBC_PB7CR) && !(CFG_INIT_DCACHE_CS == 7))
mtebc(pb7ap, CFG_EBC_PB7AP);
mtebc(pb7cr, CFG_EBC_PB7CR);
#endif
@@ -146,6 +213,24 @@ int cpu_init_r (void)
uint pvr = get_pvr();
#endif
#ifdef CFG_INIT_DCACHE_CS
/*
* Flush and invalidate dcache, then disable CS for temporary stack.
* Afterwards, this CS can be used for other purposes
*/
dcache_disable(); /* flush and invalidate dcache */
mtebc(PBxAP, 0);
mtebc(PBxCR, 0); /* disable CS for temporary stack */
#if (defined(PBxAP_VAL) && defined(PBxCR_VAL))
/*
* Write new value into CS register
*/
mtebc(PBxAP, PBxAP_VAL);
mtebc(PBxCR, PBxCR_VAL);
#endif
#endif /* CFG_INIT_DCACHE_CS */
/*
* Write Ethernetaddress into on-chip register
*/

View File

@@ -1,10 +1,13 @@
/* Copyright MontaVista Software Incorporated, 2000 */
#include <config.h>
.section .resetvec,"ax"
#if defined(CONFIG_440)
b _start_440
#else
#if defined(CONFIG_BOOT_PCI) && defined(CONFIG_MIP405)
b _start_pci
#else
b _start
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More