Compare commits

...

15 Commits

Author SHA1 Message Date
wdenk
db2f721ffc * 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
2003-03-06 00:58:30 +00:00
wdenk
43d9616cff * 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

* 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
2003-03-06 00:02:04 +00:00
wdenk
6069ff2653 * 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

* 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

* Start adding MIPS support files
2003-02-28 00:49:47 +00:00
stroese
2a9e02ead3 CPCIISER4 configuration updated. 2003-02-18 11:30:24 +00:00
stroese
d7787c6e57 Fixed bug in ext. serial clock setup on PPC405 (since PPC440 port). 2003-02-17 16:06:06 +00:00
stroese
ad10dd9aaf Add "pcidelay" environment variable (in ms, enabled via CONFIG_PCI_BOOTDELAY). 2003-02-14 11:21:23 +00:00
wdenk
e5ad56b13b Cleanup: remove trailing white space 2003-02-11 01:49:43 +00:00
stroese
ee1b3b5fe4 Add support for 4MB and 128MB onboard SDRAM (cpu/ppc4xx/sdram.c) 2003-02-10 16:39:00 +00:00
stroese
6177445dab Added 4MByte and 128MByte onboard SDRAM 2003-02-10 16:26:37 +00:00
wdenk
aacf9a49aa * 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)
2003-01-17 16:27:01 +00:00
wdenk
608c91460b Add support for V37 board
(patch by Jn Benediktsson, 11 Dec 2002)
2003-01-13 23:54:46 +00:00
wdenk
d0fb80c302 * Restrict baudrate settings on LWMON to higher speeds
when watchdog is on

* 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)
2003-01-11 09:48:40 +00:00
wdenk
a25f862ba8 Patch by Detlev Zundel, 30 Dec 2002:
Add single quote support for (old) command line parser
2003-01-02 23:57:29 +00:00
wdenk
13122b4f1d Adjust LWMON environment to current requirements 2002-12-28 15:55:42 +00:00
wdenk
288b3d7f5a * Switch LWMON board default config from FRAM to EEPROM;
in POST, EEPROM shows up on 8 addresses
2002-12-20 23:42:25 +00:00
152 changed files with 13788 additions and 1985 deletions

111
CHANGELOG
View File

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

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

View File

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

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

View File

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

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

View File

@@ -107,7 +107,7 @@ int misc_init_r (void)
}
void pci_init (void)
void pci_init_board (void)
{
#ifndef CONFIG_RAMBOOT
articiaS_pci_init ();

View File

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

View File

@@ -113,7 +113,7 @@ struct pci_controller hose = {
#endif
};
void pci_init(void)
void pci_init_board(void)
{
pci_mpc824x_init(&hose);
}

View File

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

View File

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

View File

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

@@ -0,0 +1,40 @@
#
# (C) Copyright 2000
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
OBJS = $(BOARD).o flash.o
$(LIB): .depend $(OBJS)
$(AR) crv $@ $^
#########################################################################
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
sinclude .depend
#########################################################################

490
board/emk/top860/flash.c Normal file
View 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
View 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
View 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 = .);
}

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

View File

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

View File

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

View File

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

@@ -0,0 +1,47 @@
#
# (C) Copyright 2000
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
OBJS := 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
View 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
View 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
View 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
View 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
View 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 = .;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

@@ -124,7 +124,7 @@ struct pci_controller hose = {
#endif
};
void pci_init(void)
void pci_init_board(void)
{
pci_mpc824x_init(&hose);
}

View File

@@ -108,7 +108,7 @@ static struct pci_controller hose = {
#endif
};
void pci_init (void)
void pci_init_board (void)
{
pci_mpc824x_init(&hose);
}

View File

@@ -135,7 +135,7 @@ int misc_init_r (void)
return (0);
}
void pci_init (void)
void pci_init_board (void)
{
cpc710_pci_init ();

View File

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

View File

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

View File

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

View File

@@ -121,7 +121,7 @@ struct pci_controller hose = {
#endif
};
void pci_init(void)
void pci_init_board(void)
{
pci_mpc824x_init(&hose);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 = &ether_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 */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

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

View 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