Compare commits

...

38 Commits

Author SHA1 Message Date
wdenk
4a6fd34b26 * Patch by Lutz Dennig, 10 Apr 2003:
Update for R360MPI board

* Add new meaning to "autostart" environment variable:
  If set to "no", a standalone image passed to the
  "bootm" command will be copied to the load address
  (and eventually uncompressed), but NOT be started.
  This can be used to load and uncompress arbitrary
  data.

* Set max brightness for MN11236 displays on TRAB board
2003-04-12 23:38:12 +00:00
stroese
69f8f827d5 Patch from Stefan Roese. 2003-04-10 13:30:28 +00:00
stroese
759a51b4f3 Changed DHCP client to use ip address from server option field #54 from the OFFER-paket in the server option field #54 in the REQUEST-paket. This fixes a problem using a Windows 2000 DHCP server, where the DHCP-server is not the TFTP-server. 2003-04-10 13:26:44 +00:00
wdenk
d126bfbdbd Add support for TQM862L modules 2003-04-10 11:18:18 +00:00
wdenk
60fbe25424 Prepare for 0.3.0 release
* Add support for Purple Board (MIPS64 5Kc)

* Add support for MIPS64 5Kc CPUs
2003-04-08 23:25:21 +00:00
wdenk
3e38691e8f * Patch by Arun Dharankar, 4 Apr 2003:
Add IDMA example code (tested on 8260 only)

* Add support for Purple Board (MIPS64 5Kc)

* Add support for MIPS64 5Kc CPUs

* Fix missing setting of "loadaddr" and "bootfile" on ARM and MIPS

* Patch by Denis Peter, 04 Apr 2003:
  - update MIP405-4 board

* Patches by Denis Peter, 03 April 2003:
  - fix PCI IRQs on MPL boards
  - fix two more un-relocated pointer problems

* Fix behaviour of "run" command:
  - print error message iv variable does not exist
  - terminate processing of arguments in case of error

* Patches by Peter Figuli, 10 Mar 2003
  - Add support for BTUART on PXA platform
  - Add support for WEP EP250 (PXA) board

* Fix flash problems on INCA-IP; add tool to allow bruning images  to
  flash using a BDI2000

* Implement fix for I2C Edge Conditions problem for all boards that
  use the bit-banging driver (common/soft_i2c.c)

* Add patches by Robert Schwebel, 31 Mar 2003:
  - csb226 board: bring in sync with innokom/memsetup.S
  - csb226 board: fix MDREFR handling
  - misc doc fixes / extensions
  - innokom board: cleanup, MDREFR fix in memsetup.S, config update
  - add BOOT_PROGRESS to armlinux.c
2003-04-05 00:53:31 +00:00
stroese
36c05a80ec Patch from Stefan Roese. 2003-04-04 16:55:30 +00:00
stroese
afcc4a7404 Changed CPCI405 to use CTS instead of DSR on PPC405 UART1. 2003-04-04 16:52:57 +00:00
stroese
9e7d5ebea9 U-Boot version environment variable "ver" added (CONFIG_VERSION_VARIABLE). 2003-04-04 16:48:07 +00:00
stroese
baa3d528fe Changed PPC405GPr version from A to B. 2003-04-04 16:00:33 +00:00
stroese
c1551ea817 U-Boot version environment variable "ver" added (CONFIG_VERSION_VARIABLE). 2003-04-04 15:53:41 +00:00
stroese
0587597ca3 U-Boot version environment variable "ver" added (CONFIG_VERSION_VARIABLE). 2003-04-04 15:44:49 +00:00
wdenk
0db5bca807 * Patch by Martin Winistoerfer, 23 Mar 2003
- Add port to MPC555/556 microcontrollers
  - Add support for cmi customer board with
    Intel 28F128J3A, 28F320J3A or 28F640J3A flash.

* Patch by Rick Bronson, 28 Mar 2003:
  - fix common/cmd_nand.c
2003-03-31 17:27:09 +00:00
wdenk
85ec0bcc1b * Patch by Arun Dharankar, 24 Mar 2003:
- add threads / scheduler example code

* Add patches by Robert Schwebel, 31 Mar 2003:
  - add ctrl-c support for kermit download
  - align bdinfo output on ARM

* Add CPU ID, version, and clock speed for INCA-IP
2003-03-31 16:34:49 +00:00
wdenk
506f044131 Patches by Dave Ellis, 18 Mar 2003 for SXNI855T board:
- fix SRAM and SDRAM memory sizing
- add status LED support
- add MAC address for second (SCC1) ethernet port

Update default environment for TQM8260 board
2003-03-28 14:40:36 +00:00
wdenk
cdd8a0f151 Fix MIPS build problem 2003-03-27 18:00:16 +00:00
wdenk
c021880ac5 * Add support for MIPS32 4Kc CPUs
* Add support for INCA-IP Board
2003-03-27 12:09:35 +00:00
wdenk
ac6dbb85b7 Make compile clean, fix the usual small problems. 2003-03-26 11:42:53 +00:00
stroese
2a46cabd77 esd PCI405 updated. 2003-03-26 10:36:12 +00:00
wdenk
dc7c9a1a52 * Patch by Rick Bronson, 16 Mar 2003:
Add support for Atmel AT91RM9200DK w/NAND

* Patches by Robert Schwebel, 19 Mar 2003:
  - use arm-linux-gcc as default compiler for ARM
  - fix i2c fixup code
  - fix missing baudrate setting
  - added $loadaddr / CFG_LOAD_ADDR support to loadb
  - moved "ignoring trailing characters" _before_ u-boot wants to
    print out diagnostics messages; removes bogus characters at the
    end of transmission

* Patch by John Zhan, 18 Mar 2003:
  Add support for SinoVee Microsystems SC8xx boards

* Patch by Rolf Offermanns, 21 Mar 2003:
  ported the dnp1110 related changes from the current armboot cvs to
  current u-boot cvs. smc91111 does not work. problem marked in
  smc91111.c, grep for "FIXME".

* Patch by Brian Auld, 25 Mar 2003:
  Add support for STM flash chips on ebony board

 * Add PCI support for MPC8250 Boards (PM825 module)

 * Patch by Stefan Roese, 25 Mar 2003:
2003-03-26 06:55:25 +00:00
wdenk
10f670178c *** empty log message *** 2003-03-25 18:06:06 +00:00
wdenk
4d75a504d0 Add PCI support for MPC8250 Boards (PM825 module) 2003-03-25 16:50:56 +00:00
stroese
44e5c5c4f1 Patch by Stefan Roese , 25 Mar 2003. 2003-03-25 14:44:48 +00:00
stroese
a02ab7d184 BSP-Command for esd PCI405 added. 2003-03-25 14:43:01 +00:00
stroese
d69b100e70 esd PCI405 updated. 2003-03-25 14:41:35 +00:00
stroese
5d5d44e717 Patch by Stefan Roese , 20 Mar 2003. 2003-03-20 15:32:59 +00:00
stroese
6f4474e87b CPCI4052 update (support for revision 3). 2003-03-20 15:31:19 +00:00
stroese
97a43d641d Added edge conditioning register (ecr) for PPC405GPr. 2003-03-20 15:27:41 +00:00
stroese
7e11d8269e Clip udiv to 5 bits on PPC405 (serial.c). 2003-03-20 15:25:59 +00:00
stroese
38daa27d21 Set edge conditioning circuitry on PPC405GPr for compatibility to existing PPC405GP designs. 2003-03-20 15:21:50 +00:00
wdenk
1957dd29d9 Add files that were forgotten 2003-03-14 21:34:25 +00:00
wdenk
06d01dbe00 * Avoid flicker on the TRAB's VFD by synchronizing the enable with
the HSYNC/VSYNC. Requires new CPLD code (Version 101 for Rev. 100
  boards, version 153 for Rev. 200 boards).

* Patch by Vladimir Gurevich, 12 Mar 2003:
  Fix relocation problem of statically initialized string pointers
  in common/cmd_pci.c

* Patch by Kai-Uwe Blm, 12 Mar 2003:
  Cleanup & bug fixes for JFFS2 code:
  - the memory mangement was broken. It caused havoc on malloc by
    writing beyond the block boundaries.
  - the length calculation for files was wrong, sometimes resulting
    in short file reads.
  - data copying now optionally takes fragment version numbers into
    account, to avoid copying from older data.
  See doc/README.JFFS2 for details.
2003-03-14 20:47:52 +00:00
wdenk
09127c6096 Cleanup compiler warning 2003-03-12 10:43:01 +00:00
wdenk
3bac351370 * Patch by Josef Wagner, 12 Mar 2003:
- 16/32 MB and 50/80 MHz support with auto-detection for IP860
  - ETH05 and BEDBUG support for CU824
  - added support for MicroSys CPC45
  - new BOOTROM/FLASH0 and DOC base for PM826

* Patch by Robert Schwebel, 12 Mar 2003:
  Fix the chpart command on innokom board

* Name cleanup:
  mv include/asm-i386/ppcboot-i386.h include/asm-i386/u-boot-i386.h
  s/PPCBoot/U-Boot/ in some files
  s/pImage/uImage/  in some files

* Patch by Detlev Zundel, 15 Jan 2003:
  Fix '' command line quoting

* Patch by The LEOX team, 19 Jan 2003:
  - add support for the ELPT860 board
  - add support for Dallas ds164x RTC
2003-03-12 10:41:04 +00:00
wdenk
1cb8e980c4 * Patches by David Mller, 31 Jan 2003:
- minimal setup for CardBus bridges
  - add EEPROM read/write support in the CS8900 driver
  - add support for the builtin I2C controller in the Samsung s3c24x0 chips
  - add support for  MPL's VCMA9 (Samsung s3c2410 based) board

* Patch by Steven Scholz, 04 Feb 2003:
  add support for RTC DS1307

* Patch by Reinhard Meyer, 5 Feb 2003:
  fix PLPRCR/SCCR init sequence on 8xx to allow for
  changes of EBDF by software

* Patch by Vladimir Gurevich, 07 Feb 2003:
  "API-compatibility patch" for 4xx I2C driver
2003-03-06 21:55:29 +00:00
wdenk
500545cc6b Fix problem with default #defines
Cleanup compiler warning
2003-03-06 14:23:06 +00:00
wdenk
47cd00fa70 * Patches by Robert Schwebel, 06 Mar 2003:
- fix bug in BOOTP code (must use NetCopyIP)
  - update of CSB226 port
  - clear BSS segment on XScale
  - added support for i2c_init_board() function
  - update to the Innokom plattform

* Extend support for redundand environments for configurations where
  environment size < sector size
2003-03-06 13:39:27 +00:00
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
322 changed files with 40349 additions and 4516 deletions

236
CHANGELOG
View File

@@ -1,7 +1,237 @@
======================================================================
Changes since U-Boot 0.2.2:
Changes since U-Boot 0.3.0:
======================================================================
* Patch by Lutz Dennig, 10 Apr 2003:
Update for R360MPI board
* Add new meaning to "autostart" environment variable:
If set to "no", a standalone image passed to the
"bootm" command will be copied to the load address
(and eventually uncompressed), but NOT be started.
This can be used to load and uncompress arbitrary
data.
* Patch by Stefan Roese, 10 Apr 2003:
Changed DHCP client to use IP address from server option field #54
from the OFFER packet in the server option field #54 in the REQUEST
packet. This fixes a problem using a Windows 2000 DHCP server,
where the DHCP-server is not the TFTP-server.
* Set max brightness for MN11236 displays on TRAB board
* Add support for TQM862L modules
======================================================================
Changes for U-Boot 0.3.0:
======================================================================
* Patch by Arun Dharankar, 4 Apr 2003:
Add IDMA example code (tested on 8260 only)
* Add support for Purple Board (MIPS64 5Kc)
* Add support for MIPS64 5Kc CPUs
* Fix missing setting of "loadaddr" and "bootfile" on ARM and MIPS
* Patch by Denis Peter, 04 Apr 2003:
- update MIP405-4 board
* Patch by Stefan Roese, 4 Apr 2003:
- U-Boot version environment variable "ver" added
(CONFIG_VERSION_VARIABLE).
- Changed PPC405GPr version from A to B.
- Changed CPCI405 to use CTS instead of DSR on PPC405 UART1.
* Patches by Denis Peter, 03 April 2003:
- fix PCI IRQs on MPL boards
- fix two more un-relocated pointer problems
* Fix behaviour of "run" command:
- print error message iv variable does not exist
- terminate processing of arguments in case of error
* Patches by Peter Figuli, 10 Mar 2003
- Add support for BTUART on PXA platform
- Add support for WEP EP250 (PXA) board
* Fix flash problems on INCA-IP; add tool to allow bruning images to
flash using a BDI2000
* Implement fix for I2C Edge Conditions problem for all boards that
use the bit-banging driver (common/soft_i2c.c)
* Patch by Martin Winistoerfer, 23 Mar 2003
- Add port to MPC555/556 microcontrollers
- Add support for cmi customer board with
Intel 28F128J3A, 28F320J3A or 28F640J3A flash.
* Patch by Rick Bronson, 28 Mar 2003:
- fix common/cmd_nand.c
* Patch by Arun Dharankar, 24 Mar 2003:
- add threads / scheduler example code
* Add patches by Robert Schwebel, 31 Mar 2003:
- add ctrl-c support for kermit download
- align bdinfo output on ARM
- csb226 board: bring in sync with innokom/memsetup.S
- csb226 board: fix MDREFR handling
- misc doc fixes / extensions
- innokom board: cleanup, MDREFR fix in memsetup.S, config update
- add BOOT_PROGRESS to armlinux.c
* Add CPU ID, version, and clock speed for INCA-IP
* Patches by Dave Ellis, 18 Mar 2003 for SXNI855T board:
- fix SRAM and SDRAM memory sizing
- add status LED support
- add MAC address for second (SCC1) ethernet port
* Update default environment for TQM8260 board
* Patch by Rick Bronson, 16 Mar 2003:
- Add NAND flash support for reading, writing, and erasing NAND
flash (certain forms of which are called SmartMedia).
- Add support for Atmel AT91RM9200DK ARM920T based development kit.
* Patches by Robert Schwebel, 19 Mar 2003:
- use arm-linux-gcc as default compiler for ARM
- fix i2c fixup code
- fix missing baudrate setting
- added $loadaddr / CFG_LOAD_ADDR support to loadb
- moved "ignoring trailing characters" _before_ u-boot wants to
print out diagnostics messages; removes bogus characters at the
end of transmission
* Patch by John Zhan, 18 Mar 2003:
Add support for SinoVee Microsystems SC8xx boards
* Patch by Rolf Offermanns, 21 Mar 2003:
ported the dnp1110 related changes from the current armboot cvs to
current u-boot cvs. smc91111 does not work. problem marked in
smc91111.c, grep for "FIXME".
* Patch by Brian Auld, 25 Mar 2003:
Add support for STM flash chips on ebony board
* Add PCI support for MPC8250 Boards (PM825 module)
* Patch by Stefan Roese, 25 Mar 2003:
- PCI405 update.
* Patch by Stefan Roese, 20 Mar 2003:
- CPCI4052 update (support for revision 3).
- Set edge conditioning circuitry on PPC405GPr for compatibility
to existing PPC405GP designs.
- Clip udiv to 5 bits on PPC405 (serial.c).
* Extend INCAIP board support:
- add automatic RAM size detection
- add "bdinfo" command
- pass flash address and size to Linux kernel
- switch to 150 MHz clock
* Avoid flicker on the TRAB's VFD by synchronizing the enable with
the HSYNC/VSYNC. Requires new CPLD code (Version 101 for Rev. 100
boards, version 153 for Rev. 200 boards).
* Patch by Vladimir Gurevich, 12 Mar 2003:
Fix relocation problem of statically initialized string pointers
in common/cmd_pci.c
* Patch by Kai-Uwe Blöm, 12 Mar 2003:
Cleanup & bug fixes for JFFS2 code:
- the memory mangement was broken. It caused havoc on malloc by
writing beyond the block boundaries.
- the length calculation for files was wrong, sometimes resulting
in short file reads.
- data copying now optionally takes fragment version numbers into
account, to avoid copying from older data.
See doc/README.JFFS2 for details.
* Patch by Josef Wagner, 12 Mar 2003:
- 16/32 MB and 50/80 MHz support with auto-detection for IP860
- ETH05 and BEDBUG support for CU824
- added support for MicroSys CPC45
- new BOOTROM/FLASH0 and DOC base for PM826
* Patch by Robert Schwebel, 12 Mar 2003:
Fix the chpart command on innokom board
* Name cleanup:
mv include/asm-i386/ppcboot-i386.h include/asm-i386/u-boot-i386.h
s/PPCBoot/U-Boot/ in some files
s/pImage/uImage/ in some files
* Patch by Detlev Zundel, 15 Jan 2003:
Fix '' command line quoting
* Patch by The LEOX team, 19 Jan 2003:
- add support for the ELPT860 board
- add support for Dallas ds164x RTC
* Patches by David Müller, 31 Jan 2003:
- minimal setup for CardBus bridges
- add EEPROM read/write support in the CS8900 driver
- add support for the builtin I2C controller in the Samsung s3c24x0 chips
- add support for MPL's VCMA9 (Samsung s3c2410 based) board
* Patch by Steven Scholz, 04 Feb 2003:
add support for RTC DS1307
* Patch by Reinhard Meyer, 5 Feb 2003:
fix PLPRCR/SCCR init sequence on 8xx to allow for
changes of EBDF by software
* Patch by Vladimir Gurevich, 07 Feb 2003:
"API-compatibility patch" for 4xx I2C driver
* TRAB fixes / extensions:
- Restore VFD brightness as saved in environment
- add support for FGujitsu flashes
- make sure both buzzers are turned off (drive low level)
* Patches by Robert Schwebel, 06 Mar 2003:
- fix bug in BOOTP code (must use NetCopyIP)
- update of CSB226 port
- clear BSS segment on XScale
- added support for i2c_init_board() function
- update to the Innokom plattform
* Extend support for redundand environments for configurations where
environment size < sector size
* 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
@@ -46,6 +276,10 @@ Changes since U-Boot 0.2.2:
* Patch by Stefan Roese, 10 Feb 2003:
Add support for 4MB and 128MB onboard SDRAM (cpu/ppc4xx/sdram.c)
* Add support for MIPS32 4Kc CPUs
* Add support for INCA-IP Board
======================================================================
Changes for U-Boot 0.2.2:
======================================================================

33
CREDITS
View File

@@ -46,6 +46,10 @@ N: Raphael Bossek
E: raphael.bossek@solutions4linux.de
D: 8xxrom-0.3.0
N: Rick Bronson
E: rick@efn.org
D: Atmel AT91RM9200DK and NAND support
N: David Brown
E: DBrown03@harris.com
D: Extensions to 8xxrom-0.3.0
@@ -66,6 +70,10 @@ N: Magnus Damm
E: eramdam@kieray1.p.y.ki.era.ericsson.se
D: 8xxrom
N: Arun Dharankar
E: ADharankar@ATTBI.Com
D: threads / scheduler example code
N: Kári Davíðsson
E: kd@flaga.is
D: FLAGA DM Support
@@ -96,6 +104,10 @@ E: wg@denx.de
D: Support for Interphase 4539 T1/E1/J1 PMC, PN62, CCM, SCM boards
W: www.denx.de
N: Peter Figuli
E: peposh@etc.sk
D: Support for WEP EP250 (PXA) board
N: Thomas Frieden
E: ThomasF@hyperion-entertainment.com
D: Support for AmigaOne
@@ -166,6 +178,11 @@ N: Thomas Lange
E: thomas@corelatus.com
D: Support for GTH board; lots of PCMCIA fixes
N: The LEOX team
E: team@leox.org
D: Support for LEOX boards, DS164x RTC
W: http://www.leox.org
N: Raymond Lo
E: lo@routefree.com
D: Support for DOS partitions
@@ -174,6 +191,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
@@ -241,14 +262,26 @@ 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
N: Martin Winistoerfer
E: martinwinistoerfer@gmx.ch
D: Port to MPC555/556 microcontrollers and support for cmi board
N: Christian Vejlbo
E: christian.vejlbo@tellabs.com
D: FADS860T ethernet support
N: John Zhan
E: zhanz@sinovee.com
D: Support for SinoVee Microsystems SC8xx SBC
N: Alex Zuepke
E: azu@sysgo.de
D: Overall improvements on StrongARM, ARM720TDMI; Support for Tuxscreen; initial PCMCIA support for ARM

View File

@@ -14,6 +14,7 @@
#########################################################################
# PowerPC Systems: #
# #
# Maintainer Name, Email Address #
# Board CPU #
@@ -31,6 +32,10 @@ Jerry Van Baren <vanbaren_gerald@si.com>
sacsng MPC8260
Rick Bronson <rick@efn.org>
AT91RM9200DK at91rm9200
Oliver Brown <obrown@adventnetworks.com>
gw8260 MPC8260
@@ -136,10 +141,18 @@ Thomas Lange <thomas@corelatus.com>
GTH MPC860
The LEOX team <team@leox.org>
ELPT860 MPC860T
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 +197,14 @@ Jim Thompson <jim@musenki.com>
MUSENKI MPC8245/8241
Sandpoint8245 MPC8245
Rune Torgersen <runet@innovsys.com>
MPC8266ADS MPC8266
John Zhan <zhanz@sinovee.com>
svm_sc8xx MPC8xx
-------------------------------------------------------------------------
Unknown / orphaned boards:
@@ -220,6 +241,10 @@ Unknown / orphaned boards:
# Board CPU #
#########################################################################
Peter Figuli <peposh@etc.sk>
wepep250 xscale
Marius Gröger <mag@sysgo.de>
impa7 ARM720T (EP7211)
@@ -238,6 +263,7 @@ Gary Jennejohn <gj@denx.de>
David Müller <d.mueller@elsoft.ch>
smdk2410 ARM920T
VCMA9 ARM920T
Rolf Offermanns <rof@sysgo.de>
@@ -274,6 +300,7 @@ Daniel Engstr
Wolfgang Denk <wd@denx.de>
incaip MIPS32 4Kc
purple MIPS64 5Kc
#########################################################################
# End of MAINTAINERS list #

71
MAKEALL
View File

@@ -10,24 +10,33 @@ fi
LIST=""
#########################################################################
## MPC5xx Systems
#########################################################################
LIST_5xx=" \
cmi_mpc5xx \
"
#########################################################################
## MPC8xx Systems
#########################################################################
LIST_8xx=" \
ADS860 AMX860 c2mon CCM \
cogent_mpc8xx ESTEEM192E ETX094 FADS823 \
FADS850SAR FADS860T FLAGADM FPS850L \
GEN860T GENIETV GTH hermes \
IAD210 ICU862_100MHz IP860 IVML24 \
IVML24_128 IVML24_256 IVMS8 IVMS8_128 \
IVMS8_256 KUP4K LANTEC lwmon \
MBX MBX860T MHPC MVS1 \
NETVIA NX823 pcu_e R360MPI \
RPXClassic RPXlite RRvision SM850 \
SPD823TS SXNI855T TQM823L TQM823L_LCD \
TQM850L TQM855L TQM860L TQM860L_FEC \
TTTech v37 \
cogent_mpc8xx ESTEEM192E ETX094 ELPT860 \
FADS823 FADS850SAR FADS860T FLAGADM \
FPS850L GEN860T GENIETV GTH \
hermes IAD210 ICU862_100MHz IP860 \
IVML24 IVML24_128 IVML24_256 IVMS8 \
IVMS8_128 IVMS8_256 KUP4K LANTEC \
lwmon MBX MBX860T MHPC \
MVS1 NETVIA NX823 pcu_e \
R360MPI RPXClassic RPXlite RRvision \
SM850 SPD823TS svm_sc8xx SXNI855T \
TOP860 TQM823L TQM823L_LCD TQM850L \
TQM855L TQM860L TQM860L_FEC TTTech \
v37 \
"
#########################################################################
@@ -48,9 +57,9 @@ LIST_4xx=" \
#########################################################################
LIST_824x=" \
BMW CU824 MOUSSE MUSENKI \
OXC PN62 Sandpoint8240 Sandpoint8245 \
utx8245 \
BMW CPC45 CU824 MOUSSE \
MUSENKI OXC PN62 Sandpoint8240 \
Sandpoint8245 utx8245 \
"
#########################################################################
@@ -59,9 +68,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 \
"
#########################################################################
@@ -76,36 +85,48 @@ LIST_7xx=" \
BAB7xx ELPPC \
"
LIST_ppc="${LIST_8xx} ${LIST_824x} ${LIST_8260} \
${LIST_4xx} ${LIST_74xx} ${LIST_7xx}"
LIST_ppc="${LIST_5xx} ${LIST_8xx} \
${LIST_824x} ${LIST_8260} \
${LIST_4xx} \
${LIST_74xx} ${LIST_7xx}"
#########################################################################
## StrongARM Systems
#########################################################################
LIST_SA="lart shannon dnp1110"
LIST_SA="dnp1110 lart shannon"
#########################################################################
## ARM7 Systems
#########################################################################
LIST_ARM7="impa7 ep7312"
LIST_ARM7="ep7312 impa7"
#########################################################################
## ARM9 Systems
#########################################################################
LIST_ARM9="smdk2400 smdk2410 trab"
LIST_ARM9="at91rm9200dk smdk2400 smdk2410 trab VCMA9"
#########################################################################
## Xscale Systems
#########################################################################
LIST_xscale="lubbock cradle csb226 innokom"
LIST_xscale="cradle csb226 innokom lubbock wepep250"
LIST_arm="${LIST_SA} ${LIST_ARM7} ${LIST_ARM9} ${LIST_xscale}"
#########################################################################
## MIPS 4Kc Systems
#########################################################################
LIST_mips4kc="incaip"
LIST_mips5kc="purple"
LIST_mips="${LIST_mips4kc} ${LIST_mips5kc}"
#----- for now, just run PPC by default -----
[ $# = 0 ] && set $LIST_ppc
@@ -127,7 +148,7 @@ build_target() {
for arg in $@
do
case "$arg" in
8xx|824x|8260|4xx|7xx|74xx|SA|ARM7|ARM9|ppc|arm|xscale)
5xx|8xx|824x|8260|4xx|7xx|74xx|SA|ARM7|ARM9|ppc|arm|xscale|mips)
for target in `eval echo '$LIST_'${arg}`
do
build_target ${target}

101
Makefile
View File

@@ -53,26 +53,11 @@ ifndef CROSS_COMPILE
ifeq ($(HOSTARCH),ppc)
CROSS_COMPILE =
else
## #ifeq ($(CPU),mpc8xx)
## CROSS_COMPILE = ppc_8xx-
## #endif
## #ifeq ($(CPU),ppc4xx)
## #CROSS_COMPILE = ppc_4xx-
## #endif
## #ifeq ($(CPU),mpc824x)
## #CROSS_COMPILE = ppc_82xx-
## #endif
## #ifeq ($(CPU),mpc8260)
## #CROSS_COMPILE = ppc_82xx-
## #endif
## #ifeq ($(CPU),74xx_7xx)
## #CROSS_COMPILE = ppc_74xx-)
## #endif
ifeq ($(ARCH),ppc)
CROSS_COMPILE = ppc_8xx-
endif
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm_920TDI-
CROSS_COMPILE = arm-linux-
endif
ifeq ($(ARCH),i386)
#CROSS_COMPILE = i386-elf-
@@ -183,6 +168,14 @@ unconfig:
#========================================================================
# PowerPC
#========================================================================
#########################################################################
## MPC5xx Systems
#########################################################################
cmi_mpc5xx_config: unconfig
@./mkconfig $(@:_config=) ppc mpc5xx cmi
#########################################################################
## MPC8xx Systems
#########################################################################
@@ -202,6 +195,9 @@ CCM_config: unconfig
cogent_mpc8xx_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8xx cogent
ELPT860_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8xx elpt860 LEOX
ESTEEM192E_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8xx esteem192e
@@ -326,9 +322,17 @@ SM850_config : unconfig
SPD823TS_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8xx spd8xx
svm_sc8xx_config: unconfig
@ >include/config.h
@./mkconfig $(@:_config=) ppc mpc8xx svm_sc8xx
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
@@ -349,15 +353,12 @@ TQM850L_80MHz_config \
TQM855L_config \
TQM855L_66MHz_config \
TQM855L_80MHz_config \
TQM855L_FEC_config \
TQM855L_FEC_66MHz_config \
TQM855L_FEC_80MHz_config \
TQM860L_config \
TQM860L_66MHz_config \
TQM860L_80MHz_config \
TQM860L_FEC_config \
TQM860L_FEC_66MHz_config \
TQM860L_FEC_80MHz_config: unconfig
TQM862L_config \
TQM862L_66MHz_config \
TQM862L_80MHz_config: unconfig
@ >include/config.h
@[ -z "$(findstring _FEC,$@)" ] || \
{ echo "#define CONFIG_FEC_ENET" >>include/config.h ; \
@@ -453,9 +454,24 @@ WALNUT405_config:unconfig
#########################################################################
## MPC824x Systems
#########################################################################
xtract_82xx = $(subst _ROMBOOT,,$(subst _L2,,$(subst _266MHz,,$(subst _300MHz,,$(subst _config,,$1)))))
BMW_config: unconfig
@./mkconfig $(@:_config=) ppc mpc824x bmw
CPC45_config \
CPC45_ROMBOOT_config: unconfig
@./mkconfig $(call xtract_82xx,$@) ppc mpc824x cpc45
@cd ./include ; \
if [ "$(findstring _ROMBOOT_,$@)" ] ; then \
echo "CONFIG_BOOT_ROM = y" >> config.mk ; \
echo "... booting from 8-bit flash" ; \
else \
echo "CONFIG_BOOT_ROM = n" >> config.mk ; \
echo "... booting from 64-bit flash" ; \
fi; \
echo "export CONFIG_BOOT_ROM" >> config.mk;
CU824_config: unconfig
@./mkconfig $(@:_config=) ppc mpc824x cu824
@@ -483,7 +499,6 @@ utx8245_config: unconfig
#########################################################################
## MPC8260 Systems
#########################################################################
xtract_82xx = $(subst _ROMBOOT,,$(subst _L2,,$(subst _266MHz,,$(subst _300MHz,,$(subst _config,,$1)))))
cogent_mpc8260_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8260 cogent
@@ -516,6 +531,23 @@ IPHASE4539_config: unconfig
MPC8260ADS_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8260 mpc8260ads
MPC8266ADS_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8260 mpc8266ads
PM825_config \
PM825_ROMBOOT_config: unconfig
@echo "#define CONFIG_PCI" >include/config.h
@./mkconfig -a PM826 ppc mpc8260 pm826
@cd ./include ; \
if [ "$(findstring _ROMBOOT_,$@)" ] ; then \
echo "CONFIG_BOOT_ROM = y" >> config.mk ; \
echo "... booting from 8-bit flash" ; \
else \
echo "CONFIG_BOOT_ROM = n" >> config.mk ; \
echo "... booting from 64-bit flash" ; \
fi; \
echo "export CONFIG_BOOT_ROM" >> config.mk; \
PM826_config \
PM826_ROMBOOT_config: unconfig
@./mkconfig $(call xtract_82xx,$@) ppc mpc8260 pm826
@@ -601,6 +633,9 @@ ELPPC_config: unconfig
## StrongARM Systems
#########################################################################
at91rm9200dk_config : unconfig
@./mkconfig $(@:_config=) arm at91rm9200 at91rm9200dk
lart_config : unconfig
@./mkconfig $(@:_config=) arm sa1100 lart
@@ -631,6 +666,9 @@ trab_big_flash_config: unconfig
}
@./mkconfig -a $(call xtract_trab,$@) arm arm920t trab
VCMA9_config : unconfig
@./mkconfig $(@:_config=) arm arm920t vcma9 mpl
#########################################################################
## ARM720T Systems
#########################################################################
@@ -657,11 +695,14 @@ innokom_config : unconfig
lubbock_config : unconfig
@./mkconfig $(@:_config=) arm xscale lubbock
wepep250_config : unconfig
@./mkconfig $(@:_config=) arm xscale wepep250
#========================================================================
# i386
#========================================================================
#########################################################################
## AMD SC520 CDP
## AMD SC520 CDP
#########################################################################
sc520_cdp_config : unconfig
@./mkconfig $(@:_config=) i386 i386 sc520_cdp
@@ -676,14 +717,20 @@ sc520_cdp_config : unconfig
incaip_config : unconfig
@./mkconfig $(@:_config=) mips mips incaip
purple_config : unconfig
@./mkconfig $(@:_config=) mips mips purple
#########################################################################
#########################################################################
clean:
find . -type f \
\( -name 'core' -o -name '*.bak' -o -name '*~' \
-o -name '*.o' -o -name '*.a' \) -print \
| xargs rm -f
rm -f examples/hello_world examples/timer examples/eepro100_eeprom
rm -f examples/hello_world examples/timer \
examples/eepro100_eeprom examples/sched \
examples/mem_to_mem_idma2intr
rm -f tools/img2srec tools/mkimage tools/envcrc tools/gen_eth_addr
rm -f tools/easylogo/easylogo tools/bmp_logo
rm -f tools/gdb/astest tools/gdb/gdbcont tools/gdb/gdbsend
@@ -696,9 +743,9 @@ clobber: clean
| xargs rm -f
rm -f $(OBJS) *.bak tags TAGS
rm -fr *.*~
rm -f u-boot u-boot.bin u-boot.elf u-boot.srec u-boot.map System.map
rm -f u-boot u-boot.bin 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 tools/inca-swap-bytes cpu/mpc824x/bedbug_603e.c
rm -f include/asm/arch include/asm
mrproper \

