Compare commits

...

24 Commits

Author SHA1 Message Date
wdenk
e799d3755e Fix cirrus voltage detection (for CPC45) 2005-02-07 19:44:17 +00:00
wdenk
2f916943c9 Fix for incomplete byteorder fix in cmd_scsi.c and cmd_usb.c 2005-02-04 21:33:05 +00:00
wdenk
f8883cb101 Fix byteorder problem in usbboot and scsiboot commands. 2005-02-04 15:38:08 +00:00
wdenk
20a80418f9 * Patch by Cajus Hahn, 04 Feb 2005:
- don't insist on leading '/' for filename in ext2load
  - set default partition to useful value (1) in ext2load

* Patch by Andrew Dyer, 08 Jan 2005:
  fix wrong return codes in ext2 code
2005-02-04 15:02:06 +00:00
wdenk
1a344f298d * Removed '--no-warn-mismatch' option from Makefile. This option
makes 'ld' to overlook binary objects compatibility.

* Moved $(PLATFORM_LIBS) from the library group (--start-group ...
  --end-group) outside of the group. This will make 'ld' to do
  _multiple_ search in the library group when resolving symbol
  references and do only a _single_ seach in libgcc.a after the group
  search.

* Fix stability problems on CPC45 board again.

* Make image detection for diskboot / usbboot / scsiboot more robust
  (also check header checksum)
2005-02-03 23:00:49 +00:00
wdenk
436be29cad * Update CPC45 board configuration.
* Add USB and PCI support for INKA4x0 board
2005-01-31 22:09:11 +00:00
wdenk
cd172b7108 Fix IDE stability problems on CPC45 board. 2005-01-22 18:26:04 +00:00
wdenk
c3d2b4b48a Code cleanup. 2005-01-22 18:13:04 +00:00
wdenk
5a95f6fbd2 * Patch by Robin Getz, 13 Oct 2004:
Add standalone application to change SMC91C111 MAC addresses,
  see examples/README.smc91111_eeprom

* Patch by Xiaogeng (Shawn) Jin, 12 Oct 2004:
  Fix Flash support for ARM Integrator CP.
2005-01-12 00:38:03 +00:00
wdenk
289f932c5f * Some Cleanup.
* Patch by Richard Woodruff, 10 Jan 2005:
  Update support for OMAP2420 (ARM11) and H4 board:
  o clean up and add new types to H4 memory probe code.
  o fix to work with internal boot.
  o added PRCM config III operation.
  o fix marginal flash timings.
  o add revison ATAG usage.
  o enable voltage scaling at power chip.
  o fix compile error for i2c.

* Fix network problem (error when receiving multiple ARP packets)
2005-01-12 00:15:14 +00:00
wdenk
082acfd484 Coding Style cleanup 2005-01-10 00:01:04 +00:00
wdenk
652a10c096 * Patch by Daniel Poirot, 10 Oct 2004:
Add support for Wind River sbc405 board

* Patch by Rainer Brestan, 12 Oct 2004:
  Make examples/Makefile more robust
2005-01-09 23:48:14 +00:00
wdenk
6225c5db6c * Patch by Sam Song, 11 October 2004:
- Add RESET/PREBOOT/AUTOBOOT support for RPXlite_DW board
  - Adjust CPU:BUS frequency ratio 1:1 when core frequency
    less than 50MHz

* Patch by Sam Song, 10 Oct 2004:
  Fix a parameter error in run_command() in main.c
2005-01-09 23:33:49 +00:00
wdenk
8ed9604613 * Patches by Richard Woodruff, 01 Oct 2004:
add support for the TI OMAP2420 processor and its H4 reference
  board

* Patch by Christian Pellegrin, 24 Sep 2004:
  Added support for NE2000 compatible (DP8390, DP83902) NICs.
2005-01-09 23:16:25 +00:00
wdenk
ff36fd8591 * Patch by Leif Lindholm, 23 Sep 2004:
add support for the AMD db1550 board

* Patch by Travis Sawyer, 15 Sep 2004:
  Add CONFIG_SERIAL_MULTI support for ppc4xx,
  update README.serial_multi
2005-01-09 22:28:56 +00:00
wdenk
6310eb9da7 Patches by David Snowdon, 07 Sep 2004:
- add u-boot.hex target in the top level Makefile
- add support for the UNSW/NICTA PLEB 2 board (pleb2)
- use -mtune=xscale and -march=armv5 options for PXA
2005-01-09 21:28:15 +00:00
wdenk
a562e1bd9d Patch by Florian Schlote, 08 Sep 2004:
Add support for SenTec-COBRA5272-board (Coldfire).
2005-01-09 18:21:42 +00:00
wdenk
30ce5ab043 * Patch by Gleb Natapov, 07 Sep 2004:
mpc824x: set PCI latency timer to a sane value
  (is 0 after reset).

* Patch by Kurt Stremerch, 03 Sep 2004:
  Add bitstream configuration option for fpga command (Xilinx only).
2005-01-09 18:12:51 +00:00
wdenk
9dd611b8c1 * Patch by Kurt Stremerch, 03 Sep 2004:
Add Xilinx Spartan2E family FPGA support

* Patch by Jeff Angielski, 02 Sep 2004:
  Add Added support for H2 revision of the EP8260 board.
  Fixed formatting for some of the EP8260 related source files.
2005-01-09 17:19:34 +00:00
wdenk
a1191902ca * Patch by Jon Loeliger, 02 Sep 2004:
Reset monitor size back to 256 so environment can be written
  to flash on MPC85xx ADS and CDS releases.

* Patch by Paolo Broggini, 02 Sep 2004:
  Make BSS clearing on ARM systems more robust

* Patch by Yue Hu and Joe, 01 Sep 2004:
  - add PCI support for ixp425;
  - add EEPRO100 suppor tfor ixdp425 board.

* Fix problem with protected sector detection in driver/cfi_flash.c
2005-01-09 17:12:27 +00:00
wdenk
15c7a8efd2 Release U-Boot 1.1.2 2005-01-02 17:02:54 +00:00
wdenk
e2ffd59b4d * Code cleanup, mostly for GCC-3.3.x
* Cleanup confusing use of CONFIG_ETH*ADDR - ust his only to
  pre-define a MAC address; use CONFIG_HAS_ETH* to enable support for
  additional ethernet addresses.

* Cleanup drivers/i82365.c - avoid duplication of code

* Fix bogus "cannot span across banks" flash error message

* Add support for CompactFlash for the CPC45 Board.
2004-12-31 09:32:47 +00:00
wdenk
400ab719c6 Fix problems with CMC_PU2 flash driver. 2004-12-20 11:18:07 +00:00
wdenk
08f272787a * Fix problems with CMC_PU2 flash driver.
* Adjust INKA 4x0 default settings
2004-12-19 21:39:27 +00:00
177 changed files with 15386 additions and 961 deletions

137
CHANGELOG
View File

@@ -1,7 +1,142 @@
======================================================================
Changes since U-Boot 1.1.1:
Changes for U-Boot 1.1.3:
======================================================================
* Fix cirrus voltage detection (for CPC45)
* Fix byteorder problem in usbboot and scsiboot commands.
* Patch by Cajus Hahn, 04 Feb 2005:
- don't insist on leading '/' for filename in ext2load
- set default partition to useful value (1) in ext2load
* Patch by Andrew Dyer, 08 Jan 2005:
fix wrong return codes in ext2 code
* Removed '--no-warn-mismatch' option from Makefile. This option
makes 'ld' to overlook binary objects compatibility.
* Moved $(PLATFORM_LIBS) from the library group (--start-group ...
--end-group) outside of the group. This will make 'ld' to do
_multiple_ search in the library group when resolving symbol
references and do only a _single_ seach in libgcc.a after the group
search.
* Fix stability problems on CPC45 board again.
* Make image detection for diskboot / usbboot / scsiboot more robust
(also check header checksum)
* Update CPC45 board configuration.
* Add USB and PCI support for INKA4x0 board
* Fix IDE stability problems on CPC45 board (needs 2 x EIEIO).
* Code cleanup
* Patch by Robin Getz, 13 Oct 2004:
Add standalone application to change SMC91C111 MAC addresses,
see examples/README.smc91111_eeprom
* Patch by Xiaogeng (Shawn) Jin, 12 Oct 2004:
Fix Flash support for ARM Integrator CP.
* Patch by Richard Woodruff, 10 Jan 2005:
Update support for OMAP2420 (ARM11) and H4 board:
o clean up and add new types to H4 memory probe code.
o fix to work with internal boot.
o added PRCM config III operation.
o fix marginal flash timings.
o add revison ATAG usage.
o enable voltage scaling at power chip.
o fix compile error for i2c.
* Fix network problem (error when receiving multiple ARP packets)
* Patch by Daniel Poirot, 12 Oct 2004:
Add support for Wind River sbc405 board
* Patch by Rainer Brestan, 12 Oct 2004:
Make examples/Makefile more robust
* Patch by Sam Song, 11 October 2004:
- Add RESET/PREBOOT/AUTOBOOT support for RPXlite_DW board
- Adjust CPU:BUS frequency ratio 1:1 when core frequency
less than 50MHz
* Patch by Sam Song, 10 Oct 2004:
Fix a parameter error in run_command() in main.c
* Patch by Richard Woodruff, 01 Oct 2004:
add support for the TI OMAP2420 processor and its H4 reference
board
* Patch by Christian Pellegrin, 24 Sep 2004:
Added support for NE2000 compatible (DP8390, DP83902) NICs.
* Patch by Leif Lindholm, 23 Sep 2004:
add support for the AMD db1550 board
* Patch by Travis Sawyer, 15 Sep 2004:
Add CONFIG_SERIAL_MULTI support for ppc4xx,
update README.serial_multi
* Patches by David Snowdon, 07 Sep 2004:
- add u-boot.hex target in the top level Makefile
- add support for the UNSW/NICTA PLEB 2 board (pleb2)
- use -mtune=xscale and -march=armv5 options for PXA
* Patch by Florian Schlote, 08 Sep 2004:
Add support for SenTec-COBRA5272-board (Coldfire).
* Patch by Gleb Natapov, 07 Sep 2004:
mpc824x: set PCI latency timer to a sane value
(is 0 after reset).
* Patch by Kurt Stremerch, 03 Sep 2004:
Add bitstream configuration option for fpga command (Xilinx only).
* Patch by Kurt Stremerch, 03 Sep 2004:
Add Xilinx Spartan2E family FPGA support
* Patch by Jeff Angielski, 02 Sep 2004:
Add Added support for H2 revision of the EP8260 board.
Fixed formatting for some of the EP8260 related source files.
* Patch by Jon Loeliger, 02 Sep 2004:
Reset monitor size back to 256 so environment can be written
to flash on MPC85xx ADS and CDS releases.
* Patch by Paolo Broggini, 02 Sep 2004:
Make BSS clearing on ARM systems more robust
* Patch by Yue Hu and Joe, 01 Sep 2004:
- add PCI support for ixp425;
- add EEPRO100 suppor tfor ixdp425 board.
* Fix problem with protected sector detection in driver/cfi_flash.c
======================================================================
Changes for U-Boot 1.1.2:
======================================================================
* Code cleanup, mostly for GCC-3.3.x
* Cleanup confusing use of CONFIG_ETH*ADDR - ust his only to
pre-define a MAC address; use CONFIG_HAS_ETH* to enable support for
additional ethernet addresses.
* Cleanup drivers/i82365.c - avoid duplication of code
* Fix bogus "cannot span across banks" flash error message
* Code cleanup
* Add support for CompactFlash for the CPC45 Board.
* Fix problems with CMC_PU2 flash driver.
* Cleanup:
- avoid trigraph warning in fs/ext2/ext2fs.c
- rename UC100 -> uc100

View File

@@ -253,6 +253,10 @@ E: team@leox.org
D: Support for LEOX boards, DS164x RTC
W: http://www.leox.org
N: Leif Lindholm
E: leif.lindholm@i3micro.com
D: Support for AMD dbau1550 board.
N: Stephan Linz
E: linz@li-pro.net
D: Support for Nios Stratix Development Kit (DK-1S10)
@@ -329,7 +333,7 @@ D: BedBug embedded debugger code
N: Daniel Poirot
E: dan.poirot@windriver.com
D: Support for the sbc8240 board
D: Support for the Wind River sbc405, sbc8240 board
W: http://www.windriver.com
N: Stefan Roese

View File

@@ -225,6 +225,10 @@ Denis Peter <d.peter@mpl.ch>
MIP405 PPC4xx
PIP405 PPC4xx
Daniel Poirot <dan.poirot@windriver.com>
sbc8240 MPC8240
sbc405 PPC405GP
Stefan Roese <stefan.roese@esd-electronics.com>
ADCIOP IOP480 (PPC401)
@@ -382,6 +386,10 @@ Rishi Bhattacharya <rishi@ti.com>
omap5912osk ARM926EJS
Richard Woodruff <r-woodruff2@ti.com>
omap2420h4 ARM1136EJS
David Müller <d.mueller@elsoft.ch>
smdk2410 ARM920T

23
MAKEALL
View File

@@ -99,9 +99,9 @@ LIST_8260=" \
atc cogent_mpc8260 CPU86 ep8260 \
gw8260 hymod IPHASE4539 ISPAN \
MPC8260ADS MPC8266ADS MPC8272ADS PM826 \
PM828 ppmc8260 PQ2FADS RPXsuper \
rsdproto sacsng sbc8260 SCM \
TQM8260_AC TQM8260_AD TQM8260_AE ZPC1900 \
PM828 ppmc8260 RPXsuper rsdproto \
sacsng sbc8260 SCM TQM8260_AC \
TQM8260_AD TQM8260_AE ZPC1900 \
"
#########################################################################
@@ -157,6 +157,11 @@ LIST_ARM9=" \
versatile \
"
#########################################################################
## ARM11 Systems
#########################################################################
LIST_ARM11="omap2420h4"
#########################################################################
## Xscale Systems
#########################################################################
@@ -170,7 +175,11 @@ LIST_pxa=" \
LIST_ixp="ixdp425"
LIST_arm="${LIST_SA} ${LIST_ARM7} ${LIST_ARM9} ${LIST_pxa} ${LIST_ixp}"
LIST_arm=" \
${LIST_SA} \
${LIST_ARM7} ${LIST_ARM9} ${LIST_ARM11} \
${LIST_pxa} ${LIST_ixp} \
"
#########################################################################
## MIPS Systems
@@ -180,9 +189,9 @@ LIST_mips4kc="incaip"
LIST_mips5kc="purple"
LIST_au1x00="dbau1000 dbau1100 dbau1500"
LIST_au1xx0="dbau1000 dbau1100 dbau1500 dbau1550 dbau1550_el"
LIST_mips="${LIST_mips4kc} ${LIST_mips5kc} ${LIST_au1x00}"
LIST_mips="${LIST_mips4kc} ${LIST_mips5kc} ${LIST_au1xx0}"
#########################################################################
## i386 Systems
@@ -238,7 +247,7 @@ for arg in $@
do
case "$arg" in
ppc|5xx|5xxx|8xx|8220|824x|8260|85xx|4xx|7xx|74xx| \
arm|SA|ARM7|ARM9|pxa|ixp| \
arm|SA|ARM7|ARM9|ARM11|pxa|ixp| \
microblaze| \
mips| \
nios|nios2| \

View File

@@ -121,7 +121,7 @@ LIBS += common/libcommon.a
.PHONY : $(LIBS)
# Add GCC lib
PLATFORM_LIBS += --no-warn-mismatch -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
# The "tools" are needed early, so put this first
@@ -139,6 +139,9 @@ ALL = u-boot.srec u-boot.bin System.map
all: $(ALL)
u-boot.hex: u-boot
$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@
u-boot.srec: u-boot
$(OBJCOPY) ${OBJCFLAGS} -O srec $< $@
@@ -158,7 +161,7 @@ u-boot.dis: u-boot
u-boot: depend $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
$(LD) $(LDFLAGS) $$UNDEF_SYM $(OBJS) \
--start-group $(LIBS) $(PLATFORM_LIBS) --end-group \
--start-group $(LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot
$(LIBS):
@@ -833,6 +836,9 @@ PPChameleonEVB_HI_33_config: unconfig
}
@./mkconfig -a $(call xtract_4xx,$@) ppc ppc4xx PPChameleonEVB dave
sbc405_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx sbc405
VOH405_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx voh405 esd
@@ -924,6 +930,9 @@ SL8245_config: unconfig
utx8245_config: unconfig
@./mkconfig $(@:_config=) ppc mpc824x utx8245
cobra5272_config : unconfig
@./mkconfig $(@:_config=) m68k mcf52x2 cobra5272
#########################################################################
## MPC8260 Systems
#########################################################################
@@ -1397,6 +1406,12 @@ xm250_config : unconfig
xsengine_config : unconfig
@./mkconfig $(@:_config=) arm pxa xsengine
#########################################################################
## ARM1136 Systems
#########################################################################
omap2420h4_config : unconfig
@./mkconfig $(@:_config=) arm arm1136 omap2420h4
#========================================================================
# i386
#========================================================================
@@ -1461,6 +1476,16 @@ dbau1500_config : unconfig
@echo "#define CONFIG_DBAU1500 1" >>include/config.h
@./mkconfig -a dbau1x00 mips mips dbau1x00
dbau1550_config : unconfig
@ >include/config.h
@echo "#define CONFIG_DBAU1550 1" >>include/config.h
@./mkconfig -a dbau1x00 mips mips dbau1x00
dbau1550_el_config : unconfig
@ >include/config.h
@echo "#define CONFIG_DBAU1550 1" >>include/config.h
@./mkconfig -a dbau1x00 mips mips dbau1x00 "" little
#########################################################################
## MIPS64 5Kc
#########################################################################
@@ -1581,7 +1606,7 @@ clobber: clean
| xargs -0 rm -f
rm -f $(OBJS) *.bak tags TAGS
rm -fr *.*~
rm -f u-boot u-boot.map $(ALL)
rm -f u-boot u-boot.map u-boot.hex $(ALL)
rm -f tools/crc32.c tools/environment.c tools/env/crc32.c
rm -f tools/inca-swap-bytes cpu/mpc824x/bedbug_603e.c
rm -f include/asm/proc include/asm/arch include/asm

17
README
View File

@@ -130,6 +130,7 @@ Directory Hierarchy:
- s3c24x0 Files specific to Samsung S3C24X0 CPUs
- arm925t Files specific to ARM 925 CPUs
- arm926ejs Files specific to ARM 926 CPUs
- arm1136 Files specific to ARM 1136 CPUs
- at91rm9200 Files specific to Atmel AT91RM9200 CPUs
- i386 Files specific to i386 CPUs
- ixp Files specific to Intel XScale IXP CPUs
@@ -301,13 +302,13 @@ The following options need to be configured:
ARM based boards:
-----------------
CONFIG_AT91RM9200DK, CONFIG_CERF250, CONFIG_DNP1110,
CONFIG_EP7312, CONFIG_H2_OMAP1610, CONFIG_HHP_CRADLE,
CONFIG_IMPA7, CONFIG_INNOVATOROMAP1510, CONFIG_INNOVATOROMAP1610,
CONFIG_LART, CONFIG_LPD7A400 CONFIG_LUBBOCK,
CONFIG_OSK_OMAP5912, CONFIG_SHANNON, CONFIG_P2_OMAP730,
CONFIG_SMDK2400, CONFIG_SMDK2410, CONFIG_TRAB,
CONFIG_VCMA9
CONFIG_AT91RM9200DK, CONFIG_CERF250, CONFIG_DNP1110,
CONFIG_EP7312, CONFIG_H2_OMAP1610, CONFIG_HHP_CRADLE,
CONFIG_IMPA7, CONFIG_INNOVATOROMAP1510, CONFIG_INNOVATOROMAP1610,
CONFIG_LART, CONFIG_LPD7A400 CONFIG_LUBBOCK,
CONFIG_OSK_OMAP5912, CONFIG_OMAP2420H4, CONFIG_SHANNON,
CONFIG_P2_OMAP730, CONFIG_SMDK2400, CONFIG_SMDK2410,
CONFIG_TRAB, CONFIG_VCMA9
MicroBlaze based boards:
------------------------
@@ -2177,7 +2178,7 @@ configurations; the following names are supported:
FADS850SAR_config omap1610h2_config TQM850L_config
FADS860T_config omap1610inn_config TQM855L_config
FPS850L_config omap5912osk_config TQM860L_config
WALNUT405_config
omap2420h4_config WALNUT405_config
Yukon8220_config
ZPC1900_config

View File

@@ -2,11 +2,11 @@
After following the step of Yoo. Jonghoon and Wolfgang Denk,
I ported u-boot on RPXlite DW version board: RPXlite_DW or LITE_DW.
There are three differences between the Yoo-ported RPXlite and the RPXlite_DW.
There are at least three differences between the Yoo-ported RPXlite and the RPXlite_DW.
Board(in U-BOOT) version(in EmbeddedPlanet) CPU SDRAM FLASH
Board(in U-Boot) version(in EmbeddedPlanet) CPU SDRAM FLASH
RPXlite RPXlite CW 850 16MB 4MB
RPXlite_DW RPXlite DW 823e 64MB 16MB
RPXlite_DW RPXlite DW(EP 823 H1 DW) 823e 64MB 16MB
This fireware is specially coded for EmbeddedPlanet Co. Software Development
Platform(RPXlite DW),which has a NEC NL6448BC20-08 LCD panel.
@@ -17,6 +17,7 @@ It has the following three features:
The default setting is 48MHz.To get a 64MHz u-boot,just add
'64' in make command,like
make distclean
make RPXlite_DW_64_config
make all
@@ -28,19 +29,21 @@ didn't use EEPROM for ENV is that PlanetCore V2.0 use EEPROM as environment para
home.Because of the possibility of using two firewares on this board,I didn't
'disturb' EEPROM.To get NVRAM support,you may use the following build command:
make distclean
make RPXlite_DW_NVRAM_config
make all
3. LCD panel support
To support the Platform better,I added LCD panel(NL6448BC20-08) function.But bewear of
the fact that once you build this support and program it to FLASH,you should make sure
you put workable kernel and ramdisk at the right place in FLASH or through NFS.
Otherwise, you must erase this fireware manually via BDI2000 or ICE tools.So this
function is used for deployment and demo only.Pls look before you leap.
To support the Platform better,I added LCD panel(NL6448BC20-08) function.
For the convenience of debug, CONFIG_PERBOOT was supported. So you just
perss ENTER if you want to get a serial console in boot downcounting.
Then you can switch to LCD and serial console freely just typing
'run lcd' or 'run ser'. They are only vaild when CONFIG_LCD was enabled.
To get a LCD support u-boot,you can do the following:
make distclean
make RPXlite_DW_LCD_config
make all
@@ -68,7 +71,7 @@ make RPXlite_DW_64_LCD_config
The boot process by "make RPXlite_DW_config" could be:
U-Boot 1.1.1 (Jun 8 2004 - 11:16:30)
U-Boot 1.1.2 (Aug 29 2004 - 15:11:27)
CPU: PPC823EZTnnB2 at 48 MHz: 16 kB I-Cache 8 kB D-Cache
Board: RPXlite_DW
@@ -84,6 +87,68 @@ u-boot>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A word on the U-Boot enviroment variable setting and usage :
In the beginning, you could just need very simple defult environment variable setting,
like[include/configs/RPXlite.h] :
#define CONFIG_BOOTCOMMAND \
"bootp; " \
"setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \
"ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; " \
"bootm"
This is enough for kernel NFS test. But as debug process goes on, you would expect
to save some time on environment variable setting and u-boot/kernel updating.
So the default environment variable setting would become more complicated. Just like
the one I did in include/configs/RPXlite_DW.h.
Two u-boot commands, ku and uu, should be careful to use. They were designed to update
kernel and u-boot image file respectively. You must tftp your image to default address
'100000' and then use them correctly. Yeah, you can create your own command to do this
job. :-) The example u-boot image updating process could be :
u-boot>t 100000 RPXlite_DW_LCD.bin
Using SCC ETHERNET device
TFTP from server 172.16.115.6; our IP address is 172.16.115.7
Filename 'RPXlite_DW_LCD.bin'.
Load address: 0x100000
Loading: #############################
done
Bytes transferred = 144700 (2353c hex)
u-boot>run uu
Un-Protect Flash Sectors 0-4 in Bank # 1
Erase Flash Sectors 0-4 in Bank # 1
.... done
Copy to Flash... done
ff000000: 27051956 552d426f 6f742031 2e312e32 '..VU-Boot 1.1.2
ff000010: 20284175 67203239 20323030 34202d20 (Aug 29 2004 -
ff000020: 31353a32 303a3238 29000000 00000000 15:20:28).......
ff000030: 00000000 00000000 00000000 00000000 ................
ff000040: 00000000 00000000 00000000 00000000 ................
ff000050: 00000000 00000000 00000000 00000000 ................
ff000060: 00000000 00000000 00000000 00000000 ................
ff000070: 00000000 00000000 00000000 00000000 ................
ff000080: 00000000 00000000 00000000 00000000 ................
ff000090: 00000000 00000000 00000000 00000000 ................
ff0000a0: 00000000 00000000 00000000 00000000 ................
ff0000b0: 00000000 00000000 00000000 00000000 ................
ff0000c0: 00000000 00000000 00000000 00000000 ................
ff0000d0: 00000000 00000000 00000000 00000000 ................
ff0000e0: 00000000 00000000 00000000 00000000 ................
ff0000f0: 00000000 00000000 00000000 00000000 ................
u-boot updating finished
u-boot>
Also for environment updating, 'run eu' could let you erase OLD default environment variable
and then use the working u-boot environment setting.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Finally, if you want to keep the serial port to possible debug on spot for deployment, you
just need to enable 'DEPLOYMENT' in RPXlite_DW.h as 'DEBUG' does. Only the special string
defined by CONFIG_AUTOBOOT_STOP_STR like 'st' can stop the autoboot.
I'd like to extend my heartfelt gratitute to kind people for helping me work it out.
I would particually thank Wolfgang Denk for his nice help.
@@ -93,4 +158,4 @@ Sam Song, samsongshu@yahoo.com.cn
Institute of Electrical Machinery and Controls
Shanghai University
June 8,2004
Oct. 11, 2004

View File

@@ -1 +1,3 @@
TEXT_BASE = 0x20f00000
TEXT_BASE = 0x20F00000
## For testing: load at 0x20100000 and "go" at 0x201000A4
#TEXT_BASE = 0x20100000

View File

@@ -35,24 +35,15 @@
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*
* CPU to flash interface is 32-bit, so make declaration accordingly
*/
typedef unsigned short FLASH_PORT_WIDTH;
typedef volatile unsigned short FLASH_PORT_WIDTHV;
#define FPW FLASH_PORT_WIDTH
#define FPWV FLASH_PORT_WIDTHV
#define FLASH_CYCLE1 0x0555
#define FLASH_CYCLE2 0x02AA
/*-----------------------------------------------------------------------
* Functions
*/
static ulong flash_get_size(FPWV *addr, flash_info_t *info);
static ulong flash_get_size(vu_short *addr, flash_info_t *info);
static void flash_reset(flash_info_t *info);
static int write_word_amd(flash_info_t *info, FPWV *dest, FPW data);
static int write_word_amd(flash_info_t *info, vu_short *dest, ushort data);
static flash_info_t *flash_get_info(ulong base);
/*-----------------------------------------------------------------------
@@ -68,8 +59,7 @@ unsigned long flash_init (void)
/* Init: no FLASHes known */
memset(&flash_info[0], 0, sizeof(flash_info_t));
flash_info[0].size =
flash_get_size((FPW *)flashbase, &flash_info[0]);
flash_info[0].size = flash_get_size((vu_short *)flashbase, &flash_info[0]);
size = flash_info[0].size;
@@ -96,13 +86,13 @@ unsigned long flash_init (void)
*/
static void flash_reset(flash_info_t *info)
{
FPWV *base = (FPWV *)(info->start[0]);
vu_short *base = (vu_short *)(info->start[0]);
/* Put FLASH back in read mode */
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
*base = (FPW)0x00FF; /* Intel Read Mode */
*base = 0x00FF; /* Intel Read Mode */
else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
*base = (FPW)0x00F0; /* AMD Read Mode */
*base = 0x00F0; /* AMD Read Mode */
}
/*-----------------------------------------------------------------------
@@ -180,49 +170,53 @@ void flash_print_info (flash_info_t *info)
* The following code cannot be run from FLASH!
*/
ulong flash_get_size (FPWV *addr, flash_info_t *info)
ulong flash_get_size (vu_short *addr, flash_info_t *info)
{
int i;
ushort value;
ulong base = (ulong)addr;
/* Write auto select command: read Manufacturer ID */
/* Write auto select command sequence and test FLASH answer */
addr[FLASH_CYCLE1] = (FPW)0x00AA; /* for AMD, Intel ignores this */
addr[FLASH_CYCLE2] = (FPW)0x0055; /* for AMD, Intel ignores this */
addr[FLASH_CYCLE1] = (FPW)0x0090; /* selects Intel or AMD */
/* Write auto select command sequence */
addr[FLASH_CYCLE1] = 0x00AA; /* for AMD, Intel ignores this */
addr[FLASH_CYCLE2] = 0x0055; /* for AMD, Intel ignores this */
addr[FLASH_CYCLE1] = 0x0090; /* 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.
*/
/* read Manufacturer ID */
udelay(100);
switch (addr[0] & 0xff) {
value = addr[0];
debug ("Manufacturer ID: %04X\n", value);
case (uchar)AMD_MANUFACT:
switch (value) {
case (AMD_MANUFACT & 0xFFFF):
debug ("Manufacturer: AMD (Spansion)\n");
info->flash_id = FLASH_MAN_AMD;
break;
case (uchar)INTEL_MANUFACT:
case (INTEL_MANUFACT & 0xFFFF):
debug ("Manufacturer: Intel (not supported yet)\n");
info->flash_id = FLASH_MAN_INTEL;
break;
default:
printf ("Unknown Manufacturer ID: %04X\n", value);
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
break;
goto out;
}
/* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
if (info->flash_id != FLASH_UNKNOWN) switch ((FPW)addr[1]) {
value = addr[1];
debug ("Device ID: %04X\n", value);
case AMD_ID_MIRROR:
switch (addr[1]) {
case (AMD_ID_MIRROR & 0xFFFF):
debug ("Mirror Bit flash: addr[14] = %08X addr[15] = %08X\n",
addr[14], addr[15]);
switch(addr[14] & 0xffff) {
case (AMD_ID_GL064M_2 & 0xffff):
switch(addr[14]) {
case (AMD_ID_GL064M_2 & 0xFFFF):
if (addr[15] != (AMD_ID_GL064M_3 & 0xffff)) {
printf ("Chip: S29GLxxxM -> unknown\n");
info->flash_id = FLASH_UNKNOWN;
@@ -249,11 +243,14 @@ ulong flash_get_size (FPWV *addr, flash_info_t *info)
break;
default:
printf ("Unknown Device ID: %04X\n", value);
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
break;
}
out:
/* Put FLASH back in read mode */
flash_reset(info);
@@ -265,9 +262,9 @@ ulong flash_get_size (FPWV *addr, flash_info_t *info)
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
FPWV *addr = (FPWV *)(info->start[0]);
vu_short *addr = (vu_short *)(info->start[0]);
int flag, prot, sect, ssect, l_sect;
ulong start, now, last;
ulong now, last;
debug ("flash_erase: first: %d last: %d\n", s_first, s_last);
@@ -324,7 +321,7 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
if ((sect + ssect) > s_last)
break;
if (info->protect[sect + ssect] == 0) { /* not protected */
addr = (FPWV *)(info->start[sect + ssect]);
addr = (vu_short *)(info->start[sect + ssect]);
addr[0] = 0x0030;
l_sect = sect + ssect;
}
@@ -338,11 +335,11 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
if (l_sect < 0)
goto DONE;
start = get_timer (0);
last = start;
addr = (FPWV *)(info->start[l_sect]);
reset_timer_masked ();
last = 0;
addr = (vu_short *)(info->start[l_sect]);
while ((addr[0] & 0x0080) != 0x0080) {
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
if ((now = get_timer_masked ()) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
return 1;
}
@@ -352,7 +349,7 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
last = now;
}
}
addr = (FPWV *)info->start[0];
addr = (vu_short *)info->start[0];
addr[0] = 0x00F0; /* reset bank */
sect += ssect;
}
@@ -363,7 +360,7 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
DONE:
/* reset to read mode */
addr = (FPWV *)info->start[0];
addr = (vu_short *)info->start[0];
addr[0] = 0x00F0; /* reset bank */
printf (" done\n");
@@ -395,8 +392,9 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
wp = addr;
while (cnt >= 2) {
data = *((FPWV *)src);
if ((rc = write_word_amd(info, (FPW *)wp, data)) != 0) {
data = *((vu_short *)src);
if ((rc = write_word_amd(info, (vu_short *)wp, data)) != 0) {
printf ("write_buff 1: write_word_amd() rc=%d\n", rc);
return (rc);
}
src += 2;
@@ -405,13 +403,13 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
}
if (cnt == 0) {
return (0);
return (ERR_OK);
}
if (cnt == 1) {
data = (*((volatile u8 *) src)) | (*((volatile u8 *) (wp + 1))
<< 8);
if ((rc = write_word_amd(info, (FPW *)wp, data)) != 0) {
data = (*((volatile u8 *) src)) | (*((volatile u8 *) (wp + 1)) << 8);
if ((rc = write_word_amd(info, (vu_short *)wp, data)) != 0) {
printf ("write_buff 1: write_word_amd() rc=%d\n", rc);
return (rc);
}
src += 1;
@@ -432,25 +430,24 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data)
static int write_word_amd (flash_info_t *info, vu_short *dest, ushort data)
{
ulong start;
int flag;
FPWV *base; /* first address in flash bank */
vu_short *base; /* first address in flash bank */
/* Check if Flash is (sufficiently) erased */
if ((*dest & data) != data) {
return (2);
}
base = (FPWV *)(info->start[0]);
base = (vu_short *)(info->start[0]);
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
base[FLASH_CYCLE1] = (FPW)0x00AA; /* unlock */
base[FLASH_CYCLE2] = (FPW)0x0055; /* unlock */
base[FLASH_CYCLE1] = (FPW)0x00A0; /* selects program mode */
base[FLASH_CYCLE1] = 0x00AA; /* unlock */
base[FLASH_CYCLE2] = 0x0055; /* unlock */
base[FLASH_CYCLE1] = 0x00A0; /* selects program mode */
*dest = data; /* start programming the data */
@@ -458,12 +455,12 @@ static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data)
if (flag)
enable_interrupts();
start = get_timer (0);
reset_timer_masked ();
/* data polling for D7 */
while ((*dest & (FPW)0x0080) != (data & (FPW)0x0080)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
*dest = (FPW)0x00F0; /* reset bank */
while ((*dest & 0x0080) != (data & 0x0080)) {
if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
*dest = 0x00F0; /* reset bank */
return (1);
}
}

40
board/cobra5272/Makefile Normal file
View File

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

View File

@@ -0,0 +1,169 @@
#
# GDB Init script for the Coldfire 5272 processor.
#
# The main purpose of this script is to configure the
# DRAM controller so code can be loaded.
#
# This file was changed to suite the senTec COBRA5272 board.
#
define addresses
set $mbar = 0x10000001
set $scr = $mbar - 1 + 0x004
set $spr = $mbar - 1 + 0x006
set $pmr = $mbar - 1 + 0x008
set $apmr = $mbar - 1 + 0x00e
set $dir = $mbar - 1 + 0x010
set $icr1 = $mbar - 1 + 0x020
set $icr2 = $mbar - 1 + 0x024
set $icr3 = $mbar - 1 + 0x028
set $icr4 = $mbar - 1 + 0x02c
set $isr = $mbar - 1 + 0x030
set $pitr = $mbar - 1 + 0x034
set $piwr = $mbar - 1 + 0x038
set $pivr = $mbar - 1 + 0x03f
set $csbr0 = $mbar - 1 + 0x040
set $csor0 = $mbar - 1 + 0x044
set $csbr1 = $mbar - 1 + 0x048
set $csor1 = $mbar - 1 + 0x04c
set $csbr2 = $mbar - 1 + 0x050
set $csor2 = $mbar - 1 + 0x054
set $csbr3 = $mbar - 1 + 0x058
set $csor3 = $mbar - 1 + 0x05c
set $csbr4 = $mbar - 1 + 0x060
set $csor4 = $mbar - 1 + 0x064
set $csbr5 = $mbar - 1 + 0x068
set $csor5 = $mbar - 1 + 0x06c
set $csbr6 = $mbar - 1 + 0x070
set $csor6 = $mbar - 1 + 0x074
set $csbr7 = $mbar - 1 + 0x078
set $csor7 = $mbar - 1 + 0x07c
set $pacnt = $mbar - 1 + 0x080
set $paddr = $mbar - 1 + 0x084
set $padat = $mbar - 1 + 0x086
set $pbcnt = $mbar - 1 + 0x088
set $pbddr = $mbar - 1 + 0x08c
set $pbdat = $mbar - 1 + 0x08e
set $pcddr = $mbar - 1 + 0x094
set $pcdat = $mbar - 1 + 0x096
set $pdcnt = $mbar - 1 + 0x098
set $sdcr = $mbar - 1 + 0x180
set $sdtr = $mbar - 1 + 0x184
set $wrrr = $mbar - 1 + 0x280
set $wirr = $mbar - 1 + 0x283
set $wcr = $mbar - 1 + 0x288
set $wer = $mbar - 1 + 0x28c
end
#
# Setup system configuration
#
define setup-sys
set *((unsigned short *) $scr) = 0x0003
set *((unsigned short *) $spr) = 0xffff
set *((unsigned char *) $pivr) = 0x4f
end
#
# Setup Chip Selects (as per Motorola M5272C3 board)
#
define setup-cs
# CS0 -- FLASH
set *((unsigned long *) $csbr0) = 0xffe00201
set *((unsigned long *) $csor0) = 0xffe00014
# CS1 -- external bus test
set *((unsigned long *) $csbr1) = 0x0
set *((unsigned long *) $csor1) = 0x0
# CS2 -- Optional FSRAM
set *((unsigned long *) $csbr2) = 0x30000001
set *((unsigned long *) $csor2) = 0xfff80000
# CS3 -- not used
set *((unsigned long *) $csbr3) = 0x0
set *((unsigned long *) $csor3) = 0x0
# CS4 -- not used
set *((unsigned long *) $csbr4) = 0x0
set *((unsigned long *) $csor4) = 0x0
# CS5 -- PLI socket0
set *((unsigned long *) $csbr5) = 0x0
set *((unsigned long *) $csor5) = 0x0
# CS6 -- PLI socket1
set *((unsigned long *) $csbr6) = 0x0
set *((unsigned long *) $csor6) = 0x0
# CS7 -- SDRAM
set *((unsigned long *) $csbr7) = 0x00000701
set *((unsigned long *) $csor7) = 0xff00007c
end
#
# Setup the DRAM controller.
#
define setup-dram
set *((unsigned long *) $sdtr) = 0x0000f539
set *((unsigned long *) $sdcr) = 0x00004211
# Dummy write to start SDRAM
set *((unsigned long *) 0) = 0
end
#
# Setup for GPIO pins
#
define setup-ppio
# PORT A -- the LED's
set *((unsigned long *) $pacnt) = 0x00000000
# lower 8 bits for output:
set *((unsigned short *) $paddr) = 0xff
# LED's off:
set *((unsigned short *) $padat) = 0xff
# PORT B
set *((unsigned long *) $pbcnt) = 0x55554155
set *((unsigned short *) $pbddr) = 0x0000
set *((unsigned short *) $pbdat) = 0x17ea
# PORT C
#set *((unsigned short *) $pcddr) = 0x0000
#set *((unsigned short *) $pcdat) = 0x1898
# PORT D
set *((unsigned long *) $pdcnt) = 0x00000000
end
#
# Added for uClinux-coldfire target...
#
target bdm /dev/bdm
addresses
setup-sys
setup-cs
setup-dram
setup-ppio
set print pretty
set print asm-demangle
display/i $pc
#
load u-boot
set $pc=0x20000
c

View File

@@ -0,0 +1,2 @@
target bdm /dev/bdmcf0
q

View File

@@ -0,0 +1,2 @@
m68k-bdm-elf-gdb -n -x board/cobra5272/bdm/cobra5272_uboot.gdb u-boot

View File

@@ -0,0 +1,2 @@
m68k-bdm-elf-gdb -n -x bdm/gdbinit.reset

View File

@@ -0,0 +1,55 @@
/*
* (C) Copyright 2000-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/m5272.h>
#include <asm/immap_5272.h>
int checkboard (void)
{
puts ("Board: ");
puts ("senTec COBRA5272 Board\n");
return 0;
};
long int initdram (int board_type)
{
volatile sdramctrl_t *sdp = (sdramctrl_t *) (CFG_MBAR + MCFSIM_SDCR);
sdp->sdram_sdtr = 0xf539;
sdp->sdram_sdcr = 0x4211;
/* Dummy write to start SDRAM */
*((volatile unsigned long *) 0) = 0;
return CFG_SDRAM_SIZE * 1024 * 1024;
};
int testdram (void)
{
/* TODO: XXX XXX XXX */
printf ("DRAM test not implemented!\n");
return (0);
}

25
board/cobra5272/config.mk Normal file
View File

@@ -0,0 +1,25 @@
#
# (C) Copyright 2000-2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
# Coldfire contribution by Bernhard Kuhn <bkuhn@metrowerks.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
#
TEXT_BASE = 0xffe00000

378
board/cobra5272/flash.c Normal file
View File

@@ -0,0 +1,378 @@
/*
* (C) Copyright 2000-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>
#define PHYS_FLASH_1 CFG_FLASH_BASE
#define FLASH_BANK_SIZE 0x200000
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
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_PL160CB & FLASH_TYPEMASK):
printf ("AM29PL160CB (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:
}
unsigned long 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 =
(AMD_MANUFACT & FLASH_VENDMASK) |
(AMD_ID_PL160CB & 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 == 0) {
/* 1st is 16 KiB */
flash_info[i].start[j] = flashbase;
}
if ((j >= 1) && (j <= 2)) {
/* 2nd and 3rd are 8 KiB */
flash_info[i].start[j] =
flashbase + 0x4000 + 0x2000 * (j - 1);
}
if (j == 3) {
/* 4th is 224 KiB */
flash_info[i].start[j] = flashbase + 0x8000;
}
if ((j >= 4) && (j <= 10)) {
/* rest is 256 KiB */
flash_info[i].start[j] =
flashbase + 0x40000 + 0x40000 * (j -
4);
}
}
size += flash_info[i].size;
}
flash_protect (FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_FLASH_BASE + 0x3ffff, &flash_info[0]);
return size;
}
#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 + (0x00000555<<1)))
#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x000002AA<<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
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) !=
(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 ();
printf ("\n");
/* 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 */
set_timer (0);
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 (0) > 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 (10000);
if (iflag)
enable_interrupts ();
if (cflag)
icache_enable ();
return rc;
}
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 */
set_timer (0);
/* wait until flash is ready */
chip1 = 0;
do {
result = *addr;
/* check timeout */
if (get_timer (0) > 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;
}
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 0
if (cnt & 1) {
printf ("odd transfer sizes not supported\n");
return ERR_ALIGN;
}
#endif
wp = addr;
if (addr & 1) {
data = (*((volatile u8 *) addr) << 8) | *((volatile u8 *)
src);
if ((rc = write_word (info, wp - 1, data)) != 0) {
return (rc);
}
src += 1;
wp += 1;
cnt -= 1;
}
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) << 8) |
*((volatile u8 *) (wp + 1));
if ((rc = write_word (info, wp, data)) != 0) {
return (rc);
}
src += 1;
wp += 1;
cnt -= 1;
}
return ERR_OK;
}

142
board/cobra5272/u-boot.lds Normal file
View File

@@ -0,0 +1,142 @@
/*
* (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(m68k)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/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/mcf52x2/start.o (.text)
cpu/mcf52x2/cpu_init.o (.text)
lib_m68k/traps.o (.text)
cpu/mcf52x2/interrupts.o (.text)
common/dlmalloc.o (.text)
lib_generic/zlib.o (.text)
. = DEFINED(env_offset) ? 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_start = .;
*(.got)
__got_end = .;
_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 = .);
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
__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 = .;
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
. = ALIGN(4);
_ebss = .;
}
_end = . ;
PROVIDE (end = .);
}

View File

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

View File

@@ -24,11 +24,13 @@
#include <common.h>
#include <mpc824x.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <pci.h>
#include <i2c.h>
int sysControlDisplay(int digit, uchar ascii_code);
extern void Plx9030Init(void);
extern void SPD67290Init(void);
/* We have to clear the initial data area here. Couldn't have done it
* earlier because DRAM had not been initialized.
@@ -180,6 +182,10 @@ static struct pci_config_table pci_cpc45_config_table[] = {
pci_cfgfunc_config_device, { PCI_PLX9030_IOADDR,
PCI_PLX9030_MEMADDR,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0E, PCI_ANY_ID,
pci_cfgfunc_config_device, { PCMCIA_IO_BASE,
PCMCIA_IO_BASE,
PCI_COMMAND_MEMORY | PCI_COMMAND_IO }},
#endif /*CONFIG_PCI_PNP*/
{ }
};
@@ -233,3 +239,37 @@ int sysControlDisplay (int digit, /* number of digit 0..7 */
return (0);
}
#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
#ifdef CFG_PCMCIA_MEM_ADDR
volatile unsigned char *pcmcia_mem = (unsigned char*)CFG_PCMCIA_MEM_ADDR;
#endif
int pcmcia_init(void)
{
u_int rc;
debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
rc = i82365_init();
return rc;
}
#endif /* CFG_CMD_PCMCIA */
# ifdef CONFIG_IDE_LED
void ide_led (uchar led, uchar status)
{
u_char val;
/* We have one PCMCIA slot and use LED H4 for the IDE Interface */
val = readb(BCSR_BASE + 0x04);
if (status) { /* led on */
val |= B_CTRL_LED0;
} else {
val &= ~B_CTRL_LED0;
}
writeb(val, BCSR_BASE + 0x04);
}
# endif

68
board/cpc45/pd67290.c Normal file
View File

@@ -0,0 +1,68 @@
/* pd67290.c - system configuration module for SPD67290
*
* 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
*
* (C) 2004 DENX Software Engineering, Heiko Schocher <hs@denx.de>
*/
#include <common.h>
#include <malloc.h>
#include <net.h>
#include <asm/io.h>
#include <pci.h>
/* imports */
#include <mpc824x.h>
static struct pci_device_id supported[] = {
{PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6729},
{}
};
/***************************************************************************
*
* SPD67290Init -
*
* RETURNS: -1 on error, 0 if OK
*/
int SPD67290Init (void)
{
pci_dev_t devno;
int idx = 0; /* general index */
ulong membaseCsr; /* base address of device memory space */
/* find PD67290 device */
if ((devno = pci_find_devices (supported, idx++)) < 0) {
printf ("No PD67290 device found !!\n");
return -1;
}
/* - 0xfe000000 see MPC 8245 Users Manual Adress Map B */
membaseCsr = PCMCIA_IO_BASE - 0xfe000000;
/* 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_IO | PCI_COMMAND_WAIT);
return 0;
}

View File

@@ -30,7 +30,7 @@ long int initdram(int board_type)
{
/* Sdram is setup by assembler code */
/* If memory could be changed, we should return the true value here */
return 64*1024*1024;
return MEM_SIZE*1024*1024;
}
#define BCSR_PCMCIA_PC0DRVEN 0x0010
@@ -41,9 +41,11 @@ void write_one_tlb( int index, u32 pagemask, u32 hi, u32 low0, u32 low1 );
int checkboard (void)
{
#ifdef CONFIG_IDE_PCMCIA
u16 status;
volatile u32 *pcmcia_bcsr = (u32*)(DB1000_BCSR_ADDR+0x10);
volatile u32 *phy = (u32*)(DB1000_BCSR_ADDR+0xC);
volatile u32 *pcmcia_bcsr = (u32*)(DB1XX0_BCSR_ADDR+0x10);
#endif /* CONFIG_IDE_PCMCIA */
volatile u32 *phy = (u32*)(DB1XX0_BCSR_ADDR+0xC);
volatile u32 *sys_counter = (volatile u32*)SYS_COUNTER_CNTRL;
u32 proc_id;
@@ -67,6 +69,11 @@ int checkboard (void)
printf ("CPU: Au1100, id: 0x%02x, rev: 0x%02x\n",
(proc_id >> 8) & 0xFF, proc_id & 0xFF);
break;
case 3:
puts ("Board: DbAu1550\n");
printf ("CPU: Au1550, id: 0x%02x, rev: 0x%02x\n",
(proc_id >> 8) & 0xFF, proc_id & 0xFF);
break;
default:
printf ("Unsupported cpu %d, proc_id=0x%x\n", proc_id >> 24, proc_id);
}

View File

@@ -9,7 +9,8 @@
#define AU1500_SYS_ADDR 0xB1900000
#define sys_endian 0x0038
#define CP0_Config0 $16
#define MEM_1MS ((396000000/1000000) * 1000)
#define CPU_SCALE ((CFG_MHZ) / 12) /* CPU clock is a multiple of 12 MHz */
#define MEM_1MS ((CFG_MHZ) * 1000)
.text
.set noreorder
@@ -23,6 +24,19 @@ memsetup:
* Switch S1.1 Off(bit7 reads 1) is Little Endian
* Switch S1.1 On (bit7 reads 0) is Big Endian
*/
#ifdef CONFIG_DBAU1550
li t0, MEM_STCFG2
li t1, 0x00000040
sw t1, 0(t0)
li t0, MEM_STTIME2
li t1, 0x22080a20
sw t1, 0(t0)
li t0, MEM_STADDR2
li t1, 0x10c03f00
sw t1, 0(t0)
#else
li t0, MEM_STCFG1
li t1, 0x00000080
sw t1, 0(t0)
@@ -34,9 +48,10 @@ memsetup:
li t0, MEM_STADDR1
li t1, 0x10c03f00
sw t1, 0(t0)
#endif
li t0, 0xAE000008
lw t1,0(t0)
li t0, DB1XX0_BCSR_ADDR
lw t1,8(t0)
andi t1,t1,0x80
beq zero,t1,big_endian
nop
@@ -98,10 +113,82 @@ big_endian:
mtc0 zero, CP0_WIRED
nop
#ifdef CONFIG_DBAU1550
/* No workaround if running from ram */
lui t0, 0xffc0
lui t3, 0xbfc0
and t1, ra, t0
bne t1, t3, noCacheJump
nop
/*** From AMD YAMON ***/
/*
* Step 8) Initialize the caches
*/
li t0, (16*1024)
li t1, 32
li t2, 0x80000000
addu t3, t0, t2
cacheloop:
cache 0, 0(t2)
cache 1, 0(t2)
addu t2, t1
bne t2, t3, cacheloop
nop
/* Save return address */
move t3, ra
/* Run from cacheable space now */
bal cachehere
nop
cachehere:
li t1, ~0x20000000 /* convert to KSEG0 */
and t0, ra, t1
addi t0, 5*4 /* 5 insns beyond cachehere */
jr t0
nop
/* Restore return address */
move ra, t3
/*
* Step 9) Initialize the TLB
*/
li t0, 0 # index value
li t1, 0x00000000 # entryhi value
li t2, 32 # 32 entries
tlbloop:
/* Probe TLB for matching EntryHi */
mtc0 t1, CP0_ENTRYHI
tlbp
nop
/* Examine Index[P], 1=no matching entry */
mfc0 t3, CP0_INDEX
li t4, 0x80000000
and t3, t4, t3
addiu t1, t1, 1 # increment t1 (asid)
beq zero, t3, tlbloop
nop
/* Initialize the TLB entry */
mtc0 t0, CP0_INDEX
mtc0 zero, CP0_ENTRYLO0
mtc0 zero, CP0_ENTRYLO1
mtc0 zero, CP0_PAGEMASK
tlbwi
/* Do it again */
addiu t0, t0, 1
bne t0, t2, tlbloop
nop
/* First setup pll:s to make serial work ok */
/* We have a 12 MHz crystal */
li t0, SYS_CPUPLL
li t1, 0x21 /* 396 MHz */
li t1, CPU_SCALE /* CPU clock */
sw t1, 0(t0)
sync
nop
@@ -119,19 +206,49 @@ big_endian:
sync
/* Static memory controller */
/* RCE0 - can not change while fetching, do so from icache */
move t2, ra /* Store return address */
bal getAddr
nop
getAddr:
move t1, ra
move ra, t2 /* Move return addess back */
cache 0x14,0(t1)
cache 0x14,32(t1)
/*** /From YAMON ***/
noCacheJump:
#endif /* CONFIG_DBAU1550 */
#ifdef CONFIG_DBAU1550
li t0, MEM_STTIME0
li t1, 0x040181D7
sw t1, 0(t0)
/* RCE0 AMD MirrorBit Flash (?) */
li t0, MEM_STCFG0
li t1, 0x00000003
sw t1, 0(t0)
li t0, MEM_STADDR0
li t1, 0x11803E00
sw t1, 0(t0)
#else /* CONFIG_DBAU1550 */
li t0, MEM_STTIME0
li t1, 0x00014C0F
sw t1, 0(t0)
/* RCE0 AMD 29LV640M MirrorBit Flash */
li t0, MEM_STCFG0
li t1, 0x00000013
sw t1, 0(t0)
li t0, MEM_STTIME0
li t1, 0x040181D7
sw t1, 0(t0)
li t0, MEM_STADDR0
li t1, 0x11E03F80
sw t1, 0(t0)
#endif /* CONFIG_DBAU1550 */
/* RCE1 CPLD Board Logic */
li t0, MEM_STCFG1
@@ -146,7 +263,20 @@ big_endian:
li t1, 0x10c03f00
sw t1, 0(t0)
#ifdef CONFIG_DBAU1550
/* RCE2 CPLD Board Logic */
li t0, MEM_STCFG2
li t1, 0x00000040
sw t1, 0(t0)
li t0, MEM_STTIME2
li t1, 0x22080a20
sw t1, 0(t0)
li t0, MEM_STADDR2
li t1, 0x10c03f00
sw t1, 0(t0)
#else
li t0, MEM_STCFG2
li t1, 0x00000000
sw t1, 0(t0)
@@ -158,6 +288,7 @@ big_endian:
li t0, MEM_STADDR2
li t1, 0x00000000
sw t1, 0(t0)
#endif
/* RCE3 PCMCIA 250ns */
li t0, MEM_STCFG3
@@ -281,6 +412,99 @@ big_endian:
bne t1, zero, 1b
nop
#ifdef CONFIG_DBAU1550
/* SDCS 0,1,2 DDR SDRAM */
li t0, MEM_SDMODE0
li t1, 0x04276221
sw t1, 0(t0)
li t0, MEM_SDMODE1
li t1, 0x04276221
sw t1, 0(t0)
li t0, MEM_SDMODE2
li t1, 0x04276221
sw t1, 0(t0)
li t0, MEM_SDADDR0
li t1, 0xe21003f0
sw t1, 0(t0)
li t0, MEM_SDADDR1
li t1, 0xe21043f0
sw t1, 0(t0)
li t0, MEM_SDADDR2
li t1, 0xe21083f0
sw t1, 0(t0)
sync
li t0, MEM_SDCONFIGA
li t1, 0x9030060a /* Program refresh - disabled */
sw t1, 0(t0)
sync
li t0, MEM_SDCONFIGB
li t1, 0x00028000
sw t1, 0(t0)
sync
li t0, MEM_SDPRECMD /* Precharge all */
li t1, 0
sw t1, 0(t0)
sync
li t0, MEM_SDWRMD0
li t1, 0x40000000
sw t1, 0(t0)
sync
li t0, MEM_SDWRMD1
li t1, 0x40000000
sw t1, 0(t0)
sync
li t0, MEM_SDWRMD2
li t1, 0x40000000
sw t1, 0(t0)
sync
li t0, MEM_SDWRMD0
li t1, 0x00000063
sw t1, 0(t0)
sync
li t0, MEM_SDWRMD1
li t1, 0x00000063
sw t1, 0(t0)
sync
li t0, MEM_SDWRMD2
li t1, 0x00000063
sw t1, 0(t0)
sync
li t0, MEM_SDPRECMD /* Precharge all */
sw zero, 0(t0)
sync
/* Issue 2 autoref */
li t0, MEM_SDAUTOREF
sw zero, 0(t0)
sync
li t0, MEM_SDAUTOREF
sw zero, 0(t0)
sync
/* Enable refresh */
li t0, MEM_SDCONFIGA
li t1, 0x9830060a /* Program refresh - enabled */
sw t1, 0(t0)
sync
#else /* CONFIG_DBAU1550 */
/* SDCS 0,1 SDRAM */
li t0, MEM_SDMODE0
li t1, 0x005522AA
@@ -339,6 +563,7 @@ big_endian:
sw t1, 0(t0)
sync
#endif /* CONFIG_DBAU1550 */
/* wait 1mS after setup */
li t1, MEM_1MS
1: add t1, -1

View File

@@ -227,6 +227,10 @@ int checkboard (void)
major = 1;
minor = 1;
break;
case 0x06:
major = 1;
minor = 3;
break;
default:
break;
}

View File

@@ -42,250 +42,265 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
*/
void flash_reset(void)
{
if( flash_info[0].flash_id != FLASH_UNKNOWN ) {
V_ULONG( flash_info[0].start[0] ) = 0x00F000F0;
V_ULONG( flash_info[0].start[0] + 4 ) = 0x00F000F0;
}
if( flash_info[0].flash_id != FLASH_UNKNOWN ) {
V_ULONG( flash_info[0].start[0] ) = 0x00F000F0;
V_ULONG( flash_info[0].start[0] + 4 ) = 0x00F000F0;
}
}
/*-----------------------------------------------------------------------
*/
ulong flash_get_size( ulong baseaddr, flash_info_t *info )
{
short i;
unsigned long flashtest_h, flashtest_l;
short i;
unsigned long flashtest_h, flashtest_l;
/* Write auto select command sequence and test FLASH answer */
V_ULONG(baseaddr + ((ulong)0x0555 << 3)) = 0x00AA00AA;
V_ULONG(baseaddr + ((ulong)0x02AA << 3)) = 0x00550055;
V_ULONG(baseaddr + ((ulong)0x0555 << 3)) = 0x00900090;
V_ULONG(baseaddr + 4 + ((ulong)0x0555 << 3)) = 0x00AA00AA;
V_ULONG(baseaddr + 4 + ((ulong)0x02AA << 3)) = 0x00550055;
V_ULONG(baseaddr + 4 + ((ulong)0x0555 << 3)) = 0x00900090;
/* Write auto select command sequence and test FLASH answer */
V_ULONG(baseaddr + ((ulong)0x0555 << 3)) = 0x00AA00AA;
V_ULONG(baseaddr + ((ulong)0x02AA << 3)) = 0x00550055;
V_ULONG(baseaddr + ((ulong)0x0555 << 3)) = 0x00900090;
V_ULONG(baseaddr + 4 + ((ulong)0x0555 << 3)) = 0x00AA00AA;
V_ULONG(baseaddr + 4 + ((ulong)0x02AA << 3)) = 0x00550055;
V_ULONG(baseaddr + 4 + ((ulong)0x0555 << 3)) = 0x00900090;
flashtest_h = V_ULONG(baseaddr); /* manufacturer ID */
flashtest_l = V_ULONG(baseaddr + 4);
flashtest_h = V_ULONG(baseaddr); /* manufacturer ID */
flashtest_l = V_ULONG(baseaddr + 4);
if ((int)flashtest_h == AMD_MANUFACT) {
info->flash_id = FLASH_MAN_AMD;
} else {
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* no or unknown flash */
}
if ((int)flashtest_h == AMD_MANUFACT) {
info->flash_id = FLASH_MAN_AMD;
} else {
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* no or unknown flash */
}
flashtest_h = V_ULONG(baseaddr + 8); /* device ID */
flashtest_l = V_ULONG(baseaddr + 12);
if (flashtest_h != flashtest_l) {
info->flash_id = FLASH_UNKNOWN;
return(0);
}
if (flashtest_h == AMD_ID_DL323B) {
info->flash_id += FLASH_AMDL323B;
info->sector_count = 71;
info->size = 0x01000000; /* 4 * 4 MB = 16 MB */
} else {
info->flash_id = FLASH_UNKNOWN;
return(0); /* no or unknown flash */
}
flashtest_h = V_ULONG(baseaddr + 8); /* device ID */
flashtest_l = V_ULONG(baseaddr + 12);
if (flashtest_h != flashtest_l) {
info->flash_id = FLASH_UNKNOWN;
return(0);
}
/* set up sector start adress table (bottom sector type) */
for (i = 0; i < 8; i++) {
info->start[i] = baseaddr + (i * 0x00008000);
}
for (i = 8; i < info->sector_count; i++) {
info->start[i] = baseaddr + (i * 0x00040000) - 0x001C0000;
}
switch((int)flashtest_h) {
case AMD_ID_DL323B:
info->flash_id += FLASH_AMDL323B;
info->sector_count = 71;
info->size = 0x01000000; /* 4 * 4 MB = 16 MB */
break;
case AMD_ID_LV640U: /* AMDLV640 and AMDLV641 have same ID */
info->flash_id += FLASH_AMLV640U;
info->sector_count = 128;
info->size = 0x02000000; /* 4 * 8 MB = 32 MB */
break;
default:
info->flash_id = FLASH_UNKNOWN;
return(0); /* no or unknown flash */
}
/* check for protected sectors */
for (i = 0; i < info->sector_count; i++) {
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
if ((V_ULONG( info->start[i] + 16 ) & 0x00010001) ||
(V_ULONG( info->start[i] + 20 ) & 0x00010001)) {
info->protect[i] = 1; /* D0 = 1 if protected */
} else {
info->protect[i] = 0;
}
}
if(flashtest_h == AMD_ID_LV640U) {
/* set up sector start adress table (uniform sector type) */
for (i = 0; i < info->sector_count; i++)
info->start[i] = baseaddr + (i * 0x00040000);
} else {
/* set up sector start adress table (bottom sector type) */
for (i = 0; i < 8; i++) {
info->start[i] = baseaddr + (i * 0x00008000);
}
for (i = 8; i < info->sector_count; i++) {
info->start[i] = baseaddr + (i * 0x00040000) - 0x001C0000;
}
}
/* check for protected sectors */
for (i = 0; i < info->sector_count; i++) {
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
if ((V_ULONG( info->start[i] + 16 ) & 0x00010001) ||
(V_ULONG( info->start[i] + 20 ) & 0x00010001)) {
info->protect[i] = 1; /* D0 = 1 if protected */
} else {
info->protect[i] = 0;
}
}
flash_reset();
return(info->size);
flash_reset();
return(info->size);
}
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
unsigned long size_b0 = 0;
int i;
unsigned long size_b0 = 0;
int i;
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
}
/* 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 (only one bank) */
/* Static FLASH Bank configuration here (only one bank) */
size_b0 = flash_get_size(CFG_FLASH0_BASE, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN || size_b0 == 0) {
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
size_b0, size_b0>>20);
}
size_b0 = flash_get_size(CFG_FLASH0_BASE, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN || size_b0 == 0) {
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
size_b0, size_b0>>20);
}
/*
* protect monitor and environment sectors
*/
/*
* protect monitor and environment sectors
*/
#if CFG_MONITOR_BASE >= CFG_FLASH0_BASE
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+monitor_flash_len-1,
&flash_info[0]);
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+monitor_flash_len-1,
&flash_info[0]);
#endif
#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
# ifndef CFG_ENV_SIZE
# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
# endif
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[0]);
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[0]);
#endif
return (size_b0);
return (size_b0);
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
int i;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch ((info->flash_id >> 16) & 0xff) {
case FLASH_MAN_AMD: printf ("AMD "); break;
default: printf ("Unknown Vendor "); break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AMDL323B: printf ("29DL323B (32 M, bottom sector)\n");
break;
case FLASH_AMLV640U: printf ("29LV640U (64 M, uniform sector)\n");
break;
default: printf ("Unknown Chip Type\n");
break;
}
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
return;
}
switch ((info->flash_id >> 16) & 0xff) {
case FLASH_MAN_AMD: printf ("AMD "); break;
default: printf ("Unknown Vendor "); break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AMDL323B: printf ("29DL323B (32 M, bottom sector)\n");
break;
default: printf ("Unknown Chip Type\n");
break;
}
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
return;
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
int flag, prot, sect, l_sect;
ulong start, now, last;
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");
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;
}
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 ("- no sectors to erase\n");
printf ("\n");
}
return 1;
}
prot = 0;
for (sect = s_first; sect <= s_last; sect++) {
if (info->protect[sect])
prot++;
}
l_sect = -1;
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
l_sect = -1;
V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00AA00AA;
V_ULONG( info->start[0] + (0x02AA << 3) ) = 0x00550055;
V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00800080;
V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00AA00AA;
V_ULONG( info->start[0] + (0x02AA << 3) ) = 0x00550055;
V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00AA00AA;
V_ULONG( info->start[0] + 4 + (0x02AA << 3) ) = 0x00550055;
V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00800080;
V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00AA00AA;
V_ULONG( info->start[0] + 4 + (0x02AA << 3) ) = 0x00550055;
udelay (1000);
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00AA00AA;
V_ULONG( info->start[0] + (0x02AA << 3) ) = 0x00550055;
V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00800080;
V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00AA00AA;
V_ULONG( info->start[0] + (0x02AA << 3) ) = 0x00550055;
V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00AA00AA;
V_ULONG( info->start[0] + 4 + (0x02AA << 3) ) = 0x00550055;
V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00800080;
V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00AA00AA;
V_ULONG( info->start[0] + 4 + (0x02AA << 3) ) = 0x00550055;
udelay (1000);
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
V_ULONG( info->start[sect] ) = 0x00300030;
V_ULONG( info->start[sect] + 4 ) = 0x00300030;
l_sect = sect;
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
V_ULONG( info->start[sect] ) = 0x00300030;
V_ULONG( info->start[sect] + 4 ) = 0x00300030;
l_sect = sect;
}
}
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
/*
* We wait for the last triggered sector
*/
if (l_sect < 0)
goto DONE;
/*
* We wait for the last triggered sector
*/
if (l_sect < 0)
goto DONE;
start = get_timer (0);
last = start;
while ((V_ULONG( info->start[l_sect] ) & 0x00800080) != 0x00800080 ||
(V_ULONG( info->start[l_sect] + 4 ) & 0x00800080) != 0x00800080)
{
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
return 1;
start = get_timer (0);
last = start;
while ((V_ULONG( info->start[l_sect] ) & 0x00800080) != 0x00800080 ||
(V_ULONG( info->start[l_sect] + 4 ) & 0x00800080) != 0x00800080)
{
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;
}
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
serial_putc ('.');
last = now;
}
}
DONE:
/* reset to read mode */
flash_reset ();
DONE:
/* reset to read mode */
flash_reset ();
printf (" done\n");
return 0;
printf (" done\n");
return 0;
}
static int write_dword (flash_info_t *, ulong, unsigned char *);
@@ -299,49 +314,49 @@ static int write_dword (flash_info_t *, ulong, unsigned char *);
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong dp;
static unsigned char bb[8];
int i, l, rc, cc = cnt;
ulong dp;
static unsigned char bb[8];
int i, l, rc, cc = cnt;
dp = (addr & ~7); /* get lower dword aligned address */
dp = (addr & ~7); /* get lower dword aligned address */
/*
* handle unaligned start bytes
*/
if ((l = addr - dp) != 0) {
for (i = 0; i < 8; i++)
bb[i] = (i < l || (i-l) >= cc) ? V_BYTE(dp+i) : *src++;
if ((rc = write_dword(info, dp, bb)) != 0)
{
return (rc);
/*
* handle unaligned start bytes
*/
if ((l = addr - dp) != 0) {
for (i = 0; i < 8; i++)
bb[i] = (i < l || (i-l) >= cc) ? V_BYTE(dp+i) : *src++;
if ((rc = write_dword(info, dp, bb)) != 0)
{
return (rc);
}
dp += 8;
cc -= 8 - l;
}
dp += 8;
cc -= 8 - l;
}
/*
* handle word aligned part
*/
while (cc >= 8) {
if ((rc = write_dword(info, dp, src)) != 0) {
return (rc);
/*
* handle word aligned part
*/
while (cc >= 8) {
if ((rc = write_dword(info, dp, src)) != 0) {
return (rc);
}
dp += 8;
src += 8;
cc -= 8;
}
dp += 8;
src += 8;
cc -= 8;
}
if (cc <= 0) {
return (0);
}
if (cc <= 0) {
return (0);
}
/*
* handle unaligned tail bytes
*/
for (i = 0; i < 8; i++) {
bb[i] = (i < cc) ? *src++ : V_BYTE(dp+i);
}
return (write_dword(info, dp, bb));
/*
* handle unaligned tail bytes
*/
for (i = 0; i < 8; i++) {
bb[i] = (i < cc) ? *src++ : V_BYTE(dp+i);
}
return (write_dword(info, dp, bb));
}
/*-----------------------------------------------------------------------
@@ -352,45 +367,45 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
*/
static int write_dword (flash_info_t *info, ulong dest, unsigned char * pdata)
{
ulong start;
ulong cl = 0, ch =0;
int flag, i;
ulong start;
ulong cl = 0, ch =0;
int flag, i;
for (ch=0, i=0; i < 4; i++)
ch = (ch << 8) + *pdata++; /* high word */
for (cl=0, i=0; i < 4; i++)
cl = (cl << 8) + *pdata++; /* low word */
for (ch=0, i=0; i < 4; i++)
ch = (ch << 8) + *pdata++; /* high word */
for (cl=0, i=0; i < 4; i++)
cl = (cl << 8) + *pdata++; /* low word */
/* Check if Flash is (sufficiently) erased */
if ((*((vu_long *)dest) & ch) != ch
||(*((vu_long *)(dest + 4)) & cl) != cl)
{
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00AA00AA;
V_ULONG( info->start[0] + (0x02AA << 3) ) = 0x00550055;
V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00A000A0;
V_ULONG( dest ) = ch;
V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00AA00AA;
V_ULONG( info->start[0] + 4 + (0x02AA << 3) ) = 0x00550055;
V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00A000A0;
V_ULONG( dest + 4 ) = cl;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
while (((V_ULONG( dest ) & 0x00800080) != (ch & 0x00800080)) ||
((V_ULONG( dest + 4 ) & 0x00800080) != (cl & 0x00800080))) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
return (1);
/* Check if Flash is (sufficiently) erased */
if ((*((vu_long *)dest) & ch) != ch
||(*((vu_long *)(dest + 4)) & cl) != cl)
{
return (2);
}
}
return (0);
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00AA00AA;
V_ULONG( info->start[0] + (0x02AA << 3) ) = 0x00550055;
V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00A000A0;
V_ULONG( dest ) = ch;
V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00AA00AA;
V_ULONG( info->start[0] + 4 + (0x02AA << 3) ) = 0x00550055;
V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00A000A0;
V_ULONG( dest + 4 ) = cl;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
while (((V_ULONG( dest ) & 0x00800080) != (ch & 0x00800080)) ||
((V_ULONG( dest + 4 ) & 0x00800080) != (cl & 0x00800080))) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
return (1);
}
}
return (0);
}

View File

@@ -494,18 +494,18 @@ static void move64 (unsigned long long *src, unsigned long long *dest)
#if defined (CFG_DRAM_TEST_DATA)
unsigned long long pattern[] = {
0xaaaaaaaaaaaaaaaa,
0xcccccccccccccccc,
0xf0f0f0f0f0f0f0f0,
0xff00ff00ff00ff00,
0xffff0000ffff0000,
0xffffffff00000000,
0x00000000ffffffff,
0x0000ffff0000ffff,
0x00ff00ff00ff00ff,
0x0f0f0f0f0f0f0f0f,
0x3333333333333333,
0x5555555555555555
0xaaaaaaaaaaaaaaaaLL,
0xccccccccccccccccLL,
0xf0f0f0f0f0f0f0f0LL,
0xff00ff00ff00ff00LL,
0xffff0000ffff0000LL,
0xffffffff00000000LL,
0x00000000ffffffffLL,
0x0000ffff0000ffffLL,
0x00ff00ff00ff00ffLL,
0x0f0f0f0f0f0f0f0fLL,
0x3333333333333333LL,
0x5555555555555555LL,
};
/*********************************************************************/

View File

@@ -76,7 +76,9 @@
#define CONFIG_ETHADDR 64:36:00:00:00:01
/* next two ethernet hwaddrs */
#define CONFIG_HAS_ETH1
#define CONFIG_ETH1ADDR 86:06:2d:7e:c6:54
#define CONFIG_HAS_ETH2
#define CONFIG_ETH2ADDR 86:06:2d:7e:c6:55
#define CONFIG_ENV_OVERWRITE

View File

@@ -306,7 +306,7 @@ int misc_init_r (void)
/* mtspr(ccr0, (mfspr(ccr0) & 0xff8fffff) | 0x00100000); */
mtspr(ccr0, (mfspr(ccr0) & 0xff8fffff) | 0x00000000);
#endif
/* printf("CCR0=%08x\n", mfspr(ccr0));*/ /* test-only */
/* printf("CCR0=%08x\n", mfspr(ccr0)); */ /* test-only */
#endif
free(dst);

View File

@@ -53,7 +53,9 @@
#define CONFIG_ETHADDR 00:11:22:33:44:55
/* next two ethernet hwaddrs */
#define CONFIG_HAS_ETH1
#define CONFIG_ETH1ADDR 00:11:22:33:44:66
#define CONFIG_HAS_ETH2
#define CONFIG_ETH2ADDR 00:11:22:33:44:77
#define CONFIG_ENV_OVERWRITE

View File

@@ -162,7 +162,7 @@ long int initdram (int board_type)
int checkboard (void)
{
puts ("Board: INKA 4X0 (Indatec GmbH & Co. KG)\n");
puts ("Board: INKA 4X0\n");
return 0;
}
@@ -176,3 +176,16 @@ void flash_preinit(void)
*/
*(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
}
#ifdef CONFIG_PCI
static struct pci_controller hose;
extern void pci_mpc5xxx_init(struct pci_controller *);
void pci_init_board(void)
{
pci_mpc5xxx_init(&hose);
}
#endif

View File

@@ -1,4 +1,7 @@
/*
* (C) Copyright 2004
* Xiaogeng (Shawn) Jin, Agilent Technologies, xiaogeng_jin@agilent.com
*
* (C) Copyright 2001
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
*
@@ -31,20 +34,22 @@
#include <common.h>
#include <linux/byteorder/swab.h>
#define PHYS_FLASH_SECT_SIZE 0x00020000 /* 256 KB sectors (x2) */
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
#define DEBUG
#define PHYS_FLASH_SECT_SIZE 0x00040000 /* 256 KB sectors (x2) */
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/* Board support for 1 or 2 flash devices */
#undef FLASH_PORT_WIDTH32
#define FLASH_PORT_WIDTH16
#define FLASH_PORT_WIDTH32
#undef FLASH_PORT_WIDTH16
#ifdef FLASH_PORT_WIDTH16
#define FLASH_PORT_WIDTH ushort
#define FLASH_PORT_WIDTHV vu_short
#define FLASH_PORT_WIDTH ushort
#define FLASH_PORT_WIDTHV vu_short
#define SWAP(x) __swab16(x)
#else
#define FLASH_PORT_WIDTH ulong
#define FLASH_PORT_WIDTHV vu_long
#define FLASH_PORT_WIDTH ulong
#define FLASH_PORT_WIDTHV vu_long
#define SWAP(x) __swab32(x)
#endif
@@ -67,6 +72,12 @@ OrgDef OrgIntel_28F256L18T[] = {
{255, 128 * 1024}, /* 255 * 128kBytes sectors */
};
/* CP control register base address */
#define CPCR_BASE 0xCB000000
#define CPCR_EXTRABANK 0x8
#define CPCR_FLASHSIZE 0x4
#define CPCR_FLWREN 0x2
#define CPCR_FLVPPEN 0x1
/*-----------------------------------------------------------------------
* Functions
@@ -83,29 +94,50 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt);
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
int i;
int i, nbanks;
ulong size = 0;
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;
default:
panic ("configured too many flash banks!\n");
break;
}
vu_long *cpcr = (vu_long *)CPCR_BASE;
/* Check if there is an extra bank of flash */
if (cpcr[1] & CPCR_EXTRABANK)
nbanks = 2;
else
nbanks = 1;
if (nbanks > CFG_MAX_FLASH_BANKS)
nbanks = CFG_MAX_FLASH_BANKS;
/* Enable flash write */
cpcr[1] |= 3;
for (i = 0; i < nbanks; i++) {
flash_get_size ((FPW *)(CFG_FLASH_BASE + size), &flash_info[i]);
flash_get_offsets (CFG_FLASH_BASE + size, &flash_info[i]);
size += flash_info[i].size;
}
/* Protect monitor and environment sectors
*/
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
/* monitor protection */
flash_protect (FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_FLASH_BASE + monitor_flash_len - 1, &flash_info[0]);
CFG_MONITOR_BASE,
CFG_MONITOR_BASE + monitor_flash_len - 1, &flash_info[0]);
#endif
#ifdef CFG_ENV_IS_IN_FLASH
/* ENV protection ON */
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
&flash_info[0]);
#endif
/* Protect SIB (0x24800000) and bootMonitor (0x24c00000) */
flash_protect (FLAG_PROTECT_SET,
flash_info[0].start[62],
flash_info[0].start[63] + PHYS_FLASH_SECT_SIZE - 1,
&flash_info[0]);
return size;
}
@@ -115,23 +147,15 @@ unsigned long flash_init (void)
static void flash_get_offsets (ulong base, flash_info_t * info)
{
int i;
OrgDef *pOrgDef;
pOrgDef = OrgIntel_28F256L18T;
if (info->flash_id == FLASH_UNKNOWN) {
return;
}
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
for (i = 0; i < info->sector_count; i++) {
if (i > 255) {
info->start[i] = base + (i * 0x8000);
info->protect[i] = 0;
} else {
info->start[i] = base +
(i * PHYS_FLASH_SECT_SIZE);
info->protect[i] = 0;
}
info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
info->protect[i] = 0;
}
}
}
@@ -156,10 +180,20 @@ void flash_print_info (flash_info_t * info)
break;
}
/* Integrator CP board uses 28F640J3C or 28F128J3C parts,
* which have the same device id numbers as 28F640J3A or
* 28F128J3A
*/
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F256L18T:
printf ("FLASH 28F256L18T\n");
break;
case FLASH_28F640J3A:
printf ("FLASH 28F640J3C\n");
break;
case FLASH_28F128J3A:
printf ("FLASH 28F128J3C\n");
break;
default:
printf ("Unknown Chip Type\n");
break;
@@ -185,6 +219,17 @@ void flash_print_info (flash_info_t * info)
static ulong flash_get_size (FPW * addr, flash_info_t * info)
{
volatile FPW value;
vu_long *cpcr = (vu_long *)CPCR_BASE;
int nsects;
/* Check the flash size */
if (cpcr[1] & CPCR_FLASHSIZE)
nsects = 128;
else
nsects = 64;
if (nsects > CFG_MAX_FLASH_SECT)
nsects = CFG_MAX_FLASH_SECT;
/* Write auto select command: read Manufacturer ID */
addr[0x5555] = (FPW) 0x00AA00AA;
@@ -204,19 +249,31 @@ static ulong flash_get_size (FPW * addr, flash_info_t * info)
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
return (0); /* no or unknown flash */
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
return (0); /* no or unknown flash */
}
mb ();
value = addr[1]; /* device ID */
value = addr[1]; /* device ID */
switch (value) {
case (FPW) (INTEL_ID_28F256L18T):
info->flash_id += FLASH_28F256L18T;
info->sector_count = 259;
info->size = 0x02000000;
break; /* => 32 MB */
break; /* => 32 MB */
case (FPW) (INTEL_ID_28F640J3A):
info->flash_id += FLASH_28F640J3A;
info->sector_count = nsects;
info->size = nsects * PHYS_FLASH_SECT_SIZE;
break;
case (FPW) (INTEL_ID_28F128J3A):
info->flash_id += FLASH_28F128J3A;
info->sector_count = nsects;
info->size = nsects * PHYS_FLASH_SECT_SIZE;
break;
default:
info->flash_id = FLASH_UNKNOWN;
@@ -241,23 +298,32 @@ static ulong flash_get_size (FPW * addr, flash_info_t * info)
*/
void flash_unprotect_sectors (FPWV * addr)
{
#define PD_FINTEL_WSMS_READY_MASK 0x0080
FPW status;
*addr = (FPW) 0x00500050; /* clear status register */
/* this sends the clear lock bit command */
*addr = (FPW) 0x00600060;
*addr = (FPW) 0x00D000D0;
reset_timer_masked();
while (((status = *addr) & (FPW)0x00800080) != 0x00800080) {
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
printf("Timeout");
break;
}
}
*addr = (FPW) 0x00FF00FF;
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
int flag, prot, sect;
ulong type, start, last;
ulong type;
int rcode = 0;
if ((s_first < 0) || (s_first > s_last)) {
@@ -290,13 +356,6 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
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; sect++) {
if (info->protect[sect] == 0) { /* not protected */
@@ -305,36 +364,53 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
printf ("Erasing sector %2d ... ", sect);
flash_unprotect_sectors (addr);
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts ();
/* flash_unprotect_sectors (addr); */
/* 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 */
*addr = (FPW) 0x00500050; /* clear status register */
*addr = (FPW) 0x00200020; /* erase setup */
*addr = (FPW) 0x00D000D0; /* erase confirm */
mb();
while (((status =
*addr) & (FPW) 0x00800080) !=
(FPW) 0x00800080) {
if (get_timer_masked () >
CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
/* suspend erase */
*addr = (FPW) 0x00B000B0;
/* reset to read mode */
*addr = (FPW) 0x00FF00FF;
rcode = 1;
break;
udelay(1000); /* Let's wait 1 ms */
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
*addr = (FPW)0x00700070;
status = *addr;
if ((status & (FPW) 0x00400040) == (FPW) 0x00400040) {
/* erase suspended? Resume it */
reset_timer_masked();
*addr = (FPW) 0x00D000D0;
} else {
#ifdef DEBUG
printf ("Timeout,0x%08x\n", status);
#else
printf("Timeout\n");
#endif
*addr = (FPW) 0x00500050;
*addr = (FPW) 0x00FF00FF; /* reset to read mode */
rcode = 1;
break;
}
}
}
/* clear status register cmd. */
*addr = (FPW) 0x00500050;
*addr = (FPW) 0x00FF00FF;/* resest to read mode */
*addr = (FPW) 0x00FF00FF; /* resest to read mode */
printf (" done\n");
}
}
return rcode;
}
@@ -345,7 +421,6 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
* 2 - Flash not erased
* 4 - Flash not identified
*/
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
ulong cp, wp;
@@ -443,23 +518,39 @@ static int write_data (flash_info_t * info, ulong dest, FPW data)
printf ("not erased at %08lx (%x)\n", (ulong) addr, *addr);
return (2);
}
flash_unprotect_sectors (addr);
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts ();
/* flash_unprotect_sectors (addr); */
*addr = (FPW) 0x00400040; /* write setup */
*addr = data;
mb();
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* 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 */
#ifdef DEBUG
*addr = (FPW) 0x00700070;
status = *addr;
printf("## status=0x%08x, addr=0x%08x\n", status, addr);
#endif
*addr = (FPW) 0x00500050; /* clear status register cmd */
*addr = (FPW) 0x00FF00FF; /* restore read mode */
return (1);
}
}
*addr = (FPW) 0x00FF00FF; /* restore read mode */
*addr = (FPW) 0x00FF00FF; /* restore read mode */
return (0);
}

View File

@@ -38,18 +38,16 @@
* Miscelaneous platform dependent initialisations
*/
int
/**********************************************************/
board_late_init (void)
/**********************************************************/
int board_post_init (void)
{
return (0);
}
int
/**********************************************************/
board_init (void)
/**********************************************************/
int board_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
@@ -62,10 +60,9 @@ board_init (void)
return 0;
}
int
/**********************************************************/
dram_init (void)
/**********************************************************/
int dram_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
@@ -74,3 +71,14 @@ dram_init (void)
return (0);
}
/**********************************************************/
extern struct pci_controller hose;
void pci_init_board(void)
{
extern void pci_ixp_init (struct pci_controller *hose);
pci_ixp_init(&hose);
}

View File

@@ -39,8 +39,6 @@ void host_bridge_init (void)
/* The bridge chip is at a fixed location. */
pci_dev_t dev = PCI_BDF (0, 10, 0);
int rc;
/* Set PCI Class code --
The primary side sees this class code at 0x08 in the
primary config space. This must be something other then a

47
board/omap2420h4/Makefile Normal file
View File

@@ -0,0 +1,47 @@
#
# (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 := omap2420h4.o flash.o mem.o sys_info.o
SOBJS := platform.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,22 @@
#
# (C) Copyright 2004
# Texas Instruments, <www.ti.com>
#
# TI H4 board with OMAP2420 (ARM1136) cpu
# see http://www.ti.com/ for more information on Texas Instruments
#
# H4 has 1 bank of 32MB or 64MB mDDR-SDRAM on CS0
# H4 has 1 bank of 32MB or 00MB mDDR-SDRAM on CS1
# Physical Address:
# 8000'0000 (bank0)
# A000/0000 (bank1) ES2 will be configurable
# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000
# (mem base + reserved)
# For use with external or internal boots.
TEXT_BASE = 0x80e80000
# Used with full SRAM boot.
# This is either with a GP system or a signed boot image.
# easiest, and safest way to go if you can.
#TEXT_BASE = 0x40280000

537
board/omap2420h4/flash.c Normal file
View File

@@ -0,0 +1,537 @@
/*
* (C) Copyright 2001
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
*
* (C) Copyright 2001-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2003
* Texas Instruments, <www.ti.com>
* Kshitij Gupta <Kshitij@ti.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 <asm/arch/sizes.h>
#include <linux/byteorder/swab.h>
#define PHYS_FLASH_SECT_SIZE SZ_128K
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/* 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")
/* Flash Organization Structure */
typedef struct OrgDef {
unsigned int sector_number;
unsigned int sector_size;
} OrgDef;
/* Flash Organizations */
OrgDef OrgIntel_28F256L18T[] = {
{4, SZ_32K}, /* 4 * 32kBytes sectors */
{255, SZ_128K}, /* 255 * 128kBytes sectors */
};
/*-----------------------------------------------------------------------
* Functions
*/
unsigned long flash_init (void);
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);
void flash_print_info (flash_info_t * info);
void flash_unprotect_sectors (FPWV * addr);
int flash_erase (flash_info_t * info, int s_first, int s_last);
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt);
void flash_unlock(flash_info_t * info, int bank);
int flash_probe(void);
/*-----------------------------------------------------------------------
*/
/* see if flash is ok */
int flash_probe(void)
{
return(flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[0]));
}
unsigned long flash_init (void)
{
int i;
ulong size = 0;
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]);
/* to reset the lock bit */
flash_unlock(&flash_info[i],i);
break;
case 1:
flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]);
flash_get_offsets (PHYS_FLASH_2, &flash_info[i]);
/* to reset the lock bit */
flash_unlock(&flash_info[i],i);
break;
default:
panic ("configured too many flash banks!\n");
break;
}
size += flash_info[i].size;
}
#ifdef CFG_ENV_IS_IN_FLASH
/* Protect monitor and environment sectors
*/
flash_protect (FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_FLASH_BASE + monitor_flash_len - 1, &flash_info[0]);
flash_protect (FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
#endif
return size;
}
/*-----------------------------------------------------------------------
*/
void flash_unlock(flash_info_t * info, int bank)
{
int j;
if (!bank)
j=2; /* leave 0,1 locked for boot bank */
else
j=0; /* get the whole bank for #2 */
for (;j<CFG_MAX_FLASH_SECT;j++) {
FPWV *addr = (FPWV *) (info->start[j]);
if (addr == NULL) {
printf("Warning Flash probe failed\n");
break;
}
flash_unprotect_sectors (addr);
*addr = (FPW) 0x00500050;/* clear status register */
*addr = (FPW) 0x00FF00FF;/* resest to read mode */
}
}
/*-----------------------------------------------------------------------
*/
static void flash_get_offsets (ulong base, flash_info_t * info)
{
int i;
volatile int r; /* gcc 3.4.0-1 strangeness, need to follow up.*/
if (info->flash_id == FLASH_UNKNOWN) {
return;
}
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
for (i = 0; i < info->sector_count; i++) {
if (i > 254) { /* 255,256,257,258 */
r=i;
info->start[i] = base + (((r-(int)255) * SZ_32K) + (255*PHYS_FLASH_SECT_SIZE));
info->protect[i] = 0;
} else {
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_28F256L18T:
printf ("FLASH 28F256L18T\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;
/* mb(); this one makes ARM11 err go away, but I want it :) as a guide to problems */
/* Write auto select command: read Manufacturer ID */
addr[0x5555] = (FPW) 0x00AA00AA;
addr[0x2AAA] = (FPW) 0x00550055;
addr[0x5555] = (FPW) 0x00900090;
mb ();
value = addr[0] & 0xFF; /* just looking for 89 (8989 is hw pat)*/
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_28F256L18T): /* 880D */
info->flash_id += FLASH_28F256L18T;
info->sector_count = 259; /*0-258*/
info->size = SZ_32M;
break; /* => 32 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);
}
/* unprotects a sector for write and erase
* on some intel parts, this unprotects the entire chip, but it
* wont hurt to call this additional times per sector...
*/
void flash_unprotect_sectors (FPWV * addr)
{
#define PD_FINTEL_WSMS_READY_MASK 0x0080
*addr = (FPW) 0x00500050; /* clear status register */
/* this sends the clear lock bit command */
*addr = (FPW) 0x00600060;
*addr = (FPW) 0x00D000D0;
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
int prot, sect;
ulong type, start, last;
int rcode = 0;
#ifdef CONFIG_USE_IRQ
int iflag;
#endif
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;
}
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;
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;
#ifdef CONFIG_USE_IRQ
/* Disable interrupts which might cause a timeout here */
iflag = disable_interrupts ();
#endif
/* 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);
flash_unprotect_sectors (addr);
/* 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");
/* suspend erase */
*addr = (FPW) 0x00B000B0;
/* reset to read mode */
*addr = (FPW) 0x00FF00FF;
rcode = 1;
break;
}
}
/* clear status register cmd. */
*addr = (FPW) 0x00500050;
*addr = (FPW) 0x00FF00FF;/* resest to read mode */
printf (" done\n");
}
}
#ifdef CONFIG_USE_IRQ
if (iflag)
enable_interrupts();
#endif
return rcode;
}
/*-----------------------------------------------------------------------
* 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;
FPW data;
int count, i, l, rc, port_width;
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) {
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 < port_width && cnt > 0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
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;
#ifdef CONFIG_USE_IRQ
int iflag;
#endif
/* 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 */
#ifdef CONFIG_USE_IRQ
iflag = disable_interrupts ();
#endif
*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 */
#ifdef CONFIG_USE_IRQ
if (iflag)
enable_interrupts();
#endif
return(0);
}
void inline spin_wheel (void)
{
static int p = 0;
static char w[] = "\\/-";
printf ("\010%c", w[p]);
(++p == 3) ? (p = 0) : 0;
}

345
board/omap2420h4/mem.c Normal file
View File

@@ -0,0 +1,345 @@
/*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* 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/omap2420.h>
#include <asm/io.h>
#include <asm/arch/bits.h>
#include <asm/arch/mux.h>
#include <asm/arch/mem.h>
#include <asm/arch/clocks.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/sys_info.h>
/************************************************************
* sdelay() - simple spin loop. Will be constant time as
* its generally used in 12MHz bypass conditions only. This
* is necessary until timers are accessible.
*
* not inline to increase chances its in cache when called
*************************************************************/
void sdelay (unsigned long loops)
{
__asm__ volatile ("1:\n" "subs %0, %1, #1\n"
"bne 1b":"=r" (loops):"0" (loops));
}
/*********************************************************************************
* prcm_init() - inits clocks for PRCM as defined in clocks.h (config II default).
* -- called from SRAM, or Flash (using temp SRAM stack).
*********************************************************************************/
void prcm_init(void)
{
u32 rev,div;
void (*f_lock_pll) (u32, u32, u32, u32);
extern void *_end_vect, *_start;
f_lock_pll = (void *)((u32)&_end_vect - (u32)&_start + SRAM_VECT_CODE);
__raw_writel(0, CM_FCLKEN1_CORE); /* stop all clocks to reduce ringing */
__raw_writel(0, CM_FCLKEN2_CORE); /* may not be necessary */
__raw_writel(0, CM_ICLKEN1_CORE);
__raw_writel(0, CM_ICLKEN2_CORE);
__raw_writel(DPLL_OUT, CM_CLKSEL2_PLL); /* set DPLL out */
__raw_writel(MPU_DIV, CM_CLKSEL_MPU); /* set MPU divider */
__raw_writel(DSP_DIV, CM_CLKSEL_DSP); /* set dsp and iva dividers */
__raw_writel(GFX_DIV, CM_CLKSEL_GFX); /* set gfx dividers */
rev = get_cpu_rev();
if (rev == CPU_2420_ES1 || rev == CPU_2422_ES1)
div = BUS_DIV_ES1;
else
div = BUS_DIV;
__raw_writel(div, CM_CLKSEL1_CORE);/* set L3/L4/USB/Display/Vlnc/SSi dividers */
sdelay(1000);
if(running_in_sram()){
/* If running fully from SRAM this is OK. The Flash bus drops out for just a little.
* but then comes back. If running from Flash this sequence kills you, thus you need
* to run it using CONFIG_PARTIAL_SRAM.
*/
__raw_writel(MODE_BYPASS_FAST, CM_CLKEN_PLL); /* go to bypass, fast relock */
wait_on_value(BIT0|BIT1, BIT0, CM_IDLEST_CKGEN, LDELAY); /* wait till in bypass */
sdelay(1000);
/* set clock selection and dpll dividers. */
__raw_writel(DPLL_VAL, CM_CLKSEL1_PLL); /* set pll for target rate */
__raw_writel(COMMIT_DIVIDERS, PRCM_CLKCFG_CTRL); /* commit dividers */
sdelay(10000);
__raw_writel(DPLL_LOCK, CM_CLKEN_PLL); /* enable dpll */
sdelay(10000);
wait_on_value(BIT0|BIT1, BIT1, CM_IDLEST_CKGEN, LDELAY); /*wait for dpll lock */
}else if(running_in_flash()){
/* if running from flash, need to jump to small relocated code area in SRAM.
* This is the only safe spot to do configurations from.
*/
(*f_lock_pll)(PRCM_CLKCFG_CTRL, CM_CLKEN_PLL, DPLL_LOCK, CM_IDLEST_CKGEN);
}
__raw_writel(DPLL_LOCK|APLL_LOCK, CM_CLKEN_PLL); /* enable apll */
wait_on_value(BIT8, BIT8, CM_IDLEST_CKGEN, LDELAY); /* wait for apll lock */
sdelay(1000);
}
/********************************************************
* mem_ok() - test used to see if timings are correct
* for a part. Helps in gussing which part
* we are currently using.
*******************************************************/
u32 mem_ok(void)
{
u32 val1, val2;
u32 pattern = 0x12345678;
__raw_writel(0x0,OMAP2420_SDRC_CS0+0x400); /* clear pos A */
__raw_writel(pattern, OMAP2420_SDRC_CS0); /* pattern to pos B */
__raw_writel(0x0,OMAP2420_SDRC_CS0+4); /* remove pattern off the bus */
val1 = __raw_readl(OMAP2420_SDRC_CS0+0x400); /* get pos A value */
val2 = __raw_readl(OMAP2420_SDRC_CS0); /* get val2 */
if ((val1 != 0) || (val2 != pattern)) /* see if pos A value changed*/
return(0);
else
return(1);
}
/********************************************************
* sdrc_init() - init the sdrc chip selects CS0 and CS1
* - early init routines, called from flash or
* SRAM.
*******************************************************/
void sdrc_init(void)
{
#define EARLY_INIT 1
do_sdrc_init(SDRC_CS0_OSET, EARLY_INIT); /* only init up first bank here */
}
/*************************************************************************
* do_sdrc_init(): initialize the SDRAM for use.
* -called from low level code with stack only.
* -code sets up SDRAM timing and muxing for 2422 or 2420.
* -optimal settings can be placed here, or redone after i2c
* inspection of board info
*
* This is a bit ugly, but should handle all memory moduels
* used with the H4. The first time though this code from s_init()
* we configure the first chip select. Later on we come back and
* will configure the 2nd chip select if it exists.
*
**************************************************************************/
void do_sdrc_init(u32 offset, u32 early)
{
u32 cpu, bug=0, rev, common=0, cs0=0, pmask=0, pass_type;
sdrc_data_t *sdata; /* do not change type */
u32 a, b, r;
static const sdrc_data_t sdrc_2422 =
{
H4_2422_SDRC_SHARING, H4_2422_SDRC_MDCFG_0_DDR, 0 , H4_2422_SDRC_ACTIM_CTRLA_0,
H4_2422_SDRC_ACTIM_CTRLB_0, H4_2422_SDRC_RFR_CTRL_ES1, H4_2422_SDRC_MR_0_DDR,
0, H4_2422_SDRC_DLLA_CTRL, H4_2422_SDRC_DLLB_CTRL
};
static const sdrc_data_t sdrc_2420 =
{
H4_2420_SDRC_SHARING, H4_2420_SDRC_MDCFG_0_DDR, H4_2420_SDRC_MDCFG_0_SDR,
H4_2420_SDRC_ACTIM_CTRLA_0, H4_2420_SDRC_ACTIM_CTRLB_0,
H4_2420_SDRC_RFR_CTRL_ES1, H4_2420_SDRC_MR_0_DDR, H4_2420_SDRC_MR_0_SDR,
H4_2420_SDRC_DLLA_CTRL, H4_2420_SDRC_DLLB_CTRL
};
if (offset == SDRC_CS0_OSET)
cs0 = common = 1; /* int regs shared between both chip select */
cpu = get_cpu_type();
/* warning generated, though code generation is correct. this may bite later,
* but is ok for now. there is only so much C code you can do on stack only
* operation.
*/
if (cpu == CPU_2422){
sdata = (sdrc_data_t *)&sdrc_2422;
pass_type = STACKED;
} else{
sdata = (sdrc_data_t *)&sdrc_2420;
pass_type = IP_DDR;
}
__asm__ __volatile__("": : :"memory"); /* limit compiler scope */
/* u-boot is compiled to run in DDR or SRAM at 8xxxxxxx or 4xxxxxxx.
* If we are running in flash prior to relocation and we use data
* here which is not pc relative we need to get the address correct.
* We need to find the current flash mapping to dress up the initial
* pointer load. As long as this is const data we should be ok.
*/
if((early) && running_in_flash()){
sdata = (sdrc_data_t *)(((u32)sdata & 0x0003FFFF) | get_gpmc0_base());
/* NOR internal boot offset is 0x4000 from xloader signature */
if(running_from_internal_boot())
sdata = (sdrc_data_t *)((u32)sdata + 0x4000);
}
if (!early && (get_mem_type() == DDR_COMBO)) {/* combo part has a shared CKE signal, can't use feature */
pmask = BIT2;
pass_type = COMBO_DDR; /* CS1 config */
}
next_mem_type:
if (common) { /* do a SDRC reset between types to clear regs*/
__raw_writel(SOFTRESET, SDRC_SYSCONFIG); /* reset sdrc */
wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000);/* wait till reset done set */
__raw_writel(0, SDRC_SYSCONFIG); /* clear soft reset */
__raw_writel(sdata->sdrc_sharing, SDRC_SHARING);
__raw_writel((__raw_readl(SDRC_POWER)) & ~pmask, SDRC_POWER);
#ifdef POWER_SAVE
__raw_writel(__raw_readl(SMS_SYSCONFIG)|SMART_IDLE, SMS_SYSCONFIG);
__raw_writel(sdata->sdrc_sharing|SMART_IDLE, SDRC_SHARING);
__raw_writel((__raw_readl(SDRC_POWER)|BIT6) & ~pmask, SDRC_POWER);
#endif
}
if ((pass_type == IP_DDR) || (pass_type == STACKED)) /* (IP ddr-CS0),(2422-CS0/CS1) */
__raw_writel(sdata->sdrc_mdcfg_0_ddr, SDRC_MCFG_0+offset);
else if (pass_type == COMBO_DDR){ /* (combo-CS0/CS1) */
__raw_writel(H4_2420_COMBO_MDCFG_0_DDR,SDRC_MCFG_0+offset);
} else if (pass_type == IP_SDR){ /* ip sdr-CS0 */
__raw_writel(sdata->sdrc_mdcfg_0_sdr, SDRC_MCFG_0+offset);
}
if(pass_type == IP_SDR){ /* SDRAM can run full speed only rated for 105MHz*/
a = H4_242X_SDRC_ACTIM_CTRLA_0_100MHz;
b = H4_242X_SDRC_ACTIM_CTRLB_0_100MHz;
r = H4_2420_SDRC_RFR_CTRL;
} else {
a = sdata->sdrc_actim_ctrla_0;
b = sdata->sdrc_actim_ctrlb_0;
r = sdata->sdrc_rfr_ctrl;
}
if (cs0) {
__raw_writel(a, SDRC_ACTIM_CTRLA_0);
__raw_writel(b, SDRC_ACTIM_CTRLB_0);
} else {
__raw_writel(a, SDRC_ACTIM_CTRLA_1);
__raw_writel(b, SDRC_ACTIM_CTRLB_1);
}
__raw_writel(r, SDRC_RFR_CTRL+offset);
/* init sequence for mDDR/mSDR using manual commands (DDR is a bit different) */
__raw_writel(CMD_NOP, SDRC_MANUAL_0+offset);
sdelay(5000); /* susposed to be 100us per design spec for mddr/msdr */
__raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0+offset);
__raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0+offset);
__raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0+offset);
/*
* CSx SDRC Mode Register
* Burst length = (4 - DDR) (2-SDR)
* Serial mode
* CAS latency = x
*/
if(pass_type == IP_SDR)
__raw_writel(sdata->sdrc_mr_0_sdr, SDRC_MR_0+offset);
else
__raw_writel(sdata->sdrc_mr_0_ddr, SDRC_MR_0+offset);
/* NOTE: ES1 242x _BUG_ DLL + External Bandwidth fix*/
rev = get_cpu_rev();
if (rev == CPU_2420_ES1 || rev == CPU_2422_ES1){
bug = BIT0;
__raw_writel((__raw_readl(SMS_CLASS_ARB0)|BURSTCOMPLETE_GROUP7)
,SMS_CLASS_ARB0);/* enable bust complete for lcd */
}
/* enable & load up DLL with good value for 75MHz, and set phase to 90% */
if (common && (pass_type != IP_SDR)) {
__raw_writel(sdata->sdrc_dlla_ctrl, SDRC_DLLA_CTRL);
__raw_writel(sdata->sdrc_dlla_ctrl & ~(BIT2|bug), SDRC_DLLA_CTRL);
__raw_writel(sdata->sdrc_dllb_ctrl, SDRC_DLLB_CTRL);
__raw_writel(sdata->sdrc_dllb_ctrl & ~(BIT2|bug) , SDRC_DLLB_CTRL);
}
sdelay(90000);
if(mem_ok())
return; /* STACKED, other configued type */
++pass_type; /* IPDDR->COMBODDR->IPSDR for CS0 */
goto next_mem_type;
}
/*****************************************************
* gpmc_init(): init gpmc bus
* Init GPMC for x16, MuxMode (SDRAM in x32).
* This code can only be executed from SRAM or SDRAM.
*****************************************************/
void gpmc_init(void)
{
u32 mux=0, mtype, mwidth;
/* global settings */
__raw_writel(0x10, GPMC_SYSCONFIG); /* smart idle */
__raw_writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */
__raw_writel(0x1, GPMC_TIMEOUT_CONTROL);/* timeout disable */
#ifdef CFG_NAND_BOOT
__raw_writel(0x001, GPMC_CONFIG); /* set nWP, disable limited addr */
#else
__raw_writel(0x111, GPMC_CONFIG); /* set nWP, disable limited addr */
#endif
/* discover bus connection from sysboot */
if (is_gpmc_muxed() == GPMC_MUXED)
mux = BIT9;
mtype = get_gpmc0_type();
mwidth = get_gpmc0_width();
/* setup cs0 */
__raw_writel(0x0, GPMC_CONFIG7_0); /* disable current map */
sdelay(1000);
#ifdef CFG_NAND_BOOT
__raw_writel(H4_24XX_GPMC_CONFIG1_0|mtype|mwidth, GPMC_CONFIG1_0);
#else
__raw_writel(H4_24XX_GPMC_CONFIG1_0|mux|mtype|mwidth, GPMC_CONFIG1_0);
#endif
#ifdef PRCM_CONFIG_III
__raw_writel(H4_24XX_GPMC_CONFIG2_0, GPMC_CONFIG2_0);
#endif
__raw_writel(H4_24XX_GPMC_CONFIG3_0, GPMC_CONFIG3_0);
__raw_writel(H4_24XX_GPMC_CONFIG4_0, GPMC_CONFIG4_0);
#ifdef PRCM_CONFIG_III
__raw_writel(H4_24XX_GPMC_CONFIG5_0, GPMC_CONFIG5_0);
__raw_writel(H4_24XX_GPMC_CONFIG6_0, GPMC_CONFIG6_0);
#endif
__raw_writel(H4_24XX_GPMC_CONFIG7_0, GPMC_CONFIG7_0);/* enable new mapping */
sdelay(2000);
/* setup cs1 */
__raw_writel(0, GPMC_CONFIG7_1); /* disable any mapping */
sdelay(1000);
__raw_writel(H4_24XX_GPMC_CONFIG1_1|mux, GPMC_CONFIG1_1);
__raw_writel(H4_24XX_GPMC_CONFIG2_1, GPMC_CONFIG2_1);
__raw_writel(H4_24XX_GPMC_CONFIG3_1, GPMC_CONFIG3_1);
__raw_writel(H4_24XX_GPMC_CONFIG4_1, GPMC_CONFIG4_1);
__raw_writel(H4_24XX_GPMC_CONFIG5_1, GPMC_CONFIG5_1);
__raw_writel(H4_24XX_GPMC_CONFIG6_1, GPMC_CONFIG6_1);
__raw_writel(H4_24XX_GPMC_CONFIG7_1, GPMC_CONFIG7_1); /* enable mapping */
sdelay(2000);
}

View File

@@ -0,0 +1,859 @@
/*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.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 <asm/arch/omap2420.h>
#include <asm/io.h>
#include <asm/arch/bits.h>
#include <asm/arch/mux.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/sys_info.h>
#include <asm/arch/mem.h>
#include <i2c.h>
#include <asm/mach-types.h>
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#include <linux/mtd/nand.h>
extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
#endif
static void wait_for_command_complete(unsigned int wd_base);
/*******************************************************
* Routine: delay
* Description: spinning delay to use before udelay works
******************************************************/
static inline void delay (unsigned long loops)
{
__asm__ volatile ("1:\n" "subs %0, %1, #1\n"
"bne 1b":"=r" (loops):"0" (loops));
}
/*****************************************
* Routine: board_init
* Description: Early hardware init.
*****************************************/
int board_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
gpmc_init(); /* in SRAM or SDRM, finish GPMC */
gd->bd->bi_arch_number = MACH_TYPE_OMAP_H4; /* board id for linux */
gd->bd->bi_boot_params = (OMAP2420_SDRC_CS0+0x100); /* adress of boot parameters */
return 0;
}
/**********************************************************
* Routine: s_init
* Description: Does early system init of muxing and clocks.
* - Called path is with sram stack.
**********************************************************/
void s_init(void)
{
int in_sdram = running_in_sdram();
watchdog_init();
set_muxconf_regs();
delay(100);
if(!in_sdram)
prcm_init();
peripheral_enable();
icache_enable();
if (!in_sdram)
sdrc_init();
}
/*******************************************************
* Routine: misc_init_r
* Description: Init ethernet (done here so udelay works)
********************************************************/
int misc_init_r (void)
{
ether_init(); /* better done here so timers are init'ed */
return(0);
}
/****************************************
* Routine: watchdog_init
* Description: Shut down watch dogs
*****************************************/
void watchdog_init(void)
{
int mode;
#define GP (BIT8|BIT9)
/* There are 4 watch dogs. 1 secure, and 3 general purpose.
* I would expect that the ROM takes care of the secure one,
* but we will try also. Of the 3 GP ones, 1 can reset us
* directly, the other 2 only generate MPU interrupts.
*/
mode = (__raw_readl(CONTROL_STATUS) & (BIT8|BIT9));
if (mode == GP) {
__raw_writel(WD_UNLOCK1 ,WD1_BASE+WSPR);
wait_for_command_complete(WD1_BASE);
__raw_writel(WD_UNLOCK2 ,WD1_BASE+WSPR);
}
__raw_writel(WD_UNLOCK1 ,WD2_BASE+WSPR);
wait_for_command_complete(WD2_BASE);
__raw_writel(WD_UNLOCK2 ,WD2_BASE+WSPR);
#if MPU_WD_CLOCKED /* value 0x10 stick on aptix, BIT4 polarity seems oppsite*/
__raw_writel(WD_UNLOCK1 ,WD3_BASE+WSPR);
wait_for_command_complete(WD3_BASE);
__raw_writel(WD_UNLOCK2 ,WD3_BASE+WSPR);
__raw_writel(WD_UNLOCK1 ,WD4_BASE+WSPR);
wait_for_command_complete(WD4_BASE);
__raw_writel(WD_UNLOCK2 ,WD4_BASE+WSPR);
#endif
}
/******************************************************
* Routine: wait_for_command_complete
* Description: Wait for posting to finish on watchdog
******************************************************/
static void wait_for_command_complete(unsigned int wd_base)
{
int pending = 1;
do {
pending = __raw_readl(wd_base+WWPS);
} while (pending);
}
/*******************************************************************
* Routine:ether_init
* Description: take the Ethernet controller out of reset and wait
* for the EEPROM load to complete.
******************************************************************/
void ether_init (void)
{
#ifdef CONFIG_DRIVER_LAN91C96
int cnt = 20;
__raw_writeb(0x3,OMAP2420_CTRL_BASE+0x10a); /*protect->gpio95 */
__raw_writew(0x0, LAN_RESET_REGISTER);
do {
__raw_writew(0x1, LAN_RESET_REGISTER);
udelay (100);
if (cnt == 0)
goto h4reset_err_out;
--cnt;
} while (__raw_readw(LAN_RESET_REGISTER) != 0x1);
cnt = 20;
do {
__raw_writew(0x0, LAN_RESET_REGISTER);
udelay (100);
if (cnt == 0)
goto h4reset_err_out;
--cnt;
} while (__raw_readw(LAN_RESET_REGISTER) != 0x0000);
udelay (1000);
*((volatile unsigned char *) ETH_CONTROL_REG) &= ~0x01;
udelay (1000);
h4reset_err_out:
return;
#endif
}
/**********************************************
* Routine: dram_init
* Description: sets uboots idea of sdram size
**********************************************/
int dram_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
unsigned int size0=0,size1=0;
u32 mtype, btype;
u8 chg_on = 0x5; /* enable charge of back up battery */
u8 vmode_on = 0x8C;
#define NOT_EARLY 0
i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); /* need this a bit early */
btype = get_board_type();
mtype = get_mem_type();
display_board_info(btype);
if (btype == BOARD_H4_MENELAUS){
update_mux(btype,mtype); /* combo part on menelaus */
i2c_write(I2C_MENELAUS, 0x20, 1, &chg_on, 1); /*fix POR reset bug */
i2c_write(I2C_MENELAUS, 0x2, 1, &vmode_on, 1); /* VCORE change on VMODE */
}
if ((mtype == DDR_COMBO) || (mtype == DDR_STACKED)) {
do_sdrc_init(SDRC_CS1_OSET, NOT_EARLY); /* init other chip select */
size0 = size1 = SZ_32M;
} else if (mtype == SDR_DISCRETE)
size0 = SZ_128M;
else
size0 = SZ_64M;
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = size0;
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
gd->bd->bi_dram[1].size = size1;
return 0;
}
/**********************************************************
* Routine: set_muxconf_regs
* Description: Setting up the configuration Mux registers
* specific to the hardware
*********************************************************/
void set_muxconf_regs (void)
{
muxSetupSDRC();
muxSetupGPMC();
muxSetupUsb0();
muxSetupUart3();
muxSetupI2C1();
muxSetupUART1();
muxSetupLCD();
muxSetupCamera();
muxSetupMMCSD();
muxSetupTouchScreen();
muxSetupHDQ();
}
/*****************************************************************
* Routine: peripheral_enable
* Description: Enable the clks & power for perifs (GPT2, UART1,...)
******************************************************************/
void peripheral_enable(void)
{
unsigned int v, if_clks=0, func_clks=0;
/* Enable GP2 timer.*/
if_clks |= BIT4;
func_clks |= BIT4;
v = __raw_readl(CM_CLKSEL2_CORE) | 0x4; /* Sys_clk input OMAP2420_GPT2 */
__raw_writel(v, CM_CLKSEL2_CORE);
__raw_writel(0x1, CM_CLKSEL_WKUP);
#ifdef CFG_NS16550
/* Enable UART1 clock */
func_clks |= BIT21;
if_clks |= BIT21;
#endif
v = __raw_readl(CM_ICLKEN1_CORE) | if_clks; /* Interface clocks on */
__raw_writel(v,CM_ICLKEN1_CORE );
v = __raw_readl(CM_FCLKEN1_CORE) | func_clks; /* Functional Clocks on */
__raw_writel(v, CM_FCLKEN1_CORE);
delay(1000);
#ifndef KERNEL_UPDATED
{
#define V1 0xffffffff
#define V2 0x00000007
__raw_writel(V1, CM_FCLKEN1_CORE);
__raw_writel(V2, CM_FCLKEN2_CORE);
__raw_writel(V1, CM_ICLKEN1_CORE);
__raw_writel(V1, CM_ICLKEN2_CORE);
}
#endif
}
/****************************************
* Routine: muxSetupUsb0 (ostboot)
* Description: Setup usb muxing
*****************************************/
void muxSetupUsb0(void)
{
volatile uint8 *MuxConfigReg;
volatile uint32 *otgCtrlReg;
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_PUEN;
*MuxConfigReg &= (uint8)(~0x1F);
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_VP;
*MuxConfigReg &= (uint8)(~0x1F);
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_VM;
*MuxConfigReg &= (uint8)(~0x1F);
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_RCV;
*MuxConfigReg &= (uint8)(~0x1F);
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_TXEN;
*MuxConfigReg &= (uint8)(~0x1F);
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_SE0;
*MuxConfigReg &= (uint8)(~0x1F);
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_DAT;
*MuxConfigReg &= (uint8)(~0x1F);
/* setup for USB VBus detection */
otgCtrlReg = (volatile uint32 *)USB_OTG_CTRL;
*otgCtrlReg |= 0x00040000; /* bit 18 */
}
/****************************************
* Routine: muxSetupUart3 (ostboot)
* Description: Setup uart3 muxing
*****************************************/
void muxSetupUart3(void)
{
volatile uint8 *MuxConfigReg;
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_UART3_TX_IRTX;
*MuxConfigReg &= (uint8)(~0x1F);
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_UART3_RX_IRRX;
*MuxConfigReg &= (uint8)(~0x1F);
}
/****************************************
* Routine: muxSetupI2C1 (ostboot)
* Description: Setup i2c muxing
*****************************************/
void muxSetupI2C1(void)
{
volatile unsigned char *MuxConfigReg;
/* I2C1 Clock pin configuration, PIN = M19 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_I2C1_SCL;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* I2C1 Data pin configuration, PIN = L15 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_I2C1_SDA;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* Pull-up required on data line */
/* external pull-up already present. */
/* *MuxConfigReg |= 0x18 ;*/ /* Mode = 0, PullTypeSel=PU, PullUDEnable=Enabled */
}
/****************************************
* Routine: muxSetupUART1 (ostboot)
* Description: Set up uart1 muxing
*****************************************/
void muxSetupUART1(void)
{
volatile unsigned char *MuxConfigReg;
/* UART1_CTS pin configuration, PIN = D21 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_CTS;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* UART1_RTS pin configuration, PIN = H21 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_RTS;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* UART1_TX pin configuration, PIN = L20 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_TX;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* UART1_RX pin configuration, PIN = T21 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_RX;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
}
/****************************************
* Routine: muxSetupLCD (ostboot)
* Description: Setup lcd muxing
*****************************************/
void muxSetupLCD(void)
{
volatile unsigned char *MuxConfigReg;
/* LCD_D0 pin configuration, PIN = Y7 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D0;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D1 pin configuration, PIN = P10 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D1;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D2 pin configuration, PIN = V8 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D2;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D3 pin configuration, PIN = Y8 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D3;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D4 pin configuration, PIN = W8 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D4;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D5 pin configuration, PIN = R10 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D5;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D6 pin configuration, PIN = Y9 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D6;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D7 pin configuration, PIN = V9 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D7;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D8 pin configuration, PIN = W9 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D8;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D9 pin configuration, PIN = P11 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D9;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D10 pin configuration, PIN = V10 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D10;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D11 pin configuration, PIN = Y10 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D11;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D12 pin configuration, PIN = W10 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D12;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D13 pin configuration, PIN = R11 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D13;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D14 pin configuration, PIN = V11 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D14;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D15 pin configuration, PIN = W11 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D15;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D16 pin configuration, PIN = P12 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D16;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_D17 pin configuration, PIN = R12 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D17;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_PCLK pin configuration, PIN = W6 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_PCLK;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_VSYNC pin configuration, PIN = V7 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_VSYNC;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_HSYNC pin configuration, PIN = Y6 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_HSYNC;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* LCD_ACBIAS pin configuration, PIN = W7 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_ACBIAS;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
}
/****************************************
* Routine: muxSetupCamera (ostboot)
* Description: Setup camera muxing
*****************************************/
void muxSetupCamera(void)
{
volatile unsigned char *MuxConfigReg;
/* CAMERA_RSTZ pin configuration, PIN = Y16 */
/* CAM_RST is connected through the I2C IO expander.*/
/* MuxConfigReg = (volatile unsigned char *), CONTROL_PADCONF_SYS_NRESWARM*/
/* *MuxConfigReg = 0x00 ; / * Mode = 0, PUPD=Disabled */
/* CAMERA_XCLK pin configuration, PIN = U3 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_XCLK;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* CAMERA_LCLK pin configuration, PIN = V5 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_LCLK;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* CAMERA_VSYNC pin configuration, PIN = U2 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_VS,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* CAMERA_HSYNC pin configuration, PIN = T3 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_HS,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* CAMERA_DAT0 pin configuration, PIN = T4 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D0,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* CAMERA_DAT1 pin configuration, PIN = V2 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D1,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* CAMERA_DAT2 pin configuration, PIN = V3 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D2,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* CAMERA_DAT3 pin configuration, PIN = U4 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D3,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* CAMERA_DAT4 pin configuration, PIN = W2 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D4,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* CAMERA_DAT5 pin configuration, PIN = V4 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D5,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* CAMERA_DAT6 pin configuration, PIN = W3 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D6,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* CAMERA_DAT7 pin configuration, PIN = Y2 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D7,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* CAMERA_DAT8 pin configuration, PIN = Y4 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D8,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* CAMERA_DAT9 pin configuration, PIN = V6 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D9,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
}
/****************************************
* Routine: muxSetupMMCSD (ostboot)
* Description: set up MMC muxing
*****************************************/
void muxSetupMMCSD(void)
{
volatile unsigned char *MuxConfigReg;
/* SDMMC_CLKI pin configuration, PIN = H15 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CLKI,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* SDMMC_CLKO pin configuration, PIN = G19 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CLKO,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* SDMMC_CMD pin configuration, PIN = H18 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CMD,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* External pull-ups are present. */
/* *MuxConfigReg |= 0x18 ; #/ PullUDEnable=Enabled, PullTypeSel=PU */
/* SDMMC_DAT0 pin configuration, PIN = F20 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT0,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* External pull-ups are present. */
/* *MuxConfigReg |= 0x18 ; #/ PullUDEnable=Enabled, PullTypeSel=PU */
/* SDMMC_DAT1 pin configuration, PIN = H14 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT1,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* External pull-ups are present. */
/* *MuxConfigReg |= 0x18 ; #/ PullUDEnable=Enabled, PullTypeSel=PU */
/* SDMMC_DAT2 pin configuration, PIN = E19 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT2,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* External pull-ups are present. */
/* *MuxConfigReg |= 0x18 ; #/ PullUDEnable=Enabled, PullTypeSel=PU */
/* SDMMC_DAT3 pin configuration, PIN = D19 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT3,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* External pull-ups are present. */
/* *MuxConfigReg |= 0x18 ; #/ PullUDEnable=Enabled, PullTypeSel=PU */
/* SDMMC_DDIR0 pin configuration, PIN = F19 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR0,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* SDMMC_DDIR1 pin configuration, PIN = E20 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR1,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* SDMMC_DDIR2 pin configuration, PIN = F18 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR2,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* SDMMC_DDIR3 pin configuration, PIN = E18 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR3,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* SDMMC_CDIR pin configuration, PIN = G18 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CMD_DIR,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* MMC_CD pin configuration, PIN = B3 ---2420IP ONLY---*/
/* MMC_CD for 2422IP=K1 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SDRC_A14,
*MuxConfigReg = 0x03 ; /* Mode = 3, PUPD=Disabled */
/* MMC_WP pin configuration, PIN = B4 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SDRC_A13,
*MuxConfigReg = 0x03 ; /* Mode = 3, PUPD=Disabled */
}
/******************************************
* Routine: muxSetupTouchScreen (ostboot)
* Description: Set up touch screen muxing
*******************************************/
void muxSetupTouchScreen(void)
{
volatile unsigned char *MuxConfigReg;
/* SPI1_CLK pin configuration, PIN = U18 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_CLK,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* SPI1_MOSI pin configuration, PIN = V20 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_SIMO,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* SPI1_MISO pin configuration, PIN = T18 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_SOMI,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* SPI1_nCS0 pin configuration, PIN = U19 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_NCS0,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* PEN_IRQ pin configuration, PIN = P20 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MCBSP1_FSR,
*MuxConfigReg = 0x03 ; /* Mode = 3, PUPD=Disabled */
}
/****************************************
* Routine: muxSetupHDQ (ostboot)
* Description: setup 1wire mux
*****************************************/
void muxSetupHDQ(void)
{
volatile unsigned char *MuxConfigReg;
/* HDQ_SIO pin configuration, PIN = N18 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_HDQ_SIO,
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
}
/***************************************************************
* Routine: muxSetupGPMC (ostboot)
* Description: Configures balls which cam up in protected mode
***************************************************************/
void muxSetupGPMC(void)
{
volatile uint8 *MuxConfigReg;
volatile unsigned int *MCR = (volatile unsigned int *)0x4800008C;
/* gpmc_io_dir */
*MCR = 0x19000000;
/* NOR FLASH CS0 */
/* signal - Gpmc_clk; pin - J4; offset - 0x0088; mode - 0; Byte-3 Pull/up - N/A */
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_D2_BYTE3,
*MuxConfigReg = 0x00 ;
/* signal - Gpmc_iodir; pin - n2; offset - 0x008C; mode - 1; Byte-3 Pull/up - N/A */
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_NCS0_BYTE3,
*MuxConfigReg = 0x01 ;
/* MPDB(Multi Port Debug Port) CS1 */
/* signal - gpmc_ncs1; pin - N8; offset - 0x008C; mode - 0; Byte-1 Pull/up - N/A */
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_NCS0_BYTE1,
*MuxConfigReg = 0x00 ;
/* signal - Gpmc_ncs2; pin - E2; offset - 0x008C; mode - 0; Byte-2 Pull/up - N/A */
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_NCS0_BYTE2,
*MuxConfigReg = 0x00 ;
}
/****************************************************************
* Routine: muxSetupSDRC (ostboot)
* Description: Configures balls which come up in protected mode
****************************************************************/
void muxSetupSDRC(void)
{
volatile uint8 *MuxConfigReg;
/* signal - sdrc_ncs1; pin - C12; offset - 0x00A0; mode - 0; Byte-1 Pull/up - N/A */
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_NCS0_BYTE1,
*MuxConfigReg = 0x00 ;
/* signal - sdrc_a12; pin - D11; offset - 0x0030; mode - 0; Byte-2 Pull/up - N/A */
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_A14_BYTE2,
*MuxConfigReg = 0x00 ;
/* signal - sdrc_cke1; pin - B13; offset - 0x00A0; mode - 0; Byte-3 Pull/up - N/A */
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_NCS0_BYTE3,
*MuxConfigReg = 0x00;
if (get_cpu_type() == CPU_2422) {
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_A14_BYTE0,
*MuxConfigReg = 0x1b;
}
}
/*****************************************************************************
* Routine: update_mux()
* Description: Update balls which are different beween boards. All should be
* updated to match functionaly. However, I'm only updating ones
* which I'll be using for now. When power comes into play they
* all need updating.
*****************************************************************************/
void update_mux(u32 btype,u32 mtype)
{
u32 cpu, base = OMAP2420_CTRL_BASE;
cpu = get_cpu_type();
if (btype == BOARD_H4_MENELAUS) {
if (cpu == CPU_2420) {
/* PIN = B3, GPIO.0->KBR5, mode 3, (pun?),-DO-*/
__raw_writeb(0x3, base+0x30);
/* PIN = B13, GPIO.38->KBC6, mode 3, (pun?)-DO-*/
__raw_writeb(0x3, base+0xa3);
/* PIN = F1, GPIO.25->HSUSBxx mode 3, (for external HS USB)*/
/* PIN = H1, GPIO.26->HSUSBxx mode 3, (for external HS USB)*/
/* PIN = K1, GPMC_ncs6 mode 0, (on board nand access)*/
/* PIN = L2, GPMC_ncs67 mode 0, (for external HS USB)*/
/* PIN = M1 (HSUSBOTG) */
/* PIN = P1, GPIO.35->MEN_POK mode 3, (menelaus powerok)-DO-*/
__raw_writeb(0x3, base+0x9d);
/* PIN = U32, (WLAN_CLKREQ) */
/* PIN = Y11, WLAN */
/* PIN = AA4, GPIO.15->KBC2, mode 3, -DO- */
__raw_writeb(0x3, base+0xe7);
/* PIN = AA8, mDOC */
/* PIN = AA10, BT */
/* PIN = AA13, WLAN */
/* PIN = M18 GPIO.96->MMC2_WP mode 3 -DO- */
__raw_writeb(0x3, base+0x10e);
/* PIN = N19 GPIO.98->WLAN_INT mode 3 -DO- */
__raw_writeb(0x3, base+0x110);
/* PIN = J15 HHUSB */
/* PIN = H19 HSUSB */
/* PIN = W13, P13, R13, W16 ... */
/* PIN = V12 GPIO.25->I2C_CAMEN mode 3 -DO- */
__raw_writeb(0x3, base+0xde);
/* PIN = W19 sys_nirq->MENELAUS_INT mode 0 -DO- */
__raw_writeb(0x0, base+0x12c);
/* PIN = AA17->sys_clkreq mode 0 -DO- */
__raw_writeb(0x0, base+0x136);
} else if (cpu == CPU_2422) {
/* PIN = B3, GPIO.0->nc, mode 3, set above (pun?)*/
/* PIN = B13, GPIO.cke1->nc, mode 0, set above, (pun?)*/
/* PIN = F1, GPIO.25->HSUSBxx mode 3, (for external HS USB)*/
/* PIN = H1, GPIO.26->HSUSBxx mode 3, (for external HS USB)*/
/* PIN = K1, GPMC_ncs6 mode 0, (on board nand access)*/
__raw_writeb(0x0, base+0x92);
/* PIN = L2, GPMC_ncs67 mode 0, (for external HS USB)*/
/* PIN = M1 (HSUSBOTG) */
/* PIN = P1, GPIO.35->MEN_POK mode 3, (menelaus powerok)-DO-*/
__raw_writeb(0x3, base+0x10c);
/* PIN = U32, (WLAN_CLKREQ) */
/* PIN = AA4, GPIO.15->KBC2, mode 3, -DO- */
__raw_writeb(0x3, base+0x30);
/* PIN = AA8, mDOC */
/* PIN = AA10, BT */
/* PIN = AA12, WLAN */
/* PIN = M18 GPIO.96->MMC2_WP mode 3 -DO- */
__raw_writeb(0x3, base+0x10e);
/* PIN = N19 GPIO.98->WLAN_INT mode 3 -DO- */
__raw_writeb(0x3, base+0x110);
/* PIN = J15 HHUSB */
/* PIN = H19 HSUSB */
/* PIN = W13, P13, R13, W16 ... */
/* PIN = V12 GPIO.25->I2C_CAMEN mode 3 -DO- */
__raw_writeb(0x3, base+0xde);
/* PIN = W19 sys_nirq->MENELAUS_INT mode 0 -DO- */
__raw_writeb(0x0, base+0x12c);
/* PIN = AA17->sys_clkreq mode 0 -DO- */
__raw_writeb(0x0, base+0x136);
}
} else if (btype == BOARD_H4_SDP) {
if (cpu == CPU_2420) {
/* PIN = B3, GPIO.0->nc mode 3, set above (pun?)*/
/* PIN = B13, GPIO.cke1->nc, mode 0, set above, (pun?)*/
/* Pin = Y11 VLNQ */
/* Pin = AA4 VLNQ */
/* Pin = AA6 VLNQ */
/* Pin = AA8 VLNQ */
/* Pin = AA10 VLNQ */
/* Pin = AA12 VLNQ */
/* PIN = M18 GPIO.96->KBR5 mode 3 -DO- */
__raw_writeb(0x3, base+0x10e);
/* PIN = N19 GPIO.98->KBC6 mode 3 -DO- */
__raw_writeb(0x3, base+0x110);
/* PIN = J15 MDOC_nDMAREQ */
/* PIN = H19 GPIO.100->KBC2 mode 3 -DO- */
__raw_writeb(0x3, base+0x114);
/* PIN = W13, V12, P13, R13, W19, W16 ... */
/* PIN = AA17 sys_clkreq->bt_clk_req mode 0 */
} else if (cpu == CPU_2422) {
/* PIN = B3, GPIO.0->MMC_CD, mode 3, set above */
/* PIN = B13, GPIO.38->wlan_int, mode 3, (pun?)*/
/* Pin = Y11 VLNQ */
/* Pin = AA4 VLNQ */
/* Pin = AA6 VLNQ */
/* Pin = AA8 VLNQ */
/* Pin = AA10 VLNQ */
/* Pin = AA12 VLNQ */
/* PIN = M18 GPIO.96->KBR5 mode 3 -DO- */
__raw_writeb(0x3, base+0x10e);
/* PIN = N19 GPIO.98->KBC6 mode 3 -DO- */
__raw_writeb(0x3, base+0x110);
/* PIN = J15 MDOC_nDMAREQ */
/* PIN = H19 GPIO.100->KBC2 mode 3 -DO- */
__raw_writeb(0x3, base+0x114);
/* PIN = W13, V12, P13, R13, W19, W16 ... */
/* PIN = AA17 sys_clkreq->bt_clk_req mode 0 */
}
}
}
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
void nand_init(void)
{
extern flash_info_t flash_info[];
nand_probe(CFG_NAND_ADDR);
if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN) {
print_size(nand_dev_desc[0].totlen, "\n");
}
#ifdef CFG_JFFS2_MEM_NAND
flash_info[CFG_JFFS2_FIRST_BANK].flash_id = nand_dev_desc[0].id;
flash_info[CFG_JFFS2_FIRST_BANK].size = 1024*1024*2; /* only read kernel single meg partition */
flash_info[CFG_JFFS2_FIRST_BANK].sector_count = 1024; /* 1024 blocks in 16meg chip (use less for raw/copied partition) */
flash_info[CFG_JFFS2_FIRST_BANK].start[0] = 0x80200000; /* ?, ram for now, open question, copy to RAM or adapt for NAND */
#endif
}
#endif

185
board/omap2420h4/platform.S Normal file
View File

@@ -0,0 +1,185 @@
/*
* Board specific setup info
*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.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 <config.h>
#include <version.h>
#include <asm/arch/omap2420.h>
#include <asm/arch/mem.h>
#include <asm/arch/clocks.h>
_TEXT_BASE:
.word TEXT_BASE /* sdram load addr from config.mk */
/**************************************************************************
* cpy_clk_code: relocates clock code into SRAM where its safer to execute
* R1 = SRAM destination address.
*************************************************************************/
.global cpy_clk_code
cpy_clk_code:
/* Copy DPLL code into SRAM */
adr r0, go_to_speed /* get addr of clock setting code */
mov r2, #384 /* r2 size to copy (div by 32 bytes) */
mov r1, r1 /* r1 <- dest address (passed in) */
add r2, r2, r0 /* r2 <- source end address */
next2:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end address [r2] */
bne next2
mov pc, lr /* back to caller */
/* ****************************************************************************
* go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed
* -executed from SRAM.
* R0 = PRCM_CLKCFG_CTRL - addr of valid reg
* R1 = CM_CLKEN_PLL - addr dpll ctlr reg
* R2 = dpll value
* R3 = CM_IDLEST_CKGEN - addr dpll lock wait
******************************************************************************/
.global go_to_speed
go_to_speed:
sub sp, sp, #0x4 /* get some stack space */
str r4, [sp] /* save r4's value */
/* move into fast relock bypass */
ldr r8, pll_ctl_add
mov r4, #0x2
str r4, [r8]
ldr r4, pll_stat
block:
ldr r8, [r4] /* wait for bypass to take effect */
and r8, r8, #0x3
cmp r8, #0x1
bne block
/* set new dpll dividers _after_ in bypass */
ldr r4, pll_div_add
ldr r8, pll_div_val
str r8, [r4]
/* now prepare GPMC (flash) for new dpll speed */
/* flash needs to be stable when we jump back to it */
ldr r4, cfg3_0_addr
ldr r8, cfg3_0_val
str r8, [r4]
ldr r4, cfg4_0_addr
ldr r8, cfg4_0_val
str r8, [r4]
ldr r4, cfg1_0_addr
ldr r8, [r4]
orr r8, r8, #0x3 /* up gpmc divider */
str r8, [r4]
/* setup to 2x loop though code. The first loop pre-loads the
* icache, the 2nd commits the prcm config, and locks the dpll
*/
mov r4, #0x1000 /* spin spin spin */
mov r8, #0x4 /* first pass condition & set registers */
cmp r8, #0x4
2:
ldrne r8, [r3] /* DPLL lock check */
and r8, r8, #0x7
cmp r8, #0x2
beq 4f
3:
subeq r8, r8, #0x1
streq r8, [r0] /* commit dividers (2nd time) */
nop
lloop1:
sub r4, r4, #0x1 /* Loop currently necessary else bad jumps */
nop
cmp r4, #0x0
bne lloop1
mov r4, #0x40000
cmp r8, #0x1
nop
streq r2, [r1] /* lock dpll (2nd time) */
nop
lloop2:
sub r4, r4, #0x1 /* loop currently necessary else bad jumps */
nop
cmp r4, #0x0
bne lloop2
mov r4, #0x40000
cmp r8, #0x1
nop
ldreq r8, [r3] /* get lock condition for dpll */
cmp r8, #0x4 /* first time though? */
bne 2b
moveq r8, #0x2 /* set to dpll check condition. */
beq 3b /* if condition not true branch */
4:
ldr r4, [sp]
add sp, sp, #0x4 /* return stack space */
mov pc, lr /* back to caller, locked */
_go_to_speed: .word go_to_speed
/* these constants need to be close for PIC code */
cfg3_0_addr:
.word GPMC_CONFIG3_0
cfg3_0_val:
.word H4_24XX_GPMC_CONFIG3_0
cfg4_0_addr:
.word GPMC_CONFIG4_0
cfg4_0_val:
.word H4_24XX_GPMC_CONFIG4_0
cfg1_0_addr:
.word GPMC_CONFIG1_0
pll_ctl_add:
.word CM_CLKEN_PLL
pll_stat:
.word CM_IDLEST_CKGEN
pll_div_add:
.word CM_CLKSEL1_PLL
pll_div_val:
.word DPLL_VAL /* DPLL setting (300MHz default) */
.globl platformsetup
platformsetup:
ldr sp, SRAM_STACK
str ip, [sp] /* stash old link register */
mov ip, lr /* save link reg across call */
bl s_init /* go setup pll,mux,memory */
ldr ip, [sp] /* restore save ip */
mov lr, ip /* restore link reg */
/* map interrupt controller */
ldr r0, VAL_INTH_SETUP
mcr p15, 0, r0, c15, c2, 4
/* back to arch calling code */
mov pc, lr
/* the literal pools origin */
.ltorg
REG_CONTROL_STATUS:
.word CONTROL_STATUS
VAL_INTH_SETUP:
.word PERIFERAL_PORT_BASE
SRAM_STACK:
.word LOW_LEVEL_SRAM_STACK

302
board/omap2420h4/sys_info.c Normal file
View File

@@ -0,0 +1,302 @@
/*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* 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/omap2420.h>
#include <asm/io.h>
#include <asm/arch/bits.h>
#include <asm/arch/mem.h> /* get mem tables */
#include <asm/arch/sys_proto.h>
#include <asm/arch/sys_info.h>
#include <i2c.h>
/**************************************************************************
* get_cpu_type() - low level get cpu type
* - no C globals yet.
* - just looking to say if this is a 2422 or 2420 or ...
* - to start with we will look at switch settings..
* - 2422 id's same as 2420 for ES1 will rely on H4 board characteristics
* (mux for 2420, non-mux for 2422).
***************************************************************************/
u32 get_cpu_type(void)
{
u32 v;
v = __raw_readl(TAP_IDCODE_REG);
v &= CPU_24XX_ID_MASK;
if (v == CPU_2420_CHIPID) { /* currently 2420 and 2422 have same id */
if (is_gpmc_muxed() == GPMC_MUXED) /* if mux'ed */
return(CPU_2420);
else
return(CPU_2422);
} else
return(CPU_2420); /* don't know, say 2420 */
}
/******************************************
* get_cpu_rev(void) - extract version info
******************************************/
u32 get_cpu_rev(void)
{
u32 v;
v = __raw_readl(TAP_IDCODE_REG);
v = v >> 28;
return(v+1); /* currently 2422 and 2420 match up */
}
/***********************************************************
* get_mem_type() - identify type of mDDR part used.
* 2422 uses stacked DDR, 2 parts CS0/CS1.
* 2420 may have 1 or 2, no good way to know...only init 1...
* when eeprom data is up we can select 1 more.
*************************************************************/
u32 get_mem_type(void)
{
volatile u32 *burst = (volatile u32 *)(SDRC_MR_0+SDRC_CS0_OSET);
if (get_cpu_type() == CPU_2422)
return(DDR_STACKED);
if (get_board_type() == BOARD_H4_MENELAUS)
if(*burst == H4_2420_SDRC_MR_0_SDR)
return(SDR_DISCRETE);
else
return(DDR_COMBO);
else
if(*burst == H4_2420_SDRC_MR_0_SDR) /* SDP + SDR kit */
return(SDR_DISCRETE);
else
return(DDR_DISCRETE); /* origional SDP */
}
/***********************************************************************
* get_board_type() - get board type based on current production stats.
* --- NOTE: 2 I2C EEPROMs will someday be populated with proper info.
* when they are available we can get info from there. This should
* be correct of all known boards up until today.
************************************************************************/
u32 get_board_type(void)
{
if (i2c_probe(I2C_MENELAUS) == 0)
return(BOARD_H4_MENELAUS);
else
return(BOARD_H4_SDP);
}
/******************************************************************
* get_sysboot_value() - get init word settings (dip switch on h4)
******************************************************************/
u32 get_sysboot_value(void)
{
return(0x00000FFF & __raw_readl(CONTROL_STATUS));
}
/***************************************************************************
* get_gpmc0_base() - Return current address hardware will be
* fetching from. The below effectively gives what is correct, its a bit
* mis-leading compared to the TRM. For the most general case the mask
* needs to be also taken into account this does work in practice.
* - for u-boot we currently map:
* -- 0 to nothing,
* -- 4 to flash
* -- 8 to enent
* -- c to wifi
****************************************************************************/
u32 get_gpmc0_base(void)
{
u32 b;
b = __raw_readl(GPMC_CONFIG7_0);
b &= 0x1F; /* keep base [5:0] */
b = b << 24; /* ret 0x0b000000 */
return(b);
}
/*****************************************************************
* is_gpmc_muxed() - tells if address/data lines are multiplexed
*****************************************************************/
u32 is_gpmc_muxed(void)
{
u32 mux;
mux = get_sysboot_value();
if ((mux & (BIT0 | BIT1 | BIT2 | BIT3)) == (BIT0 | BIT2 | BIT3))
return(GPMC_MUXED); /* NAND Boot mode */
if (mux & BIT1) /* if mux'ed */
return(GPMC_MUXED);
else
return(GPMC_NONMUXED);
}
/************************************************************************
* get_gpmc0_type() - read sysboot lines to see type of memory attached
************************************************************************/
u32 get_gpmc0_type(void)
{
u32 type;
type = get_sysboot_value();
if ((type & (BIT3|BIT2)) == (BIT3|BIT2))
return(TYPE_NAND);
else
return(TYPE_NOR);
}
/*******************************************************************
* get_gpmc0_width() - See if bus is in x8 or x16 (mainly for nand)
*******************************************************************/
u32 get_gpmc0_width(void)
{
u32 width;
width = get_sysboot_value();
if ((width & 0xF) == (BIT3|BIT2))
return(WIDTH_8BIT);
else
return(WIDTH_16BIT);
}
/*********************************************************************
* wait_on_value() - common routine to allow waiting for changes in
* volatile regs.
*********************************************************************/
u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound)
{
u32 i = 0, val;
do {
++i;
val = __raw_readl(read_addr) & read_bit_mask;
if (val == match_value)
return(1);
if (i==bound)
return(0);
} while (1);
}
/*********************************************************************
* display_board_info() - print banner with board info.
*********************************************************************/
void display_board_info(u32 btype)
{
char cpu_2420[] = "2420";
char cpu_2422[] = "2422";
char db_men[] = "Menelaus";
char db_ip[]= "IP";
char *cpu_s, *db_s;
u32 cpu = get_cpu_type();
if(cpu == CPU_2420)
cpu_s = cpu_2420;
else
cpu_s = cpu_2422;
if(btype == BOARD_H4_MENELAUS)
db_s = db_men;
else
db_s = db_ip;
printf("TI H4 SDP Base Board with OMAP%s %s Daughter Board\n",cpu_s, db_s);
}
/*************************************************************************
* get_board_rev() - setup to pass kernel board revision information
* 0 = 242x IP platform (first 2xx boards)
* 1 = 242x Menelaus platfrom.
*************************************************************************/
u32 get_board_rev(void)
{
u32 rev = 0;
u32 btype = get_board_type();
if (btype == BOARD_H4_MENELAUS){
rev = 1;
}
return(rev);
}
/********************************************************
* get_base(); get upper addr of current execution
*******************************************************/
static u32 get_base(void)
{
u32 val;
__asm__ __volatile__("mov %0, pc \n" : "=r" (val) : : "memory");
val &= 0xF0000000;
val >>= 28;
return(val);
}
/********************************************************
* get_base2(); get 2upper addr of current execution
*******************************************************/
static u32 get_base2(void)
{
u32 val;
__asm__ __volatile__("mov %0, pc \n" : "=r" (val) : : "memory");
val &= 0xFF000000;
val >>= 24;
return(val);
}
/********************************************************
* running_in_flash() - tell if currently running in
* flash.
*******************************************************/
u32 running_in_flash(void)
{
if (get_base() < 4)
return(1); /* in flash */
return(0); /* running in SRAM or SDRAM */
}
/********************************************************
* running_in_sram() - tell if currently running in
* sram.
*******************************************************/
u32 running_in_sram(void)
{
if (get_base() == 4)
return(1); /* in SRAM */
return(0); /* running in FLASH or SDRAM */
}
/********************************************************
* running_in_sdram() - tell if currently running in
* flash.
*******************************************************/
u32 running_in_sdram(void)
{
if (get_base() > 4)
return(1); /* in sdram */
return(0); /* running in SRAM or FLASH */
}
/*************************************************************
* running_from_internal_boot() - am I a signed NOR image.
*************************************************************/
u32 running_from_internal_boot(void)
{
u32 v, base;
v = get_sysboot_value() & BIT3;
base = get_base2();
/* if running at mask rom flash address and
* sysboot3 says this was an internal boot
*/
if ((base == 0x08) && v)
return(1);
else
return(0);
}

View File

@@ -0,0 +1,58 @@
/*
* January 2004 - Changed to support H4 device
* Copyright (c) 2004 Texas Instruments
*
* (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_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/arm1136/start.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}

48
board/pleb2/Makefile Normal file
View File

@@ -0,0 +1,48 @@
#
# (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 := pleb2.o flash.o
SOBJS := memsetup.o
$(LIB): $(OBJS) $(SOBJS)
$(AR) crv $@ $(OBJS) $(SOBJS)
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
#########################################################################

3
board/pleb2/config.mk Normal file
View File

@@ -0,0 +1,3 @@
TEXT_BASE = 0xa1F80000
#TEXT_BASE = 0xa3080000
#TEXT_BASE = 0

814
board/pleb2/flash.c Normal file
View File

@@ -0,0 +1,814 @@
/*
* (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>
/* environment.h defines the various CFG_ENV_... values in terms
* of whichever ones are given in the configuration file.
*/
#include <environment.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)
/*-----------------------------------------------------------------------
* 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);
#ifdef CFG_FLASH_PROTECTION
static void flash_sync_real_protect (flash_info_t * info);
#endif
/*-----------------------------------------------------------------------
* flash_init()
*
* sets up flash_info and returns size of FLASH (bytes)
*/
unsigned long flash_init (void)
{
unsigned long size_b;
int i;
/* Init: no FLASHes known */
for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
}
size_b = flash_get_size ((FPW *) CFG_FLASH_BASE, &flash_info[0]);
flash_info[0].size = size_b;
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx\n",
size_b);
}
/* Do this again (was done already in flast_get_size), just
* in case we move it when remap the FLASH.
*/
flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
#ifdef CFG_FLASH_PROTECTION
/* read the hardware protection status (if any) into the
* protection array in flash_info.
*/
flash_sync_real_protect (&flash_info[0]);
#endif
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
/* monitor protection ON by default */
flash_protect (FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE + monitor_flash_len - 1,
&flash_info[0]);
#endif
#ifdef CFG_ENV_ADDR
flash_protect (FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
#endif
#ifdef CFG_ENV_ADDR_REDUND
flash_protect (FLAG_PROTECT_SET,
CFG_ENV_ADDR_REDUND,
CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1,
&flash_info[0]);
#endif
return (size_b);
}
/*-----------------------------------------------------------------------
*/
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);
} else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
&& (info->flash_id & FLASH_TYPEMASK) == FLASH_AM800T) {
int sect_size; /* number of bytes/sector */
sect_size = 0x00010000 * (sizeof (FPW) / 2);
/* set up sector start address table (top boot sector type) */
for (i = 0; i < info->sector_count - 3; i++)
info->start[i] = base + (i * sect_size);
i = info->sector_count - 1;
info->start[i--] =
base + (info->size - 0x00004000) * (sizeof (FPW) / 2);
info->start[i--] =
base + (info->size - 0x00006000) * (sizeof (FPW) / 2);
info->start[i--] =
base + (info->size - 0x00008000) * (sizeof (FPW) / 2);
}
}
/*-----------------------------------------------------------------------
*/
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_AM800T:
fmt = "29LV800B%s (8 Mbit, %s)\n";
break;
case FLASH_AM640U:
fmt = "29LV641D (64 Mbit, uniform sectors)\n";
break;
case FLASH_28F800C3B:
case FLASH_28F800C3T:
fmt = "28F800C3%s (8 Mbit, %s)\n";
break;
case FLASH_INTEL800B:
case FLASH_INTEL800T:
fmt = "28F800B3%s (8 Mbit, %s)\n";
break;
case FLASH_28F160C3B:
case FLASH_28F160C3T:
fmt = "28F160C3%s (16 Mbit, %s)\n";
break;
case FLASH_INTEL160B:
case FLASH_INTEL160T:
fmt = "28F160B3%s (16 Mbit, %s)\n";
break;
case FLASH_28F320C3B:
case FLASH_28F320C3T:
fmt = "28F320C3%s (32 Mbit, %s)\n";
break;
case FLASH_INTEL320B:
case FLASH_INTEL320T:
fmt = "28F320B3%s (32 Mbit, %s)\n";
break;
case FLASH_28F640C3B:
case FLASH_28F640C3T:
fmt = "28F640C3%s (64 Mbit, %s)\n";
break;
case FLASH_INTEL640B:
case FLASH_INTEL640T:
fmt = "28F640B3%s (64 Mbit, %s)\n";
break;
default:
fmt = "Unknown Chip Type\n";
break;
}
printf (fmt, bootletter, boottype);
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; ++i) {
if ((i % 5) == 0) {
printf ("\n ");
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
}
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
ulong flash_get_size (FPWV * addr, flash_info_t * info)
{
/* Write auto select command: read Manufacturer ID */
/* Write auto select command sequence and test FLASH answer */
addr[0x0555] = (FPW) 0x00AA00AA; /* for AMD, Intel ignores this */
addr[0x02AA] = (FPW) 0x00550055; /* for AMD, Intel ignores this */
addr[0x0555] = (FPW) 0x00900090; /* selects Intel or AMD */
/* The manufacturer codes are only 1 byte, so just use 1 byte.
* This works for any bus width and any FLASH device width.
*/
switch (addr[0] & 0xff) {
case (uchar) AMD_MANUFACT:
info->flash_id = FLASH_MAN_AMD;
break;
case (uchar) INTEL_MANUFACT:
info->flash_id = FLASH_MAN_INTEL;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
break;
}
/* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
if (info->flash_id != FLASH_UNKNOWN)
switch (addr[1]) {
case (FPW) AMD_ID_LV800T:
info->flash_id += FLASH_AM800T;
info->sector_count = 19;
info->size = 0x00100000 * (sizeof (FPW) / 2);
break; /* => 1 or 2 MiB */
case (FPW) AMD_ID_LV640U: /* 29LV640 and 29LV641 have same ID */
info->flash_id += FLASH_AM640U;
info->sector_count = 128;
info->size = 0x00800000 * (sizeof (FPW) / 2);
break; /* => 8 or 16 MB */
case (FPW) INTEL_ID_28F800C3B:
info->flash_id += FLASH_28F800C3B;
info->sector_count = 23;
info->size = 0x00100000 * (sizeof (FPW) / 2);
break; /* => 1 or 2 MB */
case (FPW) INTEL_ID_28F800B3B:
info->flash_id += FLASH_INTEL800B;
info->sector_count = 23;
info->size = 0x00100000 * (sizeof (FPW) / 2);
break; /* => 1 or 2 MB */
case (FPW) INTEL_ID_28F160C3B:
info->flash_id += FLASH_28F160C3B;
info->sector_count = 39;
info->size = 0x00200000 * (sizeof (FPW) / 2);
break; /* => 2 or 4 MB */
case (FPW) INTEL_ID_28F160B3B:
info->flash_id += FLASH_INTEL160B;
info->sector_count = 39;
info->size = 0x00200000 * (sizeof (FPW) / 2);
break; /* => 2 or 4 MB */
case (FPW) INTEL_ID_28F320C3B:
info->flash_id += FLASH_28F320C3B;
info->sector_count = 71;
info->size = 0x00400000 * (sizeof (FPW) / 2);
break; /* => 4 or 8 MB */
case (FPW) INTEL_ID_28F320B3B:
info->flash_id += FLASH_INTEL320B;
info->sector_count = 71;
info->size = 0x00400000 * (sizeof (FPW) / 2);
break; /* => 4 or 8 MB */
case (FPW) INTEL_ID_28F640C3B:
info->flash_id += FLASH_28F640C3B;
info->sector_count = 135;
info->size = 0x00800000 * (sizeof (FPW) / 2);
break; /* => 8 or 16 MB */
case (FPW) INTEL_ID_28F640B3B:
info->flash_id += FLASH_INTEL640B;
info->sector_count = 135;
info->size = 0x00800000 * (sizeof (FPW) / 2);
break; /* => 8 or 16 MB */
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* => no or unknown flash */
}
flash_get_offsets ((ulong) addr, info);
/* Put FLASH back in read mode */
flash_reset (info);
return (info->size);
}
#ifdef CFG_FLASH_PROTECTION
/*-----------------------------------------------------------------------
*/
static void flash_sync_real_protect (flash_info_t * info)
{
FPWV *addr = (FPWV *) (info->start[0]);
FPWV *sect;
int i;
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F800C3B:
case FLASH_28F800C3T:
case FLASH_28F160C3B:
case FLASH_28F160C3T:
case FLASH_28F320C3B:
case FLASH_28F320C3T:
case FLASH_28F640C3B:
case FLASH_28F640C3T:
/* check for protected sectors */
*addr = (FPW) 0x00900090;
for (i = 0; i < info->sector_count; i++) {
/* read sector protection at sector address, (A7 .. A0) = 0x02.
* D0 = 1 for each device if protected.
* If at least one device is protected the sector is marked
* protected, but mixed protected and unprotected devices
* within a sector should never happen.
*/
sect = (FPWV *) (info->start[i]);
info->protect[i] =
(sect[2] & (FPW) (0x00010001)) ? 1 : 0;
}
/* Put FLASH back in read mode */
flash_reset (info);
break;
case FLASH_AM640U:
case FLASH_AM800T:
default:
/* no hardware protect that we support */
break;
}
}
#endif
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
FPWV *addr;
int flag, prot, sect;
int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
ulong 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:
case FLASH_AM800T:
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");
}
reset_timer_masked ();
/* 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 ();
reset_timer_masked ();
last = 0;
addr = (FPWV *) (info->start[sect]);
if (intel) {
*addr = (FPW) 0x00500050; /* clear status register */
*addr = (FPW) 0x00200020; /* erase setup */
*addr = (FPW) 0x00D000D0; /* erase confirm */
} else {
/* must be AMD style if not Intel */
FPWV *base; /* first address in bank */
base = (FPWV *) (info->start[0]);
base[0x0555] = (FPW) 0x00AA00AA; /* unlock */
base[0x02AA] = (FPW) 0x00550055; /* unlock */
base[0x0555] = (FPW) 0x00800080; /* erase mode */
base[0x0555] = (FPW) 0x00AA00AA; /* unlock */
base[0x02AA] = (FPW) 0x00550055; /* unlock */
*addr = (FPW) 0x00300030; /* erase sector */
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts ();
/* wait at least 50us for AMD, 80us for Intel.
* Let's wait 1 ms.
*/
udelay (1000);
while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) {
if ((now =
get_timer_masked ()) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
if (intel) {
/* suspend erase */
*addr = (FPW) 0x00B000B0;
}
flash_reset (info); /* reset to read mode */
rcode = 1; /* failed */
break;
}
/* show that we're waiting */
if ((now - last) > 1 * CFG_HZ) { /* every second */
putc ('.');
last = now;
}
}
flash_reset (info); /* reset to read mode */
}
printf (" done\n");
return rcode;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int 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
*/
#ifdef CFG_LITTLE_ENDIAN
for (i = 0; i < sizeof (data); i++) {
data >>= 8;
if (i < bytes || i - bytes >= left)
data += (*((uchar *) addr + i)) << 24;
else
data += (*src++) << 24;
}
#else
for (i = 0; i < sizeof (data); i++) {
data <<= 8;
if (i < bytes || i - bytes >= left)
data += *((uchar *) addr + i);
else
data += *src++;
}
#endif
/* 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)
{
int flag;
int res = 0; /* result, assume success */
FPWV *base; /* first address in flash bank */
/* Check if Flash is (sufficiently) erased */
if ((*dest & data) != data) {
return (2);
}
base = (FPWV *) (info->start[0]);
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts ();
base[0x0555] = (FPW) 0x00AA00AA; /* unlock */
base[0x02AA] = (FPW) 0x00550055; /* unlock */
base[0x0555] = (FPW) 0x00A000A0; /* selects program mode */
*dest = data; /* start programming the data */
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts ();
reset_timer_masked ();
/* data polling for D7 */
while (res == 0
&& (*dest & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) {
if (get_timer_masked () > 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)
{
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 ();
reset_timer_masked ();
while (res == 0 && (*dest & (FPW) 0x00800080) != (FPW) 0x00800080) {
if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
*dest = (FPW) 0x00B000B0; /* Suspend program */
res = 1;
}
}
if (res == 0 && (*dest & (FPW) 0x00100010))
res = 1; /* write failed, time out error is close enough */
*dest = (FPW) 0x00500050; /* clear status register */
*dest = (FPW) 0x00FF00FF; /* make sure in read mode */
return (res);
}
#ifdef CFG_FLASH_PROTECTION
/*-----------------------------------------------------------------------
*/
int flash_real_protect (flash_info_t * info, long sector, int prot)
{
int rcode = 0; /* assume success */
FPWV *addr; /* address of sector */
FPW value;
addr = (FPWV *) (info->start[sector]);
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F800C3B:
case FLASH_28F800C3T:
case FLASH_28F160C3B:
case FLASH_28F160C3T:
case FLASH_28F320C3B:
case FLASH_28F320C3T:
case FLASH_28F640C3B:
case FLASH_28F640C3T:
flash_reset (info); /* make sure in read mode */
*addr = (FPW) 0x00600060L; /* lock command setup */
if (prot)
*addr = (FPW) 0x00010001L; /* lock sector */
else
*addr = (FPW) 0x00D000D0L; /* unlock sector */
flash_reset (info); /* reset to read mode */
/* now see if it really is locked/unlocked as requested */
*addr = (FPW) 0x00900090;
/* read sector protection at sector address, (A7 .. A0) = 0x02.
* D0 = 1 for each device if protected.
* If at least one device is protected the sector is marked
* protected, but return failure. Mixed protected and
* unprotected devices within a sector should never happen.
*/
value = addr[2] & (FPW) 0x00010001;
if (value == 0)
info->protect[sector] = 0;
else if (value == (FPW) 0x00010001)
info->protect[sector] = 1;
else {
/* error, mixed protected and unprotected */
rcode = 1;
info->protect[sector] = 1;
}
if (info->protect[sector] != prot)
rcode = 1; /* failed to protect/unprotect as requested */
/* reload all protection bits from hardware for now */
flash_sync_real_protect (info);
break;
case FLASH_AM640U:
case FLASH_AM800T:
default:
/* no hardware protect that we support */
info->protect[sector] = prot;
break;
}
return rcode;
}
#endif

488
board/pleb2/memsetup.S Normal file
View File

@@ -0,0 +1,488 @@
/*
* Most of this taken from Redboot hal_platform_setup.h with cleanup
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <config.h>
#include <version.h>
#include <asm/arch/pxa-regs.h>
DRAM_SIZE: .long CFG_DRAM_SIZE
/* wait for coprocessor write complete */
.macro CPWAIT reg
mrc p15,0,\reg,c2,c0,0
mov \reg,\reg
sub pc,pc,#4
.endm
.globl memsetup
memsetup:
mov r10, lr
/* Set up GPIO pins first */
ldr r0, =GPSR0
ldr r1, =CFG_GPSR0_VAL
str r1, [r0]
ldr r0, =GPSR1
ldr r1, =CFG_GPSR1_VAL
str r1, [r0]
ldr r0, =GPSR2
ldr r1, =CFG_GPSR2_VAL
str r1, [r0]
ldr r0, =GPCR0
ldr r1, =CFG_GPCR0_VAL
str r1, [r0]
ldr r0, =GPCR1
ldr r1, =CFG_GPCR1_VAL
str r1, [r0]
ldr r0, =GPCR2
ldr r1, =CFG_GPCR2_VAL
str r1, [r0]
ldr r0, =GRER0
ldr r1, =CFG_GRER0_VAL
str r1, [r0]
ldr r0, =GRER1
ldr r1, =CFG_GRER1_VAL
str r1, [r0]
ldr r0, =GRER2
ldr r1, =CFG_GRER2_VAL
str r1, [r0]
ldr r0, =GFER0
ldr r1, =CFG_GFER0_VAL
str r1, [r0]
ldr r0, =GFER1
ldr r1, =CFG_GFER1_VAL
str r1, [r0]
ldr r0, =GFER2
ldr r1, =CFG_GFER2_VAL
str r1, [r0]
ldr r0, =GPDR0
ldr r1, =CFG_GPDR0_VAL
str r1, [r0]
ldr r0, =GPDR1
ldr r1, =CFG_GPDR1_VAL
str r1, [r0]
ldr r0, =GPDR2
ldr r1, =CFG_GPDR2_VAL
str r1, [r0]
ldr r0, =GAFR0_L
ldr r1, =CFG_GAFR0_L_VAL
str r1, [r0]
ldr r0, =GAFR0_U
ldr r1, =CFG_GAFR0_U_VAL
str r1, [r0]
ldr r0, =GAFR1_L
ldr r1, =CFG_GAFR1_L_VAL
str r1, [r0]
ldr r0, =GAFR1_U
ldr r1, =CFG_GAFR1_U_VAL
str r1, [r0]
ldr r0, =GAFR2_L
ldr r1, =CFG_GAFR2_L_VAL
str r1, [r0]
ldr r0, =GAFR2_U
ldr r1, =CFG_GAFR2_U_VAL
str r1, [r0]
/* enable GPIO pins */
ldr r0, =PSSR
ldr r1, =CFG_PSSR_VAL
str r1, [r0]
/*********************************************************************
Initlialize Memory Controller
See PXA250 Operating System Developer's Guide
pause for 200 uSecs- allow internal clocks to settle
*Note: only need this if hard reset... doing it anyway for now
*/
@ Step 1
@ ---- Wait 200 usec
ldr r3, =OSCR @ reset the OS Timer Count to zero
mov r2, #0
str r2, [r3]
ldr r4, =0x300 @ really 0x2E1 is about 200usec, so 0x300 should be plenty
1:
ldr r2, [r3]
cmp r4, r2
bgt 1b
mem_init:
@ get memory controller base address
ldr r1, =MEMC_BASE
@****************************************************************************
@ Step 2
@
@ Step 2a
@ write msc0, read back to ensure data latches
@
ldr r2, =CFG_MSC0_VAL
str r2, [r1, #MSC0_OFFSET]
ldr r2, [r1, #MSC0_OFFSET]
@ write msc1
ldr r2, =CFG_MSC1_VAL
str r2, [r1, #MSC1_OFFSET]
ldr r2, [r1, #MSC1_OFFSET]
@ write msc2
ldr r2, =CFG_MSC2_VAL
str r2, [r1, #MSC2_OFFSET]
ldr r2, [r1, #MSC2_OFFSET]
@ Step 2b
@ write mecr
ldr r2, =CFG_MECR_VAL
str r2, [r1, #MECR_OFFSET]
@ write mcmem0
ldr r2, =CFG_MCMEM0_VAL
str r2, [r1, #MCMEM0_OFFSET]
@ write mcmem1
ldr r2, =CFG_MCMEM1_VAL
str r2, [r1, #MCMEM1_OFFSET]
@ write mcatt0
ldr r2, =CFG_MCATT0_VAL
str r2, [r1, #MCATT0_OFFSET]
@ write mcatt1
ldr r2, =CFG_MCATT1_VAL
str r2, [r1, #MCATT1_OFFSET]
@ write mcio0
ldr r2, =CFG_MCIO0_VAL
str r2, [r1, #MCIO0_OFFSET]
@ write mcio1
ldr r2, =CFG_MCIO1_VAL
str r2, [r1, #MCIO1_OFFSET]
@ Step 2c
@ fly-by-dma is defeatured on this part
@ write flycnfg
@ldr r2, =CFG_FLYCNFG_VAL
@str r2, [r1, #FLYCNFG_OFFSET]
/* FIXME Does this sequence really make sense */
#ifdef REDBOOT_WAY
@ Step 2d
@ get the mdrefr settings
ldr r3, =CFG_MDREFR_VAL
@ extract DRI field (we need a valid DRI field)
@
ldr r2, =0xFFF
@ valid DRI field in r3
@
and r3, r3, r2
@ get the reset state of 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 3
@
@ NO SRAM
mov pc, r10
@****************************************************************************
@ Step 4
@
@ Assumes previous mdrefr value in r4, if not then read current mdrefr
@ clear the free-running clock bits
@ (clear K0Free, K1Free, K2Free
@
bic r4, r4, #(0x00800000 | 0x01000000 | 0x02000000)
@ set K0RUN for CPLD clock
@
orr r4, r4, #0x00002000
@ set K1RUN if bank 0 installed
@
orr r4, r4, #0x00010000
@ write back mdrefr
@
str r4, [r1, #MDREFR_OFFSET]
ldr r4, [r1, #MDREFR_OFFSET]
@ deassert SLFRSH
@
bic r4, r4, #0x00400000
@ write back mdrefr
@
str r4, [r1, #MDREFR_OFFSET]
@ assert E1PIN
@
orr r4, r4, #0x00008000
@ write back mdrefr
@
str r4, [r1, #MDREFR_OFFSET]
ldr r4, [r1, #MDREFR_OFFSET]
nop
nop
#else
@ Step 2d
@ get the mdrefr settings
ldr r3, =CFG_MDREFR_VAL
@ write back mdrefr
@
str r4, [r1, #MDREFR_OFFSET]
@ Step 4
@ set K0RUN for CPLD clock
@
orr r4, r4, #0x00002000
@ set K1RUN for bank 0
@
orr r4, r4, #0x00010000
@ write back mdrefr
@
str r4, [r1, #MDREFR_OFFSET]
ldr r4, [r1, #MDREFR_OFFSET]
@ deassert SLFRSH
@
bic r4, r4, #0x00400000
@ write back mdrefr
@
str r4, [r1, #MDREFR_OFFSET]
@ assert E1PIN
@
orr r4, r4, #0x00008000
@ write back mdrefr
@
str r4, [r1, #MDREFR_OFFSET]
ldr r4, [r1, #MDREFR_OFFSET]
nop
nop
#endif
@ Step 4d
@ 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
@ write initial value of mdcnfg, w/o enabling sdram banks
@
str r2, [r1, #MDCNFG_OFFSET]
@ Step 4e
@ pause for 200 uSecs
@
ldr r3, =OSCR @ reset the OS Timer Count to zero
mov r2, #0
str r2, [r3]
ldr r4, =0x300 @ really 0x2E1 is about 200usec, so 0x300 should be plenty
1:
ldr r2, [r3]
cmp r4, r2
bgt 1b
/* Why is this here??? */
mov r0, #0x78 @turn everything off
mcr p15, 0, r0, c1, c0, 0 @(caches off, MMU off, etc.)
@ Step 4f
@ 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]
@ Step 4g
@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)
@
str r3, [r1, #MDCNFG_OFFSET]
@ Step 4h
@ write mdmrs
@
ldr r2, =CFG_MDMRS_VAL
str r2, [r1, #MDMRS_OFFSET]
@ Done Memory Init
/*SET_LED 6 */
@********************************************************************
@ Disable (mask) all interrupts at the interrupt controller
@
@ clear the interrupt level register (use IRQ, not FIQ)
@
mov r1, #0
ldr r2, =ICLR
str r1, [r2]
@ Set interrupt mask register
@
ldr r1, =CFG_ICMR_VAL
ldr r2, =ICMR
str r1, [r2]
@ ********************************************************************
@ Disable the peripheral clocks, and set the core clock
@
@ Turn Off ALL on-chip peripheral clocks for re-configuration
@
ldr r1, =CKEN
mov r2, #0
str r2, [r1]
@ set core clocks
@
ldr r2, =CFG_CCCR_VAL
ldr r1, =CCCR
str r2, [r1]
#ifdef ENABLE32KHZ
@ enable the 32Khz oscillator for RTC and PowerManager
@
ldr r1, =OSCC
mov r2, #OSCC_OON
str r2, [r1]
@ NOTE: spin here until OSCC.OOK get set,
@ meaning the PLL has settled.
@
60:
ldr r2, [r1]
ands r2, r2, #1
beq 60b
#endif
@ Turn on needed clocks
@
ldr r1, =CKEN
ldr r2, =CFG_CKEN_VAL
str r2, [r1]
/*SET_LED 7 */
/* Is this needed???? */
#define NODEBUG
#ifdef NODEBUG
/*Disable software and data breakpoints */
mov r0,#0
mcr p15,0,r0,c14,c8,0 /* ibcr0 */
mcr p15,0,r0,c14,c9,0 /* ibcr1 */
mcr p15,0,r0,c14,c4,0 /* dbcon */
/*Enable all debug functionality */
mov r0,#0x80000000
mcr p14,0,r0,c10,c0,0 /* dcsr */
#endif
mov pc, r10
@ End memsetup

76
board/pleb2/pleb2.c Normal file
View File

@@ -0,0 +1,76 @@
/*
* (C) Copyright 2002
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* 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-arm/mach-types.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 Lubbock-Board */
gd->bd->bi_arch_number = MACH_TYPE_PLEB2;
/* adress of boot parameters */
gd->bd->bi_boot_params = 0xa0000100;
return 0;
}
int board_late_init(void)
{
setenv("stdout", "serial");
setenv("stderr", "serial");
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;
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
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 0;
}

55
board/pleb2/u-boot.lds Normal file
View File

@@ -0,0 +1,55 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/pxa/start.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}

View File

@@ -145,11 +145,13 @@ int misc_init_r (void)
}
show_startup_phase (10);
#ifdef CONFIG_HAS_ETH1
if (getenv ("eth1addr") == NULL &&
get_mac_address (1, mac, str, sizeof (str)) > 0) {
setenv ("eth1addr", str);
memcpy (gd->bd->bi_enet1addr, mac, 6);
}
#endif /* CONFIG_HAS_ETH1 */
show_startup_phase (11);
/* Tell everybody that U-Boot is up and runnig */

46
board/sbc405/Makefile Normal file
View File

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

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

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

114
board/sbc405/sbc405.c Normal file
View File

@@ -0,0 +1,114 @@
/*
* (C) Copyright 2001
*
* 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/processor.h>
#include <command.h>
#include <malloc.h>
#include <spd_sdram.h>
int board_early_init_f (void)
{
/*
* IRQ 0-15 405GP internally generated; active high; level sensitive
* IRQ 16 405GP internally generated; active low; level sensitive
* IRQ 17-24 RESERVED
* IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
* IRQ 26 (EXT IRQ 1) SER0 ; active low; level sensitive
* IRQ 27 (EXT IRQ 2) SER1; active low; level sensitive
* IRQ 28 (EXT IRQ 3) FPGA 0; active low; level sensitive
* IRQ 29 (EXT IRQ 4) FPGA 1; active low; level sensitive
* IRQ 30 (EXT IRQ 5) PCI INTA; active low; level sensitive
* IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive
*/
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 */
mtdcr(uictr, 0x10000000); /* set int trigger levels */
mtdcr(uicvcr, 0x00000001); /* set vect base=0,INT0 highest priority*/
mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
/*
* EBC Configuration Register: set ready timeout to 512 ebc-clks -> ca. 15 us
*/
mtebc (epcr, 0xa8400000);
return 0;
}
/* ------------------------------------------------------------------------- */
int misc_init_f (void)
{
return 0; /* dummy implementation */
}
int misc_init_r (void)
{
return (0);
}
/*
* Check Board Identity:
*/
int checkboard (void)
{
unsigned char str[64];
int i = getenv_r ("serial#", str, sizeof(str));
puts ("Board: ");
if (i == -1) {
puts ("### No HW ID - assuming sbc405");
} else {
puts(str);
}
putc ('\n');
return 0;
}
/* ------------------------------------------------------------------------- */
long int initdram (int board_type)
{
return spd_sdram (0);
}
/* ------------------------------------------------------------------------- */
int testdram (void)
{
/* TODO: XXX XXX XXX */
printf ("test: 64 MB - ok\n");
return (0);
}
/* ------------------------------------------------------------------------- */

793
board/sbc405/strataflash.c Normal file
View File

@@ -0,0 +1,793 @@
/*
* (C) Copyright 2002
* Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.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 <asm/processor.h>
#undef DEBUG_FLASH
/*
* This file implements a Common Flash Interface (CFI) driver for ppcboot.
* The width of the port and the width of the chips are determined at initialization.
* These widths are used to calculate the address for access CFI data structures.
* It has been tested on an Intel Strataflash implementation.
*
* References
* JEDEC Standard JESD68 - Common Flash Interface (CFI)
* JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
* Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
* Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
*
* TODO
* Use Primary Extended Query table (PRI) and Alternate Algorithm Query Table (ALT) to determine if protection is available
* Add support for other command sets Use the PRI and ALT to determine command set
* Verify erase and program timeouts.
*/
#define FLASH_CMD_CFI 0x98
#define FLASH_CMD_READ_ID 0x90
#define FLASH_CMD_RESET 0xff
#define FLASH_CMD_BLOCK_ERASE 0x20
#define FLASH_CMD_ERASE_CONFIRM 0xD0
#define FLASH_CMD_WRITE 0x40
#define FLASH_CMD_PROTECT 0x60
#define FLASH_CMD_PROTECT_SET 0x01
#define FLASH_CMD_PROTECT_CLEAR 0xD0
#define FLASH_CMD_CLEAR_STATUS 0x50
#define FLASH_CMD_WRITE_TO_BUFFER 0xE8
#define FLASH_CMD_WRITE_BUFFER_CONFIRM 0xD0
#define FLASH_STATUS_DONE 0x80
#define FLASH_STATUS_ESS 0x40
#define FLASH_STATUS_ECLBS 0x20
#define FLASH_STATUS_PSLBS 0x10
#define FLASH_STATUS_VPENS 0x08
#define FLASH_STATUS_PSS 0x04
#define FLASH_STATUS_DPS 0x02
#define FLASH_STATUS_R 0x01
#define FLASH_STATUS_PROTECT 0x01
#define FLASH_OFFSET_CFI 0x55
#define FLASH_OFFSET_CFI_RESP 0x10
#define FLASH_OFFSET_WTOUT 0x1F
#define FLASH_OFFSET_WBTOUT 0x20
#define FLASH_OFFSET_ETOUT 0x21
#define FLASH_OFFSET_CETOUT 0x22
#define FLASH_OFFSET_WMAX_TOUT 0x23
#define FLASH_OFFSET_WBMAX_TOUT 0x24
#define FLASH_OFFSET_EMAX_TOUT 0x25
#define FLASH_OFFSET_CEMAX_TOUT 0x26
#define FLASH_OFFSET_SIZE 0x27
#define FLASH_OFFSET_INTERFACE 0x28
#define FLASH_OFFSET_BUFFER_SIZE 0x2A
#define FLASH_OFFSET_NUM_ERASE_REGIONS 0x2C
#define FLASH_OFFSET_ERASE_REGIONS 0x2D
#define FLASH_OFFSET_PROTECT 0x02
#define FLASH_OFFSET_USER_PROTECTION 0x85
#define FLASH_OFFSET_INTEL_PROTECTION 0x81
#define FLASH_MAN_CFI 0x01000000
typedef union {
unsigned char c;
unsigned short w;
unsigned long l;
} cfiword_t;
typedef union {
unsigned char * cp;
unsigned short *wp;
unsigned long *lp;
} cfiptr_t;
#define NUM_ERASE_REGIONS 4
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*-----------------------------------------------------------------------
* Functions
*/
static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c);
static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf);
static void flash_write_cmd(flash_info_t * info, int sect, uchar offset, uchar cmd);
static int flash_isequal(flash_info_t * info, int sect, uchar offset, uchar cmd);
static int flash_isset(flash_info_t * info, int sect, uchar offset, uchar cmd);
static int flash_detect_cfi(flash_info_t * info);
static ulong flash_get_size (ulong base, int banknum);
static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword);
static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt);
#ifdef CFG_FLASH_USE_BUFFER_WRITE
static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len);
#endif
/*-----------------------------------------------------------------------
* create an address based on the offset and the port width
*/
inline uchar * flash_make_addr(flash_info_t * info, int sect, int offset)
{
return ((uchar *)(info->start[sect] + (offset * info->portwidth)));
}
/*-----------------------------------------------------------------------
* read a character at a port width address
*/
inline uchar flash_read_uchar(flash_info_t * info, uchar offset)
{
uchar *cp;
cp = flash_make_addr(info, 0, offset);
return (cp[info->portwidth - 1]);
}
/*-----------------------------------------------------------------------
* read a short word by swapping for ppc format.
*/
ushort flash_read_ushort(flash_info_t * info, int sect, uchar offset)
{
uchar * addr;
addr = flash_make_addr(info, sect, offset);
return ((addr[(2*info->portwidth) - 1] << 8) | addr[info->portwidth - 1]);
}
/*-----------------------------------------------------------------------
* read a long word by picking the least significant byte of each maiximum
* port size word. Swap for ppc format.
*/
ulong flash_read_long(flash_info_t * info, int sect, uchar offset)
{
uchar * addr;
addr = flash_make_addr(info, sect, offset);
return ( (addr[(2*info->portwidth) - 1] << 24 ) | (addr[(info->portwidth) -1] << 16) |
(addr[(4*info->portwidth) - 1] << 8) | addr[(3*info->portwidth) - 1]);
}
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
unsigned long size;
int i;
unsigned long address;
/* The flash is positioned back to back, with the demultiplexing of the chip
* based on the A24 address line.
*
*/
address = CFG_FLASH_BASE;
size = 0;
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
size += flash_info[i].size = flash_get_size(address, i);
address += CFG_FLASH_INCREMENT;
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",i,
flash_info[0].size, flash_info[i].size<<20);
}
}
#if 0 /* test-only */
/* Monitor protection ON by default */
#if (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
for(i=0; flash_info[0].start[i] < CFG_MONITOR_BASE+CFG_MONITOR_LEN-1; i++)
(void)flash_real_protect(&flash_info[0], i, 1);
#endif
#else
/* monitor protection ON by default */
flash_protect (FLAG_PROTECT_SET,
- CFG_MONITOR_LEN,
- 1, &flash_info[1]);
#endif
return (size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
int rcode = 0;
int prot;
int sect;
if( info->flash_id != FLASH_MAN_CFI) {
printf ("Can't erase unknown flash type - aborted\n");
return 1;
}
if ((s_first < 0) || (s_first > s_last)) {
printf ("- no sectors to erase\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");
}
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
flash_write_cmd(info, sect, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd(info, sect, 0, FLASH_CMD_BLOCK_ERASE);
flash_write_cmd(info, sect, 0, FLASH_CMD_ERASE_CONFIRM);
if(flash_full_status_check(info, sect, info->erase_blk_tout, "erase")) {
rcode = 1;
} else
printf(".");
}
}
printf (" done\n");
return rcode;
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
if (info->flash_id != FLASH_MAN_CFI) {
printf ("missing or unknown FLASH type\n");
return;
}
printf("CFI conformant FLASH (%d x %d)",
(info->portwidth << 3 ), (info->chipwidth << 3 ));
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf(" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n",
info->erase_blk_tout, info->write_tout, info->buffer_write_tout, info->buffer_size);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
#ifdef CFG_FLASH_EMPTY_INFO
int k;
int size;
int erased;
volatile unsigned long *flash;
/*
* Check if whole sector is erased
*/
if (i != (info->sector_count-1))
size = info->start[i+1] - info->start[i];
else
size = info->start[0] + info->size - info->start[i];
erased = 1;
flash = (volatile unsigned long *)info->start[i];
size = size >> 2; /* divide by 4 for longword access */
for (k=0; k<size; k++)
{
if (*flash++ != 0xffffffff)
{
erased = 0;
break;
}
}
if ((i % 5) == 0)
printf ("\n ");
/* print empty and read-only info */
printf (" %08lX%s%s",
info->start[i],
erased ? " E" : " ",
info->protect[i] ? "RO " : " ");
#else
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " ");
#endif
}
printf ("\n");
return;
}
/*-----------------------------------------------------------------------
* 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 wp;
ulong cp;
int aln;
cfiword_t cword;
int i, rc;
/* get lower aligned address */
wp = (addr & ~(info->portwidth - 1));
/* handle unaligned start */
if((aln = addr - wp) != 0) {
cword.l = 0;
cp = wp;
for(i=0;i<aln; ++i, ++cp)
flash_add_byte(info, &cword, (*(uchar *)cp));
for(; (i< info->portwidth) && (cnt > 0) ; i++) {
flash_add_byte(info, &cword, *src++);
cnt--;
cp++;
}
for(; (cnt == 0) && (i < info->portwidth); ++i, ++cp)
flash_add_byte(info, &cword, (*(uchar *)cp));
if((rc = flash_write_cfiword(info, wp, cword)) != 0)
return rc;
wp = cp;
}
#ifdef CFG_FLASH_USE_BUFFER_WRITE
while(cnt >= info->portwidth) {
i = info->buffer_size > cnt? cnt: info->buffer_size;
if((rc = flash_write_cfibuffer(info, wp, src,i)) != ERR_OK)
return rc;
wp += i;
src += i;
cnt -=i;
}
#else
/* handle the aligned part */
while(cnt >= info->portwidth) {
cword.l = 0;
for(i = 0; i < info->portwidth; i++) {
flash_add_byte(info, &cword, *src++);
}
if((rc = flash_write_cfiword(info, wp, cword)) != 0)
return rc;
wp += info->portwidth;
cnt -= info->portwidth;
}
#endif /* CFG_FLASH_USE_BUFFER_WRITE */
if (cnt == 0) {
return (0);
}
/*
* handle unaligned tail bytes
*/
cword.l = 0;
for (i=0, cp=wp; (i<info->portwidth) && (cnt>0); ++i, ++cp) {
flash_add_byte(info, &cword, *src++);
--cnt;
}
for (; i<info->portwidth; ++i, ++cp) {
flash_add_byte(info, & cword, (*(uchar *)cp));
}
return flash_write_cfiword(info, wp, cword);
}
/*-----------------------------------------------------------------------
*/
int flash_real_protect(flash_info_t *info, long sector, int prot)
{
int retcode = 0;
flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT);
if(prot)
flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_SET);
else
flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
if((retcode = flash_full_status_check(info, sector, info->erase_blk_tout,
prot?"protect":"unprotect")) == 0) {
info->protect[sector] = prot;
/* Intel's unprotect unprotects all locking */
if(prot == 0) {
int i;
for(i = 0 ; i<info->sector_count; i++) {
if(info->protect[i])
flash_real_protect(info, i, 1);
}
}
}
return retcode;
}
/*-----------------------------------------------------------------------
* wait for XSR.7 to be set. Time out with an error if it does not.
* This routine does not set the flash to read-array mode.
*/
static int flash_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt)
{
ulong start;
/* Wait for command completion */
start = get_timer (0);
while(!flash_isset(info, sector, 0, FLASH_STATUS_DONE)) {
if (get_timer(start) > info->erase_blk_tout) {
printf("Flash %s timeout at address %lx\n", prompt, info->start[sector]);
flash_write_cmd(info, sector, 0, FLASH_CMD_RESET);
return ERR_TIMOUT;
}
}
return ERR_OK;
}
/*-----------------------------------------------------------------------
* Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check.
* This routine sets the flash to read-array mode.
*/
static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt)
{
int retcode;
retcode = flash_status_check(info, sector, tout, prompt);
if((retcode == ERR_OK) && !flash_isequal(info,sector, 0, FLASH_STATUS_DONE)) {
retcode = ERR_INVAL;
printf("Flash %s error at address %lx\n", prompt,info->start[sector]);
if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)){
printf("Command Sequence Error.\n");
} else if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS)){
printf("Block Erase Error.\n");
retcode = ERR_NOT_ERASED;
} else if (flash_isset(info, sector, 0, FLASH_STATUS_PSLBS)) {
printf("Locking Error\n");
}
if(flash_isset(info, sector, 0, FLASH_STATUS_DPS)){
printf("Block locked.\n");
retcode = ERR_PROTECTED;
}
if(flash_isset(info, sector, 0, FLASH_STATUS_VPENS))
printf("Vpp Low Error.\n");
}
flash_write_cmd(info, sector, 0, FLASH_CMD_RESET);
return retcode;
}
/*-----------------------------------------------------------------------
*/
static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c)
{
switch(info->portwidth) {
case FLASH_CFI_8BIT:
cword->c = c;
break;
case FLASH_CFI_16BIT:
cword->w = (cword->w << 8) | c;
break;
case FLASH_CFI_32BIT:
cword->l = (cword->l << 8) | c;
}
}
/*-----------------------------------------------------------------------
* make a proper sized command based on the port and chip widths
*/
static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf)
{
int i;
uchar *cp = (uchar *)cmdbuf;
for(i=0; i< info->portwidth; i++)
*cp++ = ((i+1) % info->chipwidth) ? '\0':cmd;
}
/*
* Write a proper sized command to the correct address
*/
static void flash_write_cmd(flash_info_t * info, int sect, uchar offset, uchar cmd)
{
volatile cfiptr_t addr;
cfiword_t cword;
addr.cp = flash_make_addr(info, sect, offset);
flash_make_cmd(info, cmd, &cword);
switch(info->portwidth) {
case FLASH_CFI_8BIT:
*addr.cp = cword.c;
break;
case FLASH_CFI_16BIT:
*addr.wp = cword.w;
break;
case FLASH_CFI_32BIT:
*addr.lp = cword.l;
break;
}
}
/*-----------------------------------------------------------------------
*/
static int flash_isequal(flash_info_t * info, int sect, uchar offset, uchar cmd)
{
cfiptr_t cptr;
cfiword_t cword;
int retval;
cptr.cp = flash_make_addr(info, sect, offset);
flash_make_cmd(info, cmd, &cword);
switch(info->portwidth) {
case FLASH_CFI_8BIT:
retval = (cptr.cp[0] == cword.c);
break;
case FLASH_CFI_16BIT:
retval = (cptr.wp[0] == cword.w);
break;
case FLASH_CFI_32BIT:
retval = (cptr.lp[0] == cword.l);
break;
default:
retval = 0;
break;
}
return retval;
}
/*-----------------------------------------------------------------------
*/
static int flash_isset(flash_info_t * info, int sect, uchar offset, uchar cmd)
{
cfiptr_t cptr;
cfiword_t cword;
int retval;
cptr.cp = flash_make_addr(info, sect, offset);
flash_make_cmd(info, cmd, &cword);
switch(info->portwidth) {
case FLASH_CFI_8BIT:
retval = ((cptr.cp[0] & cword.c) == cword.c);
break;
case FLASH_CFI_16BIT:
retval = ((cptr.wp[0] & cword.w) == cword.w);
break;
case FLASH_CFI_32BIT:
retval = ((cptr.lp[0] & cword.l) == cword.l);
break;
default:
retval = 0;
break;
}
return retval;
}
/*-----------------------------------------------------------------------
* detect if flash is compatible with the Common Flash Interface (CFI)
* http://www.jedec.org/download/search/jesd68.pdf
*
*/
static int flash_detect_cfi(flash_info_t * info)
{
for(info->portwidth=FLASH_CFI_8BIT; info->portwidth <= FLASH_CFI_32BIT;
info->portwidth <<= 1) {
for(info->chipwidth =FLASH_CFI_BY8;
info->chipwidth <= info->portwidth;
info->chipwidth <<= 1) {
flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
flash_write_cmd(info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI);
if(flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP,'Q') &&
flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R') &&
flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y'))
return 1;
}
}
return 0;
}
/*
* The following code cannot be run from FLASH!
*
*/
static ulong flash_get_size (ulong base, int banknum)
{
flash_info_t * info = &flash_info[banknum];
int i, j;
int sect_cnt;
unsigned long sector;
unsigned long tmp;
int size_ratio;
uchar num_erase_regions;
int erase_region_size;
int erase_region_count;
info->start[0] = base;
if(flash_detect_cfi(info)){
#ifdef DEBUG_FLASH
printf("portwidth=%d chipwidth=%d\n", info->portwidth, info->chipwidth); /* test-only */
#endif
size_ratio = info->portwidth / info->chipwidth;
num_erase_regions = flash_read_uchar(info, FLASH_OFFSET_NUM_ERASE_REGIONS);
#ifdef DEBUG_FLASH
printf("found %d erase regions\n", num_erase_regions);
#endif
sect_cnt = 0;
sector = base;
for(i = 0 ; i < num_erase_regions; i++) {
if(i > NUM_ERASE_REGIONS) {
printf("%d erase regions found, only %d used\n",
num_erase_regions, NUM_ERASE_REGIONS);
break;
}
tmp = flash_read_long(info, 0, FLASH_OFFSET_ERASE_REGIONS);
erase_region_size = (tmp & 0xffff)? ((tmp & 0xffff) * 256): 128;
tmp >>= 16;
erase_region_count = (tmp & 0xffff) +1;
for(j = 0; j< erase_region_count; j++) {
info->start[sect_cnt] = sector;
sector += (erase_region_size * size_ratio);
info->protect[sect_cnt] = flash_isset(info, sect_cnt, FLASH_OFFSET_PROTECT, FLASH_STATUS_PROTECT);
sect_cnt++;
}
}
info->sector_count = sect_cnt;
/* multiply the size by the number of chips */
info->size = (1 << flash_read_uchar(info, FLASH_OFFSET_SIZE)) * size_ratio;
info->buffer_size = (1 << flash_read_ushort(info, 0, FLASH_OFFSET_BUFFER_SIZE));
tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_ETOUT);
info->erase_blk_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_EMAX_TOUT)));
tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WBTOUT);
info->buffer_write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WBMAX_TOUT)));
tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WTOUT);
info->write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WMAX_TOUT)))/ 1000;
info->flash_id = FLASH_MAN_CFI;
}
flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
return(info->size);
}
/*-----------------------------------------------------------------------
*/
static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword)
{
cfiptr_t ctladdr;
cfiptr_t cptr;
int flag;
ctladdr.cp = flash_make_addr(info, 0, 0);
cptr.cp = (uchar *)dest;
/* Check if Flash is (sufficiently) erased */
switch(info->portwidth) {
case FLASH_CFI_8BIT:
flag = ((cptr.cp[0] & cword.c) == cword.c);
break;
case FLASH_CFI_16BIT:
flag = ((cptr.wp[0] & cword.w) == cword.w);
break;
case FLASH_CFI_32BIT:
flag = ((cptr.lp[0] & cword.l) == cword.l);
break;
default:
return 2;
}
if(!flag)
return 2;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
flash_write_cmd(info, 0, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd(info, 0, 0, FLASH_CMD_WRITE);
switch(info->portwidth) {
case FLASH_CFI_8BIT:
cptr.cp[0] = cword.c;
break;
case FLASH_CFI_16BIT:
cptr.wp[0] = cword.w;
break;
case FLASH_CFI_32BIT:
cptr.lp[0] = cword.l;
break;
}
/* re-enable interrupts if necessary */
if(flag)
enable_interrupts();
return flash_full_status_check(info, 0, info->write_tout, "write");
}
#ifdef CFG_FLASH_USE_BUFFER_WRITE
/* loop through the sectors from the highest address
* when the passed address is greater or equal to the sector address
* we have a match
*/
static int find_sector(flash_info_t *info, ulong addr)
{
int sector;
for(sector = info->sector_count - 1; sector >= 0; sector--) {
if(addr >= info->start[sector])
break;
}
return sector;
}
static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len)
{
int sector;
int cnt;
int retcode;
volatile cfiptr_t src;
volatile cfiptr_t dst;
src.cp = cp;
dst.cp = (uchar *)dest;
sector = find_sector(info, dest);
flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
if((retcode = flash_status_check(info, sector, info->buffer_write_tout,
"write to buffer")) == ERR_OK) {
switch(info->portwidth) {
case FLASH_CFI_8BIT:
cnt = len;
break;
case FLASH_CFI_16BIT:
cnt = len >> 1;
break;
case FLASH_CFI_32BIT:
cnt = len >> 2;
break;
default:
return ERR_INVAL;
break;
}
flash_write_cmd(info, sector, 0, (uchar)cnt-1);
while(cnt-- > 0) {
switch(info->portwidth) {
case FLASH_CFI_8BIT:
*dst.cp++ = *src.cp++;
break;
case FLASH_CFI_16BIT:
*dst.wp++ = *src.wp++;
break;
case FLASH_CFI_32BIT:
*dst.lp++ = *src.lp++;
break;
default:
return ERR_INVAL;
break;
}
}
flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_BUFFER_CONFIRM);
retcode = flash_full_status_check(info, sector, info->buffer_write_tout,
"buffer write");
}
flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
return retcode;
}
#endif /* CFG_USE_FLASH_BUFFER_WRITE */

147
board/sbc405/u-boot.lds Normal file
View File

@@ -0,0 +1,147 @@
/*
* (C) Copyright 2000, 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
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
{
.resetvec 0xFFFFFFFC :
{
*(.resetvec)
} = 0xffff
/* 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/ppc4xx/start.o (.text)
cpu/ppc4xx/traps.o (.text)
cpu/ppc4xx/interrupts.o (.text)
cpu/ppc4xx/serial.o (.text)
cpu/ppc4xx/cpu_init.o (.text)
cpu/ppc4xx/speed.o (.text)
cpu/ppc4xx/405gp_enet.o (.text)
common/dlmalloc.o (.text)
lib_generic/crc32.o (.text)
lib_ppc/extable.o (.text)
lib_generic/zlib.o (.text)
/* . = env_offset;*/
/* common/environment.o(.text)*/
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
*(.rodata.str1.4)
}
.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 = .);
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
__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

@@ -328,8 +328,9 @@ convert_env(void)
s = getenv("E");
if (s != NULL) {
sprintf(temp, "%c%c.%c%c.%c%c.%c%c.%c%c.%c%c",
*s++, *s++, *s++, *s++, *s++, *s++,
*s++, *s++, *s++, *s++, *s++, *s);
s[0], s[1], s[ 2], s[ 3],
s[4], s[5], s[ 6], s[ 7],
s[8], s[9], s[10], s[11] );
setenv("ethaddr", temp);
setenv("E", NULL);
}

View File

@@ -92,21 +92,21 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]);
}
#if defined(CONFIG_ETH1ADDR)
#if defined(CONFIG_HAS_ETH1)
puts ("\neth1addr =");
for (i=0; i<6; ++i) {
printf ("%c%02X", i ? ':' : ' ', bd->bi_enet1addr[i]);
}
#endif
#if defined(CONFIG_ETH2ADDR)
#if defined(CONFIG_HAS_ETH2)
puts ("\neth2addr =");
for (i=0; i<6; ++i) {
printf ("%c%02X", i ? ':' : ' ', bd->bi_enet2addr[i]);
}
#endif
#if defined(CONFIG_ETH3ADDR)
#if defined(CONFIG_HAS_ETH3)
puts ("\neth3addr =");
for (i=0; i<6; ++i) {
printf ("%c%02X", i ? ':' : ' ', bd->bi_enet3addr[i]);

View File

@@ -161,7 +161,7 @@ int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
char *filename = NULL;
char *ep;
int dev, part = 0;
int dev, part = 1;
ulong addr = 0, part_length, filelen;
disk_partition_t info;
block_dev_desc_t *dev_desc = NULL;

View File

@@ -164,6 +164,10 @@ flash_fill_sect_ranges (ulong addr_first, ulong addr_last,
sect = s_last[bank];
addr_first = (sect == s_end) ? b_end + 1: info->start[sect + 1];
(*s_count) += s_last[bank] - s_first[bank] + 1;
} else if (addr_first >= info->start[0] && addr_first < b_end) {
puts ("Error: start address not on sector boundary\n");
rcode = 1;
break;
} else if (s_last[bank] >= 0) {
puts ("Error: cannot span across banks when they are"
" mapped in reverse order\n");

View File

@@ -31,6 +31,7 @@
#include <net.h>
#endif
#include <fpga.h>
#include <malloc.h>
#if 0
#define FPGA_DEBUG
@@ -52,8 +53,122 @@ static int fpga_get_op (char *opstr);
#define FPGA_NONE -1
#define FPGA_INFO 0
#define FPGA_LOAD 1
#define FPGA_LOADB 2
#define FPGA_DUMP 3
/* Convert bitstream data and load into the fpga */
int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size)
{
int length;
char* swapdata;
int swapsize;
char buffer[80];
char *ptr;
char *dataptr;
int data;
int i;
int rc;
dataptr = fpgadata;
#if CFG_FPGA_XILINX
/* skip the first 13 bytes of the bitsteam, their meaning is unknown */
dataptr+=13;
/* get design name (identifier, length, string) */
if (*dataptr++ != 0x61) {
PRINTF("fpga_loadbitstream: Design name identifier not recognized in bitstream.\n");
return FPGA_FAIL;
}
length = (*dataptr << 8) + *(dataptr+1);
dataptr+=2;
for(i=0;i<length;i++)
buffer[i]=*dataptr++;
buffer[length-5]='\0'; /* remove filename extension */
PRINTF("fpga_loadbitstream: design name = \"%s\".\n",buffer);
/* get part number (identifier, length, string) */
if (*dataptr++ != 0x62) {
printf("fpga_loadbitstream: Part number identifier not recognized in bitstream.\n");
return FPGA_FAIL;
}
length = (*dataptr << 8) + *(dataptr+1); dataptr+=2;
for(i=0;i<length;i++)
buffer[i]=*dataptr++;
PRINTF("fpga_loadbitstream: part number = \"%s\".\n",buffer);
/* get date (identifier, length, string) */
if (*dataptr++ != 0x63) {
printf("fpga_loadbitstream: Date identifier not recognized in bitstream.\n");
return FPGA_FAIL;
}
length = (*dataptr << 8) + *(dataptr+1); dataptr+=2;
for(i=0;i<length;i++)
buffer[i]=*dataptr++;
PRINTF("fpga_loadbitstream: date = \"%s\".\n",buffer);
/* get time (identifier, length, string) */
if (*dataptr++ != 0x64) {
printf("fpga_loadbitstream: Time identifier not recognized in bitstream.\n");
return FPGA_FAIL;
}
length = (*dataptr << 8) + *(dataptr+1); dataptr+=2;
for(i=0;i<length;i++)
buffer[i]=*dataptr++;
PRINTF("fpga_loadbitstream: time = \"%s\".\n",buffer);
/* get fpga data length (identifier, length) */
if (*dataptr++ != 0x65) {
printf("fpga_loadbitstream: Data length identifier not recognized in bitstream.\n");
return FPGA_FAIL;
}
swapsize = ((long)*dataptr<<24) + ((long)*(dataptr+1)<<16) + ((long)*(dataptr+2)<<8) + (long)*(dataptr+3);
dataptr+=4;
PRINTF("fpga_loadbitstream: bytes in bitstream = %d.\n",swapsize);
/* check consistency of length obtained */
if (swapsize >= size) {
printf("fpga_loadbitstream: Could not find right length of data in bitstream.\n");
return FPGA_FAIL;
}
/* allocate memory */
swapdata = (char *)malloc(swapsize);
if (swapdata == NULL) {
printf("fpga_loadbitstream: Could not allocate %d bytes memory !\n",swapsize);
return FPGA_FAIL;
}
/* read data into memory and swap bits */
ptr = swapdata;
for (i = 0; i < swapsize; i++) {
data = 0x00;
data |= (*dataptr & 0x01) << 7;
data |= (*dataptr & 0x02) << 5;
data |= (*dataptr & 0x04) << 3;
data |= (*dataptr & 0x08) << 1;
data |= (*dataptr & 0x10) >> 1;
data |= (*dataptr & 0x20) >> 3;
data |= (*dataptr & 0x40) >> 5;
data |= (*dataptr & 0x80) >> 7;
*ptr++ = data;
dataptr++;
}
rc = fpga_load(dev, swapdata, swapsize);
free(swapdata);
return rc;
#else
printf("Bitstream support only for Xilinx devices.\n");
return FPGA_FAIL;
#endif
}
/* ------------------------------------------------------------------------- */
/* command form:
* fpga <op> <device number> <data addr> <datasize>
@@ -81,17 +196,16 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
data_size = simple_strtoul (argv[4], NULL, 16);
case 4: /* fpga <op> <dev> <data> */
fpga_data = (void *) simple_strtoul (argv[3], NULL, 16);
PRINTF (__FUNCTION__ ": fpga_data = 0x%x\n",
PRINTF ("do_fpga: fpga_data = 0x%x\n",
(uint) fpga_data);
case 3: /* fpga <op> <dev | data addr> */
dev = (int) simple_strtoul (argv[2], NULL, 16);
PRINTF (__FUNCTION__ ": device = %d\n", dev);
PRINTF ("do_fpga: device = %d\n", dev);
/* FIXME - this is a really weak test */
if ((argc == 3) && (dev > fpga_count ())) { /* must be buffer ptr */
PRINTF (__FUNCTION__
": Assuming buffer pointer in arg 3\n");
PRINTF ("do_fpga: Assuming buffer pointer in arg 3\n");
fpga_data = (void *) dev;
PRINTF (__FUNCTION__ ": fpga_data = 0x%x\n",
PRINTF ("do_fpga: fpga_data = 0x%x\n",
(uint) fpga_data);
dev = FPGA_INVALID_DEVICE; /* reset device num */
}
@@ -99,7 +213,7 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
op = (int) fpga_get_op (argv[1]);
break;
default:
PRINTF (__FUNCTION__ ": Too many or too few args (%d)\n",
PRINTF ("do_fpga: Too many or too few args (%d)\n",
argc);
op = FPGA_NONE; /* force usage display */
break;
@@ -118,6 +232,10 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
rc = fpga_load (dev, fpga_data, data_size);
break;
case FPGA_LOADB:
rc = fpga_loadbitstream(dev, fpga_data, data_size);
break;
case FPGA_DUMP:
rc = fpga_dump (dev, fpga_data, data_size);
break;
@@ -145,6 +263,8 @@ static int fpga_get_op (char *opstr)
if (!strcmp ("info", opstr)) {
op = FPGA_INFO;
} else if (!strcmp ("loadb", opstr)) {
op = FPGA_LOADB;
} else if (!strcmp ("load", opstr)) {
op = FPGA_LOAD;
} else if (!strcmp ("dump", opstr)) {
@@ -163,5 +283,6 @@ U_BOOT_CMD (fpga, 6, 1, do_fpga,
"fpga operations:\n"
"\tinfo\tlist known device information.\n"
"\tload\tLoad device from memory buffer.\n"
"\tloadb\tLoad device from bitstream buffer (Xilinx devices only).\n"
"\tdump\tLoad device to memory buffer.\n");
#endif /* CONFIG_FPGA && CONFIG_COMMANDS & CFG_CMD_FPGA */

View File

@@ -1,5 +1,5 @@
/*
* (C) Copyright 2000-2002
* (C) Copyright 2000-2005
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
@@ -62,17 +62,10 @@ static unsigned long mips_io_port_base = 0;
#ifdef __PPC__
# define EIEIO __asm__ volatile ("eieio")
# define SYNC __asm__ volatile ("sync")
#else
# define EIEIO /* nothing */
#endif
#undef IDE_DEBUG
#ifdef IDE_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
# define SYNC /* nothing */
#endif
#if (CONFIG_COMMANDS & CFG_CMD_IDE)
@@ -135,16 +128,16 @@ ulong ide_bus_offset[CFG_IDE_MAXBUS] = {
#define ATA_CURR_BASE(dev) (CFG_ATA_BASE_ADDR+ide_bus_offset[IDE_BUS(dev)])
#ifndef CONFIG_AMIGAONEG3SE
static int ide_bus_ok[CFG_IDE_MAXBUS];
static int ide_bus_ok[CFG_IDE_MAXBUS];
#else
static int ide_bus_ok[CFG_IDE_MAXBUS] = {0,};
static int ide_bus_ok[CFG_IDE_MAXBUS] = {0,};
#endif
block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE];
/* ------------------------------------------------------------------------- */
#ifdef CONFIG_IDE_LED
#if !defined(CONFIG_KUP4K) && !defined(CONFIG_KUP4X) &&!defined(CONFIG_BMS2003)
#if !defined(CONFIG_KUP4K) && !defined(CONFIG_KUP4X) &&!defined(CONFIG_BMS2003) &&!defined(CONFIG_CPC45)
static void ide_led (uchar led, uchar status);
#else
extern void ide_led (uchar led, uchar status);
@@ -374,8 +367,7 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
char *boot_device = NULL;
char *ep;
int dev, part = 0;
ulong cnt;
ulong addr;
ulong addr, cnt, checksum;
disk_partition_t info;
image_header_t *hdr;
int rcode = 0;
@@ -438,7 +430,7 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
"Name: %.32s Type: %.32s\n",
dev, part, info.name, info.type);
PRINTF ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n",
debug ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n",
info.start, info.size, info.blksz);
if (ide_dev_desc[dev].block_read (dev, info.start, 1, (ulong *)addr) != 1) {
@@ -449,20 +441,28 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
hdr = (image_header_t *)addr;
if (ntohl(hdr->ih_magic) == IH_MAGIC) {
print_image_hdr (hdr);
cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
cnt += info.blksz - 1;
cnt /= info.blksz;
cnt -= 1;
} else {
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
printf("\n** Bad Magic Number **\n");
SHOW_BOOT_PROGRESS (-1);
return 1;
}
checksum = ntohl(hdr->ih_hcrc);
hdr->ih_hcrc = 0;
if (crc32 (0, (char *)&hdr, sizeof(image_header_t)) != checksum) {
puts ("\n** Bad Header Checksum **\n");
SHOW_BOOT_PROGRESS (-2);
return 1;
}
print_image_hdr (hdr);
cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
cnt += info.blksz - 1;
cnt /= info.blksz;
cnt -= 1;
if (ide_dev_desc[dev].block_read (dev, info.start+1, cnt,
(ulong *)(addr+info.blksz)) != cnt) {
printf ("** Read error on %d:%d\n", dev, part);
@@ -542,19 +542,19 @@ void ide_init (void)
#ifdef CONFIG_IDE_8xx_DIRECT
/* Initialize PIO timing tables */
for (i=0; i <= IDE_MAX_PIO_MODE; ++i) {
pio_config_clk[i].t_setup = PCMCIA_MK_CLKS(pio_config_ns[i].t_setup,
gd->bus_clk);
pio_config_clk[i].t_length = PCMCIA_MK_CLKS(pio_config_ns[i].t_length,
gd->bus_clk);
pio_config_clk[i].t_hold = PCMCIA_MK_CLKS(pio_config_ns[i].t_hold,
gd->bus_clk);
PRINTF ("PIO Mode %d: setup=%2d ns/%d clk"
" len=%3d ns/%d clk"
" hold=%2d ns/%d clk\n",
i,
pio_config_ns[i].t_setup, pio_config_clk[i].t_setup,
pio_config_ns[i].t_length, pio_config_clk[i].t_length,
pio_config_ns[i].t_hold, pio_config_clk[i].t_hold);
pio_config_clk[i].t_setup = PCMCIA_MK_CLKS(pio_config_ns[i].t_setup,
gd->bus_clk);
pio_config_clk[i].t_length = PCMCIA_MK_CLKS(pio_config_ns[i].t_length,
gd->bus_clk);
pio_config_clk[i].t_hold = PCMCIA_MK_CLKS(pio_config_ns[i].t_hold,
gd->bus_clk);
debug ( "PIO Mode %d: setup=%2d ns/%d clk"
" len=%3d ns/%d clk"
" hold=%2d ns/%d clk\n",
i,
pio_config_ns[i].t_setup, pio_config_clk[i].t_setup,
pio_config_ns[i].t_length, pio_config_clk[i].t_length,
pio_config_ns[i].t_hold, pio_config_clk[i].t_hold);
}
#endif /* CONFIG_IDE_8xx_DIRECT */
@@ -583,9 +583,9 @@ void ide_init (void)
#else
s = getenv("ide_maxbus");
if (s)
max_bus_scan = simple_strtol(s, NULL, 10);
max_bus_scan = simple_strtol(s, NULL, 10);
else
max_bus_scan = CFG_IDE_MAXBUS;
max_bus_scan = CFG_IDE_MAXBUS;
for (bus=0; bus<max_bus_scan; ++bus) {
int dev = bus * (CFG_IDE_MAXDEVICE / max_bus_scan);
@@ -628,8 +628,8 @@ void ide_init (void)
#ifdef CONFIG_AMIGAONEG3SE
/* If this is the second bus, the first one was OK */
if (bus != 0) {
ide_bus_ok[bus] = 0;
goto skip_bus;
ide_bus_ok[bus] = 0;
goto skip_bus;
}
#endif
return;
@@ -641,11 +641,11 @@ void ide_init (void)
if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
puts ("not available ");
PRINTF ("Status = 0x%02X ", c);
debug ("Status = 0x%02X ", c);
#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */
} else if ((c & ATA_STAT_READY) == 0) {
puts ("not available ");
PRINTF ("Status = 0x%02X ", c);
debug ("Status = 0x%02X ", c);
#endif
} else {
puts ("OK ");
@@ -706,7 +706,7 @@ set_pcmcia_timing (int pmode)
volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia);
ulong timings;
PRINTF ("Set timing for PIO Mode %d\n", pmode);
debug ("Set timing for PIO Mode %d\n", pmode);
timings = PCMCIA_SHT(pio_config_clk[pmode].t_hold)
| PCMCIA_SST(pio_config_clk[pmode].t_setup)
@@ -721,7 +721,7 @@ set_pcmcia_timing (int pmode)
| timings
#endif
;
PRINTF ("PBR0: %08x POR0: %08x\n", pcmp->pcmc_pbr0, pcmp->pcmc_por0);
debug ("PBR0: %08x POR0: %08x\n", pcmp->pcmc_pbr0, pcmp->pcmc_por0);
pcmp->pcmc_pbr1 = CFG_PCMCIA_PBR1;
pcmp->pcmc_por1 = CFG_PCMCIA_POR1
@@ -729,7 +729,7 @@ set_pcmcia_timing (int pmode)
| timings
#endif
;
PRINTF ("PBR1: %08x POR1: %08x\n", pcmp->pcmc_pbr1, pcmp->pcmc_por1);
debug ("PBR1: %08x POR1: %08x\n", pcmp->pcmc_pbr1, pcmp->pcmc_por1);
pcmp->pcmc_pbr2 = CFG_PCMCIA_PBR2;
pcmp->pcmc_por2 = CFG_PCMCIA_POR2
@@ -737,7 +737,7 @@ set_pcmcia_timing (int pmode)
| timings
#endif
;
PRINTF ("PBR2: %08x POR2: %08x\n", pcmp->pcmc_pbr2, pcmp->pcmc_por2);
debug ("PBR2: %08x POR2: %08x\n", pcmp->pcmc_pbr2, pcmp->pcmc_por2);
pcmp->pcmc_pbr3 = CFG_PCMCIA_PBR3;
pcmp->pcmc_por3 = CFG_PCMCIA_POR3
@@ -745,7 +745,7 @@ set_pcmcia_timing (int pmode)
| timings
#endif
;
PRINTF ("PBR3: %08x POR3: %08x\n", pcmp->pcmc_pbr3, pcmp->pcmc_por3);
debug ("PBR3: %08x POR3: %08x\n", pcmp->pcmc_pbr3, pcmp->pcmc_por3);
/* IDE 1
*/
@@ -755,7 +755,7 @@ set_pcmcia_timing (int pmode)
| timings
#endif
;
PRINTF ("PBR4: %08x POR4: %08x\n", pcmp->pcmc_pbr4, pcmp->pcmc_por4);
debug ("PBR4: %08x POR4: %08x\n", pcmp->pcmc_pbr4, pcmp->pcmc_por4);
pcmp->pcmc_pbr5 = CFG_PCMCIA_PBR5;
pcmp->pcmc_por5 = CFG_PCMCIA_POR5
@@ -763,7 +763,7 @@ set_pcmcia_timing (int pmode)
| timings
#endif
;
PRINTF ("PBR5: %08x POR5: %08x\n", pcmp->pcmc_pbr5, pcmp->pcmc_por5);
debug ("PBR5: %08x POR5: %08x\n", pcmp->pcmc_pbr5, pcmp->pcmc_por5);
pcmp->pcmc_pbr6 = CFG_PCMCIA_PBR6;
pcmp->pcmc_por6 = CFG_PCMCIA_POR6
@@ -771,7 +771,7 @@ set_pcmcia_timing (int pmode)
| timings
#endif
;
PRINTF ("PBR6: %08x POR6: %08x\n", pcmp->pcmc_pbr6, pcmp->pcmc_por6);
debug ("PBR6: %08x POR6: %08x\n", pcmp->pcmc_pbr6, pcmp->pcmc_por6);
pcmp->pcmc_pbr7 = CFG_PCMCIA_PBR7;
pcmp->pcmc_por7 = CFG_PCMCIA_POR7
@@ -779,7 +779,7 @@ set_pcmcia_timing (int pmode)
| timings
#endif
;
PRINTF ("PBR7: %08x POR7: %08x\n", pcmp->pcmc_pbr7, pcmp->pcmc_por7);
debug ("PBR7: %08x POR7: %08x\n", pcmp->pcmc_pbr7, pcmp->pcmc_por7);
}
@@ -791,7 +791,7 @@ set_pcmcia_timing (int pmode)
static void __inline__
ide_outb(int dev, int port, unsigned char val)
{
PRINTF ("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
debug ("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
dev, port, val, (ATA_CURR_BASE(dev)+port));
/* Ensure I/O operations complete */
@@ -815,7 +815,7 @@ ide_inb(int dev, int port)
/* Ensure I/O operations complete */
EIEIO;
val = *((uchar *)(ATA_CURR_BASE(dev)+port));
PRINTF ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n",
debug ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n",
dev, port, (ATA_CURR_BASE(dev)+port), val);
return (val);
}
@@ -844,7 +844,7 @@ output_data_short(int dev, ulong *sect_buf, int words)
}
if (words&1)
*pbuf = 0;
*pbuf = 0;
}
# endif /* CONFIG_AMIGAONEG3SE */
#endif /* __PPC_ */
@@ -857,17 +857,7 @@ output_data_short(int dev, ulong *sect_buf, int words)
static void
input_swap_data(int dev, ulong *sect_buf, int words)
{
#ifndef CONFIG_HMI10
volatile ushort *pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
ushort *dbuf = (ushort *)sect_buf;
PRINTF("in input swap data base for read is %lx\n", (unsigned long) pbuf);
while (words--) {
*dbuf++ = ld_le16(pbuf);
*dbuf++ = ld_le16(pbuf);
}
#else /* CONFIG_HMI10 */
#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45)
uchar i;
volatile uchar *pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN);
volatile uchar *pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD);
@@ -880,7 +870,17 @@ input_swap_data(int dev, ulong *sect_buf, int words)
dbuf+=1;
}
}
#endif /* CONFIG_HMI10 */
#else
volatile ushort *pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
ushort *dbuf = (ushort *)sect_buf;
debug("in input swap data base for read is %lx\n", (unsigned long) pbuf);
while (words--) {
*dbuf++ = ld_le16(pbuf);
*dbuf++ = ld_le16(pbuf);
}
#endif
}
#endif /* __LITTLE_ENDIAN || CONFIG_AU1X00 */
@@ -889,19 +889,7 @@ input_swap_data(int dev, ulong *sect_buf, int words)
static void
output_data(int dev, ulong *sect_buf, int words)
{
#ifndef CONFIG_HMI10
ushort *dbuf;
volatile ushort *pbuf;
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
while (words--) {
EIEIO;
*pbuf = *dbuf++;
EIEIO;
*pbuf = *dbuf++;
}
#else /* CONFIG_HMI10 */
#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45)
uchar *dbuf;
volatile uchar *pbuf_even;
volatile uchar *pbuf_odd;
@@ -919,7 +907,19 @@ output_data(int dev, ulong *sect_buf, int words)
EIEIO;
*pbuf_odd = *dbuf++;
}
#endif /* CONFIG_HMI10 */
#else
ushort *dbuf;
volatile ushort *pbuf;
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
while (words--) {
EIEIO;
*pbuf = *dbuf++;
EIEIO;
*pbuf = *dbuf++;
}
#endif
}
#else /* ! __PPC__ */
static void
@@ -933,22 +933,7 @@ output_data(int dev, ulong *sect_buf, int words)
static void
input_data(int dev, ulong *sect_buf, int words)
{
#ifndef CONFIG_HMI10
ushort *dbuf;
volatile ushort *pbuf;
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
PRINTF("in input data base for read is %lx\n", (unsigned long) pbuf);
while (words--) {
EIEIO;
*dbuf++ = *pbuf;
EIEIO;
*dbuf++ = *pbuf;
}
#else /* CONFIG_HMI10 */
#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45)
uchar *dbuf;
volatile uchar *pbuf_even;
volatile uchar *pbuf_odd;
@@ -957,16 +942,35 @@ input_data(int dev, ulong *sect_buf, int words)
pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD);
dbuf = (uchar *)sect_buf;
while (words--) {
EIEIO;
*dbuf++ = *pbuf_even;
EIEIO;
SYNC;
*dbuf++ = *pbuf_odd;
EIEIO;
SYNC;
*dbuf++ = *pbuf_even;
EIEIO;
SYNC;
*dbuf++ = *pbuf_odd;
EIEIO;
SYNC;
}
#endif /* CONFIG_HMI10 */
#else
ushort *dbuf;
volatile ushort *pbuf;
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
debug("in input data base for read is %lx\n", (unsigned long) pbuf);
while (words--) {
EIEIO;
*dbuf++ = *pbuf;
EIEIO;
*dbuf++ = *pbuf;
}
#endif
}
#else /* ! __PPC__ */
static void
@@ -993,8 +997,8 @@ input_data_short(int dev, ulong *sect_buf, int words)
}
if (words&1) {
ushort dummy;
dummy = *pbuf;
ushort dummy;
dummy = *pbuf;
}
}
#endif
@@ -1083,14 +1087,14 @@ static void ide_ident (block_dev_desc_t *dev_desc)
s = getenv("ide_doreset");
if (s && strcmp(s, "on") == 0)
#endif
{
/* Need to soft reset the device in case it's an ATAPI... */
PRINTF("Retrying...\n");
ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
udelay(100000);
ide_outb (device, ATA_COMMAND, 0x08);
udelay (500000); /* 500 ms */
}
{
/* Need to soft reset the device in case it's an ATAPI... */
debug ("Retrying...\n");
ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
udelay(100000);
ide_outb (device, ATA_COMMAND, 0x08);
udelay (500000); /* 500 ms */
}
/* Select device
*/
ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
@@ -1140,16 +1144,16 @@ static void ide_ident (block_dev_desc_t *dev_desc)
printf ("tPIO = 0x%02x = %d\n",mode, mode);
if (mode > 2) { /* 2 is maximum allowed tPIO value */
mode = 2;
PRINTF ("Override tPIO -> 2\n");
debug ("Override tPIO -> 2\n");
}
if (iop->field_valid & 2) { /* drive implements ATA2? */
PRINTF ("Drive implements ATA2\n");
debug ("Drive implements ATA2\n");
if (iop->capability & 8) { /* drive supports use_iordy? */
cycle_time = iop->eide_pio_iordy;
} else {
cycle_time = iop->eide_pio;
}
PRINTF ("cycle time = %d\n", cycle_time);
debug ("cycle time = %d\n", cycle_time);
mode = 4;
if (cycle_time > 120) mode = 3; /* 120 ns for PIO mode 4 */
if (cycle_time > 180) mode = 2; /* 180 ns for PIO mode 3 */
@@ -1204,8 +1208,7 @@ static void ide_ident (block_dev_desc_t *dev_desc)
ide_outb (device, ATA_LBA_LOW, 0);
ide_outb (device, ATA_LBA_MID, 0);
ide_outb (device, ATA_LBA_HIGH, 0);
ide_outb (device, ATA_DEV_HD, ATA_LBA |
ATA_DEVICE(device));
ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
ide_outb (device, ATA_COMMAND, 0xe3);
udelay (50);
c = ide_wait (device, IDE_TIME_OUT); /* can't take over 500 ms */
@@ -1228,7 +1231,7 @@ ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer)
lba48 = 1;
}
#endif
PRINTF ("ide_read dev %d start %qX, blocks %lX buffer at %lX\n",
debug ("ide_read dev %d start %qX, blocks %lX buffer at %lX\n",
device, blknr, blkcnt, (ulong)buffer);
ide_led (DEVICE_LED(device), 1); /* LED on */
@@ -1258,7 +1261,7 @@ ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer)
printf ("No Powersaving mode %X\n", c);
} else {
c = ide_inb(device,ATA_SECT_CNT);
PRINTF("Powersaving %02X\n",c);
debug ("Powersaving %02X\n",c);
if(c==0)
pwrsave=1;
}
@@ -1548,11 +1551,12 @@ static void ide_reset (void)
/* ------------------------------------------------------------------------- */
#if defined(CONFIG_IDE_LED) && \
!defined(CONFIG_AMIGAONEG3SE) && \
!defined(CONFIG_KUP4K) && \
!defined(CONFIG_KUP4X) && \
!defined(CONFIG_HMI10)
#if defined(CONFIG_IDE_LED) && \
!defined(CONFIG_AMIGAONEG3SE)&& \
!defined(CONFIG_CPC45) && \
!defined(CONFIG_HMI10) && \
!defined(CONFIG_KUP4K) && \
!defined(CONFIG_KUP4X)
static uchar led_buffer = 0; /* Buffer for current LED status */
@@ -1578,35 +1582,13 @@ static void ide_led (uchar led, uchar status)
* ATAPI Support
*/
#undef ATAPI_DEBUG
#ifdef ATAPI_DEBUG
#define AT_PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define AT_PRINTF(fmt,args...)
#endif
#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA)
/* since ATAPI may use commands with not 4 bytes alligned length
* we have our own transfer functions, 2 bytes alligned */
static void
output_data_shorts(int dev, ushort *sect_buf, int shorts)
{
#ifndef CONFIG_HMI10
ushort *dbuf;
volatile ushort *pbuf;
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
PRINTF("in output data shorts base for read is %lx\n", (unsigned long) pbuf);
while (shorts--) {
EIEIO;
*pbuf = *dbuf++;
}
#else /* CONFIG_HMI10 */
#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45)
uchar *dbuf;
volatile uchar *pbuf_even;
volatile uchar *pbuf_odd;
@@ -1619,26 +1601,26 @@ output_data_shorts(int dev, ushort *sect_buf, int shorts)
EIEIO;
*pbuf_odd = *dbuf++;
}
#endif /* CONFIG_HMI10 */
}
static void
input_data_shorts(int dev, ushort *sect_buf, int shorts)
{
#ifndef CONFIG_HMI10
#else
ushort *dbuf;
volatile ushort *pbuf;
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
PRINTF("in input data shorts base for read is %lx\n", (unsigned long) pbuf);
debug ("in output data shorts base for read is %lx\n", (unsigned long) pbuf);
while (shorts--) {
EIEIO;
*dbuf++ = *pbuf;
*pbuf = *dbuf++;
}
#else /* CONFIG_HMI10 */
#endif
}
static void
input_data_shorts(int dev, ushort *sect_buf, int shorts)
{
#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45)
uchar *dbuf;
volatile uchar *pbuf_even;
volatile uchar *pbuf_odd;
@@ -1651,7 +1633,20 @@ input_data_shorts(int dev, ushort *sect_buf, int shorts)
EIEIO;
*dbuf++ = *pbuf_odd;
}
#endif /* CONFIG_HMI10 */
#else
ushort *dbuf;
volatile ushort *pbuf;
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
debug("in input data shorts base for read is %lx\n", (unsigned long) pbuf);
while (shorts--) {
EIEIO;
*dbuf++ = *pbuf;
}
#endif
}
#else /* ! __PPC__ */
@@ -1661,7 +1656,6 @@ output_data_shorts(int dev, ushort *sect_buf, int shorts)
outsw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, shorts);
}
static void
input_data_shorts(int dev, ushort *sect_buf, int shorts)
{
@@ -1755,7 +1749,7 @@ unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned cha
if ((c & mask) != res ) {
if (c & ATA_STAT_ERR) {
err=(ide_inb(device,ATA_ERROR_REG))>>4;
AT_PRINTF("atapi_issue 1 returned sense key %X status %02X\n",err,c);
debug ("atapi_issue 1 returned sense key %X status %02X\n",err,c);
} else {
printf ("ATTAPI_ISSUE: (no DRQ) after sending ccb (%x) status 0x%02x\n", ccb[0],c);
err=0xFF;
@@ -1776,18 +1770,18 @@ unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned cha
goto AI_OUT;
}
if(n!=buflen) {
AT_PRINTF("WARNING, transfer bytes %d not equal with requested %d\n",n,buflen);
debug ("WARNING, transfer bytes %d not equal with requested %d\n",n,buflen);
}
if(n!=0) { /* data transfer */
AT_PRINTF("ATAPI_ISSUE: %d Bytes to transfer\n",n);
debug ("ATAPI_ISSUE: %d Bytes to transfer\n",n);
/* we transfer shorts */
n>>=1;
/* ok now decide if it is an in or output */
if ((ide_inb(device, ATA_SECT_CNT)&0x02)==0) {
AT_PRINTF("Write to device\n");
debug ("Write to device\n");
output_data_shorts(device,(unsigned short *)buffer,n);
} else {
AT_PRINTF("Read from device @ %p shorts %d\n",buffer,n);
debug ("Read from device @ %p shorts %d\n",buffer,n);
input_data_shorts(device,(unsigned short *)buffer,n);
}
}
@@ -1797,7 +1791,7 @@ unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned cha
c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res);
if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
err=(ide_inb(device,ATA_ERROR_REG) >> 4);
AT_PRINTF("atapi_issue 2 returned sense key %X status %X\n",err,c);
debug ("atapi_issue 2 returned sense key %X status %X\n",err,c);
} else {
err = 0;
}
@@ -1845,7 +1839,7 @@ retry:
if (res==0xFF)
return (0xFF); /* error */
AT_PRINTF("(auto_req)atapi_issue returned sense key %X\n",res);
debug ("(auto_req)atapi_issue returned sense key %X\n",res);
memset(sense_ccb,0,sizeof(sense_ccb));
memset(sense_data,0,sizeof(sense_data));
@@ -1857,8 +1851,8 @@ retry:
asc=(sense_data[12]);
ascq=(sense_data[13]);
AT_PRINTF("ATAPI_CMD_REQ_SENSE returned %x\n",res);
AT_PRINTF(" Sense page: %02X key %02X ASC %02X ASCQ %02X\n",
debug ("ATAPI_CMD_REQ_SENSE returned %x\n",res);
debug (" Sense page: %02X key %02X ASC %02X ASCQ %02X\n",
sense_data[0],
key,
asc,
@@ -1884,13 +1878,13 @@ retry:
goto error;
}
if(asc==0x3a) {
AT_PRINTF("Media not present\n");
debug ("Media not present\n");
goto error;
}
#ifdef CONFIG_AMIGAONEG3SE
if ((sense_data[2]&0xF)==0x0B) {
AT_PRINTF("ABORTED COMMAND...retry\n");
debug ("ABORTED COMMAND...retry\n");
if (retrycnt++ < 4)
goto retry;
return (0xFF);
@@ -1899,7 +1893,7 @@ retry:
if ((sense_data[2]&0xf) == 0x02 &&
sense_data[12] == 0x04 &&
sense_data[13] == 0x01 ) {
AT_PRINTF("Waiting for unit to become active\n");
debug ("Waiting for unit to become active\n");
udelay(timeout);
if (retrycnt++ < 4)
goto retry;
@@ -1909,7 +1903,7 @@ retry:
printf ("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq);
error:
AT_PRINTF ("ERROR Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq);
debug ("ERROR Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq);
return (0xFF);
}
@@ -1932,7 +1926,7 @@ static void atapi_inquiry(block_dev_desc_t * dev_desc)
ccb[4]=40; /* allocation Legnth */
c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,40);
AT_PRINTF("ATAPI_CMD_INQUIRY returned %x\n",c);
debug ("ATAPI_CMD_INQUIRY returned %x\n",c);
if (c!=0)
return;
@@ -1958,7 +1952,7 @@ static void atapi_inquiry(block_dev_desc_t * dev_desc)
c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,0);
AT_PRINTF("ATAPI_CMD_START_STOP returned %x\n",c);
debug ("ATAPI_CMD_START_STOP returned %x\n",c);
if (c!=0)
return;
@@ -1966,7 +1960,7 @@ static void atapi_inquiry(block_dev_desc_t * dev_desc)
memset(iobuf,0,sizeof(iobuf));
c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,0);
AT_PRINTF("ATAPI_CMD_UNIT_TEST_READY returned %x\n",c);
debug ("ATAPI_CMD_UNIT_TEST_READY returned %x\n",c);
if (c!=0)
return;
@@ -1974,11 +1968,11 @@ static void atapi_inquiry(block_dev_desc_t * dev_desc)
memset(iobuf,0,sizeof(iobuf));
ccb[0]=ATAPI_CMD_READ_CAP;
c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,8);
AT_PRINTF("ATAPI_CMD_READ_CAP returned %x\n",c);
debug ("ATAPI_CMD_READ_CAP returned %x\n",c);
if (c!=0)
return;
AT_PRINTF("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n",
debug ("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n",
iobuf[0],iobuf[1],iobuf[2],iobuf[3],
iobuf[4],iobuf[5],iobuf[6],iobuf[7]);
@@ -2012,7 +2006,7 @@ ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer)
unsigned char ccb[12]; /* Command descriptor block */
ulong cnt;
AT_PRINTF("atapi_read dev %d start %lX, blocks %lX buffer at %lX\n",
debug ("atapi_read dev %d start %lX, blocks %lX buffer at %lX\n",
device, blknr, blkcnt, (ulong)buffer);
do {

View File

@@ -67,6 +67,8 @@
#include <asm/arch/pxa-regs.h>
#endif
#include <asm/io.h>
#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
@@ -540,9 +542,18 @@ static int check_ide_device (int slot)
ide_devices_found |= (1 << slot);
#if CONFIG_CPC45
#else
/* set I/O area in config reg -> only valid for ARGOSY D5!!! */
*((uchar *)(addr + config_base)) = 1;
#endif
#if 0
printf("\n## Config_base = %04x ###\n", config_base);
printf("Configuration Option Register: %02x @ %x\n", readb(addr + config_base), addr + config_base);
printf("Card Configuration and Status Register: %02x\n", readb(addr + config_base + 2));
printf("Pin Replacement Register Register: %02x\n", readb(addr + config_base + 4));
printf("Socket and Copy Register: %02x\n", readb(addr + config_base + 6));
#endif
return (0);
}
#endif /* CONFIG_IDE_8xx_PCCARD */

View File

@@ -27,7 +27,6 @@
/*
* SCSI support.
*/
#include <common.h>
#include <command.h>
#include <asm/processor.h>
@@ -35,15 +34,6 @@
#include <image.h>
#include <pci.h>
#undef SCSI_DEBUG
#ifdef SCSI_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
#ifdef CONFIG_SCSI_SYM53C8XX
@@ -120,7 +110,7 @@ void scsi_scan(int mode)
scsi_setup_inquiry(pccb);
if(scsi_exec(pccb)!=TRUE) {
if(pccb->contr_stat==SCSI_SEL_TIME_OUT) {
PRINTF("Selection timeout ID %d\n",pccb->target);
debug ("Selection timeout ID %d\n",pccb->target);
continue; /* selection timeout => assuming no device present */
}
scsi_print_error(pccb);
@@ -211,8 +201,7 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
char *boot_device = NULL;
char *ep;
int dev, part = 0;
ulong cnt;
ulong addr;
ulong addr, cnt, checksum;
disk_partition_t info;
image_header_t *hdr;
int rcode = 0;
@@ -270,7 +259,7 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
"Name: %.32s Type: %.32s\n",
dev, part, info.name, info.type);
PRINTF ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n",
debug ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n",
info.start, info.size, info.blksz);
if (scsi_read (dev, info.start, 1, (ulong *)addr) != 1) {
@@ -280,18 +269,26 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
hdr = (image_header_t *)addr;
if (hdr->ih_magic == IH_MAGIC) {
print_image_hdr (hdr);
cnt = (hdr->ih_size + sizeof(image_header_t));
cnt += info.blksz - 1;
cnt /= info.blksz;
cnt -= 1;
} else {
if (ntohl(hdr->ih_magic) == IH_MAGIC) {
printf("\n** Bad Magic Number **\n");
return 1;
}
checksum = ntohl(hdr->ih_hcrc);
hdr->ih_hcrc = 0;
if (crc32 (0, (char *)hdr, sizeof(image_header_t)) != checksum) {
puts ("\n** Bad Header Checksum **\n");
return 1;
}
hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */
print_image_hdr (hdr);
cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
cnt += info.blksz - 1;
cnt /= info.blksz;
cnt -= 1;
if (scsi_read (dev, info.start+1, cnt,
(ulong *)(addr+info.blksz)) != cnt) {
printf ("** Read error on %d:%d\n", dev, part);
@@ -359,7 +356,7 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
ok++;
if (dev)
printf("\n");
PRINTF("print_part of %x\n",dev);
debug ("print_part of %x\n",dev);
print_part(&scsi_dev_desc[dev]);
}
}
@@ -435,7 +432,7 @@ ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer)
buf_addr=(unsigned long)buffer;
start=blknr;
blks=blkcnt;
PRINTF("\nscsi_read: dev %d startblk %lx, blccnt %lx buffer %lx\n",device,start,blks,(unsigned long)buffer);
debug ("\nscsi_read: dev %d startblk %lx, blccnt %lx buffer %lx\n",device,start,blks,(unsigned long)buffer);
do {
pccb->pdata=(unsigned char *)buf_addr;
if(blks>SCSI_MAX_READ_BLK) {
@@ -452,7 +449,7 @@ ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer)
start+=blks;
blks=0;
}
PRINTF("scsi_read_ext: startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr);
debug ("scsi_read_ext: startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr);
if(scsi_exec(pccb)!=TRUE) {
scsi_print_error(pccb);
blkcnt-=blks;
@@ -460,7 +457,7 @@ ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer)
}
buf_addr+=pccb->datalen;
} while(blks!=0);
PRINTF("scsi_read_ext: end startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr);
debug ("scsi_read_ext: end startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr);
return(blkcnt);
}
@@ -551,7 +548,7 @@ void scsi_setup_read_ext(ccb * pccb, unsigned long start, unsigned short blocks)
pccb->cmd[6]=0;
pccb->cmdlen=10;
pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
PRINTF("scsi_setup_read_ext: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
debug ("scsi_setup_read_ext: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
pccb->cmd[0],pccb->cmd[1],
pccb->cmd[2],pccb->cmd[3],pccb->cmd[4],pccb->cmd[5],
pccb->cmd[7],pccb->cmd[8]);
@@ -567,7 +564,7 @@ void scsi_setup_read6(ccb * pccb, unsigned long start, unsigned short blocks)
pccb->cmd[5]=0;
pccb->cmdlen=6;
pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
PRINTF("scsi_setup_read6: cmd: %02X %02X startblk %02X%02X blccnt %02X\n",
debug ("scsi_setup_read6: cmd: %02X %02X startblk %02X%02X blccnt %02X\n",
pccb->cmd[0],pccb->cmd[1],
pccb->cmd[2],pccb->cmd[3],pccb->cmd[4]);
}

View File

@@ -28,20 +28,8 @@
#include <universe.h>
#if (CONFIG_COMMANDS & CFG_CMD_UNIVERSE)
#undef DBG
#ifdef DBG
# define UNI_DBG(fmt) printf fmt
#else
# define UNI_DBG(fmt)
#endif
#define UNI_PRINT(fmt) printf fmt
#define PCI_VENDOR PCI_VENDOR_ID_TUNDRA
#define PCI_DEVICE PCI_DEVICE_ID_TUNDRA_CA91C042
@@ -87,18 +75,18 @@ int universe_init(void)
val &= ~0xf;
dev->uregs = (UNIVERSE *)val;
UNI_DBG(("UNIVERSE-Base : %p\n", dev->uregs));
debug ("UNIVERSE-Base : %p\n", dev->uregs);
/* check mapping */
UNI_DBG((" Read via mapping, PCI_ID = %08X\n", readl(&dev->uregs->pci_id)));
debug (" Read via mapping, PCI_ID = %08X\n", readl(&dev->uregs->pci_id));
if (((PCI_DEVICE <<16) | PCI_VENDOR) != readl(&dev->uregs->pci_id)) {
UNI_PRINT(("UNIVERSE: Cannot read PCI-ID via Mapping: %08x\n",
readl(&dev->uregs->pci_id)));
printf ("UNIVERSE: Cannot read PCI-ID via Mapping: %08x\n",
readl(&dev->uregs->pci_id));
result = -1;
goto break_30;
}
UNI_DBG(("PCI_BS = %08X\n", readl(&dev->uregs->pci_bs)));
debug ("PCI_BS = %08X\n", readl(&dev->uregs->pci_bs));
dev->pci_bs = readl(&dev->uregs->pci_bs);
@@ -154,12 +142,12 @@ int universe_pci_slave_window(unsigned int pciAddr, unsigned int vmeAddr, int si
}
if (i == 4) {
UNI_PRINT(("universe: No Image available\n"));
printf ("universe: No Image available\n");
result = -1;
goto exit_10;
}
UNI_DBG(("universe: Using image %d\n", i));
debug ("universe: Using image %d\n", i);
writel(pciAddr , &dev->uregs->lsi[i].bs);
writel((pciAddr + size), &dev->uregs->lsi[i].bd);
@@ -219,11 +207,11 @@ int universe_pci_slave_window(unsigned int pciAddr, unsigned int vmeAddr, int si
writel(ctl, &dev->uregs->lsi[i].ctl);
UNI_DBG(("universe: window-addr=%p\n", &dev->uregs->lsi[i].ctl));
UNI_DBG(("universe: pci slave window[%d] ctl=%08x\n", i, readl(&dev->uregs->lsi[i].ctl)));
UNI_DBG(("universe: pci slave window[%d] bs=%08x\n", i, readl(&dev->uregs->lsi[i].bs)));
UNI_DBG(("universe: pci slave window[%d] bd=%08x\n", i, readl(&dev->uregs->lsi[i].bd)));
UNI_DBG(("universe: pci slave window[%d] to=%08x\n", i, readl(&dev->uregs->lsi[i].to)));
debug ("universe: window-addr=%p\n", &dev->uregs->lsi[i].ctl);
debug ("universe: pci slave window[%d] ctl=%08x\n", i, readl(&dev->uregs->lsi[i].ctl));
debug ("universe: pci slave window[%d] bs=%08x\n", i, readl(&dev->uregs->lsi[i].bs));
debug ("universe: pci slave window[%d] bd=%08x\n", i, readl(&dev->uregs->lsi[i].bd));
debug ("universe: pci slave window[%d] to=%08x\n", i, readl(&dev->uregs->lsi[i].to));
return 0;
@@ -251,12 +239,12 @@ int universe_vme_slave_window(unsigned int vmeAddr, unsigned int pciAddr, int si
}
if (i == 4) {
UNI_PRINT(("universe: No Image available\n"));
printf ("universe: No Image available\n");
result = -1;
goto exit_10;
}
UNI_DBG(("universe: Using image %d\n", i));
debug ("universe: Using image %d\n", i);
writel(vmeAddr , &dev->uregs->vsi[i].bs);
writel((vmeAddr + size), &dev->uregs->vsi[i].bd);
@@ -304,11 +292,11 @@ int universe_vme_slave_window(unsigned int vmeAddr, unsigned int pciAddr, int si
writel(ctl, &dev->uregs->vsi[i].ctl);
UNI_DBG(("universe: window-addr=%p\n", &dev->uregs->vsi[i].ctl));
UNI_DBG(("universe: vme slave window[%d] ctl=%08x\n", i, readl(&dev->uregs->vsi[i].ctl)));
UNI_DBG(("universe: vme slave window[%d] bs=%08x\n", i, readl(&dev->uregs->vsi[i].bs)));
UNI_DBG(("universe: vme slave window[%d] bd=%08x\n", i, readl(&dev->uregs->vsi[i].bd)));
UNI_DBG(("universe: vme slave window[%d] to=%08x\n", i, readl(&dev->uregs->vsi[i].to)));
debug ("universe: window-addr=%p\n", &dev->uregs->vsi[i].ctl);
debug ("universe: vme slave window[%d] ctl=%08x\n", i, readl(&dev->uregs->vsi[i].ctl));
debug ("universe: vme slave window[%d] bs=%08x\n", i, readl(&dev->uregs->vsi[i].bs));
debug ("universe: vme slave window[%d] bd=%08x\n", i, readl(&dev->uregs->vsi[i].bd));
debug ("universe: vme slave window[%d] to=%08x\n", i, readl(&dev->uregs->vsi[i].to));
return 0;

View File

@@ -32,13 +32,6 @@
#include <usb.h>
#undef CMD_USB_DEBUG
#ifdef CMD_USB_DEBUG
#define CMD_USB_PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define CMD_USB_PRINTF(fmt,args...)
#endif
static int usb_stor_curr_dev=-1; /* current device */
/* some display routines (info command) */
@@ -316,9 +309,8 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
char *boot_device = NULL;
char *ep;
int dev, part=0, rcode;
ulong cnt;
ulong addr;
int dev, part=1, rcode;
ulong addr, cnt, checksum;
disk_partition_t info;
image_header_t *hdr;
block_dev_desc_t *stor_dev;
@@ -385,7 +377,7 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
"Name: %.32s Type: %.32s\n",
dev, part, info.name, info.type);
printf ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n",
debug ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n",
info.start, info.size, info.blksz);
if (stor_dev->block_read(dev, info.start, 1, (ulong *)addr) != 1) {
@@ -395,17 +387,27 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
hdr = (image_header_t *)addr;
if (hdr->ih_magic == IH_MAGIC) {
print_image_hdr (hdr);
cnt = (hdr->ih_size + sizeof(image_header_t));
cnt += info.blksz - 1;
cnt /= info.blksz;
cnt -= 1;
} else {
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
printf("\n** Bad Magic Number **\n");
return 1;
}
checksum = ntohl(hdr->ih_hcrc);
hdr->ih_hcrc = 0;
if (crc32 (0, (char *)hdr, sizeof(image_header_t)) != checksum) {
puts ("\n** Bad Header Checksum **\n");
return 1;
}
hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */
print_image_hdr (hdr);
cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
cnt += info.blksz - 1;
cnt /= info.blksz;
cnt -= 1;
if (stor_dev->block_read (dev, info.start+1, cnt,
(ulong *)(addr+info.blksz)) != cnt) {
printf ("\n** Read error on %d:%d\n", dev, part);

View File

@@ -99,11 +99,7 @@ uchar env_get_char_spec (int index)
int env_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
int crc1_ok =
(crc32(0, flash_addr->data, ENV_SIZE) == flash_addr->crc);
int crc2_ok =
(crc32(0, flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc);
int crc1_ok = 0, crc2_ok = 0;
uchar flag1 = flash_addr->flags;
uchar flag2 = flash_addr_new->flags;
@@ -112,6 +108,16 @@ int env_init(void)
ulong addr1 = (ulong)&(flash_addr->data);
ulong addr2 = (ulong)&(flash_addr_new->data);
#ifdef CONFIG_OMAP2420H4
int flash_probe(void);
if(flash_probe() == 0)
goto bad_flash;
#endif
crc1_ok = (crc32(0, flash_addr->data, ENV_SIZE) == flash_addr->crc);
crc2_ok = (crc32(0, flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc);
if (crc1_ok && ! crc2_ok) {
gd->env_addr = addr1;
gd->env_valid = 1;
@@ -138,6 +144,9 @@ int env_init(void)
gd->env_valid = 2;
}
#ifdef CONFIG_OMAP2420H4
bad_flash:
#endif
return (0);
}
@@ -252,15 +261,22 @@ Done:
int env_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_OMAP2420H4
int flash_probe(void);
if(flash_probe() == 0)
goto bad_flash;
#endif
if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {
gd->env_addr = (ulong)&(env_ptr->data);
gd->env_valid = 1;
} else {
gd->env_addr = (ulong)&default_environment[0];
gd->env_valid = 0;
return(0);
}
#ifdef CONFIG_OMAP2420H4
bad_flash:
#endif
gd->env_addr = (ulong)&default_environment[0];
gd->env_valid = 0;
return (0);
}

View File

@@ -130,6 +130,9 @@ env_t environment __PPCENV__ = {
#ifdef CONFIG_ETH2ADDR
"eth2addr=" MK_STR(CONFIG_ETH2ADDR) "\0"
#endif
#ifdef CONFIG_ETH3ADDR
"eth3addr=" MK_STR(CONFIG_ETH3ADDR) "\0"
#endif
#ifdef CONFIG_ETHPRIME
"ethprime=" CONFIG_ETHPRIME "\0"
#endif

View File

@@ -432,7 +432,7 @@ void main_loop (void)
s = getenv("menucmd");
if (s) {
# ifndef CFG_HUSH_PARSER
run_command (s, bd, 0);
run_command (s, 0);
# else
parse_string_outer(s, FLAG_PARSE_SEMICOLON |
FLAG_EXIT_FROM_LOOP);

View File

@@ -38,6 +38,9 @@ struct serial_device *default_serial_console (void)
#elif defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \
|| defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
return &serial_scc_device;
#elif defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \
|| defined(CONFIG_405EP)
return &serial0_device;
#else
#error No default console
#endif
@@ -71,6 +74,12 @@ void serial_initialize (void)
serial_register (&serial_scc_device);
#endif
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \
|| defined(CONFIG_405EP)
serial_register(&serial0_device);
serial_register(&serial1_device);
#endif
serial_assign (default_serial_console ()->name);
}

View File

@@ -21,6 +21,6 @@
# MA 02111-1307 USA
#
PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi -fno-strict-aliasing
PLATFORM_CPPFLAGS += -DCONFIG_74xx_7xx -ffixed-r2 -ffixed-r29 -mstring

43
cpu/arm1136/Makefile Normal file
View File

@@ -0,0 +1,43 @@
#
# (C) Copyright 2000-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$(CPU).a
START = start.o
OBJS = interrupts.o cpu.o
all: .depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
sinclude .depend
#########################################################################

26
cpu/arm1136/config.mk Normal file
View File

@@ -0,0 +1,26 @@
#
# (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
#
PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
# Make ARMv5 to allow more compilers to work, even though its v6.
PLATFORM_CPPFLAGS += -mapcs-32 -march=armv5

163
cpu/arm1136/cpu.c Normal file
View File

@@ -0,0 +1,163 @@
/*
* (C) Copyright 2004 Texas Insturments
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (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
*/
/*
* CPU specific code
*/
#include <common.h>
#include <command.h>
#include <asm/arch/omap2420.h>
/* read co-processor 15, register #1 (control register) */
static unsigned long read_p15_c1 (void)
{
unsigned long value;
__asm__ __volatile__(
"mrc p15, 0, %0, c1, c0, 0 @ read control reg\n"
: "=r" (value)
:
: "memory");
return value;
}
/* write to co-processor 15, register #1 (control register) */
static void write_p15_c1 (unsigned long value)
{
__asm__ __volatile__(
"mcr p15, 0, %0, c1, c0, 0 @ write it back\n"
:
: "r" (value)
: "memory");
read_p15_c1 ();
}
static void cp_delay (void)
{
volatile int i;
/* Many OMAP regs need at least 2 nops */
for (i = 0; i < 100; i++);
}
/* See also ARM Ref. Man. */
#define C1_MMU (1<<0) /* mmu off/on */
#define C1_ALIGN (1<<1) /* alignment faults off/on */
#define C1_DC (1<<2) /* dcache off/on */
#define C1_WB (1<<3) /* merging write buffer on/off */
#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */
#define C1_SYS_PROT (1<<8) /* system protection */
#define C1_ROM_PROT (1<<9) /* ROM protection */
#define C1_IC (1<<12) /* icache off/on */
#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */
#define RESERVED_1 (0xf << 3) /* must be 111b for R/W */
int cpu_init (void)
{
/*
* setup up stacks if necessary
*/
#ifdef CONFIG_USE_IRQ
DECLARE_GLOBAL_DATA_PTR;
IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4;
FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
#endif
return 0;
}
int cleanup_before_linux (void)
{
/*
* this function is called just before we call linux
* it prepares the processor for linux
*
* we turn off caches etc ...
*/
unsigned long i;
disable_interrupts ();
#ifdef CONFIG_LCD
{
extern void lcd_disable(void);
extern void lcd_panel_disable(void);
lcd_disable(); /* proper disable of lcd & panel */
lcd_panel_disable();
}
#endif
/* turn off I/D-cache */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i &= ~(C1_DC | C1_IC);
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
/* flush I/D-cache */
i = 0;
asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); /* invalidate both caches and flush btb */
asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i)); /* mem barrier to sync things */
return(0);
}
int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
extern void reset_cpu (ulong addr);
disable_interrupts ();
reset_cpu (0);
/*NOTREACHED*/
return(0);
}
void icache_enable (void)
{
ulong reg;
reg = read_p15_c1 (); /* get control reg. */
cp_delay ();
write_p15_c1 (reg | C1_IC);
}
void icache_disable (void)
{
ulong reg;
reg = read_p15_c1 ();
cp_delay ();
write_p15_c1 (reg & ~C1_IC);
}
int icache_status (void)
{
return(read_p15_c1 () & C1_IC) != 0;
}

290
cpu/arm1136/interrupts.c Normal file
View File

@@ -0,0 +1,290 @@
/*
* (C) Copyright 2004
* Texas Instruments
* Richard Woodruff <r-woodruff2@ti.com>
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
* Alex Zuepke <azu@sysgo.de>
*
* (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
*/
#include <common.h>
#include <asm/arch/bits.h>
#include <asm/arch/omap2420.h>
#include <asm/proc-armv/ptrace.h>
extern void reset_cpu(ulong addr);
#define TIMER_LOAD_VAL 0
/* macro to read the 32 bit timer */
#define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+TCRR))
#ifdef CONFIG_USE_IRQ
/* enable IRQ interrupts */
void enable_interrupts (void)
{
unsigned long temp;
__asm__ __volatile__("mrs %0, cpsr\n"
"bic %0, %0, #0x80\n"
"msr cpsr_c, %0"
: "=r" (temp)
:
: "memory");
}
/*
* disable IRQ/FIQ interrupts
* returns true if interrupts had been enabled before we disabled them
*/
int disable_interrupts (void)
{
unsigned long old,temp;
__asm__ __volatile__("mrs %0, cpsr\n"
"orr %1, %0, #0xc0\n"
"msr cpsr_c, %1"
: "=r" (old), "=r" (temp)
:
: "memory");
return(old & 0x80) == 0;
}
#else
void enable_interrupts (void)
{
return;
}
int disable_interrupts (void)
{
return 0;
}
#endif
void bad_mode (void)
{
panic ("Resetting CPU ...\n");
reset_cpu (0);
}
void show_regs (struct pt_regs *regs)
{
unsigned long flags;
const char *processor_modes[] = {
"USER_26", "FIQ_26", "IRQ_26", "SVC_26",
"UK4_26", "UK5_26", "UK6_26", "UK7_26",
"UK8_26", "UK9_26", "UK10_26", "UK11_26",
"UK12_26", "UK13_26", "UK14_26", "UK15_26",
"USER_32", "FIQ_32", "IRQ_32", "SVC_32",
"UK4_32", "UK5_32", "UK6_32", "ABT_32",
"UK8_32", "UK9_32", "UK10_32", "UND_32",
"UK12_32", "UK13_32", "UK14_32", "SYS_32",
};
flags = condition_codes (regs);
printf ("pc : [<%08lx>] lr : [<%08lx>]\n"
"sp : %08lx ip : %08lx fp : %08lx\n",
instruction_pointer (regs),
regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
printf ("r10: %08lx r9 : %08lx r8 : %08lx\n",
regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
printf ("Flags: %c%c%c%c",
flags & CC_N_BIT ? 'N' : 'n',
flags & CC_Z_BIT ? 'Z' : 'z',
flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
printf (" IRQs %s FIQs %s Mode %s%s\n",
interrupts_enabled (regs) ? "on" : "off",
fast_interrupts_enabled (regs) ? "on" : "off",
processor_modes[processor_mode (regs)],
thumb_mode (regs) ? " (T)" : "");
}
void do_undefined_instruction (struct pt_regs *pt_regs)
{
printf ("undefined instruction\n");
show_regs (pt_regs);
bad_mode ();
}
void do_software_interrupt (struct pt_regs *pt_regs)
{
printf ("software interrupt\n");
show_regs (pt_regs);
bad_mode ();
}
void do_prefetch_abort (struct pt_regs *pt_regs)
{
printf ("prefetch abort\n");
show_regs (pt_regs);
bad_mode ();
}
void do_data_abort (struct pt_regs *pt_regs)
{
printf ("data abort\n");
show_regs (pt_regs);
bad_mode ();
}
void do_not_used (struct pt_regs *pt_regs)
{
printf ("not used\n");
show_regs (pt_regs);
bad_mode ();
}
void do_fiq (struct pt_regs *pt_regs)
{
printf ("fast interrupt request\n");
show_regs (pt_regs);
bad_mode ();
}
void do_irq (struct pt_regs *pt_regs)
{
printf ("interrupt request\n");
show_regs (pt_regs);
bad_mode ();
}
static ulong timestamp;
static ulong lastinc;
/* nothing really to do with interrupts, just starts up a counter. */
int interrupt_init (void)
{
int32_t val;
/* Start the counter ticking up */
*((int32_t *) (CFG_TIMERBASE + TLDR)) = TIMER_LOAD_VAL; /* reload value on overflow*/
val = (CFG_PVT << 2) | BIT5 | BIT1 | BIT0; /* mask to enable timer*/
*((int32_t *) (CFG_TIMERBASE + TCLR)) = val; /* start timer */
reset_timer_masked(); /* init the timestamp and lastinc value */
return(0);
}
/*
* timer without interrupts
*/
void reset_timer (void)
{
reset_timer_masked ();
}
ulong get_timer (ulong base)
{
return get_timer_masked () - base;
}
void set_timer (ulong t)
{
timestamp = t;
}
/* delay x useconds AND perserve advance timstamp value */
void udelay (unsigned long usec)
{
ulong tmo, tmp;
if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
tmo /= 1000; /* finish normalize. */
} else { /* else small number, don't kill it prior to HZ multiply */
tmo = usec * CFG_HZ;
tmo /= (1000*1000);
}
tmp = get_timer (0); /* get current timestamp */
if ( (tmo + tmp + 1) < tmp )/* if setting this forward will roll time stamp */
reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastinc value */
else
tmo += tmp; /* else, set advancing stamp wake up time */
while (get_timer_masked () < tmo)/* loop till event */
/*NOP*/;
}
void reset_timer_masked (void)
{
/* reset time */
lastinc = READ_TIMER; /* capture current incrementer value time */
timestamp = 0; /* start "advancing" time stamp from 0 */
}
ulong get_timer_masked (void)
{
ulong now = READ_TIMER; /* current tick value */
if (now >= lastinc) /* normal mode (non roll) */
timestamp += (now - lastinc); /* move stamp fordward with absoulte diff ticks */
else /* we have rollover of incrementer */
timestamp += (0xFFFFFFFF - lastinc) + now;
lastinc = now;
return timestamp;
}
/* waits specified delay value and resets timestamp */
void udelay_masked (unsigned long usec)
{
ulong tmo;
if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
tmo /= 1000; /* finish normalize. */
} else { /* else small number, don't kill it prior to HZ multiply */
tmo = usec * CFG_HZ;
tmo /= (1000*1000);
}
reset_timer_masked (); /* set "advancing" timestamp to 0, set lastinc vaule */
while (get_timer_masked () < tmo) /* wait for time stamp to overtake tick number.*/
/* NOP */;
}
/*
* This function is derived from PowerPC code (read timebase as long long).
* On ARM it just returns the timer value.
*/
unsigned long long get_ticks(void)
{
return get_timer(0);
}
/*
* This function is derived from PowerPC code (timebase clock frequency).
* On ARM it returns the number of timer ticks per second.
*/
ulong get_tbclk (void)
{
ulong tbclk;
tbclk = CFG_HZ;
return tbclk;
}

406
cpu/arm1136/start.S Normal file
View File

@@ -0,0 +1,406 @@
/*
* armboot - Startup Code for OMP2420/ARM1136 CPU-core
*
* Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
*
* Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
* Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
* Copyright (c) 2002 Gary Jennejohn <gj@denx.de>
* Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
* Copyright (c) 2003 Kshitij <kshitij@ti.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 <config.h>
#include <version.h>
#include <asm/arch/omap2420.h>
.globl _start
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
_pad: .word 0x12345678 /* now 16*4=64 */
.global _end_vect
_end_vect:
.balignl 16,0xdeadbeef
/*
*************************************************************************
*
* Startup Code (reset vector)
*
* do important init only if we don't start from memory!
* setup Memory and board specific bits prior to relocation.
* relocate armboot to ram
* setup stack
*
*************************************************************************
*/
_TEXT_BASE:
.word TEXT_BASE
.globl _armboot_start
_armboot_start:
.word _start
/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
/*
* the actual reset code
*/
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0
#ifdef CONFIG_OMAP2420H4
/* Copy vectors to mask ROM indirect addr */
adr r0, _start /* r0 <- current position of code */
add r0, r0, #4 /* skip reset vector */
mov r2, #64 /* r2 <- size to copy */
add r2, r0, r2 /* r2 <- source end address */
mov r1, #SRAM_OFFSET0 /* build vect addr */
mov r3, #SRAM_OFFSET1
add r1, r1, r3
mov r3, #SRAM_OFFSET2
add r1, r1, r3
next:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end address [r2] */
bne next /* loop until equal */
bl cpy_clk_code /* put dpll adjust code behind vectors */
#endif
/* the mask ROM code should have PLL and others stable */
bl cpu_init_crit
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
beq stack_setup
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot */
add r2, r0, r2 /* r2 <- source end address */
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
/* Set up the stack */
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
ldr pc, _start_armboot
_start_armboot: .word start_armboot
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr p15, 0, r0, c1, c0, 0
/*
* Jump to board specific initialization... The Mask ROM will have already initialized
* basic memory. Go here to bump up clock rate and handle wake up conditions.
*/
mov ip, lr /* persevere link reg across call */
bl platformsetup /* go setup pll,mux,memory */
mov lr, ip /* restore link */
mov pc, lr /* back to my caller */
/*
*************************************************************************
*
* Interrupt handling
*
*************************************************************************
*/
@
@ IRQ stack frame.
@
#define S_FRAME_SIZE 72
#define S_OLD_R0 68
#define S_PSR 64
#define S_PC 60
#define S_LR 56
#define S_SP 52
#define S_IP 48
#define S_FP 44
#define S_R10 40
#define S_R9 36
#define S_R8 32
#define S_R7 28
#define S_R6 24
#define S_R5 20
#define S_R4 16
#define S_R3 12
#define S_R2 8
#define S_R1 4
#define S_R0 0
#define MODE_SVC 0x13
#define I_BIT 0x80
/*
* use bad_save_user_regs for abort/prefetch/undef/swi ...
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
*/
.macro bad_save_user_regs
sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack
stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
ldr r2, _armboot_start
sub r2, r2, #(CFG_MALLOC_LEN)
sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs)
add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
mov r0, sp @ save current stack into r0 (param register)
.endm
.macro irq_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
stmdb r8, {sp, lr}^ @ Calling SP, LR
str lr, [r8, #0] @ Save calling PC
mrs r6, spsr
str r6, [r8, #4] @ Save CPSR
str r0, [r8, #8] @ Save OLD_R0
mov r0, sp
.endm
.macro irq_restore_user_regs
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
mov r0, r0
ldr lr, [sp, #S_PC] @ Get PC
add sp, sp, #S_FRAME_SIZE
subs pc, lr, #4 @ return & move spsr_svc into cpsr
.endm
.macro get_bad_stack
ldr r13, _armboot_start @ setup our mode stack (enter in banked mode)
sub r13, r13, #(CFG_MALLOC_LEN) @ move past malloc pool
sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack
str lr, [r13] @ save caller lr in position 0 of saved stack
mrs lr, spsr @ get the spsr
str lr, [r13, #4] @ save spsr in position 1 of saved stack
mov r13, #MODE_SVC @ prepare SVC-Mode
@ msr spsr_c, r13
msr spsr, r13 @ switch modes, make sure moves will execute
mov lr, pc @ capture return pc
movs pc, lr @ jump to next instruction & switch modes.
.endm
.macro get_bad_stack_swi
sub r13, r13, #4 @ space on current stack for scratch reg.
str r0, [r13] @ save R0's value.
ldr r0, _armboot_start @ get data regions start
sub r0, r0, #(CFG_MALLOC_LEN) @ move past malloc pool
sub r0, r0, #(CFG_GBL_DATA_SIZE+8) @ move past gbl and a couple spots for abort stack
str lr, [r0] @ save caller lr in position 0 of saved stack
mrs r0, spsr @ get the spsr
str lr, [r0, #4] @ save spsr in position 1 of saved stack
ldr r0, [r13] @ restore r0
add r13, r13, #4 @ pop stack entry
.endm
.macro get_irq_stack @ setup IRQ stack
ldr sp, IRQ_STACK_START
.endm
.macro get_fiq_stack @ setup FIQ stack
ldr sp, FIQ_STACK_START
.endm
/*
* exception handlers
*/
.align 5
undefined_instruction:
get_bad_stack
bad_save_user_regs
bl do_undefined_instruction
.align 5
software_interrupt:
get_bad_stack_swi
bad_save_user_regs
bl do_software_interrupt
.align 5
prefetch_abort:
get_bad_stack
bad_save_user_regs
bl do_prefetch_abort
.align 5
data_abort:
get_bad_stack
bad_save_user_regs
bl do_data_abort
.align 5
not_used:
get_bad_stack
bad_save_user_regs
bl do_not_used
#ifdef CONFIG_USE_IRQ
.align 5
irq:
get_irq_stack
irq_save_user_regs
bl do_irq
irq_restore_user_regs
.align 5
fiq:
get_fiq_stack
/* someone ought to write a more effiction fiq_save_user_regs */
irq_save_user_regs
bl do_fiq
irq_restore_user_regs
#else
.align 5
irq:
get_bad_stack
bad_save_user_regs
bl do_irq
.align 5
fiq:
get_bad_stack
bad_save_user_regs
bl do_fiq
#endif
.align 5
.global arm1136_cache_flush
arm1136_cache_flush:
mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
mov pc, lr @ back to caller
.align 5
.globl reset_cpu
reset_cpu:
ldr r1, rstctl /* get addr for global reset reg */
mov r3, #0x2 /* full reset pll+mpu */
str r3, [r1] /* force reset */
mov r0, r0
_loop_forever:
b _loop_forever
rstctl:
.word PM_RSTCTRL_WKUP

View File

@@ -168,7 +168,7 @@ clear_bss:
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
ble clbss_l
ldr pc, _start_armboot

View File

@@ -195,7 +195,7 @@ clear_bss:
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
ble clbss_l
#if 0
/* try doing this stuff after the relocation */

View File

@@ -203,7 +203,7 @@ clear_bss:
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
ble clbss_l
ldr pc, _start_armboot

View File

@@ -178,7 +178,7 @@ clear_bss:
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
ble clbss_l
ldr pc, _start_armboot

View File

@@ -216,7 +216,7 @@ clear_bss:
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
ble clbss_l
ldr pc,_start_armboot

View File

@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
LIB = lib$(CPU).a
START = start.o
OBJS = serial.o interrupts.o cpu.o timer.o
OBJS = serial.o interrupts.o cpu.o timer.o pci.o
all: .depend $(START) $(LIB)

View File

@@ -148,7 +148,9 @@ int dcache_status (void)
}
/* FIXME */
/*
void pci_init(void)
{
return;
}
*/

616
cpu/ixp/pci.c Normal file
View File

@@ -0,0 +1,616 @@
/*
* IXP PCI Init
* (C) Copyright 2004 eslab.whut.edu.cn
* Yue Hu(huyue_whut@yahoo.com.cn), Ligong Xue(lgxue@hotmail.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>
#ifdef CONFIG_PCI
#include <asm/processor.h>
#include <asm/io.h>
#include <pci.h>
#include <asm/arch/ixp425.h>
#include <asm/arch/ixp425pci.h>
static void non_prefetch_read (unsigned int addr, unsigned int cmd,
unsigned int *data);
static void non_prefetch_write (unsigned int addr, unsigned int cmd,
unsigned int data);
static void configure_pins (void);
static void sys_pci_gpio_clock_config (void);
static void pci_bus_scan (void);
static int pci_device_exists (unsigned int deviceNo);
static void sys_pci_bar_info_get (unsigned int devnum, unsigned int bus,
unsigned int dev, unsigned int func);
static void sys_pci_device_bars_write (void);
static void calc_bars (PciBar * Bars[], unsigned int nBars,
unsigned int startAddr);
#define PCI_MEMORY_BUS 0x00000000
#define PCI_MEMORY_PHY 0x48000000
#define PCI_MEMORY_SIZE 0x04000000
#define PCI_MEM_BUS 0x40000000
#define PCI_MEM_PHY 0x00000000
#define PCI_MEM_SIZE 0x04000000
#define PCI_IO_BUS 0x40000000
#define PCI_IO_PHY 0x50000000
#define PCI_IO_SIZE 0x10000000
struct pci_controller hose;
unsigned int nDevices;
unsigned int nMBars;
unsigned int nIOBars;
PciBar *memBars[IXP425_PCI_MAX_BAR];
PciBar *ioBars[IXP425_PCI_MAX_BAR];
PciDevice devices[IXP425_PCI_MAX_FUNC_ON_BUS];
void out_8 (volatile unsigned *addr, char val)
{
*addr = val;
}
void out_le16 (volatile unsigned *addr, unsigned short val)
{
*addr = cpu_to_le16 (val);
}
void out_le32 (volatile unsigned *addr, unsigned int val)
{
*addr = cpu_to_le32 (val);
}
unsigned char in_8 (volatile unsigned *addr)
{
unsigned char val;
val = *addr;
return val;
}
unsigned short in_le16 (volatile unsigned *addr)
{
unsigned short val;
val = *addr;
val = le16_to_cpu (val);
return val;
}
unsigned in_le32 (volatile unsigned *addr)
{
unsigned int val;
val = *addr;
val = le32_to_cpu (val);
return val;
}
int pci_read_config_dword (pci_dev_t dev, int where, unsigned int *val)
{
unsigned int retval;
unsigned int addr;
/*address bits 31:28 specify the device 10:8 specify the function */
/*Set the address to be read */
addr = BIT ((31 - dev)) | (where & ~3);
non_prefetch_read (addr, NP_CMD_CONFIGREAD, &retval);
*val = retval;
return (OK);
}
int pci_read_config_word (pci_dev_t dev, int where, unsigned short *val)
{
unsigned int n;
unsigned int retval;
unsigned int addr;
unsigned int byteEnables;
n = where % 4;
/*byte enables are 4 bits active low, the position of each
bit maps to the byte that it enables */
byteEnables =
(~(BIT (n) | BIT ((n + 1)))) &
IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
byteEnables = byteEnables << PCI_NP_CBE_BESL;
/*address bits 31:28 specify the device 10:8 specify the function */
/*Set the address to be read */
addr = BIT ((31 - dev)) | (where & ~3);
non_prefetch_read (addr, byteEnables | NP_CMD_CONFIGREAD, &retval);
/*Pick out the word we are interested in */
*val = (retval >> (8 * n));
return (OK);
}
int pci_read_config_byte (pci_dev_t dev, int where, unsigned char *val)
{
unsigned int retval;
unsigned int n;
unsigned int byteEnables;
unsigned int addr;
n = where % 4;
/*byte enables are 4 bits, active low, the position of each
bit maps to the byte that it enables */
byteEnables = (~BIT (n)) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
byteEnables = byteEnables << PCI_NP_CBE_BESL;
/*address bits 31:28 specify the device, 10:8 specify the function */
/*Set the address to be read */
addr = BIT ((31 - dev)) | (where & ~3);
non_prefetch_read (addr, byteEnables | NP_CMD_CONFIGREAD, &retval);
/*Pick out the byte we are interested in */
*val = (retval >> (8 * n));
return (OK);
}
int pci_write_config_byte (pci_dev_t dev, int where, unsigned char val)
{
unsigned int addr;
unsigned int byteEnables;
unsigned int n;
unsigned int ldata;
n = where % 4;
/*byte enables are 4 bits active low, the position of each
bit maps to the byte that it enables */
byteEnables = (~BIT (n)) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
byteEnables = byteEnables << PCI_NP_CBE_BESL;
ldata = val << (8 * n);
/*address bits 31:28 specify the device 10:8 specify the function */
/*Set the address to be written */
addr = BIT ((31 - dev)) | (where & ~3);
non_prefetch_write (addr, byteEnables | NP_CMD_CONFIGWRITE, ldata);
return (OK);
}
int pci_write_config_word (pci_dev_t dev, int where, unsigned short val)
{
unsigned int addr;
unsigned int byteEnables;
unsigned int n;
unsigned int ldata;
n = where % 4;
/*byte enables are 4 bits active low, the position of each
bit maps to the byte that it enables */
byteEnables =
(~(BIT (n) | BIT ((n + 1)))) &
IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
byteEnables = byteEnables << PCI_NP_CBE_BESL;
ldata = val << (8 * n);
/*address bits 31:28 specify the device 10:8 specify the function */
/*Set the address to be written */
addr = BIT (31 - dev) | (where & ~3);
non_prefetch_write (addr, byteEnables | NP_CMD_CONFIGWRITE, ldata);
return (OK);
}
int pci_write_config_dword (pci_dev_t dev, int where, unsigned int val)
{
unsigned int addr;
/*address bits 31:28 specify the device 10:8 specify the function */
/*Set the address to be written */
addr = BIT (31 - dev) | (where & ~3);
non_prefetch_write (addr, NP_CMD_CONFIGWRITE, val);
return (OK);
}
void non_prefetch_read (unsigned int addr,
unsigned int cmd, unsigned int *data)
{
REG_WRITE (PCI_CSR_BASE, PCI_NP_AD_OFFSET, addr);
/*set up and execute the read */
REG_WRITE (PCI_CSR_BASE, PCI_NP_CBE_OFFSET, cmd);
/*The result of the read is now in np_rdata */
REG_READ (PCI_CSR_BASE, PCI_NP_RDATA_OFFSET, *data);
return;
}
void non_prefetch_write (unsigned int addr,
unsigned int cmd, unsigned int data)
{
REG_WRITE (PCI_CSR_BASE, PCI_NP_AD_OFFSET, addr);
/*set up the write */
REG_WRITE (PCI_CSR_BASE, PCI_NP_CBE_OFFSET, cmd);
/*Execute the write by writing to NP_WDATA */
REG_WRITE (PCI_CSR_BASE, PCI_NP_WDATA_OFFSET, data);
return;
}
/*
* PCI controller config registers are accessed through these functions
* i.e. these allow us to set up our own BARs etc.
*/
void crp_read (unsigned int offset, unsigned int *data)
{
REG_WRITE (PCI_CSR_BASE, PCI_CRP_AD_CBE_OFFSET, offset);
REG_READ (PCI_CSR_BASE, PCI_CRP_RDATA_OFFSET, *data);
}
void crp_write (unsigned int offset, unsigned int data)
{
/*The CRP address register bit 16 indicates that we want to do a write */
REG_WRITE (PCI_CSR_BASE, PCI_CRP_AD_CBE_OFFSET,
PCI_CRP_WRITE | offset);
REG_WRITE (PCI_CSR_BASE, PCI_CRP_WDATA_OFFSET, data);
}
/*struct pci_controller *hose*/
void pci_ixp_init (struct pci_controller *hose)
{
unsigned int regval;
hose->first_busno = 0;
hose->last_busno = 0x00;
/* System memory space */
pci_set_region (hose->regions + 0,
PCI_MEMORY_BUS,
PCI_MEMORY_PHY, PCI_MEMORY_SIZE, PCI_REGION_MEMORY);
/* PCI memory space */
pci_set_region (hose->regions + 1,
PCI_MEM_BUS,
PCI_MEM_PHY, PCI_MEM_SIZE, PCI_REGION_MEM);
/* PCI I/O space */
pci_set_region (hose->regions + 2,
PCI_IO_BUS, PCI_IO_PHY, PCI_IO_SIZE, PCI_REGION_IO);
hose->region_count = 3;
pci_register_hose (hose);
/*
==========================================================
Init IXP PCI
==========================================================
*/
REG_READ (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
regval |= 1 << 2;
REG_WRITE (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
configure_pins ();
READ_GPIO_REG (IXP425_GPIO_GPOUTR, regval);
WRITE_GPIO_REG (IXP425_GPIO_GPOUTR, regval & (~(1 << 13)));
udelay (533);
sys_pci_gpio_clock_config ();
REG_WRITE (PCI_CSR_BASE, PCI_INTEN_OFFSET, 0);
udelay (100);
READ_GPIO_REG (IXP425_GPIO_GPOUTR, regval);
WRITE_GPIO_REG (IXP425_GPIO_GPOUTR, regval | (1 << 13));
udelay (533);
crp_write (PCI_CFG_BASE_ADDRESS_0, IXP425_PCI_BAR_0_DEFAULT);
crp_write (PCI_CFG_BASE_ADDRESS_1, IXP425_PCI_BAR_1_DEFAULT);
crp_write (PCI_CFG_BASE_ADDRESS_2, IXP425_PCI_BAR_2_DEFAULT);
crp_write (PCI_CFG_BASE_ADDRESS_3, IXP425_PCI_BAR_3_DEFAULT);
crp_write (PCI_CFG_BASE_ADDRESS_4, IXP425_PCI_BAR_4_DEFAULT);
crp_write (PCI_CFG_BASE_ADDRESS_5, IXP425_PCI_BAR_5_DEFAULT);
/*Setup PCI-AHB and AHB-PCI address mappings */
REG_WRITE (PCI_CSR_BASE, PCI_AHBMEMBASE_OFFSET,
IXP425_PCI_AHBMEMBASE_DEFAULT);
REG_WRITE (PCI_CSR_BASE, PCI_AHBIOBASE_OFFSET,
IXP425_PCI_AHBIOBASE_DEFAULT);
REG_WRITE (PCI_CSR_BASE, PCI_PCIMEMBASE_OFFSET,
IXP425_PCI_PCIMEMBASE_DEFAULT);
crp_write (PCI_CFG_SUB_VENDOR_ID, IXP425_PCI_SUB_VENDOR_SYSTEM);
REG_READ (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
regval |= PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS;
REG_WRITE (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
crp_write (PCI_CFG_COMMAND, PCI_CFG_CMD_MAE | PCI_CFG_CMD_BME);
udelay (1000);
pci_write_config_word (0, PCI_CFG_COMMAND, INITIAL_PCI_CMD);
REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PSE
| PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE);
#ifdef CONFIG_PCI_SCAN_SHOW
printf ("Device bus dev func deviceID vendorID \n");
#endif
pci_bus_scan ();
}
void configure_pins (void)
{
unsigned int regval;
/* Disable clock on GPIO PIN 14 */
READ_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
WRITE_GPIO_REG (IXP425_GPIO_GPCLKR, regval & (~(1 << 8)));
READ_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
READ_GPIO_REG (IXP425_GPIO_GPOER, regval);
WRITE_GPIO_REG (IXP425_GPIO_GPOER,
(((~(3 << 13)) & regval) | (0xf << 8)));
READ_GPIO_REG (IXP425_GPIO_GPOER, regval);
READ_GPIO_REG (IXP425_GPIO_GPIT2R, regval);
WRITE_GPIO_REG (IXP425_GPIO_GPIT2R,
(regval &
((0x1 << 9) | (0x1 << 6) | (0x1 << 3) | 0x1)));
READ_GPIO_REG (IXP425_GPIO_GPIT2R, regval);
READ_GPIO_REG (IXP425_GPIO_GPISR, regval);
WRITE_GPIO_REG (IXP425_GPIO_GPISR, (regval | (0xf << 8)));
READ_GPIO_REG (IXP425_GPIO_GPISR, regval);
}
void sys_pci_gpio_clock_config (void)
{
unsigned int regval;
READ_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
regval |= 0x1 << 4;
WRITE_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
READ_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
regval |= 0x1 << 8;
WRITE_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
}
void pci_bus_scan (void)
{
unsigned int bus = 0, dev, func = 0;
unsigned short data16;
unsigned int data32;
unsigned char intPin;
/* Assign first device to ourselves */
devices[0].bus = 0;
devices[0].device = 0;
devices[0].func = 0;
crp_read (PCI_CFG_VENDOR_ID, &data32);
devices[0].vendor_id = data32 & IXP425_PCI_BOTTOM_WORD_OF_LONG_MASK;
devices[0].device_id = data32 >> 16;
devices[0].error = FALSE;
devices[0].bar[NO_BAR].size = 0; /*dummy - required */
nDevices = 1;
nMBars = 0;
nIOBars = 0;
for (dev = 0; dev < IXP425_PCI_MAX_DEV; dev++) {
/*Check whether a device is present */
if (pci_device_exists (dev) != TRUE) {
/*Clear error bits in ISR, write 1 to clear */
REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PSE
| PCI_ISR_PFE | PCI_ISR_PPE |
PCI_ISR_AHBE);
continue;
}
/*A device is present, add an entry to the array */
devices[nDevices].bus = bus;
devices[nDevices].device = dev;
devices[nDevices].func = func;
pci_read_config_word (dev, PCI_CFG_VENDOR_ID, &data16);
devices[nDevices].vendor_id = data16;
pci_read_config_word (dev, PCI_CFG_DEVICE_ID, &data16);
devices[nDevices].device_id = data16;
/*The device is functioning correctly, set error to FALSE */
devices[nDevices].error = FALSE;
/*Figure out what BARs are on this device */
sys_pci_bar_info_get (nDevices, bus, dev, func);
/*Figure out what INTX# line the card uses */
pci_read_config_byte (dev, PCI_CFG_DEV_INT_PIN, &intPin);
/*assign the appropriate irq line */
if (intPin > PCI_IRQ_LINES) {
devices[nDevices].error = TRUE;
} else if (intPin != 0) {
/*This device uses an interrupt line */
/*devices[nDevices].irq = ixp425PciIntTranslate[dev][intPin-1]; */
devices[nDevices].irq = intPin;
}
#ifdef CONFIG_PCI_SCAN_SHOW
printf ("%06d %03d %03d %04d %08d %08x\n", nDevices,
devices[nDevices].vendor_id);
#endif
nDevices++;
}
calc_bars (memBars, nMBars, IXP425_PCI_BAR_MEM_BASE);
sys_pci_device_bars_write ();
REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PSE
| PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE);
}
void sys_pci_bar_info_get (unsigned int devnum,
unsigned int bus,
unsigned int dev, unsigned int func)
{
unsigned int data32;
unsigned int tmp;
unsigned int size;
pci_write_config_dword (devnum,
PCI_CFG_BASE_ADDRESS_0, IXP425_PCI_BAR_QUERY);
pci_read_config_dword (devnum, PCI_CFG_BASE_ADDRESS_0, &data32);
devices[devnum].bar[0].address = (data32 & 1);
if (data32 & 1) {
/* IO space */
tmp = data32 & ~0x3;
size = ~(tmp - 1);
devices[devnum].bar[0].size = size;
if (nIOBars < IXP425_PCI_MAX_BAR) {
ioBars[nIOBars++] = &devices[devnum].bar[0];
}
} else {
/* Mem space */
tmp = data32 & ~IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
size = ~(tmp - 1);
devices[devnum].bar[0].size = size;
if (nMBars < IXP425_PCI_MAX_BAR) {
memBars[nMBars++] = &devices[devnum].bar[0];
} else {
devices[devnum].error = TRUE;
}
}
devices[devnum].bar[1].size = 0;
}
void sortBars (PciBar * Bars[], unsigned int nBars)
{
unsigned int i, j;
PciBar *tmp;
if (nBars == 0) {
return;
}
/* Sort biggest to smallest */
for (i = 0; i < nBars - 1; i++) {
for (j = i + 1; j < nBars; j++) {
if (Bars[j]->size > Bars[i]->size) {
/* swap them */
tmp = Bars[i];
Bars[i] = Bars[j];
Bars[j] = tmp;
}
}
}
}
void calc_bars (PciBar * Bars[], unsigned int nBars, unsigned int startAddr)
{
unsigned int i;
if (nBars == 0) {
return;
}
for (i = 0; i < nBars; i++) {
Bars[i]->address |= startAddr;
startAddr += Bars[i]->size;
}
}
void sys_pci_device_bars_write (void)
{
unsigned int i;
int addr;
for (i = 1; i < nDevices; i++) {
if (devices[i].error) {
continue;
}
pci_write_config_dword (devices[i].device,
PCI_CFG_BASE_ADDRESS_0,
devices[i].bar[0].address);
addr = (BIT (31 - devices[i].device) |
(0 << PCI_NP_AD_FUNCSL) |
(PCI_CFG_BASE_ADDRESS_0) ) & ~3;
pci_write_config_dword (devices[i].device,
PCI_CFG_DEV_INT_LINE, devices[i].irq);
pci_write_config_word (devices[i].device,
PCI_CFG_COMMAND, INITIAL_PCI_CMD);
}
}
int pci_device_exists (unsigned int deviceNo)
{
unsigned int vendorId;
unsigned int regval;
pci_read_config_dword (deviceNo, PCI_CFG_VENDOR_ID, &vendorId);
/* There are two ways to find out an empty device.
* 1. check Master Abort bit after the access.
* 2. check whether the vendor id read back is 0x0.
*/
REG_READ (PCI_CSR_BASE, PCI_ISR_OFFSET, regval);
if ((vendorId != 0x0) && ((regval & PCI_ISR_PFE) == 0)) {
return TRUE;
}
/*no device present, make sure that the master abort bit is reset */
REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PFE);
return FALSE;
}
pci_dev_t pci_find_devices (struct pci_device_id * ids, int devNo)
{
unsigned int i;
unsigned int devdidvid;
unsigned int didvid;
unsigned int vendorId, deviceId;
vendorId = ids->vendor;
deviceId = ids->device;
didvid = ((deviceId << 16) & IXP425_PCI_TOP_WORD_OF_LONG_MASK) |
(vendorId & IXP425_PCI_BOTTOM_WORD_OF_LONG_MASK);
for (i = devNo + 1; i < nDevices; i++) {
pci_read_config_dword (devices[i].device, PCI_CFG_VENDOR_ID,
&devdidvid);
if (devdidvid == didvid) {
return devices[i].device;
}
}
return -1;
}
#endif /* CONFIG_PCI */

View File

@@ -159,11 +159,12 @@ reset:
str r1, [r2]
/* make sure flash is visible at 0 */
#if 0
ldr r2, =IXP425_EXP_CFG0
ldr r1, [r2]
orr r1, r1, #0x80000000
str r1, [r2]
#endif
mov r1, #CFG_SDR_CONFIG
ldr r2, =IXP425_SDR_CONFIG
str r1, [r2]
@@ -198,7 +199,7 @@ reset:
bne 111b
/* set mode register in sdram */
mov r1, #1
mov r1, #CFG_SDR_MODE_CONFIG
str r1, [r4]
DELAY_FOR 0x4000, r0
@@ -295,7 +296,7 @@ clear_bss:
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
ble clbss_l
ldr pc, _start_armboot

View File

@@ -187,7 +187,7 @@ clear_bss:
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
ble clbss_l
ldr pc, _start_armboot

View File

@@ -46,10 +46,15 @@
#define ETH0_BASE AU1500_ETH0_BASE
#define MAC0_ENABLE AU1500_MAC0_ENABLE
#else
#ifdef CONFIG_AU1550
#define ETH0_BASE AU1550_ETH0_BASE
#define MAC0_ENABLE AU1550_MAC0_ENABLE
#else
#error "No valid cpu set"
#endif
#endif
#endif
#endif
#include <common.h>
#include <malloc.h>

View File

@@ -71,8 +71,8 @@ void serial_setbrg (void)
volatile u32 *uart_clk = (volatile u32*)(UART0_ADDR+UART_CLK);
volatile u32 *uart_lcr = (volatile u32*)(UART0_ADDR+UART_LCR);
/* Set baudrate to 115200 */
*uart_clk = 0x36;
/* Set baudrate - FIXME for bus speeds != CPU/2 */
*uart_clk = ((CFG_HZ/(CONFIG_BAUDRATE * 64)));
/* Set parity, stop bits and word length to 8N1 */
*uart_lcr = UART_LCR_WLEN8;

View File

@@ -809,14 +809,14 @@ int mpc8220_fec_initialize (bd_t * bis)
{
mpc8220_fec_priv *fec;
#ifdef CONFIG_ETH1ADDR
#ifdef CONFIG_HAS_ETH1
mpc8220_fec_priv *fec2;
#endif
struct eth_device *dev;
char *tmp, *end;
char env_enetaddr[6];
#ifdef CONFIG_ETH1ADDR
#ifdef CONFIG_HAS_ETH1
char env_enet1addr[6];
#endif
int i;
@@ -826,7 +826,7 @@ int mpc8220_fec_initialize (bd_t * bis)
memset (dev, 0, sizeof *dev);
fec->eth = (ethernet_regs *) MMAP_FEC1;
#ifdef CONFIG_ETH1ADDR
#ifdef CONFIG_HAS_ETH1
fec2 = (mpc8220_fec_priv *) malloc (sizeof (*fec));
fec2->eth = (ethernet_regs *) MMAP_FEC2;
#endif
@@ -860,7 +860,7 @@ int mpc8220_fec_initialize (bd_t * bis)
}
mpc8220_fec_set_hwaddr (fec, env_enetaddr);
}
#ifdef CONFIG_ETH1ADDR
#ifdef CONFIG_HAS_ETH1
tmp = getenv ("eth1addr");
if (tmp) {
for (i = 0; i < 6; i++) {

View File

@@ -21,6 +21,6 @@
# MA 02111-1307 USA
#
PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi -fno-strict-aliasing
PLATFORM_CPPFLAGS += -DCONFIG_MPC824X -ffixed-r2 -ffixed-r29 -mstring -mcpu=603e -msoft-float

View File

@@ -90,7 +90,7 @@ cpu_init_f (void)
#endif
CONFIG_WRITE_BYTE(PCLSR, 0x8); /* set PCI cache line size */
CONFIG_WRITE_BYTE (PLTR, 0x40); /* set PCI latency timer */
/*
* Note that although this bit is cleared after a hard reset, it
* must be explicitly set and then cleared by software during

View File

@@ -21,6 +21,6 @@
# MA 02111-1307 USA
#
PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi -fno-strict-aliasing
PLATFORM_CPPFLAGS += -DCONFIG_8xx -ffixed-r2 -ffixed-r29 -mstring -mcpu=860 -msoft-float

View File

@@ -1176,36 +1176,37 @@ int ppc_440x_eth_initialize (bd_t * bis)
/* See if we can actually bring up the interface, otherwise, skip it */
switch (eth_num) {
default: /* fall through */
case 0:
if (memcmp (bis->bi_enetaddr, "\0\0\0\0\0\0", 6) == 0) {
bis->bi_phymode[eth_num] = BI_PHYMODE_NONE;
continue;
}
break;
#ifdef CONFIG_HAS_ETH1
case 1:
if (memcmp (bis->bi_enet1addr, "\0\0\0\0\0\0", 6) == 0) {
bis->bi_phymode[eth_num] = BI_PHYMODE_NONE;
continue;
}
break;
#endif
#ifdef CONFIG_HAS_ETH2
case 2:
if (memcmp (bis->bi_enet2addr, "\0\0\0\0\0\0", 6) == 0) {
bis->bi_phymode[eth_num] = BI_PHYMODE_NONE;
continue;
}
break;
#endif
#ifdef CONFIG_HAS_ETH3
case 3:
if (memcmp (bis->bi_enet3addr, "\0\0\0\0\0\0", 6) == 0) {
bis->bi_phymode[eth_num] = BI_PHYMODE_NONE;
continue;
}
break;
default:
if (memcmp (bis->bi_enetaddr, "\0\0\0\0\0\0", 6) == 0) {
bis->bi_phymode[eth_num] = BI_PHYMODE_NONE;
continue;
}
break;
#endif
}
/* Allocate device structure */
@@ -1227,26 +1228,29 @@ int ppc_440x_eth_initialize (bd_t * bis)
}
switch (eth_num) {
default: /* fall through */
case 0:
hw->hw_addr = 0;
memcpy (dev->enetaddr, bis->bi_enetaddr, 6);
break;
#ifdef CONFIG_HAS_ETH1
case 1:
hw->hw_addr = 0x100;
memcpy (dev->enetaddr, bis->bi_enet1addr, 6);
break;
#endif
#ifdef CONFIG_HAS_ETH2
case 2:
hw->hw_addr = 0x400;
memcpy (dev->enetaddr, bis->bi_enet2addr, 6);
break;
#endif
#ifdef CONFIG_HAS_ETH3
case 3:
hw->hw_addr = 0x600;
memcpy (dev->enetaddr, bis->bi_enet3addr, 6);
break;
default:
hw->hw_addr = 0;
memcpy (dev->enetaddr, bis->bi_enetaddr, 6);
break;
#endif
}
hw->devnum = eth_num;

View File

@@ -21,6 +21,6 @@
# MA 02111-1307 USA
#
PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi -fno-strict-aliasing
PLATFORM_CPPFLAGS += -DCONFIG_4xx -ffixed-r2 -ffixed-r29 -mstring -Wa,-m405 -mcpu=405 -msoft-float

View File

@@ -41,13 +41,20 @@
* LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
*/
/*------------------------------------------------------------------------------- */
/*
* Travis Sawyer 15 September 2004
* Added CONFIG_SERIAL_MULTI support
*/
#include <common.h>
#include <commproc.h>
#include <asm/processor.h>
#include <watchdog.h>
#include "vecnum.h"
#ifdef CONFIG_SERIAL_MULTI
#include <serial.h>
#endif
#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
#include <malloc.h>
#endif
@@ -147,7 +154,6 @@
#define asyncXOFFchar 0x13
#define asyncXONchar 0x11
/*
* Minimal serial functions needed to use one of the SMC ports
* as serial console interface.
@@ -177,7 +183,6 @@ int serial_init (void)
return (0);
}
void serial_setbrg (void)
{
DECLARE_GLOBAL_DATA_PTR;
@@ -190,7 +195,6 @@ void serial_setbrg (void)
out8 (SPU_BASE + spu_BRateDivh, ((br_reg & 0xff00) >> 8)); /* ... */
}
void serial_putc (const char c)
{
if (c == '\n')
@@ -208,7 +212,6 @@ void serial_putc (const char c)
}
}
void serial_puts (const char *s)
{
while (*s) {
@@ -216,7 +219,6 @@ void serial_puts (const char *s)
}
}
int serial_getc ()
{
unsigned char status = 0;
@@ -240,7 +242,6 @@ int serial_getc ()
return (0x000000ff & (int) in8 (asyncRxBufferport1));
}
int serial_tstc ()
{
unsigned char status;
@@ -264,7 +265,6 @@ int serial_tstc ()
#endif /* CONFIG_IOP480 */
/*****************************************************************************/
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || defined(CONFIG_405EP)
@@ -350,7 +350,6 @@ int serial_tstc ()
/*#define asyncTxBufferport1 ACTING_UART0_BASE+0x00 */
/*#define asyncRxBufferport1 ACTING_UART0_BASE+0x00 */
#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
/*-----------------------------------------------------------------------------+
| Fifo
@@ -364,7 +363,6 @@ typedef struct {
volatile static serial_buffer_t buf_info;
#endif
#if defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLOCK)
static void serial_divs (int baudrate, unsigned long *pudiv,
unsigned short *pbdiv )
@@ -411,14 +409,17 @@ static void serial_divs (int baudrate, unsigned long *pudiv,
}
#endif /* defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLK */
/*
* Minimal serial functions needed to use one of the SMC ports
* as serial console interface.
*/
#if defined(CONFIG_440)
int serial_init (void)
#if defined(CONFIG_SERIAL_MULTI)
int serial_init_dev (unsigned long dev_base)
#else
int serial_init(void)
#endif
{
DECLARE_GLOBAL_DATA_PTR;
@@ -431,8 +432,18 @@ int serial_init (void)
#endif
#if defined(CONFIG_440_GX)
#if defined(CONFIG_SERIAL_MULTI)
if (UART0_BASE == dev_base) {
mfsdr(UART0_SDR,reg);
reg &= ~CR0_MASK;
} else {
mfsdr(UART1_SDR,reg);
reg &= ~CR0_MASK;
}
#else
mfsdr(UART0_SDR,reg);
reg &= ~CR0_MASK;
#endif
#else
reg = mfdcr(cntrl0) & ~CR0_MASK;
#endif /* CONFIG_440_GX */
@@ -451,11 +462,32 @@ int serial_init (void)
#if defined(CONFIG_440_GX)
reg |= udiv << CR0_UDIV_POS; /* set the UART divisor */
#if defined(CONFIG_SERIAL_MULTI)
if (UART0_BASE == dev_base) {
mtsdr (UART0_SDR,reg);
} else {
mtsdr (UART1_SDR,reg);
}
#else
mtsdr (UART0_SDR,reg);
#endif
#else
reg |= (udiv - 1) << CR0_UDIV_POS; /* set the UART divisor */
mtdcr (cntrl0, reg);
#endif
#if defined(CONFIG_SERIAL_MULTI)
out8 (dev_base + UART_LCR, 0x80); /* set DLAB bit */
out8 (dev_base + UART_DLL, bdiv); /* set baudrate divisor */
out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
out8 (dev_base + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
out8 (dev_base + UART_FCR, 0x00); /* disable FIFO */
out8 (dev_base + UART_MCR, 0x00); /* no modem control DTR RTS */
val = in8 (dev_base + UART_LSR); /* clear line status */
val = in8 (dev_base + UART_RBR); /* read receive buffer */
out8 (dev_base + UART_SCR, 0x00); /* set scratchpad */
out8 (dev_base + UART_IER, 0x00); /* set interrupt enable reg */
#else
out8 (ACTING_UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */
out8 (ACTING_UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */
out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
@@ -466,13 +498,17 @@ int serial_init (void)
val = in8 (ACTING_UART0_BASE + UART_RBR); /* read receive buffer */
out8 (ACTING_UART0_BASE + UART_SCR, 0x00); /* set scratchpad */
out8 (ACTING_UART0_BASE + UART_IER, 0x00); /* set interrupt enable reg */
#endif
return (0);
}
#else /* !defined(CONFIG_440) */
#if defined(CONFIG_SERIAL_MULTI)
int serial_init_dev (unsigned long dev_base)
#else
int serial_init (void)
#endif
{
DECLARE_GLOBAL_DATA_PTR;
@@ -517,6 +553,18 @@ int serial_init (void)
tmp = gd->baudrate * udiv * 16;
bdiv = (clk + tmp / 2) / tmp;
#if defined(CONFIG_SERIAL_MULTI)
out8 (dev_base + UART_LCR, 0x80); /* set DLAB bit */
out8 (dev_base + UART_DLL, bdiv); /* set baudrate divisor */
out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
out8 (dev_base + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
out8 (dev_base + UART_FCR, 0x00); /* disable FIFO */
out8 (dev_base + UART_MCR, 0x00); /* no modem control DTR RTS */
val = in8 (dev_base + UART_LSR); /* clear line status */
val = in8 (dev_base + UART_RBR); /* read receive buffer */
out8 (dev_base + UART_SCR, 0x00); /* set scratchpad */
out8 (dev_base + UART_IER, 0x00); /* set interrupt enable reg */
#else
out8 (ACTING_UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */
out8 (ACTING_UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */
out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
@@ -527,13 +575,17 @@ int serial_init (void)
val = in8 (ACTING_UART0_BASE + UART_RBR); /* read receive buffer */
out8 (ACTING_UART0_BASE + UART_SCR, 0x00); /* set scratchpad */
out8 (ACTING_UART0_BASE + UART_IER, 0x00); /* set interrupt enable reg */
#endif
return (0);
}
#endif /* if defined(CONFIG_440) */
#if defined(CONFIG_SERIAL_MULTI)
void serial_setbrg_dev (unsigned long dev_base)
#else
void serial_setbrg (void)
#endif
{
DECLARE_GLOBAL_DATA_PTR;
@@ -556,39 +608,71 @@ void serial_setbrg (void)
tmp = gd->baudrate * udiv * 16;
bdiv = (clk + tmp / 2) / tmp;
#if defined(CONFIG_SERIAL_MULTI)
out8 (dev_base + UART_LCR, 0x80); /* set DLAB bit */
out8 (dev_base + UART_DLL, bdiv); /* set baudrate divisor */
out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
out8 (dev_base + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
#else
out8 (ACTING_UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */
out8 (ACTING_UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */
out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
out8 (ACTING_UART0_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
#endif
}
#if defined(CONFIG_SERIAL_MULTI)
void serial_putc_dev (unsigned long dev_base, const char c)
#else
void serial_putc (const char c)
#endif
{
int i;
if (c == '\n')
#if defined(CONFIG_SERIAL_MULTI)
serial_putc_dev (dev_base, '\r');
#else
serial_putc ('\r');
#endif
/* check THRE bit, wait for transmiter available */
for (i = 1; i < 3500; i++) {
#if defined(CONFIG_SERIAL_MULTI)
if ((in8 (dev_base + UART_LSR) & 0x20) == 0x20)
#else
if ((in8 (ACTING_UART0_BASE + UART_LSR) & 0x20) == 0x20)
#endif
break;
udelay (100);
}
#if defined(CONFIG_SERIAL_MULTI)
out8 (dev_base + UART_THR, c); /* put character out */
#else
out8 (ACTING_UART0_BASE + UART_THR, c); /* put character out */
#endif
}
#if defined(CONFIG_SERIAL_MULTI)
void serial_puts_dev (unsigned long dev_base, const char *s)
#else
void serial_puts (const char *s)
#endif
{
while (*s) {
#if defined(CONFIG_SERIAL_MULTI)
serial_putc_dev (dev_base, *s++);
#else
serial_putc (*s++);
#endif
}
}
int serial_getc ()
#if defined(CONFIG_SERIAL_MULTI)
int serial_getc_dev (unsigned long dev_base)
#else
int serial_getc (void)
#endif
{
unsigned char status = 0;
@@ -596,7 +680,11 @@ int serial_getc ()
#if defined(CONFIG_HW_WATCHDOG)
WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
#endif /* CONFIG_HW_WATCHDOG */
#if defined(CONFIG_SERIAL_MULTI)
status = in8 (dev_base + UART_LSR);
#else
status = in8 (ACTING_UART0_BASE + UART_LSR);
#endif
if ((status & asyncLSRDataReady1) != 0x0) {
break;
}
@@ -604,22 +692,37 @@ int serial_getc ()
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1 )) != 0) {
#if defined(CONFIG_SERIAL_MULTI)
out8 (dev_base + UART_LSR,
#else
out8 (ACTING_UART0_BASE + UART_LSR,
#endif
asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1);
}
}
#if defined(CONFIG_SERIAL_MULTI)
return (0x000000ff & (int) in8 (dev_base));
#else
return (0x000000ff & (int) in8 (ACTING_UART0_BASE));
#endif
}
int serial_tstc ()
#if defined(CONFIG_SERIAL_MULTI)
int serial_tstc_dev (unsigned long dev_base)
#else
int serial_tstc (void)
#endif
{
unsigned char status;
#if defined(CONFIG_SERIAL_MULTI)
status = in8 (dev_base + UART_LSR);
#else
status = in8 (ACTING_UART0_BASE + UART_LSR);
#endif
if ((status & asyncLSRDataReady1) != 0x0) {
return (1);
}
@@ -627,7 +730,11 @@ int serial_tstc ()
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1 )) != 0) {
#if defined(CONFIG_SERIAL_MULTI)
out8 (dev_base + UART_LSR,
#else
out8 (ACTING_UART0_BASE + UART_LSR,
#endif
asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
@@ -636,7 +743,6 @@ int serial_tstc ()
return 0;
}
#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
void serial_isr (void *arg)
@@ -651,8 +757,8 @@ void serial_isr (void *arg)
} else {
space = rx_get - rx_put;
}
while (serial_tstc ()) {
c = serial_getc ();
while (serial_tstc_dev (ACTING_UART0_BASE)) {
c = serial_getc_dev (ACTING_UART0_BASE);
if (space) {
buf_info.rx_buffer[rx_put++] = c;
space--;
@@ -752,7 +858,6 @@ int serial_buffered_tstc (void)
#endif /* CONFIG_SERIAL_SOFTWARE_FIFO */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
/*
AS HARNOIS : according to CONFIG_KGDB_SER_INDEX kgdb uses serial port
@@ -788,7 +893,6 @@ void kgdb_serial_init (void)
out8 (ACTING_UART1_BASE + UART_IER, 0x00); /* set interrupt enable reg */
}
void putDebugChar (const char c)
{
if (c == '\n')
@@ -800,7 +904,6 @@ void putDebugChar (const char c)
while ((in8 (ACTING_UART1_BASE + UART_LSR) & 0x20) != 0x20);
}
void putDebugStr (const char *s)
{
while (*s) {
@@ -808,7 +911,6 @@ void putDebugStr (const char *s)
}
}
int getDebugChar (void)
{
unsigned char status = 0;
@@ -832,7 +934,6 @@ int getDebugChar (void)
return (0x000000ff & (int) in8 (ACTING_UART1_BASE));
}
void kgdb_interruptible (int yes)
{
return;
@@ -867,4 +968,87 @@ void kgdb_interruptible (int yes)
#endif /* (CONFIG_KGDB_SER_INDEX & 2) */
#endif /* CFG_CMD_KGDB */
#if defined(CONFIG_SERIAL_MULTI)
int serial0_init(void)
{
return (serial_init_dev(UART0_BASE));
}
int serial1_init(void)
{
return (serial_init_dev(UART1_BASE));
}
void serial0_setbrg (void)
{
serial_setbrg_dev(UART0_BASE);
}
void serial1_setbrg (void)
{
serial_setbrg_dev(UART1_BASE);
}
void serial0_putc(const char c)
{
serial_putc_dev(UART0_BASE,c);
}
void serial1_putc(const char c)
{
serial_putc_dev(UART1_BASE, c);
}
void serial0_puts(const char *s)
{
serial_puts_dev(UART0_BASE, s);
}
void serial1_puts(const char *s)
{
serial_puts_dev(UART1_BASE, s);
}
int serial0_getc(void)
{
return(serial_getc_dev(UART0_BASE));
}
int serial1_getc(void)
{
return(serial_getc_dev(UART1_BASE));
}
int serial0_tstc(void)
{
return (serial_tstc_dev(UART0_BASE));
}
int serial1_tstc(void)
{
return (serial_tstc_dev(UART1_BASE));
}
struct serial_device serial0_device =
{
"serial0",
"UART0",
serial0_init,
serial0_setbrg,
serial0_getc,
serial0_tstc,
serial0_putc,
serial0_puts,
};
struct serial_device serial1_device =
{
"serial1",
"UART1",
serial1_init,
serial1_setbrg,
serial1_getc,
serial1_tstc,
serial1_putc,
serial1_puts,
};
#endif /* CONFIG_SERIAL_MULTI */
#endif /* CONFIG_405GP || CONFIG_405CR */

View File

@@ -25,4 +25,5 @@
PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
-mshort-load-bytes -msoft-float
PLATFORM_CPPFLAGS += -mapcs-32 -march=armv4 -mtune=strongarm1100
#PLATFORM_CPPFLAGS += -mapcs-32 -march=armv4 -mtune=strongarm1100
PLATFORM_CPPFLAGS += -mapcs-32 -march=armv5 -mtune=xscale

View File

@@ -147,7 +147,7 @@ clear_bss:
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
ble clbss_l
ldr pc, _start_armboot

View File

@@ -160,7 +160,7 @@ clear_bss:
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
ble clbss_l
ldr pc, _start_armboot

156
doc/README.COBRA5272 Normal file
View File

@@ -0,0 +1,156 @@
File: README.COBRA5272
Author: Florian Schlote for Sentec elektronik (linux@sentec-elektronik.de)
Contents: This is the README of u-boot (Universal bootloader) for our
COBRA5272 board.
Version: v01.00
Date: Tue Mar 30 00:28:33 CEST 2004
License: This document is published under the GNU GPL
______________________________________________________________________
CHANGES
040330 v01.00 Creation
______________________________________________________________________
CONFIGURING
-----------
1. Modify include/configs/cobra5272.h acc. to your prefs
2. If necessary, modify board/cobra5272/config.mk (see below)
3.
> make cobra5272_config
> make
Please refer to u-boot README (general info, u-boot-x-x-x/README),
to u-boot-x-x-x/doc/README.COBRA5272 and
to the comments in u-boot-x-x-x/include/configs/cobra5272.h
Configuring u-boot is done by commenting/uncommenting preprocessor defines.
Default configuration is
FLASH version (for further info see subsection below)
link address 0xffe00000
16 MB RAM
network enabled
no default IP address for target, host set, no MACaddress set
bootdelay for autoboot 5 sec.
autoboot disabled
#-----------------------------------
# u-boot FLASH version & RAM version
#-----------------------------------
The u-boot bootloader for Coldfire processors can be configured
1. as a standalone bootloader residing in flash & relocating itself to RAM on
startup automatically => "FLASH version"
2. as a RAM version which will not load from flash automatically as it needs a
prestage bootloader ("chainloading") & is running only from the RAM address it
is linked to => "RAM version"
This version may be very helpful when installing u-boot for the first time
since it can be used to make available s. th. like a "bootstrap
mechanism".
How to build the different images:
------------------------------
Flash version
------------------------------
Compile u-boot
in dir ./u-boot-x-x-x/
please first check:
in ./include/configs/cobra5272.h
CONFIG_MONITOR_IS_IN_RAM has to be undefined, e. g. as follows:
#if 0
#define CONFIG_MONITOR_IS_IN_RAM
/* define if monitor is started from a pre-loader */
#endif
=> u-boot as single bootloader starting from flash
in board/cobra5272/config.mk TEXT_BASE should be
TEXT_BASE = 0xffe00000
=> linking address for u-boot as single bootloader stored in flash
then:
host> make cobra5272_config
rm -f include/config.h include/config.mk
Configuring for cobra5272 board...
host> make
[...]
host> cp u-boot.bin /tftpboot/u-boot_flash.bin
------------------------------
RAM version
------------------------------
in dir ./u-boot-x-x-x/
host> make distclean
please modify the settings:
in ./include/configs/cobra5272.h
CONFIG_MONITOR_IS_IN_RAM now has to be defined, e. g. as follows:
#if 1
#define CONFIG_MONITOR_IS_IN_RAM
/*define if monitor is started from a pre-loader */
#endif
=> u-boot as RAM version, chainloaded by another bootloader or using bdm cable
in board/cobra5272/config.mk TEXT_BASE should be
TEXT_BASE = 0x00020000
=> target linking address for RAM
then:
host> make cobra5272_config
rm -f include/config.h include/config.mk
Configuring for cobra5272 board...
host> make
[...]
host> cp u-boot.bin /tftpboot/u-boot_ram.bin
----
HINT
----
If the m68k-elf-toolchain & the m68k-bdm-gdb is installed you can run the RAM
version by typing (in dir ./u-boot-x-x-x/)
"board/cobra5272/bdm/load-cobra_uboot" ,
in ./u-boot-x-x-x/ the RAM version u-boot (elf format) has to be available.

38
doc/README.ne2000 Normal file
View File

@@ -0,0 +1,38 @@
This driver supports NE2000 compatible cards (those based on DP8390,
DP83902 and similar). It can be used with PCMCIA/CF cards provided
that the CCR is correctly initialized.
The code is based on sources from the Linux kernel (pcnet_cs.c,
8390.h) and eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2
wonderful world are GPL, so this is, of course, GPL.
I developed and tested this driver on a custom PXA255 based system and
with a billionton CF network card connected to the PCMCIA interface of
the micro (have a look at README.PXA_CF for the support of this port).
The options you have to specify in the config file are (with the
value for my board as an example):
#define CONFIG_DRIVER_NE2000
- Enables the driver
#define CONFIG_DRIVER_NE2000_BASE (0x20000000+0x300)
- Address where the board is mapped
#define CONFIG_DRIVER_NE2000_CCR (0x28000000+0x3f8)
- Address of the CCR (card configuration register). It could be found
by enabling DEBUG in cmd_pcmcia.c. If this is not defined nothing is
done as far as PCMCIA support is concerned.
#define CONFIG_DRIVER_NE2000_VAL (0x20)
- The value to be written in the CCR. It selects among different I/O
spaces that could be used by the card.
Enjoy!
Christian Pellegrin <chri@ascensit.com>

View File

@@ -2,6 +2,8 @@ The support for multiple serial interfaces as implemented is mainly
intended to allow for modem dial-in / dial-out while still being able
to use a serial console on a (different) serial port.
MPC8XX Specific
===============
At the moment, the ports must be split on a SMC and a SCC port on a
8xx processor; other configurations are not (yet) supported.
@@ -35,3 +37,18 @@ just after switching the console:
After that press 'enter' at the SCC console. Note that baudrates <38400
are not allowed on LWMON with watchdog enabled (see CFG_BAUDRATE_TABLE in
include/configs/lwmon.h).
PPC4XX Specific
===============
*) The default console is UART0
*) The console can be switched to UART1 by any of the following commands:
setenv stdout serial1
setenv stderr serial1
setenv stdin serial1
*) The console can be switched to UART0 by any of the following commands:
setenv stdout serial0
setenv stderr serial0
setenv stdin serial0

124
drivers/8390.h Normal file
View File

@@ -0,0 +1,124 @@
/*
Ported to U-Boot by Christian Pellegrin <chri@ascensit.com>
Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
are GPL, so this is, of course, GPL.
*/
/* Generic NS8390 register definitions. */
/* This file is part of Donald Becker's 8390 drivers, and is distributed
under the same license. Auto-loading of 8390.o only in v2.2 - Paul G.
Some of these names and comments originated from the Crynwr
packet drivers, which are distributed under the GPL. */
#ifndef _8390_h
#define _8390_h
/* Some generic ethernet register configurations. */
#define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */
#define E8390_RX_IRQ_MASK 0x5
#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */
#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */
#define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */
#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */
/* Register accessed at EN_CMD, the 8390 base addr. */
#define E8390_STOP 0x01 /* Stop and reset the chip */
#define E8390_START 0x02 /* Start the chip, clear reset */
#define E8390_TRANS 0x04 /* Transmit a frame */
#define E8390_RREAD 0x08 /* Remote read */
#define E8390_RWRITE 0x10 /* Remote write */
#define E8390_NODMA 0x20 /* Remote DMA */
#define E8390_PAGE0 0x00 /* Select page chip registers */
#define E8390_PAGE1 0x40 /* using the two high-order bits */
#define E8390_PAGE2 0x80 /* Page 3 is invalid. */
/*
* Only generate indirect loads given a machine that needs them.
* - removed AMIGA_PCMCIA from this list, handled as ISA io now
*/
#define n2k_inb(port) (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE)))
#define n2k_outb(val,port) (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE)) = val)
#define EI_SHIFT(x) (x)
#define E8390_CMD EI_SHIFT(0x00) /* The command register (for all pages) */
/* Page 0 register offsets. */
#define EN0_CLDALO EI_SHIFT(0x01) /* Low byte of current local dma addr RD */
#define EN0_STARTPG EI_SHIFT(0x01) /* Starting page of ring bfr WR */
#define EN0_CLDAHI EI_SHIFT(0x02) /* High byte of current local dma addr RD */
#define EN0_STOPPG EI_SHIFT(0x02) /* Ending page +1 of ring bfr WR */
#define EN0_BOUNDARY EI_SHIFT(0x03) /* Boundary page of ring bfr RD WR */
#define EN0_TSR EI_SHIFT(0x04) /* Transmit status reg RD */
#define EN0_TPSR EI_SHIFT(0x04) /* Transmit starting page WR */
#define EN0_NCR EI_SHIFT(0x05) /* Number of collision reg RD */
#define EN0_TCNTLO EI_SHIFT(0x05) /* Low byte of tx byte count WR */
#define EN0_FIFO EI_SHIFT(0x06) /* FIFO RD */
#define EN0_TCNTHI EI_SHIFT(0x06) /* High byte of tx byte count WR */
#define EN0_ISR EI_SHIFT(0x07) /* Interrupt status reg RD WR */
#define EN0_CRDALO EI_SHIFT(0x08) /* low byte of current remote dma address RD */
#define EN0_RSARLO EI_SHIFT(0x08) /* Remote start address reg 0 */
#define EN0_CRDAHI EI_SHIFT(0x09) /* high byte, current remote dma address RD */
#define EN0_RSARHI EI_SHIFT(0x09) /* Remote start address reg 1 */
#define EN0_RCNTLO EI_SHIFT(0x0a) /* Remote byte count reg WR */
#define EN0_RCNTHI EI_SHIFT(0x0b) /* Remote byte count reg WR */
#define EN0_RSR EI_SHIFT(0x0c) /* rx status reg RD */
#define EN0_RXCR EI_SHIFT(0x0c) /* RX configuration reg WR */
#define EN0_TXCR EI_SHIFT(0x0d) /* TX configuration reg WR */
#define EN0_COUNTER0 EI_SHIFT(0x0d) /* Rcv alignment error counter RD */
#define EN0_DCFG EI_SHIFT(0x0e) /* Data configuration reg WR */
#define EN0_COUNTER1 EI_SHIFT(0x0e) /* Rcv CRC error counter RD */
#define EN0_IMR EI_SHIFT(0x0f) /* Interrupt mask reg WR */
#define EN0_COUNTER2 EI_SHIFT(0x0f) /* Rcv missed frame error counter RD */
/* Bits in EN0_ISR - Interrupt status register */
#define ENISR_RX 0x01 /* Receiver, no error */
#define ENISR_TX 0x02 /* Transmitter, no error */
#define ENISR_RX_ERR 0x04 /* Receiver, with error */
#define ENISR_TX_ERR 0x08 /* Transmitter, with error */
#define ENISR_OVER 0x10 /* Receiver overwrote the ring */
#define ENISR_COUNTERS 0x20 /* Counters need emptying */
#define ENISR_RDC 0x40 /* remote dma complete */
#define ENISR_RESET 0x80 /* Reset completed */
#define ENISR_ALL 0x3f /* Interrupts we will enable */
/* Bits in EN0_DCFG - Data config register */
#define ENDCFG_WTS 0x01 /* word transfer mode selection */
#define ENDCFG_BOS 0x02 /* byte order selection */
#define ENDCFG_AUTO_INIT 0x10 /* Auto-init to remove packets from ring */
#define ENDCFG_FIFO 0x40 /* 8 bytes */
/* Page 1 register offsets. */
#define EN1_PHYS EI_SHIFT(0x01) /* This board's physical enet addr RD WR */
#define EN1_PHYS_SHIFT(i) EI_SHIFT(i+1) /* Get and set mac address */
#define EN1_CURPAG EI_SHIFT(0x07) /* Current memory page RD WR */
#define EN1_MULT EI_SHIFT(0x08) /* Multicast filter mask array (8 bytes) RD WR */
#define EN1_MULT_SHIFT(i) EI_SHIFT(8+i) /* Get and set multicast filter */
/* Bits in received packet status byte and EN0_RSR*/
#define ENRSR_RXOK 0x01 /* Received a good packet */
#define ENRSR_CRC 0x02 /* CRC error */
#define ENRSR_FAE 0x04 /* frame alignment error */
#define ENRSR_FO 0x08 /* FIFO overrun */
#define ENRSR_MPA 0x10 /* missed pkt */
#define ENRSR_PHY 0x20 /* physical/multicast address */
#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */
#define ENRSR_DEF 0x80 /* deferring */
/* Transmitted packet status, EN0_TSR. */
#define ENTSR_PTX 0x01 /* Packet transmitted without error */
#define ENTSR_ND 0x02 /* The transmit wasn't deferred. */
#define ENTSR_COL 0x04 /* The transmit collided at least once. */
#define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */
#define ENTSR_CRS 0x10 /* The carrier sense was lost. */
#define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */
#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
#define ENTSR_OWC 0x80 /* There was an out-of-window collision. */
#define NIC_RECEIVE_MONITOR_MODE 0x20
#endif /* _8390_h */

View File

@@ -32,9 +32,10 @@ OBJS = 3c589.o 5701rls.o ali512x.o \
cs8900.o ct69000.o dataflash.o dc2114x.o dm9000x.o \
e1000.o eepro100.o \
i8042.o i82365.o inca-ip_sw.o keyboard.o \
lan91c96.o natsemi.o netarm_eth.o netconsole.o \
lan91c96.o \
natsemi.o ne2000.o netarm_eth.o netconsole.o \
ns16550.o ns8382x.o ns87308.o omap1510_i2c.o \
pci.o pci_auto.o pci_indirect.o \
omap24xx_i2c.o pci.o pci_auto.o pci_indirect.o \
pcnet.o plb2800_eth.o \
ps2ser.o ps2mult.o pc_keyb.o \
rtl8019.o rtl8139.o rtl8169.o \

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