mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-13 15:03:58 +03:00
Compare commits
21 Commits
LABEL_2004
...
LABEL_2005
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
436be29cad | ||
|
|
cd172b7108 | ||
|
|
c3d2b4b48a | ||
|
|
5a95f6fbd2 | ||
|
|
289f932c5f | ||
|
|
082acfd484 | ||
|
|
652a10c096 | ||
|
|
6225c5db6c | ||
|
|
8ed9604613 | ||
|
|
ff36fd8591 | ||
|
|
6310eb9da7 | ||
|
|
a562e1bd9d | ||
|
|
30ce5ab043 | ||
|
|
9dd611b8c1 | ||
|
|
a1191902ca | ||
|
|
15c7a8efd2 | ||
|
|
e2ffd59b4d | ||
|
|
400ab719c6 | ||
|
|
08f272787a | ||
|
|
bff96b0e6b | ||
|
|
ec0aee7b68 |
116
CHANGELOG
116
CHANGELOG
@@ -1,7 +1,121 @@
|
||||
======================================================================
|
||||
Changes since U-Boot 1.1.1:
|
||||
Changes for U-Boot 1.1.3:
|
||||
======================================================================
|
||||
|
||||
* 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
|
||||
|
||||
* Add support for UC100 board
|
||||
|
||||
* Patch by Stefan Roese, 16 Dez 2004:
|
||||
|
||||
6
CREDITS
6
CREDITS
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
26
MAKEALL
26
MAKEALL
@@ -51,7 +51,8 @@ LIST_8xx=" \
|
||||
FPS850L LANTEC QS850 TQM850L \
|
||||
GEN860T lwmon QS860T TQM855L \
|
||||
GEN860T_SC MBX quantum TQM860L \
|
||||
UC100 v37 \
|
||||
uc100 \
|
||||
v37 \
|
||||
"
|
||||
|
||||
#########################################################################
|
||||
@@ -98,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 \
|
||||
"
|
||||
|
||||
#########################################################################
|
||||
@@ -156,6 +157,11 @@ LIST_ARM9=" \
|
||||
versatile \
|
||||
"
|
||||
|
||||
#########################################################################
|
||||
## ARM11 Systems
|
||||
#########################################################################
|
||||
LIST_ARM11="omap2420h4"
|
||||
|
||||
#########################################################################
|
||||
## Xscale Systems
|
||||
#########################################################################
|
||||
@@ -169,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
|
||||
@@ -179,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
|
||||
@@ -237,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| \
|
||||
|
||||
29
Makefile
29
Makefile
@@ -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 $< $@
|
||||
|
||||
@@ -667,7 +670,7 @@ TTTech_config: unconfig
|
||||
@echo "#define CONFIG_SHARP_LQ104V7DS01" >>include/config.h
|
||||
@./mkconfig -a TQM823L ppc mpc8xx tqm8xx
|
||||
|
||||
UC100_config : unconfig
|
||||
uc100_config : unconfig
|
||||
@./mkconfig $(@:_config=) ppc mpc8xx uc100
|
||||
|
||||
v37_config: unconfig
|
||||
@@ -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
17
README
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
TEXT_BASE = 0x20f00000
|
||||
TEXT_BASE = 0x20F00000
|
||||
## For testing: load at 0x20100000 and "go" at 0x201000A4
|
||||
#TEXT_BASE = 0x20100000
|
||||
|
||||
@@ -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
40
board/cobra5272/Makefile
Normal 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
|
||||
|
||||
#########################################################################
|
||||
169
board/cobra5272/bdm/cobra5272_uboot.gdb
Normal file
169
board/cobra5272/bdm/cobra5272_uboot.gdb
Normal 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
|
||||
2
board/cobra5272/bdm/gdbinit.reset
Normal file
2
board/cobra5272/bdm/gdbinit.reset
Normal file
@@ -0,0 +1,2 @@
|
||||
target bdm /dev/bdmcf0
|
||||
q
|
||||
2
board/cobra5272/bdm/load-cobra_uboot
Normal file
2
board/cobra5272/bdm/load-cobra_uboot
Normal file
@@ -0,0 +1,2 @@
|
||||
m68k-bdm-elf-gdb -n -x board/cobra5272/bdm/cobra5272_uboot.gdb u-boot
|
||||
|
||||
2
board/cobra5272/bdm/reset
Normal file
2
board/cobra5272/bdm/reset
Normal file
@@ -0,0 +1,2 @@
|
||||
m68k-bdm-elf-gdb -n -x bdm/gdbinit.reset
|
||||
|
||||
55
board/cobra5272/cobra5272.c
Normal file
55
board/cobra5272/cobra5272.c
Normal 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
25
board/cobra5272/config.mk
Normal 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
378
board/cobra5272/flash.c
Normal 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
142
board/cobra5272/u-boot.lds
Normal 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 = .);
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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
68
board/cpc45/pd67290.c
Normal 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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -227,6 +227,10 @@ int checkboard (void)
|
||||
major = 1;
|
||||
minor = 1;
|
||||
break;
|
||||
case 0x06:
|
||||
major = 1;
|
||||
minor = 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
47
board/omap2420h4/Makefile
Normal 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
|
||||
|
||||
#########################################################################
|
||||
22
board/omap2420h4/config.mk
Normal file
22
board/omap2420h4/config.mk
Normal 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
537
board/omap2420h4/flash.c
Normal 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
345
board/omap2420h4/mem.c
Normal 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);
|
||||
}
|
||||
859
board/omap2420h4/omap2420h4.c
Normal file
859
board/omap2420h4/omap2420h4.c
Normal 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
185
board/omap2420h4/platform.S
Normal 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
302
board/omap2420h4/sys_info.c
Normal 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);
|
||||
}
|
||||
58
board/omap2420h4/u-boot.lds
Normal file
58
board/omap2420h4/u-boot.lds
Normal 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
48
board/pleb2/Makefile
Normal 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
3
board/pleb2/config.mk
Normal file
@@ -0,0 +1,3 @@
|
||||
TEXT_BASE = 0xa1F80000
|
||||
#TEXT_BASE = 0xa3080000
|
||||
#TEXT_BASE = 0
|
||||
814
board/pleb2/flash.c
Normal file
814
board/pleb2/flash.c
Normal 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
488
board/pleb2/memsetup.S
Normal 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
76
board/pleb2/pleb2.c
Normal 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
55
board/pleb2/u-boot.lds
Normal 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 = .;
|
||||
}
|
||||
@@ -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
46
board/sbc405/Makefile
Normal 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
28
board/sbc405/config.mk
Normal 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
114
board/sbc405/sbc405.c
Normal 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
793
board/sbc405/strataflash.c
Normal 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
147
board/sbc405/u-boot.lds
Normal 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 = .);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2002
|
||||
* (C) Copyright 2000-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
@@ -144,7 +144,7 @@ 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);
|
||||
@@ -957,13 +957,17 @@ 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;
|
||||
EIEIO;
|
||||
*dbuf++ = *pbuf_even;
|
||||
EIEIO;
|
||||
EIEIO;
|
||||
*dbuf++ = *pbuf_odd;
|
||||
EIEIO;
|
||||
EIEIO;
|
||||
*dbuf++ = *pbuf_even;
|
||||
EIEIO;
|
||||
EIEIO;
|
||||
*dbuf++ = *pbuf_odd;
|
||||
}
|
||||
#endif /* CONFIG_HMI10 */
|
||||
@@ -1548,11 +1552,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,7 +1583,6 @@ static void ide_led (uchar led, uchar status)
|
||||
* ATAPI Support
|
||||
*/
|
||||
|
||||
|
||||
#undef ATAPI_DEBUG
|
||||
|
||||
#ifdef ATAPI_DEBUG
|
||||
@@ -1661,7 +1665,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)
|
||||
{
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
43
cpu/arm1136/Makefile
Normal 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
26
cpu/arm1136/config.mk
Normal 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
163
cpu/arm1136/cpu.c
Normal 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
290
cpu/arm1136/interrupts.c
Normal 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
406
cpu/arm1136/start.S
Normal 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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -148,7 +148,9 @@ int dcache_status (void)
|
||||
}
|
||||
|
||||
/* FIXME */
|
||||
/*
|
||||
void pci_init(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
616
cpu/ixp/pci.c
Normal file
616
cpu/ixp/pci.c
Normal 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 */
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
156
doc/README.COBRA5272
Normal 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
38
doc/README.ne2000
Normal 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>
|
||||
@@ -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
124
drivers/8390.h
Normal 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 */
|
||||
@@ -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 \
|
||||
|
||||
@@ -1066,10 +1066,22 @@ static ulong flash_get_size (ulong base, int banknum)
|
||||
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);
|
||||
|
||||
/*
|
||||
* Only read protection status from supported devices (intel...)
|
||||
*/
|
||||
switch (info->vendor) {
|
||||
case CFI_CMDSET_INTEL_EXTENDED:
|
||||
case CFI_CMDSET_INTEL_STANDARD:
|
||||
info->protect[sect_cnt] =
|
||||
flash_isset (info, sect_cnt,
|
||||
FLASH_OFFSET_PROTECT,
|
||||
FLASH_STATUS_PROTECT);
|
||||
break;
|
||||
default:
|
||||
info->protect[sect_cnt] = 0; /* default: not protected */
|
||||
}
|
||||
|
||||
sect_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
477
drivers/i82365.c
477
drivers/i82365.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* (C) Copyright 2003-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
@@ -40,32 +40,65 @@
|
||||
|
||||
#include <pcmcia/ss.h>
|
||||
#include <pcmcia/i82365.h>
|
||||
#include <pcmcia/ti113x.h>
|
||||
#include <pcmcia/yenta.h>
|
||||
|
||||
/* #define DEBUG */
|
||||
#ifdef CONFIG_CPC45
|
||||
#include <pcmcia/cirrus.h>
|
||||
#else
|
||||
#include <pcmcia/ti113x.h>
|
||||
#endif
|
||||
|
||||
static struct pci_device_id supported[] = {
|
||||
#ifdef CONFIG_CPC45
|
||||
{PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6729},
|
||||
#else
|
||||
{PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1510},
|
||||
#endif
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
#define CYCLE_TIME 120
|
||||
|
||||
#ifdef CONFIG_CPC45
|
||||
extern int SPD67290Init (void);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
static void i82365_dump_regions (pci_dev_t dev);
|
||||
#endif
|
||||
|
||||
typedef struct socket_info_t {
|
||||
pci_dev_t dev;
|
||||
u_short bcr;
|
||||
u_char pci_lat, cb_lat, sub_bus, cache;
|
||||
u_int cb_phys;
|
||||
pci_dev_t dev;
|
||||
u_short bcr;
|
||||
u_char pci_lat, cb_lat, sub_bus, cache;
|
||||
u_int cb_phys;
|
||||
|
||||
socket_cap_t cap;
|
||||
ti113x_state_t state;
|
||||
socket_cap_t cap;
|
||||
u_short type;
|
||||
u_int flags;
|
||||
#ifdef CONFIG_CPC45
|
||||
cirrus_state_t c_state;
|
||||
#else
|
||||
ti113x_state_t state;
|
||||
#endif
|
||||
} socket_info_t;
|
||||
|
||||
#ifdef CONFIG_CPC45
|
||||
/* These definitions must match the pcic table! */
|
||||
typedef enum pcic_id {
|
||||
IS_PD6710, IS_PD672X, IS_VT83C469
|
||||
} pcic_id;
|
||||
|
||||
typedef struct pcic_t {
|
||||
char *name;
|
||||
} pcic_t;
|
||||
|
||||
static pcic_t pcic[] = {
|
||||
{" Cirrus PD6710: "},
|
||||
{" Cirrus PD672x: "},
|
||||
{" VIA VT83C469: "},
|
||||
};
|
||||
#endif
|
||||
|
||||
static socket_info_t socket;
|
||||
static socket_state_t state;
|
||||
static struct pccard_mem_map mem;
|
||||
@@ -91,6 +124,7 @@ static int pci_writew (socket_info_t * s, int r, u_short v)
|
||||
{
|
||||
return pci_write_config_word (s->dev, r, v);
|
||||
}
|
||||
#ifndef CONFIG_CPC45
|
||||
static int pci_readl (socket_info_t * s, int r, u_int * v)
|
||||
{
|
||||
return pci_read_config_dword (s->dev, r, v);
|
||||
@@ -99,14 +133,61 @@ static int pci_writel (socket_info_t * s, int r, u_int v)
|
||||
{
|
||||
return pci_write_config_dword (s->dev, r, v);
|
||||
}
|
||||
#endif /* !CONFIG_CPC45 */
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
#ifdef CONFIG_CPC45
|
||||
|
||||
#define cb_readb(s) readb((s)->cb_phys + 1)
|
||||
#define cb_writeb(s, v) writeb(v, (s)->cb_phys)
|
||||
#define cb_writeb2(s, v) writeb(v, (s)->cb_phys + 1)
|
||||
#define cb_readl(s, r) readl((s)->cb_phys + (r))
|
||||
#define cb_writel(s, r, v) writel(v, (s)->cb_phys + (r))
|
||||
|
||||
|
||||
static u_char i365_get (socket_info_t * s, u_short reg)
|
||||
{
|
||||
u_char val;
|
||||
#ifdef CONFIG_PCMCIA_SLOT_A
|
||||
int slot = 0;
|
||||
#else
|
||||
int slot = 1;
|
||||
#endif
|
||||
|
||||
val = I365_REG (slot, reg);
|
||||
|
||||
cb_writeb (s, val);
|
||||
val = cb_readb (s);
|
||||
|
||||
debug ("i365_get slot:%x reg: %x val: %x\n", slot, reg, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static void i365_set (socket_info_t * s, u_short reg, u_char data)
|
||||
{
|
||||
#ifdef CONFIG_PCMCIA_SLOT_A
|
||||
int slot = 0;
|
||||
#else
|
||||
int slot = 1;
|
||||
#endif
|
||||
u_char val;
|
||||
|
||||
val = I365_REG (slot, reg);
|
||||
|
||||
cb_writeb (s, val);
|
||||
cb_writeb2 (s, data);
|
||||
|
||||
debug ("i365_set slot:%x reg: %x data:%x\n", slot, reg, data);
|
||||
}
|
||||
|
||||
#else /* ! CONFIG_CPC45 */
|
||||
|
||||
#define cb_readb(s, r) readb((s)->cb_phys + (r))
|
||||
#define cb_readl(s, r) readl((s)->cb_phys + (r))
|
||||
#define cb_writeb(s, r, v) writeb(v, (s)->cb_phys + (r))
|
||||
#define cb_writel(s, r, v) writel(v, (s)->cb_phys + (r))
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
static u_char i365_get (socket_info_t * s, u_short reg)
|
||||
{
|
||||
return cb_readb (s, 0x0800 + reg);
|
||||
@@ -116,6 +197,7 @@ static void i365_set (socket_info_t * s, u_short reg, u_char data)
|
||||
{
|
||||
cb_writeb (s, 0x0800 + reg, data);
|
||||
}
|
||||
#endif /* CONFIG_CPC45 */
|
||||
|
||||
static void i365_bset (socket_info_t * s, u_short reg, u_char mask)
|
||||
{
|
||||
@@ -147,6 +229,115 @@ static void i365_set_pair (socket_info_t * s, u_short reg, u_short data)
|
||||
i365_set (s, reg + 1, data >> 8);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPC45
|
||||
/*======================================================================
|
||||
|
||||
Code to save and restore global state information for Cirrus
|
||||
PD67xx controllers, and to set and report global configuration
|
||||
options.
|
||||
|
||||
======================================================================*/
|
||||
|
||||
#define flip(v,b,f) (v = ((f)<0) ? v : ((f) ? ((v)|(b)) : ((v)&(~b))))
|
||||
|
||||
static void cirrus_get_state (socket_info_t * s)
|
||||
{
|
||||
int i;
|
||||
cirrus_state_t *p = &s->c_state;
|
||||
|
||||
p->misc1 = i365_get (s, PD67_MISC_CTL_1);
|
||||
p->misc1 &= (PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
|
||||
p->misc2 = i365_get (s, PD67_MISC_CTL_2);
|
||||
for (i = 0; i < 6; i++)
|
||||
p->timer[i] = i365_get (s, PD67_TIME_SETUP (0) + i);
|
||||
|
||||
}
|
||||
|
||||
static void cirrus_set_state (socket_info_t * s)
|
||||
{
|
||||
int i;
|
||||
u_char misc;
|
||||
cirrus_state_t *p = &s->c_state;
|
||||
|
||||
misc = i365_get (s, PD67_MISC_CTL_2);
|
||||
i365_set (s, PD67_MISC_CTL_2, p->misc2);
|
||||
if (misc & PD67_MC2_SUSPEND)
|
||||
udelay (50000);
|
||||
misc = i365_get (s, PD67_MISC_CTL_1);
|
||||
misc &= ~(PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
|
||||
i365_set (s, PD67_MISC_CTL_1, misc | p->misc1);
|
||||
for (i = 0; i < 6; i++)
|
||||
i365_set (s, PD67_TIME_SETUP (0) + i, p->timer[i]);
|
||||
}
|
||||
|
||||
static u_int cirrus_set_opts (socket_info_t * s)
|
||||
{
|
||||
cirrus_state_t *p = &s->c_state;
|
||||
u_int mask = 0xffff;
|
||||
#if DEBUG
|
||||
char buf[200];
|
||||
|
||||
memset (buf, 0, 200);
|
||||
#endif
|
||||
|
||||
if (has_ring == -1)
|
||||
has_ring = 1;
|
||||
flip (p->misc2, PD67_MC2_IRQ15_RI, has_ring);
|
||||
flip (p->misc2, PD67_MC2_DYNAMIC_MODE, dynamic_mode);
|
||||
#if DEBUG
|
||||
if (p->misc2 & PD67_MC2_IRQ15_RI)
|
||||
strcat (buf, " [ring]");
|
||||
if (p->misc2 & PD67_MC2_DYNAMIC_MODE)
|
||||
strcat (buf, " [dyn mode]");
|
||||
if (p->misc1 & PD67_MC1_INPACK_ENA)
|
||||
strcat (buf, " [inpack]");
|
||||
#endif
|
||||
|
||||
if (p->misc2 & PD67_MC2_IRQ15_RI)
|
||||
mask &= ~0x8000;
|
||||
if (has_led > 0) {
|
||||
#if DEBUG
|
||||
strcat (buf, " [led]");
|
||||
#endif
|
||||
mask &= ~0x1000;
|
||||
}
|
||||
if (has_dma > 0) {
|
||||
#if DEBUG
|
||||
strcat (buf, " [dma]");
|
||||
#endif
|
||||
mask &= ~0x0600;
|
||||
flip (p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass);
|
||||
#if DEBUG
|
||||
if (p->misc2 & PD67_MC2_FREQ_BYPASS)
|
||||
strcat (buf, " [freq bypass]");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (setup_time >= 0)
|
||||
p->timer[0] = p->timer[3] = setup_time;
|
||||
if (cmd_time > 0) {
|
||||
p->timer[1] = cmd_time;
|
||||
p->timer[4] = cmd_time * 2 + 4;
|
||||
}
|
||||
if (p->timer[1] == 0) {
|
||||
p->timer[1] = 6;
|
||||
p->timer[4] = 16;
|
||||
if (p->timer[0] == 0)
|
||||
p->timer[0] = p->timer[3] = 1;
|
||||
}
|
||||
if (recov_time >= 0)
|
||||
p->timer[2] = p->timer[5] = recov_time;
|
||||
|
||||
debug ("i82365 Opt: %s [%d/%d/%d] [%d/%d/%d]\n",
|
||||
buf,
|
||||
p->timer[0], p->timer[1], p->timer[2],
|
||||
p->timer[3], p->timer[4], p->timer[5]);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_CPC45 */
|
||||
|
||||
/*======================================================================
|
||||
|
||||
Code to save and restore global state information for TI 1130 and
|
||||
@@ -190,6 +381,7 @@ static u_int ti113x_set_opts (socket_info_t * s)
|
||||
|
||||
return mask;
|
||||
}
|
||||
#endif /* CONFIG_CPC45 */
|
||||
|
||||
/*======================================================================
|
||||
|
||||
@@ -213,8 +405,10 @@ static void cb_get_state (socket_info_t * s)
|
||||
|
||||
static void cb_set_state (socket_info_t * s)
|
||||
{
|
||||
#ifndef CONFIG_CPC45
|
||||
pci_writel (s, CB_LEGACY_MODE_BASE, 0);
|
||||
pci_writel (s, PCI_BASE_ADDRESS_0, s->cb_phys);
|
||||
#endif
|
||||
pci_writew (s, PCI_COMMAND, CMD_DFLT);
|
||||
pci_writeb (s, PCI_CACHE_LINE_SIZE, s->cache);
|
||||
pci_writeb (s, PCI_LATENCY_TIMER, s->pci_lat);
|
||||
@@ -226,12 +420,14 @@ static void cb_set_state (socket_info_t * s)
|
||||
|
||||
static void cb_set_opts (socket_info_t * s)
|
||||
{
|
||||
#ifndef CONFIG_CPC45
|
||||
if (s->cache == 0)
|
||||
s->cache = 8;
|
||||
if (s->pci_lat == 0)
|
||||
s->pci_lat = 0xa8;
|
||||
if (s->cb_lat == 0)
|
||||
s->cb_lat = 0xb0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
@@ -245,9 +441,70 @@ static int cb_set_power (socket_info_t * s, socket_state_t * state)
|
||||
{
|
||||
u_int reg = 0;
|
||||
|
||||
#ifdef CONFIG_CPC45
|
||||
|
||||
if ((state->Vcc == 0) && (state->Vpp == 0)) {
|
||||
u_char power, vcc, vpp;
|
||||
|
||||
power = i365_get (s, I365_POWER);
|
||||
state->flags |= (power & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
|
||||
state->flags |= (power & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
|
||||
vcc = power & I365_VCC_MASK;
|
||||
vpp = power & I365_VPP1_MASK;
|
||||
state->Vcc = state->Vpp = 0;
|
||||
if (i365_get (s, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) {
|
||||
if (power & I365_VCC_5V)
|
||||
state->Vcc = 33;
|
||||
if (vpp == I365_VPP1_5V)
|
||||
state->Vpp = 33;
|
||||
} else {
|
||||
if (power & I365_VCC_5V)
|
||||
state->Vcc = 50;
|
||||
if (vpp == I365_VPP1_5V)
|
||||
state->Vpp = 50;
|
||||
}
|
||||
if (power == I365_VPP1_12V)
|
||||
state->Vpp = 120;
|
||||
printf ("POWER Vcc:%d Vpp: %d\n", state->Vcc, state->Vpp);
|
||||
}
|
||||
|
||||
reg = I365_PWR_NORESET;
|
||||
if (state->flags & SS_PWR_AUTO)
|
||||
reg |= I365_PWR_AUTO;
|
||||
if (state->flags & SS_OUTPUT_ENA)
|
||||
reg |= I365_PWR_OUT;
|
||||
if (state->Vpp != 0) {
|
||||
if (state->Vpp == 120) {
|
||||
reg |= I365_VPP1_12V;
|
||||
puts (" 12V card found: ");
|
||||
} else if (state->Vpp == state->Vcc) {
|
||||
reg |= I365_VPP1_5V;
|
||||
} else {
|
||||
puts (" power not found: ");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (state->Vcc != 0) {
|
||||
reg |= I365_VCC_5V;
|
||||
if (state->Vcc == 33) {
|
||||
puts (" 3.3V card found: ");
|
||||
i365_bset (s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
|
||||
} else if (state->Vcc == 50) {
|
||||
puts (" 5V card found: ");
|
||||
i365_bclr (s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
|
||||
} else {
|
||||
puts (" power not found: ");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (reg != i365_get (s, I365_POWER))
|
||||
i365_set (s, I365_POWER, reg);
|
||||
|
||||
#else /* ! CONFIG_CPC45 */
|
||||
|
||||
/* restart card voltage detection if it seems appropriate */
|
||||
if ((state->Vcc == 0) && (state->Vpp == 0) &&
|
||||
!(cb_readl (s, CB_SOCKET_STATE) & CB_SS_VSENSE))
|
||||
!(cb_readl (s, CB_SOCKET_STATE) & CB_SS_VSENSE))
|
||||
cb_writel (s, CB_SOCKET_FORCE, CB_SF_CVSTEST);
|
||||
switch (state->Vcc) {
|
||||
case 0:
|
||||
@@ -279,6 +536,7 @@ static int cb_set_power (socket_info_t * s, socket_state_t * state)
|
||||
}
|
||||
if (reg != cb_readl (s, CB_SOCKET_CONTROL))
|
||||
cb_writel (s, CB_SOCKET_CONTROL, reg);
|
||||
#endif /* CONFIG_CPC45 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -290,7 +548,11 @@ static int cb_set_power (socket_info_t * s, socket_state_t * state)
|
||||
|
||||
static void get_bridge_state (socket_info_t * s)
|
||||
{
|
||||
#ifdef CONFIG_CPC45
|
||||
cirrus_get_state (s);
|
||||
#else
|
||||
ti113x_get_state (s);
|
||||
#endif
|
||||
cb_get_state (s);
|
||||
}
|
||||
|
||||
@@ -299,12 +561,20 @@ static void set_bridge_state (socket_info_t * s)
|
||||
cb_set_state (s);
|
||||
i365_set (s, I365_GBLCTL, 0x00);
|
||||
i365_set (s, I365_GENCTL, 0x00);
|
||||
#ifdef CONFIG_CPC45
|
||||
cirrus_set_state (s);
|
||||
#else
|
||||
ti113x_set_state (s);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void set_bridge_opts (socket_info_t * s)
|
||||
{
|
||||
#ifdef CONFIG_CPC45
|
||||
cirrus_set_opts (s);
|
||||
#else
|
||||
ti113x_set_opts (s);
|
||||
#endif
|
||||
cb_set_opts (s);
|
||||
}
|
||||
|
||||
@@ -313,7 +583,12 @@ static void set_bridge_opts (socket_info_t * s)
|
||||
static int i365_get_status (socket_info_t * s, u_int * value)
|
||||
{
|
||||
u_int status;
|
||||
#ifdef CONFIG_CPC45
|
||||
u_char val;
|
||||
u_char power, vcc, vpp;
|
||||
#endif
|
||||
|
||||
status = i365_get (s, I365_IDENT);
|
||||
status = i365_get (s, I365_STATUS);
|
||||
*value = ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
|
||||
if (i365_get (s, I365_INTCTL) & I365_PC_IOCARD) {
|
||||
@@ -326,6 +601,69 @@ static int i365_get_status (socket_info_t * s, u_int * value)
|
||||
*value |= (status & I365_CS_READY) ? SS_READY : 0;
|
||||
*value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
|
||||
|
||||
#ifdef CONFIG_CPC45
|
||||
/* Check for Cirrus CL-PD67xx chips */
|
||||
i365_set (s, PD67_CHIP_INFO, 0);
|
||||
val = i365_get (s, PD67_CHIP_INFO);
|
||||
s->type = -1;
|
||||
if ((val & PD67_INFO_CHIP_ID) == PD67_INFO_CHIP_ID) {
|
||||
val = i365_get (s, PD67_CHIP_INFO);
|
||||
if ((val & PD67_INFO_CHIP_ID) == 0) {
|
||||
s->type = (val & PD67_INFO_SLOTS) ? IS_PD672X : IS_PD6710;
|
||||
i365_set (s, PD67_EXT_INDEX, 0xe5);
|
||||
if (i365_get (s, PD67_EXT_INDEX) != 0xe5)
|
||||
s->type = IS_VT83C469;
|
||||
}
|
||||
} else {
|
||||
printf ("no Cirrus Chip found\n");
|
||||
*value = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
i365_bset (s, I365_POWER, I365_VCC_5V);
|
||||
power = i365_get (s, I365_POWER);
|
||||
state.flags |= (power & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
|
||||
state.flags |= (power & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
|
||||
vcc = power & I365_VCC_MASK;
|
||||
vpp = power & I365_VPP1_MASK;
|
||||
state.Vcc = state.Vpp = 0;
|
||||
if (i365_get (s, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) {
|
||||
if (power & I365_VCC_5V)
|
||||
state.Vcc = 33;
|
||||
if (vpp == I365_VPP1_5V)
|
||||
state.Vpp = 33;
|
||||
} else {
|
||||
if (power & I365_VCC_5V)
|
||||
state.Vcc = 50;
|
||||
if (vpp == I365_VPP1_5V)
|
||||
state.Vpp = 50;
|
||||
}
|
||||
if (power == I365_VPP1_12V)
|
||||
state.Vpp = 120;
|
||||
|
||||
/* IO card, RESET flags, IO interrupt */
|
||||
power = i365_get (s, I365_INTCTL);
|
||||
state.flags |= (power & I365_PC_RESET) ? 0 : SS_RESET;
|
||||
if (power & I365_PC_IOCARD)
|
||||
state.flags |= SS_IOCARD;
|
||||
state.io_irq = power & I365_IRQ_MASK;
|
||||
|
||||
/* Card status change mask */
|
||||
power = i365_get (s, I365_CSCINT);
|
||||
state.csc_mask = (power & I365_CSC_DETECT) ? SS_DETECT : 0;
|
||||
if (state.flags & SS_IOCARD)
|
||||
state.csc_mask |= (power & I365_CSC_STSCHG) ? SS_STSCHG : 0;
|
||||
else {
|
||||
state.csc_mask |= (power & I365_CSC_BVD1) ? SS_BATDEAD : 0;
|
||||
state.csc_mask |= (power & I365_CSC_BVD2) ? SS_BATWARN : 0;
|
||||
state.csc_mask |= (power & I365_CSC_READY) ? SS_READY : 0;
|
||||
}
|
||||
debug ("i82365: GetStatus(0) = flags %#3.3x, Vcc %d, Vpp %d, "
|
||||
"io_irq %d, csc_mask %#2.2x\n", state.flags,
|
||||
state.Vcc, state.Vpp, state.io_irq, state.csc_mask);
|
||||
|
||||
#else /* !CONFIG_CPC45 */
|
||||
|
||||
status = cb_readl (s, CB_SOCKET_STATE);
|
||||
*value |= (status & CB_SS_32BIT) ? SS_CARDBUS : 0;
|
||||
*value |= (status & CB_SS_3VCARD) ? SS_3VCARD : 0;
|
||||
@@ -334,7 +672,7 @@ static int i365_get_status (socket_info_t * s, u_int * value)
|
||||
/* For now, ignore cards with unsupported voltage keys */
|
||||
if (*value & SS_XVCARD)
|
||||
*value &= ~(SS_DETECT | SS_3VCARD | SS_XVCARD);
|
||||
|
||||
#endif /* CONFIG_CPC45 */
|
||||
return 0;
|
||||
} /* i365_get_status */
|
||||
|
||||
@@ -350,6 +688,31 @@ static int i365_set_socket (socket_info_t * s, socket_state_t * state)
|
||||
reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
|
||||
i365_set (s, I365_INTCTL, reg);
|
||||
|
||||
#ifdef CONFIG_CPC45
|
||||
cb_set_power (s, state);
|
||||
|
||||
#if 0
|
||||
/* Card status change interrupt mask */
|
||||
reg = s->cs_irq << 4;
|
||||
if (state->csc_mask & SS_DETECT)
|
||||
reg |= I365_CSC_DETECT;
|
||||
if (state->flags & SS_IOCARD) {
|
||||
if (state->csc_mask & SS_STSCHG)
|
||||
reg |= I365_CSC_STSCHG;
|
||||
} else {
|
||||
if (state->csc_mask & SS_BATDEAD)
|
||||
reg |= I365_CSC_BVD1;
|
||||
if (state->csc_mask & SS_BATWARN)
|
||||
reg |= I365_CSC_BVD2;
|
||||
if (state->csc_mask & SS_READY)
|
||||
reg |= I365_CSC_READY;
|
||||
}
|
||||
i365_set (s, I365_CSCINT, reg);
|
||||
i365_get (s, I365_CSC);
|
||||
#endif /* 0 */
|
||||
|
||||
#else /* !CONFIG_CPC45 */
|
||||
|
||||
reg = I365_PWR_NORESET;
|
||||
if (state->flags & SS_PWR_AUTO)
|
||||
reg |= I365_PWR_AUTO;
|
||||
@@ -361,6 +724,7 @@ static int i365_set_socket (socket_info_t * s, socket_state_t * state)
|
||||
|
||||
if (reg != i365_get (s, I365_POWER))
|
||||
i365_set (s, I365_POWER, reg);
|
||||
#endif /* CONFIG_CPC45 */
|
||||
|
||||
return 0;
|
||||
} /* i365_set_socket */
|
||||
@@ -372,6 +736,10 @@ static int i365_set_mem_map (socket_info_t * s, struct pccard_mem_map *mem)
|
||||
u_short base, i;
|
||||
u_char map;
|
||||
|
||||
debug ("i82365: SetMemMap(%d, %#2.2x, %d ns, %#5.5lx-%#5.5lx, %#5.5x)\n",
|
||||
mem->map, mem->flags, mem->speed,
|
||||
mem->sys_start, mem->sys_stop, mem->card_start);
|
||||
|
||||
map = mem->map;
|
||||
if ((map > 4) ||
|
||||
(mem->card_start > 0x3ffffff) ||
|
||||
@@ -411,13 +779,23 @@ static int i365_set_mem_map (socket_info_t * s, struct pccard_mem_map *mem)
|
||||
}
|
||||
i365_set_pair (s, base + I365_W_STOP, i);
|
||||
|
||||
#ifdef CONFIG_CPC45
|
||||
i = 0;
|
||||
#else
|
||||
i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff;
|
||||
#endif
|
||||
if (mem->flags & MAP_WRPROT)
|
||||
i |= I365_MEM_WRPROT;
|
||||
if (mem->flags & MAP_ATTRIB)
|
||||
i |= I365_MEM_REG;
|
||||
i365_set_pair (s, base + I365_W_OFF, i);
|
||||
|
||||
#ifdef CONFIG_CPC45
|
||||
/* set System Memory map Upper Adress */
|
||||
i365_set(s, PD67_EXT_INDEX, PD67_MEM_PAGE(map));
|
||||
i365_set(s, PD67_EXT_DATA, ((mem->sys_start >> 24) & 0xff));
|
||||
#endif
|
||||
|
||||
/* Turn on the window if necessary */
|
||||
if (mem->flags & MAP_ACTIVE)
|
||||
i365_bset (s, I365_ADDRWIN, I365_ENA_MEM (map));
|
||||
@@ -431,7 +809,7 @@ static int i365_set_io_map (socket_info_t * s, struct pccard_io_map *io)
|
||||
map = io->map;
|
||||
/* comment out: comparison is always false due to limited range of data type */
|
||||
if ((map > 1) || /* (io->start > 0xffff) || (io->stop > 0xffff) || */
|
||||
(io->stop < io->start))
|
||||
(io->stop < io->start))
|
||||
return -1;
|
||||
/* Turn off the window before changing anything */
|
||||
if (i365_get (s, I365_ADDRWIN) & I365_ENA_IO (map))
|
||||
@@ -461,19 +839,41 @@ int i82365_init (void)
|
||||
u_int val;
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_CPC45
|
||||
if (SPD67290Init () != 0)
|
||||
return 1;
|
||||
#endif
|
||||
if ((socket.dev = pci_find_devices (supported, 0)) < 0) {
|
||||
/* Controller not found */
|
||||
return 1;
|
||||
}
|
||||
debug ("i82365 Device Found!\n");
|
||||
|
||||
pci_read_config_dword (socket.dev, PCI_BASE_ADDRESS_0, &socket.cb_phys);
|
||||
socket.cb_phys &= ~0xf;
|
||||
|
||||
#ifdef CONFIG_CPC45
|
||||
/* + 0xfe000000 see MPC 8245 Users Manual Adress Map B */
|
||||
socket.cb_phys += 0xfe000000;
|
||||
#endif
|
||||
|
||||
get_bridge_state (&socket);
|
||||
set_bridge_opts (&socket);
|
||||
|
||||
i365_get_status (&socket, &val);
|
||||
i = i365_get_status (&socket, &val);
|
||||
|
||||
#ifdef CONFIG_CPC45
|
||||
if (i > -1) {
|
||||
puts (pcic[socket.type].name);
|
||||
} else {
|
||||
printf ("i82365: Controller not found.\n");
|
||||
return 1;
|
||||
}
|
||||
if((val & SS_DETECT) != SS_DETECT){
|
||||
puts ("No card\n");
|
||||
return 1;
|
||||
}
|
||||
#else /* !CONFIG_CPC45 */
|
||||
if (val & SS_DETECT) {
|
||||
if (val & SS_3VCARD) {
|
||||
state.Vcc = state.Vpp = 33;
|
||||
@@ -482,17 +882,23 @@ int i82365_init (void)
|
||||
state.Vcc = state.Vpp = 50;
|
||||
puts (" 5.0V card found: ");
|
||||
} else {
|
||||
printf ("i82365: unsupported voltage key\n");
|
||||
puts ("i82365: unsupported voltage key\n");
|
||||
state.Vcc = state.Vpp = 0;
|
||||
}
|
||||
} else {
|
||||
/* No card inserted */
|
||||
puts ("No card\n");
|
||||
return 1;
|
||||
}
|
||||
#endif /* CONFIG_CPC45 */
|
||||
|
||||
#ifdef CONFIG_CPC45
|
||||
state.flags |= SS_OUTPUT_ENA;
|
||||
#else
|
||||
state.flags = SS_IOCARD | SS_OUTPUT_ENA;
|
||||
state.csc_mask = 0;
|
||||
state.io_irq = 0;
|
||||
#endif
|
||||
|
||||
i365_set_socket (&socket, &state);
|
||||
|
||||
@@ -504,8 +910,10 @@ int i82365_init (void)
|
||||
|
||||
if (i == 0) {
|
||||
/* PC Card not ready for data transfer */
|
||||
puts ("i82365 PC Card not ready for data transfer\n");
|
||||
return 1;
|
||||
}
|
||||
debug (" PC Card ready for data transfer: ");
|
||||
|
||||
mem.map = 0;
|
||||
mem.flags = MAP_ATTRIB | MAP_ACTIVE;
|
||||
@@ -513,17 +921,28 @@ int i82365_init (void)
|
||||
mem.sys_start = CFG_PCMCIA_MEM_ADDR;
|
||||
mem.sys_stop = CFG_PCMCIA_MEM_ADDR + CFG_PCMCIA_MEM_SIZE - 1;
|
||||
mem.card_start = 0;
|
||||
|
||||
i365_set_mem_map (&socket, &mem);
|
||||
|
||||
#ifdef CONFIG_CPC45
|
||||
mem.map = 1;
|
||||
mem.flags = MAP_ACTIVE;
|
||||
mem.speed = 300;
|
||||
mem.sys_start = CFG_PCMCIA_MEM_ADDR + CFG_PCMCIA_MEM_SIZE;
|
||||
mem.sys_stop = CFG_PCMCIA_MEM_ADDR + (2 * CFG_PCMCIA_MEM_SIZE) - 1;
|
||||
mem.card_start = 0;
|
||||
i365_set_mem_map (&socket, &mem);
|
||||
|
||||
#else /* !CONFIG_CPC45 */
|
||||
|
||||
io.map = 0;
|
||||
io.flags = MAP_AUTOSZ | MAP_ACTIVE;
|
||||
io.speed = 0;
|
||||
io.start = 0x0100;
|
||||
io.stop = 0x010F;
|
||||
|
||||
i365_set_io_map (&socket, &io);
|
||||
|
||||
#endif /* CONFIG_CPC45 */
|
||||
|
||||
#ifdef DEBUG
|
||||
i82365_dump_regions (socket.dev);
|
||||
#endif
|
||||
@@ -550,8 +969,18 @@ void i82365_exit (void)
|
||||
|
||||
i365_set_mem_map (&socket, &mem);
|
||||
|
||||
socket.state.sysctl &= 0xFFFF00FF;
|
||||
#ifdef CONFIG_CPC45
|
||||
mem.map = 1;
|
||||
mem.flags = 0;
|
||||
mem.speed = 0;
|
||||
mem.sys_start = 0;
|
||||
mem.sys_stop = 0x1000;
|
||||
mem.card_start = 0;
|
||||
|
||||
i365_set_mem_map (&socket, &mem);
|
||||
#else /* !CONFIG_CPC45 */
|
||||
socket.state.sysctl &= 0xFFFF00FF;
|
||||
#endif
|
||||
state.Vcc = state.Vpp = 0;
|
||||
|
||||
i365_set_socket (&socket, &state);
|
||||
@@ -567,15 +996,17 @@ void i82365_exit (void)
|
||||
static void i82365_dump_regions (pci_dev_t dev)
|
||||
{
|
||||
u_int tmp[2];
|
||||
u_int *mem = (void *) sock.cb_phys;
|
||||
u_int *mem = (void *) socket.cb_phys;
|
||||
u_char *cis = (void *) CFG_PCMCIA_MEM_ADDR;
|
||||
u_char *ide = (void *) (CFG_ATA_BASE_ADDR + CFG_ATA_REG_OFFSET);
|
||||
|
||||
pci_read_config_dword (dev, 0x00, tmp + 0);
|
||||
pci_read_config_dword (dev, 0x80, tmp + 1);
|
||||
|
||||
printf ("PCI CONF: %08X ... %08X\n", tmp[0], tmp[1]);
|
||||
printf ("PCI MEM: ... %08X ... %08X\n", mem[0x8 / 4], mem[0x800 / 4]);
|
||||
printf ("PCI CONF: %08X ... %08X\n",
|
||||
tmp[0], tmp[1]);
|
||||
printf ("PCI MEM: ... %08X ... %08X\n",
|
||||
mem[0x8 / 4], mem[0x800 / 4]);
|
||||
printf ("CIS: ...%c%c%c%c%c%c%c%c...\n",
|
||||
cis[0x38], cis[0x3a], cis[0x3c], cis[0x3e],
|
||||
cis[0x40], cis[0x42], cis[0x44], cis[0x48]);
|
||||
|
||||
963
drivers/ne2000.c
Normal file
963
drivers/ne2000.c
Normal file
@@ -0,0 +1,963 @@
|
||||
/*
|
||||
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.
|
||||
|
||||
|
||||
==========================================================================
|
||||
|
||||
dev/if_dp83902a.c
|
||||
|
||||
Ethernet device driver for NS DP83902a ethernet controller
|
||||
|
||||
==========================================================================
|
||||
####ECOSGPLCOPYRIGHTBEGIN####
|
||||
-------------------------------------------
|
||||
This file is part of eCos, the Embedded Configurable Operating System.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
||||
|
||||
eCos 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 or (at your option) any later version.
|
||||
|
||||
eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
|
||||
As a special exception, if other files instantiate templates or use macros
|
||||
or inline functions from this file, or you compile this file and link it
|
||||
with other works to produce a work based on this file, this file does not
|
||||
by itself cause the resulting work to be covered by the GNU General Public
|
||||
License. However the source code for this file must still be made available
|
||||
in accordance with section (3) of the GNU General Public License.
|
||||
|
||||
This exception does not invalidate any other reasons why a work based on
|
||||
this file might be covered by the GNU General Public License.
|
||||
|
||||
Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
|
||||
at http://sources.redhat.com/ecos/ecos-license/
|
||||
-------------------------------------------
|
||||
####ECOSGPLCOPYRIGHTEND####
|
||||
####BSDCOPYRIGHTBEGIN####
|
||||
|
||||
-------------------------------------------
|
||||
|
||||
Portions of this software may have been derived from OpenBSD or other sources,
|
||||
and are covered by the appropriate copyright disclaimers included herein.
|
||||
|
||||
-------------------------------------------
|
||||
|
||||
####BSDCOPYRIGHTEND####
|
||||
==========================================================================
|
||||
#####DESCRIPTIONBEGIN####
|
||||
|
||||
Author(s): gthomas
|
||||
Contributors: gthomas, jskov, rsandifo
|
||||
Date: 2001-06-13
|
||||
Purpose:
|
||||
Description:
|
||||
|
||||
FIXME: Will fail if pinged with large packets (1520 bytes)
|
||||
Add promisc config
|
||||
Add SNMP
|
||||
|
||||
####DESCRIPTIONEND####
|
||||
|
||||
|
||||
==========================================================================
|
||||
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <net.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#ifdef CONFIG_DRIVER_NE2000
|
||||
|
||||
/* wor around udelay resetting OCR */
|
||||
static void my_udelay(long us) {
|
||||
long tmo;
|
||||
|
||||
tmo = get_timer (0) + us * CFG_HZ / 1000000; /* will this be much greater than 0 ? */
|
||||
while (get_timer (0) < tmo);
|
||||
}
|
||||
|
||||
#define mdelay(n) my_udelay((n)*1000)
|
||||
|
||||
/* forward definition of function used for the uboot interface */
|
||||
void uboot_push_packet_len(int len);
|
||||
void uboot_push_tx_done(int key, int val);
|
||||
|
||||
/* timeout for tx/rx in s */
|
||||
#define TOUT 5
|
||||
|
||||
#define ETHER_ADDR_LEN 6
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------
|
||||
Debugging details
|
||||
|
||||
Set to perms of:
|
||||
0 disables all debug output
|
||||
1 for process debug output
|
||||
2 for added data IO output: get_reg, put_reg
|
||||
4 for packet allocation/free output
|
||||
8 for only startup status, so we can tell we're installed OK
|
||||
*/
|
||||
/*#define DEBUG 0xf*/
|
||||
#define DEBUG 0
|
||||
|
||||
#if DEBUG & 1
|
||||
#define DEBUG_FUNCTION() do { printf("%s\n", __FUNCTION__); } while (0)
|
||||
#define DEBUG_LINE() do { printf("%d\n", __LINE__); } while (0)
|
||||
#else
|
||||
#define DEBUG_FUNCTION() do {} while(0)
|
||||
#define DEBUG_LINE() do {} while(0)
|
||||
#endif
|
||||
|
||||
#include "ne2000.h"
|
||||
|
||||
#if DEBUG & 1
|
||||
#define PRINTK(args...) printf(args)
|
||||
#else
|
||||
#define PRINTK(args...)
|
||||
#endif
|
||||
|
||||
static dp83902a_priv_data_t nic; /* just one instance of the card supported */
|
||||
|
||||
static bool
|
||||
dp83902a_init(void)
|
||||
{
|
||||
dp83902a_priv_data_t *dp = &nic;
|
||||
cyg_uint8* base;
|
||||
int i;
|
||||
|
||||
DEBUG_FUNCTION();
|
||||
|
||||
base = dp->base;
|
||||
if (!base) return false; /* No device found */
|
||||
|
||||
DEBUG_LINE();
|
||||
|
||||
/* Prepare ESA */
|
||||
DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); /* Select page 1 */
|
||||
/* Use the address from the serial EEPROM */
|
||||
for (i = 0; i < 6; i++)
|
||||
DP_IN(base, DP_P1_PAR0+i, dp->esa[i]);
|
||||
DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0); /* Select page 0 */
|
||||
|
||||
printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
"eeprom",
|
||||
dp->esa[0],
|
||||
dp->esa[1],
|
||||
dp->esa[2],
|
||||
dp->esa[3],
|
||||
dp->esa[4],
|
||||
dp->esa[5] );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
dp83902a_stop(void)
|
||||
{
|
||||
dp83902a_priv_data_t *dp = &nic;
|
||||
cyg_uint8 *base = dp->base;
|
||||
|
||||
DEBUG_FUNCTION();
|
||||
|
||||
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */
|
||||
DP_OUT(base, DP_ISR, 0xFF); /* Clear any pending interrupts */
|
||||
DP_OUT(base, DP_IMR, 0x00); /* Disable all interrupts */
|
||||
|
||||
dp->running = false;
|
||||
}
|
||||
|
||||
/*
|
||||
This function is called to "start up" the interface. It may be called
|
||||
multiple times, even when the hardware is already running. It will be
|
||||
called whenever something "hardware oriented" changes and should leave
|
||||
the hardware ready to send/receive packets.
|
||||
*/
|
||||
static void
|
||||
dp83902a_start(unsigned char * enaddr)
|
||||
{
|
||||
dp83902a_priv_data_t *dp = &nic;
|
||||
cyg_uint8 *base = dp->base;
|
||||
int i;
|
||||
|
||||
DEBUG_FUNCTION();
|
||||
|
||||
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */
|
||||
DP_OUT(base, DP_DCR, DP_DCR_INIT);
|
||||
DP_OUT(base, DP_RBCH, 0); /* Remote byte count */
|
||||
DP_OUT(base, DP_RBCL, 0);
|
||||
DP_OUT(base, DP_RCR, DP_RCR_MON); /* Accept no packets */
|
||||
DP_OUT(base, DP_TCR, DP_TCR_LOCAL); /* Transmitter [virtually] off */
|
||||
DP_OUT(base, DP_TPSR, dp->tx_buf1); /* Transmitter start page */
|
||||
dp->tx1 = dp->tx2 = 0;
|
||||
dp->tx_next = dp->tx_buf1;
|
||||
dp->tx_started = false;
|
||||
DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */
|
||||
DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1); /* Receive ring boundary */
|
||||
DP_OUT(base, DP_PSTOP, dp->rx_buf_end); /* Receive ring end page */
|
||||
dp->rx_next = dp->rx_buf_start-1;
|
||||
DP_OUT(base, DP_ISR, 0xFF); /* Clear any pending interrupts */
|
||||
DP_OUT(base, DP_IMR, DP_IMR_All); /* Enable all interrupts */
|
||||
DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP); /* Select page 1 */
|
||||
DP_OUT(base, DP_P1_CURP, dp->rx_buf_start); /* Current page - next free page for Rx */
|
||||
for (i = 0; i < ETHER_ADDR_LEN; i++) {
|
||||
DP_OUT(base, DP_P1_PAR0+i, enaddr[i]);
|
||||
}
|
||||
/* Enable and start device */
|
||||
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
|
||||
DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */
|
||||
DP_OUT(base, DP_RCR, DP_RCR_AB); /* Accept broadcast, no errors, no multicast */
|
||||
dp->running = true;
|
||||
}
|
||||
|
||||
/*
|
||||
This routine is called to start the transmitter. It is split out from the
|
||||
data handling routine so it may be called either when data becomes first
|
||||
available or when an Tx interrupt occurs
|
||||
*/
|
||||
|
||||
static void
|
||||
dp83902a_start_xmit(int start_page, int len)
|
||||
{
|
||||
dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic;
|
||||
cyg_uint8 *base = dp->base;
|
||||
|
||||
DEBUG_FUNCTION();
|
||||
|
||||
#if DEBUG & 1
|
||||
printf("Tx pkt %d len %d\n", start_page, len);
|
||||
if (dp->tx_started)
|
||||
printf("TX already started?!?\n");
|
||||
#endif
|
||||
|
||||
DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE));
|
||||
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
|
||||
DP_OUT(base, DP_TBCL, len & 0xFF);
|
||||
DP_OUT(base, DP_TBCH, len >> 8);
|
||||
DP_OUT(base, DP_TPSR, start_page);
|
||||
DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
|
||||
|
||||
dp->tx_started = true;
|
||||
}
|
||||
|
||||
/*
|
||||
This routine is called to send data to the hardware. It is known a-priori
|
||||
that there is free buffer space (dp->tx_next).
|
||||
*/
|
||||
static void
|
||||
dp83902a_send(unsigned char *data, int total_len, unsigned long key)
|
||||
{
|
||||
struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
|
||||
cyg_uint8 *base = dp->base;
|
||||
int len, start_page, pkt_len, i, isr;
|
||||
#if DEBUG & 4
|
||||
int dx;
|
||||
#endif
|
||||
|
||||
DEBUG_FUNCTION();
|
||||
|
||||
len = pkt_len = total_len;
|
||||
if (pkt_len < IEEE_8023_MIN_FRAME) pkt_len = IEEE_8023_MIN_FRAME;
|
||||
|
||||
start_page = dp->tx_next;
|
||||
if (dp->tx_next == dp->tx_buf1) {
|
||||
dp->tx1 = start_page;
|
||||
dp->tx1_len = pkt_len;
|
||||
dp->tx1_key = key;
|
||||
dp->tx_next = dp->tx_buf2;
|
||||
} else {
|
||||
dp->tx2 = start_page;
|
||||
dp->tx2_len = pkt_len;
|
||||
dp->tx2_key = key;
|
||||
dp->tx_next = dp->tx_buf1;
|
||||
}
|
||||
|
||||
#if DEBUG & 5
|
||||
printf("TX prep page %d len %d\n", start_page, pkt_len);
|
||||
#endif
|
||||
|
||||
DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
|
||||
{
|
||||
/* Dummy read. The manual sez something slightly different, */
|
||||
/* but the code is extended a bit to do what Hitachi's monitor */
|
||||
/* does (i.e., also read data). */
|
||||
|
||||
cyg_uint16 tmp;
|
||||
int len = 1;
|
||||
|
||||
DP_OUT(base, DP_RSAL, 0x100-len);
|
||||
DP_OUT(base, DP_RSAH, (start_page-1) & 0xff);
|
||||
DP_OUT(base, DP_RBCL, len);
|
||||
DP_OUT(base, DP_RBCH, 0);
|
||||
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START);
|
||||
DP_IN_DATA(dp->data, tmp);
|
||||
}
|
||||
|
||||
#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
|
||||
/* Stall for a bit before continuing to work around random data */
|
||||
/* corruption problems on some platforms. */
|
||||
CYGACC_CALL_IF_DELAY_US(1);
|
||||
#endif
|
||||
|
||||
/* Send data to device buffer(s) */
|
||||
DP_OUT(base, DP_RSAL, 0);
|
||||
DP_OUT(base, DP_RSAH, start_page);
|
||||
DP_OUT(base, DP_RBCL, pkt_len & 0xFF);
|
||||
DP_OUT(base, DP_RBCH, pkt_len >> 8);
|
||||
DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START);
|
||||
|
||||
/* Put data into buffer */
|
||||
#if DEBUG & 4
|
||||
printf(" sg buf %08lx len %08x\n ", (unsigned long) data, len);
|
||||
dx = 0;
|
||||
#endif
|
||||
while (len > 0) {
|
||||
#if DEBUG & 4
|
||||
printf(" %02x", *data);
|
||||
if (0 == (++dx % 16)) printf("\n ");
|
||||
#endif
|
||||
DP_OUT_DATA(dp->data, *data++);
|
||||
len--;
|
||||
}
|
||||
#if DEBUG & 4
|
||||
printf("\n");
|
||||
#endif
|
||||
if (total_len < pkt_len) {
|
||||
#if DEBUG & 4
|
||||
printf(" + %d bytes of padding\n", pkt_len - total_len);
|
||||
#endif
|
||||
/* Padding to 802.3 length was required */
|
||||
for (i = total_len; i < pkt_len;) {
|
||||
i++;
|
||||
DP_OUT_DATA(dp->data, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
|
||||
/* After last data write, delay for a bit before accessing the */
|
||||
/* device again, or we may get random data corruption in the last */
|
||||
/* datum (on some platforms). */
|
||||
CYGACC_CALL_IF_DELAY_US(1);
|
||||
#endif
|
||||
|
||||
/* Wait for DMA to complete */
|
||||
do {
|
||||
DP_IN(base, DP_ISR, isr);
|
||||
} while ((isr & DP_ISR_RDC) == 0);
|
||||
/* Then disable DMA */
|
||||
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
|
||||
|
||||
/* Start transmit if not already going */
|
||||
if (!dp->tx_started) {
|
||||
if (start_page == dp->tx1) {
|
||||
dp->tx_int = 1; /* Expecting interrupt from BUF1 */
|
||||
} else {
|
||||
dp->tx_int = 2; /* Expecting interrupt from BUF2 */
|
||||
}
|
||||
dp83902a_start_xmit(start_page, pkt_len);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This function is called when a packet has been received. It's job is
|
||||
to prepare to unload the packet from the hardware. Once the length of
|
||||
the packet is known, the upper layer of the driver can be told. When
|
||||
the upper layer is ready to unload the packet, the internal function
|
||||
'dp83902a_recv' will be called to actually fetch it from the hardware.
|
||||
*/
|
||||
static void
|
||||
dp83902a_RxEvent(void)
|
||||
{
|
||||
struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
|
||||
cyg_uint8 *base = dp->base;
|
||||
unsigned char rsr;
|
||||
unsigned char rcv_hdr[4];
|
||||
int i, len, pkt, cur;
|
||||
|
||||
DEBUG_FUNCTION();
|
||||
|
||||
DP_IN(base, DP_RSR, rsr);
|
||||
while (true) {
|
||||
/* Read incoming packet header */
|
||||
DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START);
|
||||
DP_IN(base, DP_P1_CURP, cur);
|
||||
DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
|
||||
DP_IN(base, DP_BNDRY, pkt);
|
||||
|
||||
pkt += 1;
|
||||
if (pkt == dp->rx_buf_end)
|
||||
pkt = dp->rx_buf_start;
|
||||
|
||||
if (pkt == cur) {
|
||||
break;
|
||||
}
|
||||
DP_OUT(base, DP_RBCL, sizeof(rcv_hdr));
|
||||
DP_OUT(base, DP_RBCH, 0);
|
||||
DP_OUT(base, DP_RSAL, 0);
|
||||
DP_OUT(base, DP_RSAH, pkt);
|
||||
if (dp->rx_next == pkt) {
|
||||
if (cur == dp->rx_buf_start)
|
||||
DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1);
|
||||
else
|
||||
DP_OUT(base, DP_BNDRY, cur-1); /* Update pointer */
|
||||
return;
|
||||
}
|
||||
dp->rx_next = pkt;
|
||||
DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
|
||||
DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
|
||||
#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
|
||||
CYGACC_CALL_IF_DELAY_US(10);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < sizeof(rcv_hdr);) {
|
||||
DP_IN_DATA(dp->data, rcv_hdr[i++]);
|
||||
}
|
||||
|
||||
#if DEBUG & 5
|
||||
printf("rx hdr %02x %02x %02x %02x\n",
|
||||
rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]);
|
||||
#endif
|
||||
len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr);
|
||||
uboot_push_packet_len(len);
|
||||
if (rcv_hdr[1] == dp->rx_buf_start)
|
||||
DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1);
|
||||
else
|
||||
DP_OUT(base, DP_BNDRY, rcv_hdr[1]-1); /* Update pointer */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This function is called as a result of the "eth_drv_recv()" call above.
|
||||
It's job is to actually fetch data for a packet from the hardware once
|
||||
memory buffers have been allocated for the packet. Note that the buffers
|
||||
may come in pieces, using a scatter-gather list. This allows for more
|
||||
efficient processing in the upper layers of the stack.
|
||||
*/
|
||||
static void
|
||||
dp83902a_recv(unsigned char *data, int len)
|
||||
{
|
||||
struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
|
||||
cyg_uint8 *base = dp->base;
|
||||
int i, mlen;
|
||||
cyg_uint8 saved_char = 0;
|
||||
bool saved;
|
||||
#if DEBUG & 4
|
||||
int dx;
|
||||
#endif
|
||||
|
||||
DEBUG_FUNCTION();
|
||||
|
||||
#if DEBUG & 5
|
||||
printf("Rx packet %d length %d\n", dp->rx_next, len);
|
||||
#endif
|
||||
|
||||
/* Read incoming packet data */
|
||||
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
|
||||
DP_OUT(base, DP_RBCL, len & 0xFF);
|
||||
DP_OUT(base, DP_RBCH, len >> 8);
|
||||
DP_OUT(base, DP_RSAL, 4); /* Past header */
|
||||
DP_OUT(base, DP_RSAH, dp->rx_next);
|
||||
DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
|
||||
DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
|
||||
#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
|
||||
CYGACC_CALL_IF_DELAY_US(10);
|
||||
#endif
|
||||
|
||||
saved = false;
|
||||
for (i = 0; i < 1; i++) {
|
||||
if (data) {
|
||||
mlen = len;
|
||||
#if DEBUG & 4
|
||||
printf(" sg buf %08lx len %08x \n", (unsigned long) data, mlen);
|
||||
dx = 0;
|
||||
#endif
|
||||
while (0 < mlen) {
|
||||
/* Saved byte from previous loop? */
|
||||
if (saved) {
|
||||
*data++ = saved_char;
|
||||
mlen--;
|
||||
saved = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
cyg_uint8 tmp;
|
||||
DP_IN_DATA(dp->data, tmp);
|
||||
#if DEBUG & 4
|
||||
printf(" %02x", tmp);
|
||||
if (0 == (++dx % 16)) printf("\n ");
|
||||
#endif
|
||||
*data++ = tmp;;
|
||||
mlen--;
|
||||
}
|
||||
}
|
||||
#if DEBUG & 4
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dp83902a_TxEvent(void)
|
||||
{
|
||||
struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
|
||||
cyg_uint8 *base = dp->base;
|
||||
unsigned char tsr;
|
||||
unsigned long key;
|
||||
|
||||
DEBUG_FUNCTION();
|
||||
|
||||
DP_IN(base, DP_TSR, tsr);
|
||||
if (dp->tx_int == 1) {
|
||||
key = dp->tx1_key;
|
||||
dp->tx1 = 0;
|
||||
} else {
|
||||
key = dp->tx2_key;
|
||||
dp->tx2 = 0;
|
||||
}
|
||||
/* Start next packet if one is ready */
|
||||
dp->tx_started = false;
|
||||
if (dp->tx1) {
|
||||
dp83902a_start_xmit(dp->tx1, dp->tx1_len);
|
||||
dp->tx_int = 1;
|
||||
} else if (dp->tx2) {
|
||||
dp83902a_start_xmit(dp->tx2, dp->tx2_len);
|
||||
dp->tx_int = 2;
|
||||
} else {
|
||||
dp->tx_int = 0;
|
||||
}
|
||||
/* Tell higher level we sent this packet */
|
||||
uboot_push_tx_done(key, 0);
|
||||
}
|
||||
|
||||
/* Read the tally counters to clear them. Called in response to a CNT */
|
||||
/* interrupt. */
|
||||
static void
|
||||
dp83902a_ClearCounters(void)
|
||||
{
|
||||
struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
|
||||
cyg_uint8 *base = dp->base;
|
||||
cyg_uint8 cnt1, cnt2, cnt3;
|
||||
|
||||
DP_IN(base, DP_FER, cnt1);
|
||||
DP_IN(base, DP_CER, cnt2);
|
||||
DP_IN(base, DP_MISSED, cnt3);
|
||||
DP_OUT(base, DP_ISR, DP_ISR_CNT);
|
||||
}
|
||||
|
||||
/* Deal with an overflow condition. This code follows the procedure set */
|
||||
/* out in section 7.0 of the datasheet. */
|
||||
static void
|
||||
dp83902a_Overflow(void)
|
||||
{
|
||||
struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic;
|
||||
cyg_uint8 *base = dp->base;
|
||||
cyg_uint8 isr;
|
||||
|
||||
/* Issue a stop command and wait 1.6ms for it to complete. */
|
||||
DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA);
|
||||
CYGACC_CALL_IF_DELAY_US(1600);
|
||||
|
||||
/* Clear the remote byte counter registers. */
|
||||
DP_OUT(base, DP_RBCL, 0);
|
||||
DP_OUT(base, DP_RBCH, 0);
|
||||
|
||||
/* Enter loopback mode while we clear the buffer. */
|
||||
DP_OUT(base, DP_TCR, DP_TCR_LOCAL);
|
||||
DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA);
|
||||
|
||||
/* Read in as many packets as we can and acknowledge any and receive */
|
||||
/* interrupts. Since the buffer has overflowed, a receive event of */
|
||||
/* some kind will have occured. */
|
||||
dp83902a_RxEvent();
|
||||
DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE);
|
||||
|
||||
/* Clear the overflow condition and leave loopback mode. */
|
||||
DP_OUT(base, DP_ISR, DP_ISR_OFLW);
|
||||
DP_OUT(base, DP_TCR, DP_TCR_NORMAL);
|
||||
|
||||
/* If a transmit command was issued, but no transmit event has occured, */
|
||||
/* restart it here. */
|
||||
DP_IN(base, DP_ISR, isr);
|
||||
if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) {
|
||||
DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dp83902a_poll(void)
|
||||
{
|
||||
struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
|
||||
cyg_uint8 *base = dp->base;
|
||||
unsigned char isr;
|
||||
|
||||
DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START);
|
||||
DP_IN(base, DP_ISR, isr);
|
||||
while (0 != isr) {
|
||||
/* The CNT interrupt triggers when the MSB of one of the error */
|
||||
/* counters is set. We don't much care about these counters, but */
|
||||
/* we should read their values to reset them. */
|
||||
if (isr & DP_ISR_CNT) {
|
||||
dp83902a_ClearCounters();
|
||||
}
|
||||
/* Check for overflow. It's a special case, since there's a */
|
||||
/* particular procedure that must be followed to get back into */
|
||||
/* a running state.a */
|
||||
if (isr & DP_ISR_OFLW) {
|
||||
dp83902a_Overflow();
|
||||
} else {
|
||||
/* Other kinds of interrupts can be acknowledged simply by */
|
||||
/* clearing the relevant bits of the ISR. Do that now, then */
|
||||
/* handle the interrupts we care about. */
|
||||
DP_OUT(base, DP_ISR, isr); /* Clear set bits */
|
||||
if (!dp->running) break; /* Is this necessary? */
|
||||
/* Check for tx_started on TX event since these may happen */
|
||||
/* spuriously it seems. */
|
||||
if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) {
|
||||
dp83902a_TxEvent();
|
||||
}
|
||||
if (isr & (DP_ISR_RxP|DP_ISR_RxE)) {
|
||||
dp83902a_RxEvent();
|
||||
}
|
||||
}
|
||||
DP_IN(base, DP_ISR, isr);
|
||||
}
|
||||
}
|
||||
|
||||
/* find prom (taken from pc_net_cs.c from Linux) */
|
||||
|
||||
#include "8390.h"
|
||||
|
||||
typedef struct hw_info_t {
|
||||
u_int offset;
|
||||
u_char a0, a1, a2;
|
||||
u_int flags;
|
||||
} hw_info_t;
|
||||
|
||||
#define DELAY_OUTPUT 0x01
|
||||
#define HAS_MISC_REG 0x02
|
||||
#define USE_BIG_BUF 0x04
|
||||
#define HAS_IBM_MISC 0x08
|
||||
#define IS_DL10019 0x10
|
||||
#define IS_DL10022 0x20
|
||||
#define HAS_MII 0x40
|
||||
#define USE_SHMEM 0x80 /* autodetected */
|
||||
|
||||
#define AM79C9XX_HOME_PHY 0x00006B90 /* HomePNA PHY */
|
||||
#define AM79C9XX_ETH_PHY 0x00006B70 /* 10baseT PHY */
|
||||
#define MII_PHYID_REV_MASK 0xfffffff0
|
||||
#define MII_PHYID_REG1 0x02
|
||||
#define MII_PHYID_REG2 0x03
|
||||
|
||||
static hw_info_t hw_info[] = {
|
||||
{ /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT },
|
||||
{ /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 },
|
||||
{ /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 },
|
||||
{ /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94,
|
||||
DELAY_OUTPUT | HAS_IBM_MISC },
|
||||
{ /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 },
|
||||
{ /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 },
|
||||
{ /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 },
|
||||
{ /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 },
|
||||
{ /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 },
|
||||
{ /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 },
|
||||
{ /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 },
|
||||
{ /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 },
|
||||
{ /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* IBM FME */ 0x0374, 0x00, 0x04, 0xac,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 },
|
||||
{ /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 },
|
||||
{ /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 },
|
||||
{ /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 },
|
||||
{ /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 },
|
||||
{ /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 },
|
||||
{ /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45,
|
||||
HAS_MISC_REG | HAS_IBM_MISC },
|
||||
{ /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 },
|
||||
{ /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 },
|
||||
{ /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 },
|
||||
{ /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b,
|
||||
DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF },
|
||||
{ /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 },
|
||||
{ /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 },
|
||||
{ /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 },
|
||||
{ /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 },
|
||||
{ /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 }
|
||||
};
|
||||
|
||||
#define NR_INFO (sizeof(hw_info)/sizeof(hw_info_t))
|
||||
|
||||
static hw_info_t default_info = { 0, 0, 0, 0, 0 };
|
||||
|
||||
unsigned char dev_addr[6];
|
||||
|
||||
#define PCNET_CMD 0x00
|
||||
#define PCNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */
|
||||
#define PCNET_RESET 0x1f /* Issue a read to reset, a write to clear. */
|
||||
#define PCNET_MISC 0x18 /* For IBM CCAE and Socket EA cards */
|
||||
|
||||
unsigned long nic_base;
|
||||
|
||||
static void pcnet_reset_8390(void)
|
||||
{
|
||||
int i, r;
|
||||
|
||||
PRINTK("nic base is %lx\n", nic_base);
|
||||
|
||||
#if 1
|
||||
n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
|
||||
PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
|
||||
n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD);
|
||||
PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
|
||||
n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
|
||||
PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
|
||||
#endif
|
||||
n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
|
||||
|
||||
n2k_outb(n2k_inb(nic_base + PCNET_RESET), PCNET_RESET);
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0)
|
||||
break;
|
||||
PRINTK("got %x in reset\n", r);
|
||||
my_udelay(100);
|
||||
}
|
||||
n2k_outb(ENISR_RESET, EN0_ISR); /* Ack intr. */
|
||||
|
||||
if (i == 100)
|
||||
printf("pcnet_reset_8390() did not complete.\n");
|
||||
} /* pcnet_reset_8390 */
|
||||
|
||||
static hw_info_t * get_prom(void ) {
|
||||
unsigned char prom[32];
|
||||
int i, j;
|
||||
struct {
|
||||
u_char value, offset;
|
||||
} program_seq[] = {
|
||||
{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
|
||||
{0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */
|
||||
{0x00, EN0_RCNTLO}, /* Clear the count regs. */
|
||||
{0x00, EN0_RCNTHI},
|
||||
{0x00, EN0_IMR}, /* Mask completion irq. */
|
||||
{0xFF, EN0_ISR},
|
||||
{E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
|
||||
{E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
|
||||
{32, EN0_RCNTLO},
|
||||
{0x00, EN0_RCNTHI},
|
||||
{0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
|
||||
{0x00, EN0_RSARHI},
|
||||
{E8390_RREAD+E8390_START, E8390_CMD},
|
||||
};
|
||||
|
||||
PRINTK("trying to get MAC via prom reading\n");
|
||||
|
||||
pcnet_reset_8390();
|
||||
|
||||
mdelay(10);
|
||||
|
||||
for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
|
||||
n2k_outb(program_seq[i].value, program_seq[i].offset);
|
||||
|
||||
PRINTK("PROM:");
|
||||
for (i = 0; i < 32; i++) {
|
||||
prom[i] = n2k_inb(PCNET_DATAPORT);
|
||||
PRINTK(" %02x", prom[i]);
|
||||
}
|
||||
PRINTK("\n");
|
||||
for (i = 0; i < NR_INFO; i++) {
|
||||
if ((prom[0] == hw_info[i].a0) &&
|
||||
(prom[2] == hw_info[i].a1) &&
|
||||
(prom[4] == hw_info[i].a2)) {
|
||||
PRINTK("matched board %d\n", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) {
|
||||
for (j = 0; j < 6; j++)
|
||||
dev_addr[j] = prom[j<<1];
|
||||
PRINTK("on exit i is %d/%ld\n", i, NR_INFO);
|
||||
PRINTK("MAC address is %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
dev_addr[0],dev_addr[1],dev_addr[2],dev_addr[3],dev_addr[4],dev_addr[5]);
|
||||
return (i < NR_INFO) ? hw_info+i : &default_info;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* U-boot specific routines */
|
||||
|
||||
#define NB 5
|
||||
|
||||
static unsigned char *pbuf = NULL;
|
||||
static int plen[NB];
|
||||
static int nrx = 0;
|
||||
|
||||
static int pkey = -1;
|
||||
|
||||
void uboot_push_packet_len(int len) {
|
||||
PRINTK("pushed len = %d, nrx = %d\n", len, nrx);
|
||||
if (len>=2000) {
|
||||
printf("NE2000: packet too big\n");
|
||||
return;
|
||||
}
|
||||
if (nrx >= NB) {
|
||||
printf("losing packets in rx\n");
|
||||
return;
|
||||
}
|
||||
plen[nrx] = len;
|
||||
dp83902a_recv(&pbuf[nrx*2000], len);
|
||||
nrx++;
|
||||
}
|
||||
|
||||
void uboot_push_tx_done(int key, int val) {
|
||||
PRINTK("pushed key = %d\n", key);
|
||||
pkey = key;
|
||||
}
|
||||
|
||||
int eth_init(bd_t *bd) {
|
||||
static hw_info_t * r;
|
||||
char ethaddr[20];
|
||||
|
||||
PRINTK("### eth_init\n");
|
||||
|
||||
if (!pbuf) {
|
||||
pbuf = malloc(NB*2000);
|
||||
if (!pbuf) {
|
||||
printf("Cannot allocate rx buffers\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRIVER_NE2000_CCR
|
||||
{
|
||||
volatile unsigned char *p = (volatile unsigned char *) CONFIG_DRIVER_NE2000_CCR;
|
||||
|
||||
PRINTK("CCR before is %x\n", *p);
|
||||
*p = CONFIG_DRIVER_NE2000_VAL;
|
||||
PRINTK("CCR after is %x\n", *p);
|
||||
}
|
||||
#endif
|
||||
|
||||
nic_base = CONFIG_DRIVER_NE2000_BASE;
|
||||
nic.base = (cyg_uint8 *) CONFIG_DRIVER_NE2000_BASE;
|
||||
|
||||
r = get_prom();
|
||||
if (!r)
|
||||
return -1;
|
||||
|
||||
sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
dev_addr[0], dev_addr[1],
|
||||
dev_addr[2], dev_addr[3],
|
||||
dev_addr[4], dev_addr[5]) ;
|
||||
PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr);
|
||||
setenv ("ethaddr", ethaddr);
|
||||
|
||||
|
||||
#define DP_DATA 0x10
|
||||
nic.data = nic.base + DP_DATA;
|
||||
nic.tx_buf1 = 0x40;
|
||||
nic.tx_buf2 = 0x48;
|
||||
nic.rx_buf_start = 0x50;
|
||||
nic.rx_buf_end = 0x80;
|
||||
|
||||
if (dp83902a_init() == false)
|
||||
return -1;
|
||||
dp83902a_start(dev_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void eth_halt() {
|
||||
|
||||
PRINTK("### eth_halt\n");
|
||||
|
||||
dp83902a_stop();
|
||||
}
|
||||
|
||||
int eth_rx() {
|
||||
int j, tmo;
|
||||
|
||||
PRINTK("### eth_rx\n");
|
||||
|
||||
tmo = get_timer (0) + TOUT * CFG_HZ;
|
||||
while(1) {
|
||||
dp83902a_poll();
|
||||
if (nrx > 0) {
|
||||
for(j=0; j<nrx; j++) {
|
||||
NetReceive(&pbuf[j*2000], plen[j]);
|
||||
}
|
||||
nrx = 0;
|
||||
return 1;
|
||||
}
|
||||
if (get_timer (0) >= tmo) {
|
||||
printf("timeout during rx\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eth_send(volatile void *packet, int length) {
|
||||
int tmo;
|
||||
|
||||
PRINTK("### eth_send\n");
|
||||
|
||||
pkey = -1;
|
||||
|
||||
dp83902a_send((unsigned char *) packet, length, 666);
|
||||
tmo = get_timer (0) + TOUT * CFG_HZ;
|
||||
while(1) {
|
||||
dp83902a_poll();
|
||||
if (pkey != -1) {
|
||||
PRINTK("Packet sucesfully sent\n");
|
||||
return 0;
|
||||
}
|
||||
if (get_timer (0) >= tmo) {
|
||||
printf("transmission error (timoeut)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user