106
README
View File

@@ -140,15 +140,19 @@ Directory Hierarchy:
- tools Tools to build S-Record or U-Boot images, etc.
- cpu/74xx_7xx Files specific to Motorola MPC74xx and 7xx CPUs
- cpu/mpc5xx Files specific to Motorola MPC5xx CPUs
- cpu/mpc8xx Files specific to Motorola MPC8xx CPUs
- cpu/mpc824x Files specific to Motorola MPC824x CPUs
- cpu/mpc8260 Files specific to Motorola MPC8260 CPU
- cpu/ppc4xx Files specific to IBM 4xx CPUs
- board/LEOX/ Files specific to boards manufactured by The LEOX team
- board/LEOX/elpt860 Files specific to ELPT860 boards
- board/RPXClassic
Files specific to RPXClassic boards
- board/RPXlite Files specific to RPXlite boards
- board/c2mon Files specific to c2mon boards
- board/cmi Files specific to cmi boards
- board/cogent Files specific to Cogent boards
(need further configuration)
Files specific to CPCIISER4 boards
@@ -290,6 +294,7 @@ The following options need to be configured:
PowerPC based CPUs:
-------------------
CONFIG_MPC823, CONFIG_MPC850, CONFIG_MPC855, CONFIG_MPC860
or CONFIG_MPC5xx
or CONFIG_MPC824X, CONFIG_MPC8260
or CONFIG_IOP480
or CONFIG_405GP
@@ -338,7 +343,7 @@ The following options need to be configured:
CONFIG_GTH, CONFIG_RPXClassic, CONFIG_rsdproto,
CONFIG_IAD210, CONFIG_RPXlite, CONFIG_sbc8260,
CONFIG_EBONY, CONFIG_sacsng, CONFIG_FPS860L,
CONFIG_V37
CONFIG_V37, CONFIG_ELPT860, CONFIG_CMI
ARM based boards:
-----------------
@@ -615,6 +620,13 @@ The following options need to be configured:
SIU Watchdog feature is enabled in the SYPCR
register.
- U-Boot Version:
CONFIG_VERSION_VARIABLE
If this variable is defined, an environment variable
named "ver" is created by U-Boot showing the U-Boot
version as printed by the "version" command.
This variable is readonly.
- Real-Time Clock:
When CFG_CMD_DATE is selected, the type of the RTC
@@ -624,7 +636,9 @@ The following options need to be configured:
CONFIG_RTC_MPC8xx - use internal RTC of MPC8xx
CONFIG_RTC_PCF8563 - use Philips PCF8563 RTC
CONFIG_RTC_MC146818 - use MC146818 RTC
CONFIG_RTC_DS1307 - use Maxim, Inc. DS1307 RTC
CONFIG_RTC_DS1337 - use Maxim, Inc. DS1337 RTC
CONFIG_RTC_DS164x - use Dallas DS164x RTC
- Timestamp Support:
@@ -726,7 +740,7 @@ The following options need to be configured:
16,7 Mill (24bit) 315 318 31b
(i.e. setenv videomode 317; saveenv; reset;)
CONFIG_VIDEO_SED13806
CONFIG_VIDEO_SED13806
Enable Epson SED13806 driver. This driver supports 8bpp
and 16bpp modes defined by CONFIG_VIDEO_SED13806_8BPP
or CONFIG_VIDEO_SED13806_16BPP
@@ -897,6 +911,17 @@ The following options need to be configured:
controls the rate of data transfer. The data rate thus
is 1 / (I2C_DELAY * 4).
CFG_I2C_INIT_BOARD
When a board is reset during an i2c bus transfer
chips might think that the current transfer is still
in progress. On some boards it is possible to access
the i2c SCLK line directly, either by using the
processor pin as a GPIO or by having a second pin
connected to the bus. If this option is defined a
custom i2c_init_board() routine in boards/xxx/board.c
is run early in the boot sequence.
- SPI Support: CONFIG_SPI
Enables SPI driver (so far only tested with
@@ -1043,7 +1068,7 @@ The following options need to be configured:
If CONFIG_ENV_OVERWRITE is #defined in your config
file, the write protection for vendor parameters is
completely disabled. Anybody can change or delte
completely disabled. Anybody can change or delete
these parameters.
Alternatively, if you #define _both_ CONFIG_ETHADDR
@@ -1230,7 +1255,7 @@ The following options need to be configured:
Modem Support:
--------------
[so far only for SMDK2400 board]
[so far only for SMDK2400 and TRAB boards]
- Modem support endable:
CONFIG_MODEM_SUPPORT
@@ -1437,7 +1462,7 @@ following configurations:
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 valid backup copy in case there is a power failure during
a "saveenv" operation.
BE CAREFUL! Any changes to the flash layout, and some changes to the
@@ -1517,23 +1542,20 @@ has been relocated to RAM and a RAM copy of the environment has been
created; also, when using EEPROM you will have to use getenv_r()
until then to read environment variables.
The environment is now protected by a CRC32 checksum. Before the
monitor is relocated into RAM, as a result of a bad CRC you will be
working with the compiled-in default environment - *silently*!!!
[This is necessary, because the first environment variable we need is
the "baudrate" setting for the console - if we have a bad CRC, we
don't have any device yet where we could complain.]
The environment is protected by a CRC32 checksum. Before the monitor
is relocated into RAM, as a result of a bad CRC you will be working
with the compiled-in default environment - *silently*!!! [This is
necessary, because the first environment variable we need is the
"baudrate" setting for the console - if we have a bad CRC, we don't
have any device yet where we could complain.]
Note: once the monitor has been relocated, then it will complain if
the default environment is used; a new CRC is computed as soon as you
use the "setenv" command to modify / delete / add any environment
variable [even when you try to delete a non-existing variable!].
Note2: you must edit your u-boot.lds file to reflect this
configuration.
use the "saveenv" command to store a valid environment.
Low Level (hardware related) configuration options:
---------------------------------------------------
- CFG_CACHELINE_SIZE:
Cache Line Size of the CPU.
@@ -1589,16 +1611,16 @@ Low Level (hardware related) configuration options:
- MPC824X: data cache
- PPC4xx: data cache
- CFG_INIT_DATA_OFFSET:
- CFG_GBL_DATA_OFFSET:
Offset of the initial data structure in the memory
area defined by CFG_INIT_RAM_ADDR. Usually
CFG_INIT_DATA_OFFSET is chosen such that the initial
CFG_GBL_DATA_OFFSET is chosen such that the initial
data is located at the end of the available space
(sometimes written as (CFG_INIT_RAM_END -
CFG_INIT_DATA_SIZE), and the initial stack is just
below that area (growing from (CFG_INIT_RAM_ADDR +
CFG_INIT_DATA_OFFSET) downward.
CFG_GBL_DATA_OFFSET) downward.
Note:
On the MPC824X (or other systems that use the data
@@ -1704,6 +1726,7 @@ configurations; the following names are supported:
FPS850L_config Sandpoint8240_config sbc8260_config
GENIETV_config TQM823L_config PIP405_config
GEN860T_config EBONY_config FPS860L_config
ELPT860_config cmi_mpc5xx_config
Note: for some board special configuration names may exist; check if
additional information is available from the board vendor; for
@@ -1754,14 +1777,21 @@ to port U-Boot to your hardware platform. To do this, follow these
steps:
1. Add a new configuration option for your board to the toplevel
"Makefile", using the existing entries as examples.
"Makefile" and to the "MAKEALL" script, using the existing
entries as examples. Note that here and at many other places
boards and other names are listed alphabetically sorted. Please
keep this order.
2. Create a new directory to hold your board specific code. Add any
files you need.
files you need. In your board directory, you will need at least
the "Makefile", a "<board>.c", "flash.c" and "u-boot.lds".
3. Create a new configuration file "include/configs/<board>.h" for
your board
3. If you're porting U-Boot to a new CPU, then also create a new
directory to hold your CPU specific code. Add any files you need.
4. Run "make config_name" with your new name.
4. Run "make <board>_config" with your new name.
5. Type "make", and you should get a working "u-boot.srec" file
to be installed on your target system.
6. Debug and solve any problems that might arise.
[Of course, this last step is much harder than it sounds.]
@@ -1888,6 +1918,12 @@ Some configuration options can be set using Environment Variables:
be automatically started (by internally calling
"bootm")
If set to "no", a standalone image passed to the
"bootm" command will be copied to the load address
(and eventually uncompressed), but NOT be started.
This can be used to load and uncompress arbitrary
data.
initrd_high - restrict positioning of initrd images:
If this variable is not set, initrd images will be
copied to the highest possible address in RAM; this
@@ -1912,7 +1948,7 @@ Some configuration options can be set using Environment Variables:
ipaddr - IP address; needed for tftpboot command
loadaddr - Default load address for commands like "bootp",
"rarpboot", "tftpboot" or "diskboot"
"rarpboot", "tftpboot", "loadb" or "diskboot"
loads_echo - see CONFIG_LOADS_ECHO
@@ -1950,6 +1986,13 @@ the board). U-Boot refuses to delete or overwrite these variables
once they have been set once.
Further special Environment Variables:
ver - Contains the U-Boot version string as printed
with the "version" command. This variable is
readonly (see CONFIG_VERSION_VARIABLE).
Please note that changes to some configuration parameters may take
only effect after the next boot (yes, that's just like Windoze :-).
@@ -2358,18 +2401,18 @@ U-Boot supports the following image types:
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)
@@ -2464,6 +2507,17 @@ Hit 'q':
[q, b, e, ?] ## Application terminated, rc = 0x0
Minicom warning:
================
Over time, many people have reported problems when trying to used the
"minicom" terminal emulation program for serial download. I (wd)
consider minicom to be broken, and recommend not to use it. Under
Unix, I recommend to use CKermit for general purpose use (and
especially for kermit binary protocol download ("loadb" command), and
use "cu" for S-Record download ("loads" command).
NetBSD Notes:
=============

View File

@@ -0,0 +1,47 @@
#######################################################################
#
# Copyright (C) 2000, 2001, 2002, 2003
# The LEOX team <team@leox.org>, http://www.leox.org
#
# LEOX.org is about the development of free hardware and software resources
# for system on chip.
#
# Description: U-Boot port on the LEOX's ELPT860 CPU board
# ~~~~~~~~~~~
#
#######################################################################
#
# 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
#########################################################################

View File

@@ -0,0 +1,424 @@
=============================================================================
U-Boot port on the LEOX's ELPT860 CPU board
-------------------------------------------
LEOX.org is about the development of free hardware and software resources
for system on chip.
For more information, contact The LEOX team <team@leox.org>
References:
~~~~~~~~~~
1) Get the last stable release from denx.de:
o ftp://ftp.denx.de/pub/u-boot/u-boot-0.2.0.tar.bz2
2) Get the current CVS snapshot:
o cvs -d:pserver:anonymous@cvs.u-boot.sourceforge.net:/cvsroot/u-boot login
o cvs -z6 -d:pserver:anonymous@cvs.u-boot.sourceforge.net:/cvsroot/u-boot co -P u-boot
=============================================================================
The ELPT860 CPU board has the following features:
Processor: - MPC860T @ 50MHz
- PowerPC Core
- 65 MIPS
- Caches: D->4KB, I->4KB
- CPM: 4 SCCs, 2 SMCs
- Ethernet 10/100
- SPI, I2C, PCMCIA, Parallel
CPU board: - DRAM: 16 MB
- FLASH: 512 KB + (2 * 4 MB)
- NVRAM: 128 KB
- 1 Serial link
- 2 Ethernet 10 BaseT Channels
On power-up the processor jumps to the address of 0x02000100
Thus, U-Boot is configured to reside in flash starting at the address of
0x02001000. The environment space is located in NVRAM separately from
U-Boot, at the address of 0x03000000.
=============================================================================
U-Boot test results
=============================================================================
##################################################
# Operation on the serial console (SMC1)
##############################
U-Boot 0.2.2 (Jan 19 2003 - 11:08:39)
CPU: XPC860xxZPnnB at 50 MHz: 4 kB I-Cache 4 kB D-Cache FEC present
*** Warning: CPU Core has Silicon Bugs -- Check the Errata ***
Board: ### No HW ID - assuming ELPT860
DRAM: 16 MB
FLASH: 512 kB
In: serial
Out: serial
Err: serial
Net: SCC ETHERNET
Type "run nfsboot" to mount root filesystem over NFS
Hit any key to stop autoboot: 0
LEOX_elpt860: help
askenv - get environment variables from stdin
autoscr - run script from memory
base - print or set address offset
bdinfo - print Board Info structure
bootm - boot application image from memory
bootp - boot image via network using BootP/TFTP protocol
bootd - boot default, i.e., run 'bootcmd'
cmp - memory compare
coninfo - print console devices and informations
cp - memory copy
crc32 - checksum calculation
echo - echo args to console
erase - erase FLASH memory
flinfo - print FLASH memory information
go - start application at address 'addr'
help - print online help
iminfo - print header information for application image
loadb - load binary file over serial line (kermit mode)
loads - load S-Record file over serial line
loop - infinite loop on address range
md - memory display
mm - memory modify (auto-incrementing)
mtest - simple RAM test
mw - memory write (fill)
nm - memory modify (constant address)
printenv- print environment variables
protect - enable or disable FLASH write protection
rarpboot- boot image via network using RARP/TFTP protocol
reset - Perform RESET of the CPU
run - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv - set environment variables
sleep - delay execution for some time
tftpboot- boot image via network using TFTP protocol
and env variables ipaddr and serverip
version - print monitor version
? - alias for 'help'
##################################################
# Environment Variables (CFG_ENV_IS_IN_NVRAM)
##############################
LEOX_elpt860: printenv
bootdelay=5
loads_echo=1
baudrate=9600
stdin=serial
stdout=serial
stderr=serial
ethaddr=00:03:ca:00:64:df
ipaddr=192.168.0.30
netmask=255.255.255.0
serverip=192.168.0.1
nfsserverip=192.168.0.1
preboot=echo;echo Type "run nfsboot" to mount root filesystem over NFS;echo
gatewayip=192.168.0.1
ramargs=setenv bootargs root=/dev/ram rw
rootargs=setenv rootpath /tftp/$(ipaddr)
nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=$(nfsserverip):$(rootpath)
addip=setenv bootargs $(bootargs) ip=$(ipaddr):$(nfsserverip):$(gatewayip):$(netmask):$(hostname):eth0:
ramboot=tftp 400000 /home/leox/pMulti;run ramargs;bootm
nfsboot=tftp 400000 /home/leox/uImage;run rootargs;run nfsargs;run addip;bootm
bootcmd=run ramboot
clocks_in_mhz=1
Environment size: 730/16380 bytes
##################################################
# Flash Memory Information
##############################
LEOX_elpt860: flinfo
Bank # 1: AMD AM29F040 (4 Mbits)
Size: 512 KB in 8 Sectors
Sector Start Addresses:
02000000 (RO) 02010000 (RO) 02020000 (RO) 02030000 (RO) 02040000
02050000 02060000 02070000
##################################################
# Board Information Structure
##############################
LEOX_elpt860: bdinfo
memstart = 0x00000000
memsize = 0x01000000
flashstart = 0x02000000
flashsize = 0x00080000
flashoffset = 0x00030000
sramstart = 0x00000000
sramsize = 0x00000000
immr_base = 0xFF000000
bootflags = 0x00000001
intfreq = 50 MHz
busfreq = 50 MHz
ethaddr = 00:03:ca:00:64:df
IP addr = 192.168.0.30
baudrate = 9600 bps
##################################################
# Image Download and run over serial port
# hello_world (S-Record image)
# ===> 1) Enter "loads" command into U-Boot monitor
# ===> 2) From TeraTerm's bar menu, Select 'File/Send file...'
# Then select 'hello_world.srec' with the file browser
##############################
U-Boot 0.2.2 (Jan 19 2003 - 11:08:39)
CPU: XPC860xxZPnnB at 50 MHz: 4 kB I-Cache 4 kB D-Cache FEC present
*** Warning: CPU Core has Silicon Bugs -- Check the Errata ***
Board: ### No HW ID - assuming ELPT860
DRAM: 16 MB
FLASH: 512 kB
In: serial
Out: serial
Err: serial
Net: SCC ETHERNET
Type "run nfsboot" to mount root filesystem over NFS
Hit any key to stop autoboot: 0
LEOX_elpt860: loads
## Ready for S-Record download ...
S804040004F3050154000501709905014C000501388D
## First Load Addr = 0x00040000
## Last Load Addr = 0x0005018B
## Total Size = 0x0001018C = 65932 Bytes
## Start Addr = 0x00040004
LEOX_elpt860: go 40004 This is a test !!!
## Starting application at 0x00040004 ...
Hello World
argc = 6
argv[0] = "40004"
argv[1] = "This"
argv[2] = "is"
argv[3] = "a"
argv[4] = "test"
argv[5] = "!!!"
argv[6] = "<NULL>"
Hit any key to exit ...
## Application terminated, rc = 0x0
##################################################
# Image download and run over ethernet interface
# Linux-2.4.4 (uImage) + Root filesystem mounted over NFS
##############################
U-Boot 0.2.2 (Jan 19 2003 - 11:08:39)
CPU: XPC860xxZPnnB at 50 MHz: 4 kB I-Cache 4 kB D-Cache FEC present
*** Warning: CPU Core has Silicon Bugs -- Check the Errata ***
Board: ### No HW ID - assuming ELPT860
DRAM: 16 MB
FLASH: 512 kB
In: serial
Out: serial
Err: serial
Net: SCC ETHERNET
Type "run nfsboot" to mount root filesystem over NFS
Hit any key to stop autoboot: 0
LEOX_elpt860: run nfsboot
ARP broadcast 1
TFTP from server 192.168.0.1; our IP address is 192.168.0.30
Filename '/home/leox/uImage'.
Load address: 0x400000
Loading: #################################################################
#############################
done
Bytes transferred = 477294 (7486e hex)
## Booting image at 00400000 ...
Image Name: Linux-2.4.4
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 477230 Bytes = 466 kB = 0 MB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
Linux version 2.4.4-rthal5 (leox@p5ak6650) (gcc version 2.95.3 20010315 (release/MontaVista)) #1 Wed Jul 3 10:23:53 CEST 2002
On node 0 totalpages: 4096
zone(0): 4096 pages.
zone(1): 0 pages.
zone(2): 0 pages.
Kernel command line: root=/dev/nfs rw nfsroot=192.168.0.1:/tftp/192.168.0.30 ip=192.168.0.30:192.168.0.1:192.168.0.1:255.255.255.0::eth0:
rtsched version <20010618.1050.24>
Decrementer Frequency: 3125000
Warning: real time clock seems stuck!
Calibrating delay loop... 49.76 BogoMIPS
Memory: 14720k available (928k kernel code, 384k data, 44k init, 0k highmem)
Dentry-cache hash table entries: 2048 (order: 2, 16384 bytes)
Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 1024 (order: 1, 8192 bytes)
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Starting kswapd v1.8
CPM UART driver version 0.03
ttyS0 on SMC1 at 0x0280, BRG1
block: queued sectors max/low 9701kB/3233kB, 64 slots per queue
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
eth0: CPM ENET Version 0.2 on SCC1, 00:03:ca:00:64:df
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 1024 bind 1024)
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
Looking up port of RPC 100003/2 on 192.168.0.1
Looking up port of RPC 100005/2 on 192.168.0.1
VFS: Mounted root (nfs filesystem).
Freeing unused kernel memory: 44k init
INIT: version 2.78 booting
Welcome to DENX Embedded Linux Environment
Press 'I' to enter interactive startup.
Mounting proc filesystem: [ OK ]
Configuring kernel parameters: [ OK ]
Cannot access the Hardware Clock via any known method.
Use the --debug option to see the details of our search for an access method.
Setting clock : Wed Dec 31 19:00:11 EST 1969 [ OK ]
Activating swap partitions: [ OK ]
Setting hostname 192.168.0.30: [ OK ]
Finding module dependencies:
[ OK ]
Checking filesystems
Checking all file systems.
[ OK ]
Mounting local filesystems: [ OK ]
Enabling swap space: [ OK ]
INIT: Entering runlevel: 3
Entering non-interactive startup
Starting system logger: [ OK ]
Starting kernel logger: [ OK ]
Starting xinetd: [ OK ]
192 login: root
Last login: Wed Dec 31 19:00:41 on ttyS0
bash-2.04#
##################################################
# Image download and run over ethernet interface
# Linux-2.4.4 + Root filesystem mounted from RAM (pMulti)
##############################
U-Boot 0.2.2 (Jan 19 2003 - 11:08:39)
CPU: XPC860xxZPnnB at 50 MHz: 4 kB I-Cache 4 kB D-Cache FEC present
*** Warning: CPU Core has Silicon Bugs -- Check the Errata ***
Board: ### No HW ID - assuming ELPT860
DRAM: 16 MB
FLASH: 512 kB
In: serial
Out: serial
Err: serial
Net: SCC ETHERNET
Type "run nfsboot" to mount root filesystem over NFS
Hit any key to stop autoboot: 0
LEOX_elpt860: run ramboot
ARP broadcast 1
TFTP from server 192.168.0.1; our IP address is 192.168.0.30
Filename '/home/leox/pMulti'.
Load address: 0x400000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
########################################################
done
Bytes transferred = 1947816 (1db8a8 hex)
## Booting image at 00400000 ...
Image Name: linux-2.4.4-2002-03-21 Multiboot
Image Type: PowerPC Linux Multi-File Image (gzip compressed)
Data Size: 1947752 Bytes = 1902 kB = 1 MB
Load Address: 00000000
Entry Point: 00000000
Contents:
Image 0: 477230 Bytes = 466 kB = 0 MB
Image 1: 1470508 Bytes = 1436 kB = 1 MB
Verifying Checksum ... OK
Uncompressing Multi-File Image ... OK
Loading Ramdisk to 00e44000, end 00fab02c ... OK
Linux version 2.4.4-rthal5 (leox@p5ak6650) (gcc version 2.95.3 20010315 (release/MontaVista)) #1 Wed Jul 3 10:23:53 CEST 2002
On node 0 totalpages: 4096
zone(0): 4096 pages.
zone(1): 0 pages.
zone(2): 0 pages.
Kernel command line: root=/dev/ram rw
rtsched version <20010618.1050.24>
Decrementer Frequency: 3125000
Warning: real time clock seems stuck!
Calibrating delay loop... 49.76 BogoMIPS
Memory: 13280k available (928k kernel code, 384k data, 44k init, 0k highmem)
Dentry-cache hash table entries: 2048 (order: 2, 16384 bytes)
Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 1024 (order: 1, 8192 bytes)
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Starting kswapd v1.8
CPM UART driver version 0.03
ttyS0 on SMC1 at 0x0280, BRG1
block: queued sectors max/low 8741kB/2913kB, 64 slots per queue
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
eth0: CPM ENET Version 0.2 on SCC1, 00:03:ca:00:64:df
RAMDISK: Compressed image found at block 0
Freeing initrd memory: 1436k freed
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 1024 bind 1024)
IP-Config: Incomplete network configuration information.
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
VFS: Mounted root (ext2 filesystem).
Freeing unused kernel memory: 44k iné
init started: BusyBox v0.60.2 (2002.07.01-12:06+0000) multi-call Configuring hostname
Configuring lo...
Configuring eth0...
Configuring Gateway...
Please press Enter to activate this console.
ELPT860 login: root
Password:
Welcome to Linux-2.4.4 for ELPT CPU board (MPC860T @ 50MHz)
a8888b.
d888888b.
8P"YP"Y88
_ _ 8|o||o|88
| | |_| 8' .88
| | _ ____ _ _ _ _ 8`._.' Y8.
| | | | _ \| | | |\ \/ / d/ `8b.
| |___ | | | | | |_| |/ \ .dP . Y8b.
|_____||_|_| |_|\____|\_/\_/ d8:' " `::88b.
d8" `Y88b
:8P ' :888
8a. : _a88P
._/"Yaa_ : .| 88P|
\ YP" `| 8P `.
/ \._____.d| .'
`--..__)888888P`._.'
login[21]: root login on `ttyS0'
BusyBox v0.60.3 (2002.07.20-10:39+0000) Built-in shell (ash)
Enter 'help' for a list of built-in commands.
root@ELPT860:~ #

View File

@@ -0,0 +1,36 @@
#######################################################################
#
# Copyright (C) 2000, 2001, 2002, 2003
# The LEOX team <team@leox.org>, http://www.leox.org
#
# LEOX.org is about the development of free hardware and software resources
# for system on chip.
#
# Description: U-Boot port on the LEOX's ELPT860 CPU board
# ~~~~~~~~~~~
#
#######################################################################
#
# 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
#
#######################################################################
#
# ELPT860 board
#
TEXT_BASE = 0x02000000
#TEXT_BASE = 0x00FB0000

View File

@@ -0,0 +1,399 @@
/*
**=====================================================================
**
** Copyright (C) 2000, 2001, 2002, 2003
** The LEOX team <team@leox.org>, http://www.leox.org
**
** LEOX.org is about the development of free hardware and software resources
** for system on chip.
**
** Description: U-Boot port on the LEOX's ELPT860 CPU board
** ~~~~~~~~~~~
**
**=====================================================================
**
** 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
**
**=====================================================================
*/
/*
** Note 1: In this file, you have to provide the following functions:
** ------
** int board_pre_init(void)
** int checkboard(void)
** long int initdram(int board_type)
** called from 'board_init_f()' into 'common/board.c'
**
** void reset_phy(void)
** called from 'board_init_r()' into 'common/board.c'
*/
#include <common.h>
#include <mpc8xx.h>
/* ------------------------------------------------------------------------- */
static long int dram_size (long int, long int *, long int);
/* ------------------------------------------------------------------------- */
#define _NOT_USED_ 0xFFFFFFFF
const uint init_sdram_table[] =
{
/*
* Single Read. (Offset 0 in UPMA RAM)
*/
0x0FFCCC04, 0xFFFFFC04, 0x0FFC3C04, 0xFFFFFC04,
0xFFFFFC04, /* last */
/*
* SDRAM Initialization (offset 5 in UPMA RAM)
*
* This is no UPM entry point. The following definition uses
* the remaining space to establish an initialization
* sequence, which is executed by a RUN command.
*
*/
0xFFFFFC04, 0xFFFFFC04, 0x0FFC3C04, /* last */
/*
* Burst Read. (Offset 8 in UPMA RAM)
*/
0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
0x0FFC3C04, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
0xFFFFFC04, 0x0FFC3C04, 0xFFFFFC04, 0xFFFFFC04,
0xFFFFFC04, 0xFFFFFC04, 0x0FFC3C04, 0xFFFFFC04, /* last */
/*
* Single Write. (Offset 18 in UPMA RAM)
*/
0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04, 0x0FFC3C04,
0xFFFFFC04, 0xFFFFFC04, 0x0FFFFC04, 0xFFFFFC04, /* last */
/*
* Burst Write. (Offset 20 in UPMA RAM)
*/
0x0FFC3C04, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
0xFFFFFC04, 0x0FFC3C04, 0xFFFFFC04, 0xFFFFFC04,
0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC34, 0x0FAC0C34,
0xFFFFFC05, 0xFFFFFC04, 0x0FFCFC04, 0xFFFFFC05, /* last */
};
const uint sdram_table[] =
{
/*
* Single Read. (Offset 0 in UPMA RAM)
*/
0x0F0FFC24, 0x0F0CFC04, 0xFF0FFC04, 0x00AF3C04,
0xFF0FFC00, /* last */
/*
* SDRAM Initialization (offset 5 in UPMA RAM)
*
* This is no UPM entry point. The following definition uses
* the remaining space to establish an initialization
* sequence, which is executed by a RUN command.
*
*/
0x0FFCCC04, 0xFFAFFC05, 0xFFAFFC05, /* last */
/*
* Burst Read. (Offset 8 in UPMA RAM)
*/
0x0F0FFC24, 0x0F0CFC04, 0xFF0FFC04, 0x00AF3C04,
0xF00FFC00, 0xF00FFC00, 0xF00FFC00, 0xFF0FFC00,
0x0FFCCC04, 0xFFAFFC05, 0xFFAFFC04, 0xFFAFFC04,
0xFFAFFC04, 0xFFAFFC04, 0xFFAFFC04, 0xFFAFFC04, /* last */
/*
* Single Write. (Offset 18 in UPMA RAM)
*/
0x0F0FFC24, 0x0F0CFC04, 0xFF0FFC04, 0x00AF0C00,
0xFF0FFC04, 0x0FFCCC04, 0xFFAFFC05, /* last */
_NOT_USED_,
/*
* Burst Write. (Offset 20 in UPMA RAM)
*/
0x0F0FFC24, 0x0F0CFC04, 0xFF0FFC00, 0x00AF0C00,
0xF00FFC00, 0xF00FFC00, 0xF00FFC04, 0x0FFCCC04,
0xFFAFFC04, 0xFFAFFC05, 0xFFAFFC04, 0xFFAFFC04,
0xFFAFFC04, 0xFFAFFC04, 0xFFAFFC04, 0xFFAFFC04, /* last */
/*
* Refresh (Offset 30 in UPMA RAM)
*/
0x0FFC3C04, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
0xFFFFFC05, 0xFFFFFC04, 0xFFFFFC05, _NOT_USED_,
0xFFAFFC04, 0xFFAFFC04, 0xFFAFFC04, 0xFFAFFC04, /* last */
/*
* Exception. (Offset 3c in UPMA RAM)
*/
0x0FFFFC34, 0x0FAC0C34, 0xFFFFFC05, 0xFFAFFC04, /* last */
};
/* ------------------------------------------------------------------------- */
#define CFG_PC4 0x0800
#define CFG_DS1 CFG_PC4
/*
* Very early board init code (fpga boot, etc.)
*/
int
board_pre_init (void)
{
volatile immap_t *immr = (immap_t *) CFG_IMMR;
/*
* Light up the red led on ELPT860 pcb (DS1) (PCDAT)
*/
immr->im_ioport.iop_pcdat &= ~CFG_DS1; /* PCDAT (DS1 = 0) */
immr->im_ioport.iop_pcpar &= ~CFG_DS1; /* PCPAR (0=general purpose I/O) */
immr->im_ioport.iop_pcdir |= CFG_DS1; /* PCDIR (I/O: 0=input, 1=output) */
return ( 0 ); /* success */
}
/*
* Check Board Identity:
*
* Test ELPT860 ID string
*
* Return 1 if no second DRAM bank, otherwise returns 0
*/
int
checkboard (void)
{
unsigned char *s = getenv("serial#");
if ( !s || strncmp(s, "ELPT860", 7) )
printf ("### No HW ID - assuming ELPT860\n");
return ( 0 ); /* success */
}
/* ------------------------------------------------------------------------- */
long int
initdram (int board_type)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
long int size8, size9;
long int size_b0 = 0;
/*
* This sequence initializes SDRAM chips on ELPT860 board
*/
upmconfig(UPMA, (uint *)init_sdram_table,
sizeof(init_sdram_table)/sizeof(uint));
memctl->memc_mptpr = 0x0200;
memctl->memc_mamr = 0x18002111;
memctl->memc_mar = 0x00000088;
memctl->memc_mcr = 0x80002000; /* CS1: SDRAM bank 0 */
upmconfig(UPMA, (uint *)sdram_table,
sizeof(sdram_table)/sizeof(uint));
/*
* Preliminary prescaler for refresh (depends on number of
* banks): This value is selected for four cycles every 62.4 us
* with two SDRAM banks or four cycles every 31.2 us with one
* bank. It will be adjusted after memory sizing.
*/
memctl->memc_mptpr = CFG_MPTPR_2BK_8K;
/*
* The following value is used as an address (i.e. opcode) for
* the LOAD MODE REGISTER COMMAND during SDRAM initialisation. If
* the port size is 32bit the SDRAM does NOT "see" the lower two
* address lines, i.e. mar=0x00000088 -> opcode=0x00000022 for
* MICRON SDRAMs:
* -> 0 00 010 0 010
* | | | | +- Burst Length = 4
* | | | +----- Burst Type = Sequential
* | | +------- CAS Latency = 2
* | +----------- Operating Mode = Standard
* +-------------- Write Burst Mode = Programmed Burst Length
*/
memctl->memc_mar = 0x00000088;
/*
* Map controller banks 2 and 3 to the SDRAM banks 2 and 3 at
* preliminary addresses - these have to be modified after the
* SDRAM size has been determined.
*/
memctl->memc_or1 = CFG_OR1_PRELIM;
memctl->memc_br1 = CFG_BR1_PRELIM;
memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
udelay (200);
/* perform SDRAM initializsation sequence */
memctl->memc_mcr = 0x80002105; /* CS1: SDRAM bank 0 */
udelay (1);
memctl->memc_mcr = 0x80002230; /* CS1: SDRAM bank 0 - execute twice */
udelay (1);
memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
udelay (1000);
/*
* Check Bank 0 Memory Size for re-configuration
*
* try 8 column mode
*/
size8 = dram_size (CFG_MAMR_8COL,
(ulong *) SDRAM_BASE1_PRELIM,
SDRAM_MAX_SIZE);
udelay (1000);
/*
* try 9 column mode
*/
size9 = dram_size (CFG_MAMR_9COL,
(ulong *) SDRAM_BASE1_PRELIM,
SDRAM_MAX_SIZE);
if ( size8 < size9 ) /* leave configuration at 9 columns */
{
size_b0 = size9;
/* debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20); */
}
else /* back to 8 columns */
{
size_b0 = size8;
memctl->memc_mamr = CFG_MAMR_8COL;
udelay (500);
/* debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20); */
}
udelay (1000);
/*
* Adjust refresh rate depending on SDRAM type, both banks
* For types > 128 MBit leave it at the current (fast) rate
*/
if ( size_b0 < 0x02000000 )
{
/* reduce to 15.6 us (62.4 us / quad) */
memctl->memc_mptpr = CFG_MPTPR_2BK_4K;
udelay (1000);
}
/*
* Final mapping: map bigger bank first
*/
memctl->memc_or1 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
memctl->memc_br1 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
{
unsigned long reg;
/* adjust refresh rate depending on SDRAM type, one bank */
reg = memctl->memc_mptpr;
reg >>= 1; /* reduce to CFG_MPTPR_1BK_8K / _4K */
memctl->memc_mptpr = reg;
}
udelay(10000);
return (size_b0);
}
/* ------------------------------------------------------------------------- */
/*
* Check memory range for valid RAM. A simple memory test determines
* the actually available RAM size between addresses `base' and
* `base + maxsize'. Some (not all) hardware errors are detected:
* - short between address lines
* - short between data lines
*/
static long int
dram_size (long int mamr_value,
long int *base,
long int maxsize)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
volatile long int *addr;
ulong cnt, val;
ulong save[32]; /* to make test non-destructive */
unsigned char i = 0;
memctl->memc_mamr = mamr_value;
for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1)
{
addr = base + cnt; /* pointer arith! */
save[i++] = *addr;
*addr = ~cnt;
}
/* write 0 to base address */
addr = base;
save[i] = *addr;
*addr = 0;
/* check at base address */
if ( (val = *addr) != 0 )
{
*addr = save[i];
return (0);
}
for (cnt = 1; cnt <= maxsize/sizeof(long); cnt <<= 1)
{
addr = base + cnt; /* pointer arith! */
val = *addr;
*addr = save[--i];
if ( val != (~cnt) )
{
return (cnt * sizeof(long));
}
}
return (maxsize);
}
/* ------------------------------------------------------------------------- */
#define CFG_PA1 0x4000
#define CFG_PA2 0x2000
#define CFG_LBKs (CFG_PA2 | CFG_PA1)
void
reset_phy (void)
{
volatile immap_t *immr = (immap_t *) CFG_IMMR;
/*
* Ensure LBK LXT901 ethernet 1 & 2 = 0 ... for normal loopback in effect
* and no AUI loopback
*/
immr->im_ioport.iop_padat &= ~CFG_LBKs; /* PADAT (LBK eth 1&2 = 0) */
immr->im_ioport.iop_papar &= ~CFG_LBKs; /* PAPAR (0=general purpose I/O) */
immr->im_ioport.iop_padir |= CFG_LBKs; /* PADIR (I/O: 0=input, 1=output) */
}

615
board/LEOX/elpt860/flash.c Normal file
View File

@@ -0,0 +1,615 @@
/*
**=====================================================================
**
** Copyright (C) 2000, 2001, 2002, 2003
** The LEOX team <team@leox.org>, http://www.leox.org
**
** LEOX.org is about the development of free hardware and software resources
** for system on chip.
**
** Description: U-Boot port on the LEOX's ELPT860 CPU board
** ~~~~~~~~~~~
**
**=====================================================================
**
** 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
**
**=====================================================================
*/
/*
** Note 1: In this file, you have to provide the following variable:
** ------
** flash_info_t flash_info[CFG_MAX_FLASH_BANKS]
** 'flash_info_t' structure is defined into 'include/flash.h'
** and defined as extern into 'common/cmd_flash.c'
**
** Note 2: In this file, you have to provide the following functions:
** ------
** unsigned long flash_init(void)
** called from 'board_init_r()' into 'common/board.c'
**
** void flash_print_info(flash_info_t *info)
** called from 'do_flinfo()' into 'common/cmd_flash.c'
**
** int flash_erase(flash_info_t *info,
** int s_first,
** int s_last)
** called from 'do_flerase()' & 'flash_sect_erase()' into 'common/cmd_flash.c'
**
** int write_buff (flash_info_t *info,
** uchar *src,
** ulong addr,
** ulong cnt)
** called from 'flash_write()' into 'common/cmd_flash.c'
*/
#include <common.h>
#include <mpc8xx.h>
#ifndef CFG_ENV_ADDR
# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
#endif
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*-----------------------------------------------------------------------
* Internal Functions
*/
static void flash_get_offsets (ulong base, flash_info_t *info);
static ulong flash_get_size (volatile unsigned char *addr, flash_info_t *info);
static int write_word (flash_info_t *info, ulong dest, ulong data);
static int write_byte (flash_info_t *info, ulong dest, uchar data);
/*-----------------------------------------------------------------------
*/
unsigned long
flash_init (void)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
unsigned long size_b0;
int i;
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i)
{
flash_info[i].flash_id = FLASH_UNKNOWN;
}
/* Static FLASH Bank configuration here - FIXME XXX */
size_b0 = flash_get_size ((volatile unsigned char *)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);
}
/* Remap FLASH according to real size */
memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & OR_AM_MSK);
memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_PS_8 | BR_V;
/* Re-do sizing to get full correct info */
size_b0 = flash_get_size ((volatile unsigned char *)CFG_FLASH_BASE,
&flash_info[0]);
flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
/* monitor protection ON by default */
flash_protect (FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE + 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]);
#endif
flash_info[0].size = size_b0;
return (size_b0);
}
/*-----------------------------------------------------------------------
*/
static void
flash_get_offsets (ulong base,
flash_info_t *info)
{
int i;
#define SECTOR_64KB 0x00010000
/* set up sector start adress table */
for (i = 0; i < info->sector_count; i++)
{
info->start[i] = base + (i * SECTOR_64KB);
}
}
/*-----------------------------------------------------------------------
*/
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_STM: printf ("STM (Thomson) "); break;
default: printf ("Unknown Vendor "); break;
}
switch ( info->flash_id & FLASH_TYPEMASK )
{
case FLASH_AM040: printf ("AM29F040 (4 Mbits)\n");
break;
default: printf ("Unknown Chip Type\n");
break;
}
printf (" Size: %ld KB in %d Sectors\n",
info->size >> 10, info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i)
{
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
return;
}
/*-----------------------------------------------------------------------
*/
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
static ulong
flash_get_size (volatile unsigned char *addr,
flash_info_t *info)
{
short i;
uchar value;
ulong base = (ulong)addr;
/* Write auto select command: read Manufacturer ID */
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
addr[0x0555] = 0x90;
value = addr[0];
switch ( value )
{
/* case AMD_MANUFACT: */
case 0x01:
info->flash_id = FLASH_MAN_AMD;
break;
/* case FUJ_MANUFACT: */
case 0x04:
info->flash_id = FLASH_MAN_FUJ;
break;
/* case STM_MANUFACT: */
case 0x20:
info->flash_id = FLASH_MAN_STM;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* no or unknown flash */
}
value = addr[1]; /* device ID */
switch ( value )
{
case STM_ID_F040B:
case AMD_ID_F040B:
info->flash_id += FLASH_AM040; /* 4 Mbits = 512k * 8 */
info->sector_count = 8;
info->size = 0x00080000;
break;
default:
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
}
/* set up sector start adress table */
for (i = 0; i < info->sector_count; i++)
{
info->start[i] = base + (i * 0x00010000);
}
/* check for protected sectors */
for (i = 0; i < info->sector_count; i++)
{
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
/* D0 = 1 if protected */
addr = (volatile unsigned char *)(info->start[i]);
info->protect[i] = addr[2] & 1;
}
/*
* Prevent writes to uninitialized FLASH.
*/
if ( info->flash_id != FLASH_UNKNOWN )
{
addr = (volatile unsigned char *)info->start[0];
*addr = 0xF0; /* reset bank */
}
return (info->size);
}
/*-----------------------------------------------------------------------
*/
int
flash_erase (flash_info_t *info,
int s_first,
int s_last)
{
volatile unsigned char *addr = (volatile unsigned char *)(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[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
addr[0x0555] = 0x80;
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++)
{
if (info->protect[sect] == 0) /* not protected */
{
addr = (volatile unsigned char *)(info->start[sect]);
addr[0] = 0x30;
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 = (volatile unsigned char *)(info->start[l_sect]);
while ( (addr[0] & 0x80) != 0x80 )
{
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 = (volatile unsigned char *)info->start[0];
addr[0] = 0xF0; /* 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;
uchar bdata;
int i, l, rc;
if ( (info->flash_id & FLASH_TYPEMASK) == FLASH_AM040 )
{
/* Width of the data bus: 8 bits */
wp = addr;
while ( cnt )
{
bdata = *src++;
if ( (rc = write_byte(info, wp, bdata)) != 0 )
{
return (rc);
}
++wp;
--cnt;
}
return ( 0 );
}
else
{
/* Width of the data bus: 32 bits */
wp = (addr & ~3); /* get lower word aligned address */
/*
* handle unaligned start bytes
*/
if ( (l = addr - wp) != 0 )
{
data = 0;
for (i=0, cp=wp; i<l; ++i, ++cp)
{
data = (data << 8) | (*(uchar *)cp);
}
for (; i<4 && cnt>0; ++i)
{
data = (data << 8) | *src++;
--cnt;
++cp;
}
for (; cnt==0 && i<4; ++i, ++cp)
{
data = (data << 8) | (*(uchar *)cp);
}
if ( (rc = write_word(info, wp, data)) != 0 )
{
return (rc);
}
wp += 4;
}
/*
* handle word aligned part
*/
while ( cnt >= 4 )
{
data = 0;
for (i=0; i<4; ++i)
{
data = (data << 8) | *src++;
}
if ( (rc = write_word(info, wp, data)) != 0 )
{
return (rc);
}
wp += 4;
cnt -= 4;
}
if ( cnt == 0 )
{
return (0);
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp)
{
data = (data << 8) | *src++;
--cnt;
}
for (; i<4; ++i, ++cp)
{
data = (data << 8) | (*(uchar *)cp);
}
return (write_word(info, wp, data));
}
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int
write_word (flash_info_t *info,
ulong dest,
ulong data)
{
vu_long *addr = (vu_long*)(info->start[0]);
ulong start;
int flag;
/* Check if Flash is (sufficiently) erased */
if ( (*((vu_long *)dest) & data) != data )
{
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[0x0555] = 0x00AA00AA;
addr[0x02AA] = 0x00550055;
addr[0x0555] = 0x00A000A0;
*((vu_long *)dest) = data;
/* re-enable interrupts if necessary */
if ( flag )
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
while ( (*((vu_long *)dest) & 0x00800080) != (data & 0x00800080) )
{
if ( get_timer(start) > CFG_FLASH_WRITE_TOUT )
{
return (1);
}
}
return (0);
}
/*-----------------------------------------------------------------------
* Write a byte to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int
write_byte (flash_info_t *info,
ulong dest,
uchar data)
{
volatile unsigned char *addr = (volatile unsigned char *)(info->start[0]);
ulong start;
int flag;
/* Check if Flash is (sufficiently) erased */
if ( (*((volatile unsigned char *)dest) & data) != data )
{
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
addr[0x0555] = 0xA0;
*((volatile unsigned char *)dest) = data;
/* re-enable interrupts if necessary */
if ( flag )
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
while ( (*((volatile unsigned char *)dest) & 0x80) != (data & 0x80) )
{
if ( get_timer(start) > CFG_FLASH_WRITE_TOUT )
{
return (1);
}
}
return (0);
}
/*-----------------------------------------------------------------------
*/

View File

@@ -0,0 +1,146 @@
/*
**=====================================================================
**
** Copyright (C) 2000, 2001, 2002, 2003
** The LEOX team <team@leox.org>, http://www.leox.org
**
** LEOX.org is about the development of free hardware and software resources
** for system on chip.
**
** Description: U-Boot port on the LEOX's ELPT860 CPU board
** ~~~~~~~~~~~
**
**=====================================================================
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License as
** published by the Free Software Foundation; either version 2 of
** the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307 USA
**
**=====================================================================
*/
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
.text :
{
/* WARNING - the following is hand-optimized to fit within */
/* the sector layout of our flash chips! XXX FIXME XXX */
cpu/mpc8xx/start.o (.text)
common/dlmalloc.o (.text)
lib_ppc/ppcstring.o (.text)
lib_generic/vsprintf.o (.text)
lib_generic/crc32.o (.text)
lib_generic/zlib.o (.text)
lib_generic/string.o (.text)
lib_ppc/cache.o (.text)
lib_ppc/extable.o (.text)
lib_ppc/time.o (.text)
lib_ppc/ticks.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: */
. = (. + 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,140 @@
/*
**=====================================================================
**
** Copyright (C) 2000, 2001, 2002, 2003
** The LEOX team <team@leox.org>, http://www.leox.org
**
** LEOX.org is about the development of free hardware and software resources
** for system on chip.
**
** Description: U-Boot port on the LEOX's ELPT860 CPU board
** ~~~~~~~~~~~
**
**=====================================================================
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License as
** published by the Free Software Foundation; either version 2 of
** the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307 USA
**
**=====================================================================
*/
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
.text :
{
/* WARNING - the following is hand-optimized to fit within */
/* the sector layout of our flash chips! XXX FIXME XXX */
cpu/mpc8xx/start.o (.text)
common/dlmalloc.o (.text)
lib_generic/vsprintf.o (.text)
lib_generic/crc32.o (.text)
. = env_offset;
common/environment.o (.text)
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x0FFF) & 0xFFFFF000;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(4096);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(4096);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

View File

@@ -0,0 +1 @@
This file is just to ensure that the directory is created.

View File

@@ -0,0 +1 @@
This file is just to ensure that the directory is created.

Binary file not shown.

View File

@@ -0,0 +1,47 @@
#
# (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 := at91rm9200dk.o flash.o
SOBJS :=
$(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,105 @@
/*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/arch/AT91RM9200.h>
/* ------------------------------------------------------------------------- */
/*
* Miscelaneous platform dependent initialisations
*/
int board_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
/* memory and cpu-speed are setup before relocation */
/* so we do _nothing_ here */
/* arch number of AT91RM9200DK-Board */
gd->bd->bi_arch_number = 251;
/* adress of boot parameters */
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
return 0;
}
int dram_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
gd->bd->bi_dram[0].start = PHYS_SDRAM;
gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE;
return 0;
}
/*
* Disk On Chip (NAND) Millenium initialization.
* The NAND lives in the CS2* space
*/
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
extern void
nand_probe(ulong physadr);
#define AT91_SMARTMEDIA_BASE 0x40000000 /* physical address to access memory on NCS3 */
void
nand_init(void)
{
/* Setup Smart Media, fitst enable the address range of CS3 */
*AT91C_EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia;
/* set the bus interface characteristics based on
tDS Data Set up Time 30 - ns
tDH Data Hold Time 20 - ns
tALS ALE Set up Time 20 - ns
16ns at 60 MHz ~= 3 */
/*memory mapping structures */
#define SM_ID_RWH (5 << 28)
#define SM_RWH (1 << 28)
#define SM_RWS (0 << 24)
#define SM_TDF (1 << 8)
#define SM_NWS (3)
AT91C_BASE_SMC2->SMC2_CSR[3] = ( SM_RWH|SM_RWS | AT91C_SMC2_ACSS_STANDARD |
AT91C_SMC2_DBW_8 | SM_TDF |
AT91C_SMC2_WSEN | SM_NWS);
/* enable the SMOE line PC0=SMCE, A21=CLE, A22=ALE */
*AT91C_PIOC_ASR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE;
*AT91C_PIOC_PDR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE;
/* Configure PC2 as input (signal READY of the SmartMedia) */
*AT91C_PIOC_PER = AT91C_PC2_BFAVD; /* enable direct output enable */
*AT91C_PIOC_ODR = AT91C_PC2_BFAVD; /* disable output */
/* Configure PB1 as input (signal Card Detect of the SmartMedia) */
*AT91C_PIOB_PER = AT91C_PIO_PB1; /* enable direct output enable */
*AT91C_PIOB_ODR = AT91C_PIO_PB1; /* disable output */
if (*AT91C_PIOB_PDSR & AT91C_PIO_PB1)
printf ("No ");
printf ("SmartMedia card inserted\n");
printf("Probing at 0x%.8x\n", AT91_SMARTMEDIA_BASE);
nand_probe(AT91_SMARTMEDIA_BASE);
}
#endif

View File

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

397
board/at91rm9200dk/flash.c Normal file
View File

@@ -0,0 +1,397 @@
/*
* (C) Copyright 2002
* Lineo, Inc. <www.lineo.com>
* Bernhard Kuhn <bkuhn@lineo.com>
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Alex Zuepke <azu@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>
ulong myflush(void);
#define FLASH_BANK_SIZE 0x200000 /* 2 MB */
#define MAIN_SECT_SIZE 0x10000 /* 64 KB */
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
#define CMD_READ_ARRAY 0x00F0
#define CMD_UNLOCK1 0x00AA
#define CMD_UNLOCK2 0x0055
#define CMD_ERASE_SETUP 0x0080
#define CMD_ERASE_CONFIRM 0x0030
#define CMD_PROGRAM 0x00A0
#define CMD_UNLOCK_BYPASS 0x0020
#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00005555<<1)))
#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00002AAA<<1)))
#define BIT_ERASE_DONE 0x0080
#define BIT_RDY_MASK 0x0080
#define BIT_PROGRAM_ERROR 0x0020
#define BIT_TIMEOUT 0x80000000 /* our flag */
#define READY 1
#define ERR 2
#define TMO 4
/*-----------------------------------------------------------------------
*/
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 =
(ATM_MANUFACT & FLASH_VENDMASK) |
(ATM_ID_BV1614 & FLASH_TYPEMASK);
flash_info[i].size = FLASH_BANK_SIZE;
flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
if (i == 0)
flashbase = PHYS_FLASH_1;
else
panic("configured to many flash banks!\n");
for (j = 0; j < flash_info[i].sector_count; j++)
{
if (j <= 9)
{
/* 1st to 8th are 8 KB */
if (j <= 7)
{
flash_info[i].start[j] = flashbase + j*0x2000;
}
/* 9th and 10th are both 32 KB */
if ((j == 8) || (j == 9))
{
flash_info[i].start[j] = flashbase + 0x10000 + (j-8)*0x8000;
}
}
else
{
flash_info[i].start[j] = flashbase + (j-8)*MAIN_SECT_SIZE;
}
}
size += flash_info[i].size;
}
flash_protect(FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_ENV_ADDR - 1,
&flash_info[0]);
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[0]);
return size;
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
switch (info->flash_id & FLASH_VENDMASK)
{
case (ATM_MANUFACT & FLASH_VENDMASK):
printf("Atmel: ");
break;
default:
printf("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK)
{
case (ATM_ID_BV1614 & FLASH_TYPEMASK):
printf("AT49BV1614 (16Mbit)\n");
break;
default:
printf("Unknown Chip Type\n");
goto Done;
break;
}
printf(" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf(" Sector Start Addresses:");
for (i = 0; i < info->sector_count; i++)
{
if ((i % 5) == 0)
{
printf ("\n ");
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
Done:
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
ulong result;
int iflag, cflag, prot, sect;
int rc = ERR_OK;
int chip1;
/* first look for protection bits */
if (info->flash_id == FLASH_UNKNOWN)
return ERR_UNKNOWN_FLASH_TYPE;
if ((s_first < 0) || (s_first > s_last)) {
return ERR_INVAL;
}
if ((info->flash_id & FLASH_VENDMASK) !=
(ATM_MANUFACT & FLASH_VENDMASK)) {
return ERR_UNKNOWN_FLASH_VENDOR;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot)
return ERR_PROTECTED;
/*
* Disable interrupts which might cause a timeout
* here. Remember that our exception vectors are
* at address 0 in the flash, and we don't want a
* (ticker) exception to happen while the flash
* chip is in programming mode.
*/
cflag = icache_status();
icache_disable();
iflag = disable_interrupts();
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last && !ctrlc(); sect++)
{
printf("Erasing sector %2d ... ", sect);
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
if (info->protect[sect] == 0)
{ /* not protected */
volatile u16 *addr = (volatile u16 *)(info->start[sect]);
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
*addr = CMD_ERASE_CONFIRM;
/* wait until flash is ready */
chip1 = 0;
do
{
result = *addr;
/* check timeout */
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
{
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
chip1 = TMO;
break;
}
if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE)
chip1 = READY;
} while (!chip1);
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
if (chip1 == ERR)
{
rc = ERR_PROG_ERROR;
goto outahere;
}
if (chip1 == TMO)
{
rc = ERR_TIMOUT;
goto outahere;
}
printf("ok.\n");
}
else /* it was protected */
{
printf("protected!\n");
}
}
if (ctrlc())
printf("User Interrupt!\n");
outahere:
/* allow flash to settle - wait 10 ms */
udelay_masked(10000);
if (iflag)
enable_interrupts();
if (cflag)
icache_enable();
return rc;
}
/*-----------------------------------------------------------------------
* Copy memory to flash
*/
volatile static int write_word (flash_info_t *info, ulong dest, ulong data)
{
volatile u16 *addr = (volatile u16 *)dest;
ulong result;
int rc = ERR_OK;
int cflag, iflag;
int chip1;
/*
* Check if Flash is (sufficiently) erased
*/
result = *addr;
if ((result & data) != data)
return ERR_NOT_ERASED;
/*
* Disable interrupts which might cause a timeout
* here. Remember that our exception vectors are
* at address 0 in the flash, and we don't want a
* (ticker) exception to happen while the flash
* chip is in programming mode.
*/
cflag = icache_status();
icache_disable();
iflag = disable_interrupts();
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
MEM_FLASH_ADDR1 = CMD_PROGRAM;
*addr = data;
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
/* wait until flash is ready */
chip1 = 0;
do
{
result = *addr;
/* check timeout */
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
{
chip1 = ERR | TMO;
break;
}
if (!chip1 && ((result & 0x80) == (data & 0x80)))
chip1 = READY;
} while (!chip1);
*addr = CMD_READ_ARRAY;
if (chip1 == ERR || *addr != data)
rc = ERR_PROG_ERROR;
if (iflag)
enable_interrupts();
if (cflag)
icache_enable();
return rc;
}
/*-----------------------------------------------------------------------
* Copy memory to flash.
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong wp, data;
int rc;
if(addr & 1) {
printf("unaligned destination not supported\n");
return ERR_ALIGN;
};
if((int)src & 1) {
printf("unaligned source not supported\n");
return ERR_ALIGN;
};
wp = addr;
while (cnt >= 2) {
data = *((volatile u16*)src);
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
src += 2;
wp += 2;
cnt -= 2;
}
if(cnt == 1) {
data = (*((volatile u8*)src)) | (*((volatile u8*)(wp+1)) << 8);
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
src += 1;
wp += 1;
cnt -= 1;
};
return ERR_OK;
}

View File

@@ -0,0 +1,54 @@
/*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <gj@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_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/at91rm9200/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 = .;
}

47
board/cmi/Makefile Normal file
View File

@@ -0,0 +1,47 @@
#
# (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 := flash.o cmi.o
SOBJS :=
$(LIB): $(OBJS)
$(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
#########################################################################

73
board/cmi/cmi.c Normal file
View File

@@ -0,0 +1,73 @@
/*
* (C) Copyright 2003
* Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* File: cmi.c
*
* Discription: For generic board specific functions
*
*/
#include <common.h>
#include <mpc5xx.h>
#define SRAM_SIZE 1024000L /* 1M RAM available*/
#if defined(__APPLE__)
/* Leading underscore on symbols */
# define SYM_CHAR "_"
#else /* No leading character on symbols */
# define SYM_CHAR
#endif
/*
* Macros to generate global absolutes.
*/
#define GEN_SYMNAME(str) SYM_CHAR #str
#define GEN_VALUE(str) #str
#define GEN_ABS(name, value) \
asm (".globl " GEN_SYMNAME(name)); \
asm (GEN_SYMNAME(name) " = " GEN_VALUE(value))
/*
* Check the board
*/
int checkboard(void)
{
puts ("Board: ### No HW ID - assuming CMI board\n");
return (0);
}
/*
* Get RAM size.
*/
long int initdram(int board_type)
{
return (SRAM_SIZE); /* We currently have a static size adapted for cmi board. */
}
/*
* Absolute environment address for linker file.
*/
GEN_ABS(env_start, CFG_ENV_OFFSET + CFG_FLASH_BASE);

31
board/cmi/config.mk Normal file
View File

@@ -0,0 +1,31 @@
#
# (C) Copyright 2003
# Martin Winistoerfer, martinwinistoerfer@gmx.ch.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
#
# EPQ Board Configuration
#
# Boot from flash at location 0x00000000
TEXT_BASE = 0x02000000
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)

517
board/cmi/flash.c Normal file
View File

@@ -0,0 +1,517 @@
/*
* (C) Copyright 2003
* Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* File: flash.c
*
* Discription: This Driver is for 28F320J3A, 28F640J3A and
* 28F128J3A Intel flashs working in 16 Bit mode.
* They are single bank flashs.
*
* Most of this code is taken from existing u-boot
* source code.
*/
#include <common.h>
#include <mpc5xx.h>
#if defined(CFG_ENV_IS_IN_FLASH)
# ifndef CFG_ENV_ADDR
# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
# endif
# ifndef CFG_ENV_SIZE
# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
# endif
# ifndef CFG_ENV_SECT_SIZE
# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
# endif
#endif
#define FLASH_ID_MASK 0xFFFF
#define FLASH_BLOCK_SIZE 0x00010000
#define FLASH_CMD_READ_ID 0x0090
#define FLASH_CMD_RESET 0x00ff
#define FLASH_CMD_BLOCK_ERASE 0x0020
#define FLASH_CMD_ERASE_CONFIRM 0x00D0
#define FLASH_CMD_CLEAR_STATUS 0x0050
#define FLASH_CMD_SUSPEND_ERASE 0x00B0
#define FLASH_CMD_WRITE 0x0040
#define FLASH_CMD_PROTECT 0x0060
#define FLASH_CMD_PROTECT_SET 0x0001
#define FLASH_CMD_PROTECT_CLEAR 0x00D0
#define FLASH_STATUS_DONE 0x0080
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
/*
* Local function prototypes
*/
static ulong flash_get_size (vu_short *addr, flash_info_t *info);
static int write_short (flash_info_t *info, ulong dest, ushort data);
static void flash_get_offsets (ulong base, flash_info_t *info);
/*
* Initialize flash
*/
unsigned long flash_init (void)
{
unsigned long size_b0;
int i;
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
}
/* Static FLASH Bank configuration here - FIXME XXX */
#if 1
debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_PRELIM);
#endif
size_b0 = flash_get_size((vu_short *)FLASH_BASE0_PRELIM, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank 0: "
"ID 0x%lx, Size = 0x%08lx = %ld MB\n",
flash_info[0].flash_id,
size_b0, size_b0<<20);
}
flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]);
flash_info[0].size = size_b0;
#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_b0;
}
/*
* Compute start adress of each sector (block)
*/
static void flash_get_offsets (ulong base, flash_info_t *info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_INTEL:
for (i = 0; i < info->sector_count; i++) {
info->start[i] = base + i * FLASH_BLOCK_SIZE;
}
return;
default:
printf ("Don't know sector offsets for flash type 0x%lx\n",
info->flash_id);
return;
}
}
/*
* Print flash information
*/
void flash_print_info (flash_info_t *info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD: printf ("AMD "); break;
case FLASH_MAN_FUJ: printf ("Fujitsu "); break;
case FLASH_MAN_SST: printf ("SST "); break;
case FLASH_MAN_STM: printf ("STM "); break;
case FLASH_MAN_INTEL: printf ("Intel "); break;
case FLASH_MAN_MT: printf ("MT "); break;
default: printf ("Unknown Vendor "); break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F320J3A: printf ("28F320J3A (32Mbit) 16-Bit\n");
break;
case FLASH_28F640J3A: printf ("28F640J3A (64Mbit) 16-Bit\n");
break;
case FLASH_28F128J3A: printf ("28F128J3A (128Mbit) 16-Bit\n");
break;
default: printf ("Unknown Chip Type\n");
break;
}
if (info->size >= (1 << 20)) {
i = 20;
} else {
i = 10;
}
printf (" Size: %ld %cB in %d Sectors\n",
info->size >> i,
(i == 20) ? 'M' : 'k',
info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
return;
}
/*
* Get size of flash in bytes.
* The following code cannot be run from FLASH!
*/
static ulong flash_get_size (vu_short *addr, flash_info_t *info)
{
vu_short value;
/* Read Manufacturer ID */
addr[0] = FLASH_CMD_READ_ID;
value = addr[0];
switch (value) {
case (AMD_MANUFACT & FLASH_ID_MASK):
info->flash_id = FLASH_MAN_AMD;
break;
case (FUJ_MANUFACT & FLASH_ID_MASK):
info->flash_id = FLASH_MAN_FUJ;
break;
case (SST_MANUFACT & FLASH_ID_MASK):
info->flash_id = FLASH_MAN_SST;
break;
case (STM_MANUFACT & FLASH_ID_MASK):
info->flash_id = FLASH_MAN_STM;
break;
case (INTEL_MANUFACT & FLASH_ID_MASK):
info->flash_id = FLASH_MAN_INTEL;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
addr[0] = FLASH_CMD_RESET; /* restore read mode */
return (0); /* no or unknown flash */
}
value = addr[1]; /* device ID */
switch (value) {
case (INTEL_ID_28F320J3A & FLASH_ID_MASK):
info->flash_id += FLASH_28F320J3A;
info->sector_count = 32;
info->size = 0x00400000;
break; /* => 32 MBit */
case (INTEL_ID_28F640J3A & FLASH_ID_MASK):
info->flash_id += FLASH_28F640J3A;
info->sector_count = 64;
info->size = 0x00800000;
break; /* => 64 MBit */
case (INTEL_ID_28F128J3A & FLASH_ID_MASK):
info->flash_id += FLASH_28F128J3A;
info->sector_count = 128;
info->size = 0x01000000;
break; /* => 128 MBit */
default:
info->flash_id = FLASH_UNKNOWN;
addr[0] = FLASH_CMD_RESET; /* 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;
}
addr[0] = FLASH_CMD_RESET; /* restore read mode */
return (info->size);
}
/*
* Erase unprotected sectors
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
int flag, prot, sect;
ulong start, now, last;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
printf ("Can erase only Intel flash types - aborted\n");
return 1;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
start = get_timer (0);
last = start;
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
vu_short *addr = (vu_short *)(info->start[sect]);
unsigned long status;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
#ifdef DEBUG
printf("Erase sector %d at start addr 0x%08X", sect, (unsigned int)info->start[sect]);
#endif
*addr = FLASH_CMD_CLEAR_STATUS;
*addr = FLASH_CMD_BLOCK_ERASE;
*addr = FLASH_CMD_ERASE_CONFIRM;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
while (((status = *addr) & FLASH_STATUS_DONE) != FLASH_STATUS_DONE) {
if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf("Flash erase timeout at address %lx\n", info->start[sect]);
*addr = FLASH_CMD_SUSPEND_ERASE;
*addr = FLASH_CMD_RESET;
return 1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc ('.');
last = now;
}
}
*addr = FLASH_CMD_RESET;
}
}
printf (" done\n");
return 0;
}
/*
* 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 i, rc;
if (info->flash_id == FLASH_UNKNOWN) {
return 4;
}
wp = (addr & ~1); /* get lower word aligned address */
/*
* handle unaligned start byte
*/
if (addr - wp) {
data = 0;
data = (data << 8) | *src++;
--cnt;
if ((rc = write_short(info, wp, data)) != 0) {
return (rc);
}
wp += 2;
}
/*
* handle word aligned part
*/
while (cnt >= 2) {
data = 0;
for (i=0; i<2; ++i) {
data = (data << 8) | *src++;
}
if ((rc = write_short(info, wp, data)) != 0) {
return (rc);
}
wp += 2;
cnt -= 2;
}
if (cnt == 0) {
return (0);
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
for (; i<2; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
return (write_short(info, wp, data));
}
/*
* Write 16 bit (short) to flash
*/
static int write_short (flash_info_t *info, ulong dest, ushort data)
{
vu_short *addr = (vu_short*)(info->start[0]);
ulong start;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((*((vu_short *)dest) & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
if (!(info->flash_id & FLASH_VENDMASK)) {
return 4;
}
*addr = FLASH_CMD_ERASE_CONFIRM;
*addr = FLASH_CMD_WRITE;
*((vu_short *)dest) = data;
/* re-enable interrupts if necessary */
if (flag) {
enable_interrupts();
}
/* data polling for D7 */
start = get_timer (0);
/* wait for error or finish */
while(!(addr[0] & FLASH_STATUS_DONE)){
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
addr[0] = FLASH_CMD_RESET;
return (1);
}
}
*addr = FLASH_CMD_RESET;
return (0);
}
/*
* Protects a flash sector
*/
int flash_real_protect(flash_info_t *info, long sector, int prot)
{
vu_short *addr = (vu_short*)(info->start[sector]);
ulong start;
*addr = FLASH_CMD_CLEAR_STATUS;
*addr = FLASH_CMD_PROTECT;
if(prot) {
*addr = FLASH_CMD_PROTECT_SET;
} else {
*addr = FLASH_CMD_PROTECT_CLEAR;
}
/* wait for error or finish */
start = get_timer (0);
while(!(addr[0] & FLASH_STATUS_DONE)){
if (get_timer(start) > CFG_FLASH_ERASE_TOUT) {
printf("Flash protect timeout at address %lx\n", info->start[sector]);
addr[0] = FLASH_CMD_RESET;
return (1);
}
}
/* Set software protect flag */
info->protect[sector] = prot;
*addr = FLASH_CMD_RESET;
return (0);
}

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

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

40
board/cpc45/Makefile Normal file
View File

@@ -0,0 +1,40 @@
#
# (C) Copyright 2001-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 plx9030.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
#########################################################################

36
board/cpc45/config.mk Normal file
View File

@@ -0,0 +1,36 @@
#
# (C) Copyright 2001-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
#
#
# CPC45 board
#
ifeq ($(CONFIG_BOOT_ROM),y)
TEXT_BASE := 0xFFF00000
PLATFORM_CPPFLAGS += -DCONFIG_BOOT_ROM
else
TEXT_BASE := 0xFFF00000
endif
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)

173
board/cpc45/cpc45.c Normal file
View File

@@ -0,0 +1,173 @@
/*
* (C) Copyright 2001
* Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <mpc824x.h>
#include <asm/processor.h>
#include <pci.h>
int sysControlDisplay(int digit, uchar ascii_code);
extern void Plx9030Init(void);
/* We have to clear the initial data area here. Couldn't have done it
* earlier because DRAM had not been initialized.
*/
int board_pre_init(void)
{
/* enable DUAL UART Mode on CPC45 */
*(uchar*)DUART_DCR |= 0x1; /* set DCM bit */
return 0;
}
int checkboard(void)
{
/*
char revision = BOARD_REV;
*/
ulong busfreq = get_bus_freq(0);
char buf[32];
printf("CPC45 ");
/*
printf("Revision %d ", revision);
*/
printf("Local Bus at %s MHz\n", strmhz(buf, busfreq));
return 0;
}
long int initdram(int board_type)
{
int i, cnt;
volatile uchar * base = CFG_SDRAM_BASE;
volatile ulong * addr;
ulong save[32];
ulong val, ret = 0;
for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
addr = (volatile ulong *)base + cnt;
save[i++] = *addr;
*addr = ~cnt;
}
addr = (volatile ulong *)base;
save[i] = *addr;
*addr = 0;
if (*addr != 0) {
*addr = save[i];
goto Done;
}
for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1) {
addr = (volatile ulong *)base + cnt;
val = *addr;
*addr = save[--i];
if (val != ~cnt) {
ulong new_bank0_end = cnt * sizeof(long) - 1;
ulong mear1 = mpc824x_mpc107_getreg(MEAR1);
ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
mear1 = (mear1 & 0xFFFFFF00) |
((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
emear1 = (emear1 & 0xFFFFFF00) |
((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
mpc824x_mpc107_setreg(MEAR1, mear1);
mpc824x_mpc107_setreg(EMEAR1, emear1);
ret = cnt * sizeof(long);
goto Done;
}
}
ret = CFG_MAX_RAM_SIZE;
Done:
return ret;
}
/*
* Initialize PCI Devices, report devices found.
*/
#ifndef CONFIG_PCI_PNP
static struct pci_config_table pci_sandpoint_config_table[] = {
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0f, PCI_ANY_ID,
pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
PCI_ENET0_MEMADDR,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
{ }
};
#endif
struct pci_controller hose = {
#ifndef CONFIG_PCI_PNP
config_table: pci_sandpoint_config_table,
#endif
};
void pci_init_board(void)
{
pci_mpc824x_init(&hose);
/* init PCI_to_LOCAL Bus BRIDGE */
Plx9030Init();
sysControlDisplay(0,' ');
sysControlDisplay(1,'C');
sysControlDisplay(2,'P');
sysControlDisplay(3,'C');
sysControlDisplay(4,' ');
sysControlDisplay(5,'4');
sysControlDisplay(6,'5');
sysControlDisplay(7,' ');
}
/**************************************************************************
*
* sysControlDisplay - controls one of the Alphanum. Display digits.
*
* This routine will write an ASCII character to the display digit requested.
*
* SEE ALSO:
*
* RETURNS: NA
*/
int sysControlDisplay
(
int digit, /* number of digit 0..7 */
uchar ascii_code /* ASCII code */
)
{
if ((digit < 0) || (digit > 7))
return (-1);
*((volatile uchar*)(DISP_CHR_RAM + digit)) = ascii_code;
return (0);
}

493
board/cpc45/flash.c Normal file
View File

@@ -0,0 +1,493 @@
/*
* (C) Copyright 2001-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 <common.h>
#include <mpc824x.h>
#include <asm/processor.h>
#if defined(CFG_ENV_IS_IN_FLASH)
# ifndef CFG_ENV_ADDR
# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
# endif
# ifndef CFG_ENV_SIZE
# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
# endif
# ifndef CFG_ENV_SECT_SIZE
# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
# endif
#endif
#define FLASH_BANK_SIZE 0x800000
#define MAIN_SECT_SIZE 0x40000
#define PARAM_SECT_SIZE 0x8000
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
static int write_data (flash_info_t *info, ulong dest, ulong *data);
static void write_via_fpu(vu_long *addr, ulong *data);
static __inline__ unsigned long get_msr(void);
static __inline__ void set_msr(unsigned long msr);
/*---------------------------------------------------------------------*/
#undef DEBUG_FLASH
/*---------------------------------------------------------------------*/
#ifdef DEBUG_FLASH
#define DEBUGF(fmt,args...) printf(fmt ,##args)
#else
#define DEBUGF(fmt,args...)
#endif
/*---------------------------------------------------------------------*/
/*-----------------------------------------------------------------------
*/
unsigned long flash_init(void)
{
int i, j;
ulong size = 0;
uchar tempChar;
/* Enable flash writes on CPC45 */
tempChar = BOARD_CTRL;
tempChar |= (B_CTRL_FWPT_1 | B_CTRL_FWRE_1);
tempChar &= ~(B_CTRL_FWPT_0 | B_CTRL_FWRE_0);
BOARD_CTRL = tempChar;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
vu_long *addr = (vu_long *)(CFG_FLASH_BASE + i * FLASH_BANK_SIZE);
addr[0] = 0x00900090;
DEBUGF ("Flash bank # %d:\n"
"\tManuf. ID @ 0x%08lX: 0x%08lX\n"
"\tDevice ID @ 0x%08lX: 0x%08lX\n",
i,
(ulong)(&addr[0]), addr[0],
(ulong)(&addr[2]), addr[2]);
if ((addr[0] == addr[1]) && (addr[0] == INTEL_MANUFACT) &&
(addr[2] == addr[3]) && (addr[2] == INTEL_ID_28F160F3T))
{
flash_info[i].flash_id = (FLASH_MAN_INTEL & FLASH_VENDMASK) |
(INTEL_ID_28F160F3T & FLASH_TYPEMASK);
} else {
flash_info[i].flash_id = FLASH_UNKNOWN;
addr[0] = 0xFFFFFFFF;
goto Done;
}
DEBUGF ("flash_id = 0x%08lX\n", flash_info[i].flash_id);
addr[0] = 0xFFFFFFFF;
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);
for (j = 0; j < flash_info[i].sector_count; j++) {
if (j > 30) {
flash_info[i].start[j] = CFG_FLASH_BASE +
i * FLASH_BANK_SIZE +
(MAIN_SECT_SIZE * 31) + (j - 31) * PARAM_SECT_SIZE;
} else {
flash_info[i].start[j] = CFG_FLASH_BASE +
i * FLASH_BANK_SIZE +
j * MAIN_SECT_SIZE;
}
}
size += flash_info[i].size;
}
/* Protect monitor and environment sectors
*/
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE + FLASH_BANK_SIZE
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1,
&flash_info[1]);
#else
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1,
&flash_info[0]);
#endif
#endif
#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
#if CFG_ENV_ADDR >= CFG_FLASH_BASE + FLASH_BANK_SIZE
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[1]);
#else
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[0]);
#endif
#endif
Done:
return size;
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t * info)
{
int i;
switch ((i = info->flash_id & FLASH_VENDMASK)) {
case (FLASH_MAN_INTEL & FLASH_VENDMASK):
printf ("Intel: ");
break;
default:
printf ("Unknown Vendor 0x%04x ", i);
break;
}
switch ((i = info->flash_id & FLASH_TYPEMASK)) {
case (INTEL_ID_28F160F3T & FLASH_TYPEMASK):
printf ("28F160F3T (16Mbit)\n");
break;
default:
printf ("Unknown Chip Type 0x%04x\n", i);
goto Done;
break;
}
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; i++) {
if ((i % 5) == 0) {
printf ("\n ");
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
Done:
return;
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
int flag, prot, sect;
ulong start, now, last;
DEBUGF ("Erase flash bank %d sect %d ... %d\n",
info - &flash_info[0], s_first, s_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 & FLASH_VENDMASK)) {
printf ("Can erase only Intel flash types - aborted\n");
return 1;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
start = get_timer (0);
last = start;
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
vu_long *addr = (vu_long *)(info->start[sect]);
DEBUGF ("Erase sect %d @ 0x%08lX\n",
sect, (ulong)addr);
/* Disable interrupts which might cause a timeout
* here.
*/
flag = disable_interrupts();
addr[0] = 0x00500050; /* clear status register */
addr[0] = 0x00200020; /* erase setup */
addr[0] = 0x00D000D0; /* erase confirm */
addr[1] = 0x00500050; /* clear status register */
addr[1] = 0x00200020; /* erase setup */
addr[1] = 0x00D000D0; /* erase confirm */
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
while (((addr[0] & 0x00800080) != 0x00800080) ||
((addr[1] & 0x00800080) != 0x00800080) ) {
if ((now=get_timer(start)) >
CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
addr[0] = 0x00B000B0; /* suspend erase */
addr[0] = 0x00FF00FF; /* to read mode */
return 1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc ('.');
last = now;
}
}
addr[0] = 0x00FF00FF;
}
}
printf (" done\n");
return 0;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
* 4 - Flash not identified
*/
#define FLASH_WIDTH 8 /* flash bus width in bytes */
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong wp, cp, msr;
int l, rc, i;
ulong data[2];
ulong *datah = &data[0];
ulong *datal = &data[1];
DEBUGF ("Flash write_buff: @ 0x%08lx, src 0x%08lx len %ld\n",
addr, (ulong)src, cnt);
if (info->flash_id == FLASH_UNKNOWN) {
return 4;
}
msr = get_msr();
set_msr(msr | MSR_FP);
wp = (addr & ~(FLASH_WIDTH-1)); /* get lower aligned address */
/*
* handle unaligned start bytes
*/
if ((l = addr - wp) != 0) {
*datah = *datal = 0;
for (i = 0, cp = wp; i < l; i++, cp++) {
if (i >= 4) {
*datah = (*datah << 8) |
((*datal & 0xFF000000) >> 24);
}
*datal = (*datal << 8) | (*(uchar *)cp);
}
for (; i < FLASH_WIDTH && cnt > 0; ++i) {
char tmp;
tmp = *src;
src++;
if (i >= 4) {
*datah = (*datah << 8) |
((*datal & 0xFF000000) >> 24);
}
*datal = (*datal << 8) | tmp;
--cnt; ++cp;
}
for (; cnt == 0 && i < FLASH_WIDTH; ++i, ++cp) {
if (i >= 4) {
*datah = (*datah << 8) |
((*datal & 0xFF000000) >> 24);
}
*datal = (*datah << 8) | (*(uchar *)cp);
}
if ((rc = write_data(info, wp, data)) != 0) {
set_msr(msr);
return (rc);
}
wp += FLASH_WIDTH;
}
/*
* handle FLASH_WIDTH aligned part
*/
while (cnt >= FLASH_WIDTH) {
*datah = *(ulong *)src;
*datal = *(ulong *)(src + 4);
if ((rc = write_data(info, wp, data)) != 0) {
set_msr(msr);
return (rc);
}
wp += FLASH_WIDTH;
cnt -= FLASH_WIDTH;
src += FLASH_WIDTH;
}
if (cnt == 0) {
set_msr(msr);
return (0);
}
/*
* handle unaligned tail bytes
*/
*datah = *datal = 0;
for (i = 0, cp = wp; i < FLASH_WIDTH && cnt > 0; ++i, ++cp) {
char tmp;
tmp = *src;
src++;
if (i >= 4) {
*datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24);
}
*datal = (*datal << 8) | tmp;
--cnt;
}
for (; i < FLASH_WIDTH; ++i, ++cp) {
if (i >= 4) {
*datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24);
}
*datal = (*datal << 8) | (*(uchar *)cp);
}
rc = write_data(info, wp, data);
set_msr(msr);
return (rc);
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_data (flash_info_t *info, ulong dest, ulong *data)
{
vu_long *addr = (vu_long *)dest;
ulong start;
int flag;
/* Check if Flash is (sufficiently) erased */
if (((addr[0] & data[0]) != data[0]) ||
((addr[1] & data[1]) != data[1]) ) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[0] = 0x00400040; /* write setup */
write_via_fpu(addr, data);
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
start = get_timer (0);
while (((addr[0] & 0x00800080) != 0x00800080) ||
((addr[1] & 0x00800080) != 0x00800080) ) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
addr[0] = 0x00FF00FF; /* restore read mode */
return (1);
}
}
addr[0] = 0x00FF00FF; /* restore read mode */
return (0);
}
/*-----------------------------------------------------------------------
*/
static void write_via_fpu(vu_long *addr, ulong *data)
{
__asm__ __volatile__ ("lfd 1, 0(%0)" : : "r" (data));
__asm__ __volatile__ ("stfd 1, 0(%0)" : : "r" (addr));
}
/*-----------------------------------------------------------------------
*/
static __inline__ unsigned long get_msr(void)
{
unsigned long msr;
__asm__ __volatile__ ("mfmsr %0" : "=r" (msr) :);
return msr;
}
static __inline__ void set_msr(unsigned long msr)
{
__asm__ __volatile__ ("mtmsr %0" : : "r" (msr));
}

174
board/cpc45/plx9030.c Normal file
View File

@@ -0,0 +1,174 @@
/* Plx9030.c - system configuration module for PLX9030 PCI to Local Bus Bridge */
/*
* (C) Copyright 2002-2003
* Josef Wagner, MicroSys GmbH, wagner@microsys.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
*
* Date Modification by
* ------- ---------------------------------------------- ---
* 30sep02 converted from VxWorks to LINUX wa
*/
/*
DESCRIPTION
This is the configuration module for the PLX9030 PCI to Local Bus Bridge.
It configures the Chip select lines for SRAM (CS0), ST16C552 (CS1,CS2), Display and local
registers (CS3) on CPC45.
*/
/* includes */
#include <common.h>
#include <malloc.h>
#include <net.h>
#include <asm/io.h>
#include <pci.h>
/* imports */
/* defines */
#define PLX9030_VENDOR_ID 0x10B5
#define PLX9030_DEVICE_ID 0x9030
#undef PLX_DEBUG
/* PLX9030 register offsets */
#define P9030_LAS0RR 0x00
#define P9030_LAS1RR 0x04
#define P9030_LAS2RR 0x08
#define P9030_LAS3RR 0x0c
#define P9030_EROMRR 0x10
#define P9030_LAS0BA 0x14
#define P9030_LAS1BA 0x18
#define P9030_LAS2BA 0x1c
#define P9030_LAS3BA 0x20
#define P9030_EROMBA 0x24
#define P9030_LAS0BRD 0x28
#define P9030_LAS1BRD 0x2c
#define P9030_LAS2BRD 0x30
#define P9030_LAS3BRD 0x34
#define P9030_EROMBRD 0x38
#define P9030_CS0BASE 0x3C
#define P9030_CS1BASE 0x40
#define P9030_CS2BASE 0x44
#define P9030_CS3BASE 0x48
#define P9030_INTCSR 0x4c
#define P9030_CNTRL 0x50
#define P9030_GPIOC 0x54
/* typedefs */
/* locals */
static struct pci_device_id supported[] = {
{ PLX9030_VENDOR_ID, PLX9030_DEVICE_ID },
{ }
};
/* forward declarations */
void sysOutLong(ulong address, ulong value);
/***************************************************************************
*
* Plx9030Init - init CS0..CS3 for CPC45
*
*
* RETURNS: N/A
*/
void Plx9030Init (void)
{
pci_dev_t devno;
ulong membaseCsr; /* base address of device memory space */
int idx = 0; /* general index */
/* find plx9030 device */
if ((devno = pci_find_devices(supported, idx++)) < 0)
{
printf("No PLX9030 device found !!\n");
return;
}
#ifdef PLX_DEBUG
printf("PLX 9030 device found ! devno = 0x%x\n",devno);
#endif
membaseCsr = PCI_PLX9030_MEMADDR;
/* set base address */
pci_write_config_dword(devno, PCI_BASE_ADDRESS_0, membaseCsr);
/* enable mapped memory and IO addresses */
pci_write_config_dword(devno,
PCI_COMMAND,
PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER);
/* configure GBIOC */
sysOutLong((membaseCsr + P9030_GPIOC), 0x00000FC0); /* CS2/CS3 enable */
/* configure CS0 (SRAM) */
sysOutLong((membaseCsr + P9030_LAS0BA), 0x00000001); /* enable space base */
sysOutLong((membaseCsr + P9030_LAS0RR), 0x0FE00000); /* 2 MByte */
sysOutLong((membaseCsr + P9030_LAS0BRD), 0x51928900); /* 4 wait states */
sysOutLong((membaseCsr + P9030_CS0BASE), 0x00100001); /* enable 2 MByte */
/* remap CS0 (SRAM) */
pci_write_config_dword(devno, PCI_BASE_ADDRESS_2, SRAM_BASE);
/* configure CS1 (ST16552 / CHAN A) */
sysOutLong((membaseCsr + P9030_LAS1BA), 0x00400001); /* enable space base */
sysOutLong((membaseCsr + P9030_LAS1RR), 0x0FFFFF00); /* 256 byte */
sysOutLong((membaseCsr + P9030_LAS1BRD), 0x55122900); /* 4 wait states */
sysOutLong((membaseCsr + P9030_CS1BASE), 0x00400081); /* enable 256 Byte */
/* remap CS1 (ST16552 / CHAN A) */
/* remap CS1 (ST16552 / CHAN A) */
pci_write_config_dword(devno, PCI_BASE_ADDRESS_3, ST16552_A_BASE);
/* configure CS2 (ST16552 / CHAN B) */
sysOutLong((membaseCsr + P9030_LAS2BA), 0x00800001); /* enable space base */
sysOutLong((membaseCsr + P9030_LAS2RR), 0x0FFFFF00); /* 256 byte */
sysOutLong((membaseCsr + P9030_LAS2BRD), 0x55122900); /* 4 wait states */
sysOutLong((membaseCsr + P9030_CS2BASE), 0x00800081); /* enable 256 Byte */
/* remap CS2 (ST16552 / CHAN B) */
pci_write_config_dword(devno, PCI_BASE_ADDRESS_4, ST16552_B_BASE);
/* configure CS3 (BCSR) */
sysOutLong((membaseCsr + P9030_LAS3BA), 0x00C00001); /* enable space base */
sysOutLong((membaseCsr + P9030_LAS3RR), 0x0FFFFF00); /* 256 byte */
sysOutLong((membaseCsr + P9030_LAS3BRD), 0x55357A80); /* 9 wait states */
sysOutLong((membaseCsr + P9030_CS3BASE), 0x00C00081); /* enable 256 Byte */
/* remap CS3 (DISPLAY and BCSR) */
pci_write_config_dword(devno, PCI_BASE_ADDRESS_5, BCSR_BASE);
}
void sysOutLong(ulong address, ulong value)
{
*(ulong*)address = cpu_to_le32(value);
}

128
board/cpc45/u-boot.lds Normal file
View File

@@ -0,0 +1,128 @@
/*
* (C) Copyright 2001-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 :
{
cpu/mpc824x/start.o (.text)
lib_ppc/board.o (.text)
lib_ppc/ppcstring.o (.text)
lib_generic/vsprintf.o (.text)
lib_generic/crc32.o (.text)
lib_generic/zlib.o (.text)
. = DEFINED(env_offset) ? env_offset : .;
common/environment.o (.text)
*(.text)
*(.fixup)
*(.got1)
. = ALIGN(16);
*(.rodata)
*(.rodata1)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x0FFF) & 0xFFFFF000;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
__fixup_entries = (. - _FIXUP_TABLE_) >> 2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(4096);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(4096);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

View File

@@ -47,7 +47,9 @@ SECTIONS
armboot_end_data = .;
. = ALIGN(4);
bss_start = .;
.bss : { *(.bss) }
bss_end = .;
armboot_end = .;
}

View File

@@ -32,10 +32,30 @@
# define SHOW_BOOT_PROGRESS(arg)
#endif
/*
* Miscelaneous platform dependent initialisations
/**
* misc_init_r: - misc initialisation routines
*/
int misc_init_r(void)
{
#if 0
uchar *str;
/* determine if the software update key is pressed during startup */
/* not ported yet... */
if (GPLR0 & 0x00000800) {
printf("using bootcmd_normal (sw-update button not pressed)\n");
str = getenv("bootcmd_normal");
} else {
printf("using bootcmd_update (sw-update button pressed)\n");
str = getenv("bootcmd_update");
}
setenv("bootcmd",str);
#endif
return 0;
}
/**
* board_init: - setup some data structures

View File

@@ -45,44 +45,44 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
ulong flash_init(void)
{
int i, j;
ulong size = 0;
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);
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;
}
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;
flash_info[i].start[j] = flashbase + j*MAIN_SECT_SIZE;
}
size += flash_info[i].size;
}
size += flash_info[i].size;
}
/* Protect monitor and environment sectors */
flash_protect(FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
&flash_info[0]);
flash_protect(FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
&flash_info[0]);
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[0]);
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[0]);
return size;
return size;
}
@@ -94,43 +94,43 @@ ulong flash_init(void)
void flash_print_info (flash_info_t *info)
{
int i, j;
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;
}
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");
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(" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf(" Sector Start Addresses:");
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++;
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
info++;
}
}
@@ -139,46 +139,47 @@ void flash_print_info (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;
int rc = ERR_OK;
int flag, prot, sect;
int rc = ERR_OK;
if (info->flash_id == FLASH_UNKNOWN)
return ERR_UNKNOWN_FLASH_TYPE;
if (info->flash_id == FLASH_UNKNOWN)
return ERR_UNKNOWN_FLASH_TYPE;
if ((s_first < 0) || (s_first > s_last)) {
return ERR_INVAL;
}
if ((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) {
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();
/*
* 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.
*/
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
flag = disable_interrupts();
printf("Erasing sector %2d ... ", sect);
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
printf("Erasing sector %2d ... ", sect);
if (info->protect[sect] == 0) { /* not protected */
/* 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: */
@@ -190,32 +191,32 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
*addr = 0x00D000D0; /* erase confirm */
while ((*addr & 0x00800080) != 0x00800080) {
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
*addr = 0x00B000B0; /* suspend erase*/
*addr = 0x00FF00FF; /* read mode */
rc = ERR_TIMOUT;
goto outahere;
}
}
rc = ERR_TIMOUT;
goto outahere;
}
}
*addr = 0x00500050; /* clear status register cmd. */
*addr = 0x00FF00FF; /* resest to read mode */
}
}
printf("ok.\n");
}
printf("ok.\n");
}
if (ctrlc()) printf("User Interrupt!\n");
outahere:
outahere:
/* allow flash to settle - wait 10 ms */
udelay_masked(10000);
/* allow flash to settle - wait 10 ms */
udelay_masked(10000);
if (flag) enable_interrupts();
return rc;
return rc;
}
@@ -230,71 +231,71 @@ outahere:
static int write_word (flash_info_t *info, ulong dest, ushort data)
{
ushort *addr = (ushort *)dest, val;
int rc = ERR_OK;
int flag;
u32 * volatile addr = (u32 * volatile)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();
/*
* 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;
/* clear status register command */
*addr = 0x50;
/* program set-up command */
*addr = 0x40;
/* program set-up command */
*addr = 0x40;
/* latch address/data */
*addr = data;
/* latch address/data */
*addr = data;
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
/* wait while polling the status register */
/* wait while polling the status register */
while(((val = *addr) & 0x80) != 0x80) {
if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
rc = ERR_TIMOUT;
if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
rc = ERR_TIMOUT;
*addr = 0xB0; /* suspend program command */
goto outahere;
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;
}
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:
outahere:
*addr = 0xFF; /* read array command */
if (flag) enable_interrupts();
return rc;
return rc;
}
@@ -311,63 +312,64 @@ outahere:
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong cp, wp;
ushort data;
int l;
int i, rc;
ulong cp, wp;
ushort data;
int l;
int i, rc;
wp = (addr & ~1); /* get lower word aligned address */
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);
/*
* 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;
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
/*
* 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;
}
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);
}
/*
* 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);
return write_word(info, wp, data);
}

View File

@@ -38,6 +38,9 @@ DRAM_SIZE: .long CFG_DRAM_SIZE
sub pc,pc,#4
.endm
_TEXT_BASE:
.word TEXT_BASE
/*
* Memory setup
@@ -222,24 +225,29 @@ mem_init:
/* Step 2c: Write FLYCNFG FIXME: what's that??? */
/* ---------------------------------------------------------------- */
/* test if we run from flash or RAM - RAM/BDI: don't setup RAM */
adr r3, mem_init /* r0 <- current position of code */
ldr r2, =mem_init
cmp r3, r2 /* skip init if in place */
beq initirqs
/* ---------------------------------------------------------------- */
/* Step 2d: Initialize Timing for Sync Memory (SDCLK0) */
/* ---------------------------------------------------------------- */
/* Before accessing MDREFR we need a valid DRI field, so we set */
/* this to power on defaults + DIR field. */
/* this to power on defaults + DRI field. */
ldr r3, =CFG_MDREFR_VAL
ldr r2, =0xFFF
and r3, r3, r2
ldr r4, =0x03ca4000
orr r4, r4, r3
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) */
@@ -258,18 +266,16 @@ mem_init:
/* Step 4: Initialize SDRAM */
/* ---------------------------------------------------------------- */
/* Step 4a: assert MDREFR:K1RUN and MDREFR:K2RUN and configure */
/* Step 4a: assert MDREFR:K?RUN 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]
ldr r4, =CFG_MDREFR_VAL
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
ldr r4, [r1, #MDREFR_OFFSET]
/* Step 4b: de-assert MDREFR:SLFRSH. */
bic r4, r4, #(MDREFR_SLFRSH)
bic r4, r4, #(MDREFR_SLFRSH)
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
ldr r4, [r1, #MDREFR_OFFSET]
@@ -313,17 +319,23 @@ mem_init:
/* 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]
/* There should 9 writes, since the first write doesn't */
/* trigger a refresh cycle on PXA250. See Intel PXA250 and */
/* PXA210 Processors Specification Update, */
/* Jan 2003, Errata #116, page 30. */
ldr r3, =CFG_DRAM_BASE
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
/* Step 4g: Write MDCNFG with enable bits asserted */
/* (MDCNFG:DEx set to 1). */
@@ -339,7 +351,6 @@ mem_init:
/* We are finished with Intel's memory controller initialisation */
/* ---------------------------------------------------------------- */
/* Disable (mask) all interrupts at interrupt controller */
/* ---------------------------------------------------------------- */
@@ -378,10 +389,11 @@ initclks:
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:
@@ -404,8 +416,7 @@ initclks:
/* FIXME */
#define NODEBUG
#ifdef NODEBUG
#ifndef DEBUG
/*Disable software and data breakpoints */
mov r0,#0
mcr p15,0,r0,c14,c8,0 /* ibcr0 */
@@ -415,7 +426,6 @@ initclks:
/*Enable all debug functionality */
mov r0,#0x80000000
mcr p14,0,r0,c10,c0,0 /* dcsr */
#endif
/* ---------------------------------------------------------------- */

View File

@@ -47,7 +47,9 @@ SECTIONS
armboot_end_data = .;
. = ALIGN(4);
bss_start = .;
.bss : { *(.bss) }
bss_end = .;
armboot_end = .;
}

View File

@@ -98,11 +98,11 @@ Done:
*/
#ifndef CONFIG_PCI_PNP
static struct pci_config_table pci_sandpoint_config_table[] = {
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_BUS(CFG_ETH_DEV_FN), PCI_DEV(CFG_ETH_DEV_FN), PCI_FUNC(CFG_ETH_DEV_FN),
pci_cfgfunc_config_device, { CFG_ETH_IOBASE,
0,
PCI_COMMAND_IO | PCI_COMMAND_MASTER }},
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0f, PCI_ANY_ID,
pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
PCI_ENET0_MEMADDR,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
{ }
};
#endif

View File

@@ -23,7 +23,7 @@
*/
#include <common.h>
#include <SA-1100.h>
/* ------------------------------------------------------------------------- */
@@ -41,8 +41,9 @@ int board_init (void)
/* arch number of DNP1110-Board */
gd->bd->bi_arch_number = 255;
/* adress of boot parameters */
gd->bd->bi_boot_params = 0xc0000100;
/* flash vpp on */
PPDR |= 0x80; /* assumes LCD controller is off */
PPSR |= 0x80;
return 0;
}

View File

@@ -1,7 +1,9 @@
/*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Rolf Offermanns <rof@sysgo.de>
* (C) Copyright 2001
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
*
* (C) Copyright 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -23,81 +25,58 @@
*/
#include <common.h>
ulong myflush(void);
#include <linux/byteorder/swab.h>
#define FLASH_BANK_SIZE 0x800000
#define MAIN_SECT_SIZE 0x20000
#define PARAM_SECT_SIZE 0x4000
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/* puzzle magic for lart
* data_*_flash are def'd in flashasm.S
/* Board support for 1 or 2 flash devices */
#undef FLASH_PORT_WIDTH32
#define 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
*/
extern u32 data_from_flash(u32);
extern u32 data_to_flash(u32);
#define PUZZLE_FROM_FLASH(x) (x)
#define PUZZLE_TO_FLASH(x) (x)
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
#define CMD_READ_ARRAY 0x00FF00FF
#define CMD_IDENTIFY 0x00900090
#define CMD_ERASE_SETUP 0x00200020
#define CMD_ERASE_CONFIRM 0x00D000D0
#define CMD_PROGRAM 0x00400040
#define CMD_RESUME 0x00D000D0
#define CMD_SUSPEND 0x00B000B0
#define CMD_STATUS_READ 0x00700070
#define CMD_STATUS_RESET 0x00500050
#define BIT_BUSY 0x00800080
#define BIT_ERASE_SUSPEND 0x00400040
#define BIT_ERASE_ERROR 0x00200020
#define BIT_PROGRAM_ERROR 0x00100010
#define BIT_VPP_RANGE_ERROR 0x00080008
#define BIT_PROGRAM_SUSPEND 0x00040004
#define BIT_PROTECT_ERROR 0x00020002
#define BIT_UNDEFINED 0x00010001
#define BIT_SEQUENCE_ERROR 0x00300030
#define BIT_TIMEOUT 0x80000000
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_28F160F3B & FLASH_TYPEMASK);
flash_info[i].size = FLASH_BANK_SIZE;
flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
if (i == 0)
flashbase = PHYS_FLASH_1;
else
panic("configured to many flash banks!\n");
for (j = 0; j < flash_info[i].sector_count; j++)
{
if (j <= 7)
{
flash_info[i].start[j] = flashbase + j * PARAM_SECT_SIZE;
}
else
{
flash_info[i].start[j] = flashbase + (j - 7)*MAIN_SECT_SIZE;
}
}
switch (i)
{
case 0:
flash_get_size((FPW *)PHYS_FLASH_1, &flash_info[i]);
flash_get_offsets(PHYS_FLASH_1, &flash_info[i]);
break;
default:
panic("configured to many flash banks!\n");
break;
}
size += flash_info[i].size;
}
@@ -118,150 +97,138 @@ ulong flash_init(void)
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
static void flash_get_offsets (ulong base, flash_info_t *info)
{
int i;
int i;
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_28F160F3B & FLASH_TYPEMASK):
printf("2x 28F160F3B (16Mbit)\n");
break;
default:
printf("Unknown Chip Type\n");
goto Done;
break;
}
printf(" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf(" Sector Start Addresses:");
for (i = 0; i < info->sector_count; i++)
{
if ((i % 5) == 0)
{
printf ("\n ");
if (info->flash_id == FLASH_UNKNOWN) {
return;
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
Done:
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;
}
}
}
/*-----------------------------------------------------------------------
*/
int flash_error (ulong code)
void flash_print_info (flash_info_t *info)
{
/* Check bit patterns */
/* SR.7=0 is busy, SR.7=1 is ready */
/* all other flags indicate error on 1 */
/* SR.0 is undefined */
/* Timeout is our faked flag */
int i;
/* sequence is described in Intel 290644-005 document */
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
/* check Timeout */
if (code & BIT_TIMEOUT)
{
printf ("Timeout\n");
return ERR_TIMOUT;
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_INTEL: printf ("INTEL "); break;
default: printf ("Unknown Vendor "); break;
}
/* check Busy, SR.7 */
if (~code & BIT_BUSY)
{
printf ("Busy\n");
return ERR_PROG_ERROR;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F128J3A:
printf ("28F128J3A\n"); break;
default: printf ("Unknown Chip Type\n"); break;
}
/* check Vpp low, SR.3 */
if (code & BIT_VPP_RANGE_ERROR)
{
printf ("Vpp range error\n");
return ERR_PROG_ERROR;
}
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
/* check Device Protect Error, SR.1 */
if (code & BIT_PROTECT_ERROR)
{
printf ("Device protect error\n");
return ERR_PROG_ERROR;
}
/* check Command Seq Error, SR.4 & SR.5 */
if (code & BIT_SEQUENCE_ERROR)
{
printf ("Command seqence error\n");
return ERR_PROG_ERROR;
}
/* check Block Erase Error, SR.5 */
if (code & BIT_ERASE_ERROR)
{
printf ("Block erase error\n");
return ERR_PROG_ERROR;
}
/* check Program Error, SR.4 */
if (code & BIT_PROGRAM_ERROR)
{
printf ("Program error\n");
return ERR_PROG_ERROR;
}
/* check Block Erase Suspended, SR.6 */
if (code & BIT_ERASE_SUSPEND)
{
printf ("Block erase suspended\n");
return ERR_PROG_ERROR;
}
/* check Program Suspended, SR.2 */
if (code & BIT_PROGRAM_SUSPEND)
{
printf ("Program suspended\n");
return ERR_PROG_ERROR;
}
/* OK, no error */
return ERR_OK;
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
return;
}
/*
* The following code cannot be run from FLASH!
*/
static ulong flash_get_size (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;
}
addr[0] = (FPW)0x00FF00FF; /* restore read mode */
return (info->size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
ulong result;
int iflag, cflag, prot, sect;
int rc = ERR_OK;
/* first look for protection bits */
if (info->flash_id == FLASH_UNKNOWN)
return ERR_UNKNOWN_FLASH_TYPE;
int flag, prot, sect;
ulong type, start, 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;
@@ -270,152 +237,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.
*/
cflag = icache_status();
icache_disable();
iflag = disable_interrupts();
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_long *addr = (vu_long *)(info->start[sect]);
*addr = (FPW)0x00500050; /* clear status register */
*addr = (FPW)0x00200020; /* erase setup */
*addr = (FPW)0x00D000D0; /* erase confirm */
*addr = PUZZLE_TO_FLASH(CMD_STATUS_RESET);
*addr = PUZZLE_TO_FLASH(CMD_ERASE_SETUP);
*addr = PUZZLE_TO_FLASH(CMD_ERASE_CONFIRM);
/* wait until flash is ready */
do
{
/* check timeout */
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
{
*addr = PUZZLE_TO_FLASH(CMD_SUSPEND);
result = BIT_TIMEOUT;
break;
}
result = PUZZLE_FROM_FLASH(*addr);
} while (~result & BIT_BUSY);
*addr = PUZZLE_TO_FLASH(CMD_READ_ARRAY);
if ((rc = flash_error(result)) != ERR_OK)
goto outahere;
printf("ok.\n");
}
else /* it was protected */
{
printf("protected!\n");
while (((status = *addr) & (FPW)0x00800080) != (FPW)0x00800080) {
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
*addr = (FPW)0x00B000B0; /* suspend erase */
*addr = (FPW)0x00FF00FF; /* reset to read mode */
rcode = 1;
break;
}
}
if (ctrlc())
printf("User Interrupt!\n");
*addr = (FPW)0x00500050; /* clear status register cmd. */
*addr = (FPW)0x00FF00FF; /* resest to read mode */
outahere:
/* allow flash to settle - wait 10 ms */
udelay_masked(10000);
if (iflag)
enable_interrupts();
if (cflag)
icache_enable();
return rc;
printf (" done\n");
}
}
return rcode;
}
/*-----------------------------------------------------------------------
* Copy memory to flash
*/
volatile static int write_word (flash_info_t *info, ulong dest, ulong data)
{
vu_long *addr = (vu_long *)dest;
ulong result;
int rc = ERR_OK;
int cflag, iflag;
/* Check if Flash is (sufficiently) erased
*/
result = PUZZLE_FROM_FLASH(*addr);
if ((result & data) != data)
return ERR_NOT_ERASED;
/*
* Disable interrupts which might cause a timeout
* here. Remember that our exception vectors are
* at address 0 in the flash, and we don't want a
* (ticker) exception to happen while the flash
* chip is in programming mode.
*/
cflag = icache_status();
icache_disable();
iflag = disable_interrupts();
*addr = PUZZLE_TO_FLASH(CMD_STATUS_RESET);
*addr = PUZZLE_TO_FLASH(CMD_PROGRAM);
*addr = data;
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
/* wait until flash is ready */
do
{
/* check timeout */
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
{
*addr = PUZZLE_TO_FLASH(CMD_SUSPEND);
result = BIT_TIMEOUT;
break;
}
result = PUZZLE_FROM_FLASH(*addr);
} while (~result & BIT_BUSY);
*addr = PUZZLE_TO_FLASH(CMD_READ_ARRAY);
rc = flash_error(result);
if (iflag)
enable_interrupts();
if (cflag)
icache_enable();
return rc;
}
/*-----------------------------------------------------------------------
* 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, data;
int l;
int i, rc;
ulong cp, wp;
FPW data;
int count, i, l, rc, port_width;
wp = (addr & ~3); /* 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
@@ -423,51 +317,109 @@ 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 << 24);
data = (data << 8) | (*(uchar *)cp);
}
for (; i<4 && cnt>0; ++i) {
data = (data >> 8) | (*src++ << 24);
for (; i<port_width && cnt>0; ++i) {
data = (data << 8) | *src++;
--cnt;
++cp;
}
for (; cnt==0 && i<4; ++i, ++cp) {
data = (data >> 8) | (*(uchar *)cp << 24);
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 += 4;
wp += port_width;
}
/*
* handle word aligned part
*/
while (cnt >= 4) {
data = *((vu_long*)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 += 4;
wp += 4;
cnt -= 4;
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<4 && cnt>0; ++i, ++cp) {
data = (data >> 8) | (*src++ << 24);
for (i=0, cp=wp; i<port_width && cnt>0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
for (; i<4; ++i, ++cp) {
data = (data >> 8) | (*(uchar *)cp << 24);
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;
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 p=0;
static char w[] = "\\/-";
printf("\010%c", w[p]);
(++p == 3) ? (p = 0) : 0;
}

View File

@@ -25,8 +25,8 @@
#include <config.h>
#include <version.h>
#include "config.h"
#include "version.h"
/* some parameters for the board */
@@ -34,63 +34,103 @@
MEM_BASE: .long 0xa0000000
MEM_START: .long 0xc0000000
#define MDCNFG 0x00
#define MDCAS0 0x04
#define MDCAS1 0x08
#define MDCAS2 0x0c
#define MSC0 0x10
#define MSC1 0x14
#define MECR 0x18
#define MDCNFG 0x00
#define MDCAS00 0x04 /* CAS waveform rotate reg 0 */
#define MDCAS01 0x08 /* CAS waveform rotate reg 1 bank */
#define MDCAS02 0x0C /* CAS waveform rotate reg 2 bank */
#define MDREFR 0x1C /* DRAM refresh control reg */
#define MDCAS20 0x20 /* CAS waveform rotate reg 0 bank */
#define MDCAS21 0x24 /* CAS waveform rotate reg 1 bank */
#define MDCAS22 0x28 /* CAS waveform rotate reg 2 bank */
#define MECR 0x18 /* Expansion memory (PCMCIA) bus configuration register */
#define MSC0 0x10 /* static memory control reg 0 */
#define MSC1 0x14 /* static memory control reg 1 */
#define MSC2 0x2C /* static memory control reg 2 */
#define SMCNFG 0x30 /* SMROM configuration reg */
mdcas0: .long 0xc71c703f
mdcas1: .long 0xffc71c71
mdcas2: .long 0xffffffff
/* mdcnfg: .long 0x0bb2bcbf */
mdcnfg: .long 0x0334b22f @ alt
/* mcs0: .long 0xfff8fff8 */
msc0: .long 0xad8c4888 @ alt
mecr: .long 0x00060006
/* mecr: .long 0x994a994a @ alt */
mdcas00: .long 0x5555557F
mdcas01: .long 0x55555555
mdcas02: .long 0x55555555
mdcas20: .long 0x5555557F
mdcas21: .long 0x55555555
mdcas22: .long 0x55555555
mdcnfg: .long 0x0000B25C
mdrefr: .long 0x007000C1
mecr: .long 0x10841084
msc0: .long 0x00004774
msc1: .long 0x00000000
msc2: .long 0x00000000
smcnfg: .long 0x00000000
/* setting up the memory */
.globl memsetup
memsetup:
ldr r0, MEM_BASE
/* Setup the flash memory */
ldr r1, msc0
str r1, [r0, #MSC0]
ldr r0, MEM_BASE
/* Set up the DRAM */
/* MDCAS0 */
ldr r1, mdcas0
str r1, [r0, #MDCAS0]
/* MDCAS00 */
ldr r1, mdcas00
str r1, [r0, #MDCAS00]
/* MDCAS1 */
ldr r1, mdcas1
str r1, [r0, #MDCAS1]
/* MDCAS01 */
ldr r1, mdcas01
str r1, [r0, #MDCAS01]
/* MDCAS2 */
ldr r1, mdcas2
str r1, [r0, #MDCAS2]
/* MDCAS02 */
ldr r1, mdcas02
str r1, [r0, #MDCAS02]
/* MDCNFG */
ldr r1, mdcnfg
str r1, [r0, #MDCNFG]
/* MDCAS20 */
ldr r1, mdcas20
str r1, [r0, #MDCAS20]
/* MDCAS21 */
ldr r1, mdcas21
str r1, [r0, #MDCAS21]
/* MDCAS22 */
ldr r1, mdcas22
str r1, [r0, #MDCAS22]
/* MDREFR */
ldr r1, mdrefr
str r1, [r0, #MDREFR]
/* Set up PCMCIA space */
ldr r1, mecr
str r1, [r0, #MECR]
/* Load something to activate bank */
ldr r1, MEM_START
/* Setup the flash memory and other */
ldr r1, msc0
str r1, [r0, #MSC0]
ldr r1, msc1
str r1, [r0, #MSC1]
ldr r1, msc2
str r1, [r0, #MSC2]
ldr r1, smcnfg
str r1, [r0, #SMCNFG]
/* MDCNFG */
ldr r1, mdcnfg
bic r1, r1, #0x00000001
str r1, [r0, #MDCNFG]
/* Load something to activate bank */
ldr r2, MEM_START
.rept 8
ldr r0, [r1]
ldr r1, [r2]
.endr
/* MDCNFG */
ldr r1, mdcnfg
orr r1, r1, #0x00000001
str r1, [r0, #MDCNFG]
/* everything is fine now */
mov pc, lr

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

@@ -327,6 +327,9 @@ void flash_print_info (flash_info_t *info)
case (FLASH_WORD_SIZE)SST_MANUFACT:
info->flash_id = FLASH_MAN_SST;
break;
case (FLASH_WORD_SIZE)STM_MANUFACT:
info->flash_id = FLASH_MAN_STM;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
@@ -349,6 +352,11 @@ void flash_print_info (flash_info_t *info)
info->sector_count = 32;
info->size = 0x00200000;
break; /* => 2 MB */
case (FLASH_WORD_SIZE)STM_ID_F040B:
info->flash_id += FLASH_AM040;
info->sector_count = 8;
info->size = 0x0080000; /* => 512 ko */
break;
case (FLASH_WORD_SIZE)AMD_ID_F040B:
info->flash_id += FLASH_AM040;
info->sector_count = 8;

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

View File

@@ -0,0 +1,28 @@
#
# (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
#
#
# TOP860 board
#
TEXT_BASE = 0x80000000

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

@@ -1,5 +1,5 @@
/*
* (C) Copyright 2001
* (C) Copyright 2001-2003
* Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
*
* See file CREDITS for list of people who contributed to this
@@ -50,7 +50,7 @@ const unsigned char fpgadata[] =
/* Prototypes */
int version2(void);
int cpci405_version(void);
int gunzip(void *, int, unsigned char *, int *);
@@ -83,7 +83,7 @@ int board_pre_init (void)
* Boot onboard FPGA
*/
#ifndef CONFIG_CPCI405_VER2
if (!version2()) {
if (cpci405_version() == 1) {
status = fpga_boot((unsigned char *)fpgadata, sizeof(fpgadata));
if (status != 0) {
/* booting FPGA failed */
@@ -144,7 +144,11 @@ int board_pre_init (void)
mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
mtdcr(uicer, 0x00000000); /* disable all ints */
mtdcr(uiccr, 0x00000000); /* set all to be non-critical*/
mtdcr(uicpr, 0xFFFFFF81); /* set int polarities */
if (cpci405_version() == 3) {
mtdcr(uicpr, 0xFFFFFF99); /* set int polarities */
} else {
mtdcr(uicpr, 0xFFFFFF81); /* set int polarities */
}
mtdcr(uictr, 0x10000000); /* set int trigger levels */
mtdcr(uicvcr, 0x00000001); /* set vect base=0,INT0 highest priority*/
mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
@@ -178,29 +182,43 @@ int cpci405_host(void)
}
int version2(void)
int cpci405_version(void)
{
unsigned long cntrl0Reg;
unsigned long value;
/*
* Setup GPIO pins (CS2/GPIO11 as GPIO)
* Setup GPIO pins (CS2/GPIO11 and CS3/GPIO12 as GPIO)
*/
cntrl0Reg = mfdcr(cntrl0);
mtdcr(cntrl0, cntrl0Reg | 0x02000000);
mtdcr(cntrl0, cntrl0Reg | 0x03000000);
out32(IBM405GP_GPIO0_ODR, in32(IBM405GP_GPIO0_ODR) & ~0x00180000);
out32(IBM405GP_GPIO0_TCR, in32(IBM405GP_GPIO0_TCR) & ~0x00180000);
udelay(1000); /* wait some time before reading input */
value = in32(IBM405GP_GPIO0_IR) & 0x00100000; /* test GPIO11 */
value = in32(IBM405GP_GPIO0_IR) & 0x00180000; /* get config bits */
/*
* Setup GPIO pins (CS2/GPIO11 as CS again)
* Restore GPIO settings
*/
mtdcr(cntrl0, cntrl0Reg);
if (value)
return 0; /* no, board is version 1.x */
else
return -1; /* yes, board is version 2.x */
switch (value) {
case 0x00180000:
/* CS2==1 && CS3==1 -> version 1 */
return 1;
case 0x00080000:
/* CS2==0 && CS3==1 -> version 2 */
return 2;
case 0x00100000:
/* CS2==1 && CS3==0 -> version 3 */
return 3;
case 0x00000000:
/* CS2==0 && CS3==0 -> version 4 */
return 4;
default:
/* should not be reached! */
return 2;
}
}
@@ -216,6 +234,7 @@ int misc_init_r (void)
bd_t *bd = gd->bd;
char * tmp; /* Temporary char pointer */
unsigned long cntrl0Reg;
#ifdef CONFIG_CPCI405_VER2
unsigned char *dst;
@@ -223,14 +242,13 @@ int misc_init_r (void)
int status;
int index;
int i;
unsigned long cntrl0Reg;
/*
* On CPCI-405 version 2 the environment is saved in eeprom!
* FPGA can be gzip compressed (malloc) and booted this late.
*/
if (version2()) {
if (cpci405_version() >= 2) {
/*
* Setup GPIO pins (CS6+CS7 as GPIO)
*/
@@ -291,11 +309,41 @@ int misc_init_r (void)
putc ('\n');
free(dst);
/*
* Reset FPGA via FPGA_DATA pin
*/
SET_FPGA(FPGA_PRG | FPGA_CLK);
udelay(1000); /* wait 1ms */
SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
udelay(1000); /* wait 1ms */
if (cpci405_version() == 3) {
volatile unsigned short *fpga_mode = (unsigned short *)CFG_FPGA_BASE_ADDR;
volatile unsigned char *leds = (unsigned char *)CFG_LED_ADDR;
/*
* Enable outputs in fpga on version 3 board
*/
*fpga_mode |= CFG_FPGA_MODE_ENABLE_OUTPUT;
/*
* Set outputs to 0
*/
*leds = 0x00;
/*
* Reset external DUART
*/
*fpga_mode |= CFG_FPGA_MODE_DUART_RESET;
udelay(100);
*fpga_mode &= ~(CFG_FPGA_MODE_DUART_RESET);
}
}
else {
printf("\n*** U-Boot Version does not match Board Version!\n");
printf("*** CPCI-405 Version 2.x detected!\n");
printf("*** Please use correct U-Boot version (CPCI4052)!\n\n");
puts("\n*** U-Boot Version does not match Board Version!\n");
puts("*** CPCI-405 Version 1.x detected!\n");
puts("*** Please use correct U-Boot version (CPCI405 instead of CPCI4052)!\n\n");
}
#else /* CONFIG_CPCI405_VER2 */
@@ -321,14 +369,20 @@ int misc_init_r (void)
}
}
if (version2()) {
printf("\n*** U-Boot Version does not match Board Version!\n");
printf("*** CPCI-405 Board Version 1.x detected!\n");
printf("*** Please use correct U-Boot version (CPCI405)!\n\n");
if (cpci405_version() >= 2) {
puts("\n*** U-Boot Version does not match Board Version!\n");
puts("*** CPCI-405 Board Version 2.x detected!\n");
puts("*** Please use correct U-Boot version (CPCI4052 instead of CPCI405)!\n\n");
}
#endif /* CONFIG_CPCI405_VER2 */
/*
* Select cts (and not dsr) on uart1
*/
cntrl0Reg = mfdcr(cntrl0);
mtdcr(cntrl0, cntrl0Reg | 0x00001000);
/*
* Write ethernet addr in NVRAM for VxWorks
*/
@@ -350,6 +404,7 @@ int checkboard (void)
#endif
unsigned char str[64];
int i = getenv_r ("serial#", str, sizeof(str));
unsigned short ver;
puts ("Board: ");
@@ -359,17 +414,19 @@ int checkboard (void)
puts(str);
}
if (version2())
puts (" (Ver 2.x, ");
else
puts (" (Ver 1.x, ");
ver = cpci405_version();
printf(" (Ver %d.x, ", ver);
#if 0
if ((*(unsigned short *)((unsigned long)CFG_FPGA_BASE_ADDR) + CFG_FPGA_STATUS)
& CFG_FPGA_STATUS_FLASH)
puts ("FLASH Bank A, ");
else
puts ("FLASH Bank B, ");
#if 0 /* test-only */
if (ver >= 2) {
volatile u16 *fpga_status = (u16 *)CFG_FPGA_BASE_ADDR + 1;
if (*fpga_status & CFG_FPGA_STATUS_FLASH) {
puts ("FLASH Bank B, ");
} else {
puts ("FLASH Bank A, ");
}
}
#endif
if (ctermm2()) {

View File

@@ -1,5 +1,5 @@
/*
* (C) Copyright 2001
* (C) Copyright 2001-2003
* Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
*
* See file CREDITS for list of people who contributed to this
@@ -39,13 +39,31 @@ static void flash_get_offsets (ulong base, flash_info_t * info);
/*-----------------------------------------------------------------------
*/
unsigned long calc_size(unsigned long size)
{
switch (size) {
case 1 << 20:
return 0;
case 2 << 20:
return 1;
case 4 << 20:
return 2;
case 8 << 20:
return 3;
case 16 << 20:
return 4;
default:
return 0;
}
}
unsigned long flash_init (void)
{
unsigned long size_b0, size_b1;
int i;
uint pbcr;
unsigned long base_b0, base_b1;
int size_val = 0;
/* Init: no FLASHes known */
for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
@@ -68,61 +86,37 @@ unsigned long flash_init (void)
/* Re-do sizing to get full correct info */
if (size_b1) {
base_b1 = -size_b1;
if (size_b1 < (1 << 20)) {
/* minimum CS size on PPC405GP is 1MB !!! */
size_b1 = 1 << 20;
}
mtdcr (ebccfga, pb0cr);
pbcr = mfdcr (ebccfgd);
mtdcr (ebccfga, pb0cr);
base_b1 = -size_b1;
switch (size_b1) {
case 1 << 20:
size_val = 0;
break;
case 2 << 20:
size_val = 1;
break;
case 4 << 20:
size_val = 2;
break;
case 8 << 20:
size_val = 3;
break;
case 16 << 20:
size_val = 4;
break;
default:
size_val = 0;
break;
}
pbcr = (pbcr & 0x0001ffff) | base_b1 | (size_val << 17);
pbcr = (pbcr & 0x0001ffff) | base_b1 | (calc_size(size_b1) << 17);
mtdcr (ebccfgd, pbcr);
/* printf("pb1cr = %x\n", pbcr); */
#if 0 /* test-only */
printf("size_b1=%x base_b1=%x pb1cr = %x\n",
size_b1, base_b1, pbcr); /* test-only */
#endif
}
if (size_b0) {
base_b0 = base_b1 - size_b0;
if (size_b0 < (1 << 20)) {
/* minimum CS size on PPC405GP is 1MB !!! */
size_b0 = 1 << 20;
}
mtdcr (ebccfga, pb1cr);
pbcr = mfdcr (ebccfgd);
mtdcr (ebccfga, pb1cr);
base_b0 = base_b1 - size_b0;
switch (size_b1) {
case 1 << 20:
size_val = 0;
break;
case 2 << 20:
size_val = 1;
break;
case 4 << 20:
size_val = 2;
break;
case 8 << 20:
size_val = 3;
break;
case 16 << 20:
size_val = 4;
break;
}
pbcr = (pbcr & 0x0001ffff) | base_b0 | (size_val << 17);
pbcr = (pbcr & 0x0001ffff) | base_b0 | (calc_size(size_b0) << 17);
mtdcr (ebccfgd, pbcr);
/* printf("pb0cr = %x\n", pbcr); */
#if 0 /* test-only */
printf("size_b0=%x base_b0=%x pb0cr = %x\n",
size_b0, base_b0, pbcr); /* test-only */
#endif
}
size_b0 = flash_get_size ((vu_long *) base_b0, &flash_info[0]);

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
OBJS = $(BOARD).o flash.o
OBJS = $(BOARD).o flash.o cmd_pci405.o
$(LIB): $(OBJS) $(SOBJS)
$(AR) crv $@ $^

View File

@@ -0,0 +1,230 @@
/*
* (C) Copyright 2002
* Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <malloc.h>
#include <net.h>
#include <asm/io.h>
#include <pci.h>
#include <405gp_pci.h>
#include <cmd_bsp.h>
#include "pci405.h"
#if (CONFIG_COMMANDS & CFG_CMD_BSP)
extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
#if 0 /* test-only */
#include "../common/fpga.c"
void error_print(void)
{
int i;
volatile unsigned char *ptr;
volatile unsigned long *ptr2;
printf("\n 2nd SJA1000:\n");
ptr = 0xf0000100;
for (i=0; i<0x20; i++) {
printf("%02x ", *ptr++);
}
ptr2 = 0xf0400008;
printf("\nTimestamp = %x\n", *ptr2);
udelay(1000);
printf("Timestamp = %x\n", *ptr2);
udelay(1000);
printf("Timestamp = %x\n", *ptr2);
#if 0 /* test-only */
/*
* Reset FPGA via FPGA_DATA pin
*/
printf("Resetting FPGA...\n");
SET_FPGA(FPGA_PRG | FPGA_CLK);
udelay(1000); /* wait 1ms */
SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
udelay(1000); /* wait 1ms */
do_loadpci(NULL, 0,0, NULL);
#endif
}
void read_loop(void)
{
int i;
volatile unsigned char *ptr;
volatile unsigned char val;
volatile unsigned long *ptr2;
printf("\nread loop on 1st sja1000...");
while (1) {
ptr = 0xf0000000;
/* printf("\n1st SJA1000:\n");*/
for (i=0; i<0x20; i++) {
i = i;
val = *ptr++;
/* printf("%02x ", val);*/
}
/* Abort if ctrl-c was pressed */
if (ctrlc()) {
puts("\nAbort\n");
return 0;
}
}
}
#endif
/*
* Command loadpci: wait for signal from host and boot image.
*/
int do_loadpci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
unsigned int *ptr = 0;
int count = 0;
int count2 = 0;
int status;
int i;
char addr[16];
char str[] = "\\|/-";
char *local_args[2];
#if 0 /* test-only */
puts("\nStarting sja1000 test...");
{
int count;
volatile unsigned char *ptr;
volatile unsigned char val;
volatile unsigned char val2;
#if 1 /* write test */
ptr = 0xf0000014;
for (i=1; i<11; i++)
*ptr++ = i;
#endif
count = 0;
while (1) {
count++;
#if 0 /* write test */
ptr = 0xf0000014;
for (i=1; i<11; i++)
*ptr++ = i;
#endif
#if 1 /* read test */
ptr = 0xf0000014;
for (i=1; i<11; i++) {
val = *ptr++;
#if 1
if (val != i) {
ptr = 0xf0000100;
val = *ptr; /* trigger las */
ptr = 0xf0000014;
val2 = *ptr;
printf("\nERROR: count=%d: soll=%x ist=%x -> staring read loop on 1st sja1000...\n", count, i, val);
printf("soll=%x ist=%x -> staring read loop on 1st sja1000...\n", 1, val2);
return 0; /* test-only */
udelay(1000);
error_print();
read_loop();
return 0;
}
#endif
}
#endif
/* Abort if ctrl-c was pressed */
if (ctrlc()) {
puts("\nAbort\n");
return 0;
}
if (!(count % 100000)) {
printf(".");
}
}
}
#endif
/*
* Mark sync address
*/
ptr = 0;
*ptr = 0xffffffff;
puts("\nWaiting for image from pci host -");
/*
* Wait for host to write the start address
*/
while (*ptr == 0xffffffff) {
count++;
if (!(count % 100)) {
count2++;
putc(0x08); /* backspace */
putc(str[count2 % 4]);
}
/* Abort if ctrl-c was pressed */
if (ctrlc()) {
puts("\nAbort\n");
return 0;
}
udelay(1000);
}
if (*ptr == PCI_RECONFIG_MAGIC) {
/*
* Save own pci configuration in PRAM
*/
memset((char *)PCI_REGS_ADDR, 0, PCI_REGS_LEN);
ptr = (unsigned int *)PCI_REGS_ADDR + 1;
for (i=0; i<0x40; i+=4) {
pci_read_config_dword(PCIDEVID_405GP, i, ptr++);
}
ptr = (unsigned int *)PCI_REGS_ADDR;
*ptr = crc32(0, (char *)PCI_REGS_ADDR+4, PCI_REGS_LEN-4);
printf("\nStoring PCI Configuration Regs...\n");
} else {
sprintf(addr, "%08x", *ptr);
/*
* Boot image
*/
printf("\nBooting image at addr 0x%s ...\n", addr);
setenv("loadaddr", addr);
local_args[0] = argv[0];
local_args[1] = NULL;
status = do_bootm (cmdtp, 0, 1, local_args);
}
return 0;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -29,25 +29,15 @@
#include <pci.h>
#include <405gp_pci.h>
#include "pci405.h"
/* ------------------------------------------------------------------------- */
#if 0
#define FPGA_DEBUG
#endif
#define PCI_RECONFIG_MAGIC 0x07081967
struct pci_config_regs {
unsigned short command;
unsigned char latency_timer;
unsigned char int_line;
unsigned long bar1;
unsigned long bar2;
unsigned long magic;
};
/* fpga configuration data - generated by bin2cc */
const unsigned char fpgadata[] =
{
@@ -113,7 +103,8 @@ int misc_init_r (void)
int status;
int index;
int i;
struct pci_config_regs *pci_regs;
unsigned int *ptr;
unsigned int *magic;
/*
* On PCI-405 the environment is saved in eeprom!
@@ -171,32 +162,33 @@ int misc_init_r (void)
putc ('\n');
/*
* Rewrite pci config regs (only after soft-reset with magic set)
* Reset FPGA via FPGA_DATA pin
*/
pci_regs = (struct pci_config_regs *)0x10;
if (pci_regs->magic == PCI_RECONFIG_MAGIC) {
puts("PCI: Found magic, rewriting config regs...\n");
pci_write_config_word(PCIDEVID_405GP, PCI_COMMAND,
pci_regs->command);
pci_write_config_byte(PCIDEVID_405GP, PCI_LATENCY_TIMER,
pci_regs->latency_timer);
pci_write_config_byte(PCIDEVID_405GP, PCI_INTERRUPT_LINE,
pci_regs->int_line);
pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_1,
pci_regs->bar1);
pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2,
pci_regs->bar2);
}
pci_regs->magic = 0; /* clear magic again */
SET_FPGA(FPGA_PRG | FPGA_CLK);
udelay(1000); /* wait 1ms */
SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
udelay(1000); /* wait 1ms */
#if 0 /* test-only */
pci_read_config_word(PCIDEVID_405GP, PCI_COMMAND, &(pci_regs->command));
pci_read_config_byte(PCIDEVID_405GP, PCI_LATENCY_TIMER, &(pci_regs->latency_timer));
pci_read_config_byte(PCIDEVID_405GP, PCI_INTERRUPT_LINE, &(pci_regs->int_line));
pci_read_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_1, &(pci_regs->bar1));
pci_read_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2, &(pci_regs->bar2));
pci_regs->magic = PCI_RECONFIG_MAGIC; /* set magic */
#endif
/*
* Check if magic for pci reconfig is written
*/
magic = (unsigned int *)0x00000004;
if (*magic == PCI_RECONFIG_MAGIC) {
/*
* Rewrite pci config regs (only after soft-reset with magic set)
*/
ptr = (unsigned int *)PCI_REGS_ADDR;
if (crc32(0, (char *)PCI_REGS_ADDR+4, PCI_REGS_LEN-4) == *ptr) {
puts("Restoring PCI Configurations Regs!\n");
ptr = (unsigned int *)PCI_REGS_ADDR + 1;
for (i=0; i<0x40; i+=4) {
pci_write_config_dword(PCIDEVID_405GP, i, *ptr++);
}
}
mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
*magic = 0; /* clear pci reconfig magic again */
}
free(dst);
return (0);
@@ -215,7 +207,7 @@ int checkboard (void)
puts ("Board: ");
if (i == -1) {
puts ("### No HW ID - assuming CPCI405");
puts ("### No HW ID - assuming PCI405");
} else {
puts (str);
}
@@ -238,7 +230,11 @@ long int initdram (int board_type)
printf("strap=%x\n", mfdcr(strap)); /* test-only */
#endif
#if 0 /* test-only: all PCI405 version must report 16mb */
return (4*1024*1024 << ((val & 0x000e0000) >> 17));
#else
return (16*1024*1024);
#endif
}
/* ------------------------------------------------------------------------- */

32
board/esd/pci405/pci405.h Normal file
View File

@@ -0,0 +1,32 @@
/*
* (C) Copyright 2003
* Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef _PCI405_H_
#define _PCI405_H_
#define PCI_REGS_LEN 0x100
#define PCI_REGS_ADDR ((unsigned long)0x01000000 - PCI_REGS_LEN)
#define PCI_RECONFIG_MAGIC 0x07081967
#endif /* _PCI405_H_ */

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;
}
/*
@@ -603,7 +620,7 @@ pci_init_board(void)
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_board(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,

41
board/incaip/Makefile Normal file
View File

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

32
board/incaip/config.mk Normal file
View File

@@ -0,0 +1,32 @@
#
# (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
#
#
# INCA-IP board with MIPS 4Kc CPU core
#
# ROM version
TEXT_BASE = 0xB0000000
# RAM version
#TEXT_BASE = 0x80100000

671
board/incaip/flash.c Normal file
View File

@@ -0,0 +1,671 @@
/*
* (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 <common.h>
#include <asm/inca-ip.h>
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/* NOTE - CONFIG_FLASH_16BIT means the CPU interface is 16-bit, it
* has nothing to do with the flash chip being 8-bit or 16-bit.
*/
#ifdef CONFIG_FLASH_16BIT
typedef unsigned short FLASH_PORT_WIDTH;
typedef volatile unsigned short FLASH_PORT_WIDTHV;
#define FLASH_ID_MASK 0xFFFF
#else
typedef unsigned long FLASH_PORT_WIDTH;
typedef volatile unsigned long FLASH_PORT_WIDTHV;
#define FLASH_ID_MASK 0xFFFFFFFF
#endif
#define FPW FLASH_PORT_WIDTH
#define FPWV FLASH_PORT_WIDTHV
#define ORMASK(size) ((-size) & OR_AM_MSK)
#if 0
#define FLASH_CYCLE1 0x0555
#define FLASH_CYCLE2 0x02aa
#else
#define FLASH_CYCLE1 0x0554
#define FLASH_CYCLE2 0x02ab
#endif
/*-----------------------------------------------------------------------
* Functions
*/
static ulong flash_get_size(FPWV *addr, flash_info_t *info);
static void flash_reset(flash_info_t *info);
static int write_word_intel(flash_info_t *info, FPWV *dest, FPW data);
static int write_word_amd(flash_info_t *info, FPWV *dest, FPW data);
static void flash_get_offsets(ulong base, flash_info_t *info);
static flash_info_t *flash_get_info(ulong base);
/*-----------------------------------------------------------------------
* flash_init()
*
* sets up flash_info and returns size of FLASH (bytes)
*/
unsigned long flash_init (void)
{
unsigned long size = 0;
int i;
/* Init: no FLASHes known */
for (i=0; i < CFG_MAX_FLASH_BANKS; ++i) {
ulong flashbase = (i == 0) ? PHYS_FLASH_1 : PHYS_FLASH_2;
ulong * buscon = (ulong *)
((i == 0) ? INCA_IP_EBU_EBU_BUSCON0 : INCA_IP_EBU_EBU_BUSCON2);
/* Disable write protection */
*buscon &= ~INCA_IP_EBU_EBU_BUSCON1_WRDIS;
#if 1
memset(&flash_info[i], 0, sizeof(flash_info_t));
#endif
flash_info[i].size =
flash_get_size((FPW *)flashbase, &flash_info[i]);
if (flash_info[i].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx\n",
i, flash_info[i].size);
}
size += flash_info[i].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_get_info(CFG_MONITOR_BASE));
#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_get_info(CFG_ENV_ADDR));
#endif
return size;
}
/*-----------------------------------------------------------------------
*/
static void flash_reset(flash_info_t *info)
{
FPWV *base = (FPWV *)(info->start[0]);
/* Put FLASH back in read mode */
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
*base = (FPW)0x00FF00FF; /* Intel Read Mode */
else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
*base = (FPW)0x00F000F0; /* AMD Read Mode */
}
/*-----------------------------------------------------------------------
*/
static void flash_get_offsets (ulong base, flash_info_t *info)
{
int i;
/* set up sector start address table */
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL
&& (info->flash_id & FLASH_BTYPE)) {
int bootsect_size; /* number of bytes/boot sector */
int sect_size; /* number of bytes/regular sector */
bootsect_size = 0x00002000 * (sizeof(FPW)/2);
sect_size = 0x00010000 * (sizeof(FPW)/2);
/* set sector offsets for bottom boot block type */
for (i = 0; i < 8; ++i) {
info->start[i] = base + (i * bootsect_size);
}
for (i = 8; i < info->sector_count; i++) {
info->start[i] = base + ((i - 7) * sect_size);
}
}
else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
&& (info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U) {
int sect_size; /* number of bytes/sector */
sect_size = 0x00010000 * (sizeof(FPW)/2);
/* set up sector start address table (uniform sector type) */
for( i = 0; i < info->sector_count; i++ )
info->start[i] = base + (i * sect_size);
}
}
/*-----------------------------------------------------------------------
*/
static flash_info_t *flash_get_info(ulong base)
{
int i;
flash_info_t * info;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
info = & flash_info[i];
if (info->start[0] <= base && base < info->start[0] + info->size)
break;
}
return i == CFG_MAX_FLASH_BANKS ? 0 : info;
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
uchar *boottype;
uchar *bootletter;
uchar *fmt;
uchar botbootletter[] = "B";
uchar topbootletter[] = "T";
uchar botboottype[] = "bottom boot sector";
uchar topboottype[] = "top boot sector";
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD: printf ("AMD "); break;
case FLASH_MAN_BM: printf ("BRIGHT MICRO "); break;
case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
case FLASH_MAN_SST: printf ("SST "); break;
case FLASH_MAN_STM: printf ("STM "); break;
case FLASH_MAN_INTEL: printf ("INTEL "); break;
default: printf ("Unknown Vendor "); break;
}
/* check for top or bottom boot, if it applies */
if (info->flash_id & FLASH_BTYPE) {
boottype = botboottype;
bootletter = botbootletter;
}
else {
boottype = topboottype;
bootletter = topbootletter;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AM640U:
fmt = "29LV641D (64 Mbit, uniform sectors)\n";
break;
case FLASH_28F800C3B:
case FLASH_28F800C3T:
fmt = "28F800C3%s (8 Mbit, %s)\n";
break;
case FLASH_INTEL800B:
case FLASH_INTEL800T:
fmt = "28F800B3%s (8 Mbit, %s)\n";
break;
case FLASH_28F160C3B:
case FLASH_28F160C3T:
fmt = "28F160C3%s (16 Mbit, %s)\n";
break;
case FLASH_INTEL160B:
case FLASH_INTEL160T:
fmt = "28F160B3%s (16 Mbit, %s)\n";
break;
case FLASH_28F320C3B:
case FLASH_28F320C3T:
fmt = "28F320C3%s (32 Mbit, %s)\n";
break;
case FLASH_INTEL320B:
case FLASH_INTEL320T:
fmt = "28F320B3%s (32 Mbit, %s)\n";
break;
case FLASH_28F640C3B:
case FLASH_28F640C3T:
fmt = "28F640C3%s (64 Mbit, %s)\n";
break;
case FLASH_INTEL640B:
case FLASH_INTEL640T:
fmt = "28F640B3%s (64 Mbit, %s)\n";
break;
default:
fmt = "Unknown Chip Type\n";
break;
}
printf (fmt, bootletter, boottype);
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20,
info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0) {
printf ("\n ");
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
}
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
ulong flash_get_size (FPWV *addr, flash_info_t *info)
{
/* Write auto select command: read Manufacturer ID */
/* Write auto select command sequence and test FLASH answer */
addr[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* for AMD, Intel ignores this */
addr[FLASH_CYCLE2] = (FPW)0x00550055; /* for AMD, Intel ignores this */
addr[FLASH_CYCLE1] = (FPW)0x00900090; /* selects Intel or AMD */
/* The manufacturer codes are only 1 byte, so just use 1 byte.
* This works for any bus width and any FLASH device width.
*/
switch (addr[1] & 0xff) {
case (uchar)AMD_MANUFACT:
info->flash_id = FLASH_MAN_AMD;
break;
case (uchar)INTEL_MANUFACT:
info->flash_id = FLASH_MAN_INTEL;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
break;
}
/* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
if (info->flash_id != FLASH_UNKNOWN) switch (addr[0]) {
case (FPW)AMD_ID_LV640U: /* 29LV640 and 29LV641 have same ID */
info->flash_id += FLASH_AM640U;
info->sector_count = 128;
info->size = 0x00800000 * (sizeof(FPW)/2);
break; /* => 8 or 16 MB */
case (FPW)INTEL_ID_28F800C3B:
info->flash_id += FLASH_28F800C3B;
info->sector_count = 23;
info->size = 0x00100000 * (sizeof(FPW)/2);
break; /* => 1 or 2 MB */
case (FPW)INTEL_ID_28F800B3B:
info->flash_id += FLASH_INTEL800B;
info->sector_count = 23;
info->size = 0x00100000 * (sizeof(FPW)/2);
break; /* => 1 or 2 MB */
case (FPW)INTEL_ID_28F160C3B:
info->flash_id += FLASH_28F160C3B;
info->sector_count = 39;
info->size = 0x00200000 * (sizeof(FPW)/2);
break; /* => 2 or 4 MB */
case (FPW)INTEL_ID_28F160B3B:
info->flash_id += FLASH_INTEL160B;
info->sector_count = 39;
info->size = 0x00200000 * (sizeof(FPW)/2);
break; /* => 2 or 4 MB */
case (FPW)INTEL_ID_28F320C3B:
info->flash_id += FLASH_28F320C3B;
info->sector_count = 71;
info->size = 0x00400000 * (sizeof(FPW)/2);
break; /* => 4 or 8 MB */
case (FPW)INTEL_ID_28F320B3B:
info->flash_id += FLASH_INTEL320B;
info->sector_count = 71;
info->size = 0x00400000 * (sizeof(FPW)/2);
break; /* => 4 or 8 MB */
case (FPW)INTEL_ID_28F640C3B:
info->flash_id += FLASH_28F640C3B;
info->sector_count = 135;
info->size = 0x00800000 * (sizeof(FPW)/2);
break; /* => 8 or 16 MB */
case (FPW)INTEL_ID_28F640B3B:
info->flash_id += FLASH_INTEL640B;
info->sector_count = 135;
info->size = 0x00800000 * (sizeof(FPW)/2);
break; /* => 8 or 16 MB */
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* => no or unknown flash */
}
flash_get_offsets((ulong)addr, info);
/* Put FLASH back in read mode */
flash_reset(info);
return (info->size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
FPWV *addr;
int flag, prot, sect;
int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
ulong start, now, last;
int rcode = 0;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_INTEL800B:
case FLASH_INTEL160B:
case FLASH_INTEL320B:
case FLASH_INTEL640B:
case FLASH_28F800C3B:
case FLASH_28F160C3B:
case FLASH_28F320C3B:
case FLASH_28F640C3B:
case FLASH_AM640U:
break;
case FLASH_UNKNOWN:
default:
printf ("Can't erase unknown flash type %08lx - aborted\n",
info->flash_id);
return 1;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
last = get_timer(0);
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last && rcode == 0; sect++) {
if (info->protect[sect] != 0) /* protected, skip it */
continue;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr = (FPWV *)(info->start[sect]);
if (intel) {
*addr = (FPW)0x00500050; /* clear status register */
*addr = (FPW)0x00200020; /* erase setup */
*addr = (FPW)0x00D000D0; /* erase confirm */
}
else {
/* must be AMD style if not Intel */
FPWV *base; /* first address in bank */
base = (FPWV *)(info->start[0]);
base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
base[FLASH_CYCLE1] = (FPW)0x00800080; /* erase mode */
base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
*addr = (FPW)0x00300030; /* erase sector */
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
start = get_timer(0);
/* wait at least 50us for AMD, 80us for Intel.
* Let's wait 1 ms.
*/
udelay (1000);
while ((*addr & (FPW)0x00800080) != (FPW)0x00800080) {
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
if (intel) {
/* suspend erase */
*addr = (FPW)0x00B000B0;
}
flash_reset(info); /* reset to read mode */
rcode = 1; /* failed */
break;
}
/* show that we're waiting */
if ((get_timer(last)) > CFG_HZ) {/* every second */
putc ('.');
last = get_timer(0);
}
}
/* show that we're waiting */
if ((get_timer(last)) > CFG_HZ) { /* every second */
putc ('.');
last = get_timer(0);
}
flash_reset(info); /* reset to read mode */
}
printf (" done\n");
return rcode;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
int bytes; /* number of bytes to program in current word */
int left; /* number of bytes left to program */
int i, res;
for (left = cnt, res = 0;
left > 0 && res == 0;
addr += sizeof(data), left -= sizeof(data) - bytes) {
bytes = addr & (sizeof(data) - 1);
addr &= ~(sizeof(data) - 1);
/* combine source and destination data so can program
* an entire word of 16 or 32 bits
*/
for (i = 0; i < sizeof(data); i++) {
data <<= 8;
if (i < bytes || i - bytes >= left )
data += *((uchar *)addr + i);
else
data += *src++;
}
/* write one word to the flash */
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD:
res = write_word_amd(info, (FPWV *)addr, data);
break;
case FLASH_MAN_INTEL:
res = write_word_intel(info, (FPWV *)addr, data);
break;
default:
/* unknown flash type, error! */
printf ("missing or unknown FLASH type\n");
res = 1; /* not really a timeout, but gives error */
break;
}
}
return (res);
}
/*-----------------------------------------------------------------------
* Write a word to Flash for AMD FLASH
* A word is 16 or 32 bits, whichever the bus width of the flash bank
* (not an individual chip) is.
*
* returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data)
{
ulong start;
int flag;
int res = 0; /* result, assume success */
FPWV *base; /* first address in flash bank */
/* Check if Flash is (sufficiently) erased */
if ((*dest & data) != data) {
return (2);
}
base = (FPWV *)(info->start[0]);
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
base[FLASH_CYCLE1] = (FPW)0x00A000A0; /* selects program mode */
*dest = data; /* start programming the data */
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
start = get_timer (0);
/* data polling for D7 */
while (res == 0 && (*dest & (FPW)0x00800080) != (data & (FPW)0x00800080)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
*dest = (FPW)0x00F000F0; /* reset bank */
res = 1;
}
}
return (res);
}
/*-----------------------------------------------------------------------
* Write a word to Flash for Intel FLASH
* A word is 16 or 32 bits, whichever the bus width of the flash bank
* (not an individual chip) is.
*
* returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word_intel (flash_info_t *info, FPWV *dest, FPW data)
{
ulong start;
int flag;
int res = 0; /* result, assume success */
/* Check if Flash is (sufficiently) erased */
if ((*dest & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
*dest = (FPW)0x00500050; /* clear status register */
*dest = (FPW)0x00FF00FF; /* make sure in read mode */
*dest = (FPW)0x00400040; /* program setup */
*dest = data; /* start programming the data */
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
start = get_timer (0);
while (res == 0 && (*dest & (FPW)0x00800080) != (FPW)0x00800080) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
*dest = (FPW)0x00B000B0; /* Suspend program */
res = 1;
}
}
if (res == 0 && (*dest & (FPW)0x00100010))
res = 1; /* write failed, time out error is close enough */
*dest = (FPW)0x00500050; /* clear status register */
*dest = (FPW)0x00FF00FF; /* make sure in read mode */
return (res);
}

157
board/incaip/incaip.c Normal file
View File

@@ -0,0 +1,157 @@
/*
* (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 <common.h>
#include <command.h>
#include <asm/addrspace.h>
#include <asm/inca-ip.h>
extern uint incaip_get_cpuclk(void);
static ulong max_sdram_size(void)
{
/* The only supported SDRAM data width is 16bit.
*/
#define CFG_DW 2
/* The only supported number of SDRAM banks is 4.
*/
#define CFG_NB 4
ulong cfgpb0 = *INCA_IP_SDRAM_MC_CFGPB0;
int cols = cfgpb0 & 0xF;
int rows = (cfgpb0 & 0xF0) >> 4;
ulong size = (1 << (rows + cols)) * CFG_DW * CFG_NB;
return size;
}
/*
* Check memory range for valid RAM. A simple memory test determines
* the actually available RAM size between addresses `base' and
* `base + maxsize'. Some (not all) hardware errors are detected:
* - short between address lines
* - short between data lines
*/
static long int dram_size(long int *base, long int maxsize)
{
volatile long int *addr;
ulong cnt, val;
ulong save[32]; /* to make test non-destructive */
unsigned char i = 0;
for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) {
addr = base + cnt; /* pointer arith! */
save[i++] = *addr;
*addr = ~cnt;
}
/* write 0 to base address */
addr = base;
save[i] = *addr;
*addr = 0;
/* check at base address */
if ((val = *addr) != 0) {
*addr = save[i];
return (0);
}
for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
addr = base + cnt; /* pointer arith! */
val = *addr;
*addr = save[--i];
if (val != (~cnt)) {
return (cnt * sizeof (long));
}
}
return (maxsize);
}
long int initdram(int board_type)
{
int rows, cols, best_val = *INCA_IP_SDRAM_MC_CFGPB0;
ulong size, max_size = 0;
ulong our_address;
asm volatile ("move %0, $25" : "=r" (our_address) :);
/* Can't probe for RAM size unless we are running from Flash.
*/
if (PHYSADDR(our_address) < PHYSADDR(PHYS_FLASH_1))
{
return max_sdram_size();
}
for (cols = 0x8; cols <= 0xC; cols++)
{
for (rows = 0xB; rows <= 0xD; rows++)
{
*INCA_IP_SDRAM_MC_CFGPB0 = (0x14 << 8) |
(rows << 4) | cols;
size = dram_size((ulong *)CFG_SDRAM_BASE,
max_sdram_size());
if (size > max_size)
{
best_val = *INCA_IP_SDRAM_MC_CFGPB0;
max_size = size;
}
}
}
*INCA_IP_SDRAM_MC_CFGPB0 = best_val;
return max_size;
}
int checkboard (void)
{
unsigned long chipid = *INCA_IP_WDT_CHIPID;
int part_num;
puts ("Board: INCA-IP ");
part_num = (chipid >> 12) & 0xffff;
switch (part_num) {
case 0xc0:
printf ("Standard Version, ");
break;
case 0xc1:
printf ("Basic Version, ");
break;
default:
printf ("Unknown Part Number 0x%x ", part_num);
break;
}
printf ("Chip V1.%ld, ", (chipid >> 28));
printf("CPU Speed %d MHz\n", incaip_get_cpuclk()/1000000);
return 0;
}

151
board/incaip/memsetup.S Normal file
View File

@@ -0,0 +1,151 @@
/*
* Memory sub-system initialization code for INCA-IP development board.
*
* Copyright (c) 2003 Wolfgang Denk <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 <config.h>
#include <version.h>
#include <asm/regdef.h>
#define EBU_MODUL_BASE 0xB8000200
#define EBU_CLC(value) 0x0000(value)
#define EBU_CON(value) 0x0010(value)
#define EBU_ADDSEL0(value) 0x0020(value)
#define EBU_ADDSEL1(value) 0x0024(value)
#define EBU_ADDSEL2(value) 0x0028(value)
#define EBU_BUSCON0(value) 0x0060(value)
#define EBU_BUSCON1(value) 0x0064(value)
#define EBU_BUSCON2(value) 0x0068(value)
#define MC_MODUL_BASE 0xBF800000
#define MC_ERRCAUSE(value) 0x0100(value)
#define MC_ERRADDR(value) 0x0108(value)
#define MC_IOGP(value) 0x0800(value)
#define MC_SELFRFSH(value) 0x0A00(value)
#define MC_CTRLENA(value) 0x1000(value)
#define MC_MRSCODE(value) 0x1008(value)
#define MC_CFGDW(value) 0x1010(value)
#define MC_CFGPB0(value) 0x1018(value)
#define MC_LATENCY(value) 0x1038(value)
#define MC_TREFRESH(value) 0x1040(value)
#if CPU_CLOCK_RATE==150000000 /* 150 MHz clock for the MIPS core */
#define CGU_MODUL_BASE 0xBF107000
#define CGU_PLL1CR(value) 0x0008(value)
#define CGU_DIVCR(value) 0x0010(value)
#define CGU_MUXCR(value) 0x0014(value)
#define CGU_PLL1SR(value) 0x000C(value)
#endif
.globl memsetup
memsetup:
/* EBU Initialization for the Flash CS0 and CS2.
*/
li t0, EBU_MODUL_BASE
li t1, 0xA0000041
sw t1, EBU_ADDSEL0(t0)
#if CPU_CLOCK_RATE==150000000 /* 150 MHz clock for the MIPS core */
li t1, 0xA841417E
sw t1, EBU_BUSCON0(t0) /* value set up by magic flash word */
sw t1, EBU_BUSCON2(t0)
#else /* 100 MHz */
lw t1, EBU_BUSCON0(t0) /* value set up by magic flash word */
sw t1, EBU_BUSCON2(t0)
#endif
li t1, 0xA0800041
sw t1, EBU_ADDSEL2(t0)
/* Need to initialize CS1 too, so as to to prevent overlapping with
* Flash bank 1.
*/
li t1, 0xBE0000F1
sw t1, EBU_ADDSEL1(t0)
#if CPU_CLOCK_RATE==150000000 /* 150 MHz clock for the MIPS core */
li t1, 0x684143FD
#else /* 100 MHz */
li t1, 0x684142BD
#endif
sw t1, EBU_BUSCON1(t0)
#if CPU_CLOCK_RATE==150000000 /* 150 MHz clock for the MIPS core */
li t0, CGU_MODUL_BASE
li t1, 0x80000017
sw t1, CGU_DIVCR(t0)
li t1, 0xC00B0001
sw t1, CGU_PLL1CR(t0)
lui t2, 0x8000
b1:
lw t1, CGU_PLL1SR(t0)
and t1, t1, t2
beq t1, zero, b1
li t1, 0x80000001
sw t1, CGU_MUXCR(t0)
#endif
/* SDRAM Initialization.
*/
li t0, MC_MODUL_BASE
/* Clear Error log registers */
sw zero, MC_ERRCAUSE(t0)
sw zero, MC_ERRADDR(t0)
/* Set clock ratio to 1:1 */
li t1, 0x03 /* clkrat=1:1, rddel=3 */
sw t1, MC_IOGP(t0)
/* Clear Power-down registers */
sw zero, MC_SELFRFSH(t0)
/* Set CAS Latency */
li t1, 0x00000020 /* CL = 2 */
sw t1, MC_MRSCODE(t0)
/* Set word width to 16 bit */
li t1, 0x2
sw t1, MC_CFGDW(t0)
/* Set CS0 to SDRAM parameters */
li t1, 0x000014C9
sw t1, MC_CFGPB0(t0)
/* Set SDRAM latency parameters */
li t1, 0x00026325 /* BC PC100 */
sw t1, MC_LATENCY(t0)
/* Set SDRAM refresh rate */
li t1, 0x00000C30 /* 4K/64ms @ 100MHz */
sw t1, MC_TREFRESH(t0)
/* Finally enable the controller */
li t1, 1
sw t1, MC_CTRLENA(t0)
j ra
nop

64
board/incaip/u-boot.lds Normal file
View File

@@ -0,0 +1,64 @@
/*
* (C) Copyright 2003
* Wolfgang Denk 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-bigmips", "elf32-bigmips", "elf32-bigmips")
*/
OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradbigmips")
OUTPUT_ARCH(mips)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
*(.text)
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.sdata : { *(.sdata) }
_gp = ALIGN(16);
__got_start = .;
.got : { *(.got) }
__got_end = .;
.sdata : { *(.sdata) }
uboot_end_data = .;
num_got_entries = (__got_end - __got_start) >> 2;
. = ALIGN(4);
.sbss : { *(.sbss) }
.bss : { *(.bss) }
uboot_end = .;
}

View File

@@ -9,6 +9,10 @@
* (C) Copyright 2002
* Robert Schwebel, Pengutronix, <r.schwebel@pengutronix.de>
*
* (C) Copyright 2002
* Auerswald GmbH & Co KG, Germany
* Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
@@ -31,12 +35,223 @@
#include <common.h>
#include <asm/arch/pxa-regs.h>
#define FLASH_BANK_SIZE 0x02000000
#define MAIN_SECT_SIZE 0x40000 /* 2x16 = 256k per sector */
#if defined CFG_JFFS_CUSTOM_PART
#include <jffs2/jffs2.h>
#endif
/* Debugging macros ------------------------------------------------------ */
#undef FLASH_DEBUG
//#define FLASH_DEBUG 1
/* Some debug macros */
#if (FLASH_DEBUG > 2 )
#define PRINTK3(args...) printf(args)
#else
#define PRINTK3(args...)
#endif
#if FLASH_DEBUG > 1
#define PRINTK2(args...) printf(args)
#else
#define PRINTK2(args...)
#endif
#ifdef FLASH_DEBUG
#define PRINTK(args...) printf(args)
#else
#define PRINTK(args...)
#endif
/* ------------------------------------------------------------------------ */
/* Development system: we have only 16 MB Flash */
#ifdef CONFIG_MTD_INNOKOM_16MB
#define FLASH_BANK_SIZE 0x01000000 /* 16 MB (during development) */
#define MAIN_SECT_SIZE 0x00020000 /* 128k per sector */
#endif
/* Production system: we have 64 MB Flash */
#ifdef CONFIG_MTD_INNOKOM_64MB
#define FLASH_BANK_SIZE 0x04000000 /* 64 MB */
#define MAIN_SECT_SIZE 0x00020000 /* 128k per sector */
#endif
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
#if defined CFG_JFFS_CUSTOM_PART
/**
* jffs2_part_info - get information about a JFFS2 partition
*
* @part_num: number of the partition you want to get info about
* @return: struct part_info* in case of success, 0 if failure
*/
static struct part_info part;
static int current_part = -1;
#ifdef CONFIG_MTD_INNOKOM_16MB
#ifdef CONFIG_MTD_INNOKOM_64MB
#error Please define only one CONFIG_MTD_INNOKOM_XXMB option.
#endif
struct part_info* jffs2_part_info(int part_num) {
void *jffs2_priv_saved = part.jffs2_priv;
PRINTK2("jffs2_part_info: part_num=%i\n",part_num);
if (current_part == part_num)
return &part;
/* u-boot partition */
if(part_num==0){
memset(&part, 0, sizeof(part));
part.offset=(char*)0x00000000;
part.size=256*1024;
/* Mark the struct as ready */
current_part = part_num;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
}
/* primary OS+firmware partition */
if(part_num==1){
memset(&part, 0, sizeof(part));
part.offset=(char*)0x00040000;
part.size=768*1024;
/* Mark the struct as ready */
current_part = part_num;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
}
/* secondary OS+firmware partition */
if(part_num==2){
memset(&part, 0, sizeof(part));
part.offset=(char*)0x00100000;
part.size=8*1024*1024;
/* Mark the struct as ready */
current_part = part_num;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
}
/* data partition */
if(part_num==3){
memset(&part, 0, sizeof(part));
part.offset=(char*)0x00900000;
part.size=7*1024*1024;
/* Mark the struct as ready */
current_part = part_num;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
}
if (current_part == part_num) {
part.usr_priv = &current_part;
part.jffs2_priv = jffs2_priv_saved;
return &part;
}
PRINTK("jffs2_part_info: end of partition table\n");
return 0;
}
#endif /* CONFIG_MTD_INNOKOM_16MB */
#ifdef CONFIG_MTD_INNOKOM_64MB
#ifdef CONFIG_MTD_INNOKOM_16MB
#error Please define only one CONFIG_MTD_INNOKOM_XXMB option.
#endif
struct part_info* jffs2_part_info(int part_num) {
void *jffs2_priv_saved = part.jffs2_priv;
PRINTK2("jffs2_part_info: part_num=%i\n",part_num);
if (current_part == part_num)
return &part;
/* u-boot partition */
if(part_num==0){
memset(&part, 0, sizeof(part));
part.offset=(char*)0x00000000;
part.size=256*1024;
/* Mark the struct as ready */
current_part = part_num;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
}
/* primary OS+firmware partition */
if(part_num==1){
memset(&part, 0, sizeof(part));
part.offset=(char*)0x00040000;
part.size=16*1024*1024-128*1024;
/* Mark the struct as ready */
current_part = part_num;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
}
/* secondary OS+firmware partition */
if(part_num==2){
memset(&part, 0, sizeof(part));
part.offset=(char*)0x01020000;
part.size=16*1024*1024-128*1024;
/* Mark the struct as ready */
current_part = part_num;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
}
/* data partition */
if(part_num==3){
memset(&part, 0, sizeof(part));
part.offset=(char*)0x02000000;
part.size=32*1024*1024;
/* Mark the struct as ready */
current_part = part_num;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
}
if (current_part == part_num) {
part.usr_priv = &current_part;
part.jffs2_priv = jffs2_priv_saved;
return &part;
}
PRINTK("jffs2_part_info: end of partition table\n");
return 0;
}
#endif /* CONFIG_MTD_INNOKOM_64MB */
#endif /* defined CFG_JFFS_CUSTOM_PART */
/**
* flash_init: - initialize data structures for flash chips
*
@@ -71,10 +286,10 @@ ulong flash_init(void)
size += flash_info[i].size;
}
/* Protect monitor and environment sectors */
/* Protect u-boot sectors */
flash_protect(FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
CFG_FLASH_BASE + (256*1024) - 1,
&flash_info[0]);
#ifdef CFG_ENV_IS_IN_FLASH
@@ -120,13 +335,13 @@ void flash_print_info (flash_info_t *info)
return;
}
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++) {
if ((i % 5) == 0) printf ("\n ");
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
@@ -155,7 +370,7 @@ int flash_erase(flash_info_t *info, int s_first, int s_last)
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++;
@@ -178,34 +393,40 @@ int flash_erase(flash_info_t *info, int s_first, int s_last)
printf("Erasing sector %2d ... ", sect);
PRINTK("\n");
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
if (info->protect[sect] == 0) { /* not protected */
u32 * volatile addr = (u32 * volatile)(info->start[sect]);
u16 * volatile addr = (u16 * 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: */
PRINTK("unlocking sector\n");
*addr = 0x0060;
*addr = 0x00d0;
*addr = 0x00ff;
*addr = 0x00200020; /* erase setup */
*addr = 0x00D000D0; /* erase confirm */
PRINTK("erasing sector\n");
*addr = 0x0020;
PRINTK("confirming erase\n");
*addr = 0x00D0;
while ((*addr & 0x00800080) != 0x00800080) {
while ((*addr & 0x0080) != 0x0080) {
PRINTK(".");
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
*addr = 0x00B000B0; /* suspend erase*/
*addr = 0x00FF00FF; /* read mode */
*addr = 0x00B0; /* suspend erase*/
*addr = 0x00FF; /* read mode */
rc = ERR_TIMOUT;
goto outahere;
}
}
*addr = 0x00500050; /* clear status register cmd. */
*addr = 0x00FF00FF; /* resest to read mode */
PRINTK("clearing status register\n");
*addr = 0x0050;
PRINTK("resetting to read mode");
*addr = 0x00FF;
}
printf("ok.\n");
}
@@ -233,7 +454,7 @@ int flash_erase(flash_info_t *info, int s_first, int s_last)
static int write_word (flash_info_t *info, ulong dest, ushort data)
{
ushort *addr = (ushort *)dest, val;
volatile u16 *addr = (u16 *)dest, val;
int rc = ERR_OK;
int flag;

View File

@@ -25,6 +25,7 @@
#include <common.h>
#include <asm/arch/pxa-regs.h>
#include <asm/mach-types.h>
#ifdef CONFIG_SHOW_BOOT_PROGRESS
# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
@@ -32,9 +33,58 @@
# define SHOW_BOOT_PROGRESS(arg)
#endif
/*
* Miscelaneous platform dependent initialisations
/**
* i2c_init_board - reset i2c bus. When the board is powercycled during a
* bus transfer it might hang; for details see doc/I2C_Edge_Conditions.
* The Innokom board has GPIO70 connected to SCLK which can be toggled
* until all chips think that their current cycles are finished.
*/
int i2c_init_board(void)
{
int i, icr;
/* disable I2C controller first, otherwhise it thinks we want to */
/* talk to the slave port... */
icr = ICR; ICR &= ~(ICR_SCLE | ICR_IUE);
/* set gpio pin low _before_ we change direction to output */
GPCR(70) = GPIO_bit(70);
/* now toggle between output=low and high-impedance */
for (i = 0; i < 20; i++) {
GPDR(70) |= GPIO_bit(70); /* output */
udelay(10);
GPDR(70) &= ~GPIO_bit(70); /* input */
udelay(10);
}
ICR = icr;
return 0;
}
/**
* misc_init_r: - misc initialisation routines
*/
int misc_init_r(void)
{
uchar *str;
/* determine if the software update key is pressed during startup */
if (GPLR0 & 0x00000800) {
printf("using bootcmd_normal (sw-update button not pressed)\n");
str = getenv("bootcmd_normal");
} else {
printf("using bootcmd_update (sw-update button pressed)\n");
str = getenv("bootcmd_update");
}
setenv("bootcmd",str);
return 0;
}
/**
@@ -50,11 +100,9 @@ int board_init (void)
/* 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_arch_number = MACH_TYPE_INNOKOM;
gd->bd->bi_boot_params = 0xa0000100;
gd->bd->bi_baudrate = CONFIG_BAUDRATE;
return 0;
}

View File

@@ -38,6 +38,9 @@ DRAM_SIZE: .long CFG_DRAM_SIZE
sub pc,pc,#4
.endm
_TEXT_BASE:
.word TEXT_BASE
/*
* Memory setup
@@ -222,24 +225,29 @@ mem_init:
/* Step 2c: Write FLYCNFG FIXME: what's that??? */
/* ---------------------------------------------------------------- */
/* test if we run from flash or RAM - RAM/BDI: don't setup RAM */
adr r3, mem_init /* r0 <- current position of code */
ldr r2, =mem_init
cmp r3, r2 /* skip init if in place */
beq initirqs
/* ---------------------------------------------------------------- */
/* Step 2d: Initialize Timing for Sync Memory (SDCLK0) */
/* ---------------------------------------------------------------- */
/* Before accessing MDREFR we need a valid DRI field, so we set */
/* this to power on defaults + DIR field. */
/* this to power on defaults + DRI field. */
ldr r3, =CFG_MDREFR_VAL
ldr r2, =0xFFF
and r3, r3, r2
ldr r4, =0x03ca4000
orr r4, r4, r3
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) */
@@ -258,18 +266,16 @@ mem_init:
/* Step 4: Initialize SDRAM */
/* ---------------------------------------------------------------- */
/* Step 4a: assert MDREFR:K1RUN and MDREFR:K2RUN and configure */
/* Step 4a: assert MDREFR:K?RUN 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]
ldr r4, =CFG_MDREFR_VAL
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
ldr r4, [r1, #MDREFR_OFFSET]
/* Step 4b: de-assert MDREFR:SLFRSH. */
bic r4, r4, #(MDREFR_SLFRSH)
bic r4, r4, #(MDREFR_SLFRSH)
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
ldr r4, [r1, #MDREFR_OFFSET]
@@ -313,17 +319,23 @@ mem_init:
/* 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]
/* There should 9 writes, since the first write doesn't */
/* trigger a refresh cycle on PXA250. See Intel PXA250 and */
/* PXA210 Processors Specification Update, */
/* Jan 2003, Errata #116, page 30. */
ldr r3, =CFG_DRAM_BASE
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
/* Step 4g: Write MDCNFG with enable bits asserted */
/* (MDCNFG:DEx set to 1). */
@@ -339,7 +351,6 @@ mem_init:
/* We are finished with Intel's memory controller initialisation */
/* ---------------------------------------------------------------- */
/* Disable (mask) all interrupts at interrupt controller */
/* ---------------------------------------------------------------- */
@@ -405,8 +416,7 @@ initclks:
/* FIXME */
#define NODEBUG
#ifdef NODEBUG
#ifndef DEBUG
/*Disable software and data breakpoints */
mov r0,#0
mcr p15,0,r0,c14,c8,0 /* ibcr0 */
@@ -416,7 +426,6 @@ initclks:
/*Enable all debug functionality */
mov r0,#0x80000000
mcr p14,0,r0,c10,c0,0 /* dcsr */
#endif
/* ---------------------------------------------------------------- */

View File

@@ -47,7 +47,9 @@ SECTIONS
armboot_end_data = .;
. = ALIGN(4);
bss_start = .;
.bss : { *(.bss) }
bss_end = .;
armboot_end = .;
}

View File

@@ -28,7 +28,8 @@
/* ------------------------------------------------------------------------- */
static long int dram_size (long int, long int *, long int);
unsigned long ip860_get_dram_size(void);
unsigned long ip860_get_clk_freq (void);
/* ------------------------------------------------------------------------- */
#define _NOT_USED_ 0xFFFFFFFF
@@ -82,8 +83,22 @@ const uint sdram_table[] = {
_NOT_USED_, _NOT_USED_, _NOT_USED_,
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
int board_pre_init(void)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
/* init BCSR chipselect line for ip860_get_clk_freq() and ip860_get_dram_size() */
memctl->memc_or4 = CFG_OR4;
memctl->memc_br4 = CFG_BR4;
return 0;
}
/* ------------------------------------------------------------------------- */
/*
* Check Board Identity:
@@ -127,6 +142,7 @@ long int initdram (int board_type)
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
long int size;
ulong refresh_val;
upmconfig (UPMA, (uint *) sdram_table,
sizeof (sdram_table) / sizeof (uint));
@@ -134,7 +150,17 @@ long int initdram (int board_type)
/*
* Preliminary prescaler for refresh
*/
memctl->memc_mptpr = 0x0400;
if (ip860_get_clk_freq() == 50000000)
{
memctl->memc_mptpr = 0x0400;
refresh_val = 0xC3000000;
}
else
{
memctl->memc_mptpr = 0x0200;
refresh_val = 0x9C000000;
}
memctl->memc_mar = 0x00000088;
@@ -151,18 +177,22 @@ long int initdram (int board_type)
/* perform SDRAM initializsation sequence */
memctl->memc_mamr = 0xC3804114;
memctl->memc_mcr = 0x80004105; /* run precharge pattern from loc 5 */
udelay (1);
memctl->memc_mamr = 0xC3804118;
memctl->memc_mcr = 0x80004130; /* run refresh pattern 8 times */
memctl->memc_mamr = 0x00804114 | refresh_val;
memctl->memc_mcr = 0x80004105; /* run precharge pattern from loc 5 */
udelay(1);
memctl->memc_mamr = 0x00804118 | refresh_val;
memctl->memc_mcr = 0x80004130; /* run refresh pattern 8 times */
udelay (1000);
/*
* Check SDRAM Memory Size
*/
size = dram_size (CFG_MAMR, (ulong *) SDRAM_BASE, SDRAM_MAX_SIZE);
if (ip860_get_dram_size() == 16)
size = dram_size (refresh_val | 0x00804114, (ulong *)SDRAM_BASE, SDRAM_MAX_SIZE);
else
size = dram_size (refresh_val | 0x00906114, (ulong *)SDRAM_BASE, SDRAM_MAX_SIZE);
udelay (1000);
@@ -291,3 +321,68 @@ void reset_phy (void)
}
/* ------------------------------------------------------------------------- */
unsigned long ip860_get_clk_freq(void)
{
volatile ip860_bcsr_t *bcsr = (ip860_bcsr_t *)BCSR_BASE;
ulong temp;
uchar sysclk;
if ((bcsr->bd_status & 0x80) == 0x80) /* bd_rev valid ? */
sysclk = (bcsr->bd_rev & 0x18) >> 3;
else
sysclk = 0x00;
switch (sysclk)
{
case 0x00:
temp = 50000000;
break;
case 0x01:
temp = 80000000;
break;
default:
temp = 50000000;
break;
}
return (temp);
}
/* ------------------------------------------------------------------------- */
unsigned long ip860_get_dram_size(void)
{
volatile ip860_bcsr_t *bcsr = (ip860_bcsr_t *)BCSR_BASE;
ulong temp;
uchar dram_size;
if ((bcsr->bd_status & 0x80) == 0x80) /* bd_rev valid ? */
dram_size = (bcsr->bd_rev & 0xE0) >> 5;
else
dram_size = 0x00; /* default is 16 MB */
switch (dram_size)
{
case 0x00:
temp = 16;
break;
case 0x01:
temp = 32;
break;
default:
temp = 16;
break;
}
return (temp);
}
/* ------------------------------------------------------------------------- */

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,338 +25,407 @@
*/
#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;
ulong size = 0;
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;
break;
case 1:
flashbase = PHYS_FLASH_2;
break;
default:
panic("configured to many flash banks!\n");
break;
}
for (j = 0; j < flash_info[i].sector_count; j++)
{
flash_info[i].start[j] = flashbase + j*MAIN_SECT_SIZE;
}
size += flash_info[i].size;
}
/* Protect monitor and environment sectors
*/
flash_protect(FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
&flash_info[0]);
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[0]);
return size;
}
/*-----------------------------------------------------------------------
*/
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");
goto Done;
break;
}
printf(" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf(" Sector Start Addresses:");
for (i = 0; i < info->sector_count; i++)
{
if ((i % 5) == 0)
{
printf ("\n ");
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
info++;
}
Done:
}
/*-----------------------------------------------------------------------
*/
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 */
vu_short *addr = (vu_short *)(info->start[sect]);
*addr = 0x20; /* erase setup */
*addr = 0xD0; /* erase confirm */
while ((*addr & 0x80) != 0x80) {
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
*addr = 0xB0; /* suspend erase */
*addr = 0xFF; /* reset to read mode */
rc = ERR_TIMOUT;
goto outahere;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
switch (i) {
case 0:
flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]);
flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);
break;
case 1:
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;
}
}
/* clear status register command */
*addr = 0x50;
/* reset to read mode */
*addr = 0xFF;
size += flash_info[i].size;
}
printf("ok.\n");
}
if (ctrlc())
printf("User Interrupt!\n");
outahere:
/* Protect monitor and environment sectors
*/
flash_protect ( FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
&flash_info[0] );
/* allow flash to settle - wait 10 ms */
udelay_masked(10000);
flash_protect ( FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] );
if (flag)
enable_interrupts();
return rc;
return size;
}
/*-----------------------------------------------------------------------
* Copy memory to flash
*/
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;
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;
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",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
return;
}
/*
* The following code cannot be run from FLASH!
*/
static ulong flash_get_size (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;
}
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
return (info->size);
}
/*-----------------------------------------------------------------------
*/
static int write_word (flash_info_t *info, ulong dest, ushort data)
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
vu_short *addr = (vu_short *)dest, val;
int rc = ERR_OK;
int flag;
int flag, prot, sect;
ulong type, start, last;
int rcode = 0;
/* 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;
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(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;
}
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;
}
outahere:
/* read array command */
*addr = 0xFF;
prot = 0;
for (sect = s_first; sect <= s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (flag)
enable_interrupts();
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
return rc;
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; 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 ();
*addr = (FPW) 0x00500050; /* clear status register */
*addr = (FPW) 0x00200020; /* erase setup */
*addr = (FPW) 0x00D000D0; /* erase confirm */
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
*addr = (FPW) 0x00B000B0; /* suspend erase */
*addr = (FPW) 0x00FF00FF; /* reset to read mode */
rcode = 1;
break;
}
}
*addr = 0x00500050; /* clear status register cmd. */
*addr = 0x00FF00FF; /* resest to read mode */
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;
ulong cp, wp;
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
*/
if ((l = addr - wp) != 0) {
/*
* 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 < port_width && cnt > 0; ++i) {
data = (data << 8) | *src++;
--cnt;
++cp;
}
for (; cnt == 0 && i < port_width; ++i, ++cp) {
data = (data << 8) | (*(uchar *) cp);
}
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
return (rc);
}
wp += port_width;
}
/*
* handle word aligned part
*/
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);
}
wp += port_width;
cnt -= port_width;
if (count++ > 0x800) {
spin_wheel ();
count = 0;
}
}
if (cnt == 0) {
return (0);
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i=0, cp=wp; i<l; ++i, ++cp) {
data = (data >> 8) | (*(uchar *)cp << 8);
for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
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);
for (; i < port_width; ++i, ++cp) {
data = (data << 8) | (*(uchar *) cp);
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
wp += 2;
}
/*
* handle word aligned part
*/
while (cnt >= 2) {
data = *((vu_short*)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);
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;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((*addr & data) != data) {
printf ("not erased at %08lx (%lx)\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);
}
}
*addr = (FPW) 0x00FF00FF; /* restore read mode */
return (0);
}
void inline spin_wheel (void)
{
static int 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

@@ -47,7 +47,9 @@ SECTIONS
armboot_end_data = .;
. = ALIGN(4);
bss_start = .;
.bss : { *(.bss) }
bss_end = .;
armboot_end = .;
}

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

@@ -27,6 +27,7 @@
#include <video_fb.h>
#include "common_util.h"
#include <asm/processor.h>
#include <asm/byteorder.h>
#include <i2c.h>
#include <devices.h>
#include <pci.h>
@@ -39,7 +40,7 @@ extern int mem_test(unsigned long start, unsigned long ramsize, int quiet);
extern flash_info_t flash_info[]; /* info for FLASH chips */
image_header_t header;
static image_header_t header;
@@ -48,9 +49,18 @@ int mpl_prg(unsigned long src,unsigned long size)
unsigned long start;
flash_info_t *info;
int i,rc;
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
unsigned long *magic = (unsigned long *)src;
#endif
info = &flash_info[0];
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
if(ntohl(magic[0]) != IH_MAGIC) {
printf("Bad Magic number\n");
return -1;
}
start = 0 - size;
for(i=info->sector_count-1;i>0;i--)
{
@@ -60,13 +70,25 @@ int mpl_prg(unsigned long src,unsigned long size)
}
/* set-up flash location */
/* now erase flash */
if(magic[0]!=IH_MAGIC) {
printf("Bad Magic number\n");
return -1;
}
printf("Erasing at %lx (sector %d) (start %lx)\n",
start,i,info->start[i]);
flash_erase (info, i, info->sector_count-1);
#elif defined(CONFIG_VCMA9)
start = 0;
for (i = 0; i <info->sector_count; i++)
{
info->protect[i] = 0; /* unprotect this sector */
if (size < info->start[i])
break;
}
/* set-up flash location */
/* now erase flash */
printf("Erasing at %lx (sector %d) (start %lx)\n",
start,0,info->start[0]);
flash_erase (info, 0, i);
#endif
printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",src,size);
if ((rc = flash_write ((uchar *)src, start, size)) != 0) {
puts ("ERROR ");
@@ -84,7 +106,7 @@ int mpl_prg_image(unsigned long ld_addr)
image_header_t *hdr=&header;
/* Copy header so we can blank CRC field for re-calculation */
memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
if (hdr->ih_magic != IH_MAGIC) {
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
printf ("Bad Magic Number\n");
return 1;
}
@@ -99,16 +121,16 @@ int mpl_prg_image(unsigned long ld_addr)
}
data = (ulong)&header;
len = sizeof(image_header_t);
checksum = hdr->ih_hcrc;
checksum = ntohl(hdr->ih_hcrc);
hdr->ih_hcrc = 0;
if (crc32 (0, (char *)data, len) != checksum) {
printf ("Bad Header Checksum\n");
return 1;
}
data = ld_addr + sizeof(image_header_t);
len = hdr->ih_size;
len = ntohl(hdr->ih_size);
printf ("Verifying Checksum ... ");
if (crc32 (0, (char *)data, len) != hdr->ih_dcrc) {
if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
printf ("Bad Data CRC\n");
return 1;
}
@@ -152,14 +174,14 @@ void set_backup_values(int overwrite)
}
}
memcpy(back.signature,"MPL\0",4);
i=getenv_r("serial#",back.serial_name,16);
if(i==0) {
i = getenv_r("serial#",back.serial_name,16);
if(i < 0) {
printf("Not possible to write Backup\n");
return;
}
back.serial_name[16]=0;
i=getenv_r("ethaddr",back.eth_addr,20);
if(i==0) {
i = getenv_r("ethaddr",back.eth_addr,20);
if(i < 0) {
printf("Not possible to write Backup\n");
return;
}
@@ -301,7 +323,7 @@ extern char *stdio_names[];
void show_stdio_dev(void)
{
/* Print informations */
/* Print information */
printf ("In: ");
if (stdio_devices[stdin] == NULL) {
printf ("No input devices available!\n");
@@ -338,7 +360,7 @@ void show_stdio_dev(void)
#define SW_CS_PRINTF(fmt,args...)
#endif
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
int switch_cs(unsigned char boot)
{
unsigned long pbcr;
@@ -391,7 +413,12 @@ int switch_cs(unsigned char boot)
return 0;
}
}
#elif defined(CONFIG_VCMA9)
int switch_cs(unsigned char boot)
{
return 0;
}
#endif /* CONFIG_VCMA9 */
int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{

View File

@@ -65,21 +65,22 @@ void pci_pip405_write_regs(struct pci_controller *hose, pci_dev_t dev,
static void pci_pip405_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
{
unsigned char int_line = 0xff;
unsigned char pin;
/*
* Write pci interrupt line register
*/
if(PCI_DEV(dev)==0) /* Device0 = PPC405 -> skip */
return;
if(PCI_FUNC(dev)==0)
{
/* assuming all function 0 are using their INTA# Pin*/
int_line=PCI_IRQ_VECTOR(dev);
pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, int_line);
pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &pin);
if ((pin == 0) || (pin > 4))
return;
int_line = ((PCI_DEV(dev) + (pin-1) + 10) % 4) + 28;
pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, int_line);
#ifdef DEBUG
printf("Fixup IRQ: dev %d (%x) int line %d 0x%x\n",
PCI_DEV(dev),dev,int_line,int_line);
printf("Fixup IRQ: dev %d (%x) int line %d 0x%x\n",
PCI_DEV(dev),dev,int_line,int_line);
#endif
}
}
extern void pci_405gp_init(struct pci_controller *hose);
@@ -90,11 +91,34 @@ static struct pci_controller hose = {
fixup_irq: pci_pip405_fixup_irq,
};
static void reloc_pci_cfg_table(struct pci_config_table *table)
{
DECLARE_GLOBAL_DATA_PTR;
unsigned long addr;
for (; table && table->vendor; table++) {
addr = (ulong) (table->config_device) + gd->reloc_off;
#ifdef DEBUG
printf ("device \"%d\": 0x%08lx => 0x%08lx\n",
table->device, (ulong) (table->config_device), addr);
#endif
table->config_device =
(void (*)(struct pci_controller* hose, pci_dev_t dev,
struct pci_config_table *))addr;
table->priv[0]+=gd->reloc_off;
}
}
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;
hose.config_table = pci_pip405_config_table;
reloc_pci_cfg_table(hose.config_table);
#ifdef DEBUG
printf("Init PCI: fixup_irq=%p config_table=%p hose=%p\n",pci_pip405_fixup_irq,pci_pip405_config_table,hose);
#endif
pci_405gp_init(&hose);
}

View File

@@ -128,6 +128,15 @@ const sdram_t sdram_table[] = {
2, /* Address Mode = 2 */
4, /* size value */
1}, /* ECC enabled */
{ 0x03, /* Rev A, 128MByte -4 Board */
3, /* Case Latenty = 3 */
3, /* trp 20ns / 7.5 ns datain[27] */
3, /* trcd 20ns /7.5 ns (datain[29]) */
6, /* tras 44ns /7.5 ns (datain[30]) */
4, /* tcpt 44 - 20ns = 24ns */
3, /* Address Mode = 3 */
5, /* size value */
1}, /* ECC enabled */
{ 0xff, /* terminator */
0xff,
0xff,
@@ -616,9 +625,15 @@ void print_mip405_rev (void)
int last_stage_init (void)
{
/* write correct LED configuration */
if (miiphy_write (0x1, 0x14, 0x2402) != 0) {
printf ("Error writing to the PHY\n");
}
/* since LED/CFG2 is not connected on the -2,
* write to correct capability information */
if (miiphy_write (0x1, 0x4, 0x01E1) != 0) {
printf ("Error writing to the PHY\n");
}
print_mip405_rev ();
show_stdio_dev ();
check_env ();

49
board/mpl/vcma9/Makefile Normal file
View File

@@ -0,0 +1,49 @@
#
# (C) Copyright 2000, 2001, 2002
# 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 := vcma9.o flash.o cmd_vcma9.o
OBJS += ../common/common_util.o ../common/memtst.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
#########################################################################

144
board/mpl/vcma9/cmd_vcma9.c Normal file
View File

@@ -0,0 +1,144 @@
/*
* (C) Copyright 2002
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* adapted for VCMA9
* David Mueller, ELSOFT AG, d.mueller@elsoft.ch
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <common.h>
#include <command.h>
#include "vcma9.h"
#include "../common/common_util.h"
#if defined(CONFIG_DRIVER_CS8900)
#include <../drivers/cs8900.h>
static uchar cs8900_chksum(ushort data)
{
return((data >> 8) & 0x00FF) + (data & 0x00FF);
}
#endif
extern void print_vcma9_info(void);
extern int vcma9_cantest(void);
extern int vcma9_nandtest(void);
extern int vcma9_dactest(void);
extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
/* ------------------------------------------------------------------------- */
int do_vcma9(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
DECLARE_GLOBAL_DATA_PTR;
if (strcmp(argv[1], "info") == 0)
{
print_vcma9_info();
return 0;
}
#if defined(CONFIG_DRIVER_CS8900)
if (strcmp(argv[1], "cs8900_eeprom") == 0) {
if (strcmp(argv[2], "read") == 0) {
uchar addr; ushort data;
addr = simple_strtoul(argv[3], NULL, 16);
cs8900_e2prom_read(addr, &data);
printf("0x%2.2X: 0x%4.4X\n", addr, data);
} else if (strcmp(argv[2], "write") == 0) {
uchar addr; ushort data;
addr = simple_strtoul(argv[3], NULL, 16);
data = simple_strtoul(argv[4], NULL, 16);
cs8900_e2prom_write(addr, data);
} else if (strcmp(argv[2], "setaddr") == 0) {
uchar addr, i, csum; ushort data;
/* check for valid ethaddr */
for (i = 0; i < 6; i++)
if (gd->bd->bi_enetaddr[i] != 0)
break;
if (i < 6) {
addr = 1;
data = 0x2158;
cs8900_e2prom_write(addr, data);
csum = cs8900_chksum(data);
addr++;
for (i = 0; i < 6; i+=2) {
data = gd->bd->bi_enetaddr[i+1] << 8 |
gd->bd->bi_enetaddr[i];
cs8900_e2prom_write(addr, data);
csum += cs8900_chksum(data);
addr++;
}
/* calculate header link byte */
data = 0xA100 | (addr * 2);
cs8900_e2prom_write(0, data);
csum += cs8900_chksum(data);
/* write checksum word */
cs8900_e2prom_write(addr, (0 - csum) << 8);
} else {
printf("\nplease defined 'ethaddr'\n");
}
} else if (strcmp(argv[2], "dump") == 0) {
uchar addr = 0, endaddr, csum; ushort data;
printf("Dump of CS8900 config device: ");
cs8900_e2prom_read(addr, &data);
if ((data & 0xE000) == 0xA000) {
endaddr = (data & 0x00FF) / 2;
csum = cs8900_chksum(data);
for (addr = 1; addr <= endaddr; addr++) {
cs8900_e2prom_read(addr, &data);
printf("\n0x%2.2X: 0x%4.4X", addr, data);
csum += cs8900_chksum(data);
}
printf("\nChecksum: %s", (csum == 0) ? "ok" : "wrong");
} else {
printf("no valid config found");
}
printf("\n");
}
return 0;
}
#endif
#if 0
if (strcmp(argv[1], "cantest") == 0) {
vcma9_cantest();
return 0;
}
if (strcmp(argv[1], "nandtest") == 0) {
vcma9_nandtest();
return 0;
}
if (strcmp(argv[1], "dactest") == 0) {
vcma9_dactest();
return 0;
}
#endif
return (do_mplcommon(cmdtp, flag, argc, argv));
}

24
board/mpl/vcma9/config.mk Normal file
View File

@@ -0,0 +1,24 @@
#
# (C) Copyright 2002
# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
#
# MPL VCMA9 board with S3C2410X (ARM920T) cpu
#
# see http://www.mpl.ch/ for more information about the MPL VCMA9
#
#
# MPL VCMA9 has 1 bank of 64 MB DRAM
#
# 3000'0000 to 3400'0000
#
# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
# optionally with a ramdisk at 3080'0000
#
# we load ourself to 33F0'0000
#
# download area is 3300'0000
#
TEXT_BASE = 0x33F00000

445
board/mpl/vcma9/flash.c Normal file
View File

@@ -0,0 +1,445 @@
/*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Alex Zuepke <azu@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>
ulong myflush(void);
#define FLASH_BANK_SIZE PHYS_FLASH_SIZE
#define MAIN_SECT_SIZE 0x10000 /* 64 KB */
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
#define CMD_READ_ARRAY 0x000000F0
#define CMD_UNLOCK1 0x000000AA
#define CMD_UNLOCK2 0x00000055
#define CMD_ERASE_SETUP 0x00000080
#define CMD_ERASE_CONFIRM 0x00000030
#define CMD_PROGRAM 0x000000A0
#define CMD_UNLOCK_BYPASS 0x00000020
#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555 << 1)))
#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x000002AA << 1)))
#define BIT_ERASE_DONE 0x00000080
#define BIT_RDY_MASK 0x00000080
#define BIT_PROGRAM_ERROR 0x00000020
#define BIT_TIMEOUT 0x80000000 /* our flag */
#define READY 1
#define ERR 2
#define TMO 4
/*-----------------------------------------------------------------------
*/
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 =
#if defined(CONFIG_AMD_LV400)
(AMD_MANUFACT & FLASH_VENDMASK) |
(AMD_ID_LV400B & FLASH_TYPEMASK);
#elif defined(CONFIG_AMD_LV800)
(AMD_MANUFACT & FLASH_VENDMASK) |
(AMD_ID_LV800B & FLASH_TYPEMASK);
#else
#error "Unknown flash configured"
#endif
flash_info[i].size = FLASH_BANK_SIZE;
flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
if (i == 0)
flashbase = PHYS_FLASH_1;
else
panic("configured to many flash banks!\n");
for (j = 0; j < flash_info[i].sector_count; j++)
{
if (j <= 3)
{
/* 1st one is 16 KB */
if (j == 0)
{
flash_info[i].start[j] = flashbase + 0;
}
/* 2nd and 3rd are both 8 KB */
if ((j == 1) || (j == 2))
{
flash_info[i].start[j] = flashbase + 0x4000 + (j-1)*0x2000;
}
/* 4th 32 KB */
if (j == 3)
{
flash_info[i].start[j] = flashbase + 0x8000;
}
}
else
{
flash_info[i].start[j] = flashbase + (j - 3)*MAIN_SECT_SIZE;
}
}
size += flash_info[i].size;
}
flash_protect(FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_FLASH_BASE + _armboot_end - _armboot_start,
&flash_info[0]);
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[0]);
return size;
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
switch (info->flash_id & FLASH_VENDMASK)
{
case (AMD_MANUFACT & FLASH_VENDMASK):
printf("AMD: ");
break;
default:
printf("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK)
{
case (AMD_ID_LV400B & FLASH_TYPEMASK):
printf("1x Amd29LV400BB (4Mbit)\n");
break;
case (AMD_ID_LV800B & FLASH_TYPEMASK):
printf("1x Amd29LV800BB (8Mbit)\n");
break;
default:
printf("Unknown Chip Type\n");
goto Done;
break;
}
printf(" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf(" Sector Start Addresses:");
for (i = 0; i < info->sector_count; i++)
{
if ((i % 5) == 0)
{
printf ("\n ");
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
Done:
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
ushort result;
int iflag, cflag, prot, sect;
int rc = ERR_OK;
int chip;
/* first look for protection bits */
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) !=
(AMD_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.
*/
cflag = icache_status();
icache_disable();
iflag = disable_interrupts();
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last && !ctrlc(); sect++)
{
printf("Erasing sector %2d ... ", sect);
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
if (info->protect[sect] == 0)
{ /* not protected */
vu_short *addr = (vu_short *)(info->start[sect]);
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
*addr = CMD_ERASE_CONFIRM;
/* wait until flash is ready */
chip = 0;
do
{
result = *addr;
/* check timeout */
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
{
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
chip = TMO;
break;
}
if (!chip && (result & 0xFFFF) & BIT_ERASE_DONE)
chip = READY;
if (!chip && (result & 0xFFFF) & BIT_PROGRAM_ERROR)
chip = ERR;
} while (!chip);
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
if (chip == ERR)
{
rc = ERR_PROG_ERROR;
goto outahere;
}
if (chip == TMO)
{
rc = ERR_TIMOUT;
goto outahere;
}
printf("ok.\n");
}
else /* it was protected */
{
printf("protected!\n");
}
}
if (ctrlc())
printf("User Interrupt!\n");
outahere:
/* allow flash to settle - wait 10 ms */
udelay_masked(10000);
if (iflag)
enable_interrupts();
if (cflag)
icache_enable();
return rc;
}
/*-----------------------------------------------------------------------
* Copy memory to flash
*/
volatile static int write_hword (flash_info_t *info, ulong dest, ushort data)
{
vu_short *addr = (vu_short *)dest;
ushort result;
int rc = ERR_OK;
int cflag, iflag;
int chip;
/*
* Check if Flash is (sufficiently) erased
*/
result = *addr;
if ((result & data) != data)
return ERR_NOT_ERASED;
/*
* Disable interrupts which might cause a timeout
* here. Remember that our exception vectors are
* at address 0 in the flash, and we don't want a
* (ticker) exception to happen while the flash
* chip is in programming mode.
*/
cflag = icache_status();
icache_disable();
iflag = disable_interrupts();
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
MEM_FLASH_ADDR1 = CMD_PROGRAM;
*addr = data;
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
/* wait until flash is ready */
chip = 0;
do
{
result = *addr;
/* check timeout */
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
{
chip = ERR | TMO;
break;
}
if (!chip && ((result & 0x80) == (data & 0x80)))
chip = READY;
if (!chip && ((result & 0xFFFF) & BIT_PROGRAM_ERROR))
{
result = *addr;
if ((result & 0x80) == (data & 0x80))
chip = READY;
else
chip = ERR;
}
} while (!chip);
*addr = CMD_READ_ARRAY;
if (chip == ERR || *addr != data)
rc = ERR_PROG_ERROR;
if (iflag)
enable_interrupts();
if (cflag)
icache_enable();
return rc;
}
/*-----------------------------------------------------------------------
* Copy memory to flash.
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong cp, wp;
int l;
int i, rc;
ushort data;
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_hword(info, wp, data)) != 0) {
return (rc);
}
wp += 2;
}
/*
* handle word aligned part
*/
while (cnt >= 2) {
data = *((vu_short*)src);
if ((rc = write_hword(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_hword(info, wp, data);
}

160
board/mpl/vcma9/memsetup.S Normal file
View File

@@ -0,0 +1,160 @@
/*
* Memory Setup stuff - taken from blob memsetup.S
*
* Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
* Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
*
* Modified for the Samsung SMDK2410 by
* (C) Copyright 2002
* David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <config.h>
#include <version.h>
/* some parameters for the board */
#define BWSCON 0x48000000
/* BWSCON */
#define DW8 (0x0)
#define DW16 (0x1)
#define DW32 (0x2)
#define WAIT (0x1<<2)
#define UBLB (0x1<<3)
#define B1_BWSCON (DW16)
#define B2_BWSCON (DW32)
#define B3_BWSCON (DW32)
#define B4_BWSCON (DW16 + WAIT + UBLB)
#define B5_BWSCON (DW8 + UBLB)
#define B6_BWSCON (DW32)
#define B7_BWSCON (DW32)
/* BANK0CON */
#define B0_Tacs 0x0 /* 0clk */
#define B0_Tcos 0x0 /* 0clk */
#define B0_Tacc 0x5 /* 8clk */
#define B0_Tcoh 0x0 /* 0clk */
#define B0_Tah 0x0 /* 0clk */
#define B0_Tacp 0x0 /* page mode is not used */
#define B0_PMC 0x0 /* page mode disabled */
/* BANK1CON */
#define B1_Tacs 0x0 /* 0clk */
#define B1_Tcos 0x0 /* 0clk */
#define B1_Tacc 0x5 /* 8clk */
#define B1_Tcoh 0x0 /* 0clk */
#define B1_Tah 0x0 /* 0clk */
#define B1_Tacp 0x0 /* page mode is not used */
#define B1_PMC 0x0 /* page mode disabled */
#define B2_Tacs 0x3 /* 4clk */
#define B2_Tcos 0x3 /* 4clk */
#define B2_Tacc 0x7 /* 14clk */
#define B2_Tcoh 0x3 /* 4clk */
#define B2_Tah 0x3 /* 4clk */
#define B2_Tacp 0x0 /* page mode is not used */
#define B2_PMC 0x0 /* page mode disabled */
#define B3_Tacs 0x3 /* 4clk */
#define B3_Tcos 0x3 /* 4clk */
#define B3_Tacc 0x7 /* 14clk */
#define B3_Tcoh 0x3 /* 4clk */
#define B3_Tah 0x3 /* 4clk */
#define B3_Tacp 0x0 /* page mode is not used */
#define B3_PMC 0x0 /* page mode disabled */
#define B4_Tacs 0x3 /* 4clk */
#define B4_Tcos 0x1 /* 1clk */
#define B4_Tacc 0x7 /* 14clk */
#define B4_Tcoh 0x1 /* 1clk */
#define B4_Tah 0x0 /* 0clk */
#define B4_Tacp 0x0 /* page mode is not used */
#define B4_PMC 0x0 /* page mode disabled */
#define B5_Tacs 0x0 /* 0clk */
#define B5_Tcos 0x3 /* 4clk */
#define B5_Tacc 0x5 /* 8clk */
#define B5_Tcoh 0x2 /* 2clk */
#define B5_Tah 0x1 /* 1clk */
#define B5_Tacp 0x0 /* page mode is not used */
#define B5_PMC 0x0 /* page mode disabled */
#define B6_MT 0x3 /* SDRAM */
#define B6_Trcd 0x1 /* 3clk */
#define B6_SCAN 0x2 /* 10bit */
#define B7_MT 0x3 /* SDRAM */
#define B7_Trcd 0x1 /* 3clk */
#define B7_SCAN 0x2 /* 10bit */
/* REFRESH parameter */
#define REFEN 0x1 /* Refresh enable */
#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */
#define Trp 0x0 /* 2clk */
#define Trc 0x3 /* 7clk */
#define Tchr 0x2 /* 3clk */
#define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
/**************************************/
_TEXT_BASE:
.word TEXT_BASE
.globl memsetup
memsetup:
/* memory control configuration */
/* make r0 relative the current location so that it */
/* reads SMRDATA out of FLASH rather than memory ! */
ldr r0, =SMRDATA
ldr r1, _TEXT_BASE
sub r0, r0, r1
ldr r1, =BWSCON /* Bus Width Status Controller */
add r2, r0, #13*4
0:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne 0b
/* everything is fine now */
mov pc, lr
.ltorg
/* the literal pools origin */
SMRDATA:
.word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x32
.word 0x30
.word 0x30

View File

@@ -0,0 +1,54 @@
/*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <gj@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_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/arm920t/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 = .;
}

247
board/mpl/vcma9/vcma9.c Normal file
View File

@@ -0,0 +1,247 @@
/*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2002
* David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <s3c2410.h>
#include <i2c.h>
#include "vcma9.h"
#include "../common/common_util.h"
/* ------------------------------------------------------------------------- */
#define FCLK_SPEED 1
#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */
#define M_MDIV 0xC3
#define M_PDIV 0x4
#define M_SDIV 0x1
#elif FCLK_SPEED==1 /* Fout = 202.8MHz */
#define M_MDIV 0xA1
#define M_PDIV 0x3
#define M_SDIV 0x1
#endif
#define USB_CLOCK 1
#if USB_CLOCK==0
#define U_M_MDIV 0xA1
#define U_M_PDIV 0x3
#define U_M_SDIV 0x1
#elif USB_CLOCK==1
#define U_M_MDIV 0x48
#define U_M_PDIV 0x3
#define U_M_SDIV 0x2
#endif
static inline void delay(unsigned long loops)
{
__asm__ volatile ("1:\n"
"subs %0, %1, #1\n"
"bne 1b":"=r" (loops):"0" (loops));
}
/*
* Miscellaneous platform dependent initialisations
*/
int board_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
/* to reduce PLL lock time, adjust the LOCKTIME register */
rLOCKTIME = 0xFFFFFF;
/* configure MPLL */
rMPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
/* some delay between MPLL and UPLL */
delay (4000);
/* configure UPLL */
rUPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
/* some delay between MPLL and UPLL */
delay (8000);
/* set up the I/O ports */
rGPACON = 0x007FFFFF;
rGPBCON = 0x002AAAAA;
rGPBUP = 0x000002BF;
rGPCCON = 0xAAAAAAAA;
rGPCUP = 0x0000FFFF;
rGPDCON = 0xAAAAAAAA;
rGPDUP = 0x0000FFFF;
rGPECON = 0xAAAAAAAA;
rGPEUP = 0x000037F7;
rGPFCON = 0x00000000;
rGPFUP = 0x00000000;
rGPGCON = 0xFFEAFF5A;
rGPGUP = 0x0000F0DC;
rGPHCON = 0x0028AAAA;
rGPHUP = 0x00000656;
/* setup correct IRQ modes for NIC */
rEXTINT2 = (rEXTINT2 & ~(7<<8)) | (4<<8); /* rising edge mode */
/* init serial */
gd->baudrate = CONFIG_BAUDRATE;
gd->have_console = 1;
serial_init();
/* arch number of VCMA9-Board */
gd->bd->bi_arch_number = 227;
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x30000100;
icache_enable();
dcache_enable();
return 0;
}
int dram_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
return 0;
}
/*
* Get some Board/PLD Info
*/
static uchar Get_PLD_ID(void)
{
return(*(volatile uchar *)PLD_ID_REG);
}
static uchar Get_PLD_BOARD(void)
{
return(*(volatile uchar *)PLD_BOARD_REG);
}
static uchar Get_PLD_Version(void)
{
return((Get_PLD_ID() >> 4) & 0x0F);
}
static uchar Get_PLD_Revision(void)
{
return(Get_PLD_ID() & 0x0F);
}
static int Get_Board_Config(void)
{
uchar config = Get_PLD_BOARD() & 0x03;
if (config == 3)
return 1;
else
return 0;
}
static uchar Get_Board_PCB(void)
{
return(((Get_PLD_BOARD() >> 4) & 0x03) + 'A');
}
/* ------------------------------------------------------------------------- */
/*
* Check Board Identity:
*/
int checkboard(void)
{
unsigned char s[50];
int i;
backup_t *b = (backup_t *) s;
puts("Board: ");
i = getenv_r("serial#", s, 32);
if ((i < 0) || strncmp (s, "VCMA9", 5)) {
get_backup_values (b);
if (strncmp (b->signature, "MPL\0", 4) != 0) {
puts ("### No HW ID - assuming VCMA9");
} else {
b->serial_name[5] = 0;
printf ("%s-%d Rev %c SN: %s", b->serial_name, Get_Board_Config(),
Get_Board_PCB(), &b->serial_name[6]);
}
} else {
s[5] = 0;
printf ("%s-%d Rev %c SN: %s", s, Get_Board_Config(), Get_Board_PCB(),
&s[6]);
}
printf("\n");
return(0);
}
void print_vcma9_rev(void)
{
printf("Board: VCMA9-%d Rev: %c (PLD Ver: %d, Rev: %d)\n",
Get_Board_Config(), Get_Board_PCB(),
Get_PLD_Version(), Get_PLD_Revision());
}
int last_stage_init(void)
{
print_vcma9_rev();
show_stdio_dev();
check_env();
return 0;
}
/***************************************************************************
* some helping routines
*/
int overwrite_console(void)
{
/* return TRUE if console should be overwritten */
return 0;
}
/************************************************************************
* Print VCMA9 Info
************************************************************************/
void print_vcma9_info(void)
{
print_vcma9_rev();
}

43
board/mpl/vcma9/vcma9.h Normal file
View File

@@ -0,0 +1,43 @@
/*
* (C) Copyright 2002
* David Mueller, ELSOFT AG, d.mueller@elsoft.ch
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
/****************************************************************************
* Global routines used for VCMA9
*****************************************************************************/
extern int mem_test(unsigned long start, unsigned long ramsize,int mode);
void print_vcma9_info(void);
#define PLD_BASE_ADDRESS 0x2C000100
#define PLD_ID_REG (PLD_BASE_ADDRESS + 0)
#define PLD_NIC_REG (PLD_BASE_ADDRESS + 1)
#define PLD_CAN_REG (PLD_BASE_ADDRESS + 2)
#define PLD_MISC_REG (PLD_BASE_ADDRESS + 3)
#define PLD_GPCD_REG (PLD_BASE_ADDRESS + 4)
#define PLD_BOARD_REG (PLD_BASE_ADDRESS + 5)

View File

@@ -33,10 +33,10 @@
#
ifeq ($(CONFIG_BOOT_ROM),y)
TEXT_BASE := 0x60000000
TEXT_BASE := 0xFF800000
PLATFORM_CPPFLAGS += -DCONFIG_BOOT_ROM
else
TEXT_BASE := 0x40000000
TEXT_BASE := 0xFF000000
endif
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)

View File

@@ -24,6 +24,7 @@
#include <common.h>
#include <ioports.h>
#include <mpc8260.h>
#include <pci.h>
/*
* I/O Port configuration table
@@ -349,3 +350,14 @@ void doc_init (void)
doc_probe (CFG_DOC_BASE);
}
#endif
#ifdef CONFIG_PCI
struct pci_controller hose;
extern void pci_mpc8250_init(struct pci_controller *);
void pci_init_board(void)
{
pci_mpc8250_init(&hose);
}
#endif

41
board/purple/Makefile Normal file
View File

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

32
board/purple/config.mk Normal file
View File

@@ -0,0 +1,32 @@
#
# (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
#
#
# Purple board with MIPS 5Kc CPU core
#
# ROM version
TEXT_BASE = 0xB0000000
# RAM version
#TEXT_BASE = 0x80100000

596
board/purple/flash.c Normal file
View File

@@ -0,0 +1,596 @@
/*
* (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 <common.h>
#include <asm/inca-ip.h>
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
typedef unsigned long FLASH_PORT_WIDTH;
typedef volatile unsigned long FLASH_PORT_WIDTHV;
#define FLASH_ID_MASK 0xFFFFFFFF
#define FPW FLASH_PORT_WIDTH
#define FPWV FLASH_PORT_WIDTHV
#define ORMASK(size) ((-size) & OR_AM_MSK)
#define FLASH29_REG_ADRS(reg) ((FPWV *)PHYS_FLASH_1 + (reg))
/* FLASH29 command register addresses */
#define FLASH29_REG_FIRST_CYCLE FLASH29_REG_ADRS (0x1555)
#define FLASH29_REG_SECOND_CYCLE FLASH29_REG_ADRS (0x2aaa)
#define FLASH29_REG_THIRD_CYCLE FLASH29_REG_ADRS (0x3555)
#define FLASH29_REG_FOURTH_CYCLE FLASH29_REG_ADRS (0x4555)
#define FLASH29_REG_FIFTH_CYCLE FLASH29_REG_ADRS (0x5aaa)
#define FLASH29_REG_SIXTH_CYCLE FLASH29_REG_ADRS (0x6555)
/* FLASH29 command definitions */
#define FLASH29_CMD_FIRST 0xaaaaaaaa
#define FLASH29_CMD_SECOND 0x55555555
#define FLASH29_CMD_FOURTH 0xaaaaaaaa
#define FLASH29_CMD_FIFTH 0x55555555
#define FLASH29_CMD_SIXTH 0x10101010
#define FLASH29_CMD_SECTOR 0x30303030
#define FLASH29_CMD_PROGRAM 0xa0a0a0a0
#define FLASH29_CMD_CHIP_ERASE 0x80808080
#define FLASH29_CMD_READ_RESET 0xf0f0f0f0
#define FLASH29_CMD_AUTOSELECT 0x90909090
#define FLASH29_CMD_READ 0x70707070
#define IN_RAM_CMD_READ 0x1
#define IN_RAM_CMD_WRITE 0x2
#define FLASH_WRITE_CMD ((ulong)(flash_write_cmd) & 0x7)+0xbf008000
#define FLASH_READ_CMD ((ulong)(flash_read_cmd) & 0x7)+0xbf008000
typedef void (*FUNCPTR_CP)(ulong *source, ulong *destination, ulong nlongs);
typedef void (*FUNCPTR_RD)(int cmd, FPWV * pFA, char * string, int strLen);
typedef void (*FUNCPTR_WR)(int cmd, FPWV * pFA, FPW value);
static ulong flash_get_size(FPWV *addr, flash_info_t *info);
static int write_word(flash_info_t *info, FPWV *dest, FPW data);
static void flash_get_offsets(ulong base, flash_info_t *info);
static flash_info_t *flash_get_info(ulong base);
static void load_cmd(ulong cmd);
static ulong in_ram_cmd = 0;
/******************************************************************************
*
* Don't change the program architecture
* This architecture assure the program
* can be relocated to scratch ram
*/
static void flash_read_cmd(int cmd, FPWV * pFA, char * string, int strLen)
{
int i,j;
FPW temp,temp1;
FPWV *str;
str = (FPWV *)string;
j= strLen/4;
if(cmd == FLASH29_CMD_AUTOSELECT)
{
*(FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_FIRST;
*(FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
*(FLASH29_REG_THIRD_CYCLE) = FLASH29_CMD_AUTOSELECT;
}
if(cmd == FLASH29_CMD_READ)
{
i = 0;
while(i<j)
{
temp = *pFA++;
temp1 = *(int *)0xa0000000;
*(int *)0xbf0081f8 = temp1 + temp;
*str++ = temp;
i++;
}
}
if(cmd == FLASH29_CMD_READ_RESET)
{
*(FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_FIRST;
*(FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
*(FLASH29_REG_THIRD_CYCLE) = FLASH29_CMD_READ_RESET;
}
*(int *)0xbf0081f8 = *(int *)0xa0000000; /* dummy read switch back to sdram interface */
}
/******************************************************************************
*
* Don't change the program architecture
* This architecture assure the program
* can be relocated to scratch ram
*/
static void flash_write_cmd(int cmd, FPWV * pFA, FPW value)
{
*(FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_FIRST;
*(FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
if (cmd == FLASH29_CMD_SECTOR)
{
*(FLASH29_REG_THIRD_CYCLE) = FLASH29_CMD_CHIP_ERASE;
*(FLASH29_REG_FOURTH_CYCLE) = FLASH29_CMD_FOURTH;
*(FLASH29_REG_FIFTH_CYCLE) = FLASH29_CMD_FIFTH;
*pFA = FLASH29_CMD_SECTOR;
}
if (cmd == FLASH29_CMD_SIXTH)
{
*(FLASH29_REG_THIRD_CYCLE) = FLASH29_CMD_CHIP_ERASE;
*(FLASH29_REG_FOURTH_CYCLE) = FLASH29_CMD_FOURTH;
*(FLASH29_REG_FIFTH_CYCLE) = FLASH29_CMD_FIFTH;
*(FLASH29_REG_SIXTH_CYCLE) = FLASH29_CMD_SIXTH;
}
if (cmd == FLASH29_CMD_PROGRAM)
{
*(FLASH29_REG_THIRD_CYCLE) = FLASH29_CMD_PROGRAM;
*pFA = value;
}
if (cmd == FLASH29_CMD_READ_RESET)
{
*(FLASH29_REG_THIRD_CYCLE) = FLASH29_CMD_READ_RESET;
}
*(int *)0xbf0081f8 = *(int *)0xa0000000; /* dummy read switch back to sdram interface */
}
static void load_cmd(ulong cmd)
{
ulong *src;
ulong *dst;
FUNCPTR_CP absEntry;
ulong func;
if (in_ram_cmd & cmd) return;
if (cmd == IN_RAM_CMD_READ)
{
func = (ulong)flash_read_cmd;
}
else
{
func = (ulong)flash_write_cmd;
}
src = (ulong *)(func & 0xfffffff8);
dst = (ulong *)0xbf008000;
absEntry = (FUNCPTR_CP)(0xbf0081d0);
absEntry(src,dst,0x38);
in_ram_cmd = cmd;
}
/*-----------------------------------------------------------------------
* flash_init()
*
* sets up flash_info and returns size of FLASH (bytes)
*/
unsigned long flash_init (void)
{
unsigned long size = 0;
int i;
load_cmd(IN_RAM_CMD_READ);
/* Init: no FLASHes known */
for (i=0; i < CFG_MAX_FLASH_BANKS; ++i) {
ulong flashbase = PHYS_FLASH_1;
ulong * buscon = (ulong *) INCA_IP_EBU_EBU_BUSCON0;
/* Disable write protection */
*buscon &= ~INCA_IP_EBU_EBU_BUSCON1_WRDIS;
#if 1
memset(&flash_info[i], 0, sizeof(flash_info_t));
#endif
flash_info[i].size =
flash_get_size((FPW *)flashbase, &flash_info[i]);
if (flash_info[i].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx\n",
i, flash_info[i].size);
}
size += flash_info[i].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_get_info(CFG_MONITOR_BASE));
#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_get_info(CFG_ENV_ADDR));
#endif
return size;
}
/*-----------------------------------------------------------------------
*/
static void flash_get_offsets (ulong base, flash_info_t *info)
{
int i;
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
&& (info->flash_id & FLASH_TYPEMASK) == FLASH_AM160B) {
int bootsect_size[4]; /* number of bytes/boot sector */
int sect_size; /* number of bytes/regular sector */
bootsect_size[0] = 0x00008000;
bootsect_size[1] = 0x00004000;
bootsect_size[2] = 0x00004000;
bootsect_size[3] = 0x00010000;
sect_size = 0x00020000;
/* set sector offsets for bottom boot block type */
for (i = 0; i < info->sector_count; i++) {
info->start[i] = base;
base += i < 4 ? bootsect_size[i] : sect_size;
}
}
}
/*-----------------------------------------------------------------------
*/
static flash_info_t *flash_get_info(ulong base)
{
int i;
flash_info_t * info;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
info = & flash_info[i];
if (info->start[0] <= base && base < info->start[0] + info->size)
break;
}
return i == CFG_MAX_FLASH_BANKS ? 0 : info;
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
uchar *boottype;
uchar *bootletter;
uchar *fmt;
uchar botbootletter[] = "B";
uchar topbootletter[] = "T";
uchar botboottype[] = "bottom boot sector";
uchar topboottype[] = "top boot sector";
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD: printf ("AMD "); break;
case FLASH_MAN_BM: printf ("BRIGHT MICRO "); break;
case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
case FLASH_MAN_SST: printf ("SST "); break;
case FLASH_MAN_STM: printf ("STM "); break;
case FLASH_MAN_INTEL: printf ("INTEL "); break;
default: printf ("Unknown Vendor "); break;
}
/* check for top or bottom boot, if it applies */
if (info->flash_id & FLASH_BTYPE) {
boottype = botboottype;
bootletter = botbootletter;
}
else {
boottype = topboottype;
bootletter = topbootletter;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AM160B:
fmt = "29LV160B%s (16 Mbit, %s)\n";
break;
case FLASH_28F800C3B:
case FLASH_28F800C3T:
fmt = "28F800C3%s (8 Mbit, %s)\n";
break;
case FLASH_INTEL800B:
case FLASH_INTEL800T:
fmt = "28F800B3%s (8 Mbit, %s)\n";
break;
case FLASH_28F160C3B:
case FLASH_28F160C3T:
fmt = "28F160C3%s (16 Mbit, %s)\n";
break;
case FLASH_INTEL160B:
case FLASH_INTEL160T:
fmt = "28F160B3%s (16 Mbit, %s)\n";
break;
case FLASH_28F320C3B:
case FLASH_28F320C3T:
fmt = "28F320C3%s (32 Mbit, %s)\n";
break;
case FLASH_INTEL320B:
case FLASH_INTEL320T:
fmt = "28F320B3%s (32 Mbit, %s)\n";
break;
case FLASH_28F640C3B:
case FLASH_28F640C3T:
fmt = "28F640C3%s (64 Mbit, %s)\n";
break;
case FLASH_INTEL640B:
case FLASH_INTEL640T:
fmt = "28F640B3%s (64 Mbit, %s)\n";
break;
default:
fmt = "Unknown Chip Type\n";
break;
}
printf (fmt, bootletter, boottype);
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20,
info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0) {
printf ("\n ");
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
}
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
ulong flash_get_size (FPWV *addr, flash_info_t *info)
{
FUNCPTR_RD absEntry;
FPW retValue;
int flag;
load_cmd(IN_RAM_CMD_READ);
absEntry = (FUNCPTR_RD)FLASH_READ_CMD;
flag = disable_interrupts();
absEntry(FLASH29_CMD_AUTOSELECT,0,0,0);
if (flag) enable_interrupts();
udelay(100);
flag = disable_interrupts();
absEntry(FLASH29_CMD_READ, addr + 1, (char *)&retValue, sizeof(retValue));
absEntry(FLASH29_CMD_READ_RESET,0,0,0);
if (flag) enable_interrupts();
udelay(100);
switch (retValue) {
case (FPW)AMD_ID_LV160B:
info->flash_id += FLASH_AM160B;
info->sector_count = 35;
info->size = 0x00400000;
break; /* => 8 or 16 MB */
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* => no or unknown flash */
}
flash_get_offsets((ulong)addr, info);
return (info->size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
FPWV *addr;
int flag, prot, sect;
ulong start, now, last;
int rcode = 0;
FUNCPTR_WR absEntry;
load_cmd(IN_RAM_CMD_WRITE);
absEntry = (FUNCPTR_WR)FLASH_WRITE_CMD;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AM160B:
break;
case FLASH_UNKNOWN:
default:
printf ("Can't erase unknown flash type %08lx - aborted\n",
info->flash_id);
return 1;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
last = get_timer(0);
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last && rcode == 0; sect++) {
if (info->protect[sect] != 0) /* protected, skip it */
continue;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr = (FPWV *)(info->start[sect]);
absEntry(FLASH29_CMD_SECTOR, addr, 0);
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
start = get_timer(0);
while ((now = get_timer(start)) <= CFG_FLASH_ERASE_TOUT) {
/* show that we're waiting */
if ((get_timer(last)) > CFG_HZ) {/* every second */
putc ('.');
last = get_timer(0);
}
}
flag = disable_interrupts();
absEntry(FLASH29_CMD_READ_RESET,0,0);
if (flag)
enable_interrupts();
}
printf (" done\n");
return rcode;
}
/*-----------------------------------------------------------------------
* 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)
{
FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
int bytes; /* number of bytes to program in current word */
int left; /* number of bytes left to program */
int i, res;
for (left = cnt, res = 0;
left > 0 && res == 0;
addr += sizeof(data), left -= sizeof(data) - bytes) {
bytes = addr & (sizeof(data) - 1);
addr &= ~(sizeof(data) - 1);
/* combine source and destination data so can program
* an entire word of 16 or 32 bits
*/
for (i = 0; i < sizeof(data); i++) {
data <<= 8;
if (i < bytes || i - bytes >= left )
data += *((uchar *)addr + i);
else
data += *src++;
}
res = write_word(info, (FPWV *)addr, data);
}
return (res);
}
static int write_word (flash_info_t *info, FPWV *dest, FPW data)
{
int res = 0; /* result, assume success */
FUNCPTR_WR absEntry;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((*dest & data) != data) {
return (2);
}
if (info->start[0] != PHYS_FLASH_1)
{
return (3);
}
load_cmd(IN_RAM_CMD_WRITE);
absEntry = (FUNCPTR_WR)FLASH_WRITE_CMD;
flag = disable_interrupts();
absEntry(FLASH29_CMD_PROGRAM,dest,data);
if (flag) enable_interrupts();
udelay(100);
flag = disable_interrupts();
absEntry(FLASH29_CMD_READ_RESET,0,0);
if (flag) enable_interrupts();
return (res);
}

35
board/purple/memsetup.S Normal file
View File

@@ -0,0 +1,35 @@
/*
* Memory sub-system initialization code for PURPLE development board.
*
* Copyright (c) 2003 Wolfgang Denk <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 <config.h>
#include <version.h>
#include <asm/regdef.h>
.globl memsetup
memsetup:
j ra
nop

197
board/purple/purple.c Normal file
View File

@@ -0,0 +1,197 @@
/*
* (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 <common.h>
#include <command.h>
#include <asm/inca-ip.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <asm/cacheops.h>
#include "sconsole.h"
#define cache_unroll(base,op) \
__asm__ __volatile__(" \
.set noreorder; \
.set mips3; \
cache %1, (%0); \
.set mips0; \
.set reorder" \
: \
: "r" (base), \
"i" (op));
typedef void (*FUNCPTR)(ulong *source, ulong *destination, ulong nlongs);
extern void asc_serial_init (void);
extern void asc_serial_putc (char);
extern void asc_serial_puts (const char *);
extern int asc_serial_getc (void);
extern int asc_serial_tstc (void);
extern void asc_serial_setbrg (void);
long int initdram(int board_type)
{
/* The only supported number of SDRAM banks is 4.
*/
#define CFG_NB 4
ulong cfgpb0 = *INCA_IP_SDRAM_MC_CFGPB0;
ulong cfgdw = *INCA_IP_SDRAM_MC_CFGDW;
int cols = cfgpb0 & 0xF;
int rows = (cfgpb0 & 0xF0) >> 4;
int dw = cfgdw & 0xF;
ulong size = (1 << (rows + cols)) * (1 << (dw - 1)) * CFG_NB;
return size;
}
int checkboard (void)
{
unsigned long chipid = *(unsigned long *)0xB800C800;
printf ("Board: Purple PLB 2800 chip version %ld, ", chipid & 0xF);
printf("CPU Speed %d MHz\n", CPU_CLOCK_RATE/1000000);
return 0;
}
int misc_init_r (void)
{
asc_serial_init ();
sconsole_putc = asc_serial_putc;
sconsole_puts = asc_serial_puts;
sconsole_getc = asc_serial_getc;
sconsole_tstc = asc_serial_tstc;
sconsole_setbrg = asc_serial_setbrg;
sconsole_flush ();
return (0);
}
/*******************************************************************************
*
* copydwords - copy one buffer to another a long at a time
*
* This routine copies the first <nlongs> longs from <source> to <destination>.
*/
static void copydwords (ulong *source, ulong *destination, ulong nlongs)
{
ulong temp,temp1;
ulong *dstend = destination + nlongs;
while (destination < dstend)
{
temp = *source++;
/* dummy read from sdram */
temp1 = *(ulong *)0xa0000000;
/* avoid optimization from compliler */
*(ulong *)0xbf0081f8 = temp1 + temp;
*destination++ = temp;
}
}
/*******************************************************************************
*
* copyLongs - copy one buffer to another a long at a time
*
* This routine copies the first <nlongs> longs from <source> to <destination>.
*/
static void copyLongs (ulong *source, ulong *destination, ulong nlongs)
{
FUNCPTR absEntry;
absEntry = (FUNCPTR)(0xbf008000+((ulong)copydwords & 0x7));
absEntry(source, destination, nlongs);
}
/*******************************************************************************
*
* programLoad - load program into ram
*
* This routine load copydwords into ram
*
*/
static void programLoad(void)
{
FUNCPTR absEntry;
ulong *src,*dst;
src = (ulong *)(TEXT_BASE + 0x428);
dst = (ulong *)0xbf0081d0;
absEntry = (FUNCPTR)(TEXT_BASE + 0x400);
absEntry(src,dst,0x6);
src = (ulong *)((ulong)copydwords & 0xfffffff8);
dst = (ulong *)0xbf008000;
absEntry(src,dst,0x38);
}
/*******************************************************************************
*
* copy_code - copy u-boot image from flash to RAM
*
* This routine is needed to solve flash problems on this board
*
*/
void copy_code (ulong dest_addr)
{
unsigned long start;
unsigned long end;
/* load copydwords into ram
*/
programLoad();
/* copy u-boot code
*/
copyLongs((ulong *)CFG_MONITOR_BASE,
(ulong *)dest_addr,
(CFG_MONITOR_LEN + 3) / 4);
/* flush caches
*/
start = KSEG0;
end = start + CFG_DCACHE_SIZE;
while(start < end) {
cache_unroll(start,Index_Writeback_Inv_D);
start += CFG_CACHELINE_SIZE;
}
start = KSEG0;
end = start + CFG_ICACHE_SIZE;
while(start < end) {
cache_unroll(start,Index_Invalidate_I);
start += CFG_CACHELINE_SIZE;
}
}

125
board/purple/sconsole.c Normal file
View File

@@ -0,0 +1,125 @@
/*
* (C) Copyright 2002
* 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 <config.h>
#include <common.h>
#include "sconsole.h"
void (*sconsole_putc) (char) = 0;
void (*sconsole_puts) (const char *) = 0;
int (*sconsole_getc) (void) = 0;
int (*sconsole_tstc) (void) = 0;
void (*sconsole_setbrg) (void) = 0;
int serial_init (void)
{
sconsole_buffer_t *sb = SCONSOLE_BUFFER;
sb->pos = 0;
sb->size = 0;
sb->max_size = CFG_SCONSOLE_SIZE - sizeof (sconsole_buffer_t);
return (0);
}
void serial_putc (char c)
{
if (sconsole_putc) {
(*sconsole_putc) (c);
} else {
sconsole_buffer_t *sb = SCONSOLE_BUFFER;
if (c) {
sb->data[sb->pos++] = c;
if (sb->pos == sb->max_size) {
sb->pos = 0;
}
if (sb->size < sb->max_size) {
sb->size++;
}
}
}
}
void serial_puts (const char *s)
{
if (sconsole_puts) {
(*sconsole_puts) (s);
} else {
sconsole_buffer_t *sb = SCONSOLE_BUFFER;
while (*s) {
sb->data[sb->pos++] = *s++;
if (sb->pos == sb->max_size) {
sb->pos = 0;
}
if (sb->size < sb->max_size) {
sb->size++;
}
}
}
}
int serial_getc (void)
{
if (sconsole_getc) {
return (*sconsole_getc) ();
} else {
return 0;
}
}
int serial_tstc (void)
{
if (sconsole_tstc) {
return (*sconsole_tstc) ();
} else {
return 0;
}
}
void serial_setbrg (void)
{
if (sconsole_setbrg) {
(*sconsole_setbrg) ();
}
}
void sconsole_flush (void)
{
if (sconsole_putc) {
sconsole_buffer_t *sb = SCONSOLE_BUFFER;
unsigned int end = sb->pos < sb->size
? sb->pos + sb->max_size - sb->size
: sb->pos - sb->size;
while (sb->size) {
(*sconsole_putc) (sb->data[end++]);
if (end == sb->max_size) {
end = 0;
}
sb->size--;
}
}
}

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