mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-02 17:56:44 +03:00
Compare commits
15 Commits
U-Boot-0_2
...
LABEL_2003
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db2f721ffc | ||
|
|
43d9616cff | ||
|
|
6069ff2653 | ||
|
|
2a9e02ead3 | ||
|
|
d7787c6e57 | ||
|
|
ad10dd9aaf | ||
|
|
e5ad56b13b | ||
|
|
ee1b3b5fe4 | ||
|
|
6177445dab | ||
|
|
aacf9a49aa | ||
|
|
608c91460b | ||
|
|
d0fb80c302 | ||
|
|
a25f862ba8 | ||
|
|
13122b4f1d | ||
|
|
288b3d7f5a |
111
CHANGELOG
111
CHANGELOG
@@ -1,3 +1,114 @@
|
||||
======================================================================
|
||||
Changes since U-Boot 0.2.2:
|
||||
======================================================================
|
||||
|
||||
* Patch by Rune Torgersen, 13 Feb 2003:
|
||||
Add support for Motorola MPC8266ADS board
|
||||
|
||||
* Patch by Kyle Harris, 19 Feb 2003:
|
||||
patches for the Intel lubbock board:
|
||||
memsetup.S - general cleanup (based on Robert's csb226 code)
|
||||
flash.c - overhaul, actually works now
|
||||
lubbock.c - fix init funcs to return proper value
|
||||
|
||||
* Patch by Kenneth Johansson, 26 Feb 2003:
|
||||
- Fixed off by one in RFTA calculation.
|
||||
- No need to abort when LDF is lower than we can program it's only
|
||||
minimum timing so clamp it to what we can do.
|
||||
- Takes function pointer to function for reading the spd_nvram. Usefull
|
||||
for faking data or hardcode a module without the nvram.
|
||||
- fix other user for above change
|
||||
- fix some comments.
|
||||
|
||||
* Patches by Brian Waite, 26 Feb 2003:
|
||||
- fix port for evb64260 board
|
||||
- fix PCI for evb64260 board
|
||||
- fix PCI scan
|
||||
|
||||
* Patch by Reinhard Meyer, 1 Mar 2003:
|
||||
Add support for EMK TOP860 Module
|
||||
|
||||
* Patch by Yuli Barcohen, 02 Mar 2003:
|
||||
Add SPD EEPROM support for MPC8260ADS board
|
||||
|
||||
* Patch by Robert Schwebel, 21 Jan 2003:
|
||||
- Add support for Innokom board
|
||||
- Don't complain if "install" fails
|
||||
- README cleanup (remove duplicated lines)
|
||||
- Update PXA header files
|
||||
|
||||
* Add documentation for existing POST code (doc/README.POST)
|
||||
|
||||
* Patch by Laudney Ren, 15 Jan 2003:
|
||||
Fix handling of redundand environment in "tools/envcrc.c"
|
||||
|
||||
* Patch by Detlev Zundel, 28 Feb 2003:
|
||||
Add bedbug support for 824x systems
|
||||
|
||||
* Add support for 16 MB flash configuration of TRAB board
|
||||
|
||||
* Patch by Erwin Rol, 27 Feb 2003:
|
||||
Add support for RTEMS
|
||||
|
||||
* Add image information to README
|
||||
|
||||
* Patch by Stefan Roese, 18 Feb 2003:
|
||||
CPCIISER4 configuration updated.
|
||||
|
||||
* Patch by Stefan Roese, 17 Feb 2003:
|
||||
Fixed bug in ext. serial clock setup on PPC405 (since PPC440 port).
|
||||
|
||||
* Patch by Stefan Roese, 13 Feb 2003:
|
||||
Add "pcidelay" environment variable (in ms, enabled via
|
||||
CONFIG_PCI_BOOTDELAY).
|
||||
PCI spec 2.2 defines, that a pci target has 2^25 pci clocks after
|
||||
RST# to respond to configuration cycles (33MHz -> 1s).
|
||||
|
||||
* Fix dual PCMCIA slot support (when running with just one
|
||||
slot populated)
|
||||
|
||||
* Add VFD type detection to trab board
|
||||
|
||||
* extend drivers/cs8900.c driver to synchronize ethaddr environment
|
||||
variable with value in the EEPROM
|
||||
|
||||
* Patch by Stefan Roese, 10 Feb 2003:
|
||||
Add support for 4MB and 128MB onboard SDRAM (cpu/ppc4xx/sdram.c)
|
||||
|
||||
======================================================================
|
||||
Changes for U-Boot 0.2.2:
|
||||
======================================================================
|
||||
|
||||
* Add dual ethernet support on PM826
|
||||
|
||||
* Add support for LXT971 PHY on PM826
|
||||
|
||||
* Patch by Tord Andersson, 16 Jan 2003:
|
||||
Fix flash sector count for TQM8xxL
|
||||
|
||||
* Fix I2C EEPROM problem on ICU862 board (would only write the first
|
||||
16 bytes out of each 32 byte block)
|
||||
|
||||
======================================================================
|
||||
Changes for U-Boot 0.2.1:
|
||||
======================================================================
|
||||
|
||||
* Add support for V37 board
|
||||
(patch by Jón Benediktsson, 11 Dec 2002)
|
||||
|
||||
* Update baudrate in bd_info when it gets changed
|
||||
|
||||
* Add watchdog trigger points while waiting for serial port
|
||||
(so far only 8xx -- needed on LWMON with 100ms watchdog)
|
||||
|
||||
* Improve command line tool to access the U-Boot's environment
|
||||
(figuration of the utility, using a config file)
|
||||
|
||||
* Add single quote support for (old) command line parser
|
||||
|
||||
* Switch LWMON board default config from FRAM to EEPROM;
|
||||
in POST, EEPROM shows up on 8 addresses
|
||||
|
||||
======================================================================
|
||||
Changes for U-Boot 0.2.0:
|
||||
======================================================================
|
||||
|
||||
21
CREDITS
21
CREDITS
@@ -30,13 +30,17 @@ N: Pierre Aubert
|
||||
E: <p.aubert@staubli.com>
|
||||
D: Support for RPXClassic board
|
||||
|
||||
N: Jerry van Baren
|
||||
E: <vanbaren@cideas.com>
|
||||
D: BedBug port to 603e core (MPC82xx). Code for enhanced memory test.
|
||||
|
||||
N: Andre Beaudin
|
||||
E: <andre.beaudin@colubris.com>
|
||||
D: PCMCIA, Ethernet, TFTP
|
||||
|
||||
N: Jerry van Baren
|
||||
E: <vanbaren@cideas.com>
|
||||
D: BedBug port to 603e core (MPC82xx). Code for enhanced memory test.
|
||||
N: Jon Benediktsson
|
||||
E: jonb@marel.is
|
||||
D: Support for Marel V37 board
|
||||
|
||||
N: Raphael Bossek
|
||||
E: raphael.bossek@solutions4linux.de
|
||||
@@ -170,6 +174,10 @@ N: Dan Malek
|
||||
E: dan@netx4.com
|
||||
D: FADSROM, the grandfather of all of this
|
||||
|
||||
N: Reinhard Meyer
|
||||
E: r.meyer@emk-elektronik.de
|
||||
D: Port to EMK TOP860 Module
|
||||
|
||||
N: Jay Monkman
|
||||
E: jtm@smoothsmoothie.com
|
||||
D: EST SBC8260 support
|
||||
@@ -223,7 +231,8 @@ D: FADS823 configuration, MPC823 video support, I2C, wireless keyboard, lots mor
|
||||
|
||||
N: Robert Schwebel
|
||||
E: r.schwebel@pengutronix.de
|
||||
D: Support for csb226 board (xscale)
|
||||
D: Support for csb226 and innokom boards (xscale)
|
||||
|
||||
N: Rob Taylor
|
||||
E: robt@flyingpig.com
|
||||
D: Port to MBX860T and Sandpoint8240
|
||||
@@ -236,6 +245,10 @@ N: Jim Thompson
|
||||
E: jim@musenki.com
|
||||
D: Support for MUSENKI board
|
||||
|
||||
N: Rune Torgersen
|
||||
E: <runet@innovsys.com>
|
||||
D: Support for Motorola MPC8266ADS board
|
||||
|
||||
N: David Updegraff
|
||||
E: dave@cray.com
|
||||
D: Port to Cray L1 board; DHCP vendor extensions
|
||||
|
||||
21
MAINTAINERS
21
MAINTAINERS
@@ -14,6 +14,7 @@
|
||||
|
||||
|
||||
#########################################################################
|
||||
# PowerPC Systems: #
|
||||
# #
|
||||
# Maintainer Name, Email Address #
|
||||
# Board CPU #
|
||||
@@ -140,6 +141,10 @@ Eran Man <eran@nbase.co.il>
|
||||
|
||||
EVB64260_750CX MPC750CX
|
||||
|
||||
Reinhard Meyer <r.meyer@emk-elektronik.de>
|
||||
|
||||
TOP860 MPC860
|
||||
|
||||
Scott McNutt <smcnutt@artesyncp.com>
|
||||
|
||||
EBONY PPC440GP
|
||||
@@ -184,6 +189,10 @@ Jim Thompson <jim@musenki.com>
|
||||
MUSENKI MPC8245/8241
|
||||
Sandpoint8245 MPC8245
|
||||
|
||||
Rune Torgersen <runet@innovsys.com>
|
||||
|
||||
MPC8266ADS MPC8266
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
Unknown / orphaned boards:
|
||||
@@ -246,6 +255,7 @@ Rolf Offermanns <rof@sysgo.de>
|
||||
Robert Schwebel <r.schwebel@pengutronix.de>
|
||||
|
||||
csb226 xscale
|
||||
innokom xscale
|
||||
|
||||
Alex Züpke <azu@sysgo.de>
|
||||
|
||||
@@ -263,6 +273,17 @@ Daniel Engstr
|
||||
|
||||
sc520_cdp x86
|
||||
|
||||
#########################################################################
|
||||
# MIPS Systems: #
|
||||
# #
|
||||
# Maintainer Name, Email Address #
|
||||
# Board CPU #
|
||||
#########################################################################
|
||||
|
||||
Wolfgang Denk <wd@denx.de>
|
||||
|
||||
incaip MIPS32 4Kc
|
||||
|
||||
#########################################################################
|
||||
# End of MAINTAINERS list #
|
||||
#########################################################################
|
||||
|
||||
14
MAKEALL
14
MAKEALL
@@ -25,9 +25,9 @@ LIST_8xx=" \
|
||||
MBX MBX860T MHPC MVS1 \
|
||||
NETVIA NX823 pcu_e R360MPI \
|
||||
RPXClassic RPXlite RRvision SM850 \
|
||||
SPD823TS SXNI855T TQM823L TQM823L_LCD \
|
||||
TQM850L TQM855L TQM860L TQM860L_FEC \
|
||||
TTTech
|
||||
SPD823TS SXNI855T TOP860 TQM823L \
|
||||
TQM823L_LCD TQM850L TQM855L TQM860L \
|
||||
TQM860L_FEC TTTech v37 \
|
||||
"
|
||||
|
||||
#########################################################################
|
||||
@@ -59,9 +59,9 @@ LIST_824x=" \
|
||||
|
||||
LIST_8260=" \
|
||||
cogent_mpc8260 CPU86 ep8260 gw8260 \
|
||||
hymod IPHASE4539 MPC8260ADS PM826 \
|
||||
ppmc8260 RPXsuper rsdproto sacsng \
|
||||
sbc8260 SCM TQM8260 \
|
||||
hymod IPHASE4539 MPC8260ADS MPC8266ADS \
|
||||
PM826 ppmc8260 RPXsuper rsdproto \
|
||||
sacsng sbc8260 SCM TQM8260 \
|
||||
"
|
||||
|
||||
#########################################################################
|
||||
@@ -101,7 +101,7 @@ LIST_ARM9="smdk2400 smdk2410 trab"
|
||||
## Xscale Systems
|
||||
#########################################################################
|
||||
|
||||
LIST_xscale="lubbock cradle csb226"
|
||||
LIST_xscale="lubbock cradle csb226 innokom"
|
||||
|
||||
|
||||
LIST_arm="${LIST_SA} ${LIST_ARM7} ${LIST_ARM9} ${LIST_xscale}"
|
||||
|
||||
53
Makefile
53
Makefile
@@ -77,6 +77,9 @@ endif
|
||||
ifeq ($(ARCH),i386)
|
||||
#CROSS_COMPILE = i386-elf-
|
||||
endif
|
||||
ifeq ($(ARCH),mips)
|
||||
CROSS_COMPILE = mips_4KC-
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -129,8 +132,8 @@ LIBS += lib_generic/libgeneric.a
|
||||
all: u-boot.srec u-boot.bin System.map
|
||||
|
||||
install: all
|
||||
cp u-boot.bin /tftpboot/u-boot.bin
|
||||
cp u-boot.bin /net/sam/tftpboot/u-boot.bin
|
||||
-cp u-boot.bin /tftpboot/u-boot.bin
|
||||
-cp u-boot.bin /net/denx/tftpboot/u-boot.bin
|
||||
|
||||
u-boot.srec: u-boot
|
||||
$(OBJCOPY) ${OBJCFLAGS} -O srec $< $@
|
||||
@@ -326,6 +329,10 @@ SPD823TS_config: unconfig
|
||||
SXNI855T_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc mpc8xx sixnet
|
||||
|
||||
# EMK MPC8xx based modules
|
||||
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,
|
||||
# but only 855 and 860 boards may come with FEC
|
||||
@@ -380,6 +387,11 @@ TTTech_config: unconfig
|
||||
@echo "#define CONFIG_SHARP_LQ104V7DS01" >>include/config.h
|
||||
@./mkconfig -a TQM823L ppc mpc8xx tqm8xx
|
||||
|
||||
v37_config: unconfig
|
||||
@echo "#define CONFIG_LCD" >include/config.h
|
||||
@echo "#define CONFIG_SHARP_LQ084V1DG21" >>include/config.h
|
||||
@./mkconfig $(@:_config=) ppc mpc8xx v37
|
||||
|
||||
#########################################################################
|
||||
## PPC4xx Systems
|
||||
#########################################################################
|
||||
@@ -508,6 +520,9 @@ IPHASE4539_config: unconfig
|
||||
MPC8260ADS_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc mpc8260 mpc8260ads
|
||||
|
||||
MPC8266ADS_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc mpc8260 mpc8266ads
|
||||
|
||||
PM826_config \
|
||||
PM826_ROMBOOT_config: unconfig
|
||||
@./mkconfig $(call xtract_82xx,$@) ppc mpc8260 pm826
|
||||
@@ -606,14 +621,22 @@ shannon_config : unconfig
|
||||
## ARM920T Systems
|
||||
#########################################################################
|
||||
|
||||
xtract_trab = $(subst _big_flash,,$(subst _config,,$1))
|
||||
|
||||
smdk2400_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm arm920t smdk2400
|
||||
|
||||
smdk2410_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm arm920t smdk2410
|
||||
|
||||
trab_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm arm920t trab
|
||||
trab_config \
|
||||
trab_big_flash_config: unconfig
|
||||
@ >include/config.h
|
||||
@[ -z "$(findstring _big_flash,$@)" ] || \
|
||||
{ echo "#define CONFIG_BIG_FLASH" >>include/config.h ; \
|
||||
echo "... with big flash support" ; \
|
||||
}
|
||||
@./mkconfig -a $(call xtract_trab,$@) arm arm920t trab
|
||||
|
||||
#########################################################################
|
||||
## ARM720T Systems
|
||||
@@ -626,18 +649,21 @@ ep7312_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm arm720t ep7312
|
||||
|
||||
#########################################################################
|
||||
## Xscale Systems
|
||||
## XScale Systems
|
||||
#########################################################################
|
||||
|
||||
lubbock_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm xscale lubbock
|
||||
|
||||
cradle_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm xscale cradle
|
||||
|
||||
csb226_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm xscale csb226
|
||||
|
||||
innokom_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm xscale innokom
|
||||
|
||||
lubbock_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm xscale lubbock
|
||||
|
||||
#========================================================================
|
||||
# i386
|
||||
#========================================================================
|
||||
@@ -647,7 +673,17 @@ csb226_config : unconfig
|
||||
sc520_cdp_config : unconfig
|
||||
@./mkconfig $(@:_config=) i386 i386 sc520_cdp
|
||||
|
||||
#========================================================================
|
||||
# MIPS
|
||||
#========================================================================
|
||||
#########################################################################
|
||||
## MIPS32 4Kc
|
||||
#########################################################################
|
||||
|
||||
incaip_config : unconfig
|
||||
@./mkconfig $(@:_config=) mips mips incaip
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
find . -type f \
|
||||
@@ -669,6 +705,7 @@ clobber: clean
|
||||
rm -fr *.*~
|
||||
rm -f u-boot u-boot.bin u-boot.elf u-boot.srec u-boot.map System.map
|
||||
rm -f tools/crc32.c tools/environment.c tools/env/crc32.c
|
||||
rm -f cpu/mpc824x/bedbug_603e.c
|
||||
rm -f include/asm/arch include/asm
|
||||
|
||||
mrproper \
|
||||
|
||||
418
README
418
README
@@ -337,7 +337,8 @@ The following options need to be configured:
|
||||
CONFIG_GENIETV, CONFIG_PM826, CONFIG_ppmc8260,
|
||||
CONFIG_GTH, CONFIG_RPXClassic, CONFIG_rsdproto,
|
||||
CONFIG_IAD210, CONFIG_RPXlite, CONFIG_sbc8260,
|
||||
CONFIG_EBONY, CONFIG_sacsng, CONFIG_FPS860L
|
||||
CONFIG_EBONY, CONFIG_sacsng, CONFIG_FPS860L,
|
||||
CONFIG_V37
|
||||
|
||||
ARM based boards:
|
||||
-----------------
|
||||
@@ -394,10 +395,10 @@ The following options need to be configured:
|
||||
default environment.
|
||||
|
||||
- Console Interface:
|
||||
Depending on board, define exactly one serial port
|
||||
(like CONFIG_8xx_CONS_SMC1, CONFIG_8xx_CONS_SMC2,
|
||||
CONFIG_8xx_CONS_SCC1, ...), or switch off the serial
|
||||
console by defining CONFIG_8xx_CONS_NONE
|
||||
Depending on board, define exactly one serial port
|
||||
(like CONFIG_8xx_CONS_SMC1, CONFIG_8xx_CONS_SMC2,
|
||||
CONFIG_8xx_CONS_SCC1, ...), or switch off the serial
|
||||
console by defining CONFIG_8xx_CONS_NONE
|
||||
|
||||
Note: if CONFIG_8xx_CONS_NONE is defined, the serial
|
||||
port routines must be defined elsewhere
|
||||
@@ -442,9 +443,9 @@ The following options need to be configured:
|
||||
addional board info beside
|
||||
the logo
|
||||
|
||||
When CONFIG_CFB_CONSOLE is defined, video console is
|
||||
default i/o. Serial console can be forced with
|
||||
environment 'console=serial'.
|
||||
When CONFIG_CFB_CONSOLE is defined, video console is
|
||||
default i/o. Serial console can be forced with
|
||||
environment 'console=serial'.
|
||||
|
||||
- Console Baudrate:
|
||||
CONFIG_BAUDRATE - in bps
|
||||
@@ -488,15 +489,15 @@ The following options need to be configured:
|
||||
within "Boot Delay" after reset.
|
||||
|
||||
CONFIG_BOOTARGS
|
||||
This can be used to pass arguments to the bootm
|
||||
command. The value of CONFIG_BOOTARGS goes into the
|
||||
environment value "bootargs".
|
||||
This can be used to pass arguments to the bootm
|
||||
command. The value of CONFIG_BOOTARGS goes into the
|
||||
environment value "bootargs".
|
||||
|
||||
CONFIG_RAMBOOT and CONFIG_NFSBOOT
|
||||
The value of these goes into the environment as
|
||||
"ramboot" and "nfsboot" respectively, and can be used
|
||||
as a convenience, when switching between booting from
|
||||
ram and nfs.
|
||||
The value of these goes into the environment as
|
||||
"ramboot" and "nfsboot" respectively, and can be used
|
||||
as a convenience, when switching between booting from
|
||||
ram and nfs.
|
||||
|
||||
- Pre-Boot Commands:
|
||||
CONFIG_PREBOOT
|
||||
@@ -595,13 +596,13 @@ The following options need to be configured:
|
||||
|
||||
|
||||
Note: Don't enable the "icache" and "dcache" commands
|
||||
(configuration option CFG_CMD_CACHE) unless you know
|
||||
what you (and your U-Boot users) are doing. Data
|
||||
cache cannot be enabled on systems like the 8xx or
|
||||
8260 (where accesses to the IMMR region must be
|
||||
uncached), and it cannot be disabled on all other
|
||||
systems where we (mis-) use the data cache to hold an
|
||||
initial stack and some data.
|
||||
(configuration option CFG_CMD_CACHE) unless you know
|
||||
what you (and your U-Boot users) are doing. Data
|
||||
cache cannot be enabled on systems like the 8xx or
|
||||
8260 (where accesses to the IMMR region must be
|
||||
uncached), and it cannot be disabled on all other
|
||||
systems where we (mis-) use the data cache to hold an
|
||||
initial stack and some data.
|
||||
|
||||
|
||||
XXX - this list needs to get updated!
|
||||
@@ -627,10 +628,10 @@ The following options need to be configured:
|
||||
|
||||
- Timestamp Support:
|
||||
|
||||
When CONFIG_TIMESTAMP is selected, the timestamp
|
||||
(date and time) of an image is printed by image
|
||||
commands like bootm or iminfo. This option is
|
||||
automatically enabled when you select CFG_CMD_DATE .
|
||||
When CONFIG_TIMESTAMP is selected, the timestamp
|
||||
(date and time) of an image is printed by image
|
||||
commands like bootm or iminfo. This option is
|
||||
automatically enabled when you select CFG_CMD_DATE .
|
||||
|
||||
- Partition Support:
|
||||
CONFIG_MAC_PARTITION and/or CONFIG_DOS_PARTITION
|
||||
@@ -719,14 +720,14 @@ The following options need to be configured:
|
||||
standard LiLo mode numbers.
|
||||
Following modes are supported (* is default):
|
||||
|
||||
800x600 1024x768 1280x1024
|
||||
256 (8bit) 303* 305 307
|
||||
65536 (16bit) 314 317 31a
|
||||
16,7 Mill (24bit) 315 318 31b
|
||||
800x600 1024x768 1280x1024
|
||||
256 (8bit) 303* 305 307
|
||||
65536 (16bit) 314 317 31a
|
||||
16,7 Mill (24bit) 315 318 31b
|
||||
(i.e. setenv videomode 317; saveenv; reset;)
|
||||
|
||||
CONFIG_VIDEO_SED13806
|
||||
Enable Epson SED13806 driver. This driver supports 8bpp
|
||||
Enable Epson SED13806 driver. This driver supports 8bpp
|
||||
and 16bpp modes defined by CONFIG_VIDEO_SED13806_8BPP
|
||||
or CONFIG_VIDEO_SED13806_16BPP
|
||||
|
||||
@@ -838,8 +839,8 @@ The following options need to be configured:
|
||||
either CONFIG_HARD_I2C or CONFIG_SOFT_I2C must be defined
|
||||
to include the appropriate I2C driver.
|
||||
|
||||
See also: common/cmd_i2c.c for a description of the
|
||||
command line interface.
|
||||
See also: common/cmd_i2c.c for a description of the
|
||||
command line interface.
|
||||
|
||||
|
||||
CONFIG_HARD_I2C
|
||||
@@ -854,14 +855,14 @@ The following options need to be configured:
|
||||
|
||||
I2C_INIT
|
||||
|
||||
(Optional). Any commands necessary to enable I2C
|
||||
controller or configure ports.
|
||||
(Optional). Any commands necessary to enable I2C
|
||||
controller or configure ports.
|
||||
|
||||
I2C_PORT
|
||||
|
||||
(Only for MPC8260 CPU). The I/O port to use (the code
|
||||
assumes both bits are on the same port). Valid values
|
||||
are 0..3 for ports A..D.
|
||||
(Only for MPC8260 CPU). The I/O port to use (the code
|
||||
assumes both bits are on the same port). Valid values
|
||||
are 0..3 for ports A..D.
|
||||
|
||||
I2C_ACTIVE
|
||||
|
||||
@@ -909,40 +910,40 @@ The following options need to be configured:
|
||||
|
||||
CONFIG_SOFT_SPI
|
||||
|
||||
Enables a software (bit-bang) SPI driver rather than
|
||||
using hardware support. This is a general purpose
|
||||
driver that only requires three general I/O port pins
|
||||
(two outputs, one input) to function. If this is
|
||||
defined, the board configuration must define several
|
||||
SPI configuration items (port pins to use, etc). For
|
||||
an example, see include/configs/sacsng.h.
|
||||
Enables a software (bit-bang) SPI driver rather than
|
||||
using hardware support. This is a general purpose
|
||||
driver that only requires three general I/O port pins
|
||||
(two outputs, one input) to function. If this is
|
||||
defined, the board configuration must define several
|
||||
SPI configuration items (port pins to use, etc). For
|
||||
an example, see include/configs/sacsng.h.
|
||||
|
||||
- FPGA Support: CONFIG_FPGA_COUNT
|
||||
|
||||
Specify the number of FPGA devices to support.
|
||||
Specify the number of FPGA devices to support.
|
||||
|
||||
CONFIG_FPGA
|
||||
CONFIG_FPGA
|
||||
|
||||
Used to specify the types of FPGA devices. For
|
||||
Used to specify the types of FPGA devices. For
|
||||
example,
|
||||
#define CONFIG_FPGA CFG_XILINX_VIRTEX2
|
||||
|
||||
CFG_FPGA_PROG_FEEDBACK
|
||||
|
||||
Enable printing of hash marks during FPGA
|
||||
Enable printing of hash marks during FPGA
|
||||
configuration.
|
||||
|
||||
CFG_FPGA_CHECK_BUSY
|
||||
|
||||
Enable checks on FPGA configuration interface busy
|
||||
status by the configuration function. This option
|
||||
will require a board or device specific function to
|
||||
be written.
|
||||
Enable checks on FPGA configuration interface busy
|
||||
status by the configuration function. This option
|
||||
will require a board or device specific function to
|
||||
be written.
|
||||
|
||||
CONFIG_FPGA_DELAY
|
||||
|
||||
If defined, a function that provides delays in the
|
||||
FPGA configuration driver.
|
||||
If defined, a function that provides delays in the
|
||||
FPGA configuration driver.
|
||||
|
||||
CFG_FPGA_CHECK_CTRLC
|
||||
|
||||
@@ -950,25 +951,25 @@ The following options need to be configured:
|
||||
|
||||
CFG_FPGA_CHECK_ERROR
|
||||
|
||||
Check for configuration errors during FPGA bitfile
|
||||
loading. For example, abort during Virtex II
|
||||
configuration if the INIT_B line goes low (which
|
||||
indicated a CRC error).
|
||||
Check for configuration errors during FPGA bitfile
|
||||
loading. For example, abort during Virtex II
|
||||
configuration if the INIT_B line goes low (which
|
||||
indicated a CRC error).
|
||||
|
||||
CFG_FPGA_WAIT_INIT
|
||||
|
||||
Maximum time to wait for the INIT_B line to deassert
|
||||
after PROB_B has been deasserted during a Virtex II
|
||||
FPGA configuration sequence. The default time is 500 mS.
|
||||
Maximum time to wait for the INIT_B line to deassert
|
||||
after PROB_B has been deasserted during a Virtex II
|
||||
FPGA configuration sequence. The default time is 500 mS.
|
||||
|
||||
CFG_FPGA_WAIT_BUSY
|
||||
|
||||
Maximum time to wait for BUSY to deassert during
|
||||
Virtex II FPGA configuration. The default is 5 mS.
|
||||
Maximum time to wait for BUSY to deassert during
|
||||
Virtex II FPGA configuration. The default is 5 mS.
|
||||
|
||||
CFG_FPGA_WAIT_CONFIG
|
||||
|
||||
Time to wait after FPGA configuration. The default is
|
||||
Time to wait after FPGA configuration. The default is
|
||||
200 mS.
|
||||
|
||||
- FPGA Support: CONFIG_FPGA_COUNT
|
||||
@@ -986,10 +987,10 @@ The following options need to be configured:
|
||||
|
||||
CFG_FPGA_CHECK_BUSY
|
||||
|
||||
Enable checks on FPGA configuration interface busy
|
||||
status by the configuration function. This option
|
||||
will require a board or device specific function to
|
||||
be written.
|
||||
Enable checks on FPGA configuration interface busy
|
||||
status by the configuration function. This option
|
||||
will require a board or device specific function to
|
||||
be written.
|
||||
|
||||
CONFIG_FPGA_DELAY
|
||||
|
||||
@@ -1001,44 +1002,44 @@ The following options need to be configured:
|
||||
|
||||
CFG_FPGA_CHECK_ERROR
|
||||
|
||||
Check for configuration errors during FPGA bitfile
|
||||
loading. For example, abort during Virtex II
|
||||
configuration if the INIT_B line goes low (which
|
||||
indicated a CRC error).
|
||||
Check for configuration errors during FPGA bitfile
|
||||
loading. For example, abort during Virtex II
|
||||
configuration if the INIT_B line goes low (which
|
||||
indicated a CRC error).
|
||||
|
||||
CFG_FPGA_WAIT_INIT
|
||||
|
||||
Maximum time to wait for the INIT_B line to deassert
|
||||
after PROB_B has been deasserted during a Virtex II
|
||||
FPGA configuration sequence. The default time is 500
|
||||
mS.
|
||||
Maximum time to wait for the INIT_B line to deassert
|
||||
after PROB_B has been deasserted during a Virtex II
|
||||
FPGA configuration sequence. The default time is 500
|
||||
mS.
|
||||
|
||||
CFG_FPGA_WAIT_BUSY
|
||||
|
||||
Maximum time to wait for BUSY to deassert during
|
||||
Virtex II FPGA configuration. The default is 5 mS.
|
||||
Maximum time to wait for BUSY to deassert during
|
||||
Virtex II FPGA configuration. The default is 5 mS.
|
||||
|
||||
CFG_FPGA_WAIT_CONFIG
|
||||
|
||||
Time to wait after FPGA configuration. The default is
|
||||
200 mS.
|
||||
Time to wait after FPGA configuration. The default is
|
||||
200 mS.
|
||||
|
||||
- Configuration Management:
|
||||
CONFIG_IDENT_STRING
|
||||
|
||||
If defined, this string will be added to the U-Boot
|
||||
version information (U_BOOT_VERSION)
|
||||
If defined, this string will be added to the U-Boot
|
||||
version information (U_BOOT_VERSION)
|
||||
|
||||
- Vendor Parameter Protection:
|
||||
|
||||
U-Boot considers the values of the environment
|
||||
variables "serial#" (Board Serial Number) and
|
||||
"ethaddr" (Ethernet Address) to bb parameters that
|
||||
are set once by the board vendor / manufacturer, and
|
||||
protects these variables from casual modification by
|
||||
the user. Once set, these variables are read-only,
|
||||
and write or delete attempts are rejected. You can
|
||||
change this behviour:
|
||||
U-Boot considers the values of the environment
|
||||
variables "serial#" (Board Serial Number) and
|
||||
"ethaddr" (Ethernet Address) to bb parameters that
|
||||
are set once by the board vendor / manufacturer, and
|
||||
protects these variables from casual modification by
|
||||
the user. Once set, these variables are read-only,
|
||||
and write or delete attempts are rejected. You can
|
||||
change this behviour:
|
||||
|
||||
If CONFIG_ENV_OVERWRITE is #defined in your config
|
||||
file, the write protection for vendor parameters is
|
||||
@@ -1098,10 +1099,10 @@ The following options need to be configured:
|
||||
|
||||
CONFIG_NET_RETRY_COUNT
|
||||
|
||||
This variable defines the number of retries for
|
||||
network operations like ARP, RARP, TFTP, or BOOTP
|
||||
before giving up the operation. If not defined, a
|
||||
default value of 5 is used.
|
||||
This variable defines the number of retries for
|
||||
network operations like ARP, RARP, TFTP, or BOOTP
|
||||
before giving up the operation. If not defined, a
|
||||
default value of 5 is used.
|
||||
|
||||
- Command Interpreter:
|
||||
CFG_HUSH_PARSER
|
||||
@@ -1124,18 +1125,18 @@ The following options need to be configured:
|
||||
|
||||
Note:
|
||||
|
||||
In the current implementation, the local variables
|
||||
space and global environment variables space are
|
||||
separated. Local variables are those you define by
|
||||
simply typing like `name=value'. To access a local
|
||||
variable later on, you have write `$name' or
|
||||
`${name}'; variable directly by typing say `$name' at
|
||||
the command prompt.
|
||||
In the current implementation, the local variables
|
||||
space and global environment variables space are
|
||||
separated. Local variables are those you define by
|
||||
simply typing like `name=value'. To access a local
|
||||
variable later on, you have write `$name' or
|
||||
`${name}'; variable directly by typing say `$name' at
|
||||
the command prompt.
|
||||
|
||||
Global environment variables are those you use
|
||||
setenv/printenv to work with. To run a command stored
|
||||
in such a variable, you need to use the run command,
|
||||
and you must not use the '$' sign to access them.
|
||||
Global environment variables are those you use
|
||||
setenv/printenv to work with. To run a command stored
|
||||
in such a variable, you need to use the run command,
|
||||
and you must not use the '$' sign to access them.
|
||||
|
||||
To store commands and special characters in a
|
||||
variable, please use double quotation marks
|
||||
@@ -1146,38 +1147,38 @@ The following options need to be configured:
|
||||
- Default Environment
|
||||
CONFIG_EXTRA_ENV_SETTINGS
|
||||
|
||||
Define this to contain any number of null terminated
|
||||
strings (variable = value pairs) that will be part of
|
||||
the default enviroment compiled into the boot image.
|
||||
Define this to contain any number of null terminated
|
||||
strings (variable = value pairs) that will be part of
|
||||
the default enviroment compiled into the boot image.
|
||||
|
||||
For example, place something like this in your
|
||||
board's config file:
|
||||
For example, place something like this in your
|
||||
board's config file:
|
||||
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
"myvar1=value1\0" \
|
||||
"myvar2=value2\0"
|
||||
|
||||
Warning: This method is based on knowledge about the
|
||||
internal format how the environment is stored by the
|
||||
U-Boot code. This is NOT an official, exported
|
||||
interface! Although it is unlikely that this format
|
||||
will change soon, but there is no guarantee either.
|
||||
Warning: This method is based on knowledge about the
|
||||
internal format how the environment is stored by the
|
||||
U-Boot code. This is NOT an official, exported
|
||||
interface! Although it is unlikely that this format
|
||||
will change soon, but there is no guarantee either.
|
||||
You better know what you are doing here.
|
||||
|
||||
Note: overly (ab)use of the default environment is
|
||||
discouraged. Make sure to check other ways to preset
|
||||
the environment like the autoscript function or the
|
||||
boot command first.
|
||||
Note: overly (ab)use of the default environment is
|
||||
discouraged. Make sure to check other ways to preset
|
||||
the environment like the autoscript function or the
|
||||
boot command first.
|
||||
|
||||
- Show boot progress
|
||||
CONFIG_SHOW_BOOT_PROGRESS
|
||||
|
||||
Defining this option allows to add some board-
|
||||
specific code (calling a user-provided function
|
||||
"show_boot_progress(int)") that enables you to show
|
||||
the system's boot progress on some display (for
|
||||
example, some LED's) on your board. At the moment,
|
||||
the following checkpoints are implemented:
|
||||
Defining this option allows to add some board-
|
||||
specific code (calling a user-provided function
|
||||
"show_boot_progress(int)") that enables you to show
|
||||
the system's boot progress on some display (for
|
||||
example, some LED's) on your board. At the moment,
|
||||
the following checkpoints are implemented:
|
||||
|
||||
Arg Where When
|
||||
1 common/cmd_bootm.c before attempting to boot an image
|
||||
@@ -1240,23 +1241,23 @@ Modem Support:
|
||||
- Modem debug support:
|
||||
CONFIG_MODEM_SUPPORT_DEBUG
|
||||
|
||||
Enables debugging stuff (char screen[1024], dbg())
|
||||
for modem support. Useful only with BDI2000.
|
||||
Enables debugging stuff (char screen[1024], dbg())
|
||||
for modem support. Useful only with BDI2000.
|
||||
|
||||
- General:
|
||||
|
||||
In the target system modem support is enabled when a
|
||||
specific key (key combination) is pressed during
|
||||
power-on. Otherwise U-Boot will boot normally
|
||||
(autoboot). The key_pressed() fuction is called from
|
||||
board_init(). Currently key_pressed() is a dummy
|
||||
function, returning 1 and thus enabling modem
|
||||
initialization.
|
||||
In the target system modem support is enabled when a
|
||||
specific key (key combination) is pressed during
|
||||
power-on. Otherwise U-Boot will boot normally
|
||||
(autoboot). The key_pressed() fuction is called from
|
||||
board_init(). Currently key_pressed() is a dummy
|
||||
function, returning 1 and thus enabling modem
|
||||
initialization.
|
||||
|
||||
If there are no modem init strings in the
|
||||
environment, U-Boot proceed to autoboot; the
|
||||
previous output (banner, info printfs) will be
|
||||
supressed, though.
|
||||
If there are no modem init strings in the
|
||||
environment, U-Boot proceed to autoboot; the
|
||||
previous output (banner, info printfs) will be
|
||||
supressed, though.
|
||||
|
||||
See also: doc/README.Modem
|
||||
|
||||
@@ -1367,8 +1368,8 @@ Configuration Settings:
|
||||
downloaded image) this option may be very useful.
|
||||
|
||||
- CFG_FLASH_CFI:
|
||||
Define if the flash driver uses extra elements in the
|
||||
common flash structure for storing flash geometry
|
||||
Define if the flash driver uses extra elements in the
|
||||
common flash structure for storing flash geometry
|
||||
|
||||
The following definitions that deal with the placement and management
|
||||
of environment data (variable area); in general, we support the
|
||||
@@ -1434,10 +1435,10 @@ following configurations:
|
||||
- CFG_ENV_ADDR_REDUND
|
||||
CFG_ENV_SIZE_REDUND
|
||||
|
||||
These settings describe a second storage area used to hold
|
||||
a redundand copy of the environment data, so that there is
|
||||
a valid backup copy in case there is a power failur during
|
||||
a "saveenv" operation.
|
||||
These settings describe a second storage area used to hold
|
||||
a redundand copy of the environment data, so that there is
|
||||
a valid backup copy in case there is a power failur during
|
||||
a "saveenv" operation.
|
||||
|
||||
BE CAREFUL! Any changes to the flash layout, and some changes to the
|
||||
source code will make it necessary to adapt <board>/u-boot.lds*
|
||||
@@ -1500,25 +1501,6 @@ to save the current settings.
|
||||
- CFG_EEPROM_SIZE:
|
||||
The size in bytes of the EEPROM device.
|
||||
|
||||
- CFG_I2C_EEPROM_ADDR:
|
||||
If defined, specified the chip address of the EEPROM device.
|
||||
The default address is zero.
|
||||
|
||||
- CFG_EEPROM_PAGE_WRITE_BITS:
|
||||
If defined, the number of bits used to address bytes in a
|
||||
single page in the EEPROM device. A 64 byte page, for example
|
||||
would require six bits.
|
||||
|
||||
- CFG_EEPROM_PAGE_WRITE_DELAY_MS:
|
||||
If defined, the number of milliseconds to delay between
|
||||
page writes. The default is zero milliseconds.
|
||||
|
||||
- CFG_I2C_EEPROM_ADDR_LEN:
|
||||
The length in bytes of the EEPROM memory array address. Note
|
||||
that this is NOT the chip address length!
|
||||
|
||||
- CFG_EEPROM_SIZE:
|
||||
The size in bytes of the EEPROM device.
|
||||
|
||||
- CFG_SPI_INIT_OFFSET
|
||||
|
||||
@@ -1574,19 +1556,19 @@ Low Level (hardware related) configuration options:
|
||||
|
||||
CFG_ISA_IO_OFFSET
|
||||
|
||||
defines the offset of register from address. It
|
||||
depends on which part of the data bus is connected to
|
||||
the fdc chipset. (default value 0)
|
||||
defines the offset of register from address. It
|
||||
depends on which part of the data bus is connected to
|
||||
the fdc chipset. (default value 0)
|
||||
|
||||
If CFG_ISA_IO_STRIDE CFG_ISA_IO_OFFSET and
|
||||
CFG_FDC_DRIVE_NUMBER are undefined, they take their
|
||||
default value.
|
||||
If CFG_ISA_IO_STRIDE CFG_ISA_IO_OFFSET and
|
||||
CFG_FDC_DRIVE_NUMBER are undefined, they take their
|
||||
default value.
|
||||
|
||||
if CFG_FDC_HW_INIT is defined, then the function
|
||||
fdc_hw_init() is called at the beginning of the FDC
|
||||
setup. fdc_hw_init() must be provided by the board
|
||||
source code. It is used to make hardware dependant
|
||||
initializations.
|
||||
if CFG_FDC_HW_INIT is defined, then the function
|
||||
fdc_hw_init() is called at the beginning of the FDC
|
||||
setup. fdc_hw_init() must be provided by the board
|
||||
source code. It is used to make hardware dependant
|
||||
initializations.
|
||||
|
||||
- CFG_IMMR: Physical address of the Internal Memory Mapped
|
||||
Register; DO NOT CHANGE! (11-4)
|
||||
@@ -1675,10 +1657,10 @@ Low Level (hardware related) configuration options:
|
||||
doc/README.MBX before setting this variable!
|
||||
|
||||
- CFG_CPM_POST_WORD_ADDR: (MPC8xx, MPC8260 only)
|
||||
Offset of the bootmode word in DPRAM used by post
|
||||
(Power On Self Tests). This definition overrides
|
||||
#define'd default value in commproc.h resp.
|
||||
cpm_8260.h.
|
||||
Offset of the bootmode word in DPRAM used by post
|
||||
(Power On Self Tests). This definition overrides
|
||||
#define'd default value in commproc.h resp.
|
||||
cpm_8260.h.
|
||||
|
||||
Building the Software:
|
||||
======================
|
||||
@@ -2353,6 +2335,46 @@ format!) to the "bootm" command:
|
||||
|
||||
bash#
|
||||
|
||||
More About U-Boot Image Types:
|
||||
------------------------------
|
||||
|
||||
U-Boot supports the following image types:
|
||||
|
||||
"Standalone Programs" are directly runnable in the environment
|
||||
provided by U-Boot; it is expected that (if they behave
|
||||
well) you can continue to work in U-Boot after return from
|
||||
the Standalone Program.
|
||||
"OS Kernel Images" are usually images of some Embedded OS which
|
||||
will take over control completely. Usually these programs
|
||||
will install their own set of exception handlers, device
|
||||
drivers, set up the MMU, etc. - this means, that you cannot
|
||||
expect to re-enter U-Boot except by resetting the CPU.
|
||||
"RAMDisk Images" are more or less just data blocks, and their
|
||||
parameters (address, size) are passed to an OS kernel that is
|
||||
being started.
|
||||
"Multi-File Images" contain several images, typically an OS
|
||||
(Linux) kernel image and one or more data images like
|
||||
RAMDisks. This construct is useful for instance when you want
|
||||
to boot over the network using BOOTP etc., where the boot
|
||||
server provides just a single image file, but you want to get
|
||||
for instance an OS kernel and a RAMDisk image.
|
||||
|
||||
"Multi-File Images" start with a list of image sizes, each
|
||||
image size (in bytes) specified by an "uint32_t" in network
|
||||
byte order. This list is terminated by an "(uint32_t)0".
|
||||
Immediately after the terminating 0 follow the images, one by
|
||||
one, all aligned on "uint32_t" boundaries (size rounded up to
|
||||
a multiple of 4 bytes).
|
||||
|
||||
"Firmware Images" are binary images containing firmware (like
|
||||
U-Boot or FPGA images) which usually will be programmed to
|
||||
flash memory.
|
||||
|
||||
"Script files" are command sequences that will be executed by
|
||||
U-Boot's command interpreter; this feature is especially
|
||||
useful when you configure U-Boot to use a real shell (hush)
|
||||
as command interpreter.
|
||||
|
||||
|
||||
Standalone HOWTO:
|
||||
=================
|
||||
@@ -2495,6 +2517,44 @@ models provide on-chip memory (like the IMMR area on MPC8xx and
|
||||
MPC826x processors), on others (parts of) the data cache can be
|
||||
locked as (mis-) used as memory, etc.
|
||||
|
||||
Chris Hallinan posted a good summy of these issues to the
|
||||
u-boot-users mailing list:
|
||||
|
||||
Subject: RE: [U-Boot-Users] RE: More On Memory Bank x (nothingness)?
|
||||
From: "Chris Hallinan" <clh@net1plus.com>
|
||||
Date: Mon, 10 Feb 2003 16:43:46 -0500 (22:43 MET)
|
||||
...
|
||||
|
||||
Correct me if I'm wrong, folks, but the way I understand it
|
||||
is this: Using DCACHE as initial RAM for Stack, etc, does not
|
||||
require any physical RAM backing up the cache. The cleverness
|
||||
is that the cache is being used as a temporary supply of
|
||||
necessary storage before the SDRAM controller is setup. It's
|
||||
beyond the scope of this list to expain the details, but you
|
||||
can see how this works by studying the cache architecture and
|
||||
operation in the architecture and processor-specific manuals.
|
||||
|
||||
OCM is On Chip Memory, which I believe the 405GP has 4K. It
|
||||
is another option for the system designer to use as an
|
||||
initial stack/ram area prior to SDRAM being available. Either
|
||||
option should work for you. Using CS 4 should be fine if your
|
||||
board designers haven't used it for something that would
|
||||
cause you grief during the initial boot! It is frequently not
|
||||
used.
|
||||
|
||||
CFG_INIT_RAM_ADDR should be somewhere that won't interfere
|
||||
with your processor/board/system design. The default value
|
||||
you will find in any recent u-boot distribution in
|
||||
Walnut405.h should work for you. I'd set it to a value larger
|
||||
than your SDRAM module. If you have a 64MB SDRAM module, set
|
||||
it above 400_0000. Just make sure your board has no resources
|
||||
that are supposed to respond to that address! That code in
|
||||
start.S has been around a while and should work as is when
|
||||
you get the config right.
|
||||
|
||||
-Chris Hallinan
|
||||
DS4.COM, Inc.
|
||||
|
||||
It is essential to remember this, since it has some impact on the C
|
||||
code for the initialization procedures:
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ int misc_init_r (void)
|
||||
}
|
||||
|
||||
|
||||
void pci_init (void)
|
||||
void pci_init_board (void)
|
||||
{
|
||||
#ifndef CONFIG_RAMBOOT
|
||||
articiaS_pci_init ();
|
||||
|
||||
@@ -102,7 +102,7 @@ int misc_init_f (void)
|
||||
*/
|
||||
struct pci_controller hose;
|
||||
|
||||
void pci_init (void)
|
||||
void pci_init_board (void)
|
||||
{
|
||||
pci_mpc824x_init(&hose);
|
||||
/* pci_dev_init(0); */
|
||||
|
||||
@@ -113,7 +113,7 @@ struct pci_controller hose = {
|
||||
#endif
|
||||
};
|
||||
|
||||
void pci_init(void)
|
||||
void pci_init_board(void)
|
||||
{
|
||||
pci_mpc824x_init(&hose);
|
||||
}
|
||||
|
||||
@@ -21,11 +21,10 @@
|
||||
*/
|
||||
|
||||
|
||||
extern long int spd_sdram (void);
|
||||
|
||||
#include <common.h>
|
||||
#include "ebony.h"
|
||||
#include <asm/processor.h>
|
||||
#include <spd_sdram.h>
|
||||
|
||||
#define BOOT_SMALL_FLASH 32 /* 00100000 */
|
||||
#define FLASH_ONBD_N 2 /* 00000010 */
|
||||
@@ -113,10 +112,9 @@ int checkboard (void)
|
||||
long int initdram (int board_type)
|
||||
{
|
||||
long dram_size = 0;
|
||||
extern long spd_sdram (void);
|
||||
|
||||
#if defined(CONFIG_SPD_EEPROM)
|
||||
dram_size = spd_sdram ();
|
||||
dram_size = spd_sdram (0);
|
||||
#else
|
||||
dram_size = fixed_sdram ();
|
||||
#endif
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
struct pci_controller local_hose;
|
||||
|
||||
void pci_init(void)
|
||||
void pci_init_board(void)
|
||||
{
|
||||
struct pci_controller* hose = (struct pci_controller *)&local_hose;
|
||||
u32 reg32;
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
struct pci_controller local_hose;
|
||||
|
||||
void pci_init(void)
|
||||
void pci_init_board(void)
|
||||
{
|
||||
struct pci_controller* hose = (struct pci_controller *)&local_hose;
|
||||
u16 reg16;
|
||||
|
||||
40
board/emk/top860/Makefile
Normal file
40
board/emk/top860/Makefile
Normal 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
|
||||
|
||||
#########################################################################
|
||||
490
board/emk/top860/flash.c
Normal file
490
board/emk/top860/flash.c
Normal file
@@ -0,0 +1,490 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* EMK Elektronik GmbH <www.emk-elektronik.de>
|
||||
* Reinhard Meyer <r.meyer@emk-elektronik.de>
|
||||
*
|
||||
* copied from the BMW Port - seems that its similiar enough
|
||||
* to be easily adaped ;) --- Well, it turned out to become a
|
||||
* merger between parts of the EMKstax Flash routines and the
|
||||
* BMW funtion frames...
|
||||
*
|
||||
* (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>
|
||||
|
||||
#define FLASH_WORD_SIZE unsigned short
|
||||
#define FLASH_WORD_WIDTH (sizeof (FLASH_WORD_SIZE))
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static int write_word (flash_info_t *info, ulong dest, ulong data);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* software product ID entry/exit
|
||||
*****************************************************************************/
|
||||
static void FlashProductIdMode (
|
||||
volatile FLASH_WORD_SIZE *b,
|
||||
int on_off)
|
||||
{
|
||||
b[0x5555] = 0xaa;
|
||||
b[0x2aaa] = 0x55;
|
||||
b[0x5555] = on_off ? 0x90 : 0xf0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* sector erase start
|
||||
*****************************************************************************/
|
||||
static void FlashSectorErase (
|
||||
volatile FLASH_WORD_SIZE *b,
|
||||
volatile FLASH_WORD_SIZE *a)
|
||||
{
|
||||
b[0x5555] = 0xaa;
|
||||
b[0x2aaa] = 0x55;
|
||||
b[0x5555] = 0x80;
|
||||
b[0x5555] = 0xaa;
|
||||
b[0x2aaa] = 0x55;
|
||||
a[0] = 0x30;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* program a word
|
||||
*****************************************************************************/
|
||||
static void FlashProgWord (
|
||||
volatile FLASH_WORD_SIZE *b,
|
||||
volatile FLASH_WORD_SIZE *a,
|
||||
FLASH_WORD_SIZE v)
|
||||
{
|
||||
b[0x5555] = 0xaa;
|
||||
b[0x2aaa] = 0x55;
|
||||
b[0x5555] = 0xa0;
|
||||
a[0] = v;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* reset bank, back to read mode
|
||||
*****************************************************************************/
|
||||
static void FlashReset (volatile FLASH_WORD_SIZE *b)
|
||||
{
|
||||
b[0] = 0xf0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* identify FLASH chip
|
||||
* this code is a stripped version of the FlashGetType() function in EMKstax
|
||||
*****************************************************************************/
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
volatile FLASH_WORD_SIZE * const flash = (volatile FLASH_WORD_SIZE *) CFG_FLASH_BASE;
|
||||
FLASH_WORD_SIZE manu, dev;
|
||||
flash_info_t * const pflinfo = &flash_info[0];
|
||||
int j;
|
||||
|
||||
/* get Id Bytes */
|
||||
FlashProductIdMode (flash, 1);
|
||||
manu = flash[0];
|
||||
dev = flash[1];
|
||||
FlashProductIdMode (flash, 0);
|
||||
|
||||
pflinfo->size = 0;
|
||||
pflinfo->sector_count = 0;
|
||||
pflinfo->flash_id = 0xffffffff;
|
||||
pflinfo->portwidth = FLASH_CFI_16BIT;
|
||||
pflinfo->chipwidth = FLASH_CFI_BY16;
|
||||
|
||||
switch (manu&0xff)
|
||||
{
|
||||
case 0x01: /* AMD */
|
||||
pflinfo->flash_id = FLASH_MAN_AMD;
|
||||
switch (dev&0xff)
|
||||
{
|
||||
case 0x49:
|
||||
pflinfo->size = 0x00200000;
|
||||
pflinfo->sector_count = 35;
|
||||
pflinfo->flash_id |= FLASH_AM160B;
|
||||
pflinfo->start[0] = CFG_FLASH_BASE;
|
||||
pflinfo->start[1] = CFG_FLASH_BASE + 0x4000;
|
||||
pflinfo->start[2] = CFG_FLASH_BASE + 0x6000;
|
||||
pflinfo->start[3] = CFG_FLASH_BASE + 0x8000;
|
||||
for (j = 4; j < 35; j++)
|
||||
{
|
||||
pflinfo->start[j] = CFG_FLASH_BASE + 0x00010000 * (j-3);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xf9:
|
||||
pflinfo->size = 0x00400000;
|
||||
pflinfo->sector_count = 71;
|
||||
pflinfo->flash_id |= FLASH_AM320B;
|
||||
pflinfo->start[0] = CFG_FLASH_BASE;
|
||||
pflinfo->start[1] = CFG_FLASH_BASE + 0x4000;
|
||||
pflinfo->start[2] = CFG_FLASH_BASE + 0x6000;
|
||||
pflinfo->start[3] = CFG_FLASH_BASE + 0x8000;
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
pflinfo->start[j] = CFG_FLASH_BASE + 0x00002000 * (j);
|
||||
}
|
||||
for (j = 8; j < 71; j++)
|
||||
{
|
||||
pflinfo->start[j] = CFG_FLASH_BASE + 0x00010000 * (j-7);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("unknown AMD dev=%x ", dev);
|
||||
pflinfo->flash_id |= FLASH_UNKNOWN;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("unknown manu=%x ", manu);
|
||||
}
|
||||
return pflinfo->size;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* print info about a FLASH
|
||||
*****************************************************************************/
|
||||
void flash_print_info (flash_info_t *info)
|
||||
{
|
||||
static const char unk[] = "Unknown";
|
||||
unsigned int i;
|
||||
const char *mfct=unk,
|
||||
*type=unk;
|
||||
|
||||
if(info->flash_id != FLASH_UNKNOWN)
|
||||
{
|
||||
switch (info->flash_id & FLASH_VENDMASK)
|
||||
{
|
||||
case FLASH_MAN_AMD:
|
||||
mfct = "AMD";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK)
|
||||
{
|
||||
case FLASH_AM160B:
|
||||
type = "AM29LV160B (16 Mbit, bottom boot sect)";
|
||||
break;
|
||||
case FLASH_AM320B:
|
||||
type = "AM29LV320B (32 Mbit, bottom boot sect)";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf (
|
||||
"\n Brand: %s Type: %s\n"
|
||||
" Size: %lu KB in %d Sectors\n",
|
||||
mfct,
|
||||
type,
|
||||
info->size >> 10,
|
||||
info->sector_count
|
||||
);
|
||||
|
||||
printf (" Sector Start Addresses:");
|
||||
|
||||
for (i = 0; i < info->sector_count; i++)
|
||||
{
|
||||
unsigned long size;
|
||||
unsigned int erased;
|
||||
unsigned long *flash = (unsigned long *) info->start[i];
|
||||
|
||||
/*
|
||||
* Check if whole sector is erased
|
||||
*/
|
||||
size =
|
||||
(i != (info->sector_count - 1)) ?
|
||||
(info->start[i + 1] - info->start[i]) >> 2 :
|
||||
(info->start[0] + info->size - info->start[i]) >> 2;
|
||||
|
||||
for (
|
||||
flash = (unsigned long *) info->start[i], erased = 1;
|
||||
(flash != (unsigned long *) info->start[i] + size) && erased;
|
||||
flash++
|
||||
)
|
||||
erased = *flash == ~0x0UL;
|
||||
|
||||
printf (
|
||||
"%s %08lX %s %s",
|
||||
(i % 5) ? "" : "\n ",
|
||||
info->start[i],
|
||||
erased ? "E" : " ",
|
||||
info->protect[i] ? "RO" : " "
|
||||
);
|
||||
}
|
||||
|
||||
puts ("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* erase one or more sectors
|
||||
*****************************************************************************/
|
||||
int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
{
|
||||
volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(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_MAN_STM | FLASH_AMD_COMP)))
|
||||
{
|
||||
printf ("Can't erase unknown flash type - 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");
|
||||
}
|
||||
|
||||
l_sect = -1;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect<=s_last; sect++)
|
||||
{
|
||||
if (info->protect[sect] == 0)
|
||||
{ /* not protected */
|
||||
FlashSectorErase ((FLASH_WORD_SIZE *)info->start[0], (FLASH_WORD_SIZE *)info->start[sect]);
|
||||
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 = (FLASH_WORD_SIZE *)info->start[l_sect];
|
||||
while ((addr[0] & 0x0080) != 0x0080)
|
||||
{
|
||||
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 */
|
||||
serial_putc ('.');
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
|
||||
DONE:
|
||||
/* reset to read mode */
|
||||
FlashReset ((FLASH_WORD_SIZE *)info->start[0]);
|
||||
|
||||
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 & ~(FLASH_WORD_WIDTH-1)); /* get lower word aligned address */
|
||||
|
||||
/*
|
||||
* handle unaligned start bytes, if there are...
|
||||
*/
|
||||
if ((l = addr - wp) != 0)
|
||||
{
|
||||
data = 0;
|
||||
|
||||
/* get the current before the new data into our data word */
|
||||
for (i=0, cp=wp; i<l; ++i, ++cp)
|
||||
{
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
}
|
||||
|
||||
/* now merge the to be programmed values */
|
||||
for (; i<4 && cnt>0; ++i, ++cp, --cnt)
|
||||
{
|
||||
data = (data << 8) | *src++;
|
||||
}
|
||||
|
||||
/* get the current after the new data into our data word */
|
||||
for (; cnt==0 && i<FLASH_WORD_WIDTH; ++i, ++cp)
|
||||
{
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
}
|
||||
|
||||
/* now write the combined word */
|
||||
if ((rc = write_word (info, wp, data)) != 0)
|
||||
{
|
||||
return (rc);
|
||||
}
|
||||
wp += FLASH_WORD_WIDTH;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle word aligned part
|
||||
*/
|
||||
while (cnt >= FLASH_WORD_WIDTH)
|
||||
{
|
||||
data = 0;
|
||||
for (i=0; i<FLASH_WORD_WIDTH; ++i)
|
||||
{
|
||||
data = (data << 8) | *src++;
|
||||
}
|
||||
if ((rc = write_word (info, wp, data)) != 0)
|
||||
{
|
||||
return (rc);
|
||||
}
|
||||
wp += FLASH_WORD_WIDTH;
|
||||
cnt -= FLASH_WORD_WIDTH;
|
||||
}
|
||||
|
||||
if (cnt == 0)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* handle unaligned tail bytes, if there are...
|
||||
*/
|
||||
data = 0;
|
||||
|
||||
/* now merge the to be programmed values */
|
||||
for (i=0, cp=wp; i<FLASH_WORD_WIDTH && cnt>0; ++i, ++cp)
|
||||
{
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
}
|
||||
|
||||
/* get the current after the new data into our data word */
|
||||
for (; i<FLASH_WORD_WIDTH; ++i, ++cp)
|
||||
{
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
}
|
||||
|
||||
/* now write the combined word */
|
||||
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)
|
||||
{
|
||||
volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)info->start[0];
|
||||
volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *)dest;
|
||||
FLASH_WORD_SIZE data2 = data;
|
||||
ulong start;
|
||||
int flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*dest2 & data2) != data2)
|
||||
{
|
||||
return (2);
|
||||
}
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
|
||||
FlashProgWord (addr2, dest2, data2);
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts ();
|
||||
|
||||
/* data polling for D7 */
|
||||
start = get_timer (0);
|
||||
while ((*dest2 & 0x0080) != (data2 & 0x0080))
|
||||
{
|
||||
if (get_timer (start) > CFG_FLASH_WRITE_TOUT)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
187
board/emk/top860/top860.c
Normal file
187
board/emk/top860/top860.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* EMK Elektronik GmbH <www.emk-elektronik.de>
|
||||
* Reinhard Meyer <r.meyer@emk-elektronik.de>
|
||||
*
|
||||
* Board specific routines for the TOP860
|
||||
*
|
||||
* - initialisation
|
||||
* - interface to VPD data (mac address, clock speeds)
|
||||
* - memory controller
|
||||
* - serial io initialisation
|
||||
* - ethernet io initialisation
|
||||
*
|
||||
* -----------------------------------------------------------------
|
||||
* 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 <commproc.h>
|
||||
#include <mpc8xx.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* UPM table for 60ns EDO RAM at 25 MHz bus/external clock
|
||||
*****************************************************************************/
|
||||
static const uint edo_60ns_25MHz_tbl[] = {
|
||||
|
||||
/* single read (offset 0x00 in upm ram) */
|
||||
0x0ff3fc04,0x08f3fc04,0x00f3fc04,0x00f3fc00,
|
||||
0x33f7fc07,0xfffffc05,0xfffffc05,0xfffffc05,
|
||||
/* burst read (offset 0x08 in upm ram) */
|
||||
0x0ff3fc04,0x08f3fc04,0x00f3fc0c,0x0ff3fc40,
|
||||
0x0cf3fc04,0x03f3fc48,0x0cf3fc04,0x03f3fc48,
|
||||
0x0cf3fc04,0x03f3fc00,0x3ff7fc07,0xfffffc05,
|
||||
0xfffffc05,0xfffffc05,0xfffffc05,0xfffffc05,
|
||||
/* single write (offset 0x18 in upm ram) */
|
||||
0x0ffffc04,0x08fffc04,0x30fffc00,0xf1fffc07,
|
||||
0xfffffc05,0xfffffc05,0xfffffc05,0xfffffc05,
|
||||
/* burst write (offset 0x20 in upm ram) */
|
||||
0x0ffffc04,0x08fffc00,0x00fffc04,0x03fffc4c,
|
||||
0x00fffc00,0x07fffc4c,0x00fffc00,0x0ffffc4c,
|
||||
0x00fffc00,0x3ffffc07,0xfffffc05,0xfffffc05,
|
||||
0xfffffc05,0xfffffc05,0xfffffc05,0xfffffc05,
|
||||
/* refresh (offset 0x30 in upm ram) */
|
||||
0xc0fffc04,0x07fffc04,0x0ffffc04,0x0ffffc04,
|
||||
0xfffffc05,0xfffffc05,0xfffffc05,0xfffffc05,
|
||||
0xfffffc05,0xfffffc05,0xfffffc05,0xfffffc05,
|
||||
/* exception (offset 0x3C in upm ram) */
|
||||
0xfffffc07,0xfffffc03,0xfffffc05,0xfffffc05,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Print Board Identity
|
||||
*****************************************************************************/
|
||||
int checkboard (void)
|
||||
{
|
||||
puts ("Board:"CONFIG_IDENT_STRING"\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Initialize DRAM controller
|
||||
*****************************************************************************/
|
||||
long int initdram (int board_type)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
volatile memctl8xx_t *memctl = &immap->im_memctl;
|
||||
|
||||
/*
|
||||
* Only initialize memory controller when running from FLASH.
|
||||
* When running from RAM, don't touch it.
|
||||
*/
|
||||
if ((ulong) initdram & 0xff000000)
|
||||
{
|
||||
volatile uint *addr1, *addr2;
|
||||
uint i, j;
|
||||
|
||||
upmconfig (UPMA, (uint *) edo_60ns_25MHz_tbl,
|
||||
sizeof (edo_60ns_25MHz_tbl) / sizeof (uint));
|
||||
memctl->memc_mptpr = 0x0200;
|
||||
memctl->memc_mamr = 0x0ca20330;
|
||||
memctl->memc_or2 = -CFG_DRAM_MAX | OR_CSNT_SAM;
|
||||
memctl->memc_br2 = CFG_DRAM_BASE | BR_MS_UPMA | BR_V;
|
||||
/*
|
||||
* Do 8 read accesses to DRAM
|
||||
*/
|
||||
addr1 = (volatile uint*) 0;
|
||||
addr2 = (volatile uint*) 0x00400000;
|
||||
for (i=0, j=0; i<8; i++)
|
||||
j = addr1[0];
|
||||
|
||||
/*
|
||||
* Now check whether we got 4MB or 16MB populated
|
||||
*/
|
||||
addr1[0] = 0x12345678;
|
||||
addr1[1] = 0x9abcdef0;
|
||||
addr2[0] = 0xfeedc0de;
|
||||
addr2[1] = 0x47110815;
|
||||
if (addr1[0] == 0xfeedc0de && addr1[1] == 0x47110815)
|
||||
{
|
||||
/* only 4MB populated */
|
||||
memctl->memc_or2 = -(CFG_DRAM_MAX/4) | OR_CSNT_SAM;
|
||||
}
|
||||
}
|
||||
|
||||
return -(memctl->memc_or2 & 0xffff0000);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* otherinits after RAM is there and we are relocated to RAM
|
||||
* note: though this is an int function, nobody cares for the result!
|
||||
*****************************************************************************/
|
||||
int misc_init_r (void)
|
||||
{
|
||||
/* read 'factory' part of EEPROM */
|
||||
uchar buf[81];
|
||||
uchar *p;
|
||||
uint length;
|
||||
uint addr;
|
||||
uint len;
|
||||
|
||||
/* get length first */
|
||||
addr = CFG_FACT_OFFSET;
|
||||
if (eeprom_read (CFG_I2C_FACT_ADDR, addr, buf, 2))
|
||||
{
|
||||
bailout:
|
||||
printf ("cannot read factory configuration\n");
|
||||
printf ("be sure to set ethaddr yourself!\n");
|
||||
return 0;
|
||||
}
|
||||
length = buf[0] + (buf[1]<<8);
|
||||
addr += 2;
|
||||
|
||||
/* sanity check */
|
||||
if (length < 20 || length > CFG_FACT_SIZE-2)
|
||||
goto bailout;
|
||||
|
||||
/* read lines */
|
||||
while (length > 0)
|
||||
{
|
||||
/* read one line */
|
||||
len = length > 80 ? 80 : length;
|
||||
if (eeprom_read (CFG_I2C_FACT_ADDR, addr, buf, len))
|
||||
goto bailout;
|
||||
/* mark end of buffer */
|
||||
buf[len] = 0;
|
||||
/* search end of line */
|
||||
for (p=buf; *p && *p != 0x0a; p++) ;
|
||||
if (!*p)
|
||||
goto bailout;
|
||||
*p++ = 0;
|
||||
/* advance to next line start */
|
||||
length -= p-buf;
|
||||
addr += p-buf;
|
||||
/*printf ("%s\n", buf);*/
|
||||
/* search for our specific entry */
|
||||
if (!strncmp ((char *)buf, "[RLA/lan/Ethernet] ", 19))
|
||||
{
|
||||
setenv ("ethaddr", buf+19);
|
||||
}
|
||||
else if (!strncmp ((char *)buf, "[BOARD/SERIAL] ", 15))
|
||||
{
|
||||
setenv ("serial#", buf+15);
|
||||
}
|
||||
else if (!strncmp ((char *)buf, "[BOARD/TYPE] ", 13))
|
||||
{
|
||||
setenv ("board_id", buf+13);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
122
board/emk/top860/u-boot.lds
Normal file
122
board/emk/top860/u-boot.lds
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* (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 :
|
||||
{
|
||||
cpu/mpc8xx/start.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 = .);
|
||||
}
|
||||
|
||||
132
board/emk/top860/u-boot.lds.debug
Normal file
132
board/emk/top860/u-boot.lds.debug
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* (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)
|
||||
lib_ppc/extable.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 = .);
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ static struct pci_controller pci9054_hose = {
|
||||
config_table: pci9054_config_table,
|
||||
};
|
||||
|
||||
void pci_init(void)
|
||||
void pci_init_board(void)
|
||||
{
|
||||
struct pci_controller *hose = &pci9054_hose;
|
||||
|
||||
|
||||
@@ -315,8 +315,10 @@ int misc_init_r (void)
|
||||
}
|
||||
|
||||
void
|
||||
after_reloc(gd_t *gd, ulong dest_addr)
|
||||
after_reloc(ulong dest_addr)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* check to see if we booted from the sram. If so, move things
|
||||
* back to the way they should be. (we're running from main
|
||||
* memory at this point now */
|
||||
|
||||
@@ -52,6 +52,7 @@ static const unsigned int pci_scs_bank_size[2][4] = {
|
||||
static const unsigned int pci_p2p_configuration[] = {
|
||||
PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION};
|
||||
|
||||
static unsigned int local_buses[] = { 0, 0};
|
||||
/********************************************************************
|
||||
* pciWriteConfigReg - Write to a PCI configuration register
|
||||
* - Make sure the GT is configured as a master before writing
|
||||
@@ -74,7 +75,7 @@ void pciWriteConfigReg(PCI_HOST host, unsigned int regOffset,unsigned int pciDev
|
||||
{
|
||||
volatile unsigned int DataForAddrReg;
|
||||
unsigned int functionNum;
|
||||
unsigned int busNum = 0;
|
||||
unsigned int busNum = PCI_BUS(pciDevNum);
|
||||
unsigned int addr;
|
||||
|
||||
if(pciDevNum > 32) /* illegal device Number */
|
||||
@@ -117,7 +118,7 @@ unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset,unsigned in
|
||||
volatile unsigned int DataForAddrReg;
|
||||
unsigned int data;
|
||||
unsigned int functionNum;
|
||||
unsigned int busNum = 0;
|
||||
unsigned int busNum = PCI_BUS(pciDevNum);
|
||||
|
||||
if(pciDevNum > 32) /* illegal device Number */
|
||||
return 0xffffffff;
|
||||
@@ -531,16 +532,32 @@ static int gt_read_config_dword(struct pci_controller *hose,
|
||||
pci_dev_t dev,
|
||||
int offset, u32* value)
|
||||
{
|
||||
*value = pciReadConfigReg((PCI_HOST) hose->cfg_addr, offset, PCI_DEV(dev));
|
||||
return 0;
|
||||
int bus = PCI_BUS(dev);
|
||||
|
||||
if ((bus == local_buses[0]) || (bus == local_buses[1])){
|
||||
*value = pciReadConfigReg((PCI_HOST) hose->cfg_addr, offset,
|
||||
PCI_DEV(dev));
|
||||
} else {
|
||||
*value = pciOverBridgeReadConfigReg((PCI_HOST) hose->cfg_addr,
|
||||
offset, PCI_DEV(dev), bus);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gt_write_config_dword(struct pci_controller *hose,
|
||||
pci_dev_t dev,
|
||||
int offset, u32 value)
|
||||
{
|
||||
pciWriteConfigReg((PCI_HOST)hose->cfg_addr, offset, PCI_DEV(dev), value);
|
||||
return 0;
|
||||
int bus = PCI_BUS(dev);
|
||||
|
||||
if ((bus == local_buses[0]) || (bus == local_buses[1])){
|
||||
pciWriteConfigReg((PCI_HOST)hose->cfg_addr, offset,
|
||||
PCI_DEV(dev), value);
|
||||
} else {
|
||||
pciOverBridgeWriteConfigReg((PCI_HOST)hose->cfg_addr, offset,
|
||||
PCI_DEV(dev), value, bus);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -597,13 +614,13 @@ struct pci_controller pci1_hose = {
|
||||
};
|
||||
|
||||
void
|
||||
pci_init(void)
|
||||
pci_init_board(void)
|
||||
{
|
||||
unsigned int command;
|
||||
|
||||
pci0_hose.first_busno = 0;
|
||||
pci0_hose.last_busno = 0xff;
|
||||
|
||||
local_buses[0] = pci0_hose.first_busno;
|
||||
/* PCI memory space */
|
||||
pci_set_region(pci0_hose.regions + 0,
|
||||
CFG_PCI0_0_MEM_SPACE,
|
||||
@@ -647,6 +664,8 @@ pci_init(void)
|
||||
|
||||
pci1_hose.first_busno = pci0_hose.last_busno + 1;
|
||||
pci1_hose.last_busno = 0xff;
|
||||
pci1_hose.current_busno = pci0_hose.current_busno;
|
||||
local_buses[1] = pci1_hose.first_busno;
|
||||
|
||||
/* PCI memory space */
|
||||
pci_set_region(pci1_hose.regions + 0,
|
||||
|
||||
47
board/innokom/Makefile
Normal file
47
board/innokom/Makefile
Normal file
@@ -0,0 +1,47 @@
|
||||
#
|
||||
# (C) Copyright 2000
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS := innokom.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
|
||||
|
||||
#########################################################################
|
||||
16
board/innokom/config.mk
Normal file
16
board/innokom/config.mk
Normal file
@@ -0,0 +1,16 @@
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
||||
# This is the address where U-Boot lives in flash:
|
||||
#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 = 0xa1fe0000
|
||||
|
||||
377
board/innokom/flash.c
Normal file
377
board/innokom/flash.c
Normal file
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
* (C) Copyright 2002
|
||||
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Robert Schwebel, Pengutronix, <r.schwebel@pengutronix.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 <asm/arch/pxa-regs.h>
|
||||
|
||||
#define FLASH_BANK_SIZE 0x02000000
|
||||
#define MAIN_SECT_SIZE 0x40000 /* 2x16 = 256k per sector */
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
|
||||
|
||||
|
||||
/**
|
||||
* flash_init: - initialize data structures for flash chips
|
||||
*
|
||||
* @return: size of the flash
|
||||
*/
|
||||
|
||||
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 =
|
||||
(INTEL_MANUFACT & FLASH_VENDMASK) |
|
||||
(INTEL_ID_28F128J3 & 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;
|
||||
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]);
|
||||
|
||||
#ifdef CFG_ENV_IS_IN_FLASH
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
|
||||
&flash_info[0]);
|
||||
#endif
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* flash_print_info: - print information about the flash situation
|
||||
*
|
||||
* @param info:
|
||||
*/
|
||||
|
||||
void flash_print_info (flash_info_t *info)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (j=0; j<CFG_MAX_FLASH_BANKS; j++) {
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
|
||||
case (INTEL_MANUFACT & FLASH_VENDMASK):
|
||||
printf("Intel: ");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown Vendor ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
|
||||
case (INTEL_ID_28F128J3 & FLASH_TYPEMASK):
|
||||
printf("28F128J3 (128Mbit)\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown Chip Type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
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");
|
||||
info++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* flash_erase: - erase flash sectors
|
||||
*
|
||||
*/
|
||||
|
||||
int flash_erase(flash_info_t *info, int s_first, int s_last)
|
||||
{
|
||||
int flag, prot, sect;
|
||||
int rc = ERR_OK;
|
||||
|
||||
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) != (INTEL_MANUFACT & FLASH_VENDMASK))
|
||||
return ERR_UNKNOWN_FLASH_VENDOR;
|
||||
|
||||
prot = 0;
|
||||
for (sect=s_first; sect<=s_last; ++sect) {
|
||||
if (info->protect[sect]) prot++;
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
flag = 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 */
|
||||
u32 * volatile addr = (u32 * volatile)(info->start[sect]);
|
||||
|
||||
/* erase sector: */
|
||||
/* The strata flashs are aligned side by side on */
|
||||
/* the data bus, so we have to write the commands */
|
||||
/* to both chips here: */
|
||||
|
||||
*addr = 0x00200020; /* erase setup */
|
||||
*addr = 0x00D000D0; /* erase confirm */
|
||||
|
||||
while ((*addr & 0x00800080) != 0x00800080) {
|
||||
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
|
||||
*addr = 0x00B000B0; /* suspend erase*/
|
||||
*addr = 0x00FF00FF; /* read mode */
|
||||
rc = ERR_TIMOUT;
|
||||
goto outahere;
|
||||
}
|
||||
}
|
||||
|
||||
*addr = 0x00500050; /* clear status register cmd. */
|
||||
*addr = 0x00FF00FF; /* resest to read mode */
|
||||
|
||||
}
|
||||
|
||||
printf("ok.\n");
|
||||
}
|
||||
|
||||
if (ctrlc()) printf("User Interrupt!\n");
|
||||
|
||||
outahere:
|
||||
|
||||
/* allow flash to settle - wait 10 ms */
|
||||
udelay_masked(10000);
|
||||
|
||||
if (flag) enable_interrupts();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* write_word: - copy memory to flash
|
||||
*
|
||||
* @param info:
|
||||
* @param dest:
|
||||
* @param data:
|
||||
* @return:
|
||||
*/
|
||||
|
||||
static int write_word (flash_info_t *info, ulong dest, ushort data)
|
||||
{
|
||||
ushort *addr = (ushort *)dest, val;
|
||||
int rc = ERR_OK;
|
||||
int flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*addr & 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.
|
||||
*/
|
||||
flag = disable_interrupts();
|
||||
|
||||
/* clear status register command */
|
||||
*addr = 0x50;
|
||||
|
||||
/* program set-up command */
|
||||
*addr = 0x40;
|
||||
|
||||
/* latch address/data */
|
||||
*addr = data;
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked();
|
||||
|
||||
/* wait while polling the status register */
|
||||
while(((val = *addr) & 0x80) != 0x80) {
|
||||
if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
|
||||
rc = ERR_TIMOUT;
|
||||
*addr = 0xB0; /* suspend program command */
|
||||
goto outahere;
|
||||
}
|
||||
}
|
||||
|
||||
if(val & 0x1A) { /* check for error */
|
||||
printf("\nFlash write error %02x at address %08lx\n",
|
||||
(int)val, (unsigned long)dest);
|
||||
if(val & (1<<3)) {
|
||||
printf("Voltage range error.\n");
|
||||
rc = ERR_PROG_ERROR;
|
||||
goto outahere;
|
||||
}
|
||||
if(val & (1<<1)) {
|
||||
printf("Device protect error.\n");
|
||||
rc = ERR_PROTECTED;
|
||||
goto outahere;
|
||||
}
|
||||
if(val & (1<<4)) {
|
||||
printf("Programming error.\n");
|
||||
rc = ERR_PROG_ERROR;
|
||||
goto outahere;
|
||||
}
|
||||
rc = ERR_PROG_ERROR;
|
||||
goto outahere;
|
||||
}
|
||||
|
||||
outahere:
|
||||
|
||||
*addr = 0xFF; /* read array command */
|
||||
if (flag) enable_interrupts();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
ushort 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 = *((ushort*)src);
|
||||
if ((rc = write_word(info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
src += 2;
|
||||
wp += 2;
|
||||
cnt -= 2;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
139
board/innokom/innokom.c
Normal file
139
board/innokom/innokom.c
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* (C) Copyright 2002
|
||||
* Robert Schwebel, Pengutronix, r.schwebel@pengutronix.de
|
||||
* Kyle Harris, Nexus Technologies, Inc., kharris@nexus-tech.net
|
||||
* Marius Groeger, Sysgo Real-Time Solutions GmbH, mgroeger@sysgo.de
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
|
||||
#ifdef CONFIG_SHOW_BOOT_PROGRESS
|
||||
# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
|
||||
#else
|
||||
# define SHOW_BOOT_PROGRESS(arg)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Miscelaneous platform dependent initialisations
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
|
||||
/* arch number of Innokom board */
|
||||
gd->bd->bi_arch_number = 258;
|
||||
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = 0xa0000100;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* innokom_set_led: - switch LEDs on or off
|
||||
*
|
||||
* @param led: LED to switch (0,1,2)
|
||||
* @param state: switch on (1) or off (0)
|
||||
*/
|
||||
|
||||
void innokom_set_led(int led, int state)
|
||||
{
|
||||
switch(led) {
|
||||
/*
|
||||
case 0: if (state==1) {
|
||||
GPCR0 |= CSB226_USER_LED0;
|
||||
} else if (state==0) {
|
||||
GPSR0 |= CSB226_USER_LED0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: if (state==1) {
|
||||
GPCR0 |= CSB226_USER_LED1;
|
||||
} else if (state==0) {
|
||||
GPSR0 |= CSB226_USER_LED1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: if (state==1) {
|
||||
GPCR0 |= CSB226_USER_LED2;
|
||||
} else if (state==0) {
|
||||
GPSR0 |= CSB226_USER_LED2;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* show_boot_progress: - indicate state of the boot process
|
||||
*
|
||||
* @param status: Status number - see README for details.
|
||||
*
|
||||
* The CSB226 does only have 3 LEDs, so we switch them on at the most
|
||||
* important states (1, 5, 15).
|
||||
*/
|
||||
|
||||
void show_boot_progress (int status)
|
||||
{
|
||||
switch(status) {
|
||||
/*
|
||||
case 1: csb226_set_led(0,1); break;
|
||||
case 5: csb226_set_led(1,1); break;
|
||||
case 15: csb226_set_led(2,1); break;
|
||||
*/
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
429
board/innokom/memsetup.S
Normal file
429
board/innokom/memsetup.S
Normal file
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
|
||||
/*
|
||||
* 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??? */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* 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 + DIR field. */
|
||||
|
||||
ldr r4, =0x03ca4fff
|
||||
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
|
||||
ldr r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
ldr r4, =0x03ca4030
|
||||
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
|
||||
ldr r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
/* Note: preserve the mdrefr value in r4 */
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* 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:K1RUN and MDREFR:K2RUN and configure */
|
||||
/* MDREFR:K1DB2 and MDREFR:K2DB2 as desired. */
|
||||
|
||||
orr r4, r4, #(MDREFR_K1RUN|MDREFR_K0RUN)
|
||||
|
||||
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. */
|
||||
|
||||
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]
|
||||
|
||||
|
||||
/* 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 */
|
||||
|
||||
#define NODEBUG
|
||||
#ifdef NODEBUG
|
||||
/*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
|
||||
|
||||
53
board/innokom/u-boot.lds
Normal file
53
board/innokom/u-boot.lds
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* (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/xscale/start.o (.text)
|
||||
*(.text)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(.rodata) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : { *(.data) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.got : { *(.got) }
|
||||
|
||||
armboot_end_data = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
.bss : { *(.bss) }
|
||||
|
||||
armboot_end = .;
|
||||
}
|
||||
@@ -1,12 +1,3 @@
|
||||
#
|
||||
# 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 = 0xa1700000
|
||||
TEXT_BASE = 0xa3000000
|
||||
#TEXT_BASE = 0
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/*
|
||||
* (C) Copyright 2002
|
||||
* (C) Copyright 2001
|
||||
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
* (C) Copyright 2001
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
@@ -26,46 +25,62 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/byteorder/swab.h>
|
||||
|
||||
#define FLASH_BANK_SIZE 0x2000000
|
||||
#define MAIN_SECT_SIZE 0x40000 /* 2x16 = 256k per sector */
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
/* Board support for 1 or 2 flash devices */
|
||||
#define FLASH_PORT_WIDTH32
|
||||
#undef FLASH_PORT_WIDTH16
|
||||
|
||||
#ifdef FLASH_PORT_WIDTH16
|
||||
#define FLASH_PORT_WIDTH ushort
|
||||
#define FLASH_PORT_WIDTHV vu_short
|
||||
#define SWAP(x) __swab16(x)
|
||||
#else
|
||||
#define FLASH_PORT_WIDTH ulong
|
||||
#define FLASH_PORT_WIDTHV vu_long
|
||||
#define SWAP(x) __swab32(x)
|
||||
#endif
|
||||
|
||||
#define FPW FLASH_PORT_WIDTH
|
||||
#define FPWV FLASH_PORT_WIDTHV
|
||||
|
||||
#define mb() __asm__ __volatile__ ("" : : : "memory")
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static ulong flash_get_size (FPW *addr, flash_info_t *info);
|
||||
static int write_data (flash_info_t *info, ulong dest, FPW data);
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info);
|
||||
void inline spin_wheel(void);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
ulong flash_init(void)
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
ulong size = 0;
|
||||
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
|
||||
{
|
||||
ulong flashbase = 0;
|
||||
flash_info[i].flash_id =
|
||||
(INTEL_MANUFACT & FLASH_VENDMASK) |
|
||||
(INTEL_ID_28F128J3 & 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;
|
||||
flash_get_size((FPW *)PHYS_FLASH_1, &flash_info[i]);
|
||||
flash_get_offsets(PHYS_FLASH_1, &flash_info[i]);
|
||||
break;
|
||||
case 1:
|
||||
flashbase = PHYS_FLASH_2;
|
||||
flash_get_size((FPW *)PHYS_FLASH_2, &flash_info[i]);
|
||||
flash_get_offsets(PHYS_FLASH_2, &flash_info[i]);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -84,73 +99,142 @@ ulong flash_init(void)
|
||||
return size;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
|
||||
info->protect[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
void flash_print_info (flash_info_t *info)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
for (j=0; j<CFG_MAX_FLASH_BANKS; j++)
|
||||
{
|
||||
switch (info->flash_id & FLASH_VENDMASK)
|
||||
{
|
||||
case (INTEL_MANUFACT & FLASH_VENDMASK):
|
||||
printf("Intel: ");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown Vendor ");
|
||||
break;
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("missing or unknown FLASH type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK)
|
||||
{
|
||||
case (INTEL_ID_28F128J3 & FLASH_TYPEMASK):
|
||||
printf("28F128J3 (128Mbit)\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown Chip Type\n");
|
||||
goto Done;
|
||||
break;
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_INTEL: printf ("INTEL "); break;
|
||||
default: printf ("Unknown Vendor "); break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_28F128J3A:
|
||||
printf ("28F128J3A\n"); break;
|
||||
default: printf ("Unknown Chip Type\n"); break;
|
||||
}
|
||||
|
||||
printf(" Size: %ld MB in %d Sectors\n",
|
||||
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++)
|
||||
{
|
||||
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 (" %08lX%s",
|
||||
info->start[i],
|
||||
info->protect[i] ? " (RO)" : " "
|
||||
);
|
||||
}
|
||||
printf ("\n");
|
||||
info++;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
static ulong flash_get_size (FPW *addr, flash_info_t *info)
|
||||
{
|
||||
volatile FPW value;
|
||||
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
addr[0x5555] = (FPW)0x00AA00AA;
|
||||
addr[0x2AAA] = (FPW)0x00550055;
|
||||
addr[0x5555] = (FPW)0x00900090;
|
||||
|
||||
mb();
|
||||
value = addr[0];
|
||||
|
||||
switch (value) {
|
||||
|
||||
case (FPW)INTEL_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_INTEL;
|
||||
break;
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
addr[0] = (FPW)0x00FF00FF; /* restore read mode */
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
mb();
|
||||
value = addr[1]; /* device ID */
|
||||
|
||||
switch (value) {
|
||||
|
||||
case (FPW)INTEL_ID_28F128J3A:
|
||||
info->flash_id += FLASH_28F128J3A;
|
||||
info->sector_count = 128;
|
||||
info->size = 0x02000000;
|
||||
break; /* => 16 MB */
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Done:
|
||||
addr[0] = (FPW)0x00FF00FF; /* restore read mode */
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
{
|
||||
int flag, prot, sect;
|
||||
int rc = ERR_OK;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN)
|
||||
return ERR_UNKNOWN_FLASH_TYPE;
|
||||
ulong type, start, now, last;
|
||||
int rcode = 0;
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
return ERR_INVAL;
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("- missing\n");
|
||||
} else {
|
||||
printf ("- no sectors to erase\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) !=
|
||||
(INTEL_MANUFACT & FLASH_VENDMASK)) {
|
||||
return ERR_UNKNOWN_FLASH_VENDOR;
|
||||
type = (info->flash_id & FLASH_VENDMASK);
|
||||
if ((type != FLASH_MAN_INTEL)) {
|
||||
printf ("Can't erase unknown flash type %08lx - aborted\n",
|
||||
info->flash_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
@@ -159,153 +243,79 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
prot++;
|
||||
}
|
||||
}
|
||||
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.
|
||||
*/
|
||||
if (prot) {
|
||||
printf ("- Warning: %d protected sectors will not be erased!\n",
|
||||
prot);
|
||||
} else {
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
start = get_timer (0);
|
||||
last = start;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
|
||||
for (sect = s_first; sect<=s_last; sect++) {
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
FPWV *addr = (FPWV *)(info->start[sect]);
|
||||
FPW status;
|
||||
|
||||
printf("Erasing sector %2d ... ", sect);
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked();
|
||||
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
vu_short *addr = (vu_short *)(info->start[sect]);
|
||||
*addr = (FPW)0x00500050; /* clear status register */
|
||||
*addr = (FPW)0x00200020; /* erase setup */
|
||||
*addr = (FPW)0x00D000D0; /* erase confirm */
|
||||
|
||||
*addr = 0x20; /* erase setup */
|
||||
*addr = 0xD0; /* erase confirm */
|
||||
|
||||
while ((*addr & 0x80) != 0x80) {
|
||||
while (((status = *addr) & (FPW)0x00800080) != (FPW)0x00800080) {
|
||||
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
|
||||
*addr = 0xB0; /* suspend erase */
|
||||
*addr = 0xFF; /* reset to read mode */
|
||||
rc = ERR_TIMOUT;
|
||||
goto outahere;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear status register command */
|
||||
*addr = 0x50;
|
||||
/* reset to read mode */
|
||||
*addr = 0xFF;
|
||||
}
|
||||
printf("ok.\n");
|
||||
}
|
||||
if (ctrlc())
|
||||
printf("User Interrupt!\n");
|
||||
|
||||
outahere:
|
||||
|
||||
/* allow flash to settle - wait 10 ms */
|
||||
udelay_masked(10000);
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash
|
||||
*/
|
||||
|
||||
static int write_word (flash_info_t *info, ulong dest, ushort data)
|
||||
{
|
||||
vu_short *addr = (vu_short *)dest, val;
|
||||
int rc = ERR_OK;
|
||||
int flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased
|
||||
*/
|
||||
if ((*addr & 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.
|
||||
*/
|
||||
flag = disable_interrupts();
|
||||
|
||||
/* clear status register command */
|
||||
*addr = 0x50;
|
||||
|
||||
/* program set-up command */
|
||||
*addr = 0x40;
|
||||
|
||||
/* latch address/data */
|
||||
*addr = data;
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked();
|
||||
|
||||
/* wait while polling the status register */
|
||||
while(((val = *addr) & 0x80) != 0x80)
|
||||
{
|
||||
if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
|
||||
rc = ERR_TIMOUT;
|
||||
/* suspend program command */
|
||||
*addr = 0xB0;
|
||||
goto outahere;
|
||||
printf ("Timeout\n");
|
||||
*addr = (FPW)0x00B000B0; /* suspend erase */
|
||||
*addr = (FPW)0x00FF00FF; /* reset to read mode */
|
||||
rcode = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(val & 0x1A) { /* check for error */
|
||||
printf("\nFlash write error %02x at address %08lx\n",
|
||||
(int)val, (unsigned long)dest);
|
||||
if(val & (1<<3)) {
|
||||
printf("Voltage range error.\n");
|
||||
rc = ERR_PROG_ERROR;
|
||||
goto outahere;
|
||||
}
|
||||
if(val & (1<<1)) {
|
||||
printf("Device protect error.\n");
|
||||
rc = ERR_PROTECTED;
|
||||
goto outahere;
|
||||
}
|
||||
if(val & (1<<4)) {
|
||||
printf("Programming error.\n");
|
||||
rc = ERR_PROG_ERROR;
|
||||
goto outahere;
|
||||
}
|
||||
rc = ERR_PROG_ERROR;
|
||||
goto outahere;
|
||||
}
|
||||
*addr = 0x00500050; /* clear status register cmd. */
|
||||
*addr = 0x00FF00FF; /* resest to read mode */
|
||||
|
||||
outahere:
|
||||
/* read array command */
|
||||
*addr = 0xFF;
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return rc;
|
||||
printf (" done\n");
|
||||
}
|
||||
}
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash.
|
||||
* Copy memory to flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
* 4 - Flash not identified
|
||||
*/
|
||||
|
||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong cp, wp;
|
||||
ushort data;
|
||||
int l;
|
||||
int i, rc;
|
||||
FPW data;
|
||||
int count, i, l, rc, port_width;
|
||||
|
||||
wp = (addr & ~1); /* get lower word aligned address */
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
return 4;
|
||||
}
|
||||
/* get lower word aligned address */
|
||||
#ifdef FLASH_PORT_WIDTH16
|
||||
wp = (addr & ~1);
|
||||
port_width = 2;
|
||||
#else
|
||||
wp = (addr & ~3);
|
||||
port_width = 4;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* handle unaligned start bytes
|
||||
@@ -313,51 +323,110 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
if ((l = addr - wp) != 0) {
|
||||
data = 0;
|
||||
for (i=0, cp=wp; i<l; ++i, ++cp) {
|
||||
data = (data >> 8) | (*(uchar *)cp << 8);
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
}
|
||||
for (; i<2 && cnt>0; ++i) {
|
||||
data = (data >> 8) | (*src++ << 8);
|
||||
for (; i<port_width && cnt>0; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
++cp;
|
||||
}
|
||||
for (; cnt==0 && i<2; ++i, ++cp) {
|
||||
data = (data >> 8) | (*(uchar *)cp << 8);
|
||||
for (; cnt==0 && i<port_width; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
}
|
||||
|
||||
if ((rc = write_word(info, wp, data)) != 0) {
|
||||
if ((rc = write_data(info, wp, SWAP(data))) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += 2;
|
||||
wp += port_width;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle word aligned part
|
||||
*/
|
||||
while (cnt >= 2) {
|
||||
data = *((vu_short*)src);
|
||||
if ((rc = write_word(info, wp, data)) != 0) {
|
||||
count = 0;
|
||||
while (cnt >= port_width) {
|
||||
data = 0;
|
||||
for (i=0; i<port_width; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
}
|
||||
if ((rc = write_data(info, wp, SWAP(data))) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
src += 2;
|
||||
wp += 2;
|
||||
cnt -= 2;
|
||||
wp += port_width;
|
||||
cnt -= port_width;
|
||||
if (count++ > 0x800)
|
||||
{
|
||||
spin_wheel();
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
return ERR_OK;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* handle unaligned tail bytes
|
||||
*/
|
||||
data = 0;
|
||||
for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) {
|
||||
data = (data >> 8) | (*src++ << 8);
|
||||
for (i=0, cp=wp; i<port_width && cnt>0; ++i, ++cp) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
}
|
||||
for (; i<2; ++i, ++cp) {
|
||||
data = (data >> 8) | (*(uchar *)cp << 8);
|
||||
for (; i<port_width; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
}
|
||||
|
||||
return (write_data(info, wp, SWAP(data)));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word or halfword to Flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
static int write_data (flash_info_t *info, ulong dest, FPW data)
|
||||
{
|
||||
FPWV *addr = (FPWV *)dest;
|
||||
ulong status;
|
||||
ulong start;
|
||||
int flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*addr & data) != data) {
|
||||
printf("not erased at %08lx (%x)\n",(ulong)addr,*addr);
|
||||
return (2);
|
||||
}
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
*addr = (FPW)0x00400040; /* write setup */
|
||||
*addr = data;
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked();
|
||||
|
||||
/* wait while polling the status register */
|
||||
while (((status = *addr) & (FPW)0x00800080) != (FPW)0x00800080) {
|
||||
if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
|
||||
*addr = (FPW)0x00FF00FF; /* restore read mode */
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
return write_word(info, wp, data);
|
||||
*addr = (FPW)0x00FF00FF; /* restore read mode */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void inline
|
||||
spin_wheel(void)
|
||||
{
|
||||
static int r=0,p=0;
|
||||
static char w[] = "\\/-";
|
||||
|
||||
printf("\010%c", w[p]);
|
||||
(++p == 3) ? (p = 0) : 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ int board_init (void)
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = 0xa0000100;
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init (void)
|
||||
@@ -62,6 +62,6 @@ int dram_init (void)
|
||||
gd->bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;
|
||||
gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
|
||||
gd->bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE;
|
||||
return PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE + PHYS_SDRAM_3_SIZE +
|
||||
PHYS_SDRAM_4_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -39,12 +39,16 @@ DRAM_SIZE: .long CFG_DRAM_SIZE
|
||||
.endm
|
||||
|
||||
|
||||
/*
|
||||
* Memory setup
|
||||
*/
|
||||
|
||||
.globl memsetup
|
||||
memsetup:
|
||||
|
||||
mov r10, lr
|
||||
|
||||
/* Set up GPIO pins first */
|
||||
/* Set up GPIO pins first ----------------------------------------- */
|
||||
|
||||
ldr r0, =GPSR0
|
||||
ldr r1, =CFG_GPSR0_VAL
|
||||
@@ -106,562 +110,284 @@ memsetup:
|
||||
ldr r1, =CFG_GAFR2_U_VAL
|
||||
str r1, [r0]
|
||||
|
||||
/* enable GPIO pins */
|
||||
ldr r0, =PSSR
|
||||
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) */
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Enable memory interface */
|
||||
/* */
|
||||
/* The sequence below is based on the recommended init steps */
|
||||
/* detailed in the Intel PXA250 Operating Systems Developers Guide, */
|
||||
/* Chapter 10. */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
ldr r1, =LED_BLANK
|
||||
mov r0, #0xFF
|
||||
str r0, [r1] /* turn on hex leds */
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Step 1: Wait for at least 200 microsedonds to allow internal */
|
||||
/* clocks to settle. Only necessary after hard reset... */
|
||||
/* FIXME: can be optimized later */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
loop:
|
||||
ldr r0, =0xB0070001
|
||||
ldr r1, =_LED
|
||||
str r0, [r1] /* hex display */
|
||||
|
||||
/*********************************************************************
|
||||
Initlialize Memory Controller
|
||||
The sequence below is based on the recommended init steps detailed
|
||||
in the EAS, chapter 5 (Chapter 10, Operating Systems Developers Guide)
|
||||
|
||||
|
||||
pause for 200 uSecs- allow internal clocks to settle
|
||||
*Note: only need this if hard reset... doing it anyway for now
|
||||
*/
|
||||
|
||||
@ ---- Wait 200 usec
|
||||
ldr r3, =OSCR @ reset the OS Timer Count to zero
|
||||
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
|
||||
ldr r4, =0x300 /* really 0x2E1 is about 200usec, */
|
||||
/* so 0x300 should be plenty */
|
||||
1:
|
||||
ldr r2, [r3]
|
||||
cmp r4, r2
|
||||
bgt 1b
|
||||
|
||||
mem_init:
|
||||
@ get memory controller base address
|
||||
ldr r1, =MEMC_BASE
|
||||
|
||||
@****************************************************************************
|
||||
@ Step 1
|
||||
@
|
||||
ldr r1, =MEMC_BASE /* get memory controller base addr. */
|
||||
|
||||
@ write msc0, read back to ensure data latches
|
||||
@
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* 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]
|
||||
|
||||
@ write msc1
|
||||
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]
|
||||
|
||||
@ write msc2
|
||||
/* MSC2: nCS(4,5) */
|
||||
ldr r2, =CFG_MSC2_VAL
|
||||
str r2, [r1, #MSC2_OFFSET]
|
||||
ldr r2, [r1, #MSC2_OFFSET]
|
||||
|
||||
@ write mecr
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* 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]
|
||||
|
||||
@ write mcmem0
|
||||
/* MCMEM0: Card Interface slot 0 timing */
|
||||
ldr r2, =CFG_MCMEM0_VAL
|
||||
str r2, [r1, #MCMEM0_OFFSET]
|
||||
ldr r2, [r1, #MCMEM0_OFFSET]
|
||||
|
||||
@ write mcmem1
|
||||
/* MCMEM1: Card Interface slot 1 timing */
|
||||
ldr r2, =CFG_MCMEM1_VAL
|
||||
str r2, [r1, #MCMEM1_OFFSET]
|
||||
ldr r2, [r1, #MCMEM1_OFFSET]
|
||||
|
||||
@ write mcatt0
|
||||
/* MCATT0: Card Interface Attribute Space Timing, slot 0 */
|
||||
ldr r2, =CFG_MCATT0_VAL
|
||||
str r2, [r1, #MCATT0_OFFSET]
|
||||
ldr r2, [r1, #MCATT0_OFFSET]
|
||||
|
||||
@ write mcatt1
|
||||
/* MCATT1: Card Interface Attribute Space Timing, slot 1 */
|
||||
ldr r2, =CFG_MCATT1_VAL
|
||||
str r2, [r1, #MCATT1_OFFSET]
|
||||
ldr r2, [r1, #MCATT1_OFFSET]
|
||||
|
||||
@ write mcio0
|
||||
/* MCIO0: Card Interface I/O Space Timing, slot 0 */
|
||||
ldr r2, =CFG_MCIO0_VAL
|
||||
str r2, [r1, #MCIO0_OFFSET]
|
||||
ldr r2, [r1, #MCIO0_OFFSET]
|
||||
|
||||
@ write mcio1
|
||||
/* MCIO1: Card Interface I/O Space Timing, slot 1 */
|
||||
ldr r2, =CFG_MCIO1_VAL
|
||||
str r2, [r1, #MCIO1_OFFSET]
|
||||
ldr r2, [r1, #MCIO1_OFFSET]
|
||||
|
||||
@-------------------------------------------------------
|
||||
@ 3rd bullet, Step 1
|
||||
@
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Step 2c: Write FLYCNFG FIXME: what's that??? */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
@ get the mdrefr settings
|
||||
ldr r3, =CFG_MDREFR_VAL_100
|
||||
|
||||
@ extract DRI field (we need a valid DRI field)
|
||||
@
|
||||
ldr r2, =0xFFF
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Step 2d: Initialize Timing for Sync Memory (SDCLK0) */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
@ valid DRI field in r3
|
||||
@
|
||||
and r3, r3, r2
|
||||
/* Before accessing MDREFR we need a valid DRI field, so we set */
|
||||
/* this to power on defaults + DRI field. */
|
||||
|
||||
@ get the reset state of MDREFR
|
||||
@
|
||||
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]
|
||||
|
||||
@ clear the DRI field
|
||||
@
|
||||
bic r4, r4, r2
|
||||
|
||||
@ insert the valid DRI field loaded above
|
||||
@
|
||||
orr r4, r4, r3
|
||||
|
||||
@ write back mdrefr
|
||||
@
|
||||
str r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
@ *Note: preserve the mdrefr value in r4 *
|
||||
|
||||
@****************************************************************************
|
||||
@ Step 2
|
||||
@
|
||||
/* This should be for SRAM, why is it commented out??? */
|
||||
|
||||
@ fetch sxcnfg value
|
||||
@
|
||||
@ldr r2, =0
|
||||
@ write back sxcnfg
|
||||
@str r2, [r1, #SXCNFG_OFFSET]
|
||||
|
||||
/* @if sxcnfg=0, don't program for synch-static memory */
|
||||
@cmp r2, #0
|
||||
@beq 1f
|
||||
|
||||
@program sxmrs
|
||||
@ldr r2, =SXMRS_SETTINGS
|
||||
@str r2, [r1, #SXMRS_OFFSET]
|
||||
/* Note: preserve the mdrefr value in r4 */
|
||||
|
||||
|
||||
@****************************************************************************
|
||||
@ Step 3
|
||||
@
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Step 3: Initialize Synchronous Static Memory (Flash/Peripherals) */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
@ Assumes previous mdrefr value in r4, if not then read current mdrefr
|
||||
/* Initialize SXCNFG register. Assert the enable bits */
|
||||
|
||||
@ clear the free-running clock bits
|
||||
@ (clear K0Free, K1Free, K2Free
|
||||
@
|
||||
bic r4, r4, #(0x00800000 | 0x01000000 | 0x02000000)
|
||||
/* 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. */
|
||||
|
||||
@ set K1RUN if bank 0 installed
|
||||
@
|
||||
orr r4, r4, #0x00010000
|
||||
/* FIXME: we use async mode for now */
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Step 4: Initialize SDRAM */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#ifdef THIS
|
||||
@<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
|
||||
@<!<!<!<!<!<!<!<!<!<!<! Begin INSERT 1 <!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ Lubbock: Allow the user to select the {T/R/M} with predetermined
|
||||
@ SDCLK. Based on Table 3-1 in PXA250 and PXA210 Dev Man.
|
||||
@
|
||||
@ * = Must set MDREFR.K1DB2 to halve the MemClk for desired SDCLK[1]
|
||||
@
|
||||
@ S25, S26 used to provide all 400 MHz BIN values for Cotulla (0,0 - 1,3)
|
||||
@ S25, S26 used to provide all 200 MHz BIN values for Sabinal
|
||||
@
|
||||
@ S23: Force the halving of MemClk when deriving SDCLK[1]
|
||||
@ DOT: no override !DOT: halve (if not already forced half)
|
||||
/* @ *For certain MemClks, SDCLK's derivation is forced to be halved */
|
||||
@
|
||||
@ S24: Run/Turbo.
|
||||
@ DOT: Run mode !DOT: Turbo mode
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
/* set MDREFR according to user define with exception of a few bits */
|
||||
|
||||
@
|
||||
@ Allow the user to control K1DB2 where applicable
|
||||
@
|
||||
@ Get the value of S23: @ 1 = DOT (unity), 0 = !DOT (halve it)
|
||||
@
|
||||
@ DOT: set K1DB2 (SDCLD = MemClk)
|
||||
@ !DOT: clear K1DB2 (SDCLK = MemClk/2)
|
||||
@
|
||||
@ldr r2, =FPGA_REGS_BASE_PHYSICAL
|
||||
|
||||
bl GET_S23 @ r3, r2 @ get the value of S23 in R0, i put the base adx of fpga in r3
|
||||
|
||||
cmp r3, #0x0 @ is !DOT?
|
||||
orreq r4, r4, #0x00020000 @ SDClk[1] = MemClk/2
|
||||
bicne r4, r4, #0x00020000 @ SDClk[1] = MemClk
|
||||
|
||||
@
|
||||
@ Next, we need to look for S25,S26 selections that necessitate the
|
||||
@ halving of MemClk to derive SDCLK[1]: (S25,S26)={03-0C, 10-13}
|
||||
@ Override above S23-based selection accordingly.
|
||||
@
|
||||
ldr r2, =FPGA_REGS_BASE_PHYSICAL
|
||||
bl GET_S25 @ r0, r2
|
||||
@ get the value of S25 in R0, i put the base adx of fpga in r2
|
||||
|
||||
|
||||
|
||||
ldr r2, =FPGA_REGS_BASE_PHYSICAL
|
||||
BL GET_S26 @ r3, r2
|
||||
@ get the value of S26 in R1, i put the base adx of fpga in r2
|
||||
|
||||
orr r0, r0, r3 @ concatenate S25 & S26 vals
|
||||
and r0, r0, #0xFF
|
||||
|
||||
@ Set K1DB2 for the frequencies that require it
|
||||
@
|
||||
cmp r0, #0x03
|
||||
cmpne r0, #0x04
|
||||
cmpne r0, #0x05
|
||||
cmpne r0, #0x06
|
||||
cmpne r0, #0x07
|
||||
cmpne r0, #0x08
|
||||
cmpne r0, #0x09
|
||||
cmpne r0, #0x0A
|
||||
cmpne r0, #0x0B
|
||||
cmpne r0, #0x0C
|
||||
cmpne r0, #0x10
|
||||
cmpne r0, #0x11
|
||||
cmpne r0, #0x12
|
||||
cmpne r0, #0x13
|
||||
orreq r4, r4, #0x00020000 @ SDCLK[1] = (MemClk)/2 for 03 - 0C @ 10 - 13
|
||||
|
||||
@
|
||||
@ *Must make MSC0&1 adjustments now for MEMClks > 100MHz.
|
||||
@
|
||||
@ Adjust MSC0 for MemClks > 100 MHz
|
||||
@
|
||||
ldreq r0, [r1, #MSC0_OFFSET]
|
||||
ldreq r3, =0x7F007F00
|
||||
biceq r0, r0, r3 @ clear MSC0[14:12, 11:8] (RRR, RDN)
|
||||
ldreq r3, =0x46004600
|
||||
orreq r0, r0, r3 @ set MSC0[14, 10:9] (doubling RRR, RDN)
|
||||
streq r0, [r1, #MSC0_OFFSET]
|
||||
ldreq r0, [r1, #MSC0_OFFSET] @ read it back to ensure that the data latches
|
||||
|
||||
@
|
||||
@ Adjust MSC1.LH for MemClks > 100 MHz
|
||||
@
|
||||
ldreq r0, [r1, #MSC1_OFFSET]
|
||||
ldreq r3, =0x7FF0
|
||||
biceq r0, r0, r3 @ clear MSC1[14:12, 11:8, 7:4] (RRR, RDN, RDF)
|
||||
ldreq r3, =0x4880
|
||||
orreq r0, r0, r3 @ set MSC1[14, 11, 7] (doubling RRR, RDN, RDF)
|
||||
streq r0, [r1, #MSC1_OFFSET]
|
||||
ldreq r0, [r1, #MSC1_OFFSET] @ read it back to ensure that the data latches
|
||||
|
||||
@ @
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
#endif
|
||||
|
||||
@<!<!<!<!<!<!<!<!<!<!<! End INSERT 1 <!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
|
||||
@<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
|
||||
|
||||
|
||||
@ write back mdrefr
|
||||
@
|
||||
str r4, [r1, #MDREFR_OFFSET]
|
||||
ldr r4, =CFG_MDREFR_VAL
|
||||
orr r4, r4, #(MDREFR_SLFRSH)
|
||||
bic r4, r4, #(MDREFR_E1PIN|MDREFR_E0PIN)
|
||||
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
|
||||
ldr r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
@ deassert SLFRSH
|
||||
@
|
||||
bic r4, r4, #0x00400000
|
||||
/* Step 4b: de-assert MDREFR:SLFRSH. */
|
||||
|
||||
@ write back mdrefr
|
||||
@
|
||||
str r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
@ assert E1PIN
|
||||
@
|
||||
orr r4, r4, #0x00008000
|
||||
|
||||
@ write back mdrefr
|
||||
@
|
||||
str r4, [r1, #MDREFR_OFFSET]
|
||||
bic r4, r4, #(MDREFR_SLFRSH)
|
||||
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
|
||||
ldr r4, [r1, #MDREFR_OFFSET]
|
||||
nop
|
||||
nop
|
||||
|
||||
|
||||
@****************************************************************************
|
||||
@ Step 4
|
||||
@
|
||||
/* Step 4c: assert MDREFR:E1PIN and E0PIO as desired */
|
||||
|
||||
@ fetch platform value of mdcnfg
|
||||
@
|
||||
ldr r2, =CFG_MDCNFG_VAL
|
||||
|
||||
@ disable all sdram banks
|
||||
@
|
||||
bic r2, r2, #(MDCNFG_DE0 | MDCNFG_DE1)
|
||||
bic r2, r2, #(MDCNFG_DE2 | MDCNFG_DE3)
|
||||
|
||||
@ program banks 0/1 for bus width
|
||||
@
|
||||
bic r2, r2, #MDCNFG_DWID0 @0=32-bit
|
||||
ldr r4, =CFG_MDREFR_VAL
|
||||
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
|
||||
ldr r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
|
||||
@ write initial value of mdcnfg, w/o enabling sdram banks
|
||||
@
|
||||
str r2, [r1, #MDCNFG_OFFSET]
|
||||
/* Step 4d: write MDCNFG with MDCNFG:DEx deasserted (set to 0), to */
|
||||
/* configure but not enable each SDRAM partition pair. */
|
||||
|
||||
@ ****************************************************************************
|
||||
@ Step 5
|
||||
@
|
||||
ldr r4, =CFG_MDCNFG_VAL
|
||||
bic r4, r4, #(MDCNFG_DE0|MDCNFG_DE1)
|
||||
|
||||
@ pause for 200 uSecs
|
||||
@
|
||||
ldr r3, =OSCR @reset the OS Timer Count to zero
|
||||
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
|
||||
ldr r4, =0x300 /* really 0x2E1 is about 200usec, */
|
||||
/* so 0x300 should be plenty */
|
||||
1:
|
||||
ldr r2, [r3]
|
||||
cmp r4, r2
|
||||
bgt 1b
|
||||
|
||||
|
||||
@****************************************************************************
|
||||
@ Step 6
|
||||
@
|
||||
/* 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. */
|
||||
|
||||
mov r0, #0x78 @turn everything off
|
||||
mcr p15, 0, r0, c1, c0, 0 @(caches off, MMU off, etc.)
|
||||
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]
|
||||
|
||||
|
||||
@ ****************************************************************************
|
||||
@ Step 7
|
||||
@
|
||||
@ Access memory *not yet enabled* for CBR refresh cycles (8)
|
||||
@ - CBR is generated for all banks
|
||||
/* Step 4g: Write MDCNFG with enable bits asserted */
|
||||
/* (MDCNFG:DEx set to 1). */
|
||||
|
||||
ldr r2, =CFG_DRAM_BASE
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
|
||||
|
||||
@ ****************************************************************************
|
||||
@ Step 8: NOP (enable dcache if you wanna... we dont)
|
||||
@
|
||||
|
||||
|
||||
@ ****************************************************************************
|
||||
@ Step 9
|
||||
@
|
||||
|
||||
|
||||
@get memory controller base address
|
||||
@
|
||||
ldr r1, =MEMC_BASE
|
||||
|
||||
@fetch current mdcnfg value
|
||||
@
|
||||
ldr r3, [r1, #MDCNFG_OFFSET]
|
||||
|
||||
@enable sdram bank 0 if installed (must do for any populated bank)
|
||||
@
|
||||
orr r3, r3, #MDCNFG_DE0
|
||||
|
||||
@write back mdcnfg, enabling the sdram bank(s)
|
||||
@
|
||||
orr r3, r3, #(MDCNFG_DE0|MDCNFG_DE1)
|
||||
str r3, [r1, #MDCNFG_OFFSET]
|
||||
|
||||
/* Step 4h: Write MDMRS. */
|
||||
|
||||
@****************************************************************************
|
||||
@ Step 10
|
||||
@
|
||||
|
||||
@ write mdmrs
|
||||
@
|
||||
ldr r2, =CFG_MDMRS_VAL
|
||||
str r2, [r1, #MDMRS_OFFSET]
|
||||
|
||||
|
||||
@****************************************************************************
|
||||
@ Step 11: Final Step
|
||||
@
|
||||
/* We are finished with Intel's memory controller initialisation */
|
||||
|
||||
@INITINTC
|
||||
@********************************************************************
|
||||
@ Disable (mask) all interrupts at the interrupt controller
|
||||
@
|
||||
|
||||
@ clear the interrupt level register (use IRQ, not FIQ)
|
||||
@
|
||||
mov r1, #0
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Disable (mask) all interrupts at interrupt controller */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
initirqs:
|
||||
|
||||
mov r1, #0 /* clear int. level register (IRQ, not FIQ) */
|
||||
ldr r2, =ICLR
|
||||
str r1, [r2]
|
||||
|
||||
@ mask all interrupts at the controller
|
||||
@
|
||||
ldr r2, =ICMR
|
||||
ldr r2, =ICMR /* mask all interrupts at the controller */
|
||||
str r1, [r2]
|
||||
|
||||
|
||||
@INITCLKS
|
||||
@ ********************************************************************
|
||||
@ Disable the peripheral clocks, and set the core clock
|
||||
@ frequency (hard-coding at 398.12MHz for now).
|
||||
@
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Clock initialisation */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
@ Turn Off ALL on-chip peripheral clocks for re-configuration
|
||||
@ *Note: See label 'ENABLECLKS' for the re-enabling
|
||||
@
|
||||
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}
|
||||
/* 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
|
||||
@
|
||||
/* ... and write the core clock config register */
|
||||
ldr r1, =CCCR
|
||||
str r2, [r1]
|
||||
|
||||
/* @ enable the 32Khz oscillator for RTC and PowerManager
|
||||
@
|
||||
#ifdef RTC
|
||||
/* 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.
|
||||
@
|
||||
/* NOTE: spin here until OSCC.OOK get set, meaning the PLL */
|
||||
/* has settled. */
|
||||
60:
|
||||
ldr r2, [r1]
|
||||
ands r2, r2, #1
|
||||
beq 60b
|
||||
*/
|
||||
|
||||
@OSCC_OON_DONE
|
||||
|
||||
|
||||
#ifdef A0_COTULLA
|
||||
@****************************************************************************
|
||||
@ !!! Take care of A0 Errata Sighting #4 --
|
||||
@ after a frequency change, the memory controller must be restarted
|
||||
@
|
||||
|
||||
@ get memory controller base address
|
||||
ldr r1, =MEMC_BASE
|
||||
|
||||
@ get the current state of MDREFR
|
||||
@
|
||||
ldr r2, [r1, #MDREFR_OFFSET]
|
||||
|
||||
@ clear E0PIN, E1PIN
|
||||
@
|
||||
bic r3, r2, #(MDREFR_E0PIN | MDREFR_E1PIN)
|
||||
|
||||
@ write MDREFR with E0PIN, E1PIN cleared (disable sdclk[0,1])
|
||||
@
|
||||
str r3, [r1, #MDREFR_OFFSET]
|
||||
|
||||
@ then write MDREFR with E0PIN, E1PIN set (enable sdclk[0,1])
|
||||
@
|
||||
str r2, [r1, #MDREFR_OFFSET]
|
||||
|
||||
@ get the current state of MDCNFG
|
||||
@
|
||||
ldr r3, [r1, #MDCNFG_OFFSET]
|
||||
|
||||
@ disable all SDRAM banks
|
||||
@
|
||||
bic r3, r3, #(MDCNFG_DE0 | MDCNFG_DE1)
|
||||
bic r3, r3, #(MDCNFG_DE2 | MDCNFG_DE3)
|
||||
|
||||
@ write back MDCNFG
|
||||
@
|
||||
ldr r3, [r1, #MDCNFG_OFFSET]
|
||||
|
||||
@ Access memory not yet enabled for CBR refresh cycles (8)
|
||||
@ - CBR is generated for *all* banks
|
||||
ldr r2, =CFG_DRAM_BASE
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
|
||||
@ fetch current mdcnfg value
|
||||
@
|
||||
ldr r3, [r1, #MDCNFG_OFFSET]
|
||||
|
||||
@ enable sdram bank 0 if installed
|
||||
@
|
||||
orr r3, r3, #MDCNFG_DE0
|
||||
|
||||
@ write back mdcnfg, enabling the sdram bank(s)
|
||||
@
|
||||
str r3, [r1, #MDCNFG_OFFSET]
|
||||
|
||||
@ write mdmrs
|
||||
@
|
||||
ldr r2, =CFG_MDMRS_VAL
|
||||
str r2, [r1, #MDMRS_OFFSET]
|
||||
|
||||
|
||||
|
||||
/* @ errata: don't enable auto power-down */
|
||||
@ get current value of mdrefr
|
||||
@ldr r3, [r1, #MDREFR_OFFSET]
|
||||
@ enable auto-power down
|
||||
@orr r3, r3, #MDREFR_APD
|
||||
@write back mdrefr
|
||||
@str r3, [r1, #MDREFR_OFFSET]
|
||||
|
||||
#endif A0_Cotulla
|
||||
|
||||
|
||||
ldr r0, =0x000C0dE3
|
||||
ldr r1, =_LED
|
||||
str r0, [r1] /* hex display */
|
||||
|
||||
@ ^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%
|
||||
@ ^%^%^%^%^%^%^%^%^% above could be replaced by prememLLI ^%^%^%^%^%^%^%^%^%
|
||||
@ ^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Save SDRAM size */
|
||||
ldr r1, =DRAM_SIZE
|
||||
str r8, [r1]
|
||||
|
||||
ldr r0, =0xC0DE0006
|
||||
ldr r1, =_LED
|
||||
str r0, [r1] /* hex display */
|
||||
|
||||
/* Interrupt init */
|
||||
/* Mask all interrupts */
|
||||
/* Interrupt init: Mask all interrupts */
|
||||
ldr r0, =ICMR /* enable no sources */
|
||||
mov r1, #0
|
||||
str r1, [r0]
|
||||
|
||||
/* FIXME */
|
||||
|
||||
#define NODEBUG
|
||||
#ifdef NODEBUG
|
||||
/*Disable software and data breakpoints */
|
||||
@@ -676,74 +402,11 @@ mem_init:
|
||||
|
||||
#endif
|
||||
|
||||
ldr r0, =0xBEEF001D
|
||||
ldr r1, =_LED
|
||||
str r0, [r1] /* hex display */
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* End memsetup */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
mov pc, r10
|
||||
|
||||
@ End memsetup
|
||||
|
||||
@ %%%%%%%%%%% Useful subroutines
|
||||
GET_S23:
|
||||
@ This macro will read S23 and return its value in r3
|
||||
@ r2 contains the base address of the Lubbock user registers
|
||||
ldr r2, =FPGA_REGS_BASE_PHYSICAL
|
||||
|
||||
/*@ read S23's value */
|
||||
ldr r3, [r2, #USER_SWITCHES_OFFSET]
|
||||
|
||||
@ mask out irrelevant bits
|
||||
and r3, r3, #0x200
|
||||
|
||||
@ get bit into position 0
|
||||
mov r3, r3, LSR #9
|
||||
endmemsetup:
|
||||
|
||||
mov pc, lr
|
||||
@ End GET_S23
|
||||
|
||||
|
||||
GET_S24:
|
||||
@ This macro will read S24 and return its value in r0
|
||||
@ r2 contains the base address of the Lubbock user registers
|
||||
ldr r2, =FPGA_REGS_BASE_PHYSICAL
|
||||
|
||||
/*@ read S24's value */
|
||||
ldr r0, [r2, #USER_SWITCHES_OFFSET]
|
||||
|
||||
@ mask out irrelevant bits
|
||||
and r0, r0, #0x100
|
||||
|
||||
@ get bit into position 0
|
||||
mov r0, r0, LSR #8
|
||||
|
||||
mov pc, lr
|
||||
@ End GET_S23
|
||||
|
||||
|
||||
GET_S25:
|
||||
@ This macro will read rotary S25 and return its value in r0
|
||||
@ r2 contains the base address of the Lubbock user registers
|
||||
@ read the user switches register
|
||||
ldr r0, [r2, #USER_SWITCHES_OFFSET]
|
||||
|
||||
@ mask out irrelevant bits
|
||||
and r0, r0, #0xF0
|
||||
|
||||
mov pc, lr
|
||||
@ End subroutine
|
||||
|
||||
|
||||
GET_S26:
|
||||
@ This macro will read rotary S26 and return its value in r3
|
||||
@ r2 contains the base address of the Lubbock user registers
|
||||
@ read the user switches register
|
||||
ldr r3, [r2, #USER_SWITCHES_OFFSET]
|
||||
|
||||
@ mask out irrelevant bits
|
||||
and r3, r3, #0x0F
|
||||
|
||||
mov pc, lr
|
||||
@ End subroutine GET_S26
|
||||
|
||||
|
||||
|
||||
@@ -833,7 +833,7 @@ int do_kbd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Read and set LSB switch */
|
||||
#define CFG_PC_TXD1_ENA 0x0008
|
||||
#define CFG_PC_TXD1_ENA 0x0008 /* PC.12 */
|
||||
|
||||
/***********************************************************************
|
||||
F* Function: int do_lsb (cmd_tbl_t *cmdtp, int flag,
|
||||
|
||||
@@ -277,7 +277,7 @@ struct pci_controller hose = {
|
||||
fixup_irq: pci_mousse_fixup_irq,
|
||||
};
|
||||
|
||||
void pci_init(void)
|
||||
void pci_init_board(void)
|
||||
{
|
||||
pci_mpc824x_init(&hose);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (C) Copyright 2001
|
||||
* (C) Copyright 2001-2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* Modified during 2001 by
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <common.h>
|
||||
#include <ioports.h>
|
||||
#include <mpc8260.h>
|
||||
#include <i2c.h>
|
||||
#include <spd.h>
|
||||
|
||||
/*
|
||||
* I/O Port configuration table
|
||||
@@ -167,8 +169,8 @@ const iop_conf_t iop_conf_tab[4][32] = {
|
||||
/* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD18 */
|
||||
/* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */
|
||||
/* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */
|
||||
/* PD15 */ { 0, 1, 1, 0, 1, 0 }, /* I2C SDA */
|
||||
/* PD14 */ { 1, 0, 0, 1, 0, 0 }, /* LED */
|
||||
/* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */
|
||||
/* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */
|
||||
/* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* PD13 */
|
||||
/* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* PD12 */
|
||||
/* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* PD11 */
|
||||
@@ -197,76 +199,222 @@ typedef struct bscr_ {
|
||||
unsigned long bcsr7;
|
||||
} bcsr_t;
|
||||
|
||||
void reset_phy(void)
|
||||
void reset_phy (void)
|
||||
{
|
||||
volatile bcsr_t *bcsr = (bcsr_t *)CFG_BCSR;
|
||||
volatile bcsr_t *bcsr = (bcsr_t *) CFG_BCSR;
|
||||
|
||||
/* reset the FEC port */
|
||||
bcsr->bcsr1 &= ~FETH_RST;
|
||||
bcsr->bcsr1 |= FETH_RST;
|
||||
/* reset the FEC port */
|
||||
bcsr->bcsr1 &= ~FETH_RST;
|
||||
bcsr->bcsr1 |= FETH_RST;
|
||||
}
|
||||
|
||||
|
||||
int board_pre_init (void)
|
||||
{
|
||||
volatile bcsr_t *bcsr = (bcsr_t *)CFG_BCSR;
|
||||
bcsr->bcsr1 = ~FETHIEN & ~RS232EN_1;
|
||||
volatile bcsr_t *bcsr = (bcsr_t *) CFG_BCSR;
|
||||
|
||||
return 0;
|
||||
bcsr->bcsr1 = ~FETHIEN & ~RS232EN_1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
long int initdram(int board_type)
|
||||
#define ns2clk(ns) (ns / (1000000000 / CONFIG_8260_CLKIN) + 1)
|
||||
|
||||
long int initdram (int board_type)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile memctl8260_t *memctl = &immap->im_memctl;
|
||||
volatile uchar *ramaddr,
|
||||
c = 0xff;
|
||||
int i;
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
volatile memctl8260_t *memctl = &immap->im_memctl;
|
||||
volatile uchar *ramaddr, c = 0xff;
|
||||
|
||||
/* Initialisation is for 16MB DIMM the board is shipped with */
|
||||
long int msize = 16;
|
||||
uint or = 0xFF000CA0;
|
||||
uint psdmr = CFG_PSDMR;
|
||||
uint psrt = CFG_PSRT;
|
||||
|
||||
int i;
|
||||
|
||||
#ifndef CFG_RAMBOOT
|
||||
immap->im_siu_conf.sc_ppc_acr = 0x00000002;
|
||||
immap->im_siu_conf.sc_ppc_alrh = 0x01267893;
|
||||
immap->im_siu_conf.sc_tescr1 = 0x00004000;
|
||||
immap->im_siu_conf.sc_ppc_acr = 0x00000002;
|
||||
immap->im_siu_conf.sc_ppc_alrh = 0x01267893;
|
||||
immap->im_siu_conf.sc_tescr1 = 0x00004000;
|
||||
|
||||
/* init local sdram, bank 4 */
|
||||
memctl->memc_lsrt = 0x00000010;
|
||||
memctl->memc_or4 = 0xFFC01480;
|
||||
memctl->memc_br4 = 0x04001861;
|
||||
memctl->memc_lsdmr = 0x2886A522;
|
||||
ramaddr = (uchar *)CFG_LSDRAM_BASE;
|
||||
*ramaddr = c;
|
||||
memctl->memc_lsdmr = 0x0886A522;
|
||||
for( i = 0; i < 8; i++ ) {
|
||||
*ramaddr = c;
|
||||
}
|
||||
memctl->memc_lsdmr = 0x1886A522;
|
||||
*ramaddr = c;
|
||||
memctl->memc_lsdmr = 0x4086A522;
|
||||
memctl->memc_mptpr = CFG_MPTPR;
|
||||
/* init local sdram, bank 4 */
|
||||
memctl->memc_lsrt = 0x00000010;
|
||||
memctl->memc_or4 = 0xFFC01480;
|
||||
memctl->memc_br4 = 0x04001861;
|
||||
memctl->memc_lsdmr = 0x2886A522;
|
||||
ramaddr = (uchar *) CFG_LSDRAM_BASE;
|
||||
*ramaddr = c;
|
||||
memctl->memc_lsdmr = 0x0886A522;
|
||||
for (i = 0; i < 8; i++) {
|
||||
*ramaddr = c;
|
||||
}
|
||||
memctl->memc_lsdmr = 0x1886A522;
|
||||
*ramaddr = c;
|
||||
memctl->memc_lsdmr = 0x4086A522;
|
||||
|
||||
/* init sdram dimm */
|
||||
ramaddr = (uchar *)CFG_SDRAM_BASE;
|
||||
memctl->memc_psrt = 0x00000010;
|
||||
immap->im_memctl.memc_or2 = 0xFF000CA0;
|
||||
immap->im_memctl.memc_br2 = 0x00000041;
|
||||
memctl->memc_psdmr = 0x296EB452;
|
||||
*ramaddr = c;
|
||||
memctl->memc_psdmr = 0x096EB452;
|
||||
for (i = 0; i < 8; i++)
|
||||
*ramaddr = c;
|
||||
/* init sdram dimm */
|
||||
#ifdef CONFIG_SPD_EEPROM
|
||||
{
|
||||
spd_eeprom_t spd;
|
||||
uint pbi, bsel, rowst, lsb, tmp;
|
||||
|
||||
memctl->memc_psdmr = 0x196EB452;
|
||||
*ramaddr = c;
|
||||
memctl->memc_psdmr = 0x416EB452;
|
||||
*ramaddr = c;
|
||||
i2c_read (CONFIG_SPD_ADDR, 0, 1, (uchar *) & spd, sizeof (spd));
|
||||
|
||||
/* Bank-based interleaving is not supported for physical bank
|
||||
sizes greater than 128MB which is encoded as 0x20 in SPD
|
||||
*/
|
||||
pbi = (spd.row_dens > 32) ? 1 : CONFIG_SDRAM_PBI;
|
||||
msize = spd.nrows * (4 * spd.row_dens); /* Mixed size not supported */
|
||||
or = ~(msize - 1) << 20; /* SDAM */
|
||||
switch (spd.nbanks) { /* BPD */
|
||||
case 2:
|
||||
bsel = 1;
|
||||
break;
|
||||
case 4:
|
||||
bsel = 2;
|
||||
or |= 0x00002000;
|
||||
break;
|
||||
case 8:
|
||||
bsel = 3;
|
||||
or |= 0x00004000;
|
||||
break;
|
||||
}
|
||||
lsb = 3; /* For 64-bit port, lsb is 3 bits */
|
||||
|
||||
if (pbi) { /* Bus partition depends on interleaving */
|
||||
rowst = 32 - (spd.nrow_addr + spd.ncol_addr + bsel + lsb);
|
||||
or |= (rowst << 9); /* ROWST */
|
||||
} else {
|
||||
rowst = 32 - (spd.nrow_addr + spd.ncol_addr + lsb);
|
||||
or |= ((rowst * 2 - 12) << 9); /* ROWST */
|
||||
}
|
||||
or |= ((spd.nrow_addr - 9) << 6); /* NUMR */
|
||||
|
||||
psdmr = (pbi << 31); /* PBI */
|
||||
/* Bus multiplexing parameters */
|
||||
tmp = 32 - (lsb + spd.nrow_addr); /* Tables 10-19 and 10-20 */
|
||||
psdmr |= ((tmp - (rowst - 5) - 13) << 24); /* SDAM */
|
||||
psdmr |= ((tmp - 3 - 12) << 21); /* BSMA */
|
||||
|
||||
tmp = (31 - lsb - 10) - tmp;
|
||||
/* Pin connected to SDA10 is (31 - lsb - 10).
|
||||
rowst is multiplexed over (32 - (lsb + spd.nrow_addr)),
|
||||
so (rowst + tmp) alternates with AP.
|
||||
*/
|
||||
if (pbi) /* Table 10-7 */
|
||||
psdmr |= ((10 - (rowst + tmp)) << 18); /* SDA10 */
|
||||
else
|
||||
psdmr |= ((12 - (rowst + tmp)) << 18); /* SDA10 */
|
||||
|
||||
/* SDRAM device-specific parameters */
|
||||
tmp = ns2clk (70); /* Refresh recovery is not in SPD, so assume 70ns */
|
||||
switch (tmp) { /* RFRC */
|
||||
case 1:
|
||||
case 2:
|
||||
psdmr |= (1 << 15);
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
psdmr |= ((tmp - 2) << 15);
|
||||
break;
|
||||
default:
|
||||
psdmr |= (7 << 15);
|
||||
}
|
||||
psdmr |= (ns2clk (spd.trp) % 8 << 12); /* PRETOACT */
|
||||
psdmr |= (ns2clk (spd.trcd) % 8 << 9); /* ACTTORW */
|
||||
/* BL=0 because for 64-bit SDRAM burst length must be 4 */
|
||||
/* LDOTOPRE ??? */
|
||||
for (i = 0, tmp = spd.write_lat; (i < 4) && ((tmp & 1) == 0); i++)
|
||||
tmp >>= 1;
|
||||
switch (i) { /* WRC */
|
||||
case 0:
|
||||
case 1:
|
||||
psdmr |= (1 << 4);
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
psdmr |= (i << 4);
|
||||
break;
|
||||
}
|
||||
/* EAMUX=0 - no external address multiplexing */
|
||||
/* BUFCMD=0 - no external buffers */
|
||||
for (i = 1, tmp = spd.cas_lat; (i < 3) && ((tmp & 1) == 0); i++)
|
||||
tmp >>= 1;
|
||||
psdmr |= i; /* CL */
|
||||
|
||||
switch (spd.refresh & 0x7F) {
|
||||
case 1:
|
||||
tmp = 3900;
|
||||
break;
|
||||
case 2:
|
||||
tmp = 7800;
|
||||
break;
|
||||
case 3:
|
||||
tmp = 31300;
|
||||
break;
|
||||
case 4:
|
||||
tmp = 62500;
|
||||
break;
|
||||
case 5:
|
||||
tmp = 125000;
|
||||
break;
|
||||
default:
|
||||
tmp = 15625;
|
||||
}
|
||||
psrt = tmp / (1000000000 / CONFIG_8260_CLKIN *
|
||||
((memctl->memc_mptpr >> 8) + 1)) - 1;
|
||||
#ifdef SPD_DEBUG
|
||||
printf ("\nDIMM type: %-18.18s\n", spd.mpart);
|
||||
printf ("SPD size: %d\n", spd.info_size);
|
||||
printf ("EEPROM size: %d\n", 1 << spd.chip_size);
|
||||
printf ("Memory type: %d\n", spd.mem_type);
|
||||
printf ("Row addr: %d\n", spd.nrow_addr);
|
||||
printf ("Column addr: %d\n", spd.ncol_addr);
|
||||
printf ("# of rows: %d\n", spd.nrows);
|
||||
printf ("Row density: %d\n", spd.row_dens);
|
||||
printf ("# of banks: %d\n", spd.nbanks);
|
||||
printf ("Data width: %d\n",
|
||||
256 * spd.dataw_msb + spd.dataw_lsb);
|
||||
printf ("Chip width: %d\n", spd.primw);
|
||||
printf ("Refresh rate: %02X\n", spd.refresh);
|
||||
printf ("CAS latencies: %02X\n", spd.cas_lat);
|
||||
printf ("Write latencies: %02X\n", spd.write_lat);
|
||||
printf ("tRP: %d\n", spd.trp);
|
||||
printf ("tRCD: %d\n", spd.trcd);
|
||||
|
||||
printf ("OR=%X, PSDMR=%08X, PSRT=%0X\n", or, psdmr, psrt);
|
||||
#endif /* SPD_DEBUG */
|
||||
}
|
||||
#endif /* CONFIG_SPD_EEPROM */
|
||||
memctl->memc_psrt = psrt;
|
||||
memctl->memc_or2 = or;
|
||||
memctl->memc_br2 = CFG_SDRAM_BASE | 0x00000041;
|
||||
ramaddr = (uchar *) CFG_SDRAM_BASE;
|
||||
memctl->memc_psdmr = psdmr | 0x28000000; /* Precharge all banks */
|
||||
*ramaddr = c;
|
||||
memctl->memc_psdmr = psdmr | 0x08000000; /* CBR refresh */
|
||||
for (i = 0; i < 8; i++)
|
||||
*ramaddr = c;
|
||||
|
||||
memctl->memc_psdmr = psdmr | 0x18000000; /* Mode Register write */
|
||||
*ramaddr = c;
|
||||
memctl->memc_psdmr = psdmr | 0x40000000; /* Refresh enable */
|
||||
*ramaddr = c;
|
||||
#endif
|
||||
|
||||
/* return total ram size of simm */
|
||||
return (16 * 1024 * 1024);
|
||||
/* return total ram size of DIMM */
|
||||
return (msize * 1024 * 1024);
|
||||
}
|
||||
|
||||
int checkboard(void)
|
||||
int checkboard (void)
|
||||
{
|
||||
puts ("Board: Motorola MPC8260ADS\n");
|
||||
return 0;
|
||||
puts ("Board: Motorola MPC8260ADS\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
46
board/mpc8266ads/Makefile
Normal file
46
board/mpc8266ads/Makefile
Normal file
@@ -0,0 +1,46 @@
|
||||
#
|
||||
# (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): $(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
|
||||
|
||||
#########################################################################
|
||||
32
board/mpc8266ads/config.mk
Normal file
32
board/mpc8266ads/config.mk
Normal file
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# (C) Copyright 2001
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# Modified by, Stuart Hughes, Lineo Inc, stuarth@lineo.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
|
||||
#
|
||||
|
||||
#
|
||||
# mpc8260ads board
|
||||
#
|
||||
|
||||
TEXT_BASE = 0xfff00000
|
||||
|
||||
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
|
||||
509
board/mpc8266ads/flash.c
Normal file
509
board/mpc8266ads/flash.c
Normal file
@@ -0,0 +1,509 @@
|
||||
/*
|
||||
* (C) Copyright 2000, 2001
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com
|
||||
* Add support the Sharp chips on the mpc8260ads.
|
||||
* I started with board/ip860/flash.c and made changes I found in
|
||||
* the MTD project by David Schleef.
|
||||
*
|
||||
* 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>
|
||||
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
#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
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* 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 int clear_block_lock_bit(vu_long * addr);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
#ifndef CONFIG_MPC8260ADS
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile memctl8xx_t *memctl = &immap->im_memctl;
|
||||
volatile ip860_bcsr_t *bcsr = (ip860_bcsr_t *)BCSR_BASE;
|
||||
#endif
|
||||
unsigned long size;
|
||||
int i;
|
||||
|
||||
/* Init: enable write,
|
||||
* or we cannot even write flash commands
|
||||
*/
|
||||
#ifndef CONFIG_MPC8260ADS
|
||||
bcsr->bd_ctrl |= BD_CTRL_FLWE;
|
||||
#endif
|
||||
|
||||
|
||||
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
|
||||
flash_info[i].flash_id = FLASH_UNKNOWN;
|
||||
|
||||
/* set the default sector offset */
|
||||
}
|
||||
|
||||
/* Static FLASH Bank configuration here - FIXME XXX */
|
||||
|
||||
size = flash_get_size((vu_long *)FLASH_BASE, &flash_info[0]);
|
||||
|
||||
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
|
||||
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
|
||||
size, size<<20);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_MPC8260ADS
|
||||
/* Remap FLASH according to real size */
|
||||
memctl->memc_or1 = CFG_OR_TIMING_FLASH | (-size & 0xFFFF8000);
|
||||
memctl->memc_br1 = (CFG_FLASH_BASE & BR_BA_MSK) |
|
||||
(memctl->memc_br1 & ~(BR_BA_MSK));
|
||||
#endif
|
||||
/* Re-do sizing to get full correct info */
|
||||
size = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
|
||||
|
||||
flash_info[0].size = size;
|
||||
|
||||
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
|
||||
/* 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 */
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR+CFG_ENV_SECT_SIZE-1,
|
||||
&flash_info[0]);
|
||||
#endif
|
||||
return (size);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
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_INTEL: printf ("Intel "); break;
|
||||
case FLASH_MAN_SHARP: printf ("Sharp "); break;
|
||||
default: printf ("Unknown Vendor "); break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_28F016SV: printf ("28F016SV (16 Mbit, 32 x 64k)\n");
|
||||
break;
|
||||
case FLASH_28F160S3: printf ("28F160S3 (16 Mbit, 32 x 512K)\n");
|
||||
break;
|
||||
case FLASH_28F320S3: printf ("28F320S3 (32 Mbit, 64 x 512K)\n");
|
||||
break;
|
||||
case FLASH_LH28F016SCT: printf ("28F016SC (16 Mbit, 32 x 64K)\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");
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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;
|
||||
ulong sector_offset;
|
||||
|
||||
/* Write "Intelligent Identifier" command: read Manufacturer ID */
|
||||
*addr = 0x90909090;
|
||||
|
||||
value = addr[0] & 0x00FF00FF;
|
||||
switch (value) {
|
||||
case MT_MANUFACT: /* SHARP, MT or => Intel */
|
||||
case INTEL_ALT_MANU:
|
||||
info->flash_id = FLASH_MAN_INTEL;
|
||||
break;
|
||||
default:
|
||||
printf("unknown manufacturer: %x\n", (unsigned int)value);
|
||||
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 (INTEL_ID_28F016S):
|
||||
info->flash_id += FLASH_28F016SV;
|
||||
info->sector_count = 32;
|
||||
info->size = 0x00400000;
|
||||
sector_offset = 0x20000;
|
||||
break; /* => 2x2 MB */
|
||||
|
||||
case (INTEL_ID_28F160S3):
|
||||
info->flash_id += FLASH_28F160S3;
|
||||
info->sector_count = 32;
|
||||
info->size = 0x00400000;
|
||||
sector_offset = 0x20000;
|
||||
break; /* => 2x2 MB */
|
||||
|
||||
case (INTEL_ID_28F320S3):
|
||||
info->flash_id += FLASH_28F320S3;
|
||||
info->sector_count = 64;
|
||||
info->size = 0x00800000;
|
||||
sector_offset = 0x20000;
|
||||
break; /* => 2x4 MB */
|
||||
|
||||
case SHARP_ID_28F016SCL:
|
||||
case SHARP_ID_28F016SCZ:
|
||||
info->flash_id = FLASH_MAN_SHARP | FLASH_LH28F016SCT;
|
||||
info->sector_count = 32;
|
||||
info->size = 0x00800000;
|
||||
sector_offset = 0x40000;
|
||||
break; /* => 4x2 MB */
|
||||
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
return (0); /* => no or unknown flash */
|
||||
|
||||
}
|
||||
|
||||
/* set up sector start address table */
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
info->start[i] = base;
|
||||
base += sector_offset;
|
||||
/* don't know how to check sector protection */
|
||||
info->protect[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevent writes to uninitialized FLASH.
|
||||
*/
|
||||
if (info->flash_id != FLASH_UNKNOWN) {
|
||||
addr = (vu_long *)info->start[0];
|
||||
|
||||
*addr = 0xFFFFFF; /* reset bank to read array 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)
|
||||
&& ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_SHARP) ) {
|
||||
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");
|
||||
}
|
||||
|
||||
/* Make Sure Block Lock Bit is not set. */
|
||||
if(clear_block_lock_bit((vu_long *)(info->start[s_first]))){
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect<=s_last; sect++) {
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
vu_long *addr = (vu_long *)(info->start[sect]);
|
||||
|
||||
last = start = get_timer (0);
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
/* Reset Array */
|
||||
*addr = 0xffffffff;
|
||||
/* Clear Status Register */
|
||||
*addr = 0x50505050;
|
||||
/* Single Block Erase Command */
|
||||
*addr = 0x20202020;
|
||||
/* Confirm */
|
||||
*addr = 0xD0D0D0D0;
|
||||
|
||||
if((info->flash_id & FLASH_TYPEMASK) != FLASH_LH28F016SCT) {
|
||||
/* Resume Command, as per errata update */
|
||||
*addr = 0xD0D0D0D0;
|
||||
}
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
/* wait at least 80us - let's wait 1 ms */
|
||||
udelay (1000);
|
||||
while ((*addr & 0x80808080) != 0x80808080) {
|
||||
if(*addr & 0x20202020){
|
||||
printf("Error in Block Erase - Lock Bit may be set!\n");
|
||||
printf("Status Register = 0x%X\n", (uint)*addr);
|
||||
*addr = 0xFFFFFFFF; /* reset bank */
|
||||
return 1;
|
||||
}
|
||||
if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout\n");
|
||||
*addr = 0xFFFFFFFF; /* reset bank */
|
||||
return 1;
|
||||
}
|
||||
/* show that we're waiting */
|
||||
if ((now - last) > 1000) { /* every second */
|
||||
putc ('.');
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
|
||||
/* reset to read mode */
|
||||
*addr = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
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 *)dest;
|
||||
ulong start, csr;
|
||||
int flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*addr & data) != data) {
|
||||
return (2);
|
||||
}
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
/* Write Command */
|
||||
*addr = 0x10101010;
|
||||
|
||||
/* Write Data */
|
||||
*addr = data;
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
/* data polling for D7 */
|
||||
start = get_timer (0);
|
||||
flag = 0;
|
||||
while (((csr = *addr) & 0x80808080) != 0x80808080) {
|
||||
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (csr & 0x40404040) {
|
||||
printf ("CSR indicates write error (%08lx) at %08lx\n", csr, (ulong)addr);
|
||||
flag = 1;
|
||||
}
|
||||
|
||||
/* Clear Status Registers Command */
|
||||
*addr = 0x50505050;
|
||||
/* Reset to read array mode */
|
||||
*addr = 0xFFFFFFFF;
|
||||
|
||||
return (flag);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Clear Block Lock Bit, returns:
|
||||
* 0 - OK
|
||||
* 1 - Timeout
|
||||
*/
|
||||
|
||||
static int clear_block_lock_bit(vu_long * addr)
|
||||
{
|
||||
ulong start, now;
|
||||
|
||||
/* Reset Array */
|
||||
*addr = 0xffffffff;
|
||||
/* Clear Status Register */
|
||||
*addr = 0x50505050;
|
||||
|
||||
*addr = 0x60606060;
|
||||
*addr = 0xd0d0d0d0;
|
||||
|
||||
start = get_timer (0);
|
||||
while(*addr != 0x80808080){
|
||||
if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout on clearing Block Lock Bit\n");
|
||||
*addr = 0xFFFFFFFF; /* reset bank */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
565
board/mpc8266ads/mpc8266ads.c
Normal file
565
board/mpc8266ads/mpc8266ads.c
Normal file
@@ -0,0 +1,565 @@
|
||||
/*
|
||||
* (C) Copyright 2001
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* Modified during 2001 by
|
||||
* Advanced Communications Technologies (Australia) Pty. Ltd.
|
||||
* Howard Walker, Tuong Vu-Dinh
|
||||
*
|
||||
* (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com
|
||||
* Added support for the 16M dram simm on the 8260ads boards
|
||||
*
|
||||
* 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 <ioports.h>
|
||||
#include <i2c.h>
|
||||
#include <mpc8260.h>
|
||||
|
||||
/*
|
||||
* PBI Page Based Interleaving
|
||||
* PSDMR_PBI page based interleaving
|
||||
* 0 bank based interleaving
|
||||
* External Address Multiplexing (EAMUX) adds a clock to address cycles
|
||||
* (this can help with marginal board layouts)
|
||||
* PSDMR_EAMUX adds a clock
|
||||
* 0 no extra clock
|
||||
* Buffer Command (BUFCMD) adds a clock to command cycles.
|
||||
* PSDMR_BUFCMD adds a clock
|
||||
* 0 no extra clock
|
||||
*/
|
||||
#define CONFIG_PBI 0
|
||||
#define PESSIMISTIC_SDRAM 0
|
||||
#define EAMUX 0 /* EST requires EAMUX */
|
||||
#define BUFCMD 0
|
||||
|
||||
|
||||
/*
|
||||
* I/O Port configuration table
|
||||
*
|
||||
* if conf is 1, then that port pin will be configured at boot time
|
||||
* according to the five values podr/pdir/ppar/psor/pdat for that entry
|
||||
*/
|
||||
|
||||
const iop_conf_t iop_conf_tab[4][32] = {
|
||||
|
||||
/* Port A configuration */
|
||||
{ /* conf ppar psor pdir podr pdat */
|
||||
/* PA31 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 TxENB */
|
||||
/* PA30 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 TxClav */
|
||||
/* PA29 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 TxSOC */
|
||||
/* PA28 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 RxENB */
|
||||
/* PA27 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 RxSOC */
|
||||
/* PA26 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 RxClav */
|
||||
/* PA25 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[0] */
|
||||
/* PA24 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[1] */
|
||||
/* PA23 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[2] */
|
||||
/* PA22 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[3] */
|
||||
/* PA21 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[4] */
|
||||
/* PA20 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[5] */
|
||||
/* PA19 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[6] */
|
||||
/* PA18 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[7] */
|
||||
/* PA17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[7] */
|
||||
/* PA16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[6] */
|
||||
/* PA15 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[5] */
|
||||
/* PA14 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[4] */
|
||||
/* PA13 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[3] */
|
||||
/* PA12 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[2] */
|
||||
/* PA11 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[1] */
|
||||
/* PA10 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[0] */
|
||||
/* PA9 */ { 0, 1, 1, 1, 0, 0 }, /* FCC1 L1TXD */
|
||||
/* PA8 */ { 0, 1, 1, 0, 0, 0 }, /* FCC1 L1RXD */
|
||||
/* PA7 */ { 0, 0, 0, 1, 0, 0 }, /* PA7 */
|
||||
/* PA6 */ { 1, 1, 1, 1, 0, 0 }, /* TDM A1 L1RSYNC */
|
||||
/* PA5 */ { 0, 0, 0, 1, 0, 0 }, /* PA5 */
|
||||
/* PA4 */ { 0, 0, 0, 1, 0, 0 }, /* PA4 */
|
||||
/* PA3 */ { 0, 0, 0, 1, 0, 0 }, /* PA3 */
|
||||
/* PA2 */ { 0, 0, 0, 1, 0, 0 }, /* PA2 */
|
||||
/* PA1 */ { 1, 0, 0, 0, 0, 0 }, /* FREERUN */
|
||||
/* PA0 */ { 0, 0, 0, 1, 0, 0 } /* PA0 */
|
||||
},
|
||||
|
||||
/* 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 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RX_DIV */
|
||||
/* PB16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RX_ERR */
|
||||
/* PB15 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TX_ERR */
|
||||
/* PB14 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TX_EN */
|
||||
/* PB13 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:COL */
|
||||
/* PB12 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:CRS */
|
||||
/* PB11 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
|
||||
/* PB10 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
|
||||
/* PB9 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
|
||||
/* PB8 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
|
||||
/* PB7 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
|
||||
/* PB6 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
|
||||
/* PB5 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
|
||||
/* PB4 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
|
||||
/* 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 */
|
||||
},
|
||||
|
||||
/* Port C */
|
||||
{ /* conf ppar psor pdir podr pdat */
|
||||
/* PC31 */ { 0, 0, 0, 1, 0, 0 }, /* PC31 */
|
||||
/* PC30 */ { 0, 0, 0, 1, 0, 0 }, /* PC30 */
|
||||
/* PC29 */ { 0, 1, 1, 0, 0, 0 }, /* SCC1 EN *CLSN */
|
||||
/* PC28 */ { 0, 0, 0, 1, 0, 0 }, /* PC28 */
|
||||
/* PC27 */ { 0, 0, 0, 1, 0, 0 }, /* UART Clock in */
|
||||
/* PC26 */ { 0, 0, 0, 1, 0, 0 }, /* PC26 */
|
||||
/* PC25 */ { 0, 0, 0, 1, 0, 0 }, /* PC25 */
|
||||
/* PC24 */ { 0, 0, 0, 1, 0, 0 }, /* PC24 */
|
||||
/* PC23 */ { 0, 1, 0, 1, 0, 0 }, /* ATMTFCLK */
|
||||
/* PC22 */ { 0, 1, 0, 0, 0, 0 }, /* ATMRFCLK */
|
||||
/* PC21 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN RXCLK */
|
||||
/* PC20 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN TXCLK */
|
||||
/* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK CLK13 */
|
||||
/* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC Tx Clock (CLK14) */
|
||||
/* PC17 */ { 0, 0, 0, 1, 0, 0 }, /* PC17 */
|
||||
/* PC16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC Tx Clock (CLK16) */
|
||||
/* PC15 */ { 0, 0, 0, 1, 0, 0 }, /* PC15 */
|
||||
/* PC14 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN *CD */
|
||||
/* PC13 */ { 0, 0, 0, 1, 0, 0 }, /* PC13 */
|
||||
/* PC12 */ { 0, 1, 0, 1, 0, 0 }, /* PC12 */
|
||||
/* PC11 */ { 0, 0, 0, 1, 0, 0 }, /* LXT971 transmit control */
|
||||
/* PC10 */ { 1, 1, 0, 0, 0, 0 }, /* LXT970 FETHMDC */
|
||||
/* PC9 */ { 1, 1, 0, 0, 0, 0 }, /* LXT970 FETHMDIO */
|
||||
/* PC8 */ { 0, 0, 0, 1, 0, 0 }, /* PC8 */
|
||||
/* PC7 */ { 0, 0, 0, 1, 0, 0 }, /* PC7 */
|
||||
/* PC6 */ { 0, 0, 0, 1, 0, 0 }, /* PC6 */
|
||||
/* PC5 */ { 0, 0, 0, 1, 0, 0 }, /* PC5 */
|
||||
/* PC4 */ { 0, 0, 0, 1, 0, 0 }, /* PC4 */
|
||||
/* PC3 */ { 0, 0, 0, 1, 0, 0 }, /* PC3 */
|
||||
/* PC2 */ { 0, 0, 0, 1, 0, 1 }, /* ENET FDE */
|
||||
/* PC1 */ { 0, 0, 0, 1, 0, 0 }, /* ENET DSQE */
|
||||
/* PC0 */ { 0, 0, 0, 1, 0, 0 }, /* ENET LBK */
|
||||
},
|
||||
|
||||
/* Port D */
|
||||
{ /* conf ppar psor pdir podr pdat */
|
||||
/* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RxD */
|
||||
/* PD30 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 EN TxD */
|
||||
/* PD29 */ { 0, 1, 0, 1, 0, 0 }, /* SCC1 EN TENA */
|
||||
/* PD28 */ { 0, 1, 0, 0, 0, 0 }, /* PD28 */
|
||||
/* PD27 */ { 0, 1, 1, 1, 0, 0 }, /* PD27 */
|
||||
/* PD26 */ { 0, 0, 0, 1, 0, 0 }, /* PD26 */
|
||||
/* PD25 */ { 0, 0, 0, 1, 0, 0 }, /* PD25 */
|
||||
/* PD24 */ { 0, 0, 0, 1, 0, 0 }, /* PD24 */
|
||||
/* PD23 */ { 0, 0, 0, 1, 0, 0 }, /* PD23 */
|
||||
/* PD22 */ { 0, 0, 0, 1, 0, 0 }, /* PD22 */
|
||||
/* PD21 */ { 0, 0, 0, 1, 0, 0 }, /* PD21 */
|
||||
/* PD20 */ { 0, 0, 0, 1, 0, 0 }, /* PD20 */
|
||||
/* PD19 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
|
||||
/* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD18 */
|
||||
/* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */
|
||||
/* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */
|
||||
/* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */
|
||||
/* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */
|
||||
/* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* PD13 */
|
||||
/* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* PD12 */
|
||||
/* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* PD11 */
|
||||
/* PD10 */ { 0, 0, 0, 0, 0, 0 }, /* PD10 */
|
||||
/* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1 TXD */
|
||||
/* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1 RXD */
|
||||
/* PD7 */ { 0, 0, 0, 1, 0, 1 }, /* PD7 */
|
||||
/* PD6 */ { 0, 0, 0, 1, 0, 1 }, /* PD6 */
|
||||
/* PD5 */ { 0, 0, 0, 1, 0, 1 }, /* PD5 */
|
||||
/* PD4 */ { 0, 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 */
|
||||
}
|
||||
};
|
||||
|
||||
typedef struct bscr_ {
|
||||
unsigned long bcsr0;
|
||||
unsigned long bcsr1;
|
||||
unsigned long bcsr2;
|
||||
unsigned long bcsr3;
|
||||
unsigned long bcsr4;
|
||||
unsigned long bcsr5;
|
||||
unsigned long bcsr6;
|
||||
unsigned long bcsr7;
|
||||
} bcsr_t;
|
||||
|
||||
void reset_phy(void)
|
||||
{
|
||||
volatile bcsr_t *bcsr = (bcsr_t *)CFG_BCSR;
|
||||
|
||||
/* reset the FEC port */
|
||||
bcsr->bcsr1 &= ~FETH_RST;
|
||||
bcsr->bcsr1 |= FETH_RST;
|
||||
}
|
||||
|
||||
|
||||
int board_pre_init (void)
|
||||
{
|
||||
volatile bcsr_t *bcsr = (bcsr_t *)CFG_BCSR;
|
||||
bcsr->bcsr1 = ~FETHIEN & ~RS232EN_1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
puts ("Board: Motorola MPC8266ADS\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
long int initdram(int board_type)
|
||||
{
|
||||
/* Autoinit part stolen from board/sacsng/sacsng.c */
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile memctl8260_t *memctl = &immap->im_memctl;
|
||||
volatile uchar c = 0xff;
|
||||
volatile uchar *ramaddr = (uchar *)(CFG_SDRAM_BASE + 0x8);
|
||||
uint psdmr = CFG_PSDMR;
|
||||
int i;
|
||||
|
||||
uint psrt = 14; /* for no SPD */
|
||||
uint chipselects = 1; /* for no SPD */
|
||||
uint sdram_size = CFG_SDRAM_SIZE * 1024 * 1024; /* for no SPD */
|
||||
uint or = CFG_OR2_PRELIM; /* for no SPD */
|
||||
uint data_width;
|
||||
uint rows;
|
||||
uint banks;
|
||||
uint cols;
|
||||
uint caslatency;
|
||||
uint width;
|
||||
uint rowst;
|
||||
uint sdam;
|
||||
uint bsma;
|
||||
uint sda10;
|
||||
u_char spd_size;
|
||||
u_char data;
|
||||
u_char cksum;
|
||||
int j;
|
||||
|
||||
/* Keep the compiler from complaining about potentially uninitialized vars */
|
||||
data_width = chipselects = rows = banks = cols = caslatency = psrt = 0;
|
||||
|
||||
/*
|
||||
* Read the SDRAM SPD EEPROM via I2C.
|
||||
*/
|
||||
i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
|
||||
|
||||
i2c_read(SDRAM_SPD_ADDR, 0, 1, &data, 1);
|
||||
spd_size = data;
|
||||
cksum = data;
|
||||
for(j = 1; j < 64; j++)
|
||||
{ /* read only the checksummed bytes */
|
||||
/* note: the I2C address autoincrements when alen == 0 */
|
||||
i2c_read(SDRAM_SPD_ADDR, 0, 0, &data, 1);
|
||||
/*printf("addr %d = 0x%02x\n", j, data);*/
|
||||
if(j == 5) chipselects = data & 0x0F;
|
||||
else if(j == 6) data_width = data;
|
||||
else if(j == 7) data_width |= data << 8;
|
||||
else if(j == 3) rows = data & 0x0F;
|
||||
else if(j == 4) cols = data & 0x0F;
|
||||
else if(j == 12)
|
||||
{
|
||||
/*
|
||||
* Refresh rate: this assumes the prescaler is set to
|
||||
* approximately 1uSec per tick.
|
||||
*/
|
||||
switch(data & 0x7F)
|
||||
{
|
||||
default:
|
||||
case 0: psrt = 16; /* 15.625uS */ break;
|
||||
case 1: psrt = 2; /* 3.9uS */ break;
|
||||
case 2: psrt = 6; /* 7.8uS */ break;
|
||||
case 3: psrt = 29; /* 31.3uS */ break;
|
||||
case 4: psrt = 60; /* 62.5uS */ break;
|
||||
case 5: psrt = 120; /* 125uS */ break;
|
||||
}
|
||||
}
|
||||
else if(j == 17) banks = data;
|
||||
else if(j == 18)
|
||||
{
|
||||
caslatency = 3; /* default CL */
|
||||
# if(PESSIMISTIC_SDRAM)
|
||||
if((data & 0x04) != 0) caslatency = 3;
|
||||
else if((data & 0x02) != 0) caslatency = 2;
|
||||
else if((data & 0x01) != 0) caslatency = 1;
|
||||
# else
|
||||
if((data & 0x01) != 0) caslatency = 1;
|
||||
else if((data & 0x02) != 0) caslatency = 2;
|
||||
else if((data & 0x04) != 0) caslatency = 3;
|
||||
# endif
|
||||
else
|
||||
{
|
||||
printf ("WARNING: Unknown CAS latency 0x%02X, using 3\n",
|
||||
data);
|
||||
}
|
||||
}
|
||||
else if(j == 63)
|
||||
{
|
||||
if(data != cksum)
|
||||
{
|
||||
printf ("WARNING: Configuration data checksum failure:"
|
||||
" is 0x%02x, calculated 0x%02x\n",
|
||||
data, cksum);
|
||||
}
|
||||
}
|
||||
cksum += data;
|
||||
}
|
||||
|
||||
/* We don't trust CL less than 2 (only saw it on an old 16MByte DIMM) */
|
||||
if(caslatency < 2) {
|
||||
printf("CL was %d, forcing to 2\n", caslatency);
|
||||
caslatency = 2;
|
||||
}
|
||||
if(rows > 14) {
|
||||
printf("This doesn't look good, rows = %d, should be <= 14\n", rows);
|
||||
rows = 14;
|
||||
}
|
||||
if(cols > 11) {
|
||||
printf("This doesn't look good, columns = %d, should be <= 11\n", cols);
|
||||
cols = 11;
|
||||
}
|
||||
|
||||
if((data_width != 64) && (data_width != 72))
|
||||
{
|
||||
printf("WARNING: SDRAM width unsupported, is %d, expected 64 or 72.\n",
|
||||
data_width);
|
||||
}
|
||||
width = 3; /* 2^3 = 8 bytes = 64 bits wide */
|
||||
/*
|
||||
* Convert banks into log2(banks)
|
||||
*/
|
||||
if (banks == 2) banks = 1;
|
||||
else if(banks == 4) banks = 2;
|
||||
else if(banks == 8) banks = 3;
|
||||
|
||||
|
||||
sdram_size = 1 << (rows + cols + banks + width);
|
||||
|
||||
#if(CONFIG_PBI == 0) /* bank-based interleaving */
|
||||
rowst = ((32 - 6) - (rows + cols + width)) * 2;
|
||||
#else
|
||||
rowst = 32 - (rows + banks + cols + width);
|
||||
#endif
|
||||
|
||||
or = ~(sdram_size - 1) | /* SDAM address mask */
|
||||
((banks-1) << 13) | /* banks per device */
|
||||
(rowst << 9) | /* rowst */
|
||||
((rows - 9) << 6); /* numr */
|
||||
|
||||
|
||||
/*printf("memctl->memc_or2 = 0x%08x\n", or);*/
|
||||
|
||||
/*
|
||||
* SDAM specifies the number of columns that are multiplexed
|
||||
* (reference AN2165/D), defined to be (columns - 6) for page
|
||||
* interleave, (columns - 8) for bank interleave.
|
||||
*
|
||||
* BSMA is 14 - max(rows, cols). The bank select lines come
|
||||
* into play above the highest "address" line going into the
|
||||
* the SDRAM.
|
||||
*/
|
||||
#if(CONFIG_PBI == 0) /* bank-based interleaving */
|
||||
sdam = cols - 8;
|
||||
bsma = ((31 - width) - 14) - ((rows > cols) ? rows : cols);
|
||||
sda10 = sdam + 2;
|
||||
#else
|
||||
sdam = cols - 6;
|
||||
bsma = ((31 - width) - 14) - ((rows > cols) ? rows : cols);
|
||||
sda10 = sdam;
|
||||
#endif
|
||||
#if(PESSIMISTIC_SDRAM)
|
||||
psdmr = (CONFIG_PBI |\
|
||||
PSDMR_RFEN |\
|
||||
PSDMR_RFRC_16_CLK |\
|
||||
PSDMR_PRETOACT_8W |\
|
||||
PSDMR_ACTTORW_8W |\
|
||||
PSDMR_WRC_4C |\
|
||||
PSDMR_EAMUX |\
|
||||
PSDMR_BUFCMD) |\
|
||||
caslatency |\
|
||||
((caslatency - 1) << 6) | /* LDOTOPRE is CL - 1 */ \
|
||||
(sdam << 24) |\
|
||||
(bsma << 21) |\
|
||||
(sda10 << 18);
|
||||
#else
|
||||
psdmr = (CONFIG_PBI |\
|
||||
PSDMR_RFEN |\
|
||||
PSDMR_RFRC_7_CLK |\
|
||||
PSDMR_PRETOACT_3W | /* 1 for 7E parts (fast PC-133) */ \
|
||||
PSDMR_ACTTORW_2W | /* 1 for 7E parts (fast PC-133) */ \
|
||||
PSDMR_WRC_1C | /* 1 clock + 7nSec */
|
||||
EAMUX |\
|
||||
BUFCMD) |\
|
||||
caslatency |\
|
||||
((caslatency - 1) << 6) | /* LDOTOPRE is CL - 1 */ \
|
||||
(sdam << 24) |\
|
||||
(bsma << 21) |\
|
||||
(sda10 << 18);
|
||||
#endif
|
||||
/*printf("psdmr = 0x%08x\n", psdmr);*/
|
||||
|
||||
/*
|
||||
* Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
|
||||
*
|
||||
* "At system reset, initialization software must set up the
|
||||
* programmable parameters in the memory controller banks registers
|
||||
* (ORx, BRx, P/LSDMR). After all memory parameters are configured,
|
||||
* system software should execute the following initialization sequence
|
||||
* for each SDRAM device.
|
||||
*
|
||||
* 1. Issue a PRECHARGE-ALL-BANKS command
|
||||
* 2. Issue eight CBR REFRESH commands
|
||||
* 3. Issue a MODE-SET command to initialize the mode register
|
||||
*
|
||||
* Quote from Micron MT48LC8M16A2 data sheet:
|
||||
*
|
||||
* "...the SDRAM requires a 100uS delay prior to issuing any
|
||||
* command other than a COMMAND INHIBIT or NOP. Starting at some
|
||||
* point during this 100uS period and continuing at least through
|
||||
* the end of this period, COMMAND INHIBIT or NOP commands should
|
||||
* be applied."
|
||||
*
|
||||
* "Once the 100uS delay has been satisfied with at least one COMMAND
|
||||
* INHIBIT or NOP command having been applied, a /PRECHARGE command/
|
||||
* should be applied. All banks must then be precharged, thereby
|
||||
* placing the device in the all banks idle state."
|
||||
*
|
||||
* "Once in the idle state, /two/ AUTO REFRESH cycles must be
|
||||
* performed. After the AUTO REFRESH cycles are complete, the
|
||||
* SDRAM is ready for mode register programming."
|
||||
*
|
||||
* (/emphasis/ mine, gvb)
|
||||
*
|
||||
* The way I interpret this, Micron start up sequence is:
|
||||
* 1. Issue a PRECHARGE-BANK command (initial precharge)
|
||||
* 2. Issue a PRECHARGE-ALL-BANKS command ("all banks ... precharged")
|
||||
* 3. Issue two (presumably, doing eight is OK) CBR REFRESH commands
|
||||
* 4. Issue a MODE-SET command to initialize the mode register
|
||||
*
|
||||
* --------
|
||||
*
|
||||
* The initial commands are executed by setting P/LSDMR[OP] and
|
||||
* accessing the SDRAM with a single-byte transaction."
|
||||
*
|
||||
* The appropriate BRx/ORx registers have already been set when we
|
||||
* get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
|
||||
*/
|
||||
#if 1
|
||||
memctl->memc_mptpr = CFG_MPTPR;
|
||||
memctl->memc_psrt = psrt;
|
||||
|
||||
memctl->memc_psdmr = psdmr | PSDMR_OP_PREA;
|
||||
*ramaddr = c;
|
||||
|
||||
memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR;
|
||||
for (i = 0; i < 8; i++)
|
||||
*ramaddr = c;
|
||||
|
||||
memctl->memc_psdmr = psdmr | PSDMR_OP_MRW;
|
||||
*ramaddr = c;
|
||||
|
||||
memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN;
|
||||
*ramaddr = c;
|
||||
|
||||
/*
|
||||
* Do it a second time for the second set of chips if the DIMM has
|
||||
* two chip selects (double sided).
|
||||
*/
|
||||
if(chipselects > 1)
|
||||
{
|
||||
ramaddr += sdram_size;
|
||||
|
||||
memctl->memc_br3 = CFG_BR3_PRELIM + sdram_size;
|
||||
memctl->memc_or3 = or;
|
||||
|
||||
memctl->memc_psdmr = psdmr | PSDMR_OP_PREA;
|
||||
*ramaddr = c;
|
||||
|
||||
memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR;
|
||||
for (i = 0; i < 8; i++)
|
||||
*ramaddr = c;
|
||||
|
||||
memctl->memc_psdmr = psdmr | PSDMR_OP_MRW;
|
||||
*ramaddr = c;
|
||||
|
||||
memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN;
|
||||
*ramaddr = c;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
printf("memctl->memc_mptpr = 0x%08x\n", CFG_MPTPR);
|
||||
printf("memctl->memc_psrt = 0x%08x\n", psrt);
|
||||
|
||||
printf("memctl->memc_psdmr = 0x%08x\n", psdmr | PSDMR_OP_PREA);
|
||||
printf("ramaddr = 0x%08x\n", ramaddr);
|
||||
|
||||
printf("memctl->memc_psdmr = 0x%08x\n", psdmr | PSDMR_OP_CBRR);
|
||||
|
||||
printf("memctl->memc_psdmr = 0x%08x\n", psdmr | PSDMR_OP_MRW);
|
||||
|
||||
printf("memctl->memc_psdmr = 0x%08x\n", psdmr | PSDMR_OP_NORM | PSDMR_RFEN);
|
||||
|
||||
immap->im_siu_conf.sc_ppc_acr = 0x00000002;
|
||||
immap->im_siu_conf.sc_ppc_alrh = 0x01267893;
|
||||
immap->im_siu_conf.sc_tescr1 = 0x00004000;
|
||||
*/
|
||||
#if 0
|
||||
/* init sdram dimm */
|
||||
ramaddr = (uchar *)CFG_SDRAM_BASE;
|
||||
memctl->memc_psrt = 0x00000010;
|
||||
immap->im_memctl.memc_or2 = 0xFF000CA0;
|
||||
immap->im_memctl.memc_br2 = 0x00000041;
|
||||
memctl->memc_psdmr = 0x296EB452;
|
||||
*ramaddr = c;
|
||||
memctl->memc_psdmr = 0x096EB452;
|
||||
for (i = 0; i < 8; i++)
|
||||
*ramaddr = c;
|
||||
|
||||
memctl->memc_psdmr = 0x196EB452;
|
||||
*ramaddr = c;
|
||||
memctl->memc_psdmr = 0x416EB452;
|
||||
*ramaddr = c;
|
||||
#endif
|
||||
/* print info */
|
||||
printf("SDRAM configuration read from SPD\n");
|
||||
printf("\tSize per side = %dMB\n", sdram_size >> 20);
|
||||
printf("\tOrganization: %d sides, %d banks, %d Columns, %d Rows, Data width = %d bits\n", chipselects, 1<<(banks), cols, rows, data_width);
|
||||
printf("\tRefresh rate = %d, CAS latency = %d\n", psrt, caslatency);
|
||||
printf("\tTotal size: ");
|
||||
|
||||
return (sdram_size * chipselects);
|
||||
/*return (16 * 1024 * 1024);*/
|
||||
}
|
||||
117
board/mpc8266ads/u-boot.lds
Normal file
117
board/mpc8266ads/u-boot.lds
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* (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/mpc8260/start.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 = .);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ static struct pci_controller hose = {
|
||||
fixup_irq: pci_pip405_fixup_irq,
|
||||
};
|
||||
|
||||
void pci_init(void)
|
||||
void pci_init_board(void)
|
||||
{
|
||||
/*we want the ptrs to RAM not flash (ie don't use init list)*/
|
||||
hose.fixup_irq = pci_pip405_fixup_irq;
|
||||
|
||||
@@ -124,7 +124,7 @@ struct pci_controller hose = {
|
||||
#endif
|
||||
};
|
||||
|
||||
void pci_init(void)
|
||||
void pci_init_board(void)
|
||||
{
|
||||
pci_mpc824x_init(&hose);
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ static struct pci_controller hose = {
|
||||
#endif
|
||||
};
|
||||
|
||||
void pci_init (void)
|
||||
void pci_init_board (void)
|
||||
{
|
||||
pci_mpc824x_init(&hose);
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ int misc_init_r (void)
|
||||
return (0);
|
||||
}
|
||||
|
||||
void pci_init (void)
|
||||
void pci_init_board (void)
|
||||
{
|
||||
cpc710_pci_init ();
|
||||
|
||||
|
||||
@@ -72,20 +72,27 @@ const iop_conf_t iop_conf_tab[4][32] = {
|
||||
|
||||
/* Port B configuration */
|
||||
{ /* conf ppar psor pdir podr pdat */
|
||||
/* PB31 */ { 0, 1, 0, 1, 0, 0 }, /* PB31 */
|
||||
/* PB30 */ { 0, 1, 0, 0, 0, 0 }, /* PB30 */
|
||||
/* PB29 */ { 0, 1, 1, 1, 0, 0 }, /* PB29 */
|
||||
/* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TX_ER */
|
||||
/* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RX_DV */
|
||||
/* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 TX_EN */
|
||||
#if defined(CONFIG_ETHER_ON_SCC) && (CONFIG_ETHER_INDEX == 1)
|
||||
#ifdef CONFIG_ETHER_ON_FCC2
|
||||
#error "SCC1 conflicts with FCC2"
|
||||
#endif
|
||||
/* PB28 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 TXD */
|
||||
/* PB27 */ { 0, 1, 0, 0, 0, 0 }, /* PB27 */
|
||||
/* PB26 */ { 0, 1, 0, 0, 0, 0 }, /* PB26 */
|
||||
/* PB25 */ { 0, 1, 0, 1, 0, 0 }, /* PB25 */
|
||||
/* PB24 */ { 0, 1, 0, 1, 0, 0 }, /* PB24 */
|
||||
/* PB23 */ { 0, 1, 0, 1, 0, 0 }, /* PB23 */
|
||||
/* PB22 */ { 0, 1, 0, 1, 0, 0 }, /* PB22 */
|
||||
/* PB21 */ { 0, 1, 0, 0, 0, 0 }, /* PB21 */
|
||||
/* PB20 */ { 0, 1, 0, 0, 0, 0 }, /* PB20 */
|
||||
/* PB19 */ { 0, 1, 0, 0, 0, 0 }, /* PB19 */
|
||||
/* PB18 */ { 0, 1, 0, 0, 0, 0 }, /* PB18 */
|
||||
#else
|
||||
/* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RX_ER */
|
||||
#endif
|
||||
/* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 COL */
|
||||
/* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 CRS */
|
||||
/* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TxD[3] */
|
||||
/* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TxD[2] */
|
||||
/* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TxD[1] */
|
||||
/* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TxD[0] */
|
||||
/* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RxD[0] */
|
||||
/* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RxD[1] */
|
||||
/* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RxD[2] */
|
||||
/* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RxD[3] */
|
||||
/* PB17 */ { 0, 0, 0, 0, 0, 0 }, /* PB17 */
|
||||
/* PB16 */ { 0, 0, 0, 0, 0, 0 }, /* PB16 */
|
||||
/* PB15 */ { 1, 1, 0, 0, 0, 0 }, /* SCC2 RXD */
|
||||
@@ -119,9 +126,9 @@ const iop_conf_t iop_conf_tab[4][32] = {
|
||||
/* PC23 */ { 0, 1, 0, 1, 0, 0 }, /* PC23 */
|
||||
/* PC22 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 TXCK */
|
||||
/* PC21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 RXCK */
|
||||
/* PC20 */ { 0, 1, 0, 0, 0, 0 }, /* PC20 */
|
||||
/* PC19 */ { 0, 1, 0, 0, 0, 0 }, /* PC19 */
|
||||
/* PC18 */ { 0, 1, 0, 0, 0, 0 }, /* PC18 */
|
||||
/* PC20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 TXCK(2) */
|
||||
/* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RXCK */
|
||||
/* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 TXCK */
|
||||
/* PC17 */ { 0, 0, 0, 1, 0, 0 }, /* PC17 */
|
||||
/* PC16 */ { 0, 0, 0, 1, 0, 0 }, /* PC16 */
|
||||
/* PC15 */ { 1, 1, 0, 1, 0, 0 }, /* SMC2 TXD */
|
||||
|
||||
@@ -137,7 +137,7 @@ long int initdram (int board_type)
|
||||
struct pci_controller hose = {
|
||||
};
|
||||
|
||||
void pci_init (void)
|
||||
void pci_init_board (void)
|
||||
{
|
||||
show_startup_phase (4);
|
||||
pci_mpc824x_init (&hose);
|
||||
|
||||
@@ -24,10 +24,12 @@
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc8xx.h>
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
#if defined(CFG_ENV_IS_IN_FLASH)
|
||||
# ifndef CFG_ENV_ADDR
|
||||
@@ -52,44 +54,44 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
#define FLASH_PORT_WIDTH16
|
||||
|
||||
#ifdef FLASH_PORT_WIDTH16
|
||||
#define FLASH_PORT_WIDTH ushort
|
||||
#define FLASH_PORT_WIDTHV vu_short
|
||||
#define FLASH_PORT_WIDTH ushort
|
||||
#define FLASH_PORT_WIDTHV vu_short
|
||||
#else
|
||||
#define FLASH_PORT_WIDTH ulong
|
||||
#define FLASH_PORT_WIDTHV vu_long
|
||||
#define FLASH_PORT_WIDTH ulong
|
||||
#define FLASH_PORT_WIDTHV vu_long
|
||||
#endif
|
||||
|
||||
#define FPW FLASH_PORT_WIDTH
|
||||
#define FPWV FLASH_PORT_WIDTHV
|
||||
#define FPW FLASH_PORT_WIDTH
|
||||
#define FPWV FLASH_PORT_WIDTHV
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static ulong flash_get_size (FPW *addr, flash_info_t *info);
|
||||
static int write_data (flash_info_t *info, ulong dest, FPW data);
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info);
|
||||
static ulong flash_get_size (FPW * addr, flash_info_t * info);
|
||||
static int write_data (flash_info_t * info, ulong dest, FPW 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 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) {
|
||||
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((FPW *)FLASH_BASE0_PRELIM, &flash_info[0]);
|
||||
size_b0 = flash_get_size ((FPW *) FLASH_BASE0_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);
|
||||
size_b0, size_b0 << 20);
|
||||
}
|
||||
|
||||
/* Remap FLASH according to real size */
|
||||
@@ -97,24 +99,24 @@ unsigned long flash_init (void)
|
||||
memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_PS_16 | BR_MS_GPCM | BR_V;
|
||||
|
||||
/* Re-do sizing to get full correct info */
|
||||
size_b0 = flash_get_size((FPW *)CFG_FLASH_BASE, &flash_info[0]);
|
||||
size_b0 = flash_get_size ((FPW *) 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 */
|
||||
(void)flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_FLASH_BASE,
|
||||
CFG_FLASH_BASE+CFG_MONITOR_LEN-1,
|
||||
&flash_info[0]);
|
||||
(void) flash_protect (FLAG_PROTECT_SET,
|
||||
CFG_FLASH_BASE,
|
||||
CFG_FLASH_BASE + CFG_MONITOR_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]);
|
||||
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;
|
||||
@@ -124,7 +126,7 @@ unsigned long flash_init (void)
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info)
|
||||
static void flash_get_offsets (ulong base, flash_info_t * info)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -141,7 +143,7 @@ static void flash_get_offsets (ulong base, flash_info_t *info)
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
void flash_print_info (flash_info_t *info)
|
||||
void flash_print_info (flash_info_t * info)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -151,31 +153,39 @@ void flash_print_info (flash_info_t *info)
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_INTEL: printf ("INTEL "); break;
|
||||
default: printf ("Unknown Vendor "); break;
|
||||
case FLASH_MAN_INTEL:
|
||||
printf ("INTEL ");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Vendor ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_28F320J3A:
|
||||
printf ("28F320J3A\n"); break;
|
||||
case FLASH_28F640J3A:
|
||||
printf ("28F640J3A\n"); break;
|
||||
case FLASH_28F128J3A:
|
||||
printf ("28F128J3A\n"); break;
|
||||
default: printf ("Unknown Chip Type\n"); break;
|
||||
case FLASH_28F320J3A:
|
||||
printf ("28F320J3A\n");
|
||||
break;
|
||||
case FLASH_28F640J3A:
|
||||
printf ("28F640J3A\n");
|
||||
break;
|
||||
case FLASH_28F128J3A:
|
||||
printf ("28F128J3A\n");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Chip Type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf (" Size: %ld MB in %d Sectors\n",
|
||||
info->size >> 20, info->sector_count);
|
||||
info->size >> 20, info->sector_count);
|
||||
|
||||
printf (" Sector Start Addresses:");
|
||||
for (i=0; i<info->sector_count; ++i) {
|
||||
for (i = 0; i < info->sector_count; ++i) {
|
||||
if ((i % 5) == 0)
|
||||
printf ("\n ");
|
||||
printf (" %08lX%s",
|
||||
info->start[i],
|
||||
info->protect[i] ? " (RO)" : " "
|
||||
);
|
||||
info->protect[i] ? " (RO)" : " ");
|
||||
}
|
||||
printf ("\n");
|
||||
return;
|
||||
@@ -192,49 +202,53 @@ void flash_print_info (flash_info_t *info)
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
|
||||
static ulong flash_get_size (FPW *addr, flash_info_t *info)
|
||||
static ulong flash_get_size (FPW * addr, flash_info_t * info)
|
||||
{
|
||||
FPW value;
|
||||
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
addr[0x5555] = (FPW)0x00AA00AA;
|
||||
addr[0x2AAA] = (FPW)0x00550055;
|
||||
addr[0x5555] = (FPW)0x00900090;
|
||||
addr[0x5555] = (FPW) 0x00AA00AA;
|
||||
addr[0x2AAA] = (FPW) 0x00550055;
|
||||
addr[0x5555] = (FPW) 0x00900090;
|
||||
|
||||
value = addr[0];
|
||||
|
||||
switch (value) {
|
||||
case (FPW)INTEL_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_INTEL;
|
||||
break;
|
||||
debug ("Manuf. ID @ 0x%08lx: 0x%08lx\n", (ulong)addr, value);
|
||||
|
||||
switch (value) {
|
||||
case (FPW) INTEL_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_INTEL;
|
||||
break;
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
addr[0] = (FPW)0x00FF00FF; /* restore read mode */
|
||||
return (0); /* no or unknown flash */
|
||||
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
value = addr[1]; /* device ID */
|
||||
value = addr[1]; /* device ID */
|
||||
|
||||
switch (value) {
|
||||
case (FPW)INTEL_ID_28F320J3A:
|
||||
info->flash_id += FLASH_28F320J3A;
|
||||
info->sector_count = 32;
|
||||
info->size = 0x00400000;
|
||||
break; /* => 4 MB */
|
||||
debug ("Device ID @ 0x%08lx: 0x%08lx\n", (ulong)(&addr[1]), value);
|
||||
|
||||
case (FPW)INTEL_ID_28F640J3A:
|
||||
info->flash_id += FLASH_28F640J3A;
|
||||
info->sector_count = 64;
|
||||
info->size = 0x00800000;
|
||||
break; /* => 8 MB */
|
||||
switch (value) {
|
||||
case (FPW) INTEL_ID_28F320J3A:
|
||||
info->flash_id += FLASH_28F320J3A;
|
||||
info->sector_count = 32;
|
||||
info->size = 0x00400000;
|
||||
break; /* => 4 MB */
|
||||
|
||||
case (FPW)INTEL_ID_28F128J3A:
|
||||
info->flash_id += FLASH_28F128J3A;
|
||||
info->sector_count = 128;
|
||||
info->size = 0x01000000;
|
||||
break; /* => 16 MB */
|
||||
case (FPW) INTEL_ID_28F640J3A:
|
||||
info->flash_id += FLASH_28F640J3A;
|
||||
info->sector_count = 64;
|
||||
info->size = 0x00800000;
|
||||
break; /* => 8 MB */
|
||||
|
||||
case (FPW) INTEL_ID_28F128J3A:
|
||||
info->flash_id += FLASH_28F128J3A;
|
||||
info->sector_count = 128;
|
||||
info->size = 0x01000000;
|
||||
break; /* => 16 MB */
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
@@ -243,11 +257,11 @@ static ulong flash_get_size (FPW *addr, flash_info_t *info)
|
||||
|
||||
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);
|
||||
info->sector_count = CFG_MAX_FLASH_SECT;
|
||||
}
|
||||
|
||||
addr[0] = (FPW)0x00FF00FF; /* restore read mode */
|
||||
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
@@ -256,7 +270,7 @@ static ulong flash_get_size (FPW *addr, flash_info_t *info)
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
int flag, prot, sect;
|
||||
ulong type, start, now, last;
|
||||
@@ -279,7 +293,7 @@ int 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++;
|
||||
}
|
||||
@@ -293,44 +307,44 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
}
|
||||
|
||||
start = get_timer (0);
|
||||
last = start;
|
||||
last = start;
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect<=s_last; sect++) {
|
||||
for (sect = s_first; sect <= s_last; sect++) {
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
FPWV *addr = (FPWV *)(info->start[sect]);
|
||||
FPWV *addr = (FPWV *) (info->start[sect]);
|
||||
FPW status;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
flag = disable_interrupts ();
|
||||
|
||||
*addr = (FPW)0x00500050; /* clear status register */
|
||||
*addr = (FPW)0x00200020; /* erase setup */
|
||||
*addr = (FPW)0x00D000D0; /* erase confirm */
|
||||
*addr = (FPW) 0x00500050; /* clear status register */
|
||||
*addr = (FPW) 0x00200020; /* erase setup */
|
||||
*addr = (FPW) 0x00D000D0; /* erase confirm */
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
enable_interrupts ();
|
||||
|
||||
/* wait at least 80us - let's wait 1 ms */
|
||||
udelay (1000);
|
||||
|
||||
while (((status = *addr) & (FPW)0x00800080) != (FPW)0x00800080) {
|
||||
if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout\n");
|
||||
*addr = (FPW)0x00B000B0; /* suspend erase */
|
||||
*addr = (FPW)0x00FF00FF; /* reset to read mode */
|
||||
rcode = 1;
|
||||
break;
|
||||
}
|
||||
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
|
||||
if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout\n");
|
||||
*addr = (FPW) 0x00B000B0; /* suspend erase */
|
||||
*addr = (FPW) 0x00FF00FF; /* reset to read mode */
|
||||
rcode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* show that we're waiting */
|
||||
if ((now - last) > 1000) { /* every second */
|
||||
putc ('.');
|
||||
last = now;
|
||||
}
|
||||
/* show that we're waiting */
|
||||
if ((now - last) > 1000) { /* every second */
|
||||
putc ('.');
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
|
||||
*addr = (FPW)0x00FF00FF; /* reset to read mode */
|
||||
*addr = (FPW) 0x00FF00FF; /* reset to read mode */
|
||||
}
|
||||
}
|
||||
printf (" done\n");
|
||||
@@ -345,15 +359,12 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
* 4 - Flash not identified
|
||||
*/
|
||||
|
||||
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 cp, wp;
|
||||
FPW data;
|
||||
#if 0
|
||||
int count, i, l, rc, port_width;
|
||||
#else
|
||||
|
||||
int i, l, rc, port_width;
|
||||
#endif
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
return 4;
|
||||
@@ -372,19 +383,19 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
*/
|
||||
if ((l = addr - wp) != 0) {
|
||||
data = 0;
|
||||
for (i=0, cp=wp; i<l; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
for (i = 0, cp = wp; i < l; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
for (; i<port_width && cnt>0; ++i) {
|
||||
for (; i < port_width && cnt > 0; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
++cp;
|
||||
}
|
||||
for (; cnt==0 && i<port_width; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
for (; cnt == 0 && i < port_width; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
|
||||
if ((rc = write_data(info, wp, data)) != 0) {
|
||||
if ((rc = write_data (info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += port_width;
|
||||
@@ -393,26 +404,16 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
/*
|
||||
* handle word aligned part
|
||||
*/
|
||||
#if 0
|
||||
count = 0;
|
||||
#endif
|
||||
while (cnt >= port_width) {
|
||||
data = 0;
|
||||
for (i=0; i<port_width; ++i) {
|
||||
for (i = 0; i < port_width; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
}
|
||||
if ((rc = write_data(info, wp, data)) != 0) {
|
||||
if ((rc = write_data (info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += port_width;
|
||||
wp += port_width;
|
||||
cnt -= port_width;
|
||||
#if 0
|
||||
if (count++ > 0x20000)
|
||||
{
|
||||
putc('.');
|
||||
count = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
@@ -423,15 +424,15 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
* handle unaligned tail bytes
|
||||
*/
|
||||
data = 0;
|
||||
for (i=0, cp=wp; i<port_width && cnt>0; ++i, ++cp) {
|
||||
for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
}
|
||||
for (; i<port_width; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
for (; i < port_width; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
|
||||
return (write_data(info, wp, data));
|
||||
return (write_data (info, wp, data));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
@@ -440,39 +441,38 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
static int write_data (flash_info_t *info, ulong dest, FPW data)
|
||||
static int write_data (flash_info_t * info, ulong dest, FPW data)
|
||||
{
|
||||
FPWV *addr = (FPWV *)dest;
|
||||
FPWV *addr = (FPWV *) dest;
|
||||
ulong status;
|
||||
ulong start;
|
||||
int flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*addr & data) != data) {
|
||||
printf("not erased at %08lx (%x)\n",(ulong)addr,*addr);
|
||||
printf ("not erased at %08lx (%x)\n", (ulong) addr, *addr);
|
||||
return (2);
|
||||
}
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
flag = disable_interrupts ();
|
||||
|
||||
*addr = (FPW)0x00400040; /* write setup */
|
||||
*addr = (FPW) 0x00400040; /* write setup */
|
||||
*addr = data;
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
enable_interrupts ();
|
||||
|
||||
start = get_timer (0);
|
||||
|
||||
while (((status = *addr) & (FPW)0x00800080) != (FPW)0x00800080) {
|
||||
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
|
||||
*addr = (FPW)0x00FF00FF; /* restore read mode */
|
||||
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
|
||||
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
|
||||
*addr = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
*addr = (FPW)0x00FF00FF; /* restore read mode */
|
||||
*addr = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ struct pci_controller hose = {
|
||||
#endif
|
||||
};
|
||||
|
||||
void pci_init(void)
|
||||
void pci_init_board(void)
|
||||
{
|
||||
pci_mpc824x_init(&hose);
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ static struct pci_controller sc520_cdp_hose = {
|
||||
fixup_irq: pci_sc520_cdp_fixup_irq,
|
||||
};
|
||||
|
||||
void pci_init(void)
|
||||
void pci_init_board(void)
|
||||
{
|
||||
pci_sc520_init(&sc520_cdp_hose);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ ulong flash_init (void)
|
||||
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;
|
||||
flashbase = CFG_FLASH_BASE;
|
||||
else
|
||||
panic ("configured too many flash banks!\n");
|
||||
for (j = 0; j < flash_info[i].sector_count; j++) {
|
||||
|
||||
@@ -26,12 +26,7 @@
|
||||
#include <common.h>
|
||||
#include <environment.h>
|
||||
|
||||
ulong myflush (void);
|
||||
|
||||
|
||||
#define FLASH_BANK_SIZE 0x800000 /* 8 MB */
|
||||
/* this varies depending on the sector */
|
||||
#define MAIN_SECT_SIZE 0x20000 /* 2 x 64 kB */
|
||||
static ulong flash_get_size (vu_long *addr, flash_info_t *info);
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
|
||||
|
||||
@@ -43,6 +38,7 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
|
||||
#define CMD_ERASE_CONFIRM 0x00300030
|
||||
#define CMD_PROGRAM 0x00A000A0
|
||||
#define CMD_UNLOCK_BYPASS 0x00200020
|
||||
#define CMD_READ_MANF_ID 0x00900090
|
||||
|
||||
#define MEM_FLASH_ADDR1 (*(volatile u32 *)(CFG_FLASH_BASE + (0x00000555 << 2)))
|
||||
#define MEM_FLASH_ADDR2 (*(volatile u32 *)(CFG_FLASH_BASE + (0x000002AA << 2)))
|
||||
@@ -64,27 +60,38 @@ ulong flash_init (void)
|
||||
int i, j;
|
||||
ulong size = 0;
|
||||
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
|
||||
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
|
||||
ulong flashbase = 0;
|
||||
flash_info_t *info = &flash_info[i];
|
||||
|
||||
/* Init: no FLASHes known */
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
|
||||
size += flash_get_size (CFG_FLASH_BASE, info);
|
||||
|
||||
flash_info[i].flash_id =
|
||||
(AMD_MANUFACT & FLASH_VENDMASK) |
|
||||
(AMD_ID_LV320B & 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;
|
||||
flashbase = CFG_FLASH_BASE;
|
||||
else
|
||||
panic ("configured too many flash banks!\n");
|
||||
for (j = 0; j < flash_info[i].sector_count; j++) {
|
||||
for (j = 0; j < info->sector_count; j++) {
|
||||
|
||||
flash_info[i].start[j] = flashbase;
|
||||
info->protect[j] = 0;
|
||||
info->start[j] = flashbase;
|
||||
|
||||
/* the first 8 sectors are 8 kB */
|
||||
flashbase += (j < 8) ? 0x4000 : MAIN_SECT_SIZE;
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case (FLASH_AM320B & FLASH_TYPEMASK):
|
||||
/* Boot sector type: 8 x 8 + N x 128 kB */
|
||||
flashbase += (j < 8) ? 0x4000 : 0x20000;
|
||||
break;
|
||||
case (FLASH_AM640U & FLASH_TYPEMASK):
|
||||
/* Uniform sector type: 128 kB */
|
||||
flashbase += 0x20000;
|
||||
break;
|
||||
default:
|
||||
printf ("## Bad flash chip type 0x%04lX\n",
|
||||
info->flash_id & FLASH_TYPEMASK);
|
||||
}
|
||||
}
|
||||
size += flash_info[i].size;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -116,7 +123,7 @@ void flash_print_info (flash_info_t * info)
|
||||
int i;
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case (AMD_MANUFACT & FLASH_VENDMASK):
|
||||
case (FLASH_MAN_AMD & FLASH_VENDMASK):
|
||||
printf ("AMD: ");
|
||||
break;
|
||||
default:
|
||||
@@ -125,9 +132,12 @@ void flash_print_info (flash_info_t * info)
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case (AMD_ID_LV320B & FLASH_TYPEMASK):
|
||||
case (FLASH_AM320B & FLASH_TYPEMASK):
|
||||
printf ("2x Am29LV320DB (32Mbit)\n");
|
||||
break;
|
||||
case (FLASH_AM640U & FLASH_TYPEMASK):
|
||||
printf ("2x Am29LV640D (64Mbit)\n");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Chip Type\n");
|
||||
goto Done;
|
||||
@@ -177,7 +187,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
|
||||
}
|
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) !=
|
||||
(AMD_MANUFACT & FLASH_VENDMASK)) {
|
||||
(FLASH_MAN_AMD & FLASH_VENDMASK)) {
|
||||
return ERR_UNKNOWN_FLASH_VENDOR;
|
||||
}
|
||||
|
||||
@@ -265,13 +275,6 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
|
||||
rc = ERR_TIMOUT;
|
||||
goto outahere;
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf ("ok.\n");
|
||||
} else { /* it was protected */
|
||||
|
||||
printf ("protected!\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,3 +456,71 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
|
||||
|
||||
return write_word (info, wp, data);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static ulong flash_get_size (vu_long *addr, flash_info_t *info)
|
||||
{
|
||||
ulong value;
|
||||
|
||||
/* Write auto select command sequence and read Manufacturer ID */
|
||||
addr[0x0555] = CMD_UNLOCK1;
|
||||
addr[0x02AA] = CMD_UNLOCK2;
|
||||
addr[0x0555] = CMD_READ_MANF_ID;
|
||||
|
||||
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;
|
||||
break;
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
addr[0] = 0x00FF00FF; /* restore read mode */
|
||||
debug ("## flash_init: unknown manufacturer\n");
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
value = addr[1]; /* device ID */
|
||||
|
||||
debug ("Device ID @ 0x%08lx: 0x%08lx\n", (ulong)(&addr[1]), value);
|
||||
|
||||
switch (value) {
|
||||
case AMD_ID_LV320B:
|
||||
info->flash_id += FLASH_AM320B;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00800000;
|
||||
|
||||
addr[0] = 0x00FF00FF; /* restore read mode */
|
||||
break; /* => 8 MB */
|
||||
|
||||
case AMD_ID_LV640U:
|
||||
info->flash_id += FLASH_AM640U;
|
||||
info->sector_count = 128;
|
||||
info->size = 0x01000000;
|
||||
|
||||
addr[0] = 0x00F000F0; /* restore read mode */
|
||||
break; /* => 16 MB */
|
||||
|
||||
default:
|
||||
debug ("## flash_init: unknown flash chip\n");
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
addr[0] = 0x00FF00FF; /* restore read mode */
|
||||
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;
|
||||
}
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
@@ -60,11 +60,8 @@ static void udelay_no_timer (int usec)
|
||||
|
||||
int board_init ()
|
||||
{
|
||||
#if defined(CONFIG_MODEM_SUPPORT) && defined(CONFIG_VFD)
|
||||
ulong size;
|
||||
unsigned long addr;
|
||||
extern void mem_malloc_init (ulong);
|
||||
extern int drv_vfd_init(void);
|
||||
#if defined(CONFIG_VFD)
|
||||
extern int vfd_init_clocks(void);
|
||||
#endif
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@@ -107,26 +104,11 @@ int board_init ()
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = 0x0c000100;
|
||||
|
||||
#ifdef CONFIG_MODEM_SUPPORT
|
||||
#ifdef CONFIG_VFD
|
||||
#ifndef PAGE_SIZE
|
||||
#define PAGE_SIZE 4096
|
||||
#endif
|
||||
/*
|
||||
* reserve memory for VFD display (always full pages)
|
||||
*/
|
||||
/* armboot_real_end is defined in the board-specific linker script */
|
||||
addr = (_armboot_real_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
|
||||
size = vfd_setmem (addr);
|
||||
gd->fb_base = addr;
|
||||
/* round to the next page boundary */
|
||||
addr += size;
|
||||
addr = (addr + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
|
||||
mem_malloc_init (addr);
|
||||
/* must do this after the framebuffer is allocated */
|
||||
drv_vfd_init();
|
||||
vfd_init_clocks();
|
||||
#endif /* CONFIG_VFD */
|
||||
|
||||
#ifdef CONFIG_MODEM_SUPPORT
|
||||
udelay_no_timer (KBD_MDELAY);
|
||||
|
||||
if (key_pressed()) {
|
||||
|
||||
472
board/trab/vfd.c
472
board/trab/vfd.c
@@ -55,12 +55,16 @@
|
||||
#define BLAU 0x0C
|
||||
#define VIOLETT 0X0D
|
||||
|
||||
ulong vfdbase;
|
||||
ulong frame_buf_size;
|
||||
ulong vfdbase;
|
||||
ulong frame_buf_size;
|
||||
#define frame_buf_offs 4
|
||||
|
||||
/* Supported VFD Types */
|
||||
#define VFD_TYPE_T119C 1 /* Noritake T119C VFD */
|
||||
#define VFD_TYPE_MN11236 2
|
||||
|
||||
/* taken from armboot/common/vfd.c */
|
||||
ulong adr_vfd_table[112][18][2][4][2];
|
||||
unsigned long adr_vfd_table[112][18][2][4][2];
|
||||
unsigned char bit_vfd_table[112][18][2][4][2];
|
||||
|
||||
/*
|
||||
@@ -68,26 +72,42 @@ unsigned char bit_vfd_table[112][18][2][4][2];
|
||||
*/
|
||||
void init_grid_ctrl(void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
ulong adr, grid_cycle;
|
||||
unsigned int bit, display;
|
||||
unsigned char temp, bit_nr;
|
||||
ulong val;
|
||||
|
||||
for (adr=vfdbase; adr<=(vfdbase+7168); adr+=4) /*clear frame buffer */
|
||||
(*(volatile ulong*)(adr))=0;
|
||||
/*
|
||||
* clear frame buffer (logical clear => set to "black")
|
||||
*/
|
||||
if (gd->vfd_inv_data == 0)
|
||||
val = 0;
|
||||
else
|
||||
val = ~0;
|
||||
|
||||
for(display=0;display<=3;display++)
|
||||
{
|
||||
for(grid_cycle=0;grid_cycle<=55;grid_cycle++)
|
||||
{
|
||||
bit = grid_cycle*256*4+(grid_cycle+200)*4+frame_buf_offs+display;
|
||||
for (adr = vfdbase; adr <= (vfdbase+7168); adr += 4) {
|
||||
(*(volatile ulong*)(adr)) = val;
|
||||
}
|
||||
|
||||
switch (gd->vfd_type) {
|
||||
case VFD_TYPE_T119C:
|
||||
for (display=0; display<4; display++) {
|
||||
for(grid_cycle=0; grid_cycle<56; grid_cycle++) {
|
||||
bit = grid_cycle * 256 * 4 +
|
||||
(grid_cycle + 200) * 4 +
|
||||
frame_buf_offs + display;
|
||||
/* wrap arround if offset (see manual S3C2400) */
|
||||
if (bit>=frame_buf_size*8)
|
||||
bit = bit-(frame_buf_size*8);
|
||||
adr = vfdbase+(bit/32)*4+(3-(bit%32)/8);
|
||||
bit_nr = bit%8;
|
||||
bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
|
||||
bit = bit - (frame_buf_size * 8);
|
||||
adr = vfdbase + (bit/32) * 4 + (3 - (bit%32) / 8);
|
||||
bit_nr = bit % 8;
|
||||
bit_nr = (bit_nr > 3) ? bit_nr-4 : bit_nr+4;
|
||||
temp=(*(volatile unsigned char*)(adr));
|
||||
temp|=(1<<bit_nr);
|
||||
if (gd->vfd_inv_data)
|
||||
temp &= ~(1<<bit_nr);
|
||||
else
|
||||
temp |= (1<<bit_nr);
|
||||
(*(volatile unsigned char*)(adr))=temp;
|
||||
|
||||
if(grid_cycle<55)
|
||||
@@ -101,9 +121,54 @@ void init_grid_ctrl(void)
|
||||
bit_nr = bit%8;
|
||||
bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
|
||||
temp=(*(volatile unsigned char*)(adr));
|
||||
temp|=(1<<bit_nr);
|
||||
if (gd->vfd_inv_data)
|
||||
temp &= ~(1<<bit_nr);
|
||||
else
|
||||
temp |= (1<<bit_nr);
|
||||
(*(volatile unsigned char*)(adr))=temp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VFD_TYPE_MN11236:
|
||||
for (display=0; display<4; display++) {
|
||||
for (grid_cycle=0; grid_cycle<38; grid_cycle++) {
|
||||
bit = grid_cycle * 256 * 4 +
|
||||
(253 - grid_cycle) * 4 +
|
||||
frame_buf_offs + display;
|
||||
/* wrap arround if offset (see manual S3C2400) */
|
||||
if (bit>=frame_buf_size*8)
|
||||
bit = bit - (frame_buf_size * 8);
|
||||
adr = vfdbase + (bit/32) * 4 + (3 - (bit%32) / 8);
|
||||
bit_nr = bit % 8;
|
||||
bit_nr = (bit_nr > 3) ? bit_nr-4 : bit_nr+4;
|
||||
temp=(*(volatile unsigned char*)(adr));
|
||||
if (gd->vfd_inv_data)
|
||||
temp &= ~(1<<bit_nr);
|
||||
else
|
||||
temp |= (1<<bit_nr);
|
||||
(*(volatile unsigned char*)(adr))=temp;
|
||||
|
||||
if(grid_cycle<37)
|
||||
bit = grid_cycle*256*4+(252-grid_cycle)*4+frame_buf_offs+display;
|
||||
|
||||
/* wrap arround if offset (see manual S3C2400) */
|
||||
if (bit>=frame_buf_size*8)
|
||||
bit = bit-(frame_buf_size*8);
|
||||
adr = vfdbase+(bit/32)*4+(3-(bit%32)/8);
|
||||
bit_nr = bit%8;
|
||||
bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
|
||||
temp=(*(volatile unsigned char*)(adr));
|
||||
if (gd->vfd_inv_data)
|
||||
temp &= ~(1<<bit_nr);
|
||||
else
|
||||
temp |= (1<<bit_nr);
|
||||
(*(volatile unsigned char*)(adr))=temp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf ("Warning: unknown display type\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,175 +178,142 @@ void init_grid_ctrl(void)
|
||||
*/
|
||||
void create_vfd_table(void)
|
||||
{
|
||||
unsigned int vfd_table[112][18][2][4][2];
|
||||
ulong adr;
|
||||
unsigned int x, y, color, display, entry, pixel, bit_nr;
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
unsigned long vfd_table[112][18][2][4][2];
|
||||
unsigned int x, y, color, display, entry, pixel;
|
||||
unsigned int x_abcdef = 0;
|
||||
|
||||
/*
|
||||
* Create translation table for Noritake-T119C-VFD-specific
|
||||
* organized frame-buffer.
|
||||
* Created is the number of the bit in the framebuffer (the
|
||||
* first transferred pixel of each frame is bit 0).
|
||||
*/
|
||||
for(y=0;y<=17;y++) /* Zeile */
|
||||
{
|
||||
for(x=0;x<=111;x++) /* Spalten */
|
||||
{
|
||||
/*Display 0 blaue Pixel Eintrag 1 */
|
||||
vfd_table[x][y][0][0][0]=((x%4)*4+y*16+(x/4)*2048);
|
||||
/*Display 0 rote Pixel Eintrag 1 */
|
||||
vfd_table[x][y][1][0][0]=((x%4)*4+y*16+(x/4)*2048+512);
|
||||
if(x<=1)
|
||||
{
|
||||
/*Display 0 blaue Pixel Eintrag 2 */
|
||||
vfd_table[x][y][0][0][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+1024);
|
||||
/*Display 0 rote Pixel Eintrag 2 */
|
||||
vfd_table[x][y][1][0][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+1024);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Display 0 blaue Pixel Eintrag 2 */
|
||||
vfd_table[x][y][0][0][1]=((x%4)*4+y*16+((x-2)/4)*2048+1024);
|
||||
/*Display 0 rote Pixel Eintrag 2 */
|
||||
vfd_table[x][y][1][0][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+1024);
|
||||
}
|
||||
/*Display 1 blaue Pixel Eintrag 1 */
|
||||
vfd_table[x][y][0][1][0]=((x%4)*4+y*16+(x/4)*2048+1);
|
||||
/*Display 1 rote Pixel Eintrag 1 */
|
||||
vfd_table[x][y][1][1][0]=((x%4)*4+y*16+(x/4)*2048+512+1);
|
||||
if(x<=1)
|
||||
{
|
||||
/*Display 1 blaue Pixel Eintrag 2 */
|
||||
vfd_table[x][y][0][1][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+1+1024);
|
||||
/*Display 1 rote Pixel Eintrag 2 */
|
||||
vfd_table[x][y][1][1][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+1+1024);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Display 1 blaue Pixel Eintrag 2 */
|
||||
vfd_table[x][y][0][1][1]=((x%4)*4+y*16+((x-2)/4)*2048+1+1024);
|
||||
/*Display 1 rote Pixel Eintrag 2 */
|
||||
vfd_table[x][y][1][1][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+1+1024);
|
||||
}
|
||||
/*Display 2 blaue Pixel Eintrag 1 */
|
||||
vfd_table[x][y][0][2][0]=((x%4)*4+y*16+(x/4)*2048+2);
|
||||
/*Display 2 rote Pixel Eintrag 1 */
|
||||
vfd_table[x][y][1][2][0]=((x%4)*4+y*16+(x/4)*2048+512+2);
|
||||
if(x<=1)
|
||||
{
|
||||
/*Display 2 blaue Pixel Eintrag 2 */
|
||||
vfd_table[x][y][0][2][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+2+1024);
|
||||
/*Display 2 rote Pixel Eintrag 2 */
|
||||
vfd_table[x][y][1][2][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+2+1024);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Display 2 blaue Pixel Eintrag 2 */
|
||||
vfd_table[x][y][0][2][1]=((x%4)*4+y*16+((x-2)/4)*2048+2+1024);
|
||||
/*Display 2 rote Pixel Eintrag 2 */
|
||||
vfd_table[x][y][1][2][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+2+1024);
|
||||
}
|
||||
/*Display 3 blaue Pixel Eintrag 1 */
|
||||
vfd_table[x][y][0][3][0]=((x%4)*4+y*16+(x/4)*2048+3);
|
||||
/*Display 3 rote Pixel Eintrag 1 */
|
||||
vfd_table[x][y][1][3][0]=((x%4)*4+y*16+(x/4)*2048+512+3);
|
||||
if(x<=1)
|
||||
{
|
||||
/*Display 3 blaue Pixel Eintrag 2 */
|
||||
vfd_table[x][y][0][3][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+3+1024);
|
||||
/*Display 3 rote Pixel Eintrag 2 */
|
||||
vfd_table[x][y][1][3][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+3+1024);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Display 3 blaue Pixel Eintrag 2 */
|
||||
vfd_table[x][y][0][3][1]=((x%4)*4+y*16+((x-2)/4)*2048+3+1024);
|
||||
/*Display 3 rote Pixel Eintrag 2 */
|
||||
vfd_table[x][y][1][3][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+3+1024);
|
||||
}
|
||||
switch (gd->vfd_type) {
|
||||
case VFD_TYPE_T119C:
|
||||
for(y=0; y<=17; y++) { /* Line */
|
||||
for(x=0; x<=111; x++) { /* Column */
|
||||
for(display=0; display <=3; display++) {
|
||||
|
||||
/* Display 0 blue pixels */
|
||||
vfd_table[x][y][0][display][0] =
|
||||
(x==0) ? y*16+display
|
||||
: (x%4)*4+y*16+((x-1)/2)*1024+display;
|
||||
/* Display 0 red pixels */
|
||||
vfd_table[x][y][1][display][0] =
|
||||
(x==0) ? y*16+512+display
|
||||
: (x%4)*4+y*16+((x-1)/2)*1024+512+display;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VFD_TYPE_MN11236:
|
||||
for(y=0; y<=17; y++) { /* Line */
|
||||
for(x=0; x<=111; x++) { /* Column */
|
||||
for(display=0; display <=3; display++) {
|
||||
|
||||
vfd_table[x][y][0][display][0]=0;
|
||||
vfd_table[x][y][0][display][1]=0;
|
||||
vfd_table[x][y][1][display][0]=0;
|
||||
vfd_table[x][y][1][display][1]=0;
|
||||
|
||||
switch (x%6) {
|
||||
case 0: x_abcdef=0; break; /* a -> a */
|
||||
case 1: x_abcdef=2; break; /* b -> c */
|
||||
case 2: x_abcdef=4; break; /* c -> e */
|
||||
case 3: x_abcdef=5; break; /* d -> f */
|
||||
case 4: x_abcdef=3; break; /* e -> d */
|
||||
case 5: x_abcdef=1; break; /* f -> b */
|
||||
}
|
||||
|
||||
/* blue pixels */
|
||||
vfd_table[x][y][0][display][0] =
|
||||
(x>1) ? x_abcdef*4+((x-1)/3)*1024+y*48+display
|
||||
: x_abcdef*4+ 0+y*48+display;
|
||||
/* blue pixels */
|
||||
if (x>1 && (x-1)%3)
|
||||
vfd_table[x][y][0][display][1] = x_abcdef*4+((x-1)/3+1)*1024+y*48+display;
|
||||
|
||||
/* red pixels */
|
||||
vfd_table[x][y][1][display][0] =
|
||||
(x>1) ? x_abcdef*4+24+((x-1)/3)*1024+y*48+display
|
||||
: x_abcdef*4+24+ 0+y*48+display;
|
||||
/* red pixels */
|
||||
if (x>1 && (x-1)%3)
|
||||
vfd_table[x][y][1][display][1] = x_abcdef*4+24+((x-1)/3+1)*1024+y*48+display;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create translation table for Noritake-T119C-VFD-specific
|
||||
* organized frame-buffer
|
||||
* Create table with entries for physical byte adresses and
|
||||
* bit-number within the byte
|
||||
* from table with bit-numbers within the total framebuffer
|
||||
*/
|
||||
for(y=0;y<=17;y++)
|
||||
{
|
||||
for(x=0;x<=111;x++)
|
||||
{
|
||||
for(color=0;color<=1;color++)
|
||||
{
|
||||
for(display=0;display<=3;display++)
|
||||
{
|
||||
for(entry=0;entry<=1;entry++)
|
||||
{
|
||||
pixel = vfd_table[x][y][color][display][entry] + frame_buf_offs;
|
||||
/*
|
||||
* wrap arround if offset
|
||||
* (see manual S3C2400)
|
||||
*/
|
||||
if (pixel>=frame_buf_size*8)
|
||||
pixel = pixel-(frame_buf_size*8);
|
||||
adr = vfdbase+(pixel/32)*4+(3-(pixel%32)/8);
|
||||
bit_nr = pixel%8;
|
||||
bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
|
||||
adr_vfd_table[x][y][color][display][entry] = adr;
|
||||
bit_vfd_table[x][y][color][display][entry] = bit_nr;
|
||||
}
|
||||
}
|
||||
for(y=0;y<18;y++) {
|
||||
for(x=0;x<112;x++) {
|
||||
for(color=0;color<2;color++) {
|
||||
for(display=0;display<4;display++) {
|
||||
for(entry=0;entry<2;entry++) {
|
||||
unsigned long adr = vfdbase;
|
||||
unsigned int bit_nr = 0;
|
||||
|
||||
if (vfd_table[x][y][color][display][entry]) {
|
||||
|
||||
pixel = vfd_table[x][y][color][display][entry] + frame_buf_offs;
|
||||
/*
|
||||
* wrap arround if offset
|
||||
* (see manual S3C2400)
|
||||
*/
|
||||
if (pixel>=frame_buf_size*8)
|
||||
pixel = pixel-(frame_buf_size*8);
|
||||
adr = vfdbase+(pixel/32)*4+(3-(pixel%32)/8);
|
||||
bit_nr = pixel%8;
|
||||
bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
|
||||
}
|
||||
adr_vfd_table[x][y][color][display][entry] = adr;
|
||||
bit_vfd_table[x][y][color][display][entry] = bit_nr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set/clear pixel of the VFDs
|
||||
*/
|
||||
void set_vfd_pixel(unsigned char x, unsigned char y, unsigned char color, unsigned char display, unsigned char value)
|
||||
void set_vfd_pixel(unsigned char x, unsigned char y,
|
||||
unsigned char color, unsigned char display,
|
||||
unsigned char value)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
ulong adr;
|
||||
unsigned char bit_nr, temp;
|
||||
|
||||
if (value!=0)
|
||||
{
|
||||
/* Pixel-Eintrag Nr. 1 */
|
||||
adr = adr_vfd_table[x][y][color][display][0];
|
||||
/* Pixel-Eintrag Nr. 1 */
|
||||
bit_nr = bit_vfd_table[x][y][color][display][0];
|
||||
temp=(*(volatile unsigned char*)(adr));
|
||||
temp|=1<<bit_nr;
|
||||
(*(volatile unsigned char*)(adr))=temp;
|
||||
|
||||
/* Pixel-Eintrag Nr. 2 */
|
||||
adr = adr_vfd_table[x][y][color][display][1];
|
||||
/* Pixel-Eintrag Nr. 2 */
|
||||
bit_nr = bit_vfd_table[x][y][color][display][1];
|
||||
temp=(*(volatile unsigned char*)(adr));
|
||||
temp|=1<<bit_nr;
|
||||
(*(volatile unsigned char*)(adr))=temp;
|
||||
if (! gd->vfd_type) {
|
||||
/* Unknown type. */
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Pixel-Eintrag Nr. 1 */
|
||||
adr = adr_vfd_table[x][y][color][display][0];
|
||||
/* Pixel-Eintrag Nr. 1 */
|
||||
bit_nr = bit_vfd_table[x][y][color][display][0];
|
||||
temp=(*(volatile unsigned char*)(adr));
|
||||
temp&=~(1<<bit_nr);
|
||||
(*(volatile unsigned char*)(adr))=temp;
|
||||
|
||||
/* Pixel-Eintrag Nr. 2 */
|
||||
adr = adr_vfd_table[x][y][color][display][1];
|
||||
/* Pixel-Eintrag Nr. 2 */
|
||||
bit_nr = bit_vfd_table[x][y][color][display][1];
|
||||
temp=(*(volatile unsigned char*)(adr));
|
||||
temp&=~(1<<bit_nr);
|
||||
(*(volatile unsigned char*)(adr))=temp;
|
||||
/* Pixel-Eintrag Nr. 1 */
|
||||
adr = adr_vfd_table[x][y][color][display][0];
|
||||
/* Pixel-Eintrag Nr. 1 */
|
||||
bit_nr = bit_vfd_table[x][y][color][display][0];
|
||||
temp=(*(volatile unsigned char*)(adr));
|
||||
|
||||
if (gd->vfd_inv_data) {
|
||||
if (value)
|
||||
temp &= ~(1<<bit_nr);
|
||||
else
|
||||
temp |= (1<<bit_nr);
|
||||
} else {
|
||||
if (value)
|
||||
temp |= (1<<bit_nr);
|
||||
else
|
||||
temp &= ~(1<<bit_nr);
|
||||
}
|
||||
|
||||
(*(volatile unsigned char*)(adr))=temp;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -334,36 +366,11 @@ void transfer_pic(int display, unsigned char *adr, int height, int width)
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize LCD-Controller of the S3C2400 for using VFDs
|
||||
* This function initializes VFD clock that is needed for the CPLD that
|
||||
* manages the keyboard.
|
||||
*/
|
||||
int drv_vfd_init(void)
|
||||
int vfd_init_clocks(void)
|
||||
{
|
||||
ulong palette;
|
||||
static int vfd_init_done = 0;
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
if (vfd_init_done != 0)
|
||||
return (0);
|
||||
vfd_init_done = 1;
|
||||
|
||||
vfdbase = gd->fb_base;
|
||||
create_vfd_table();
|
||||
init_grid_ctrl();
|
||||
|
||||
/*
|
||||
* Hinweis: Der Framebuffer ist um genau ein Nibble verschoben
|
||||
* Das erste angezeigte Pixel wird aus dem zweiten Nibble geholt
|
||||
* das letzte angezeigte Pixel wird aus dem ersten Nibble geholt
|
||||
* (wrap around)
|
||||
* see manual S3C2400
|
||||
*/
|
||||
/* frame buffer startadr */
|
||||
rLCDSADDR1 = vfdbase >> 1;
|
||||
/* frame buffer endadr */
|
||||
rLCDSADDR2 = (vfdbase + frame_buf_size) >> 1;
|
||||
rLCDSADDR3 = ((256/4));
|
||||
|
||||
/* Port-Pins als LCD-Ausgang */
|
||||
rPCCON = (rPCCON & 0xFFFFFF00)| 0x000000AA;
|
||||
/* Port-Pins als LCD-Ausgang */
|
||||
@@ -378,16 +385,93 @@ int drv_vfd_init(void)
|
||||
rLCDCON4 = 0x00000001;
|
||||
rLCDCON5 = 0x00000440;
|
||||
rLCDCON1 = 0x00000B75;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize LCD-Controller of the S3C2400 for using VFDs
|
||||
*/
|
||||
int drv_vfd_init(void)
|
||||
{
|
||||
char *tmp;
|
||||
ulong palette;
|
||||
static int vfd_init_done = 0;
|
||||
int vfd_id;
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
if (vfd_init_done != 0)
|
||||
return (0);
|
||||
vfd_init_done = 1;
|
||||
|
||||
/* try to determine display type from the value
|
||||
* defined by pull-ups
|
||||
*/
|
||||
rPCUP = (rPCUP | 0x000F); /* activate GPC0...GPC3 pullups */
|
||||
rPCCON = (rPCCON & 0xFFFFFF00); /* configure GPC0...GPC3 as inputs */
|
||||
|
||||
vfd_id = (~rPCDAT) & 0x000F; /* read GPC0...GPC3 port pins */
|
||||
debug("Detecting Revison of WA4-VFD: ID=0x%X\n", vfd_id);
|
||||
|
||||
switch (vfd_id) {
|
||||
case 0: /* board revision <= Rev.100 */
|
||||
/*-----*/
|
||||
gd->vfd_inv_data = 0;
|
||||
if (0)
|
||||
gd->vfd_type = VFD_TYPE_MN11236;
|
||||
else
|
||||
gd->vfd_type = VFD_TYPE_T119C;
|
||||
/*-----*/
|
||||
if ((tmp = getenv ("vfd_type")) == NULL) {
|
||||
break;
|
||||
}
|
||||
if (strcmp(tmp, "T119C") == 0) {
|
||||
gd->vfd_type = VFD_TYPE_T119C;
|
||||
} else if (strcmp(tmp, "MN11236") == 0) {
|
||||
gd->vfd_type = VFD_TYPE_MN11236;
|
||||
} else {
|
||||
/* cannot use printf for a warning here */
|
||||
gd->vfd_type = 0; /* unknown */
|
||||
}
|
||||
gd->vfd_inv_data = 0;
|
||||
|
||||
break;
|
||||
default: /* default to MN11236, data inverted */
|
||||
gd->vfd_type = VFD_TYPE_MN11236;
|
||||
gd->vfd_inv_data = 1;
|
||||
setenv ("vfd_type", "MN11236");
|
||||
}
|
||||
debug ("VFD type: %s%s\n",
|
||||
(gd->vfd_type == VFD_TYPE_T119C) ? "T119C" :
|
||||
(gd->vfd_type == VFD_TYPE_MN11236) ? "MN11236" :
|
||||
"unknown",
|
||||
gd->vfd_inv_data ? ", inverted data" : "");
|
||||
|
||||
vfdbase = gd->fb_base;
|
||||
create_vfd_table();
|
||||
init_grid_ctrl();
|
||||
|
||||
for (palette=0; palette < 16; palette++)
|
||||
(*(volatile unsigned int*)(PALETTE+(palette*4)))=palette;
|
||||
for (palette=16; palette < 256; palette++)
|
||||
(*(volatile unsigned int*)(PALETTE+(palette*4)))=0x00;
|
||||
|
||||
/*
|
||||
* Hinweis: Der Framebuffer ist um genau ein Nibble verschoben
|
||||
* Das erste angezeigte Pixel wird aus dem zweiten Nibble geholt
|
||||
* das letzte angezeigte Pixel wird aus dem ersten Nibble geholt
|
||||
* (wrap around)
|
||||
* see manual S3C2400
|
||||
*/
|
||||
/* frame buffer startadr */
|
||||
rLCDSADDR1 = vfdbase >> 1;
|
||||
/* frame buffer endadr */
|
||||
rLCDSADDR2 = (vfdbase + frame_buf_size) >> 1;
|
||||
rLCDSADDR3 = ((256/4));
|
||||
|
||||
debug ("LCDSADDR1: %lX\n", rLCDSADDR1);
|
||||
debug ("LCDSADDR2: %lX\n", rLCDSADDR2);
|
||||
debug ("LCDSADDR3: %lX\n", rLCDSADDR3);
|
||||
|
||||
for(palette=0;palette<=15;palette++)
|
||||
(*(volatile unsigned int*)(PALETTE+(palette*4)))=palette;
|
||||
for(palette=16;palette<=255;palette++)
|
||||
(*(volatile unsigned int*)(PALETTE+(palette*4)))=0x00;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ static struct pci_controller utx8245_hose = {
|
||||
#endif /*CONFIG_PCI_PNP*/
|
||||
};
|
||||
|
||||
void pci_init (void)
|
||||
void pci_init_board (void)
|
||||
{
|
||||
pci_mpc824x_init(&utx8245_hose);
|
||||
|
||||
|
||||
40
board/v37/Makefile
Normal file
40
board/v37/Makefile
Normal file
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# (C) Copyright 2003
|
||||
# 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
|
||||
|
||||
#########################################################################
|
||||
27
board/v37/config.mk
Normal file
27
board/v37/config.mk
Normal file
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# (C) Copyright 2003
|
||||
# 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
|
||||
#
|
||||
|
||||
#
|
||||
# Marel V37 boards
|
||||
#
|
||||
TEXT_BASE = 0x40000000
|
||||
559
board/v37/flash.c
Normal file
559
board/v37/flash.c
Normal file
@@ -0,0 +1,559 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Yoo. Jonghoon, IPone, yooth@ipone.co.kr
|
||||
* PPCboot port on RPXlite board
|
||||
*
|
||||
* Some of flash control words are modified. (from 2x16bit device
|
||||
* to 4x8bit device)
|
||||
* RPXLite board I tested has only 4 AM29LV800BB devices. Other devices
|
||||
* are not tested.
|
||||
*
|
||||
* (?) Does an RPXLite board which
|
||||
* does not use AM29LV800 flash memory exist ?
|
||||
* I don't know...
|
||||
*/
|
||||
|
||||
#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 ( short manu, short dev_id, 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, int two_chips);
|
||||
static void flash_get_id_word( void *ptr, short *ptr_manuf, short *ptr_dev_id);
|
||||
static void flash_get_id_long( void *ptr, short *ptr_manuf, short *ptr_dev_id);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile memctl8xx_t *memctl = &immap->im_memctl;
|
||||
unsigned long size_b0, size_b1;
|
||||
short manu, dev_id;
|
||||
int i;
|
||||
|
||||
/* Init: no FLASHes known */
|
||||
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
|
||||
flash_info[i].flash_id = FLASH_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Do sizing to get full correct info */
|
||||
|
||||
flash_get_id_word((void*)CFG_FLASH_BASE0,&manu,&dev_id);
|
||||
|
||||
size_b0 = flash_get_size(manu, dev_id, &flash_info[0]);
|
||||
|
||||
flash_get_offsets (CFG_FLASH_BASE0, &flash_info[0],0);
|
||||
|
||||
memctl->memc_or0 = CFG_OR_TIMING_FLASH | (0 - size_b0);
|
||||
|
||||
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE0
|
||||
/* monitor protection ON by default */
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_MONITOR_BASE,
|
||||
CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
|
||||
&flash_info[0]);
|
||||
#endif
|
||||
|
||||
flash_get_id_long((void*)CFG_FLASH_BASE1,&manu,&dev_id);
|
||||
|
||||
size_b1 = 2 * flash_get_size(manu, dev_id, &flash_info[1]);
|
||||
|
||||
flash_get_offsets(CFG_FLASH_BASE1, &flash_info[1],1);
|
||||
|
||||
memctl->memc_or1 = CFG_OR_TIMING_FLASH | (0 - size_b1);
|
||||
|
||||
flash_info[0].size = size_b0;
|
||||
flash_info[1].size = size_b1;
|
||||
|
||||
return (size_b0+size_b1);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info, int two_chips)
|
||||
{
|
||||
int i, addr_shift;
|
||||
vu_short *addr = (vu_short*)base;
|
||||
|
||||
addr[0x555] = 0x00AA ;
|
||||
addr[0xAAA] = 0x0055 ;
|
||||
addr[0x555] = 0x0090 ;
|
||||
|
||||
addr_shift = (two_chips ? 2 : 1 );
|
||||
|
||||
/* 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<<addr_shift);
|
||||
info->start[1] = base + (0x00002000<<addr_shift);
|
||||
info->start[2] = base + (0x00003000<<addr_shift);
|
||||
info->start[3] = base + (0x00004000<<addr_shift);
|
||||
for (i = 4; i < info->sector_count; i++) {
|
||||
info->start[i] = base + ((i-3) * (0x00008000<<addr_shift)) ;
|
||||
}
|
||||
} else {
|
||||
/* set sector offsets for top boot block type */
|
||||
i = info->sector_count - 1;
|
||||
info->start[i--] = base + info->size - (0x00002000<<addr_shift);
|
||||
info->start[i--] = base + info->size - (0x00003000<<addr_shift);
|
||||
info->start[i--] = base + info->size - (0x00004000<<addr_shift);
|
||||
for (; i >= 0; i--) {
|
||||
info->start[i] = base + i * (0x00008000<<addr_shift);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 = (vu_short *)(info->start[i]);
|
||||
info->protect[i] = addr[1<<addr_shift] & 1 ;
|
||||
}
|
||||
|
||||
addr = (vu_short *)info->start[0];
|
||||
*addr = 0xF0F0; /* reset bank */
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
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_TOSH: printf ("TOSHIBA "); 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");
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
|
||||
static void flash_get_id_word( void *ptr, short *ptr_manuf, short *ptr_dev_id)
|
||||
{
|
||||
vu_short *addr = (vu_short*)ptr;
|
||||
|
||||
addr[0x555] = 0x00AA ;
|
||||
addr[0xAAA] = 0x0055 ;
|
||||
addr[0x555] = 0x0090 ;
|
||||
|
||||
*ptr_manuf = addr[0];
|
||||
*ptr_dev_id = addr[1];
|
||||
|
||||
addr[0] = 0xf0f0; /* return to normal */
|
||||
}
|
||||
|
||||
static void flash_get_id_long( void *ptr, short *ptr_manuf, short *ptr_dev_id)
|
||||
{
|
||||
vu_short *addr = (vu_short*)ptr;
|
||||
vu_short *addr1, *addr2, *addr3;
|
||||
|
||||
addr1 = (vu_short*) ( ((int)ptr) + (0x5555<<2) );
|
||||
addr2 = (vu_short*) ( ((int)ptr) + (0x2AAA<<2) );
|
||||
addr3 = (vu_short*) ( ((int)ptr) + (0x5555<<2) );
|
||||
|
||||
*addr1 = 0xAAAA;
|
||||
*addr2 = 0x5555;
|
||||
*addr3 = 0x9090;
|
||||
|
||||
*ptr_manuf = addr[0];
|
||||
*ptr_dev_id = addr[2];
|
||||
|
||||
addr[0] = 0xf0f0; /* return to normal */
|
||||
}
|
||||
|
||||
static ulong flash_get_size ( short manu, short dev_id, flash_info_t *info)
|
||||
{
|
||||
switch (manu) {
|
||||
case ((short)AMD_MANUFACT):
|
||||
info->flash_id = FLASH_MAN_AMD;
|
||||
break;
|
||||
case ((short)FUJ_MANUFACT):
|
||||
info->flash_id = FLASH_MAN_FUJ;
|
||||
break;
|
||||
case ((short)TOSH_MANUFACT):
|
||||
info->flash_id = FLASH_MAN_TOSH;
|
||||
break;
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
|
||||
switch (dev_id) {
|
||||
case ((short)TOSH_ID_FVT160):
|
||||
info->flash_id += FLASH_AM160T;
|
||||
info->sector_count = 35;
|
||||
info->size = 0x00200000;
|
||||
break; /* => 1 MB */
|
||||
|
||||
case ((short)TOSH_ID_FVB160):
|
||||
info->flash_id += FLASH_AM160B;
|
||||
info->sector_count = 35;
|
||||
info->size = 0x00200000;
|
||||
break; /* => 1 MB */
|
||||
|
||||
case ((short)AMD_ID_LV400T):
|
||||
info->flash_id += FLASH_AM400T;
|
||||
info->sector_count = 11;
|
||||
info->size = 0x00100000;
|
||||
break; /* => 1 MB */
|
||||
|
||||
case ((short)AMD_ID_LV400B):
|
||||
info->flash_id += FLASH_AM400B;
|
||||
info->sector_count = 11;
|
||||
info->size = 0x00100000;
|
||||
break; /* => 1 MB */
|
||||
|
||||
case ((short)AMD_ID_LV800T):
|
||||
info->flash_id += FLASH_AM800T;
|
||||
info->sector_count = 19;
|
||||
info->size = 0x00200000;
|
||||
break; /* => 2 MB */
|
||||
|
||||
case ((short)AMD_ID_LV800B):
|
||||
info->flash_id += FLASH_AM800B;
|
||||
info->sector_count = 19;
|
||||
info->size = 0x00400000; //%%% Size doubled by yooth
|
||||
break; /* => 4 MB */
|
||||
|
||||
case ((short)AMD_ID_LV160T):
|
||||
info->flash_id += FLASH_AM160T;
|
||||
info->sector_count = 35;
|
||||
info->size = 0x00200000;
|
||||
break; /* => 4 MB */
|
||||
|
||||
case ((short)AMD_ID_LV160B):
|
||||
info->flash_id += FLASH_AM160B;
|
||||
info->sector_count = 35;
|
||||
info->size = 0x00200000;
|
||||
break; /* => 4 MB */
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
return (0); /* => no or unknown flash */
|
||||
|
||||
}
|
||||
|
||||
return(info->size);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
{
|
||||
vu_short *addr = (vu_short*)(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[0x555] = (vu_short)0xAAAAAAAA;
|
||||
addr[0xAAA] = (vu_short)0x55555555;
|
||||
addr[0x555] = (vu_short)0x80808080;
|
||||
addr[0x555] = (vu_short)0xAAAAAAAA;
|
||||
addr[0xAAA] = (vu_short)0x55555555;
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect<=s_last; sect++) {
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
addr = (vu_short *)(info->start[sect]) ;
|
||||
addr[0] = (vu_short)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_short *)(info->start[l_sect]);
|
||||
while ((addr[0] & 0x8080) != 0x8080) {
|
||||
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_short *)info->start[0];
|
||||
addr[0] = (vu_short)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_short *addr = (vu_short *)(info->start[0]);
|
||||
vu_short sdata;
|
||||
|
||||
ulong start;
|
||||
int flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*((vu_long *)dest) & data) != data) {
|
||||
return (2);
|
||||
}
|
||||
|
||||
/* First write upper 16 bits */
|
||||
sdata = (short)(data>>16);
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
addr[0x555] = 0xAAAA;
|
||||
addr[0xAAA] = 0x5555;
|
||||
addr[0x555] = 0xA0A0;
|
||||
|
||||
*((vu_short *)dest) = sdata;
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
/* data polling for D7 */
|
||||
start = get_timer (0);
|
||||
while ((*((vu_short *)dest) & 0x8080) != (sdata & 0x8080)) {
|
||||
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now write lower 16 bits */
|
||||
sdata = (short)(data&0xffff);
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
addr[0x555] = 0xAAAA;
|
||||
addr[0xAAA] = 0x5555;
|
||||
addr[0x555] = 0xA0A0;
|
||||
|
||||
*((vu_short *)dest + 1) = sdata;
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
/* data polling for D7 */
|
||||
start = get_timer (0);
|
||||
while ((*((vu_short *)dest + 1) & 0x8080) != (sdata & 0x8080)) {
|
||||
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
142
board/v37/u-boot.lds
Normal file
142
board/v37/u-boot.lds
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* 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)
|
||||
cpu/mpc8xx/traps.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)
|
||||
lib_ppc/cache.o (.text)
|
||||
lib_ppc/time.o (.text)
|
||||
|
||||
/*
|
||||
. = env_offset;
|
||||
*/
|
||||
common/environment.o (.ppcenv)
|
||||
|
||||
*(.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 = .);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
218
board/v37/v37.c
Normal file
218
board/v37/v37.c
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Yoo. Jonghoon, IPone, yooth@ipone.co.kr
|
||||
* PPCboot port on RPXlite board
|
||||
*
|
||||
* DRAM related UPMA register values are modified.
|
||||
* See RPXLite engineering note : 50MHz/60ns - UPM RAM WORDS
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include "mpc8xx.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static long int dram_size (void);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define MBYTE (1024*1024)
|
||||
#define DRAM_DELAY 0x00000379 /* DRAM delay count */
|
||||
#define _NOT_USED_ 0xFFFFCC25
|
||||
|
||||
const uint sdram_table[] =
|
||||
{
|
||||
/* single read. (offset 0 in upm RAM) */
|
||||
0x1F07D004, 0xEEAEE004, 0x11ADD004, 0xEFBBA000,
|
||||
0x1FF75447, 0x1FF77C34, 0xEFEABC34, 0x1FB57C35,
|
||||
|
||||
/* burst read. (Offset 8 in upm RAM) */
|
||||
0x1F07D004, 0xEEAEE004, 0x00ADC004, 0x00AFC000,
|
||||
0x00AFC000, 0x01AFC000, 0x0FBB8000, 0x1FF75447,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
|
||||
/* single write. (Offset 0x18 in upm RAM) */
|
||||
0x1F27D004, 0xEEAEA000, 0x01B90004, 0x1FF75447,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
|
||||
/* burst write. (Offset 0x20 in upm RAM) */
|
||||
0x1F07D004, 0xEEAEA000, 0x00AD4000, 0x00AFC000,
|
||||
0x00AFC000, 0x01BB8004, 0x1FF75447, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
|
||||
/* Refresh cycle, offset 0x30 */
|
||||
0x1FF5DC84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
|
||||
0xFFFFFC84, 0xFFFFFC07, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
|
||||
/* Exception, 0ffset 0x3C */
|
||||
0x7FFFFC07, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
};
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/*
|
||||
* Check Board Identity:
|
||||
*
|
||||
* Return 1 for now.
|
||||
*
|
||||
*/
|
||||
|
||||
int checkboard (void)
|
||||
{
|
||||
printf("Marel V37\n") ;
|
||||
return (0) ;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
long int initdram (int board_type)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile memctl8xx_t *memctl = &immap->im_memctl;
|
||||
unsigned long temp;
|
||||
volatile int delay_cnt;
|
||||
long int ramsize;
|
||||
|
||||
ramsize = dram_size();
|
||||
|
||||
/* Refresh clock prescalar */
|
||||
memctl->memc_mptpr = 0x400 ;
|
||||
|
||||
if( ramsize == 32*MBYTE )
|
||||
temp = 0xd0904110;
|
||||
else /* 16MB */
|
||||
temp = 0xd0802110;
|
||||
|
||||
memctl->memc_mbmr = temp;
|
||||
|
||||
upmconfig(UPMB, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
|
||||
|
||||
/* Map controller banks 2 to the SDRAM bank */
|
||||
memctl->memc_or2 = 0xA00 | (0 - ramsize);
|
||||
memctl->memc_br2 = 0xC1;
|
||||
|
||||
memctl->memc_mbmr = temp | 0x08;
|
||||
memctl->memc_mcr = 0x80804130;
|
||||
|
||||
delay_cnt = 0;
|
||||
while( delay_cnt++ < DRAM_DELAY )
|
||||
;
|
||||
|
||||
/* Run MRS command in location 5-8 of UPMB */
|
||||
|
||||
memctl->memc_mbmr = temp | 0x04;
|
||||
memctl->memc_mar = 0x88;
|
||||
|
||||
memctl->memc_mcr = 0x80804105;
|
||||
|
||||
delay_cnt = 0;
|
||||
while( delay_cnt++ < DRAM_DELAY )
|
||||
;
|
||||
|
||||
#ifdef CONFIG_CAN_DRIVER
|
||||
/* Initialize OR3 / BR3 */
|
||||
memctl->memc_or3 = CFG_OR3_CAN;
|
||||
memctl->memc_br3 = CFG_BR3_CAN;
|
||||
|
||||
/* Initialize MBMR */
|
||||
memctl->memc_mamr = MAMR_GPL_B4DIS; /* GPL_B4 ouput line Disable */
|
||||
|
||||
/* Initialize UPMB for CAN: single read */
|
||||
memctl->memc_mdr = 0xFFFFC004;
|
||||
memctl->memc_mcr = 0x0100 | UPMA;
|
||||
|
||||
memctl->memc_mdr = 0x0FFFD004;
|
||||
memctl->memc_mcr = 0x0101 | UPMA;
|
||||
|
||||
memctl->memc_mdr = 0x0FFFC000;
|
||||
memctl->memc_mcr = 0x0102 | UPMA;
|
||||
|
||||
memctl->memc_mdr = 0x3FFFC004;
|
||||
memctl->memc_mcr = 0x0103 | UPMA;
|
||||
|
||||
memctl->memc_mdr = 0xFFFFDC05;
|
||||
memctl->memc_mcr = 0x0104 | UPMA;
|
||||
|
||||
/* Initialize UPMB for CAN: single write */
|
||||
memctl->memc_mdr = 0xFFFCC004;
|
||||
memctl->memc_mcr = 0x0118 | UPMA;
|
||||
|
||||
memctl->memc_mdr = 0xCFFCD004;
|
||||
memctl->memc_mcr = 0x0119 | UPMA;
|
||||
|
||||
memctl->memc_mdr = 0x0FFCC000;
|
||||
memctl->memc_mcr = 0x011A | UPMA;
|
||||
|
||||
memctl->memc_mdr = 0x7FFCC004;
|
||||
memctl->memc_mcr = 0x011B | UPMA;
|
||||
|
||||
memctl->memc_mdr = 0xFFFDCC05;
|
||||
memctl->memc_mcr = 0x011C | UPMA;
|
||||
#endif /* CONFIG_CAN_DRIVER */
|
||||
|
||||
return (dram_size());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Find size of RAM from configuration pins.
|
||||
* The input pins that contain the memory size are also the debug port
|
||||
* pins. Normally they are configured as debug port pins. To be able
|
||||
* to read the memory configuration, we must deactivate the debug port
|
||||
* and enable the pcmcia input pins. Then return the register to
|
||||
* previous state.
|
||||
*/
|
||||
|
||||
static long int dram_size ()
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile sysconf8xx_t *siu = &immap->im_siu_conf;
|
||||
volatile pcmconf8xx_t *pcm = &immap->im_pcmcia;
|
||||
long int i, memory=1;
|
||||
unsigned long siu_mcr;
|
||||
|
||||
siu_mcr = siu->sc_siumcr;
|
||||
siu->sc_siumcr = siu_mcr & 0xFF9FFFFF;
|
||||
for(i=0; i<10; i++) i = i;
|
||||
|
||||
memory = (pcm->pcmc_pipr>>12) & 0x3;
|
||||
|
||||
siu->sc_siumcr = siu_mcr;
|
||||
|
||||
switch( memory )
|
||||
{
|
||||
case 1:
|
||||
return( 32*MBYTE );
|
||||
case 2:
|
||||
return( 64*MBYTE );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return( 16*MBYTE );
|
||||
}
|
||||
@@ -162,6 +162,7 @@ sdram_init:
|
||||
* contents of the SPD EEPROM. If the SPD EEPROM is blank or
|
||||
* erronious, spd_sdram returns 0 in R3.
|
||||
*/
|
||||
li r3,0
|
||||
bl spd_sdram
|
||||
addic. r3, r3, 0 /* Check for error, save dram size */
|
||||
bne ..sdri_done /* If it worked, we're done... */
|
||||
|
||||
@@ -20,13 +20,11 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
long int spd_sdram (void);
|
||||
|
||||
#include <common.h>
|
||||
#include "walnut405.h"
|
||||
#include <asm/processor.h>
|
||||
|
||||
|
||||
#include <spd_sdram.h>
|
||||
|
||||
int board_pre_init (void)
|
||||
{
|
||||
@@ -118,11 +116,8 @@ int checkboard (void)
|
||||
the necessary info for SDRAM controller configuration
|
||||
------------------------------------------------------------------------- */
|
||||
long int initdram (int board_type)
|
||||
{
|
||||
long int ret;
|
||||
|
||||
ret = spd_sdram ();
|
||||
return ret;
|
||||
{
|
||||
return spd_sdram (0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
@@ -192,6 +192,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
if (hdr->ih_arch != IH_CPU_ARM)
|
||||
#elif defined(__I386__)
|
||||
if (hdr->ih_arch != IH_CPU_I386)
|
||||
#elif defined(__mips__)
|
||||
if (hdr->ih_arch != IH_CPU_MIPS)
|
||||
#else
|
||||
# error Unknown CPU type
|
||||
#endif
|
||||
|
||||
@@ -288,7 +288,7 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn
|
||||
*/
|
||||
contr_reg[0] = 0;
|
||||
for (i = 0; i < MAX_ACKNOWLEDGE_POLLS; i++) {
|
||||
if (i2c_read (addr_void[0], addr_void[1], 1, contr_reg, 1) == 1)
|
||||
if (i2c_read (addr_void[0], addr_void[1], 1, contr_reg, 1) == 0)
|
||||
break; /* got ack */
|
||||
#if defined(CFG_EEPROM_PAGE_WRITE_DELAY_MS)
|
||||
udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
|
||||
|
||||
@@ -252,11 +252,13 @@ int valid_elf_image (unsigned long addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (ehdr->e_machine != EM_PPC) {
|
||||
printf ("## Not a PowerPC elf image at address 0x%08lx\n",
|
||||
addr);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -489,11 +489,14 @@ void ide_init (void)
|
||||
|
||||
#ifdef CONFIG_IDE_8xx_PCCARD
|
||||
extern int pcmcia_on (void);
|
||||
extern int ide_devices_found; /* Initialized in check_ide_device() */
|
||||
|
||||
WATCHDOG_RESET();
|
||||
|
||||
ide_devices_found = 0;
|
||||
/* initialize the PCMCIA IDE adapter card */
|
||||
if (pcmcia_on())
|
||||
pcmcia_on();
|
||||
if (!ide_devices_found)
|
||||
return;
|
||||
udelay (1000000); /* 1 s */
|
||||
#endif /* CONFIG_IDE_8xx_PCCARD */
|
||||
@@ -550,6 +553,13 @@ void ide_init (void)
|
||||
int dev = bus * (CFG_IDE_MAXDEVICE / max_bus_scan);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IDE_8xx_PCCARD
|
||||
/* Skip non-ide devices from probing */
|
||||
if ((ide_devices_found & (1 << bus)) == 0) {
|
||||
ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
printf ("Bus %d: ", bus);
|
||||
|
||||
ide_bus_ok[bus] = 0;
|
||||
|
||||
@@ -232,6 +232,10 @@ int _do_setenv (int flag, int argc, char *argv[])
|
||||
baudrate);
|
||||
udelay(50000);
|
||||
gd->baudrate = baudrate;
|
||||
#ifdef CONFIG_PPC
|
||||
gd->bd->bi_baudrate = baudrate;
|
||||
#endif
|
||||
|
||||
serial_setbrg ();
|
||||
udelay(50000);
|
||||
for (;;) {
|
||||
|
||||
@@ -268,6 +268,7 @@ static int pcmcia_off (void)
|
||||
#define MAX_TUPEL_SZ 512
|
||||
#define MAX_FEATURES 4
|
||||
|
||||
int ide_devices_found;
|
||||
static int check_ide_device (int slot)
|
||||
{
|
||||
volatile uchar *ident = NULL;
|
||||
@@ -282,7 +283,7 @@ static int check_ide_device (int slot)
|
||||
|
||||
addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
|
||||
CFG_PCMCIA_MEM_SIZE * (slot * 4));
|
||||
debug ("PCMCIA MEM: %08X\n", addr);
|
||||
debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
|
||||
|
||||
start = p = (volatile uchar *) addr;
|
||||
|
||||
@@ -347,6 +348,8 @@ static int check_ide_device (int slot)
|
||||
return (1);
|
||||
}
|
||||
|
||||
ide_devices_found |= (1 << slot);
|
||||
|
||||
/* set I/O area in config reg -> only valid for ARGOSY D5!!! */
|
||||
*((uchar *)(addr + config_base)) = 1;
|
||||
|
||||
|
||||
@@ -128,6 +128,9 @@ uchar default_environment[] = {
|
||||
#ifdef CONFIG_CLOCKS_IN_MHZ
|
||||
"clocks_in_mhz=1\0"
|
||||
#endif
|
||||
#if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0)
|
||||
"pcidelay=" MK_STR(CONFIG_PCI_BOOTDELAY) "\0"
|
||||
#endif
|
||||
#ifdef CONFIG_EXTRA_ENV_SETTINGS
|
||||
CONFIG_EXTRA_ENV_SETTINGS
|
||||
#endif
|
||||
|
||||
@@ -374,4 +374,4 @@ void env_relocate_spec (void)
|
||||
#endif /* ! ENV_IS_EMBEDDED || CFG_ENV_ADDR_REDUND */
|
||||
}
|
||||
|
||||
#endif /* CFG_ENV_IS_IN_FLASH) */
|
||||
#endif /* CFG_ENV_IS_IN_FLASH */
|
||||
|
||||
@@ -164,10 +164,13 @@ env_t environment __PPCENV__ = {
|
||||
#ifdef CONFIG_CLOCKS_IN_MHZ
|
||||
"clocks_in_mhz=" "1" "\0"
|
||||
#endif
|
||||
#if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0)
|
||||
"pcidelay=" MK_STR(CONFIG_PCI_BOOTDELAY) "\0"
|
||||
#endif
|
||||
#ifdef CONFIG_EXTRA_ENV_SETTINGS
|
||||
CONFIG_EXTRA_ENV_SETTINGS
|
||||
#endif
|
||||
"\0" /* Term. env_t.data with 2 NULLs */
|
||||
"\0" /* Term. env_t.data with 2 NULs */
|
||||
}
|
||||
};
|
||||
#ifdef CFG_ENV_ADDR_REDUND
|
||||
|
||||
@@ -117,14 +117,15 @@
|
||||
/* #include <dmalloc.h> */
|
||||
/* #define DEBUG_SHELL */
|
||||
|
||||
#ifdef BB_VER
|
||||
#if 1
|
||||
#include "busybox.h"
|
||||
#include "cmdedit.h"
|
||||
#else
|
||||
#define applet_name "hush"
|
||||
#include "standalone.h"
|
||||
#define hush_main main
|
||||
#undef BB_FEATURE_SH_FANCY_PROMPT
|
||||
#undef CONFIG_FEATURE_SH_FANCY_PROMPT
|
||||
#define BB_BANNER
|
||||
#endif
|
||||
#endif
|
||||
#define SPECIAL_VAR_SYMBOL 03
|
||||
@@ -430,7 +431,7 @@ static void setup_string_in_str(struct in_str *i, const char *s);
|
||||
/* close_me manipulations: */
|
||||
static void mark_open(int fd);
|
||||
static void mark_closed(int fd);
|
||||
static void close_all();
|
||||
static void close_all(void);
|
||||
#endif
|
||||
/* "run" the final data structures: */
|
||||
static char *indenter(int i);
|
||||
@@ -902,7 +903,7 @@ static void b_reset(o_string *o)
|
||||
static void b_free(o_string *o)
|
||||
{
|
||||
b_reset(o);
|
||||
if (o->data != NULL) free(o->data);
|
||||
free(o->data);
|
||||
o->data = NULL;
|
||||
o->maxlen = 0;
|
||||
}
|
||||
@@ -958,7 +959,7 @@ static int static_peek(struct in_str *i)
|
||||
#ifndef __U_BOOT__
|
||||
static inline void cmdedit_set_initial_prompt(void)
|
||||
{
|
||||
#ifndef BB_FEATURE_SH_FANCY_PROMPT
|
||||
#ifndef CONFIG_FEATURE_SH_FANCY_PROMPT
|
||||
PS1 = NULL;
|
||||
#else
|
||||
PS1 = getenv("PS1");
|
||||
@@ -970,11 +971,10 @@ static inline void cmdedit_set_initial_prompt(void)
|
||||
static inline void setup_prompt_string(int promptmode, char **prompt_str)
|
||||
{
|
||||
debug_printf("setup_prompt_string %d ",promptmode);
|
||||
#ifndef BB_FEATURE_SH_FANCY_PROMPT
|
||||
#ifndef CONFIG_FEATURE_SH_FANCY_PROMPT
|
||||
/* Set up the prompt */
|
||||
if (promptmode == 1) {
|
||||
if (PS1)
|
||||
free(PS1);
|
||||
free(PS1);
|
||||
PS1=xmalloc(strlen(cwd)+4);
|
||||
sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
|
||||
*prompt_str = PS1;
|
||||
@@ -995,7 +995,7 @@ static void get_user_input(struct in_str *i)
|
||||
static char the_command[BUFSIZ];
|
||||
|
||||
setup_prompt_string(i->promptmode, &prompt_str);
|
||||
#ifdef BB_FEATURE_COMMAND_EDITING
|
||||
#ifdef CONFIG_FEATURE_COMMAND_EDITING
|
||||
/*
|
||||
** enable command line editing only while a command line
|
||||
** is actually being read; otherwise, we'll end up bequeathing
|
||||
@@ -1176,7 +1176,7 @@ static void mark_closed(int fd)
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
static void close_all()
|
||||
static void close_all(void)
|
||||
{
|
||||
struct close_me *c;
|
||||
for (c=close_me_head; c; c=c->next) {
|
||||
@@ -1290,18 +1290,18 @@ static void pseudo_exec(struct child_prog *child)
|
||||
* really dislike relying on /proc for things. We could exec ourself
|
||||
* from global_argv[0], but if we are in a chroot, we may not be able
|
||||
* to find ourself... */
|
||||
#ifdef BB_FEATURE_SH_STANDALONE_SHELL
|
||||
#ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
|
||||
{
|
||||
int argc_l;
|
||||
char** argv_l=child->argv;
|
||||
char *name = child->argv[0];
|
||||
|
||||
#ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
|
||||
#ifdef CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN
|
||||
/* Following discussions from November 2000 on the busybox mailing
|
||||
* list, the default configuration, (without
|
||||
* get_last_path_component()) lets the user force use of an
|
||||
* external command by specifying the full (with slashes) filename.
|
||||
* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then applets
|
||||
* If you enable CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN then applets
|
||||
* _aways_ override external commands, so if you want to run
|
||||
* /bin/cat, it will use BusyBox cat even if /bin/cat exists on the
|
||||
* filesystem and is _not_ busybox. Some systems may want this,
|
||||
@@ -1524,13 +1524,26 @@ static int run_pipe_real(struct pipe *pi)
|
||||
struct child_prog *child;
|
||||
struct built_in_command *x;
|
||||
char *p;
|
||||
# if __GNUC__
|
||||
/* Avoid longjmp clobbering */
|
||||
(void) &i;
|
||||
(void) &nextin;
|
||||
(void) &nextout;
|
||||
(void) &child;
|
||||
# endif
|
||||
#else
|
||||
int nextin;
|
||||
int flag = do_repeat ? CMD_FLAG_REPEAT : 0;
|
||||
struct child_prog *child;
|
||||
cmd_tbl_t *cmdtp;
|
||||
char *p;
|
||||
#endif
|
||||
# if __GNUC__
|
||||
/* Avoid longjmp clobbering */
|
||||
(void) &i;
|
||||
(void) &nextin;
|
||||
(void) &child;
|
||||
# endif
|
||||
#endif /* __U_BOOT__ */
|
||||
|
||||
nextin = 0;
|
||||
#ifndef __U_BOOT__
|
||||
@@ -3194,7 +3207,7 @@ static void *xrealloc(void *ptr, size_t size)
|
||||
/* Make sure we have a controlling tty. If we get started under a job
|
||||
* aware app (like bash for example), make sure we are now in charge so
|
||||
* we don't fight over who gets the foreground */
|
||||
static void setup_job_control()
|
||||
static void setup_job_control(void)
|
||||
{
|
||||
static pid_t shell_pgrp;
|
||||
/* Loop until we are in the foreground. */
|
||||
@@ -3243,7 +3256,7 @@ int hush_main(int argc, char **argv)
|
||||
|
||||
/* Initialize some more globals to non-zero values */
|
||||
set_cwd();
|
||||
#ifdef BB_FEATURE_COMMAND_EDITING
|
||||
#ifdef CONFIG_FEATURE_COMMAND_EDITING
|
||||
cmdedit_set_initial_prompt();
|
||||
#else
|
||||
PS1 = NULL;
|
||||
@@ -3312,7 +3325,10 @@ int hush_main(int argc, char **argv)
|
||||
debug_printf("\ninteractive=%d\n", interactive);
|
||||
if (interactive) {
|
||||
/* Looks like they want an interactive shell */
|
||||
fprintf(stdout, "\nhush -- the humble shell v0.01 (testing)\n\n");
|
||||
#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
|
||||
printf( "\n\n" BB_BANNER " hush - the humble shell v0.01 (testing)\n");
|
||||
printf( "Enter 'help' for a list of built-in commands.\n\n");
|
||||
#endif
|
||||
setup_job_control();
|
||||
}
|
||||
|
||||
@@ -3327,7 +3343,7 @@ int hush_main(int argc, char **argv)
|
||||
input = xfopen(argv[optind], "r");
|
||||
opt = parse_file_outer(input);
|
||||
|
||||
#ifdef BB_FEATURE_CLEAN_UP
|
||||
#ifdef CONFIG_FEATURE_CLEAN_UP
|
||||
fclose(input);
|
||||
if (cwd && cwd != unknown)
|
||||
free((char*)cwd);
|
||||
|
||||
@@ -613,7 +613,7 @@ static void process_macros (const char *input, char *output)
|
||||
int state = 0; /* 0 = waiting for '$' */
|
||||
/* 1 = waiting for '(' */
|
||||
/* 2 = waiting for ')' */
|
||||
|
||||
/* 3 = waiting for ''' */
|
||||
#ifdef DEBUG_PARSER
|
||||
char *output_start = output;
|
||||
|
||||
@@ -626,6 +626,7 @@ static void process_macros (const char *input, char *output)
|
||||
c = *input++;
|
||||
inputcnt--;
|
||||
|
||||
if (state!=3) {
|
||||
/* remove one level of escape characters */
|
||||
if ((c == '\\') && (prev != '\\')) {
|
||||
if (inputcnt-- == 0)
|
||||
@@ -633,9 +634,16 @@ static void process_macros (const char *input, char *output)
|
||||
prev = c;
|
||||
c = *input++;
|
||||
}
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case 0: /* Waiting for (unescaped) $ */
|
||||
if ((c == '\'') && (prev != '\\')) {
|
||||
state = 3;
|
||||
if (inputcnt)
|
||||
inputcnt--;
|
||||
break;
|
||||
}
|
||||
if ((c == '$') && (prev != '\\')) {
|
||||
state++;
|
||||
} else {
|
||||
@@ -683,8 +691,17 @@ static void process_macros (const char *input, char *output)
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 3: /* Waiting for ' */
|
||||
if ((c == '\'') && (prev != '\\')) {
|
||||
state = 0;
|
||||
if (inputcnt)
|
||||
inputcnt--;
|
||||
} else {
|
||||
*(output++) = c;
|
||||
outputcnt--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
prev = c;
|
||||
}
|
||||
|
||||
@@ -725,6 +742,7 @@ int run_command (const char *cmd, int flag)
|
||||
char *argv[CFG_MAXARGS + 1]; /* NULL terminated */
|
||||
int argc;
|
||||
int repeatable = 1;
|
||||
int inquotes;
|
||||
|
||||
#ifdef DEBUG_PARSER
|
||||
printf ("[RUN_COMMAND] cmd[%p]=\"", cmd);
|
||||
@@ -758,8 +776,13 @@ int run_command (const char *cmd, int flag)
|
||||
* Find separator, or string end
|
||||
* Allow simple escape of ';' by writing "\;"
|
||||
*/
|
||||
for (sep = str; *sep; sep++) {
|
||||
if ((*sep == ';') && /* separator */
|
||||
for (inquotes = 0, sep = str; *sep; sep++) {
|
||||
if ((*sep=='\'') &&
|
||||
(*(sep-1) != '\\'))
|
||||
inquotes=!inquotes;
|
||||
|
||||
if (!inquotes &&
|
||||
(*sep == ';') && /* separator */
|
||||
( sep != str) && /* past string start */
|
||||
(*(sep-1) != '\\')) /* and NOT escaped */
|
||||
break;
|
||||
|
||||
@@ -27,13 +27,16 @@ LIB = lib$(CPU).a
|
||||
|
||||
START = start.S drivers/i2c/i2c2.o
|
||||
OBJS = traps.o cpu.o cpu_init.o interrupts.o speed.o \
|
||||
drivers/epic/epic1.o drivers/i2c/i2c1.o pci.o
|
||||
drivers/epic/epic1.o drivers/i2c/i2c1.o pci.o bedbug_603e.o
|
||||
|
||||
all: .depend $(START) $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(AR) crv $@ $(OBJS) drivers/i2c/i2c2.o
|
||||
|
||||
bedbug_603e.c:
|
||||
ln -s ../mpc8260/bedbug_603e.c bedbug_603e.c
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
|
||||
|
||||
@@ -336,7 +336,7 @@ _end_back:
|
||||
STD_EXCEPTION(EXC_OFF_ITME, InstructionTransMiss, UnknownException)
|
||||
STD_EXCEPTION(EXC_OFF_DLTME, DataLoadTransMiss, UnknownException)
|
||||
STD_EXCEPTION(EXC_OFF_DSTME, DataStoreTransMiss, UnknownException)
|
||||
STD_EXCEPTION(EXC_OFF_IABE, InstructionBreakpoint, UnknownException)
|
||||
STD_EXCEPTION(EXC_OFF_IABE, InstructionBreakpoint, DebugException)
|
||||
STD_EXCEPTION(EXC_OFF_SMIE, SysManageInt, UnknownException)
|
||||
STD_EXCEPTION(0x1500, Reserved5, UnknownException)
|
||||
STD_EXCEPTION(0x1600, Reserved6, UnknownException)
|
||||
|
||||
@@ -176,6 +176,21 @@ UnknownException(struct pt_regs *regs)
|
||||
_exception(0, regs);
|
||||
}
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
|
||||
extern void do_bedbug_breakpoint(struct pt_regs *);
|
||||
#endif
|
||||
|
||||
void
|
||||
DebugException(struct pt_regs *regs)
|
||||
{
|
||||
|
||||
printf("Debugger trap at @ %lx\n", regs->nip );
|
||||
show_regs(regs);
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
|
||||
do_bedbug_breakpoint( regs );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Probe an address by reading. If not present, return -1, otherwise
|
||||
* return 0.
|
||||
*/
|
||||
|
||||
@@ -40,40 +40,61 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/cpm_8260.h>
|
||||
#include <mpc8260.h>
|
||||
#include <net.h>
|
||||
#include <command.h>
|
||||
#include <config.h>
|
||||
#include <net.h>
|
||||
|
||||
#if defined(CONFIG_ETHER_ON_FCC) && (CONFIG_COMMANDS & CFG_CMD_NET)
|
||||
#if defined(CONFIG_ETHER_ON_FCC) && (CONFIG_COMMANDS & CFG_CMD_NET) && \
|
||||
defined(CONFIG_NET_MULTI)
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
#if (CONFIG_ETHER_INDEX == 1)
|
||||
|
||||
#define PROFF_ENET PROFF_FCC1
|
||||
#define CPM_CR_ENET_SBLOCK CPM_CR_FCC1_SBLOCK
|
||||
#define CPM_CR_ENET_SBLOCK CPM_CR_FCC1_SBLOCK
|
||||
#define CPM_CR_ENET_PAGE CPM_CR_FCC1_PAGE
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
#elif (CONFIG_ETHER_INDEX == 2)
|
||||
|
||||
#define PROFF_ENET PROFF_FCC2
|
||||
#define CPM_CR_ENET_SBLOCK CPM_CR_FCC2_SBLOCK
|
||||
#define CPM_CR_ENET_PAGE CPM_CR_FCC2_PAGE
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
#elif (CONFIG_ETHER_INDEX == 3)
|
||||
|
||||
#define PROFF_ENET PROFF_FCC3
|
||||
#define CPM_CR_ENET_SBLOCK CPM_CR_FCC3_SBLOCK
|
||||
#define CPM_CR_ENET_PAGE CPM_CR_FCC3_PAGE
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
#else
|
||||
#error "FCC Ethernet not correctly defined"
|
||||
static struct ether_fcc_info_s
|
||||
{
|
||||
int ether_index;
|
||||
int proff_enet;
|
||||
ulong cpm_cr_enet_sblock;
|
||||
ulong cpm_cr_enet_page;
|
||||
ulong cmxfcr_mask;
|
||||
ulong cmxfcr_value;
|
||||
}
|
||||
ether_fcc_info[] =
|
||||
{
|
||||
#ifdef CONFIG_ETHER_ON_FCC1
|
||||
{
|
||||
0,
|
||||
PROFF_FCC1,
|
||||
CPM_CR_FCC1_SBLOCK,
|
||||
CPM_CR_FCC1_PAGE,
|
||||
CFG_CMXFCR_MASK1,
|
||||
CFG_CMXFCR_VALUE1
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ETHER_ON_FCC2
|
||||
{
|
||||
1,
|
||||
PROFF_FCC2,
|
||||
CPM_CR_FCC2_SBLOCK,
|
||||
CPM_CR_FCC2_PAGE,
|
||||
CFG_CMXFCR_MASK2,
|
||||
CFG_CMXFCR_VALUE2
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ETHER_ON_FCC3
|
||||
{
|
||||
2,
|
||||
PROFF_FCC3,
|
||||
CPM_CR_FCC3_SBLOCK,
|
||||
CPM_CR_FCC3_PAGE,
|
||||
CFG_CMXFCR_MASK3,
|
||||
CFG_CMXFCR_VALUE3
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
/* Maximum input DMA size. Must be a should(?) be a multiple of 4. */
|
||||
@@ -116,7 +137,7 @@ static RTXBD rtx __attribute__ ((aligned(8)));
|
||||
#error "rtx must be 64-bit aligned"
|
||||
#endif
|
||||
|
||||
int eth_send(volatile void *packet, int length)
|
||||
static int fec_send(struct eth_device* dev, volatile void *packet, int length)
|
||||
{
|
||||
int i;
|
||||
int result = 0;
|
||||
@@ -156,7 +177,7 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
int eth_rx(void)
|
||||
static int fec_recv(struct eth_device* dev)
|
||||
{
|
||||
int length;
|
||||
|
||||
@@ -194,8 +215,9 @@ int eth_rx(void)
|
||||
}
|
||||
|
||||
|
||||
int eth_init(bd_t *bis)
|
||||
static int fec_init(struct eth_device* dev, bd_t *bis)
|
||||
{
|
||||
struct ether_fcc_info_s * info = dev->priv;
|
||||
int i;
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
volatile cpm8260_t *cp = &(immr->im_cpm);
|
||||
@@ -210,18 +232,18 @@ int eth_init(bd_t *bis)
|
||||
|
||||
/* 28.9 - (3): connect FCC's tx and rx clocks */
|
||||
immr->im_cpmux.cmx_uar = 0;
|
||||
immr->im_cpmux.cmx_fcr = (immr->im_cpmux.cmx_fcr & ~CFG_CMXFCR_MASK) |
|
||||
CFG_CMXFCR_VALUE;
|
||||
immr->im_cpmux.cmx_fcr = (immr->im_cpmux.cmx_fcr & ~info->cmxfcr_mask) |
|
||||
info->cmxfcr_value;
|
||||
|
||||
/* 28.9 - (4): GFMR: disable tx/rx, CCITT CRC, Mode Ethernet */
|
||||
immr->im_fcc[CONFIG_ETHER_INDEX-1].fcc_gfmr =
|
||||
immr->im_fcc[info->ether_index].fcc_gfmr =
|
||||
FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
|
||||
|
||||
/* 28.9 - (5): FPSMR: enable full duplex, select CCITT CRC for Ethernet */
|
||||
immr->im_fcc[CONFIG_ETHER_INDEX-1].fcc_fpsmr = CFG_FCC_PSMR | FCC_PSMR_ENCRC;
|
||||
immr->im_fcc[info->ether_index].fcc_fpsmr = CFG_FCC_PSMR | FCC_PSMR_ENCRC;
|
||||
|
||||
/* 28.9 - (6): FDSR: Ethernet Syn */
|
||||
immr->im_fcc[CONFIG_ETHER_INDEX-1].fcc_fdsr = 0xD555;
|
||||
immr->im_fcc[info->ether_index].fcc_fdsr = 0xD555;
|
||||
|
||||
/* reset indeces to current rx/tx bd (see eth_send()/eth_rx()) */
|
||||
rxIdx = 0;
|
||||
@@ -246,7 +268,7 @@ int eth_init(bd_t *bis)
|
||||
rtx.txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
|
||||
|
||||
/* 28.9 - (7): initialise parameter ram */
|
||||
pram_ptr = (fcc_enet_t *)&(immr->im_dprambase[PROFF_ENET]);
|
||||
pram_ptr = (fcc_enet_t *)&(immr->im_dprambase[info->proff_enet]);
|
||||
|
||||
/* clear whole structure to make sure all reserved fields are zero */
|
||||
memset((void*)pram_ptr, 0, sizeof(fcc_enet_t));
|
||||
@@ -259,7 +281,7 @@ int eth_init(bd_t *bis)
|
||||
* can do this. Later, we will add resource management for
|
||||
* this area.
|
||||
*/
|
||||
mem_addr = CPM_FCC_SPECIAL_BASE + ((CONFIG_ETHER_INDEX-1) * 64);
|
||||
mem_addr = CPM_FCC_SPECIAL_BASE + ((info->ether_index) * 64);
|
||||
pram_ptr->fen_genfcc.fcc_riptr = mem_addr;
|
||||
pram_ptr->fen_genfcc.fcc_tiptr = mem_addr+32;
|
||||
/*
|
||||
@@ -288,7 +310,7 @@ int eth_init(bd_t *bis)
|
||||
* it unique by setting a few bits in the upper byte of the
|
||||
* non-static part of the address.
|
||||
*/
|
||||
#define ea bis->bi_enetaddr
|
||||
#define ea eth_get_dev()->enetaddr
|
||||
pram_ptr->fen_paddrh = (ea[5] << 8) + ea[4];
|
||||
pram_ptr->fen_paddrm = (ea[3] << 8) + ea[2];
|
||||
pram_ptr->fen_paddrl = (ea[1] << 8) + ea[0];
|
||||
@@ -308,10 +330,10 @@ int eth_init(bd_t *bis)
|
||||
#endif
|
||||
|
||||
/* 28.9 - (8): clear out events in FCCE */
|
||||
immr->im_fcc[CONFIG_ETHER_INDEX-1].fcc_fcce = ~0x0;
|
||||
immr->im_fcc[info->ether_index].fcc_fcce = ~0x0;
|
||||
|
||||
/* 28.9 - (9): FCCM: mask all events */
|
||||
immr->im_fcc[CONFIG_ETHER_INDEX-1].fcc_fccm = 0;
|
||||
immr->im_fcc[info->ether_index].fcc_fccm = 0;
|
||||
|
||||
/* 28.9 - (10-12): we don't use ethernet interrupts */
|
||||
|
||||
@@ -321,8 +343,8 @@ int eth_init(bd_t *bis)
|
||||
* than the manual describes because we have just now finished
|
||||
* the BD initialization.
|
||||
*/
|
||||
cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET_PAGE,
|
||||
CPM_CR_ENET_SBLOCK,
|
||||
cp->cp_cpcr = mk_cr_cmd(info->cpm_cr_enet_page,
|
||||
info->cpm_cr_enet_sblock,
|
||||
0x0c,
|
||||
CPM_CR_INIT_TRX) | CPM_CR_FLG;
|
||||
do {
|
||||
@@ -330,18 +352,43 @@ int eth_init(bd_t *bis)
|
||||
} while (cp->cp_cpcr & CPM_CR_FLG);
|
||||
|
||||
/* 28.9 - (14): enable tx/rx in gfmr */
|
||||
immr->im_fcc[CONFIG_ETHER_INDEX-1].fcc_gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
|
||||
immr->im_fcc[info->ether_index].fcc_gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void eth_halt(void)
|
||||
static void fec_halt(struct eth_device* dev)
|
||||
{
|
||||
struct ether_fcc_info_s * info = dev->priv;
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
|
||||
/* write GFMR: disable tx/rx */
|
||||
immr->im_fcc[CONFIG_ETHER_INDEX-1].fcc_gfmr &=
|
||||
immr->im_fcc[info->ether_index].fcc_gfmr &=
|
||||
~(FCC_GFMR_ENT | FCC_GFMR_ENR);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ETHER_ON_FCC && CFG_CMD_NET */
|
||||
int fec_initialize(bd_t *bis)
|
||||
{
|
||||
struct eth_device* dev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++)
|
||||
{
|
||||
dev = (struct eth_device*) malloc(sizeof *dev);
|
||||
memset(dev, 0, sizeof *dev);
|
||||
|
||||
sprintf(dev->name, "FCC%d ETHERNET",
|
||||
ether_fcc_info[i].ether_index + 1);
|
||||
dev->priv = ðer_fcc_info[i];
|
||||
dev->init = fec_init;
|
||||
dev->halt = fec_halt;
|
||||
dev->send = fec_send;
|
||||
dev->recv = fec_recv;
|
||||
|
||||
eth_register(dev);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ETHER_ON_FCC && CFG_CMD_NET && CONFIG_NET_MULTI */
|
||||
|
||||
@@ -43,6 +43,12 @@
|
||||
#define CONFIG_LCD_LOGO
|
||||
#define LCD_INFO /* Display Logo, (C) and system info */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_V37
|
||||
#undef CONFIG_LCD_LOGO
|
||||
#undef LCD_INFO
|
||||
#endif
|
||||
|
||||
/* #define LCD_TEST_PATTERN */ /* color backgnd for frame/color adjust */
|
||||
/* #define CFG_INVERT_COLORS */ /* Not needed - adjust vl_dp instead */
|
||||
/************************************************************************/
|
||||
@@ -190,6 +196,18 @@ static vidinfo_t panel_info = {
|
||||
/* wbl, vpw, lcdac, wbf */
|
||||
};
|
||||
#endif /* CONFIG_SHARP_LQ64D341 */
|
||||
|
||||
#ifdef CONFIG_SHARP_LQ084V1DG21
|
||||
/*
|
||||
* Sharp LQ084V1DG21 display, 640x480. Active, color, single scan.
|
||||
*/
|
||||
static vidinfo_t panel_info = {
|
||||
640, 480, 171, 129, CFG_HIGH, CFG_HIGH, CFG_LOW, CFG_LOW, CFG_LOW,
|
||||
3, 0, 0, 1, 1, 160, 3, 0, 48
|
||||
/* wbl, vpw, lcdac, wbf */
|
||||
};
|
||||
#endif /* CONFIG_SHARP_LQ084V1DG21 */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#ifdef CONFIG_HLD1045
|
||||
@@ -947,6 +965,13 @@ static void lcd_enable (void)
|
||||
/* Enable the LCD panel */
|
||||
immr->im_siu_conf.sc_sdcr |= (1 << (31 - 25)); /* LAM = 1 */
|
||||
lcdp->lcd_lccr |= LCCR_PON;
|
||||
|
||||
#ifdef CONFIG_V37
|
||||
/* Turn on display backlight */
|
||||
immr->im_cpm.cp_pbpar |= 0x00008000;
|
||||
immr->im_cpm.cp_pbdir |= 0x00008000;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_LWMON)
|
||||
{ uchar c = pic_read (0x60);
|
||||
c |= 0x07; /* Power on CCFL, Enable CCFL, Chip Enable LCD */
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <common.h>
|
||||
#include <commproc.h>
|
||||
#include <command.h>
|
||||
#include <watchdog.h>
|
||||
|
||||
#if !defined(CONFIG_8xx_CONS_NONE) /* No Console at all */
|
||||
|
||||
@@ -265,20 +266,16 @@ serial_putc(const char c)
|
||||
*/
|
||||
|
||||
buf = (char *)tbdf->cbd_bufaddr;
|
||||
#if 0
|
||||
__asm__("eieio");
|
||||
while (tbdf->cbd_sc & BD_SC_READY)
|
||||
__asm__("eieio");
|
||||
#endif
|
||||
|
||||
*buf = c;
|
||||
tbdf->cbd_datlen = 1;
|
||||
tbdf->cbd_sc |= BD_SC_READY;
|
||||
__asm__("eieio");
|
||||
#if 1
|
||||
while (tbdf->cbd_sc & BD_SC_READY)
|
||||
|
||||
while (tbdf->cbd_sc & BD_SC_READY) {
|
||||
WATCHDOG_RESET ();
|
||||
__asm__("eieio");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@@ -298,8 +295,10 @@ serial_getc(void)
|
||||
/* Wait for character to show up.
|
||||
*/
|
||||
buf = (unsigned char *)rbdf->cbd_bufaddr;
|
||||
|
||||
while (rbdf->cbd_sc & BD_SC_EMPTY)
|
||||
;
|
||||
WATCHDOG_RESET ();
|
||||
|
||||
c = *buf;
|
||||
rbdf->cbd_sc |= BD_SC_EMPTY;
|
||||
|
||||
@@ -524,20 +523,16 @@ serial_putc(const char c)
|
||||
*/
|
||||
|
||||
buf = (char *)tbdf->cbd_bufaddr;
|
||||
#if 0
|
||||
__asm__("eieio");
|
||||
while (tbdf->cbd_sc & BD_SC_READY)
|
||||
__asm__("eieio");
|
||||
#endif
|
||||
|
||||
*buf = c;
|
||||
tbdf->cbd_datlen = 1;
|
||||
tbdf->cbd_sc |= BD_SC_READY;
|
||||
__asm__("eieio");
|
||||
#if 1
|
||||
while (tbdf->cbd_sc & BD_SC_READY)
|
||||
|
||||
while (tbdf->cbd_sc & BD_SC_READY) {
|
||||
__asm__("eieio");
|
||||
#endif
|
||||
WATCHDOG_RESET ();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@@ -557,8 +552,10 @@ serial_getc(void)
|
||||
/* Wait for character to show up.
|
||||
*/
|
||||
buf = (unsigned char *)rbdf->cbd_bufaddr;
|
||||
|
||||
while (rbdf->cbd_sc & BD_SC_EMPTY)
|
||||
;
|
||||
WATCHDOG_RESET ();
|
||||
|
||||
c = *buf;
|
||||
rbdf->cbd_sc |= BD_SC_EMPTY;
|
||||
|
||||
|
||||
@@ -583,7 +583,7 @@ relocate_code:
|
||||
|
||||
/* First our own GOT */
|
||||
add r14, r14, r15
|
||||
/* the the one used by the C code */
|
||||
/* then the one used by the C code */
|
||||
add r30, r30, r15
|
||||
|
||||
/*
|
||||
|
||||
@@ -376,7 +376,7 @@ static struct pci_controller hose = {
|
||||
config_table: pci_405gp_config_table,
|
||||
};
|
||||
|
||||
void pci_init(void)
|
||||
void pci_init_board(void)
|
||||
{
|
||||
/*we want the ptrs to RAM not flash (ie don't use init list)*/
|
||||
hose.fixup_irq = pci_405gp_fixup_irq;
|
||||
@@ -494,7 +494,7 @@ void pci_440_init (struct pci_controller *hose)
|
||||
}
|
||||
|
||||
|
||||
void pci_init(void)
|
||||
void pci_init_board(void)
|
||||
{
|
||||
pci_440_init (&ppc440_hose);
|
||||
}
|
||||
|
||||
@@ -35,13 +35,17 @@
|
||||
#define MAGIC2 0x22222222
|
||||
#define MAGIC3 0x33333333
|
||||
#define MAGIC4 0x44444444
|
||||
#define MAGIC5 0x55555555
|
||||
#define MAGIC6 0x66666666
|
||||
|
||||
#define ADDR_ZERO 0x00000000
|
||||
#define ADDR_400 0x00000400
|
||||
#define ADDR_01MB 0x00100000
|
||||
#define ADDR_08MB 0x00800000
|
||||
#define ADDR_16MB 0x01000000
|
||||
#define ADDR_32MB 0x02000000
|
||||
#define ADDR_64MB 0x04000000
|
||||
#define ADDR_128MB 0x08000000
|
||||
|
||||
#define mtsdram0(reg, data) mtdcr(memcfga,reg);mtdcr(memcfgd,data)
|
||||
|
||||
@@ -76,6 +80,59 @@ void sdram_init(void)
|
||||
rtr = 0x05f00000;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set MB0CF for bank 0. (0-128MB) Address Mode 3 since 13x10(4)
|
||||
*/
|
||||
mtsdram0(mem_mb0cf, 0x000A4001);
|
||||
|
||||
mtsdram0(mem_sdtr1, sdtr1);
|
||||
mtsdram0(mem_rtr, rtr);
|
||||
|
||||
/*
|
||||
* Wait for 200us
|
||||
*/
|
||||
udelay(200);
|
||||
|
||||
/*
|
||||
* Set memory controller options reg, MCOPT1.
|
||||
* Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
|
||||
* read/prefetch.
|
||||
*/
|
||||
mtsdram0(mem_mcopt1, 0x80800000);
|
||||
|
||||
/*
|
||||
* Wait for 10ms
|
||||
*/
|
||||
udelay(10000);
|
||||
|
||||
/*
|
||||
* Test if 128 MByte are equipped (mirror test)
|
||||
*/
|
||||
*(volatile ulong *)ADDR_ZERO = MAGIC0;
|
||||
*(volatile ulong *)ADDR_08MB = MAGIC1;
|
||||
*(volatile ulong *)ADDR_16MB = MAGIC2;
|
||||
*(volatile ulong *)ADDR_32MB = MAGIC3;
|
||||
*(volatile ulong *)ADDR_64MB = MAGIC4;
|
||||
|
||||
if ((*(volatile ulong *)ADDR_ZERO == MAGIC0) &&
|
||||
(*(volatile ulong *)ADDR_08MB == MAGIC1) &&
|
||||
(*(volatile ulong *)ADDR_16MB == MAGIC2) &&
|
||||
(*(volatile ulong *)ADDR_32MB == MAGIC3)) {
|
||||
/*
|
||||
* OK, 128MB detected -> all done
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now test for 64 MByte...
|
||||
*/
|
||||
|
||||
/*
|
||||
* Disable memory controller.
|
||||
*/
|
||||
mtsdram0(mem_mcopt1, 0x00000000);
|
||||
|
||||
/*
|
||||
* Set MB0CF for bank 0. (0-64MB) Address Mode 3 since 13x9(4)
|
||||
*/
|
||||
@@ -162,9 +219,8 @@ void sdram_init(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup for 16 MByte...
|
||||
* Now test for 16 MByte...
|
||||
*/
|
||||
|
||||
/*
|
||||
* Disable memory controller.
|
||||
*/
|
||||
@@ -186,6 +242,51 @@ void sdram_init(void)
|
||||
* Wait for 10ms
|
||||
*/
|
||||
udelay(10000);
|
||||
|
||||
/*
|
||||
* Test if 16 MByte are equipped (mirror test)
|
||||
*/
|
||||
*(volatile ulong *)ADDR_ZERO = MAGIC0;
|
||||
*(volatile ulong *)ADDR_400 = MAGIC1;
|
||||
*(volatile ulong *)ADDR_01MB = MAGIC5;
|
||||
*(volatile ulong *)ADDR_08MB = MAGIC2;
|
||||
/* *(volatile ulong *)ADDR_16MB = MAGIC3;*/
|
||||
|
||||
if ((*(volatile ulong *)ADDR_ZERO == MAGIC0) &&
|
||||
(*(volatile ulong *)ADDR_400 == MAGIC1) &&
|
||||
(*(volatile ulong *)ADDR_01MB == MAGIC5) &&
|
||||
(*(volatile ulong *)ADDR_08MB == MAGIC2)) {
|
||||
/*
|
||||
* OK, 16MB detected -> all done
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup for 4 MByte...
|
||||
*/
|
||||
|
||||
/*
|
||||
* Disable memory controller.
|
||||
*/
|
||||
mtsdram0(mem_mcopt1, 0x00000000);
|
||||
|
||||
/*
|
||||
* Set MB0CF for bank 0. (0-4MB) Address Mode 5 since 11x8(2)
|
||||
*/
|
||||
mtsdram0(mem_mb0cf, 0x00008001);
|
||||
|
||||
/*
|
||||
* Set memory controller options reg, MCOPT1.
|
||||
* Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
|
||||
* read/prefetch.
|
||||
*/
|
||||
mtsdram0(mem_mcopt1, 0x80800000);
|
||||
|
||||
/*
|
||||
* Wait for 10ms
|
||||
*/
|
||||
udelay(10000);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SDRAM_BANK0 */
|
||||
|
||||
@@ -279,7 +279,7 @@ int serial_tstc ()
|
||||
#define UART0_BASE 0xef600300
|
||||
#define UART1_BASE 0xef600400
|
||||
#define CR0_MASK 0x00001fff
|
||||
#define CR0_EXTCLK_ENA 0x00000c00
|
||||
#define CR0_EXTCLK_ENA 0x000000c0
|
||||
#define CR0_UDIV_POS 1
|
||||
#endif
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*
|
||||
* Based on code by:
|
||||
*
|
||||
* Kenneth Johansson ,Ericsson Business Innovation.
|
||||
* kenneth.johansson@inn.ericsson.se
|
||||
* Kenneth Johansson ,Ericsson AB.
|
||||
* kenneth.johansson@etx.ericsson.se
|
||||
*
|
||||
* hacked up by bill hunter. fixed so we could run before
|
||||
* serial_init and console_init. previous version avoided this by
|
||||
@@ -87,25 +87,16 @@
|
||||
#define SDRAM0_BXCR_SZ(x) ( (( x << SDRAM0_BXCR_SZ_SHIFT) & SDRAM0_BXCR_SZ_MASK) )
|
||||
#define SDRAM0_BXCR_AM(x) ( (( x << SDRAM0_BXCR_AM_SHIFT) & SDRAM0_BXCR_AM_MASK) )
|
||||
|
||||
#ifdef CONFIG_W7O
|
||||
#ifdef CONFIG_SPDDRAM_SILENT
|
||||
# define SPD_ERR(x) do { return 0; } while (0)
|
||||
#else
|
||||
# define SPD_ERR(x) do { printf(x); hang(); } while (0)
|
||||
# define SPD_ERR(x) do { printf(x); return(0); } while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* what we really want is
|
||||
* (1/hertz) but we don't want to use floats so multiply with 10E9
|
||||
*
|
||||
* The error needs to be on the safe side so we want the floor function.
|
||||
* This means we get an exact value or we calculate that our bus frequency is
|
||||
* a bit faster than it really is and thus we don't progam the sdram controller
|
||||
* to run to fast
|
||||
*/
|
||||
#define sdram_HZ_to_ns(hertz) (1000000000/(hertz))
|
||||
|
||||
/* function prototypes */
|
||||
int spd_read(uint addr); /* prototype */
|
||||
int spd_read(uint addr);
|
||||
|
||||
|
||||
/*
|
||||
@@ -114,17 +105,17 @@ int spd_read(uint addr); /* prototype */
|
||||
*
|
||||
* This works on boards that has the same schematics that the IBM walnut has.
|
||||
*
|
||||
* BUG: Don't handle ECC memory
|
||||
* BUG: A few values in the TR register is currently hardcoded
|
||||
* Input: null for default I2C spd functions or a pointer to a custom function
|
||||
* returning spd_data.
|
||||
*/
|
||||
|
||||
long int spd_sdram(void)
|
||||
long int spd_sdram(int(read_spd)(uint addr))
|
||||
{
|
||||
int bus_period,tmp,row,col;
|
||||
int total_size,bank_size,bank_code;
|
||||
int ecc_on;
|
||||
int mode = 4;
|
||||
int bank_cnt = 1;
|
||||
int mode;
|
||||
int bank_cnt;
|
||||
|
||||
int sdram0_pmit=0x07c00000;
|
||||
int sdram0_besr0=-1;
|
||||
@@ -144,14 +135,19 @@ long int spd_sdram(void)
|
||||
|
||||
int t_rp;
|
||||
int t_rcd;
|
||||
int t_rc = 70; /* This value not available in SPD_EEPROM */
|
||||
int min_cas = 2;
|
||||
int t_ras;
|
||||
int t_rc;
|
||||
int min_cas;
|
||||
|
||||
if(read_spd == 0){
|
||||
read_spd=spd_read;
|
||||
/*
|
||||
* Make sure I2C controller is initialized
|
||||
* before continuing.
|
||||
*/
|
||||
i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
|
||||
i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Calculate the bus period, we do it this
|
||||
@@ -162,7 +158,7 @@ long int spd_sdram(void)
|
||||
bus_period = sdram_HZ_to_ns(tmp); /* get sdram speed */
|
||||
|
||||
/* Make shure we are using SDRAM */
|
||||
if (spd_read(2) != 0x04){
|
||||
if (read_spd(2) != 0x04){
|
||||
SPD_ERR("SDRAM - non SDRAM memory module found\n");
|
||||
}
|
||||
|
||||
@@ -180,34 +176,35 @@ long int spd_sdram(void)
|
||||
* use the min supported mode
|
||||
*/
|
||||
|
||||
tmp = spd_read(127) & 0x6;
|
||||
tmp = read_spd(127) & 0x6;
|
||||
if(tmp == 0x02){ /* only cas = 2 supported */
|
||||
min_cas = 2;
|
||||
/* t_ck = spd_read(9); */
|
||||
/* t_ac = spd_read(10); */
|
||||
/* t_ck = read_spd(9); */
|
||||
/* t_ac = read_spd(10); */
|
||||
}
|
||||
else if (tmp == 0x04){ /* only cas = 3 supported */
|
||||
min_cas = 3;
|
||||
/* t_ck = spd_read(9); */
|
||||
/* t_ac = spd_read(10); */
|
||||
/* t_ck = read_spd(9); */
|
||||
/* t_ac = read_spd(10); */
|
||||
}
|
||||
else if (tmp == 0x06){ /* 2,3 supported, so use 2 */
|
||||
min_cas = 2;
|
||||
/* t_ck = spd_read(23); */
|
||||
/* t_ac = spd_read(24); */
|
||||
/* t_ck = read_spd(23); */
|
||||
/* t_ac = read_spd(24); */
|
||||
}
|
||||
else {
|
||||
SPD_ERR("SDRAM - unsupported CAS latency \n");
|
||||
}
|
||||
|
||||
/* get some timing values, t_rp,t_rcd
|
||||
/* get some timing values, t_rp,t_rcd,t_ras,t_rc
|
||||
*/
|
||||
t_rp = spd_read(27);
|
||||
t_rcd = spd_read(29);
|
||||
|
||||
t_rp = read_spd(27);
|
||||
t_rcd = read_spd(29);
|
||||
t_ras = read_spd(30);
|
||||
t_rc = t_ras + t_rp;
|
||||
|
||||
/* The following timing calcs subtract 1 before deviding.
|
||||
* this has effect of using ceiling intead of floor rounding,
|
||||
* this has effect of using ceiling instead of floor rounding,
|
||||
* and also subtracting 1 to convert number to reg value
|
||||
*/
|
||||
/* set up CASL */
|
||||
@@ -216,12 +213,12 @@ long int spd_sdram(void)
|
||||
sdram0_tr |= (((t_rp - 1)/bus_period) & 0x3) << SDRAM0_TR_PTA_SHIFT;
|
||||
/* set up CTP */
|
||||
tmp = ((t_rc - t_rcd - t_rp -1) / bus_period) & 0x3;
|
||||
if(tmp<1) SPD_ERR("SDRAM - unsupported prech to act time (Trp)\n");
|
||||
if(tmp<1) tmp=1;
|
||||
sdram0_tr |= tmp << SDRAM0_TR_CTP_SHIFT;
|
||||
/* set LDF = 2 cycles, reg value = 1 */
|
||||
sdram0_tr |= 1 << SDRAM0_TR_LDF_SHIFT;
|
||||
/* set RFTA = t_rfc/bus_period, use t_rfc = t_rc */
|
||||
tmp = ((t_rc - 1) / bus_period)-4;
|
||||
tmp = ( (t_rc - 1) / bus_period)-3;
|
||||
if(tmp<0)tmp=0;
|
||||
if(tmp>6)tmp=6;
|
||||
sdram0_tr |= tmp << SDRAM0_TR_RFTA_SHIFT;
|
||||
@@ -232,9 +229,9 @@ long int spd_sdram(void)
|
||||
/*------------------------------------------------------------------
|
||||
configure RTR register
|
||||
-------------------------------------------------------------------*/
|
||||
row = spd_read(3);
|
||||
col = spd_read(4);
|
||||
tmp = spd_read(12) & 0x7f ; /* refresh type less self refresh bit */
|
||||
row = read_spd(3);
|
||||
col = read_spd(4);
|
||||
tmp = read_spd(12) & 0x7f ; /* refresh type less self refresh bit */
|
||||
switch(tmp){
|
||||
case 0x00:
|
||||
tmp=15625;
|
||||
@@ -265,9 +262,9 @@ long int spd_sdram(void)
|
||||
determine the number of banks used
|
||||
-------------------------------------------------------------------*/
|
||||
/* byte 7:6 is module data width */
|
||||
if(spd_read(7) != 0)
|
||||
if(read_spd(7) != 0)
|
||||
SPD_ERR("SDRAM - unsupported module width\n");
|
||||
tmp = spd_read(6);
|
||||
tmp = read_spd(6);
|
||||
if (tmp < 32)
|
||||
SPD_ERR("SDRAM - unsupported module width\n");
|
||||
else if (tmp < 64)
|
||||
@@ -280,7 +277,7 @@ long int spd_sdram(void)
|
||||
SPD_ERR("SDRAM - unsupported module width\n");
|
||||
|
||||
/* byte 5 is the module row count (refered to as dimm "sides") */
|
||||
tmp = spd_read(5);
|
||||
tmp = read_spd(5);
|
||||
if(tmp==1);
|
||||
else if(tmp==2) bank_cnt *=2;
|
||||
else if(tmp==4) bank_cnt *=4;
|
||||
@@ -292,7 +289,7 @@ long int spd_sdram(void)
|
||||
/* now check for ECC ability of module. We only support ECC
|
||||
* on 32 bit wide devices with 8 bit ECC.
|
||||
*/
|
||||
if ( (spd_read(11)==2) && ((spd_read(6)==40) || (spd_read(14)==8)) ){
|
||||
if ( (read_spd(11)==2) && ((read_spd(6)==40) || (read_spd(14)==8)) ){
|
||||
sdram0_ecccfg=0xf<<SDRAM0_ECCCFG_SHIFT;
|
||||
ecc_on = 1;
|
||||
}
|
||||
@@ -305,15 +302,15 @@ long int spd_sdram(void)
|
||||
calculate total size
|
||||
-------------------------------------------------------------------*/
|
||||
/* calculate total size and do sanity check */
|
||||
tmp = spd_read(31);
|
||||
tmp = read_spd(31);
|
||||
total_size=1<<22; /* total_size = 4MB */
|
||||
/* now multiply 4M by the smallest device roe density */
|
||||
/* now multiply 4M by the smallest device row density */
|
||||
/* note that we don't support asymetric rows */
|
||||
while (((tmp & 0x0001) == 0) && (tmp != 0)){
|
||||
total_size= total_size<<1;
|
||||
tmp = tmp>>1;
|
||||
}
|
||||
total_size *= spd_read(5); /* mult by module rows (dimm sides) */
|
||||
total_size *= read_spd(5); /* mult by module rows (dimm sides) */
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
map rows * cols * banks to a mode
|
||||
@@ -357,7 +354,7 @@ long int spd_sdram(void)
|
||||
break;
|
||||
case 9:
|
||||
case 10:
|
||||
if (spd_read(17) ==2 )
|
||||
if (read_spd(17) ==2 )
|
||||
mode=6; /* mode 7 */
|
||||
else
|
||||
mode=2; /* mode 3 */
|
||||
|
||||
@@ -26,7 +26,7 @@ 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 i2c.o
|
||||
|
||||
all: .depend $(START) $(LIB)
|
||||
|
||||
|
||||
453
cpu/xscale/i2c.c
Normal file
453
cpu/xscale/i2c.c
Normal file
@@ -0,0 +1,453 @@
|
||||
/*
|
||||
* (C) Copyright 2000
|
||||
* Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
|
||||
*
|
||||
* (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* (C) Copyright 2003 Pengutronix e.K.
|
||||
* Robert Schwebel <r.schwebel@pengutronix.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
|
||||
*
|
||||
* Back ported to the 8xx platform (from the 8260 platform) by
|
||||
* Murray.Jensen@cmst.csiro.au, 27-Jan-01.
|
||||
*/
|
||||
|
||||
/* FIXME: this file is PXA255 specific! What about other XScales? */
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#ifdef CONFIG_HARD_I2C
|
||||
|
||||
/*
|
||||
* - CFG_I2C_SPEED
|
||||
* - I2C_PXA_SLAVE_ADDR
|
||||
*/
|
||||
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
#include <i2c.h>
|
||||
|
||||
//#define DEBUG_I2C 1 /* activate local debugging output */
|
||||
#define I2C_PXA_SLAVE_ADDR 0x1 /* slave pxa unit address */
|
||||
#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
|
||||
#define I2C_ISR_INIT 0x7FF
|
||||
|
||||
#ifdef DEBUG_I2C
|
||||
#define PRINTD(x) printf x
|
||||
#else
|
||||
#define PRINTD(x)
|
||||
#endif
|
||||
|
||||
|
||||
/* Shall the current transfer have a start/stop condition? */
|
||||
#define I2C_COND_NORMAL 0
|
||||
#define I2C_COND_START 1
|
||||
#define I2C_COND_STOP 2
|
||||
|
||||
/* Shall the current transfer be ack/nacked or being waited for it? */
|
||||
#define I2C_ACKNAK_WAITACK 1
|
||||
#define I2C_ACKNAK_SENDACK 2
|
||||
#define I2C_ACKNAK_SENDNAK 4
|
||||
|
||||
/* Specify who shall transfer the data (master or slave) */
|
||||
#define I2C_READ 0
|
||||
#define I2C_WRITE 1
|
||||
|
||||
/* All transfers are described by this data structure */
|
||||
struct i2c_msg {
|
||||
u8 condition;
|
||||
u8 acknack;
|
||||
u8 direction;
|
||||
u8 data;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* i2c_pxa_reset: - reset the host controller
|
||||
*
|
||||
*/
|
||||
|
||||
static void i2c_reset( void )
|
||||
{
|
||||
ICR &= ~ICR_IUE; /* disable unit */
|
||||
ICR |= ICR_UR; /* reset the unit */
|
||||
udelay(100);
|
||||
ICR &= ~ICR_IUE; /* disable unit */
|
||||
CKEN |= CKEN14_I2C; /* set the global I2C clock on */
|
||||
ISAR = I2C_PXA_SLAVE_ADDR; /* set our slave address */
|
||||
ICR = I2C_ICR_INIT; /* set control register values */
|
||||
ISR = I2C_ISR_INIT; /* set clear interrupt bits */
|
||||
ICR |= ICR_IUE; /* enable unit */
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* i2c_isr_set_cleared: - wait until certain bits of the I2C status register
|
||||
* are set and cleared
|
||||
*
|
||||
* @return: 0 in case of success, 1 means timeout (no match within 10 ms).
|
||||
*/
|
||||
|
||||
static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
|
||||
{
|
||||
int timeout = 10000;
|
||||
|
||||
while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
|
||||
udelay( 10 );
|
||||
if( timeout-- < 0 ) return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* i2c_transfer: - Transfer one byte over the i2c bus
|
||||
*
|
||||
* This function can tranfer a byte over the i2c bus in both directions.
|
||||
* It is used by the public API functions.
|
||||
*
|
||||
* @return: 0: transfer successful
|
||||
* -1: message is empty
|
||||
* -2: transmit timeout
|
||||
* -3: ACK missing
|
||||
* -4: receive timeout
|
||||
* -5: illegal parameters
|
||||
* -6: bus is busy and couldn't be aquired
|
||||
*/
|
||||
int i2c_transfer(struct i2c_msg *msg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!msg)
|
||||
goto transfer_error_msg_empty;
|
||||
|
||||
switch(msg->direction) {
|
||||
|
||||
case I2C_WRITE:
|
||||
|
||||
/* check if bus is not busy */
|
||||
if (!i2c_isr_set_cleared(0,ISR_IBB))
|
||||
goto transfer_error_bus_busy;
|
||||
|
||||
/* start transmission */
|
||||
ICR &= ~ICR_START;
|
||||
ICR &= ~ICR_STOP;
|
||||
IDBR = msg->data;
|
||||
if (msg->condition == I2C_COND_START) ICR |= ICR_START;
|
||||
if (msg->condition == I2C_COND_STOP) ICR |= ICR_STOP;
|
||||
if (msg->acknack == I2C_ACKNAK_SENDNAK) ICR |= ICR_ACKNAK;
|
||||
if (msg->acknack == I2C_ACKNAK_SENDACK) ICR &= ~ICR_ACKNAK;
|
||||
ICR &= ~ICR_ALDIE;
|
||||
ICR |= ICR_TB;
|
||||
|
||||
/* transmit register empty? */
|
||||
if (!i2c_isr_set_cleared(ISR_ITE,0))
|
||||
goto transfer_error_transmit_timeout;
|
||||
|
||||
/* clear 'transmit empty' state */
|
||||
ISR |= ISR_ITE;
|
||||
|
||||
/* wait for ACK from slave */
|
||||
if (msg->acknack == I2C_ACKNAK_WAITACK)
|
||||
if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
|
||||
goto transfer_error_ack_missing;
|
||||
break;
|
||||
|
||||
case I2C_READ:
|
||||
|
||||
/* check if bus is not busy */
|
||||
if (!i2c_isr_set_cleared(0,ISR_IBB))
|
||||
goto transfer_error_bus_busy;
|
||||
|
||||
/* start receive */
|
||||
ICR &= ~ICR_START;
|
||||
ICR &= ~ICR_STOP;
|
||||
if (msg->condition == I2C_COND_START) ICR |= ICR_START;
|
||||
if (msg->condition == I2C_COND_STOP) ICR |= ICR_STOP;
|
||||
if (msg->acknack == I2C_ACKNAK_SENDNAK) ICR |= ICR_ACKNAK;
|
||||
if (msg->acknack == I2C_ACKNAK_SENDACK) ICR &= ~ICR_ACKNAK;
|
||||
ICR &= ~ICR_ALDIE;
|
||||
ICR |= ICR_TB;
|
||||
|
||||
/* receive register full? */
|
||||
if (!i2c_isr_set_cleared(ISR_IRF,0))
|
||||
goto transfer_error_receive_timeout;
|
||||
|
||||
msg->data = IDBR;
|
||||
|
||||
/* clear 'receive empty' state */
|
||||
ISR |= ISR_IRF;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
goto transfer_error_illegal_param;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
transfer_error_msg_empty:
|
||||
PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
|
||||
ret = -1; goto i2c_transfer_finish;
|
||||
|
||||
transfer_error_transmit_timeout:
|
||||
PRINTD(("i2c_transfer: error: transmit timeout\n"));
|
||||
ret = -2; goto i2c_transfer_finish;
|
||||
|
||||
transfer_error_ack_missing:
|
||||
PRINTD(("i2c_transfer: error: ACK missing\n"));
|
||||
ret = -3; goto i2c_transfer_finish;
|
||||
|
||||
transfer_error_receive_timeout:
|
||||
PRINTD(("i2c_transfer: error: receive timeout\n"));
|
||||
ret = -4; goto i2c_transfer_finish;
|
||||
|
||||
transfer_error_illegal_param:
|
||||
PRINTD(("i2c_transfer: error: illegal parameters\n"));
|
||||
ret = -5; goto i2c_transfer_finish;
|
||||
|
||||
transfer_error_bus_busy:
|
||||
PRINTD(("i2c_transfer: error: bus is busy\n"));
|
||||
ret = -6; goto i2c_transfer_finish;
|
||||
|
||||
i2c_transfer_finish:
|
||||
PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR));
|
||||
i2c_reset();
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* API Functions */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void i2c_init(int speed, int slaveaddr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* i2c_probe: - Test if a chip answers for a given i2c address
|
||||
*
|
||||
* @chip: address of the chip which is searched for
|
||||
* @return: 0 if a chip was found, -1 otherwhise
|
||||
*/
|
||||
|
||||
int i2c_probe(uchar chip)
|
||||
{
|
||||
struct i2c_msg msg;
|
||||
|
||||
i2c_reset();
|
||||
|
||||
msg.condition = I2C_COND_START;
|
||||
msg.acknack = I2C_ACKNAK_WAITACK;
|
||||
msg.direction = I2C_WRITE;
|
||||
msg.data = (chip << 1) + 1;
|
||||
if (i2c_transfer(&msg)) return -1;
|
||||
|
||||
msg.condition = I2C_COND_STOP;
|
||||
msg.acknack = I2C_ACKNAK_SENDNAK;
|
||||
msg.direction = I2C_READ;
|
||||
msg.data = 0x00;
|
||||
if (i2c_transfer(&msg)) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* i2c_read: - Read multiple bytes from an i2c device
|
||||
*
|
||||
* The higher level routines take into account that this function is only
|
||||
* called with len < page length of the device (see configuration file)
|
||||
*
|
||||
* @chip: address of the chip which is to be read
|
||||
* @addr: i2c data address within the chip
|
||||
* @alen: length of the i2c data address (1..2 bytes)
|
||||
* @buffer: where to write the data
|
||||
* @len: how much byte do we want to read
|
||||
* @return: 0 in case of success
|
||||
*/
|
||||
|
||||
int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
|
||||
{
|
||||
struct i2c_msg msg;
|
||||
u8 addr_bytes[3]; /* lowest...highest byte of data address */
|
||||
int ret;
|
||||
|
||||
PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
|
||||
|
||||
i2c_reset();
|
||||
|
||||
/* dummy chip address write */
|
||||
PRINTD(("i2c_read: dummy chip address write\n"));
|
||||
msg.condition = I2C_COND_START;
|
||||
msg.acknack = I2C_ACKNAK_WAITACK;
|
||||
msg.direction = I2C_WRITE;
|
||||
msg.data = (chip << 1);
|
||||
msg.data &= 0xFE;
|
||||
if ((ret=i2c_transfer(&msg))) return -1;
|
||||
|
||||
/*
|
||||
* send memory address bytes;
|
||||
* alen defines how much bytes we have to send.
|
||||
*/
|
||||
//addr &= ((1 << CFG_EEPROM_PAGE_WRITE_BITS)-1);
|
||||
addr_bytes[0] = (u8)((addr >> 0) & 0x000000FF);
|
||||
addr_bytes[1] = (u8)((addr >> 8) & 0x000000FF);
|
||||
addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
|
||||
|
||||
while (--alen >= 0) {
|
||||
|
||||
PRINTD(("i2c_read: send memory word address byte %1d\n",alen));
|
||||
msg.condition = I2C_COND_NORMAL;
|
||||
msg.acknack = I2C_ACKNAK_WAITACK;
|
||||
msg.direction = I2C_WRITE;
|
||||
msg.data = addr_bytes[alen];
|
||||
if ((ret=i2c_transfer(&msg))) return -1;
|
||||
}
|
||||
|
||||
|
||||
/* start read sequence */
|
||||
PRINTD(("i2c_read: start read sequence\n"));
|
||||
msg.condition = I2C_COND_START;
|
||||
msg.acknack = I2C_ACKNAK_WAITACK;
|
||||
msg.direction = I2C_WRITE;
|
||||
msg.data = (chip << 1);
|
||||
msg.data |= 0x01;
|
||||
if ((ret=i2c_transfer(&msg))) return -1;
|
||||
|
||||
/* read bytes; send NACK at last byte */
|
||||
while (len--) {
|
||||
|
||||
if (len==0) {
|
||||
msg.condition = I2C_COND_STOP;
|
||||
msg.acknack = I2C_ACKNAK_SENDNAK;
|
||||
} else {
|
||||
msg.condition = I2C_COND_NORMAL;
|
||||
msg.acknack = I2C_ACKNAK_SENDACK;
|
||||
}
|
||||
|
||||
msg.direction = I2C_READ;
|
||||
msg.data = 0x00;
|
||||
if ((ret=i2c_transfer(&msg))) return -1;
|
||||
|
||||
*(buffer++) = msg.data;
|
||||
|
||||
PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
|
||||
|
||||
}
|
||||
|
||||
i2c_reset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* i2c_write: - Write multiple bytes to an i2c device
|
||||
*
|
||||
* The higher level routines take into account that this function is only
|
||||
* called with len < page length of the device (see configuration file)
|
||||
*
|
||||
* @chip: address of the chip which is to be written
|
||||
* @addr: i2c data address within the chip
|
||||
* @alen: length of the i2c data address (1..2 bytes)
|
||||
* @buffer: where to find the data to be written
|
||||
* @len: how much byte do we want to read
|
||||
* @return: 0 in case of success
|
||||
*/
|
||||
|
||||
int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
|
||||
{
|
||||
struct i2c_msg msg;
|
||||
u8 addr_bytes[3]; /* lowest...highest byte of data address */
|
||||
|
||||
PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
|
||||
|
||||
i2c_reset();
|
||||
|
||||
/* chip address write */
|
||||
PRINTD(("i2c_write: chip address write\n"));
|
||||
msg.condition = I2C_COND_START;
|
||||
msg.acknack = I2C_ACKNAK_WAITACK;
|
||||
msg.direction = I2C_WRITE;
|
||||
msg.data = (chip << 1);
|
||||
msg.data &= 0xFE;
|
||||
if (i2c_transfer(&msg)) return -1;
|
||||
|
||||
/*
|
||||
* send memory address bytes;
|
||||
* alen defines how much bytes we have to send.
|
||||
*/
|
||||
addr_bytes[0] = (u8)((addr >> 0) & 0x000000FF);
|
||||
addr_bytes[1] = (u8)((addr >> 8) & 0x000000FF);
|
||||
addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
|
||||
|
||||
while (--alen >= 0) {
|
||||
|
||||
PRINTD(("i2c_write: send memory word address\n"));
|
||||
msg.condition = I2C_COND_NORMAL;
|
||||
msg.acknack = I2C_ACKNAK_WAITACK;
|
||||
msg.direction = I2C_WRITE;
|
||||
msg.data = addr_bytes[alen];
|
||||
if (i2c_transfer(&msg)) return -1;
|
||||
}
|
||||
|
||||
/* write bytes; send NACK at last byte */
|
||||
while (len--) {
|
||||
|
||||
PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
|
||||
|
||||
if (len==0)
|
||||
msg.condition = I2C_COND_STOP;
|
||||
else
|
||||
msg.condition = I2C_COND_NORMAL;
|
||||
|
||||
msg.acknack = I2C_ACKNAK_WAITACK;
|
||||
msg.direction = I2C_WRITE;
|
||||
msg.data = *(buffer++);
|
||||
|
||||
if (i2c_transfer(&msg)) return -1;
|
||||
|
||||
}
|
||||
|
||||
i2c_reset();
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
uchar i2c_reg_read (uchar chip, uchar reg)
|
||||
{
|
||||
PRINTD(("i2c_reg_read(chip=0x%02x, reg=0x%02x)\n",chip,reg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void i2c_reg_write(uchar chip, uchar reg, uchar val)
|
||||
{
|
||||
PRINTD(("i2c_reg_write(chip=0x%02x, reg=0x%02x, val=0x%02x)\n",chip,reg,val));
|
||||
}
|
||||
|
||||
#endif /* CONFIG_HARD_I2C */
|
||||
732
doc/README.POST
Normal file
732
doc/README.POST
Normal file
@@ -0,0 +1,732 @@
|
||||
Power-On-Self-Test support in U-Boot
|
||||
------------------------------------
|
||||
|
||||
This project is to support Power-On-Self-Test (POST) in U-Boot.
|
||||
|
||||
1. High-level requirements
|
||||
|
||||
The key rquirements for this project are as follows:
|
||||
|
||||
1) The project shall develop a flexible framework for implementing
|
||||
and running Power-On-Self-Test in U-Boot. This framework shall
|
||||
possess the following features:
|
||||
|
||||
o) Extensibility
|
||||
|
||||
The framework shall allow adding/removing/replacing POST tests.
|
||||
Also, standalone POST tests shall be supported.
|
||||
|
||||
o) Configurability
|
||||
|
||||
The framework shall allow run-time configuration of the lists
|
||||
of tests running on normal/power-fail booting.
|
||||
|
||||
o) Controllability
|
||||
|
||||
The framework shall support manual running of the POST tests.
|
||||
|
||||
2) The results of tests shall be saved so that it will be possible to
|
||||
retrieve them from Linux.
|
||||
|
||||
3) The following POST tests shall be developed for MPC823E-based
|
||||
boards:
|
||||
|
||||
o) CPU test
|
||||
o) Cache test
|
||||
o) Memory test
|
||||
o) Ethernet test
|
||||
o) Serial channels test
|
||||
o) Watchdog timer test
|
||||
o) RTC test
|
||||
o) I2C test
|
||||
o) SPI test
|
||||
o) USB test
|
||||
|
||||
4) The LWMON board shall be used for reference.
|
||||
|
||||
2. Design
|
||||
|
||||
This section details the key points of the design for the project.
|
||||
The whole project can be divided into two independent tasks:
|
||||
enhancing U-Boot/Linux to provide a common framework for running POST
|
||||
tests and developing such tests for particular hardware.
|
||||
|
||||
2.1. Hardware-independent POST layer
|
||||
|
||||
A new optional module will be added to U-Boot, which will run POST
|
||||
tests and collect their results at boot time. Also, U-Boot will
|
||||
support running POST tests manually at any time by executing a
|
||||
special command from the system console.
|
||||
|
||||
The list of available POST tests will be configured at U-Boot build
|
||||
time. The POST layer will allow the developer to add any custom POST
|
||||
tests. All POST tests will be divided into the following groups:
|
||||
|
||||
1) Tests running on power-on booting only
|
||||
|
||||
This group will contain those tests that run only once on
|
||||
power-on reset (e.g. watchdog test)
|
||||
|
||||
2) Tests running on normal booting only
|
||||
|
||||
This group will contain those tests that do not take much
|
||||
time and can be run on the regular basis (e.g. CPU test)
|
||||
|
||||
3) Tests running on power-fail booting only
|
||||
|
||||
This group will contain POST tests that consume much time
|
||||
and cannot be run regularly (e.g. I2C test)
|
||||
|
||||
4) Manually executed tests
|
||||
|
||||
This group will contain those tests that can be run manually.
|
||||
|
||||
If necessary, some tests may belong to several groups simultaneously.
|
||||
For example, SDRAM test may run on both noarmal and power-fail
|
||||
booting. On normal booting, SDRAM test may perform a fast superficial
|
||||
memory test only, while running on power-fail booting it may perform
|
||||
a full memory check-up.
|
||||
|
||||
Also, all tests will be discriminated by the moment they run at.
|
||||
Specifically, the following groups will be singled out:
|
||||
|
||||
1) Tests running before relocating to RAM
|
||||
|
||||
These tests will run immediatelly after initializing RAM
|
||||
as to enable modifying it without taking care of its
|
||||
contents. Basically, this group will contain memory tests
|
||||
only.
|
||||
|
||||
2) Tests running after relocating to RAM
|
||||
|
||||
These tests will run immediately before entering the main
|
||||
loop as to guarantee full hardware initialization.
|
||||
|
||||
The POST layer will also distinguish a special group of tests that
|
||||
may cause system rebooting (e.g. watchdog test). For such tests, the
|
||||
layer will automatically detect rebooting and will notify the test
|
||||
about it.
|
||||
|
||||
2.1.1. POST layer interfaces
|
||||
|
||||
This section details the interfaces between the POST layer and the
|
||||
rest of U-Boot.
|
||||
|
||||
The following flags will be defined:
|
||||
|
||||
#define POST_ROM 0x01 /* test runs in ROM */
|
||||
#define POST_RAM 0x02 /* test runs in RAM */
|
||||
#define POST_POWERON 0x04 /* test runs on power-on booting */
|
||||
#define POST_NORMAL 0x08 /* test runs on normal booting */
|
||||
#define POST_SHUTDOWN 0x10 /* test runs on power-fail booting */
|
||||
#define POST_MANUAL 0x20 /* test can be executed manually */
|
||||
#define POST_REBOOT 0x80 /* test may cause rebooting */
|
||||
|
||||
The POST layer will export the following interface routines:
|
||||
|
||||
o) int post_run(bd_t *bd, char *name, int flags);
|
||||
|
||||
This routine will run the test (or the group of tests) specified
|
||||
by the name and flag arguments. More specifically, if the name
|
||||
argument is not NULL, the test with this name will be performed,
|
||||
otherwise all tests running in ROM/RAM (depending on the flag
|
||||
argument) will be executed. This routine will be called at least
|
||||
twice with name set to NULL, once from board_init_f() and once
|
||||
from board_init_r(). The flags argument will also specify the
|
||||
mode the test is executed in (power-on, normal, power-fail,
|
||||
manual).
|
||||
|
||||
o) void post_reloc(ulong offset);
|
||||
|
||||
This routine will be called from board_init_r() and will
|
||||
relocate the POST test table.
|
||||
|
||||
o) int post_info(char *name);
|
||||
|
||||
This routine will print the list of all POST tests that can be
|
||||
executed manually if name is NULL, and the description of a
|
||||
particular test if name is not NULL.
|
||||
|
||||
o) int post_log(char *format, ...);
|
||||
|
||||
This routine will be called from POST tests to log their
|
||||
results. Basically, this routine will print the results to
|
||||
stderr. The format of the arguments and the return value
|
||||
will be identical to the printf() routine.
|
||||
|
||||
Also, the following board-specific routines will be called from the
|
||||
U-Boot common code:
|
||||
|
||||
o) int board_power_mode(void)
|
||||
|
||||
This routine will return the mode the system is running in
|
||||
(POST_POWERON, POST_NORMAL or POST_SHUTDOWN).
|
||||
|
||||
o) void board_poweroff(void)
|
||||
|
||||
This routine will turn off the power supply of the board. It
|
||||
will be called on power-fail booting after running all POST
|
||||
tests.
|
||||
|
||||
The list of available POST tests be kept in the post_tests array
|
||||
filled at U-Boot build time. The format of entry in this array will
|
||||
be as follows:
|
||||
|
||||
struct post_test {
|
||||
char *name;
|
||||
char *cmd;
|
||||
char *desc;
|
||||
int flags;
|
||||
int (*test)(bd_t *bd, int flags);
|
||||
};
|
||||
|
||||
o) name
|
||||
|
||||
This field will contain a short name of the test, which will be
|
||||
used in logs and on listing POST tests (e.g. CPU test).
|
||||
|
||||
o) cmd
|
||||
|
||||
This field will keep a name for identifying the test on manual
|
||||
testing (e.g. cpu). For more information, refer to section
|
||||
"Command line interface".
|
||||
|
||||
o) desc
|
||||
|
||||
This field will contain a detailed description of the test,
|
||||
which will be printed on user request. For more information, see
|
||||
section "Command line interface".
|
||||
|
||||
o) flags
|
||||
|
||||
This field will contain a combination of the bit flags described
|
||||
above, which will specify the mode the test is running in
|
||||
(power-on, normal, power-fail or manual mode), the moment it
|
||||
should be run at (before or after relocating to RAM), whether it
|
||||
can cause system rebooting or not.
|
||||
|
||||
o) test
|
||||
|
||||
This field will contain a pointer to the routine that will
|
||||
perform the test, which will take 2 arguments. The first
|
||||
argument will be a pointer to the board info structure, while
|
||||
the second will be a combination of bit flags specifying the
|
||||
mode the test is running in (POST_POWERON, POST_NORMAL,
|
||||
POST_POWERFAIL, POST_MANUAL) and whether the last execution of
|
||||
the test caused system rebooting (POST_REBOOT). The routine will
|
||||
return 0 on successful execution of the test, and 1 if the test
|
||||
failed.
|
||||
|
||||
The lists of the POST tests that should be run at power-on/normal/
|
||||
power-fail booting will be kept in the environment. Namely, the
|
||||
following environment variables will be used: post_poweron,
|
||||
powet_normal, post_shutdown.
|
||||
|
||||
2.1.2. Test results
|
||||
|
||||
The results of tests will be collected by the POST layer. The POST
|
||||
log will have the following format:
|
||||
|
||||
...
|
||||
--------------------------------------------
|
||||
START <name>
|
||||
<test-specific output>
|
||||
[PASSED|FAILED]
|
||||
--------------------------------------------
|
||||
...
|
||||
|
||||
Basically, the results of tests will be printed to stderr. This
|
||||
feature may be enhanced in future to spool the log to a serial line,
|
||||
save it in non-volatile RAM (NVRAM), transfer it to a dedicated
|
||||
storage server and etc.
|
||||
|
||||
2.1.3. Integration issues
|
||||
|
||||
All POST-related code will be #ifdef'ed with the CONFIG_POST macro.
|
||||
This macro will be defined in the config_<board>.h file for those
|
||||
boards that need POST. The CONFIG_POST macro will contain the list of
|
||||
POST tests for the board. The macro will have the format of array
|
||||
composed of post_test structures:
|
||||
|
||||
#define CONFIG_POST \
|
||||
{
|
||||
"On-board peripherals test", "board", \
|
||||
" This test performs full check-up of the " \
|
||||
"on-board hardware.", \
|
||||
POST_RAM | POST_POWERFAIL, \
|
||||
&board_post_test \
|
||||
}
|
||||
|
||||
A new file, post.h, will be created in the include/ directory. This
|
||||
file will contain common POST declarations and will define a set of
|
||||
macros that will be reused for defining CONFIG_POST. As an example,
|
||||
the following macro may be defined:
|
||||
|
||||
#define POST_CACHE \
|
||||
{
|
||||
"Cache test", "cache", \
|
||||
" This test verifies the CPU cache operation.", \
|
||||
POST_RAM | POST_NORMAL, \
|
||||
&cache_post_test \
|
||||
}
|
||||
|
||||
A new subdirectory will be created in the U-Boot root directory. It
|
||||
will contain the source code of the POST layer and most of POST
|
||||
tests. Each POST test in this directory will be placed into a
|
||||
separate file (it will be needed for building standalone tests). Some
|
||||
POST tests (mainly those for testing peripheral devices) will be
|
||||
located in the source files of the drivers for those devices. This
|
||||
way will be used only if the test subtantially uses the driver.
|
||||
|
||||
2.1.4. Standalone tests
|
||||
|
||||
The POST framework will allow to develop and run standalone tests. A
|
||||
user-space library will be developed to provide the POST interface
|
||||
functions to standalone tests.
|
||||
|
||||
2.1.5. Command line interface
|
||||
|
||||
A new command, diag, will be added to U-Boot. This command will be
|
||||
used for listing all available hardware tests, getting detailed
|
||||
descriptions of them and running these tests.
|
||||
|
||||
More specifically, being run without any arguments, this command will
|
||||
print the list of all available hardware tests:
|
||||
|
||||
=> diag
|
||||
Available hardware tests:
|
||||
cache - cache test
|
||||
cpu - CPU test
|
||||
enet - SCC/FCC ethernet test
|
||||
Use 'diag [<test1> [<test2>]] ... ' to get more info.
|
||||
Use 'diag run [<test1> [<test2>]] ... ' to run tests.
|
||||
=>
|
||||
|
||||
If the first argument to the diag command is not 'run', detailed
|
||||
descriptions of the specified tests will be printed:
|
||||
|
||||
=> diag cpu cache
|
||||
cpu - CPU test
|
||||
This test verifies the arithmetic logic unit of CPU.
|
||||
cache - cache test
|
||||
This test verifies the CPU cache operation.
|
||||
=>
|
||||
|
||||
If the first argument to diag is 'run', the specified tests will be
|
||||
executed. If no tests are specified, all available tests will be
|
||||
executed.
|
||||
|
||||
It will be prohibited to execute tests running in ROM manually. The
|
||||
'diag' command will not display such tests and/or run them.
|
||||
|
||||
2.1.6. Power failure handling
|
||||
|
||||
The Linux kernel will be modified to detect power failures and
|
||||
automatically reboot the system in such cases. It will be assumed
|
||||
that the power failure causes a system interrupt.
|
||||
|
||||
To perform correct system shutdown, the kernel will register a
|
||||
handler of the power-fail IRQ on booting. Being called, the handler
|
||||
will run /sbin/reboot using the call_usermodehelper() routine.
|
||||
/sbin/reboot will automatically bring the system down in a secure
|
||||
way. This feature will be configured in/out from the kernel
|
||||
configuration file.
|
||||
|
||||
The POST layer of U-Boot will check whether the system runs in
|
||||
power-fail mode. If it does, the system will be powered off after
|
||||
executing all hardware tests.
|
||||
|
||||
2.1.7. Hazardous tests
|
||||
|
||||
Some tests may cause system rebooting during their execution. For
|
||||
some tests, this will indicate a failure, while for the Watchdog
|
||||
test, this means successful operation of the timer.
|
||||
|
||||
In order to support such tests, the following scheme will be
|
||||
implemented. All the tests that may cause system rebooting will have
|
||||
the POST_REBOOT bit flag set in the flag field of the correspondent
|
||||
post_test structure. Before starting tests marked with this bit flag,
|
||||
the POST layer will store an identification number of the test in a
|
||||
location in IMMR. On booting, the POST layer will check the value of
|
||||
this variable and if it is set will skip over the tests preceding the
|
||||
failed one. On second execution of the failed test, the POST_REBOOT
|
||||
bit flag will be set in the flag argument to the test routine. This
|
||||
will allow to detect system rebooting on the previous iteration. For
|
||||
example, the watchdog timer test may have the following
|
||||
declaration/body:
|
||||
|
||||
...
|
||||
#define POST_WATCHDOG \
|
||||
{
|
||||
"Watchdog timer test", "watchdog", \
|
||||
" This test checks the watchdog timer.", \
|
||||
POST_RAM | POST_POWERON | POST_REBOOT, \
|
||||
&watchdog_post_test \
|
||||
}
|
||||
...
|
||||
|
||||
...
|
||||
int watchdog_post_test(bd_t *bd, int flags)
|
||||
{
|
||||
unsigned long start_time;
|
||||
|
||||
if (flags & POST_REBOOT) {
|
||||
/* Test passed */
|
||||
return 0;
|
||||
} else {
|
||||
/* disable interrupts */
|
||||
disable_interrupts();
|
||||
/* 10-second delay */
|
||||
...
|
||||
/* if we've reached this, the watchdog timer does not work */
|
||||
enable_interrupts();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
...
|
||||
|
||||
2.2. Hardware-specific details
|
||||
|
||||
This project will also develop a set of POST tests for MPC8xx- based
|
||||
systems. This section provides technical details of how it will be
|
||||
done.
|
||||
|
||||
2.2.1. Generic PPC tests
|
||||
|
||||
The following generic POST tests will be developed:
|
||||
|
||||
o) CPU test
|
||||
|
||||
This test will check the arithmetic logic unit (ALU) of CPU. The
|
||||
test will take several milliseconds and will run on normal
|
||||
booting.
|
||||
|
||||
o) Cache test
|
||||
|
||||
This test will verify the CPU cache (L1 cache). The test will
|
||||
run on normal booting.
|
||||
|
||||
o) Memory test
|
||||
|
||||
This test will examine RAM and check it for errors. The test
|
||||
will always run on booting. On normal booting, only a limited
|
||||
amount of RAM will be checked. On power-fail booting a fool
|
||||
memory check-up will be performed.
|
||||
|
||||
2.2.1.1. CPU test
|
||||
|
||||
This test will verify the following ALU instructions:
|
||||
|
||||
o) Condition register istructions
|
||||
|
||||
This group will contain: mtcrf, mfcr, mcrxr, crand, crandc,
|
||||
cror, crorc, crxor, crnand, crnor, creqv, mcrf.
|
||||
|
||||
The mtcrf/mfcr instructions will be tested by loading different
|
||||
values into the condition register (mtcrf), moving its value to
|
||||
a general-purpose register (mfcr) and comparing this value with
|
||||
the expected one. The mcrxr instruction will be tested by
|
||||
loading a fixed value into the XER register (mtspr), moving XER
|
||||
value to the condition register (mcrxr), moving it to a
|
||||
general-purpose register (mfcr) and comparing the value of this
|
||||
register with the expected one. The rest of instructions will be
|
||||
tested by loading a fixed value into the condition register
|
||||
(mtcrf), executing each instruction several times to modify all
|
||||
4-bit condition fields, moving the value of the conditional
|
||||
register to a general-purpose register (mfcr) and comparing it
|
||||
with the expected one.
|
||||
|
||||
o) Integer compare instructions
|
||||
|
||||
This group will contain: cmp, cmpi, cmpl, cmpli.
|
||||
|
||||
To verify these instructions the test will run them with
|
||||
different combinations of operands, read the condition register
|
||||
value and compare it with the expected one. More specifically,
|
||||
the test will contain a pre-built table containing the
|
||||
description of each test case: the instruction, the values of
|
||||
the operands, the condition field to save the result in and the
|
||||
expected result.
|
||||
|
||||
o) Arithmetic instructions
|
||||
|
||||
This group will contain: add, addc, adde, addme, addze, subf,
|
||||
subfc, subfe, subme, subze, mullw, mulhw, mulhwu, divw, divwu,
|
||||
extsb, extsh.
|
||||
|
||||
The test will contain a pre-built table of instructions,
|
||||
operands, expected results and expected states of the condition
|
||||
register. For each table entry, the test will cyclically use
|
||||
different sets of operand registers and result registers. For
|
||||
example, for instructions that use 3 registers on the first
|
||||
iteration r0/r1 will be used as operands and r2 for result. On
|
||||
the second iteration, r1/r2 will be used as operands and r3 as
|
||||
for result and so on. This will enable to verify all
|
||||
general-purpose registers.
|
||||
|
||||
o) Logic instructions
|
||||
|
||||
This group will contain: and, andc, andi, andis, or, orc, ori,
|
||||
oris, xor, xori, xoris, nand, nor, neg, eqv, cntlzw.
|
||||
|
||||
The test scheme will be identical to that from the previous
|
||||
point.
|
||||
|
||||
o) Shift instructions
|
||||
|
||||
This group will contain: slw, srw, sraw, srawi, rlwinm, rlwnm,
|
||||
rlwimi
|
||||
|
||||
The test scheme will be identical to that from the previous
|
||||
point.
|
||||
|
||||
o) Branch instructions
|
||||
|
||||
This group will contain: b, bl, bc.
|
||||
|
||||
The first 2 instructions (b, bl) will be verified by jumping to
|
||||
a fixed address and checking whether control was transfered to
|
||||
that very point. For the bl instruction the value of the link
|
||||
register will be checked as well (using mfspr). To verify the bc
|
||||
instruction various combinations of the BI/BO fields, the CTR
|
||||
and the condition register values will be checked. The list of
|
||||
such combinations will be pre-built and linked in U-Boot at
|
||||
build time.
|
||||
|
||||
o) Load/store instructions
|
||||
|
||||
This group will contain: lbz(x)(u), lhz(x)(u), lha(x)(u),
|
||||
lwz(x)(u), stb(x)(u), sth(x)(u), stw(x)(u).
|
||||
|
||||
All operations will be performed on a 16-byte array. The array
|
||||
will be 4-byte aligned. The base register will point to offset
|
||||
8. The immediate offset (index register) will range in [-8 ...
|
||||
+7]. The test cases will be composed so that they will not cause
|
||||
alignment exceptions. The test will contain a pre-built table
|
||||
describing all test cases. For store instructions, the table
|
||||
entry will contain: the instruction opcode, the value of the
|
||||
index register and the value of the source register. After
|
||||
executing the instruction, the test will verify the contents of
|
||||
the array and the value of the base register (it must change for
|
||||
"store with update" instructions). For load instructions, the
|
||||
table entry will contain: the instruction opcode, the array
|
||||
contents, the value of the index register and the expected value
|
||||
of the destination register. After executing the instruction,
|
||||
the test will verify the value of the destination register and
|
||||
the value of the base register (it must change for "load with
|
||||
update" instructions).
|
||||
|
||||
o) Load/store multiple/string instructions
|
||||
|
||||
|
||||
The CPU test will run in RAM in order to allow run-time modification
|
||||
of the code to reduce the memory footprint.
|
||||
|
||||
2.2.1.2 Special-Purpose Registers Tests
|
||||
|
||||
TBD.
|
||||
|
||||
2.2.1.3. Cache test
|
||||
|
||||
To verify the data cache operation the following test scenarios will
|
||||
be used:
|
||||
|
||||
1) Basic test #1
|
||||
|
||||
- turn on the data cache
|
||||
- switch the data cache to write-back or write-through mode
|
||||
- invalidate the data cache
|
||||
- write the negative pattern to a cached area
|
||||
- read the area
|
||||
|
||||
The negative pattern must be read at the last step
|
||||
|
||||
2) Basic test #2
|
||||
|
||||
- turn on the data cache
|
||||
- switch the data cache to write-back or write-through mode
|
||||
- invalidate the data cache
|
||||
- write the zero pattern to a cached area
|
||||
- turn off the data cache
|
||||
- write the negative pattern to the area
|
||||
- turn on the data cache
|
||||
- read the area
|
||||
|
||||
The negative pattern must be read at the last step
|
||||
|
||||
3) Write-through mode test
|
||||
|
||||
- turn on the data cache
|
||||
- switch the data cache to write-through mode
|
||||
- invalidate the data cache
|
||||
- write the zero pattern to a cached area
|
||||
- flush the data cache
|
||||
- write the negative pattern to the area
|
||||
- turn off the data cache
|
||||
- read the area
|
||||
|
||||
The negative pattern must be read at the last step
|
||||
|
||||
4) Write-back mode test
|
||||
|
||||
- turn on the data cache
|
||||
- switch the data cache to write-back mode
|
||||
- invalidate the data cache
|
||||
- write the negative pattern to a cached area
|
||||
- flush the data cache
|
||||
- write the zero pattern to the area
|
||||
- invalidate the data cache
|
||||
- read the area
|
||||
|
||||
The negative pattern must be read at the last step
|
||||
|
||||
To verify the instruction cache operation the following test
|
||||
scenarios will be used:
|
||||
|
||||
1) Basic test #1
|
||||
|
||||
- turn on the instruction cache
|
||||
- unlock the entire instruction cache
|
||||
- invalidate the instruction cache
|
||||
- lock a branch instruction in the instruction cache
|
||||
- replace the branch instruction with "nop"
|
||||
- jump to the branch instruction
|
||||
- check that the branch instruction was executed
|
||||
|
||||
2) Basic test #2
|
||||
|
||||
- turn on the instruction cache
|
||||
- unlock the entire instruction cache
|
||||
- invalidate the instruction cache
|
||||
- jump to a branch instruction
|
||||
- check that the branch instruction was executed
|
||||
- replace the branch instruction with "nop"
|
||||
- invalidate the instruction cache
|
||||
- jump to the branch instruction
|
||||
- check that the "nop" instruction was executed
|
||||
|
||||
The CPU test will run in RAM in order to allow run-time modification
|
||||
of the code.
|
||||
|
||||
2.2.1.4. Memory test
|
||||
|
||||
The memory test will verify RAM using sequential writes and reads
|
||||
to/from RAM. Specifically, there will be several test cases that will
|
||||
use different patterns to verify RAM. Each test case will first fill
|
||||
a region of RAM with one pattern and then read the region back and
|
||||
compare its contents with the pattern. The following patterns will be
|
||||
used:
|
||||
|
||||
1) zero pattern (0x00000000)
|
||||
2) negative pattern (0xffffffff)
|
||||
3) checkerboard pattern (0x55555555, 0xaaaaaaaa)
|
||||
4) bit-flip pattern ((1 << (offset % 32)), ~(1 << (offset % 32)))
|
||||
5) address pattern (offset, ~offset)
|
||||
|
||||
Patterns #1, #2 will help to find unstable bits. Patterns #3, #4 will
|
||||
be used to detect adherent bits, i.e. bits whose state may randomly
|
||||
change if adjacent bits are modified. The last pattern will be used
|
||||
to detect far-located errors, i.e. situations when writing to one
|
||||
location modifies an area located far from it. Also, usage of the
|
||||
last pattern will help to detect memory controller misconfigurations
|
||||
when RAM represents a cyclically repeated portion of a smaller size.
|
||||
|
||||
Being run in normal mode, the test will verify only small 4Kb regions
|
||||
of RAM around each 1Mb boundary. For example, for 64Mb RAM the
|
||||
following areas will be verified: 0x00000000-0x00000800,
|
||||
0x000ff800-0x00100800, 0x001ff800-0x00200800, ..., 0x03fff800-
|
||||
0x04000000. If the test is run in power-fail mode, it will verify the
|
||||
whole RAM.
|
||||
|
||||
The memory test will run in ROM before relocating U-Boot to RAM in
|
||||
order to allow RAM modification without saving its contents.
|
||||
|
||||
2.2.2. Common tests
|
||||
|
||||
This section describes tests that are not based on any hardware
|
||||
peculiarities and use common U-Boot interfaces only. These tests do
|
||||
not need any modifications for porting them to another board/CPU.
|
||||
|
||||
2.2.2.1. I2C test
|
||||
|
||||
For verifying the I2C bus, a full I2C bus scanning will be performed
|
||||
using the i2c_probe() routine. If any I2C device is found, the test
|
||||
will be considered as passed, otherwise failed. This particular way
|
||||
will be used because it provides the most common method of testing.
|
||||
For example, using the internal loopback mode of the CPM I2C
|
||||
controller for testing would not work on boards where the software
|
||||
I2C driver (also known as bit-banged driver) is used.
|
||||
|
||||
2.2.2.2. Watchdog timer test
|
||||
|
||||
To test the watchdog timer the scheme mentioned above (refer to
|
||||
section "Hazardous tests") will be used. Namely, this test will be
|
||||
marked with the POST_REBOOT bit flag. On the first iteration, the
|
||||
test routine will make a 10-second delay. If the system does not
|
||||
reboot during this delay, the watchdog timer is not operational and
|
||||
the test fails. If the system reboots, on the second iteration the
|
||||
POST_REBOOT bit will be set in the flag argument to the test routine.
|
||||
The test routine will check this bit and report a success if it is
|
||||
set.
|
||||
|
||||
2.2.2.3. RTC test
|
||||
|
||||
The RTC test will use the rtc_get()/rtc_set() routines. The following
|
||||
features will be verified:
|
||||
|
||||
o) Time uniformity
|
||||
|
||||
This will be verified by reading RTC in polling within a short
|
||||
period of time (5-10 seconds).
|
||||
|
||||
o) Passing month boundaries
|
||||
|
||||
This will be checked by setting RTC to a second before a month
|
||||
boundary and reading it after its passing the boundary. The test
|
||||
will be performed for both leap- and nonleap-years.
|
||||
|
||||
2.2.3. MPC8xx peripherals tests
|
||||
|
||||
This project will develop a set of tests verifying the peripheral
|
||||
units of MPC8xx processors. Namely, the following controllers of the
|
||||
MPC8xx communication processor module (CPM) will be tested:
|
||||
|
||||
o) Serial Management Controllers (SMC)
|
||||
|
||||
o) Serial Communication Controllers (SCC)
|
||||
|
||||
2.2.3.1. Ethernet tests (SCC)
|
||||
|
||||
The internal (local) loopback mode will be used to test SCC. To do
|
||||
that the controllers will be configured accordingly and several
|
||||
packets will be transmitted. These tests may be enhanced in future to
|
||||
use external loopback for testing. That will need appropriate
|
||||
reconfiguration of the physical interface chip.
|
||||
|
||||
The test routines for the SCC ethernet tests will be located in
|
||||
cpu/mpc8xx/scc.c.
|
||||
|
||||
2.2.3.2. UART tests (SMC/SCC)
|
||||
|
||||
To perform these tests the internal (local) loopback mode will be
|
||||
used. The SMC/SCC controllers will be configured to connect the
|
||||
transmitter output to the receiver input. After that, several bytes
|
||||
will be transmitted. These tests may be enhanced to make to perform
|
||||
"external" loopback test using a loopback cable. In this case, the
|
||||
test will be executed manually.
|
||||
|
||||
The test routine for the SMC/SCC UART tests will be located in
|
||||
cpu/mpc8xx/serial.c.
|
||||
|
||||
2.2.3.3. USB test
|
||||
|
||||
TBD
|
||||
|
||||
2.2.3.4. SPI test
|
||||
|
||||
TBD
|
||||
|
||||
2.3. Design notes
|
||||
|
||||
Currently it is unknown how we will power off the board after running
|
||||
all power-fail POST tests. This point needs further clarification.
|
||||
@@ -28,12 +28,13 @@ include $(TOPDIR)/config.mk
|
||||
LIB = libdrivers.a
|
||||
|
||||
OBJS = 3c589.o 5701rls.o bcm570x.o bcm570x_autoneg.o \
|
||||
cfb_console.o cs8900.o dc2114x.o eepro100.o \
|
||||
i8042.o natsemi.o ns16550.o ns8382x.o ns87308.o \
|
||||
cfb_console.o cs8900.o ct69000.o dc2114x.o \
|
||||
eepro100.o i8042.o inca-ip_sw.o \
|
||||
natsemi.o ns16550.o ns8382x.o ns87308.o \
|
||||
pci.o pci_auto.o pci_indirect.o \
|
||||
pcnet.o sed13806.o serial.o \
|
||||
smc91111.o smiLynxEM.o sym53c8xx.o \
|
||||
tigon3.o w83c553f.o ct69000.o
|
||||
tigon3.o w83c553f.o
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
|
||||
304
drivers/cs8900.c
304
drivers/cs8900.c
@@ -1,6 +1,10 @@
|
||||
/*
|
||||
* Cirrus Logic CS8900A Ethernet
|
||||
*
|
||||
* (C) 2003 Wolfgang Denk, wd@denx.de
|
||||
* Extension to synchronize ethaddr environment variable
|
||||
* against value in EEPROM
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
@@ -48,188 +52,226 @@
|
||||
/* we don't need 16 bit initialisation on 32 bit bus */
|
||||
#define get_reg_init_bus(x) get_reg((x))
|
||||
#else
|
||||
static unsigned short get_reg_init_bus(int regno)
|
||||
static unsigned short get_reg_init_bus (int regno)
|
||||
{
|
||||
/* force 16 bit busmode */
|
||||
volatile unsigned char c;
|
||||
c = CS8900_BUS16_0;
|
||||
c = CS8900_BUS16_1;
|
||||
c = CS8900_BUS16_0;
|
||||
c = CS8900_BUS16_1;
|
||||
c = CS8900_BUS16_0;
|
||||
/* force 16 bit busmode */
|
||||
volatile unsigned char c;
|
||||
|
||||
CS8900_PPTR = regno;
|
||||
return (unsigned short) CS8900_PDATA;
|
||||
c = CS8900_BUS16_0;
|
||||
c = CS8900_BUS16_1;
|
||||
c = CS8900_BUS16_0;
|
||||
c = CS8900_BUS16_1;
|
||||
c = CS8900_BUS16_0;
|
||||
|
||||
CS8900_PPTR = regno;
|
||||
return (unsigned short) CS8900_PDATA;
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned short
|
||||
get_reg(int regno)
|
||||
static unsigned short get_reg (int regno)
|
||||
{
|
||||
CS8900_PPTR = regno;
|
||||
return (unsigned short) CS8900_PDATA;
|
||||
CS8900_PPTR = regno;
|
||||
return (unsigned short) CS8900_PDATA;
|
||||
}
|
||||
|
||||
|
||||
static void put_reg(int regno, unsigned short val)
|
||||
static void put_reg (int regno, unsigned short val)
|
||||
{
|
||||
CS8900_PPTR = regno;
|
||||
CS8900_PDATA = val;
|
||||
CS8900_PPTR = regno;
|
||||
CS8900_PDATA = val;
|
||||
}
|
||||
|
||||
static void eth_reset(void)
|
||||
static void eth_reset (void)
|
||||
{
|
||||
int tmo;
|
||||
unsigned short us;
|
||||
int tmo;
|
||||
unsigned short us;
|
||||
|
||||
/* reset NIC */
|
||||
put_reg(PP_SelfCTL, get_reg(PP_SelfCTL) | PP_SelfCTL_Reset );
|
||||
/* reset NIC */
|
||||
put_reg (PP_SelfCTL, get_reg (PP_SelfCTL) | PP_SelfCTL_Reset);
|
||||
|
||||
/* wait for 200ms */
|
||||
udelay(200000);
|
||||
/* Wait until the chip is reset */
|
||||
/* wait for 200ms */
|
||||
udelay (200000);
|
||||
/* Wait until the chip is reset */
|
||||
|
||||
tmo = get_timer(0) + 1 * CFG_HZ;
|
||||
while ((((us = get_reg_init_bus(PP_SelfSTAT)) & PP_SelfSTAT_InitD) == 0)
|
||||
&& tmo < get_timer(0))
|
||||
/*NOP*/;
|
||||
tmo = get_timer (0) + 1 * CFG_HZ;
|
||||
while ((((us = get_reg_init_bus (PP_SelfSTAT)) & PP_SelfSTAT_InitD) == 0)
|
||||
&& tmo < get_timer (0))
|
||||
/*NOP*/;
|
||||
}
|
||||
|
||||
void cs8900_get_enetaddr (uchar *addr)
|
||||
void cs8900_get_enetaddr (uchar * addr)
|
||||
{
|
||||
int i;
|
||||
/* verify chip id */
|
||||
if (get_reg_init_bus(PP_ChipID) != 0x630e)
|
||||
return;
|
||||
eth_reset();
|
||||
if ((get_reg(PP_SelfST) & (PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) ==
|
||||
(PP_SelfSTAT_EEPROM|PP_SelfSTAT_EEPROM_OK)) {
|
||||
/* Load the MAC from EEPROM */
|
||||
for (i=0; i<6/2; i++) {
|
||||
unsigned int Addr;
|
||||
Addr = get_reg(PP_IA+i*2);
|
||||
addr[i*2] = Addr & 0xFF;
|
||||
addr[i*2+1] = Addr >> 8;
|
||||
int i;
|
||||
unsigned char env_enetaddr[6];
|
||||
char *tmp = getenv ("ethaddr");
|
||||
char *end;
|
||||
|
||||
for (i=0; i<6; i++) {
|
||||
env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
|
||||
if (tmp)
|
||||
tmp = (*end) ? end+1 : end;
|
||||
}
|
||||
|
||||
/* verify chip id */
|
||||
if (get_reg_init_bus (PP_ChipID) != 0x630e)
|
||||
return;
|
||||
eth_reset ();
|
||||
if ((get_reg (PP_SelfST) & (PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) ==
|
||||
(PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) {
|
||||
|
||||
/* Load the MAC from EEPROM */
|
||||
for (i = 0; i < 6 / 2; i++) {
|
||||
unsigned int Addr;
|
||||
|
||||
Addr = get_reg (PP_IA + i * 2);
|
||||
addr[i * 2] = Addr & 0xFF;
|
||||
addr[i * 2 + 1] = Addr >> 8;
|
||||
}
|
||||
|
||||
if (memcmp(env_enetaddr, "\0\0\0\0\0\0", 6) != 0 &&
|
||||
memcmp(env_enetaddr, addr, 6) != 0) {
|
||||
printf ("\nWarning: MAC addresses don't match:\n");
|
||||
printf ("\tHW MAC address: "
|
||||
"%02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
addr[0], addr[1],
|
||||
addr[2], addr[3],
|
||||
addr[4], addr[5] );
|
||||
printf ("\t\"ethaddr\" value: "
|
||||
"%02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
env_enetaddr[0], env_enetaddr[1],
|
||||
env_enetaddr[2], env_enetaddr[3],
|
||||
env_enetaddr[4], env_enetaddr[5]) ;
|
||||
debug ("### Set MAC addr from environment\n");
|
||||
memcpy (addr, env_enetaddr, 6);
|
||||
}
|
||||
if (!tmp) {
|
||||
char ethaddr[20];
|
||||
sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
addr[0], addr[1],
|
||||
addr[2], addr[3],
|
||||
addr[4], addr[5]) ;
|
||||
debug ("### Set environment from HW MAC addr = \"%s\"\n", ethaddr);
|
||||
setenv ("ethaddr", ethaddr);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void eth_halt( void )
|
||||
void eth_halt (void)
|
||||
{
|
||||
/* disable transmitter/receiver mode */
|
||||
put_reg(PP_LineCTL, 0);
|
||||
/* disable transmitter/receiver mode */
|
||||
put_reg (PP_LineCTL, 0);
|
||||
|
||||
/* "shutdown" to show ChipID or kernel wouldn't find he cs8900 ... */
|
||||
get_reg_init_bus(PP_ChipID);
|
||||
/* "shutdown" to show ChipID or kernel wouldn't find he cs8900 ... */
|
||||
get_reg_init_bus (PP_ChipID);
|
||||
}
|
||||
|
||||
int eth_init( bd_t *bd )
|
||||
int eth_init (bd_t * bd)
|
||||
{
|
||||
|
||||
/* verify chip id */
|
||||
if (get_reg_init_bus(PP_ChipID) != 0x630e)
|
||||
{
|
||||
printf( "CS8900 Ethernet chip not found?!\n" );
|
||||
/* verify chip id */
|
||||
if (get_reg_init_bus (PP_ChipID) != 0x630e) {
|
||||
printf ("CS8900 Ethernet chip not found?!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
eth_reset ();
|
||||
/* set the ethernet address */
|
||||
put_reg (PP_IA + 0, bd->bi_enetaddr[0] | (bd->bi_enetaddr[1] << 8));
|
||||
put_reg (PP_IA + 2, bd->bi_enetaddr[2] | (bd->bi_enetaddr[3] << 8));
|
||||
put_reg (PP_IA + 4, bd->bi_enetaddr[4] | (bd->bi_enetaddr[5] << 8));
|
||||
|
||||
/* receive only error free packets addressed to this card */
|
||||
put_reg (PP_RxCTL, PP_RxCTL_IA | PP_RxCTL_Broadcast | PP_RxCTL_RxOK);
|
||||
|
||||
/* do not generate any interrupts on receive operations */
|
||||
put_reg (PP_RxCFG, 0);
|
||||
|
||||
/* do not generate any interrupts on transmit operations */
|
||||
put_reg (PP_TxCFG, 0);
|
||||
|
||||
/* do not generate any interrupts on buffer operations */
|
||||
put_reg (PP_BufCFG, 0);
|
||||
|
||||
/* enable transmitter/receiver mode */
|
||||
put_reg (PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
eth_reset();
|
||||
/* set the ethernet address */
|
||||
put_reg(PP_IA + 0, bd->bi_enetaddr[0] | (bd->bi_enetaddr[1] << 8));
|
||||
put_reg(PP_IA + 2, bd->bi_enetaddr[2] | (bd->bi_enetaddr[3] << 8));
|
||||
put_reg(PP_IA + 4, bd->bi_enetaddr[4] | (bd->bi_enetaddr[5] << 8));
|
||||
|
||||
/* receive only error free packets addressed to this card */
|
||||
put_reg(PP_RxCTL, PP_RxCTL_IA | PP_RxCTL_Broadcast | PP_RxCTL_RxOK);
|
||||
|
||||
/* do not generate any interrupts on receive operations */
|
||||
put_reg(PP_RxCFG, 0);
|
||||
|
||||
/* do not generate any interrupts on transmit operations */
|
||||
put_reg(PP_TxCFG, 0);
|
||||
|
||||
/* do not generate any interrupts on buffer operations */
|
||||
put_reg(PP_BufCFG, 0);
|
||||
|
||||
/* enable transmitter/receiver mode */
|
||||
put_reg(PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get a data block via Ethernet */
|
||||
extern int eth_rx(void)
|
||||
extern int eth_rx (void)
|
||||
{
|
||||
int i;
|
||||
unsigned short rxlen;
|
||||
unsigned short *addr;
|
||||
unsigned short status;
|
||||
int i;
|
||||
unsigned short rxlen;
|
||||
unsigned short *addr;
|
||||
unsigned short status;
|
||||
|
||||
status = get_reg(PP_RER);
|
||||
status = get_reg (PP_RER);
|
||||
|
||||
if ((status & PP_RER_RxOK) == 0)
|
||||
return 0;
|
||||
if ((status & PP_RER_RxOK) == 0)
|
||||
return 0;
|
||||
|
||||
status = CS8900_RTDATA; /* stat */
|
||||
rxlen = CS8900_RTDATA; /* len */
|
||||
status = CS8900_RTDATA; /* stat */
|
||||
rxlen = CS8900_RTDATA; /* len */
|
||||
|
||||
if(rxlen > PKTSIZE_ALIGN + PKTALIGN)
|
||||
printf("packet too big!\n");
|
||||
if (rxlen > PKTSIZE_ALIGN + PKTALIGN)
|
||||
printf ("packet too big!\n");
|
||||
|
||||
for(addr = (unsigned short *)NetRxPackets[0], i = rxlen >> 1; i > 0; i-- )
|
||||
*addr++ = CS8900_RTDATA;
|
||||
if(rxlen & 1)
|
||||
*addr++ = CS8900_RTDATA;
|
||||
for (addr = (unsigned short *) NetRxPackets[0], i = rxlen >> 1; i > 0;
|
||||
i--)
|
||||
*addr++ = CS8900_RTDATA;
|
||||
if (rxlen & 1)
|
||||
*addr++ = CS8900_RTDATA;
|
||||
|
||||
/* Pass the packet up to the protocol layers. */
|
||||
NetReceive(NetRxPackets[0], rxlen);
|
||||
/* Pass the packet up to the protocol layers. */
|
||||
NetReceive (NetRxPackets[0], rxlen);
|
||||
|
||||
return rxlen;
|
||||
return rxlen;
|
||||
}
|
||||
|
||||
/* Send a data block via Ethernet. */
|
||||
extern int eth_send(volatile void *packet, int length)
|
||||
extern int eth_send (volatile void *packet, int length)
|
||||
{
|
||||
volatile unsigned short *addr;
|
||||
int tmo;
|
||||
unsigned short s;
|
||||
volatile unsigned short *addr;
|
||||
int tmo;
|
||||
unsigned short s;
|
||||
|
||||
retry:
|
||||
/* initiate a transmit sequence */
|
||||
CS8900_TxCMD = PP_TxCmd_TxStart_Full;
|
||||
CS8900_TxLEN = length;
|
||||
/* initiate a transmit sequence */
|
||||
CS8900_TxCMD = PP_TxCmd_TxStart_Full;
|
||||
CS8900_TxLEN = length;
|
||||
|
||||
/* Test to see if the chip has allocated memory for the packet */
|
||||
if ((get_reg(PP_BusSTAT) & PP_BusSTAT_TxRDY) == 0) {
|
||||
/* Oops... this should not happen! */
|
||||
printf("cs: unable to send packet; retrying...\n");
|
||||
for (tmo = get_timer(0) + 5 * CFG_HZ; get_timer(0) < tmo; )
|
||||
/*NOP*/;
|
||||
eth_reset();
|
||||
goto retry;
|
||||
}
|
||||
/* Test to see if the chip has allocated memory for the packet */
|
||||
if ((get_reg (PP_BusSTAT) & PP_BusSTAT_TxRDY) == 0) {
|
||||
/* Oops... this should not happen! */
|
||||
printf ("cs: unable to send packet; retrying...\n");
|
||||
for (tmo = get_timer (0) + 5 * CFG_HZ; get_timer (0) < tmo;)
|
||||
/*NOP*/;
|
||||
eth_reset ();
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/* Write the contents of the packet */
|
||||
/* assume even number of bytes */
|
||||
for(addr = packet; length > 0; length -= 2 )
|
||||
CS8900_RTDATA = *addr++;
|
||||
/* Write the contents of the packet */
|
||||
/* assume even number of bytes */
|
||||
for (addr = packet; length > 0; length -= 2)
|
||||
CS8900_RTDATA = *addr++;
|
||||
|
||||
/* wait for transfer to succeed */
|
||||
tmo = get_timer(0) + 5 * CFG_HZ;
|
||||
while((s = get_reg(PP_TER) & ~0x1F) == 0)
|
||||
{
|
||||
if (get_timer(0) >= tmo)
|
||||
break;
|
||||
}
|
||||
/* wait for transfer to succeed */
|
||||
tmo = get_timer (0) + 5 * CFG_HZ;
|
||||
while ((s = get_reg (PP_TER) & ~0x1F) == 0) {
|
||||
if (get_timer (0) >= tmo)
|
||||
break;
|
||||
}
|
||||
|
||||
/* nothing */ ;
|
||||
if ((s & (PP_TER_CRS | PP_TER_TxOK)) != PP_TER_TxOK) {
|
||||
printf("\ntransmission error %#x\n", s);
|
||||
}
|
||||
/* nothing */ ;
|
||||
if ((s & (PP_TER_CRS | PP_TER_TxOK)) != PP_TER_TxOK) {
|
||||
printf ("\ntransmission error %#x\n", s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* COMMANDS & CFG_NET */
|
||||
#endif /* COMMANDS & CFG_NET */
|
||||
|
||||
#endif /* CONFIG_DRIVER_CS8900 */
|
||||
#endif /* CONFIG_DRIVER_CS8900 */
|
||||
|
||||
@@ -505,4 +505,23 @@ int pci_hose_scan(struct pci_controller *hose)
|
||||
return pci_hose_scan_bus(hose, hose->first_busno);
|
||||
}
|
||||
|
||||
void pci_init(void)
|
||||
{
|
||||
#if defined(CONFIG_PCI_BOOTDELAY)
|
||||
char *s;
|
||||
int i;
|
||||
|
||||
/* wait "pcidelay" ms (if defined)... */
|
||||
s = getenv ("pcidelay");
|
||||
if (s) {
|
||||
int val = simple_strtoul (s, NULL, 10);
|
||||
for (i=0; i<val; i++)
|
||||
udelay (1000);
|
||||
}
|
||||
#endif /* CONFIG_PCI_BOOTDELAY */
|
||||
|
||||
/* now call board specific pci_init()... */
|
||||
pci_init_board();
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
@@ -285,34 +285,22 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
|
||||
unsigned int sub_bus = PCI_BUS(dev);
|
||||
unsigned short class;
|
||||
unsigned char prg_iface;
|
||||
int n;
|
||||
|
||||
pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
|
||||
|
||||
switch(class)
|
||||
{
|
||||
case PCI_CLASS_BRIDGE_PCI:
|
||||
hose->current_busno++;
|
||||
pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_io);
|
||||
|
||||
DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n",
|
||||
PCI_DEV(dev));
|
||||
DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev));
|
||||
pciauto_prescan_setup_bridge(hose, dev, sub_bus);
|
||||
|
||||
pci_hose_scan_bus(hose, hose->current_busno);
|
||||
|
||||
/* HJF: Make sure two bridges on the same bus
|
||||
* won't get the same bus number
|
||||
*/
|
||||
pciauto_prescan_setup_bridge(hose, dev,
|
||||
max(sub_bus, hose->current_busno));
|
||||
|
||||
n = pci_hose_scan_bus(hose, hose->current_busno+1 /*PCI_BUS(dev)+1*/);
|
||||
sub_bus = max(sub_bus, n);
|
||||
sub_bus = max(sub_bus, hose->current_busno);
|
||||
|
||||
DEBUGF("PCI Autoconfig: Got %d from pci_hose_scan_bus\n",
|
||||
sub_bus);
|
||||
|
||||
pciauto_postscan_setup_bridge(hose, dev,
|
||||
max(sub_bus, hose->current_busno));
|
||||
hose->current_busno++;
|
||||
pciauto_postscan_setup_bridge(hose, dev, sub_bus);
|
||||
sub_bus = hose->current_busno;
|
||||
break;
|
||||
|
||||
case PCI_CLASS_STORAGE_IDE:
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
/* History: */
|
||||
/******************************************************************************/
|
||||
#include <common.h>
|
||||
#include "bcm570x_mm.h"
|
||||
#include <asm/types.h>
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NET) && !defined(CONFIG_NET_MULTI) && \
|
||||
defined(CONFIG_TIGON3)
|
||||
@@ -20,6 +19,7 @@
|
||||
#endif
|
||||
#include <malloc.h>
|
||||
#include <linux/byteorder/big_endian.h>
|
||||
#include "bcm570x_mm.h"
|
||||
|
||||
#define EMBEDDED 1
|
||||
/******************************************************************************/
|
||||
|
||||
@@ -27,6 +27,10 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
SREC = hello_world.srec
|
||||
|
||||
ifeq ($(CPU),mips)
|
||||
SREC =
|
||||
endif
|
||||
|
||||
# The following example is pretty 8xx specific...
|
||||
ifeq ($(CPU),mpc8xx)
|
||||
SREC += timer.srec
|
||||
|
||||
@@ -37,7 +37,37 @@ mon_free:
|
||||
stmfd sp!, {fp, ip, lr, pc}
|
||||
sub fp, ip, #4
|
||||
ldmea fp, {fp, sp, pc}
|
||||
#else /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
|
||||
#elif defined(CONFIG_MIPS)/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
|
||||
#warning MIPS version not implemented yet
|
||||
.global mon_getc
|
||||
.type mon_getc,function
|
||||
mon_getc:
|
||||
.global mon_tstc
|
||||
.type mon_tstc,function
|
||||
mon_tstc:
|
||||
.global mon_putc
|
||||
.type mon_putc,function
|
||||
mon_putc:
|
||||
.global mon_puts
|
||||
.type mon_puts,function
|
||||
mon_puts:
|
||||
.global mon_printf
|
||||
.type mon_printf,function
|
||||
mon_printf:
|
||||
.global mon_install_hdlr
|
||||
.type mon_install_hdlr,function
|
||||
mon_install_hdlr:
|
||||
.global mon_free_hdlr
|
||||
.type mon_free_hdlr,function
|
||||
mon_free_hdlr:
|
||||
.global mon_malloc
|
||||
.type mon_malloc,function
|
||||
mon_malloc:
|
||||
.global mon_free
|
||||
.type mon_free,function
|
||||
mon_free:
|
||||
|
||||
#else
|
||||
|
||||
#ifdef CONFIG_I386 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
|
||||
#define SYMBOL_NAME(X) X
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef PXA_REGS_H
|
||||
#define PXA_REGS_H 1
|
||||
|
||||
/* FIXME hack so that SA-1111.h will work [cb] */
|
||||
|
||||
@@ -425,6 +427,38 @@ typedef void (*ExcpHndlr) (void) ;
|
||||
#define ISR __REG(0x40301698) /* I2C Status Register - ISR */
|
||||
#define ISAR __REG(0x403016A0) /* I2C Slave Address Register - ISAR */
|
||||
|
||||
/* ----- Control register bits ---------------------------------------- */
|
||||
|
||||
#define ICR_START 0x1 /* start bit */
|
||||
#define ICR_STOP 0x2 /* stop bit */
|
||||
#define ICR_ACKNAK 0x4 /* send ACK(0) or NAK(1) */
|
||||
#define ICR_TB 0x8 /* transfer byte bit */
|
||||
#define ICR_MA 0x10 /* master abort */
|
||||
#define ICR_SCLE 0x20 /* master clock enable */
|
||||
#define ICR_IUE 0x40 /* unit enable */
|
||||
#define ICR_GCD 0x80 /* general call disable */
|
||||
#define ICR_ITEIE 0x100 /* enable tx interrupts */
|
||||
#define ICR_IRFIE 0x200 /* enable rx interrupts */
|
||||
#define ICR_BEIE 0x400 /* enable bus error ints */
|
||||
#define ICR_SSDIE 0x800 /* slave STOP detected int enable */
|
||||
#define ICR_ALDIE 0x1000 /* enable arbitration interrupt */
|
||||
#define ICR_SADIE 0x2000 /* slave address detected int enable */
|
||||
#define ICR_UR 0x4000 /* unit reset */
|
||||
|
||||
/* ----- Status register bits ----------------------------------------- */
|
||||
|
||||
#define ISR_RWM 0x1 /* read/write mode */
|
||||
#define ISR_ACKNAK 0x2 /* ack/nak status */
|
||||
#define ISR_UB 0x4 /* unit busy */
|
||||
#define ISR_IBB 0x8 /* bus busy */
|
||||
#define ISR_SSD 0x10 /* slave stop detected */
|
||||
#define ISR_ALD 0x20 /* arbitration loss detected */
|
||||
#define ISR_ITE 0x40 /* tx buffer empty */
|
||||
#define ISR_IRF 0x80 /* rx buffer full */
|
||||
#define ISR_GCAD 0x100 /* general call address detected */
|
||||
#define ISR_SAD 0x200 /* slave address detected */
|
||||
#define ISR_BED 0x400 /* bus error no ACK/NAK */
|
||||
|
||||
|
||||
/*
|
||||
* Serial Audio Controller
|
||||
@@ -1128,6 +1162,6 @@ typedef void (*ExcpHndlr) (void) ;
|
||||
#define MCIO1_OFFSET 0x3C
|
||||
#define MDMRS_OFFSET 0x40
|
||||
|
||||
|
||||
#endif /* PXA_REGS_H */
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
/*
|
||||
* linux/include/asm-arm/arch-pxa/pxa-regs.h
|
||||
*
|
||||
*
|
||||
* Author: Nicolas Pitre
|
||||
* Created: Jun 15, 2001
|
||||
* Copyright: MontaVista Software Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* - 2003/01/20: Robert Schwebel <r.schwebel@pengutronix.de
|
||||
* Original file taken from linux-2.4.19-rmk4-pxa1. Added some definitions.
|
||||
* Added include for hardware.h (for __REG definition)
|
||||
*/
|
||||
#ifndef _PXA_REGS_H_
|
||||
#define _PXA_REGS_H_
|
||||
|
||||
#include "bitfield.h"
|
||||
#include "hardware.h"
|
||||
|
||||
/* FIXME hack so that SA-1111.h will work [cb] */
|
||||
|
||||
@@ -22,13 +30,6 @@ typedef void *Address ;
|
||||
typedef void (*ExcpHndlr) (void) ;
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#define io_p2v(PhAdd) (PhAdd)
|
||||
#define __REG(x) (*((volatile u32 *)io_p2v(x)))
|
||||
#else
|
||||
#define __REG(x) (x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PXA Chip selects
|
||||
*/
|
||||
@@ -369,7 +370,7 @@ typedef void (*ExcpHndlr) (void) ;
|
||||
#define LSR_OE (1 << 1) /* Overrun Error */
|
||||
#define LSR_DR (1 << 0) /* Data Ready */
|
||||
|
||||
#define MCR_LOOP (1 << 4) */
|
||||
#define MCR_LOOP (1 << 4) */
|
||||
#define MCR_OUT2 (1 << 3) /* force MSR_DCD in loopback mode */
|
||||
#define MCR_OUT1 (1 << 2) /* force MSR_RI in loopback mode */
|
||||
#define MCR_RTS (1 << 1) /* Request to Send */
|
||||
@@ -414,7 +415,6 @@ typedef void (*ExcpHndlr) (void) ;
|
||||
IrSR_RCVEIR_UART_MODE | \
|
||||
IrSR_XMITIR_IR_MODE)
|
||||
|
||||
|
||||
/*
|
||||
* I2C registers
|
||||
*/
|
||||
@@ -425,6 +425,38 @@ typedef void (*ExcpHndlr) (void) ;
|
||||
#define ISR __REG(0x40301698) /* I2C Status Register - ISR */
|
||||
#define ISAR __REG(0x403016A0) /* I2C Slave Address Register - ISAR */
|
||||
|
||||
/* ----- Control register bits ---------------------------------------- */
|
||||
|
||||
#define ICR_START 0x1 /* start bit */
|
||||
#define ICR_STOP 0x2 /* stop bit */
|
||||
#define ICR_ACKNAK 0x4 /* send ACK(0) or NAK(1) */
|
||||
#define ICR_TB 0x8 /* transfer byte bit */
|
||||
#define ICR_MA 0x10 /* master abort */
|
||||
#define ICR_SCLE 0x20 /* master clock enable */
|
||||
#define ICR_IUE 0x40 /* unit enable */
|
||||
#define ICR_GCD 0x80 /* general call disable */
|
||||
#define ICR_ITEIE 0x100 /* enable tx interrupts */
|
||||
#define ICR_IRFIE 0x200 /* enable rx interrupts */
|
||||
#define ICR_BEIE 0x400 /* enable bus error ints */
|
||||
#define ICR_SSDIE 0x800 /* slave STOP detected int enable */
|
||||
#define ICR_ALDIE 0x1000 /* enable arbitration interrupt */
|
||||
#define ICR_SADIE 0x2000 /* slave address detected int enable */
|
||||
#define ICR_UR 0x4000 /* unit reset */
|
||||
#define ICR_FM 0x8000 /* Fast Mode */
|
||||
|
||||
/* ----- Status register bits ----------------------------------------- */
|
||||
|
||||
#define ISR_RWM 0x1 /* read/write mode */
|
||||
#define ISR_ACKNAK 0x2 /* ack/nak status */
|
||||
#define ISR_UB 0x4 /* unit busy */
|
||||
#define ISR_IBB 0x8 /* bus busy */
|
||||
#define ISR_SSD 0x10 /* slave stop detected */
|
||||
#define ISR_ALD 0x20 /* arbitration loss detected */
|
||||
#define ISR_ITE 0x40 /* tx buffer empty */
|
||||
#define ISR_IRF 0x80 /* rx buffer full */
|
||||
#define ISR_GCAD 0x100 /* general call address detected */
|
||||
#define ISR_SAD 0x200 /* slave address detected */
|
||||
#define ISR_BED 0x400 /* bus error no ACK/NAK */
|
||||
|
||||
/*
|
||||
* Serial Audio Controller
|
||||
@@ -524,24 +556,92 @@ typedef void (*ExcpHndlr) (void) ;
|
||||
/*
|
||||
* USB Device Controller
|
||||
*/
|
||||
#define UDC_RES1 __REG(0x40600004) /* UDC Undocumented - Reserved1 */
|
||||
#define UDC_RES2 __REG(0x40600008) /* UDC Undocumented - Reserved2 */
|
||||
#define UDC_RES3 __REG(0x4060000C) /* UDC Undocumented - Reserved3 */
|
||||
|
||||
#define UDCCR __REG(0x40600000) /* UDC Control Register */
|
||||
#define UDCCR_UDE (1 << 0) /* UDC enable */
|
||||
#define UDCCR_UDA (1 << 1) /* UDC active */
|
||||
#define UDCCR_RSM (1 << 2) /* Device resume */
|
||||
#define UDCCR_RESIR (1 << 3) /* Resume interrupt request */
|
||||
#define UDCCR_SUSIR (1 << 4) /* Suspend interrupt request */
|
||||
#define UDCCR_SRM (1 << 5) /* Suspend/resume interrupt mask */
|
||||
#define UDCCR_RSTIR (1 << 6) /* Reset interrupt request */
|
||||
#define UDCCR_REM (1 << 7) /* Reset interrupt mask */
|
||||
|
||||
#define UDCCS0 __REG(0x40600010) /* UDC Endpoint 0 Control/Status Register */
|
||||
#define UDCCS0_OPR (1 << 0) /* OUT packet ready */
|
||||
#define UDCCS0_IPR (1 << 1) /* IN packet ready */
|
||||
#define UDCCS0_FTF (1 << 2) /* Flush Tx FIFO */
|
||||
#define UDCCS0_DRWF (1 << 3) /* Device remote wakeup feature */
|
||||
#define UDCCS0_SST (1 << 4) /* Sent stall */
|
||||
#define UDCCS0_FST (1 << 5) /* Force stall */
|
||||
#define UDCCS0_RNE (1 << 6) /* Receive FIFO no empty */
|
||||
#define UDCCS0_SA (1 << 7) /* Setup active */
|
||||
|
||||
/* Bulk IN - Endpoint 1,6,11 */
|
||||
#define UDCCS1 __REG(0x40600014) /* UDC Endpoint 1 (IN) Control/Status Register */
|
||||
#define UDCCS2 __REG(0x40600018) /* UDC Endpoint 2 (OUT) Control/Status Register */
|
||||
#define UDCCS3 __REG(0x4060001C) /* UDC Endpoint 3 (IN) Control/Status Register */
|
||||
#define UDCCS4 __REG(0x40600020) /* UDC Endpoint 4 (OUT) Control/Status Register */
|
||||
#define UDCCS5 __REG(0x40600024) /* UDC Endpoint 5 (Interrupt) Control/Status Register */
|
||||
#define UDCCS6 __REG(0x40600028) /* UDC Endpoint 6 (IN) Control/Status Register */
|
||||
#define UDCCS7 __REG(0x4060002C) /* UDC Endpoint 7 (OUT) Control/Status Register */
|
||||
#define UDCCS8 __REG(0x40600030) /* UDC Endpoint 8 (IN) Control/Status Register */
|
||||
#define UDCCS9 __REG(0x40600034) /* UDC Endpoint 9 (OUT) Control/Status Register */
|
||||
#define UDCCS10 __REG(0x40600038) /* UDC Endpoint 10 (Interrupt) Control/Status Register */
|
||||
#define UDCCS11 __REG(0x4060003C) /* UDC Endpoint 11 (IN) Control/Status Register */
|
||||
|
||||
#define UDCCS_BI_TFS (1 << 0) /* Transmit FIFO service */
|
||||
#define UDCCS_BI_TPC (1 << 1) /* Transmit packet complete */
|
||||
#define UDCCS_BI_FTF (1 << 2) /* Flush Tx FIFO */
|
||||
#define UDCCS_BI_TUR (1 << 3) /* Transmit FIFO underrun */
|
||||
#define UDCCS_BI_SST (1 << 4) /* Sent stall */
|
||||
#define UDCCS_BI_FST (1 << 5) /* Force stall */
|
||||
#define UDCCS_BI_TSP (1 << 7) /* Transmit short packet */
|
||||
|
||||
/* Bulk OUT - Endpoint 2,7,12 */
|
||||
#define UDCCS2 __REG(0x40600018) /* UDC Endpoint 2 (OUT) Control/Status Register */
|
||||
#define UDCCS7 __REG(0x4060002C) /* UDC Endpoint 7 (OUT) Control/Status Register */
|
||||
#define UDCCS12 __REG(0x40600040) /* UDC Endpoint 12 (OUT) Control/Status Register */
|
||||
|
||||
#define UDCCS_BO_RFS (1 << 0) /* Receive FIFO service */
|
||||
#define UDCCS_BO_RPC (1 << 1) /* Receive packet complete */
|
||||
#define UDCCS_BO_DME (1 << 3) /* DMA enable */
|
||||
#define UDCCS_BO_SST (1 << 4) /* Sent stall */
|
||||
#define UDCCS_BO_FST (1 << 5) /* Force stall */
|
||||
#define UDCCS_BO_RNE (1 << 6) /* Receive FIFO not empty */
|
||||
#define UDCCS_BO_RSP (1 << 7) /* Receive short packet */
|
||||
|
||||
/* Isochronous IN - Endpoint 3,8,13 */
|
||||
#define UDCCS3 __REG(0x4060001C) /* UDC Endpoint 3 (IN) Control/Status Register */
|
||||
#define UDCCS8 __REG(0x40600030) /* UDC Endpoint 8 (IN) Control/Status Register */
|
||||
#define UDCCS13 __REG(0x40600044) /* UDC Endpoint 13 (IN) Control/Status Register */
|
||||
|
||||
#define UDCCS_II_TFS (1 << 0) /* Transmit FIFO service */
|
||||
#define UDCCS_II_TPC (1 << 1) /* Transmit packet complete */
|
||||
#define UDCCS_II_FTF (1 << 2) /* Flush Tx FIFO */
|
||||
#define UDCCS_II_TUR (1 << 3) /* Transmit FIFO underrun */
|
||||
#define UDCCS_II_TSP (1 << 7) /* Transmit short packet */
|
||||
|
||||
/* Isochronous OUT - Endpoint 4,9,14 */
|
||||
#define UDCCS4 __REG(0x40600020) /* UDC Endpoint 4 (OUT) Control/Status Register */
|
||||
#define UDCCS9 __REG(0x40600034) /* UDC Endpoint 9 (OUT) Control/Status Register */
|
||||
#define UDCCS14 __REG(0x40600048) /* UDC Endpoint 14 (OUT) Control/Status Register */
|
||||
|
||||
#define UDCCS_IO_RFS (1 << 0) /* Receive FIFO service */
|
||||
#define UDCCS_IO_RPC (1 << 1) /* Receive packet complete */
|
||||
#define UDCCS_IO_ROF (1 << 3) /* Receive overflow */
|
||||
#define UDCCS_IO_DME (1 << 3) /* DMA enable */
|
||||
#define UDCCS_IO_RNE (1 << 6) /* Receive FIFO not empty */
|
||||
#define UDCCS_IO_RSP (1 << 7) /* Receive short packet */
|
||||
|
||||
/* Interrupt IN - Endpoint 5,10,15 */
|
||||
#define UDCCS5 __REG(0x40600024) /* UDC Endpoint 5 (Interrupt) Control/Status Register */
|
||||
#define UDCCS10 __REG(0x40600038) /* UDC Endpoint 10 (Interrupt) Control/Status Register */
|
||||
#define UDCCS15 __REG(0x4060004C) /* UDC Endpoint 15 (Interrupt) Control/Status Register */
|
||||
|
||||
#define UDCCS_INT_TFS (1 << 0) /* Transmit FIFO service */
|
||||
#define UDCCS_INT_TPC (1 << 1) /* Transmit packet complete */
|
||||
#define UDCCS_INT_FTF (1 << 2) /* Flush Tx FIFO */
|
||||
#define UDCCS_INT_TUR (1 << 3) /* Transmit FIFO underrun */
|
||||
#define UDCCS_INT_SST (1 << 4) /* Sent stall */
|
||||
#define UDCCS_INT_FST (1 << 5) /* Force stall */
|
||||
#define UDCCS_INT_TSP (1 << 7) /* Transmit short packet */
|
||||
|
||||
#define UFNRH __REG(0x40600060) /* UDC Frame Number Register High */
|
||||
#define UFNRL __REG(0x40600064) /* UDC Frame Number Register Low */
|
||||
#define UBCR2 __REG(0x40600068) /* UDC Byte Count Reg 2 */
|
||||
@@ -566,11 +666,51 @@ typedef void (*ExcpHndlr) (void) ;
|
||||
#define UDDR13 __REG(0x40600C00) /* UDC Endpoint 13 Data Register */
|
||||
#define UDDR14 __REG(0x40600E00) /* UDC Endpoint 14 Data Register */
|
||||
#define UDDR15 __REG(0x406000E0) /* UDC Endpoint 15 Data Register */
|
||||
|
||||
#define UICR0 __REG(0x40600050) /* UDC Interrupt Control Register 0 */
|
||||
|
||||
#define UICR0_IM0 (1 << 0) /* Interrupt mask ep 0 */
|
||||
#define UICR0_IM1 (1 << 1) /* Interrupt mask ep 1 */
|
||||
#define UICR0_IM2 (1 << 2) /* Interrupt mask ep 2 */
|
||||
#define UICR0_IM3 (1 << 3) /* Interrupt mask ep 3 */
|
||||
#define UICR0_IM4 (1 << 4) /* Interrupt mask ep 4 */
|
||||
#define UICR0_IM5 (1 << 5) /* Interrupt mask ep 5 */
|
||||
#define UICR0_IM6 (1 << 6) /* Interrupt mask ep 6 */
|
||||
#define UICR0_IM7 (1 << 7) /* Interrupt mask ep 7 */
|
||||
|
||||
#define UICR1 __REG(0x40600054) /* UDC Interrupt Control Register 1 */
|
||||
|
||||
#define UICR1_IM8 (1 << 0) /* Interrupt mask ep 8 */
|
||||
#define UICR1_IM9 (1 << 1) /* Interrupt mask ep 9 */
|
||||
#define UICR1_IM10 (1 << 2) /* Interrupt mask ep 10 */
|
||||
#define UICR1_IM11 (1 << 3) /* Interrupt mask ep 11 */
|
||||
#define UICR1_IM12 (1 << 4) /* Interrupt mask ep 12 */
|
||||
#define UICR1_IM13 (1 << 5) /* Interrupt mask ep 13 */
|
||||
#define UICR1_IM14 (1 << 6) /* Interrupt mask ep 14 */
|
||||
#define UICR1_IM15 (1 << 7) /* Interrupt mask ep 15 */
|
||||
|
||||
#define USIR0 __REG(0x40600058) /* UDC Status Interrupt Register 0 */
|
||||
|
||||
#define USIR0_IR0 (1 << 0) /* Interrup request ep 0 */
|
||||
#define USIR0_IR1 (1 << 1) /* Interrup request ep 1 */
|
||||
#define USIR0_IR2 (1 << 2) /* Interrup request ep 2 */
|
||||
#define USIR0_IR3 (1 << 3) /* Interrup request ep 3 */
|
||||
#define USIR0_IR4 (1 << 4) /* Interrup request ep 4 */
|
||||
#define USIR0_IR5 (1 << 5) /* Interrup request ep 5 */
|
||||
#define USIR0_IR6 (1 << 6) /* Interrup request ep 6 */
|
||||
#define USIR0_IR7 (1 << 7) /* Interrup request ep 7 */
|
||||
|
||||
#define USIR1 __REG(0x4060005C) /* UDC Status Interrupt Register 1 */
|
||||
|
||||
#define USIR1_IR8 (1 << 0) /* Interrup request ep 8 */
|
||||
#define USIR1_IR9 (1 << 1) /* Interrup request ep 9 */
|
||||
#define USIR1_IR10 (1 << 2) /* Interrup request ep 10 */
|
||||
#define USIR1_IR11 (1 << 3) /* Interrup request ep 11 */
|
||||
#define USIR1_IR12 (1 << 4) /* Interrup request ep 12 */
|
||||
#define USIR1_IR13 (1 << 5) /* Interrup request ep 13 */
|
||||
#define USIR1_IR14 (1 << 6) /* Interrup request ep 14 */
|
||||
#define USIR1_IR15 (1 << 7) /* Interrup request ep 15 */
|
||||
|
||||
|
||||
/*
|
||||
* Fast Infrared Communication Port
|
||||
@@ -917,6 +1057,22 @@ typedef void (*ExcpHndlr) (void) ;
|
||||
#define PGSR2 __REG(0x40F00028) /* Power Manager GPIO Sleep State Register for GP[84-64] */
|
||||
#define RCSR __REG(0x40F00030) /* Reset Controller Status Register */
|
||||
|
||||
#define PSSR_RDH (1 << 5) /* Read Disable Hold */
|
||||
#define PSSR_PH (1 << 4) /* Peripheral Control Hold */
|
||||
#define PSSR_VFS (1 << 2) /* VDD Fault Status */
|
||||
#define PSSR_BFS (1 << 1) /* Battery Fault Status */
|
||||
#define PSSR_SSS (1 << 0) /* Software Sleep Status */
|
||||
|
||||
#define PCFR_DS (1 << 3) /* Deep Sleep Mode */
|
||||
#define PCFR_FS (1 << 2) /* Float Static Chip Selects */
|
||||
#define PCFR_FP (1 << 1) /* Float PCMCIA controls */
|
||||
#define PCFR_OPDE (1 << 0) /* 3.6864 MHz oscillator power-down enable */
|
||||
|
||||
#define RCSR_GPR (1 << 3) /* GPIO Reset */
|
||||
#define RCSR_SMR (1 << 2) /* Sleep Mode */
|
||||
#define RCSR_WDR (1 << 1) /* Watchdog Reset */
|
||||
#define RCSR_HWR (1 << 0) /* Hardware Reset */
|
||||
|
||||
|
||||
/*
|
||||
* SSP Serial Port Registers
|
||||
@@ -1040,19 +1196,105 @@ typedef void (*ExcpHndlr) (void) ;
|
||||
#define LCCR0_BM (1 << 20) /* Branch mask */
|
||||
#define LCCR0_OUM (1 << 21) /* Output FIFO underrun mask */
|
||||
|
||||
#define LCCR1_PPL Fld (10, 0) /* Pixels Per Line - 1 */
|
||||
#define LCCR1_DisWdth(Pixel) /* Display Width [1..800 pix.] */ \
|
||||
(((Pixel) - 1) << FShft (LCCR1_PPL))
|
||||
|
||||
#define LCCR1_HSW Fld (6, 10) /* Horizontal Synchronization */
|
||||
#define LCCR1_HorSnchWdth(Tpix) /* Horizontal Synchronization */ \
|
||||
/* pulse Width [1..64 Tpix] */ \
|
||||
(((Tpix) - 1) << FShft (LCCR1_HSW))
|
||||
|
||||
#define LCCR1_ELW Fld (8, 16) /* End-of-Line pixel clock Wait */
|
||||
/* count - 1 [Tpix] */
|
||||
#define LCCR1_EndLnDel(Tpix) /* End-of-Line Delay */ \
|
||||
/* [1..256 Tpix] */ \
|
||||
(((Tpix) - 1) << FShft (LCCR1_ELW))
|
||||
|
||||
#define LCCR1_BLW Fld (8, 24) /* Beginning-of-Line pixel clock */
|
||||
/* Wait count - 1 [Tpix] */
|
||||
#define LCCR1_BegLnDel(Tpix) /* Beginning-of-Line Delay */ \
|
||||
/* [1..256 Tpix] */ \
|
||||
(((Tpix) - 1) << FShft (LCCR1_BLW))
|
||||
|
||||
|
||||
#define LCCR2_LPP Fld (10, 0) /* Line Per Panel - 1 */
|
||||
#define LCCR2_DisHght(Line) /* Display Height [1..1024 lines] */ \
|
||||
(((Line) - 1) << FShft (LCCR2_LPP))
|
||||
|
||||
#define LCCR2_VSW Fld (6, 10) /* Vertical Synchronization pulse */
|
||||
/* Width - 1 [Tln] (L_FCLK) */
|
||||
#define LCCR2_VrtSnchWdth(Tln) /* Vertical Synchronization pulse */ \
|
||||
/* Width [1..64 Tln] */ \
|
||||
(((Tln) - 1) << FShft (LCCR2_VSW))
|
||||
|
||||
#define LCCR2_EFW Fld (8, 16) /* End-of-Frame line clock Wait */
|
||||
/* count [Tln] */
|
||||
#define LCCR2_EndFrmDel(Tln) /* End-of-Frame Delay */ \
|
||||
/* [0..255 Tln] */ \
|
||||
((Tln) << FShft (LCCR2_EFW))
|
||||
|
||||
#define LCCR2_BFW Fld (8, 24) /* Beginning-of-Frame line clock */
|
||||
/* Wait count [Tln] */
|
||||
#define LCCR2_BegFrmDel(Tln) /* Beginning-of-Frame Delay */ \
|
||||
/* [0..255 Tln] */ \
|
||||
((Tln) << FShft (LCCR2_BFW))
|
||||
|
||||
#if 0
|
||||
#define LCCR3_PCD (0xff) /* Pixel clock divisor */
|
||||
#define LCCR3_ACB (0xff << 8) /* AC Bias pin frequency */
|
||||
#define LCCR3_ACB_S 8
|
||||
#endif
|
||||
|
||||
#define LCCR3_API (0xf << 16) /* AC Bias pin trasitions per interrupt */
|
||||
#define LCCR3_API_S 16
|
||||
#define LCCR3_VSP (1 << 20) /* vertical sync polarity */
|
||||
#define LCCR3_HSP (1 << 21) /* horizontal sync polarity */
|
||||
#define LCCR3_PCP (1 << 22) /* pixel clock polarity */
|
||||
#define LCCR3_OEP (1 << 23) /* output enable polarity */
|
||||
#if 0
|
||||
#define LCCR3_BPP (7 << 24) /* bits per pixel */
|
||||
#define LCCR3_BPP_S 24
|
||||
#endif
|
||||
#define LCCR3_DPC (1 << 27) /* double pixel clock mode */
|
||||
|
||||
|
||||
#define LCCR3_PCD Fld (8, 0) /* Pixel Clock Divisor */
|
||||
#define LCCR3_PixClkDiv(Div) /* Pixel Clock Divisor */ \
|
||||
(((Div) << FShft (LCCR3_PCD)))
|
||||
|
||||
|
||||
#define LCCR3_BPP Fld (3, 24) /* Bit Per Pixel */
|
||||
#define LCCR3_Bpp(Bpp) /* Bit Per Pixel */ \
|
||||
(((Bpp) << FShft (LCCR3_BPP)))
|
||||
|
||||
#define LCCR3_ACB Fld (8, 8) /* AC Bias */
|
||||
#define LCCR3_Acb(Acb) /* BAC Bias */ \
|
||||
(((Acb) << FShft (LCCR3_ACB)))
|
||||
|
||||
#define LCCR3_HorSnchH (LCCR3_HSP*0) /* Horizontal Synchronization */
|
||||
/* pulse active High */
|
||||
#define LCCR3_HorSnchL (LCCR3_HSP*1) /* Horizontal Synchronization */
|
||||
|
||||
#define LCCR3_VrtSnchH (LCCR3_VSP*0) /* Vertical Synchronization pulse */
|
||||
/* active High */
|
||||
#define LCCR3_VrtSnchL (LCCR3_VSP*1) /* Vertical Synchronization pulse */
|
||||
/* active Low */
|
||||
|
||||
#define LCSR_LDD (1 << 0) /* LCD Disable Done */
|
||||
#define LCSR_SOF (1 << 1) /* Start of frame */
|
||||
#define LCSR_BER (1 << 2) /* Bus error */
|
||||
#define LCSR_ABC (1 << 3) /* AC Bias count */
|
||||
#define LCSR_IUL (1 << 4) /* input FIFO underrun Lower panel */
|
||||
#define LCSR_IUU (1 << 5) /* input FIFO underrun Upper panel */
|
||||
#define LCSR_OU (1 << 6) /* output FIFO underrun */
|
||||
#define LCSR_QD (1 << 7) /* quick disable */
|
||||
#define LCSR_EOF (1 << 8) /* end of frame */
|
||||
#define LCSR_BS (1 << 9) /* branch status */
|
||||
#define LCSR_SINT (1 << 10) /* subsequent interrupt */
|
||||
|
||||
#define LDCMD_PAL (1 << 26) /* instructs DMA to load palette buffer */
|
||||
|
||||
#define LCSR_LDD (1 << 0) /* LCD Disable Done */
|
||||
#define LCSR_SOF (1 << 1) /* Start of frame */
|
||||
#define LCSR_BER (1 << 2) /* Bus error */
|
||||
@@ -1071,45 +1313,7 @@ typedef void (*ExcpHndlr) (void) ;
|
||||
* Memory controller
|
||||
*/
|
||||
|
||||
#define MEMC_BASE __REG(0x48000000) /* Base of Memoriy Controller */
|
||||
#define MDCNFG __REG(0x48000000) /* SDRAM Configuration Register 0 */
|
||||
#define MDREFR __REG(0x48000004) /* SDRAM Refresh Control Register */
|
||||
#define MSC0 __REG(0x48000008) /* Static Memory Control Register 0 */
|
||||
#define MSC1 __REG(0x4800000C) /* Static Memory Control Register 1 */
|
||||
#define MSC2 __REG(0x48000010) /* Static Memory Control Register 2 */
|
||||
#define MECR __REG(0x48000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */
|
||||
#define SXLCR __REG(0x48000018) /* LCR value to be written to SDRAM-Timing Synchronous Flash */
|
||||
#define SXCNFG __REG(0x4800001C) /* Synchronous Static Memory Control Register */
|
||||
#define SXMRS __REG(0x48000024) /* MRS value to be written to Synchronous Flash or SMROM */
|
||||
#define MCMEM0 __REG(0x48000028) /* Card interface Common Memory Space Socket 0 Timing */
|
||||
#define MCMEM1 __REG(0x4800002C) /* Card interface Common Memory Space Socket 1 Timing */
|
||||
#define MCATT0 __REG(0x48000030) /* Card interface Attribute Space Socket 0 Timing Configuration */
|
||||
#define MCATT1 __REG(0x48000034) /* Card interface Attribute Space Socket 1 Timing Configuration */
|
||||
#define MCIO0 __REG(0x48000038) /* Card interface I/O Space Socket 0 Timing Configuration */
|
||||
#define MCIO1 __REG(0x4800003C) /* Card interface I/O Space Socket 1 Timing Configuration */
|
||||
#define MDMRS __REG(0x48000040) /* MRS value to be written to SDRAM */
|
||||
#define BOOT_DEF __REG(0x48000044) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */
|
||||
|
||||
#define MDCNFG_DE0 0x00000001
|
||||
#define MDCNFG_DE1 0x00000002
|
||||
#define MDCNFG_DE2 0x00010000
|
||||
#define MDCNFG_DE3 0x00020000
|
||||
#define MDCNFG_DWID0 0x00000004
|
||||
|
||||
#define MDREFR_E0PIN 0x00001000
|
||||
#define MDREFR_K0RUN 0x00002000
|
||||
#define MDREFR_K0DB2 0x00004000
|
||||
#define MDREFR_E1PIN 0x00008000
|
||||
#define MDREFR_K1RUN 0x00010000
|
||||
#define MDREFR_K1DB2 0x00020000
|
||||
#define MDREFR_K2RUN 0x00040000
|
||||
#define MDREFR_K2DB2 0x00080000
|
||||
#define MDREFR_APD 0x00100000
|
||||
#define MDREFR_SLFRSH 0x00400000
|
||||
#define MDREFR_K0FREE 0x00800000
|
||||
#define MDREFR_K1FREE 0x01000000
|
||||
#define MDREFR_K2FREE 0x02000000
|
||||
|
||||
#define MEMC_BASE __REG(0x48000000) /* Base of Memory Controller */
|
||||
#define MDCNFG_OFFSET 0x0
|
||||
#define MDREFR_OFFSET 0x4
|
||||
#define MSC0_OFFSET 0x8
|
||||
@@ -1127,7 +1331,44 @@ typedef void (*ExcpHndlr) (void) ;
|
||||
#define MCIO0_OFFSET 0x38
|
||||
#define MCIO1_OFFSET 0x3C
|
||||
#define MDMRS_OFFSET 0x40
|
||||
|
||||
#define MDCNFG __REG(0x48000000) /* SDRAM Configuration Register 0 */
|
||||
#define MDCNFG_DE0 0x00000001
|
||||
#define MDCNFG_DE1 0x00000002
|
||||
#define MDCNFG_DE2 0x00010000
|
||||
#define MDCNFG_DE3 0x00020000
|
||||
#define MDCNFG_DWID0 0x00000004
|
||||
|
||||
#define MDREFR __REG(0x48000004) /* SDRAM Refresh Control Register */
|
||||
#define MSC0 __REG(0x48000008) /* Static Memory Control Register 0 */
|
||||
#define MSC1 __REG(0x4800000C) /* Static Memory Control Register 1 */
|
||||
#define MSC2 __REG(0x48000010) /* Static Memory Control Register 2 */
|
||||
#define MECR __REG(0x48000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */
|
||||
#define SXLCR __REG(0x48000018) /* LCR value to be written to SDRAM-Timing Synchronous Flash */
|
||||
#define SXCNFG __REG(0x4800001C) /* Synchronous Static Memory Control Register */
|
||||
#define SXMRS __REG(0x48000024) /* MRS value to be written to Synchronous Flash or SMROM */
|
||||
#define MCMEM0 __REG(0x48000028) /* Card interface Common Memory Space Socket 0 Timing */
|
||||
#define MCMEM1 __REG(0x4800002C) /* Card interface Common Memory Space Socket 1 Timing */
|
||||
#define MCATT0 __REG(0x48000030) /* Card interface Attribute Space Socket 0 Timing Configuration */
|
||||
#define MCATT1 __REG(0x48000034) /* Card interface Attribute Space Socket 1 Timing Configuration */
|
||||
#define MCIO0 __REG(0x48000038) /* Card interface I/O Space Socket 0 Timing Configuration */
|
||||
#define MCIO1 __REG(0x4800003C) /* Card interface I/O Space Socket 1 Timing Configuration */
|
||||
#define MDMRS __REG(0x48000040) /* MRS value to be written to SDRAM */
|
||||
#define BOOT_DEF __REG(0x48000044) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */
|
||||
|
||||
#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */
|
||||
#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */
|
||||
#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */
|
||||
#define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */
|
||||
#define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */
|
||||
#define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */
|
||||
#define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */
|
||||
#define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */
|
||||
#define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */
|
||||
#define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */
|
||||
#define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */
|
||||
#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */
|
||||
#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -43,6 +43,8 @@ typedef struct global_data {
|
||||
unsigned long env_valid; /* Checksum of Environment valid? */
|
||||
#ifdef CONFIG_VFD
|
||||
unsigned long fb_base; /* base address of frame buffer */
|
||||
unsigned char vfd_type; /* display type */
|
||||
unsigned char vfd_inv_data; /* inverted data lines ? */
|
||||
#endif
|
||||
#if 0
|
||||
unsigned long cpu_clk; /* CPU clock in Hz! */
|
||||
|
||||
@@ -61,6 +61,8 @@ struct pt_regs {
|
||||
#define ARM_r0 uregs[0]
|
||||
#define ARM_ORIG_r0 uregs[17]
|
||||
|
||||
#define instruction_pointer(regs) ((regs)->ARM_ip)
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#define user_mode(regs) \
|
||||
|
||||
70
include/asm-mips/addrspace.h
Normal file
70
include/asm-mips/addrspace.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 1996 by Ralf Baechle
|
||||
* Copyright (C) 2000 by Maciej W. Rozycki
|
||||
*
|
||||
* Defitions for the address spaces of the MIPS CPUs.
|
||||
*/
|
||||
#ifndef __ASM_MIPS_ADDRSPACE_H
|
||||
#define __ASM_MIPS_ADDRSPACE_H
|
||||
|
||||
/*
|
||||
* Memory segments (32bit kernel mode addresses)
|
||||
*/
|
||||
#define KUSEG 0x00000000
|
||||
#define KSEG0 0x80000000
|
||||
#define KSEG1 0xa0000000
|
||||
#define KSEG2 0xc0000000
|
||||
#define KSEG3 0xe0000000
|
||||
|
||||
#define K0BASE KSEG0
|
||||
|
||||
/*
|
||||
* Returns the kernel segment base of a given address
|
||||
*/
|
||||
#ifndef __ASSEMBLY__
|
||||
#define KSEGX(a) (((unsigned long)(a)) & 0xe0000000)
|
||||
#else
|
||||
#define KSEGX(a) ((a) & 0xe0000000)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Returns the physical address of a KSEG0/KSEG1 address
|
||||
*/
|
||||
#ifndef __ASSEMBLY__
|
||||
#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff)
|
||||
#else
|
||||
#define PHYSADDR(a) ((a) & 0x1fffffff)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Map an address to a certain kernel segment
|
||||
*/
|
||||
#ifndef __ASSEMBLY__
|
||||
#define KSEG0ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG0))
|
||||
#define KSEG1ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG1))
|
||||
#define KSEG2ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG2))
|
||||
#define KSEG3ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG3))
|
||||
#else
|
||||
#define KSEG0ADDR(a) (((a) & 0x1fffffff) | KSEG0)
|
||||
#define KSEG1ADDR(a) (((a) & 0x1fffffff) | KSEG1)
|
||||
#define KSEG2ADDR(a) (((a) & 0x1fffffff) | KSEG2)
|
||||
#define KSEG3ADDR(a) (((a) & 0x1fffffff) | KSEG3)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Memory segments (64bit kernel mode addresses)
|
||||
*/
|
||||
#define XKUSEG 0x0000000000000000
|
||||
#define XKSSEG 0x4000000000000000
|
||||
#define XKPHYS 0x8000000000000000
|
||||
#define XKSEG 0xc000000000000000
|
||||
#define CKSEG0 0xffffffff80000000
|
||||
#define CKSEG1 0xffffffffa0000000
|
||||
#define CKSSEG 0xffffffffc0000000
|
||||
#define CKSEG3 0xffffffffe0000000
|
||||
|
||||
#endif /* __ASM_MIPS_ADDRSPACE_H */
|
||||
912
include/asm-mips/bitops.h
Normal file
912
include/asm-mips/bitops.h
Normal file
@@ -0,0 +1,912 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (c) 1994 - 1997, 1999, 2000 Ralf Baechle (ralf@gnu.org)
|
||||
* Copyright (c) 2000 Silicon Graphics, Inc.
|
||||
*/
|
||||
#ifndef _ASM_BITOPS_H
|
||||
#define _ASM_BITOPS_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/byteorder.h> /* sigh ... */
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <asm/sgidefs.h>
|
||||
#include <asm/system.h>
|
||||
#include <linux/config.h>
|
||||
|
||||
/*
|
||||
* clear_bit() doesn't provide any barrier for the compiler.
|
||||
*/
|
||||
#define smp_mb__before_clear_bit() barrier()
|
||||
#define smp_mb__after_clear_bit() barrier()
|
||||
|
||||
/*
|
||||
* Only disable interrupt for kernel mode stuff to keep usermode stuff
|
||||
* that dares to use kernel include files alive.
|
||||
*/
|
||||
#define __bi_flags unsigned long flags
|
||||
#define __bi_cli() __cli()
|
||||
#define __bi_save_flags(x) __save_flags(x)
|
||||
#define __bi_save_and_cli(x) __save_and_cli(x)
|
||||
#define __bi_restore_flags(x) __restore_flags(x)
|
||||
#else
|
||||
#define __bi_flags
|
||||
#define __bi_cli()
|
||||
#define __bi_save_flags(x)
|
||||
#define __bi_save_and_cli(x)
|
||||
#define __bi_restore_flags(x)
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LLSC
|
||||
|
||||
#include <asm/mipsregs.h>
|
||||
|
||||
/*
|
||||
* These functions for MIPS ISA > 1 are interrupt and SMP proof and
|
||||
* interrupt friendly
|
||||
*/
|
||||
|
||||
/*
|
||||
* set_bit - Atomically set a bit in memory
|
||||
* @nr: the bit to set
|
||||
* @addr: the address to start counting from
|
||||
*
|
||||
* This function is atomic and may not be reordered. See __set_bit()
|
||||
* if you do not require the atomic guarantees.
|
||||
* Note that @nr may be almost arbitrarily large; this function is not
|
||||
* restricted to acting on a single-word quantity.
|
||||
*/
|
||||
extern __inline__ void
|
||||
set_bit(int nr, volatile void *addr)
|
||||
{
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
|
||||
unsigned long temp;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1:\tll\t%0, %1\t\t# set_bit\n\t"
|
||||
"or\t%0, %2\n\t"
|
||||
"sc\t%0, %1\n\t"
|
||||
"beqz\t%0, 1b"
|
||||
: "=&r" (temp), "=m" (*m)
|
||||
: "ir" (1UL << (nr & 0x1f)), "m" (*m));
|
||||
}
|
||||
|
||||
/*
|
||||
* __set_bit - Set a bit in memory
|
||||
* @nr: the bit to set
|
||||
* @addr: the address to start counting from
|
||||
*
|
||||
* Unlike set_bit(), this function is non-atomic and may be reordered.
|
||||
* If it's called on the same region of memory simultaneously, the effect
|
||||
* may be that only one operation succeeds.
|
||||
*/
|
||||
extern __inline__ void __set_bit(int nr, volatile void * addr)
|
||||
{
|
||||
unsigned long * m = ((unsigned long *) addr) + (nr >> 5);
|
||||
|
||||
*m |= 1UL << (nr & 31);
|
||||
}
|
||||
|
||||
/*
|
||||
* clear_bit - Clears a bit in memory
|
||||
* @nr: Bit to clear
|
||||
* @addr: Address to start counting from
|
||||
*
|
||||
* clear_bit() is atomic and may not be reordered. However, it does
|
||||
* not contain a memory barrier, so if it is used for locking purposes,
|
||||
* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
|
||||
* in order to ensure changes are visible on other processors.
|
||||
*/
|
||||
extern __inline__ void
|
||||
clear_bit(int nr, volatile void *addr)
|
||||
{
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
|
||||
unsigned long temp;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1:\tll\t%0, %1\t\t# clear_bit\n\t"
|
||||
"and\t%0, %2\n\t"
|
||||
"sc\t%0, %1\n\t"
|
||||
"beqz\t%0, 1b\n\t"
|
||||
: "=&r" (temp), "=m" (*m)
|
||||
: "ir" (~(1UL << (nr & 0x1f))), "m" (*m));
|
||||
}
|
||||
|
||||
/*
|
||||
* change_bit - Toggle a bit in memory
|
||||
* @nr: Bit to clear
|
||||
* @addr: Address to start counting from
|
||||
*
|
||||
* change_bit() is atomic and may not be reordered.
|
||||
* Note that @nr may be almost arbitrarily large; this function is not
|
||||
* restricted to acting on a single-word quantity.
|
||||
*/
|
||||
extern __inline__ void
|
||||
change_bit(int nr, volatile void *addr)
|
||||
{
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
|
||||
unsigned long temp;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1:\tll\t%0, %1\t\t# change_bit\n\t"
|
||||
"xor\t%0, %2\n\t"
|
||||
"sc\t%0, %1\n\t"
|
||||
"beqz\t%0, 1b"
|
||||
: "=&r" (temp), "=m" (*m)
|
||||
: "ir" (1UL << (nr & 0x1f)), "m" (*m));
|
||||
}
|
||||
|
||||
/*
|
||||
* __change_bit - Toggle a bit in memory
|
||||
* @nr: the bit to set
|
||||
* @addr: the address to start counting from
|
||||
*
|
||||
* Unlike change_bit(), this function is non-atomic and may be reordered.
|
||||
* If it's called on the same region of memory simultaneously, the effect
|
||||
* may be that only one operation succeeds.
|
||||
*/
|
||||
extern __inline__ void __change_bit(int nr, volatile void * addr)
|
||||
{
|
||||
unsigned long * m = ((unsigned long *) addr) + (nr >> 5);
|
||||
|
||||
*m ^= 1UL << (nr & 31);
|
||||
}
|
||||
|
||||
/*
|
||||
* test_and_set_bit - Set a bit and return its old value
|
||||
* @nr: Bit to set
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is atomic and cannot be reordered.
|
||||
* It also implies a memory barrier.
|
||||
*/
|
||||
extern __inline__ int
|
||||
test_and_set_bit(int nr, volatile void *addr)
|
||||
{
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
|
||||
unsigned long temp, res;
|
||||
|
||||
__asm__ __volatile__(
|
||||
".set\tnoreorder\t\t# test_and_set_bit\n"
|
||||
"1:\tll\t%0, %1\n\t"
|
||||
"or\t%2, %0, %3\n\t"
|
||||
"sc\t%2, %1\n\t"
|
||||
"beqz\t%2, 1b\n\t"
|
||||
" and\t%2, %0, %3\n\t"
|
||||
".set\treorder"
|
||||
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
||||
: "r" (1UL << (nr & 0x1f)), "m" (*m)
|
||||
: "memory");
|
||||
|
||||
return res != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* __test_and_set_bit - Set a bit and return its old value
|
||||
* @nr: Bit to set
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is non-atomic and can be reordered.
|
||||
* If two examples of this operation race, one can appear to succeed
|
||||
* but actually fail. You must protect multiple accesses with a lock.
|
||||
*/
|
||||
extern __inline__ int __test_and_set_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int mask, retval;
|
||||
volatile int *a = addr;
|
||||
|
||||
a += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
retval = (mask & *a) != 0;
|
||||
*a |= mask;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* test_and_clear_bit - Clear a bit and return its old value
|
||||
* @nr: Bit to set
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is atomic and cannot be reordered.
|
||||
* It also implies a memory barrier.
|
||||
*/
|
||||
extern __inline__ int
|
||||
test_and_clear_bit(int nr, volatile void *addr)
|
||||
{
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
|
||||
unsigned long temp, res;
|
||||
|
||||
__asm__ __volatile__(
|
||||
".set\tnoreorder\t\t# test_and_clear_bit\n"
|
||||
"1:\tll\t%0, %1\n\t"
|
||||
"or\t%2, %0, %3\n\t"
|
||||
"xor\t%2, %3\n\t"
|
||||
"sc\t%2, %1\n\t"
|
||||
"beqz\t%2, 1b\n\t"
|
||||
" and\t%2, %0, %3\n\t"
|
||||
".set\treorder"
|
||||
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
||||
: "r" (1UL << (nr & 0x1f)), "m" (*m)
|
||||
: "memory");
|
||||
|
||||
return res != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* __test_and_clear_bit - Clear a bit and return its old value
|
||||
* @nr: Bit to set
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is non-atomic and can be reordered.
|
||||
* If two examples of this operation race, one can appear to succeed
|
||||
* but actually fail. You must protect multiple accesses with a lock.
|
||||
*/
|
||||
extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int mask, retval;
|
||||
volatile int *a = addr;
|
||||
|
||||
a += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
retval = (mask & *a) != 0;
|
||||
*a &= ~mask;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* test_and_change_bit - Change a bit and return its new value
|
||||
* @nr: Bit to set
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is atomic and cannot be reordered.
|
||||
* It also implies a memory barrier.
|
||||
*/
|
||||
extern __inline__ int
|
||||
test_and_change_bit(int nr, volatile void *addr)
|
||||
{
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
|
||||
unsigned long temp, res;
|
||||
|
||||
__asm__ __volatile__(
|
||||
".set\tnoreorder\t\t# test_and_change_bit\n"
|
||||
"1:\tll\t%0, %1\n\t"
|
||||
"xor\t%2, %0, %3\n\t"
|
||||
"sc\t%2, %1\n\t"
|
||||
"beqz\t%2, 1b\n\t"
|
||||
" and\t%2, %0, %3\n\t"
|
||||
".set\treorder"
|
||||
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
||||
: "r" (1UL << (nr & 0x1f)), "m" (*m)
|
||||
: "memory");
|
||||
|
||||
return res != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* __test_and_change_bit - Change a bit and return its old value
|
||||
* @nr: Bit to set
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is non-atomic and can be reordered.
|
||||
* If two examples of this operation race, one can appear to succeed
|
||||
* but actually fail. You must protect multiple accesses with a lock.
|
||||
*/
|
||||
extern __inline__ int __test_and_change_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int mask, retval;
|
||||
volatile int *a = addr;
|
||||
|
||||
a += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
retval = (mask & *a) != 0;
|
||||
*a ^= mask;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#else /* MIPS I */
|
||||
|
||||
/*
|
||||
* set_bit - Atomically set a bit in memory
|
||||
* @nr: the bit to set
|
||||
* @addr: the address to start counting from
|
||||
*
|
||||
* This function is atomic and may not be reordered. See __set_bit()
|
||||
* if you do not require the atomic guarantees.
|
||||
* Note that @nr may be almost arbitrarily large; this function is not
|
||||
* restricted to acting on a single-word quantity.
|
||||
*/
|
||||
extern __inline__ void set_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int mask;
|
||||
volatile int *a = addr;
|
||||
__bi_flags;
|
||||
|
||||
a += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
__bi_save_and_cli(flags);
|
||||
*a |= mask;
|
||||
__bi_restore_flags(flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* __set_bit - Set a bit in memory
|
||||
* @nr: the bit to set
|
||||
* @addr: the address to start counting from
|
||||
*
|
||||
* Unlike set_bit(), this function is non-atomic and may be reordered.
|
||||
* If it's called on the same region of memory simultaneously, the effect
|
||||
* may be that only one operation succeeds.
|
||||
*/
|
||||
extern __inline__ void __set_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int mask;
|
||||
volatile int *a = addr;
|
||||
|
||||
a += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
*a |= mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* clear_bit - Clears a bit in memory
|
||||
* @nr: Bit to clear
|
||||
* @addr: Address to start counting from
|
||||
*
|
||||
* clear_bit() is atomic and may not be reordered. However, it does
|
||||
* not contain a memory barrier, so if it is used for locking purposes,
|
||||
* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
|
||||
* in order to ensure changes are visible on other processors.
|
||||
*/
|
||||
extern __inline__ void clear_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int mask;
|
||||
volatile int *a = addr;
|
||||
__bi_flags;
|
||||
|
||||
a += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
__bi_save_and_cli(flags);
|
||||
*a &= ~mask;
|
||||
__bi_restore_flags(flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* change_bit - Toggle a bit in memory
|
||||
* @nr: Bit to clear
|
||||
* @addr: Address to start counting from
|
||||
*
|
||||
* change_bit() is atomic and may not be reordered.
|
||||
* Note that @nr may be almost arbitrarily large; this function is not
|
||||
* restricted to acting on a single-word quantity.
|
||||
*/
|
||||
extern __inline__ void change_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int mask;
|
||||
volatile int *a = addr;
|
||||
__bi_flags;
|
||||
|
||||
a += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
__bi_save_and_cli(flags);
|
||||
*a ^= mask;
|
||||
__bi_restore_flags(flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* __change_bit - Toggle a bit in memory
|
||||
* @nr: the bit to set
|
||||
* @addr: the address to start counting from
|
||||
*
|
||||
* Unlike change_bit(), this function is non-atomic and may be reordered.
|
||||
* If it's called on the same region of memory simultaneously, the effect
|
||||
* may be that only one operation succeeds.
|
||||
*/
|
||||
extern __inline__ void __change_bit(int nr, volatile void * addr)
|
||||
{
|
||||
unsigned long * m = ((unsigned long *) addr) + (nr >> 5);
|
||||
|
||||
*m ^= 1UL << (nr & 31);
|
||||
}
|
||||
|
||||
/*
|
||||
* test_and_set_bit - Set a bit and return its old value
|
||||
* @nr: Bit to set
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is atomic and cannot be reordered.
|
||||
* It also implies a memory barrier.
|
||||
*/
|
||||
extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int mask, retval;
|
||||
volatile int *a = addr;
|
||||
__bi_flags;
|
||||
|
||||
a += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
__bi_save_and_cli(flags);
|
||||
retval = (mask & *a) != 0;
|
||||
*a |= mask;
|
||||
__bi_restore_flags(flags);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* __test_and_set_bit - Set a bit and return its old value
|
||||
* @nr: Bit to set
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is non-atomic and can be reordered.
|
||||
* If two examples of this operation race, one can appear to succeed
|
||||
* but actually fail. You must protect multiple accesses with a lock.
|
||||
*/
|
||||
extern __inline__ int __test_and_set_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int mask, retval;
|
||||
volatile int *a = addr;
|
||||
|
||||
a += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
retval = (mask & *a) != 0;
|
||||
*a |= mask;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* test_and_clear_bit - Clear a bit and return its old value
|
||||
* @nr: Bit to set
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is atomic and cannot be reordered.
|
||||
* It also implies a memory barrier.
|
||||
*/
|
||||
extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int mask, retval;
|
||||
volatile int *a = addr;
|
||||
__bi_flags;
|
||||
|
||||
a += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
__bi_save_and_cli(flags);
|
||||
retval = (mask & *a) != 0;
|
||||
*a &= ~mask;
|
||||
__bi_restore_flags(flags);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* __test_and_clear_bit - Clear a bit and return its old value
|
||||
* @nr: Bit to set
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is non-atomic and can be reordered.
|
||||
* If two examples of this operation race, one can appear to succeed
|
||||
* but actually fail. You must protect multiple accesses with a lock.
|
||||
*/
|
||||
extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int mask, retval;
|
||||
volatile int *a = addr;
|
||||
|
||||
a += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
retval = (mask & *a) != 0;
|
||||
*a &= ~mask;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* test_and_change_bit - Change a bit and return its new value
|
||||
* @nr: Bit to set
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is atomic and cannot be reordered.
|
||||
* It also implies a memory barrier.
|
||||
*/
|
||||
extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int mask, retval;
|
||||
volatile int *a = addr;
|
||||
__bi_flags;
|
||||
|
||||
a += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
__bi_save_and_cli(flags);
|
||||
retval = (mask & *a) != 0;
|
||||
*a ^= mask;
|
||||
__bi_restore_flags(flags);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* __test_and_change_bit - Change a bit and return its old value
|
||||
* @nr: Bit to set
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is non-atomic and can be reordered.
|
||||
* If two examples of this operation race, one can appear to succeed
|
||||
* but actually fail. You must protect multiple accesses with a lock.
|
||||
*/
|
||||
extern __inline__ int __test_and_change_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int mask, retval;
|
||||
volatile int *a = addr;
|
||||
|
||||
a += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
retval = (mask & *a) != 0;
|
||||
*a ^= mask;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#undef __bi_flags
|
||||
#undef __bi_cli
|
||||
#undef __bi_save_flags
|
||||
#undef __bi_restore_flags
|
||||
|
||||
#endif /* MIPS I */
|
||||
|
||||
/*
|
||||
* test_bit - Determine whether a bit is set
|
||||
* @nr: bit number to test
|
||||
* @addr: Address to start counting from
|
||||
*/
|
||||
extern __inline__ int test_bit(int nr, volatile void *addr)
|
||||
{
|
||||
return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0;
|
||||
}
|
||||
|
||||
#ifndef __MIPSEB__
|
||||
|
||||
/* Little endian versions. */
|
||||
|
||||
/*
|
||||
* find_first_zero_bit - find the first zero bit in a memory region
|
||||
* @addr: The address to start the search at
|
||||
* @size: The maximum size to search
|
||||
*
|
||||
* Returns the bit-number of the first zero bit, not the number of the byte
|
||||
* containing a bit.
|
||||
*/
|
||||
extern __inline__ int find_first_zero_bit (void *addr, unsigned size)
|
||||
{
|
||||
unsigned long dummy;
|
||||
int res;
|
||||
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
__asm__ (".set\tnoreorder\n\t"
|
||||
".set\tnoat\n"
|
||||
"1:\tsubu\t$1,%6,%0\n\t"
|
||||
"blez\t$1,2f\n\t"
|
||||
"lw\t$1,(%5)\n\t"
|
||||
"addiu\t%5,4\n\t"
|
||||
#if (_MIPS_ISA == _MIPS_ISA_MIPS2 ) || (_MIPS_ISA == _MIPS_ISA_MIPS3 ) || \
|
||||
(_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5 ) || \
|
||||
(_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
|
||||
"beql\t%1,$1,1b\n\t"
|
||||
"addiu\t%0,32\n\t"
|
||||
#else
|
||||
"addiu\t%0,32\n\t"
|
||||
"beq\t%1,$1,1b\n\t"
|
||||
"nop\n\t"
|
||||
"subu\t%0,32\n\t"
|
||||
#endif
|
||||
#ifdef __MIPSEB__
|
||||
#error "Fix this for big endian"
|
||||
#endif /* __MIPSEB__ */
|
||||
"li\t%1,1\n"
|
||||
"1:\tand\t%2,$1,%1\n\t"
|
||||
"beqz\t%2,2f\n\t"
|
||||
"sll\t%1,%1,1\n\t"
|
||||
"bnez\t%1,1b\n\t"
|
||||
"add\t%0,%0,1\n\t"
|
||||
".set\tat\n\t"
|
||||
".set\treorder\n"
|
||||
"2:"
|
||||
: "=r" (res), "=r" (dummy), "=r" (addr)
|
||||
: "0" ((signed int) 0), "1" ((unsigned int) 0xffffffff),
|
||||
"2" (addr), "r" (size)
|
||||
: "$1");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* find_next_zero_bit - find the first zero bit in a memory region
|
||||
* @addr: The address to base the search on
|
||||
* @offset: The bitnumber to start searching at
|
||||
* @size: The maximum size to search
|
||||
*/
|
||||
extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
|
||||
{
|
||||
unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
|
||||
int set = 0, bit = offset & 31, res;
|
||||
unsigned long dummy;
|
||||
|
||||
if (bit) {
|
||||
/*
|
||||
* Look for zero in first byte
|
||||
*/
|
||||
#ifdef __MIPSEB__
|
||||
#error "Fix this for big endian byte order"
|
||||
#endif
|
||||
__asm__(".set\tnoreorder\n\t"
|
||||
".set\tnoat\n"
|
||||
"1:\tand\t$1,%4,%1\n\t"
|
||||
"beqz\t$1,1f\n\t"
|
||||
"sll\t%1,%1,1\n\t"
|
||||
"bnez\t%1,1b\n\t"
|
||||
"addiu\t%0,1\n\t"
|
||||
".set\tat\n\t"
|
||||
".set\treorder\n"
|
||||
"1:"
|
||||
: "=r" (set), "=r" (dummy)
|
||||
: "0" (0), "1" (1 << bit), "r" (*p)
|
||||
: "$1");
|
||||
if (set < (32 - bit))
|
||||
return set + offset;
|
||||
set = 32 - bit;
|
||||
p++;
|
||||
}
|
||||
/*
|
||||
* No zero yet, search remaining full bytes for a zero
|
||||
*/
|
||||
res = find_first_zero_bit(p, size - 32 * (p - (unsigned int *) addr));
|
||||
return offset + set + res;
|
||||
}
|
||||
|
||||
#endif /* !(__MIPSEB__) */
|
||||
|
||||
/*
|
||||
* ffz - find first zero in word.
|
||||
* @word: The word to search
|
||||
*
|
||||
* Undefined if no zero exists, so code should check against ~0UL first.
|
||||
*/
|
||||
extern __inline__ unsigned long ffz(unsigned long word)
|
||||
{
|
||||
unsigned int __res;
|
||||
unsigned int mask = 1;
|
||||
|
||||
__asm__ (
|
||||
".set\tnoreorder\n\t"
|
||||
".set\tnoat\n\t"
|
||||
"move\t%0,$0\n"
|
||||
"1:\tand\t$1,%2,%1\n\t"
|
||||
"beqz\t$1,2f\n\t"
|
||||
"sll\t%1,1\n\t"
|
||||
"bnez\t%1,1b\n\t"
|
||||
"addiu\t%0,1\n\t"
|
||||
".set\tat\n\t"
|
||||
".set\treorder\n"
|
||||
"2:\n\t"
|
||||
: "=&r" (__res), "=r" (mask)
|
||||
: "r" (word), "1" (mask)
|
||||
: "$1");
|
||||
|
||||
return __res;
|
||||
}
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/**
|
||||
* ffs - find first bit set
|
||||
* @x: the word to search
|
||||
*
|
||||
* This is defined the same way as
|
||||
* the libc and compiler builtin ffs routines, therefore
|
||||
* differs in spirit from the above ffz (man ffs).
|
||||
*/
|
||||
|
||||
#define ffs(x) generic_ffs(x)
|
||||
|
||||
/*
|
||||
* hweightN - returns the hamming weight of a N-bit word
|
||||
* @x: the word to weigh
|
||||
*
|
||||
* The Hamming Weight of a number is the total number of bits set in it.
|
||||
*/
|
||||
|
||||
#define hweight32(x) generic_hweight32(x)
|
||||
#define hweight16(x) generic_hweight16(x)
|
||||
#define hweight8(x) generic_hweight8(x)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#ifdef __MIPSEB__
|
||||
/*
|
||||
* find_next_zero_bit - find the first zero bit in a memory region
|
||||
* @addr: The address to base the search on
|
||||
* @offset: The bitnumber to start searching at
|
||||
* @size: The maximum size to search
|
||||
*/
|
||||
extern __inline__ int find_next_zero_bit(void *addr, int size, int offset)
|
||||
{
|
||||
unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
|
||||
unsigned long result = offset & ~31UL;
|
||||
unsigned long tmp;
|
||||
|
||||
if (offset >= size)
|
||||
return size;
|
||||
size -= result;
|
||||
offset &= 31UL;
|
||||
if (offset) {
|
||||
tmp = *(p++);
|
||||
tmp |= ~0UL >> (32-offset);
|
||||
if (size < 32)
|
||||
goto found_first;
|
||||
if (~tmp)
|
||||
goto found_middle;
|
||||
size -= 32;
|
||||
result += 32;
|
||||
}
|
||||
while (size & ~31UL) {
|
||||
if (~(tmp = *(p++)))
|
||||
goto found_middle;
|
||||
result += 32;
|
||||
size -= 32;
|
||||
}
|
||||
if (!size)
|
||||
return result;
|
||||
tmp = *p;
|
||||
|
||||
found_first:
|
||||
tmp |= ~0UL << size;
|
||||
found_middle:
|
||||
return result + ffz(tmp);
|
||||
}
|
||||
|
||||
/* Linus sez that gcc can optimize the following correctly, we'll see if this
|
||||
* holds on the Sparc as it does for the ALPHA.
|
||||
*/
|
||||
|
||||
#if 0 /* Fool kernel-doc since it doesn't do macros yet */
|
||||
/*
|
||||
* find_first_zero_bit - find the first zero bit in a memory region
|
||||
* @addr: The address to start the search at
|
||||
* @size: The maximum size to search
|
||||
*
|
||||
* Returns the bit-number of the first zero bit, not the number of the byte
|
||||
* containing a bit.
|
||||
*/
|
||||
extern int find_first_zero_bit (void *addr, unsigned size);
|
||||
#endif
|
||||
|
||||
#define find_first_zero_bit(addr, size) \
|
||||
find_next_zero_bit((addr), (size), 0)
|
||||
|
||||
#endif /* (__MIPSEB__) */
|
||||
|
||||
/* Now for the ext2 filesystem bit operations and helper routines. */
|
||||
|
||||
#ifdef __MIPSEB__
|
||||
extern __inline__ int ext2_set_bit(int nr, void * addr)
|
||||
{
|
||||
int mask, retval, flags;
|
||||
unsigned char *ADDR = (unsigned char *) addr;
|
||||
|
||||
ADDR += nr >> 3;
|
||||
mask = 1 << (nr & 0x07);
|
||||
save_and_cli(flags);
|
||||
retval = (mask & *ADDR) != 0;
|
||||
*ADDR |= mask;
|
||||
restore_flags(flags);
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern __inline__ int ext2_clear_bit(int nr, void * addr)
|
||||
{
|
||||
int mask, retval, flags;
|
||||
unsigned char *ADDR = (unsigned char *) addr;
|
||||
|
||||
ADDR += nr >> 3;
|
||||
mask = 1 << (nr & 0x07);
|
||||
save_and_cli(flags);
|
||||
retval = (mask & *ADDR) != 0;
|
||||
*ADDR &= ~mask;
|
||||
restore_flags(flags);
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern __inline__ int ext2_test_bit(int nr, const void * addr)
|
||||
{
|
||||
int mask;
|
||||
const unsigned char *ADDR = (const unsigned char *) addr;
|
||||
|
||||
ADDR += nr >> 3;
|
||||
mask = 1 << (nr & 0x07);
|
||||
return ((mask & *ADDR) != 0);
|
||||
}
|
||||
|
||||
#define ext2_find_first_zero_bit(addr, size) \
|
||||
ext2_find_next_zero_bit((addr), (size), 0)
|
||||
|
||||
extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
|
||||
{
|
||||
unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
|
||||
unsigned long result = offset & ~31UL;
|
||||
unsigned long tmp;
|
||||
|
||||
if (offset >= size)
|
||||
return size;
|
||||
size -= result;
|
||||
offset &= 31UL;
|
||||
if(offset) {
|
||||
/* We hold the little endian value in tmp, but then the
|
||||
* shift is illegal. So we could keep a big endian value
|
||||
* in tmp, like this:
|
||||
*
|
||||
* tmp = __swab32(*(p++));
|
||||
* tmp |= ~0UL >> (32-offset);
|
||||
*
|
||||
* but this would decrease preformance, so we change the
|
||||
* shift:
|
||||
*/
|
||||
tmp = *(p++);
|
||||
tmp |= __swab32(~0UL >> (32-offset));
|
||||
if(size < 32)
|
||||
goto found_first;
|
||||
if(~tmp)
|
||||
goto found_middle;
|
||||
size -= 32;
|
||||
result += 32;
|
||||
}
|
||||
while(size & ~31UL) {
|
||||
if(~(tmp = *(p++)))
|
||||
goto found_middle;
|
||||
result += 32;
|
||||
size -= 32;
|
||||
}
|
||||
if(!size)
|
||||
return result;
|
||||
tmp = *p;
|
||||
|
||||
found_first:
|
||||
/* tmp is little endian, so we would have to swab the shift,
|
||||
* see above. But then we have to swab tmp below for ffz, so
|
||||
* we might as well do this here.
|
||||
*/
|
||||
return result + ffz(__swab32(tmp) | (~0UL << size));
|
||||
found_middle:
|
||||
return result + ffz(__swab32(tmp));
|
||||
}
|
||||
#else /* !(__MIPSEB__) */
|
||||
|
||||
/* Native ext2 byte ordering, just collapse using defines. */
|
||||
#define ext2_set_bit(nr, addr) test_and_set_bit((nr), (addr))
|
||||
#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr), (addr))
|
||||
#define ext2_test_bit(nr, addr) test_bit((nr), (addr))
|
||||
#define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size))
|
||||
#define ext2_find_next_zero_bit(addr, size, offset) \
|
||||
find_next_zero_bit((addr), (size), (offset))
|
||||
|
||||
#endif /* !(__MIPSEB__) */
|
||||
|
||||
/*
|
||||
* Bitmap functions for the minix filesystem.
|
||||
* FIXME: These assume that Minix uses the native byte/bitorder.
|
||||
* This limits the Minix filesystem's value for data exchange very much.
|
||||
*/
|
||||
#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
|
||||
#define minix_set_bit(nr,addr) set_bit(nr,addr)
|
||||
#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
|
||||
#define minix_test_bit(nr,addr) test_bit(nr,addr)
|
||||
#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
|
||||
|
||||
#endif /* _ASM_BITOPS_H */
|
||||
31
include/asm-mips/byteorder.h
Normal file
31
include/asm-mips/byteorder.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/* $Id: byteorder.h,v 1.8 1998/11/02 09:29:32 ralf Exp $
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) by Ralf Baechle
|
||||
*/
|
||||
#ifndef _MIPS_BYTEORDER_H
|
||||
#define _MIPS_BYTEORDER_H
|
||||
|
||||
#include <asm/types.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
|
||||
# define __BYTEORDER_HAS_U64__
|
||||
# define __SWAB_64_THRU_32__
|
||||
#endif
|
||||
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#if defined (__MIPSEB__)
|
||||
# include <linux/byteorder/big_endian.h>
|
||||
#elif defined (__MIPSEL__)
|
||||
# include <linux/byteorder/little_endian.h>
|
||||
#else
|
||||
# error "MIPS, but neither __MIPSEB__, nor __MIPSEL__???"
|
||||
#endif
|
||||
|
||||
#endif /* _MIPS_BYTEORDER_H */
|
||||
24
include/asm-mips/cachectl.h
Normal file
24
include/asm-mips/cachectl.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* cachectl.h -- defines for MIPS cache control system calls
|
||||
*
|
||||
* Copyright (C) 1994, 1995, 1996 by Ralf Baechle
|
||||
*/
|
||||
#ifndef __ASM_MIPS_CACHECTL
|
||||
#define __ASM_MIPS_CACHECTL
|
||||
|
||||
/*
|
||||
* Options for cacheflush system call
|
||||
*/
|
||||
#define ICACHE (1<<0) /* flush instruction cache */
|
||||
#define DCACHE (1<<1) /* writeback and flush data cache */
|
||||
#define BCACHE (ICACHE|DCACHE) /* flush both caches */
|
||||
|
||||
/*
|
||||
* Caching modes for the cachectl(2) call
|
||||
*
|
||||
* cachectl(2) is currently not supported and returns ENOSYS.
|
||||
*/
|
||||
#define CACHEABLE 0 /* make pages cacheable */
|
||||
#define UNCACHEABLE 1 /* make pages uncacheable */
|
||||
|
||||
#endif /* __ASM_MIPS_CACHECTL */
|
||||
47
include/asm-mips/cacheops.h
Normal file
47
include/asm-mips/cacheops.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Cache operations for the cache instruction.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* (C) Copyright 1996, 1997 by Ralf Baechle
|
||||
*/
|
||||
#ifndef __ASM_MIPS_CACHEOPS_H
|
||||
#define __ASM_MIPS_CACHEOPS_H
|
||||
|
||||
/*
|
||||
* Cache Operations
|
||||
*/
|
||||
#define Index_Invalidate_I 0x00
|
||||
#define Index_Writeback_Inv_D 0x01
|
||||
#define Index_Invalidate_SI 0x02
|
||||
#define Index_Writeback_Inv_SD 0x03
|
||||
#define Index_Load_Tag_I 0x04
|
||||
#define Index_Load_Tag_D 0x05
|
||||
#define Index_Load_Tag_SI 0x06
|
||||
#define Index_Load_Tag_SD 0x07
|
||||
#define Index_Store_Tag_I 0x08
|
||||
#define Index_Store_Tag_D 0x09
|
||||
#define Index_Store_Tag_SI 0x0A
|
||||
#define Index_Store_Tag_SD 0x0B
|
||||
#define Create_Dirty_Excl_D 0x0d
|
||||
#define Create_Dirty_Excl_SD 0x0f
|
||||
#define Hit_Invalidate_I 0x10
|
||||
#define Hit_Invalidate_D 0x11
|
||||
#define Hit_Invalidate_SI 0x12
|
||||
#define Hit_Invalidate_SD 0x13
|
||||
#define Fill 0x14
|
||||
#define Hit_Writeback_Inv_D 0x15
|
||||
/* 0x16 is unused */
|
||||
#define Hit_Writeback_Inv_SD 0x17
|
||||
#define Hit_Writeback_I 0x18
|
||||
#define Hit_Writeback_D 0x19
|
||||
/* 0x1a is unused */
|
||||
#define Hit_Writeback_SD 0x1b
|
||||
/* 0x1c is unused */
|
||||
/* 0x1e is unused */
|
||||
#define Hit_Set_Virtual_SI 0x1e
|
||||
#define Hit_Set_Virtual_SD 0x1f
|
||||
|
||||
#endif /* __ASM_MIPS_CACHEOPS_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user