Compare commits

...

20 Commits

Author SHA1 Message Date
wdenk
5cf91d6bdc * Modify KUP4X board configuration to use SL811 driver for USB memory
sticks (including FAT / VFAT filesystem support)

* Add SL811 Host Controller Interface driver for USB

* Add CFG_I2C_EEPROM_ADDR_OVERFLOW desription to README

* Patch by Pantelis Antoniou, 19 Apr 2004:
  Allow to use shell style syntax (i. e. ${var} ) with standard parser.
  Minor patches for Intracom boards.

* Patch by Christian Pell, 19 Apr 2004:
  cleanup support for CF/IDE on PCMCIA for PXA25X
2004-04-23 20:32:05 +00:00
wdenk
e35745bb64 * Temporarily disabled John Kerl's extended MII command code because
"miivals.h" is missing

* Patches by Mark Jonas, 13 Apr 2004:
  - Remove CS0 chip select timing setting from cpu/mpc5xxx/start.S
  - Add sync instructions to IceCube SDRAM init code
  - Move SDRAM chip constants into seperate include files
  - Unify DDR and SDR initialization code
  - Unify all IceCube (Lite5xxx) target names
2004-04-18 23:32:11 +00:00
wdenk
2471111d35 * Patch by John Kerl, 16 Apr 2004:
Enable ranges in mii command, e.g. mii read 0-1f 0 or
  mii read 4-7 18-1a.  Also add mii dump subcommand for
  pretty-printing standard regs 0-5.

* Patch by  Stephen Williams, 16 April 2004:
  fix typo in JSE.h; update MAINTAINERS
2004-04-18 22:57:51 +00:00
wdenk
498b8db7f5 * Patch by Matthew S. McClintock, 14 Apr 2004:
fix initdram function for utx8245 board

* Patch by Markus Pietrek, 14 Apr 2004:
  use ATAG_INITRD2 instead of deprecated ATAG_INITRD tag

* Patch by Reinhard Meyer, 18 Apr 2004:
  provide the IDE Reset Function for EMK 5200 boards

* Patch by Masami Komiya, 12 Apr 2004:
  fix pci_hose_write_config_{byte,word}_via_dword problems
2004-04-18 22:26:17 +00:00
wdenk
a8bd82de46 * Patch by Sangmoon Kim, 12 Apr 2004:
Update max RAM size for debris board

* Patch by Travis Sawyer, 08 Apr 2004:
  Add TLB entry for second DIMM slot on ocotea

* Patch by Masami Komiya, 08 Apr 2004:
  add RTL8169 network driver
2004-04-18 22:03:42 +00:00
wdenk
7abf0c5886 * Patch by Dan Malek, 07 Apr 2004:
- Add support for RPC/STx GP3, Motorola 8560 board
  - Update 85xx TSEC driver so it searches MII for first available PHY
    and uses that one.
  - Add functions to support console MII commands.

* Patch by Tolunay Orkun, 07 Apr 2004:
  Move  initialization of bi_iic_fast[]
  from board_init_f() to board_init_r()

* Patch by Yasushi Shoji, 07 Apr 2004:
  Cleanup microblaze port

* Patch by Sangmoon Kim, 07 Apr 2004:
  Add auto SDRAM module detection for Debris board
2004-04-18 21:45:42 +00:00
wdenk
d4326aca18 * Add missing microblaze header files
* Patch by Rune Torgersen, 06 Apr 2004:
  - Fix some PCI problems on the MPC8266ADS board
  - Fix the location of some PCI entries in the immap structure
2004-04-18 21:17:30 +00:00
wdenk
507bbe3e80 * Patch by Yasushi Shoji, 07 Apr 2004:
- add support for microblaze processors
  - add support for AtmarkTechno "suzaku" board
2004-04-18 21:13:41 +00:00
wdenk
998eaaecd4 * Configure PPChameleon board to use redundand environment in flash
* Configure PPChameleon board to use JFFS2 NAND support.

* Added support for JFFS2 filesystem (read-only) on top of NAND flash
2004-04-18 19:43:36 +00:00
wdenk
6e5923851e * Cleanup, minor fixes
* Patch by Rune Torgersen, 16 Apr 2004:
  LBA48 fixes

* Patches by Pantelis Antoniou, 16 Apr 2004:
  - Fix some compile problems;
    add "once" functionality for the netretry variable
2004-04-18 17:39:38 +00:00
wdenk
c26e454dfc Patches by Pantelis Antoniou, 16 Apr 2004:
- add support for a new version of an Intracom board and fix
  various other things on others.
- add verify support to the crc32 command (define
  CONFIG_CRC32_VERIFY to enable it)
- fix FEC driver for MPC8xx systems:
  1. fix compilation problems for boards that use dynamic
     allocation of DPRAM
  2. shut down FEC after network transfers
- HUSH parser fixes:
  1. A new test command was added. This is a simplified version of
     the one in the bourne shell.
  2. A new exit command was added which terminates the current
     executing script.
  3. Fixed handing of $? (exit code of last executed command)
2004-04-18 10:13:26 +00:00
wdenk
ea66bc8804 * Patch by George G. Davis, 02 Apr 2004:
add support for Intel Assabet board
2004-04-15 23:23:39 +00:00
wdenk
db01a2ea99 * Patch by Stephen Williams, 01 Apr 2004:
Add support for Picture Elements JSE board

* Patch by Christian Pell, 01 Apr 2004:
  Add CompactFlash support for PXA systems.
2004-04-15 23:14:49 +00:00
wdenk
bda6c8aece Patches by Pantelis Antoniou, 30 Mar 2004:
- some minor patches / cleanup
2004-04-15 21:58:11 +00:00
wdenk
a3d991bd0d Patches by Pantelis Antoniou, 30 Mar 2004:
add networking support for VLANs (802.1q), and CDP (Cisco Discovery Protocol)
2004-04-15 21:48:45 +00:00
wdenk
a6ab4bf978 Patches by Pantelis Antoniou, 30 Mar 2004:
Improve and fix various things in the MPC8xx FEC driver:
1. The new 87x and 88x series of processors have two FECs,
   and the new driver supports them both.
2. Another change in the 87x/88x series is support for
   the RMII (Reduced MII) interface. However numerous
   changes are needed to make it work since the PHYs
   are connected to the same lines. That means that
   you have to address them correctly over the MII
   interface.
2004-04-15 21:31:56 +00:00
wdenk
5a8c51cd5e * Patches by Pantelis Antoniou, 30 Mar 2004:
- add support for the Epson 156x series of graphical displays
    (These displays are serial and not suitable for using a normal
    framebuffer console on them)
  - add infrastructure needed in order to POST any DSPs in a board
2004-04-15 21:16:42 +00:00
wdenk
04a85b3b36 * Patches by Pantelis Antoniou, 30 Mar 2004:
- add auto-complete support to the U-Boot CLI
  - add support for NETTA and NETPHONE boards; fix NETVIA board

* Patch by Yuli Barcohen, 28 Mar 2004:
  - Add support for MPC8272 family including MPC8247/8248/8271/8272
  - Add support for MPC8272ADS evaluation board (another flavour of MPC8260ADS)
  - Change configuration method for MPC8260ADS family
2004-04-15 18:22:41 +00:00
wdenk
d716b12671 Add startup code to clear the BSS of standalone applications 2004-04-12 16:12:49 +00:00
wdenk
56b86bf0cd Fix if / elif handling bug in HUSH shell 2004-04-12 14:31:43 +00:00
166 changed files with 21577 additions and 2302 deletions

153
CHANGELOG
View File

@@ -1,3 +1,156 @@
======================================================================
Changes for U-Boot 1.1.1:
======================================================================
* Modify KUP4X board configuration to use SL811 driver for USB memory
sticks (including FAT / VFAT filesystem support)
* Add SL811 Host Controller Interface driver for USB
* Add CFG_I2C_EEPROM_ADDR_OVERFLOW desription to README
* Patch by Pantelis Antoniou, 19 Apr 2004:
Allow to use shell style syntax (i. e. ${var} ) with standard parser.
Minor patches for Intracom boards.
* Patch by Christian Pell, 19 Apr 2004:
cleanup support for CF/IDE on PCMCIA for PXA25X
* Temporarily disabled John Kerl's extended MII command code because
"miivals.h" is missing
* Patches by Mark Jonas, 13 Apr 2004:
- Remove CS0 chip select timing setting from cpu/mpc5xxx/start.S
- Add sync instructions to IceCube SDRAM init code
- Move SDRAM chip constants into seperate include files
- Unify DDR and SDR initialization code
- Unify all IceCube (Lite5xxx) target names
* Patch by John Kerl, 16 Apr 2004:
Enable ranges in mii command, e.g. mii read 0-1f 0 or
mii read 4-7 18-1a. Also add mii dump subcommand for
pretty-printing standard regs 0-5.
* Patch by Stephen Williams, 16 April 2004:
fix typo in JSE.h; update MAINTAINERS
* Patch by Matthew S. McClintock, 14 Apr 2004:
fix initdram function for utx8245 board
* Patch by Markus Pietrek, 14 Apr 2004:
use ATAG_INITRD2 instead of deprecated ATAG_INITRD tag
* Patch by Reinhard Meyer, 18 Apr 2004:
provide the IDE Reset Function for EMK 5200 boards
* Patch by Masami Komiya, 12 Apr 2004:
fix pci_hose_write_config_{byte,word}_via_dword problems
* Patch by Sangmoon Kim, 12 Apr 2004:
Update max RAM size for debris board
* Patch by Travis Sawyer, 08 Apr 2004:
Add TLB entry for second DIMM slot on ocotea
* Patch by Masami Komiya, 08 Apr 2004:
add RTL8169 network driver
* Patch by Dan Malek, 07 Apr 2004:
- Add support for RPC/STx GP3, Motorola 8560 board
- Update 85xx TSEC driver so it searches MII for first available PHY
and uses that one.
- Add functions to support console MII commands.
* Patch by Tolunay Orkun, 07 Apr 2004:
Move initialization of bi_iic_fast[]
from board_init_f() to board_init_r()
* Patch by Yasushi Shoji, 07 Apr 2004:
Cleanup microblaze port
* Patch by Sangmoon Kim, 07 Apr 2004:
Add auto SDRAM module detection for Debris board
* Patch by Rune Torgersen, 06 Apr 2004:
- Fix some PCI problems on the MPC8266ADS board
- Fix the location of some PCI entries in the immap structure
* Patch by Yasushi Shoji, 07 Apr 2004:
- add support for microblaze processors
- add support for AtmarkTechno "suzaku" board
* Configure PPChameleon board to use redundand environment in flash
* Configure PPChameleon board to use JFFS2 NAND support.
* Added support for JFFS2 filesystem (read-only) on top of NAND flash
* Patch by Rune Torgersen, 16 Apr 2004:
LBA48 fixes
* Patches by Pantelis Antoniou, 16 Apr 2004:
- add support for a new version of an Intracom board and fix
various other things on others.
- add verify support to the crc32 command (define
CONFIG_CRC32_VERIFY to enable it)
- fix FEC driver for MPC8xx systems:
1. fix compilation problems for boards that use dynamic
allocation of DPRAM
2. shut down FEC after network transfers
- HUSH parser fixes:
1. A new test command was added. This is a simplified version of
the one in the bourne shell.
2. A new exit command was added which terminates the current
executing script.
3. Fixed handing of $? (exit code of last executed command)
- Fix some compile problems;
add "once" functionality for the netretry variable
* Patch by George G. Davis, 02 Apr 2004:
add support for Intel Assabet board
* Patch by Stephen Williams, 01 Apr 2004:
Add support for Picture Elements JSE board
* Patch by Christian Pell, 01 Apr 2004:
Add CompactFlash support for PXA systems.
* Patches by Pantelis Antoniou, 30 Mar 2004:
- add auto-complete support to the U-Boot CLI
- add support for NETTA and NETPHONE boards; fix NETVIA board
- add support for the Epson 156x series of graphical displays
(These displays are serial and not suitable for using a normal
framebuffer console on them)
- add infrastructure needed in order to POST any DSPs in a board
- improve and fix various things in the MPC8xx FEC driver:
1. The new 87x and 88x series of processors have two FECs,
and the new driver supports them both.
2. Another change in the 87x/88x series is support for
the RMII (Reduced MII) interface. However numerous
changes are needed to make it work since the PHYs
are connected to the same lines. That means that
you have to address them correctly over the MII
interface.
3. We now correctly match the MII/RMII interface
configuration to what the PHY reports.
- Fix problem when readingthe MII status register. Due to the
internal design of many PHYs you have to read the register
twice. The problem is more apparent in 10Mbit mode.
- add new mode ".jffs2s" for reading from a NAND device: it just
skips over bad blocks.
- add networking support for VLANs (802.1q), and CDP (Cisco
Discovery Protocol)
- some minor patches / cleanup
* Patch by Yuli Barcohen, 28 Mar 2004:
- Add support for MPC8272 family including MPC8247/8248/8271/8272
- Add support for MPC8272ADS evaluation board (another flavour of MPC8260ADS)
- Change configuration method for MPC8260ADS family
* add startup code to clear the BSS of standalone applications
* Fix if / elif handling bug in HUSH shell
======================================================================
Changes for U-Boot 1.1.0:
======================================================================

12
CREDITS
View File

@@ -28,12 +28,18 @@ D: ERIC Support
N: Pantelis Antoniou
E: panto@intracom.gr
D: NETVIA board support, ARTOS support.
D: NETVIA & NETPHONE board support, ARTOS support.
N: Pierre Aubert
E: <p.aubert@staubli.com>
D: Support for RPXClassic board
N: Yuli Barcohen
E: yuli@arabellasw.com
D: Unified support for Motorola MPC826xADS/MPC8272ADS/PQ2FADS boards.
D: Support for Zephyr Engineering ZPC.1900 board.
W: http://www.arabellasw.com
N: Jerry van Baren
E: <vanbaren@cideas.com>
D: BedBug port to 603e core (MPC82xx). Code for enhanced memory test.
@@ -83,6 +89,10 @@ N: Magnus Damm
E: damm@opensource.se
D: 8xxrom
N: George G. Davis
E: gdavis@mvista.com
D: Board ports for ADS GraphicsClient+ and Intel Assabet
N: Arun Dharankar
E: ADharankar@ATTBI.Com
D: threads / scheduler example code

View File

@@ -27,6 +27,7 @@ Pantelis Antoniou <panto@intracom.gr>
Yuli Barcohen <yuli@arabellasw.com>
MPC8260ADS MPC826x/MPC827x/MPC8280
ZPC1900 MPC8265
Jerry Van Baren <gerald.vanbaren@smiths-aerospace.com>
@@ -254,6 +255,10 @@ Rune Torgersen <runet@innovsys.com>
MPC8266ADS MPC8266
Stephen Williams <steve@icarus.com>
JSE PPC405GPr
John Zhan <zhanz@sinovee.com>
svm_sc8xx MPC8xx
@@ -263,6 +268,10 @@ Xianghua Xiao <x.xiao@motorola.com>
MPC8540ADS MPC8540
MPC8560ADS MPC8560
Dan Malek <dan@embeddededge.com>
STxGP3 MPC85xx
-------------------------------------------------------------------------
Unknown / orphaned boards:
@@ -285,7 +294,6 @@ Unknown / orphaned boards:
MOUSSE MPC824x
MPC8260ADS MPC8260
RPXsuper MPC8260
rsdproto MPC8260
@@ -299,6 +307,11 @@ Unknown / orphaned boards:
# Board CPU #
#########################################################################
George G. Davis <gdavis@mvista.com>
assabet SA1100
gcplus SA1100
Thomas Elste <info@elste.org>
modnet50 ARM720T (NET+50)

27
MAKEALL
View File

@@ -25,7 +25,7 @@ LIST_5xx=" \
#########################################################################
LIST_5xxx=" \
IceCube_5100 IceCube_5200 EVAL5200 PM520 \
icecube_5100 icecube_5200 EVAL5200 PM520 \
"
#########################################################################
@@ -48,7 +48,7 @@ LIST_8xx=" \
RPXClassic RPXlite RRvision SM850 \
SPD823TS svm_sc8xx SXNI855T TOP860 \
TQM823L TQM823L_LCD TQM850L TQM855L \
TQM860L v37 \
TQM860L v37 NETTA NETPHONE \
"
#########################################################################
@@ -60,11 +60,12 @@ LIST_4xx=" \
CANBT CPCI405 CPCI4052 CPCI405AB \
CPCI440 CPCIISER4 CRAYL1 csb272 \
DASA_SIM DP405 DU405 EBONY \
ERIC EXBITGEN HUB405 MIP405 \
MIP405T ML2 ml300 OCOTEA \
OCRTC ORSG PCI405 PIP405 \
PLU405 PMC405 PPChameleonEVB VOH405 \
W7OLMC W7OLMG WALNUT405 XPEDITE1K \
ERIC EXBITGEN HUB405 JSE \
MIP405 MIP405T ML2 ml300 \
OCOTEA OCRTC ORSG PCI405 \
PIP405 PLU405 PMC405 PPChameleonEVB \
VOH405 W7OLMC W7OLMG WALNUT405 \
XPEDITE1K \
"
#########################################################################
@@ -85,10 +86,10 @@ LIST_824x=" \
LIST_8260=" \
atc cogent_mpc8260 CPU86 ep8260 \
gw8260 hymod IPHASE4539 MPC8260ADS \
MPC8266ADS PM826 PM828 ppmc8260 \
RPXsuper rsdproto sacsng sbc8260 \
SCM TQM8260_AC TQM8260_AD TQM8260_AE \
ZPC1900 \
MPC8266ADS MPC8272ADS PM826 PM828 \
ppmc8260 PQ2FADS RPXsuper rsdproto \
sacsng sbc8260 SCM TQM8260_AC \
TQM8260_AD TQM8260_AE ZPC1900 \
"
#########################################################################
@@ -96,7 +97,7 @@ LIST_8260=" \
#########################################################################
LIST_85xx=" \
MPC8540ADS MPC8560ADS \
MPC8540ADS MPC8560ADS stxgp3 \
"
#########################################################################
@@ -123,7 +124,7 @@ LIST_ppc="${LIST_5xx} ${LIST_5xxx} \
## StrongARM Systems
#########################################################################
LIST_SA="dnp1110 gcplus lart shannon"
LIST_SA="assabet dnp1110 gcplus lart shannon"
#########################################################################
## ARM7 Systems

127
Makefile
View File

@@ -75,6 +75,9 @@ endif
ifeq ($(ARCH),m68k)
CROSS_COMPILE = m68k-elf-
endif
ifeq ($(ARCH),microblaze)
CROSS_COMPILE = mb-
endif
endif
endif
@@ -166,6 +169,9 @@ depend dep:
tags:
ctags -w `find $(SUBDIRS) include \
lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \
fs/cramfs fs/fat fs/fdos fs/jffs2 \
net disk rtc dtt drivers drivers/sk98lin common \
\( -name CVS -prune \) -o \( -name '*.[ch]' -print \)`
etags:
@@ -200,22 +206,22 @@ unconfig:
cmi_mpc5xx_config: unconfig
@./mkconfig $(@:_config=) ppc mpc5xx cmi
PATI_config:unconfig
PATI_config: unconfig
@./mkconfig $(@:_config=) ppc mpc5xx pati mpl
#########################################################################
## MPC5xxx Systems
#########################################################################
MPC5200LITE_config \
MPC5200LITE_LOWBOOT_config \
MPC5200LITE_LOWBOOT08_config \
icecube_5200_DDR_config \
IceCube_5200_DDR_config \
icecube_5200_DDR_LOWBOOT_config \
icecube_5200_DDR_LOWBOOT08_config \
icecube_5200_config \
IceCube_5200_config \
IceCube_5100_config: unconfig
Lite5200_config \
Lite5200_LOWBOOT_config \
Lite5200_LOWBOOT08_config \
icecube_5200_config \
icecube_5200_LOWBOOT_config \
icecube_5200_LOWBOOT08_config \
icecube_5200_DDR_config \
icecube_5200_DDR_LOWBOOT_config \
icecube_5200_DDR_LOWBOOT08_config \
icecube_5100_config: unconfig
@ >include/config.h
@[ -z "$(findstring LOWBOOT_,$@)" ] || \
{ if [ "$(findstring DDR,$@)" ] ; \
@@ -398,6 +404,32 @@ NETVIA_config: unconfig
}
@./mkconfig -a $(call xtract_NETVIA,$@) ppc mpc8xx netvia
xtract_NETPHONE = $(subst _V2,,$(subst _config,,$1))
NETPHONE_V2_config \
NETPHONE_config: unconfig
@ >include/config.h
@[ -z "$(findstring NETPHONE_config,$@)" ] || \
{ echo "#define CONFIG_NETPHONE_VERSION 1" >>include/config.h ; \
}
@[ -z "$(findstring NETPHONE_V2_config,$@)" ] || \
{ echo "#define CONFIG_NETPHONE_VERSION 2" >>include/config.h ; \
}
@./mkconfig -a $(call xtract_NETPHONE,$@) ppc mpc8xx netphone
xtract_NETTA = $(subst _ISDN,,$(subst _config,,$1))
NETTA_ISDN_config \
NETTA_config: unconfig
@ >include/config.h
@[ -z "$(findstring NETTA_config,$@)" ] || \
{ echo "#undef CONFIG_NETTA_ISDN" >>include/config.h ; \
}
@[ -z "$(findstring NETTA_ISDN_config,$@)" ] || \
{ echo "#define CONFIG_NETTA_ISDN 1" >>include/config.h ; \
}
@./mkconfig -a $(call xtract_NETTA,$@) ppc mpc8xx netta
NX823_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8xx nx823
@@ -550,7 +582,7 @@ AR405_config: unconfig
ASH405_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx ash405 esd
BUBINGA405EP_config:unconfig
BUBINGA405EP_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx bubinga405ep
CANBT_config: unconfig
@@ -568,7 +600,7 @@ CPCI440_config: unconfig
CPCIISER4_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx cpciiser4 esd
CRAYL1_config:unconfig
CRAYL1_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx L1 cray
csb272_config: unconfig
@@ -583,33 +615,36 @@ DP405_config: unconfig
DU405_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx du405 esd
EBONY_config:unconfig
EBONY_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx ebony
ERIC_config:unconfig
ERIC_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx eric
EXBITGEN_config:unconfig
EXBITGEN_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx exbitgen
HUB405_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx hub405 esd
MIP405_config:unconfig
JSE_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx jse
MIP405_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx mip405 mpl
MIP405T_config:unconfig
MIP405T_config: unconfig
@echo "#define CONFIG_MIP405T" >include/config.h
@echo "Enable subset config for MIP405T"
@./mkconfig -a MIP405 ppc ppc4xx mip405 mpl
ML2_config:unconfig
ML2_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx ml2
ml300_config:unconfig
ml300_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx ml300 xilinx
OCOTEA_config:unconfig
OCOTEA_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx ocotea
OCRTC_config \
@@ -619,7 +654,7 @@ ORSG_config: unconfig
PCI405_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx pci405 esd
PIP405_config:unconfig
PIP405_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx pip405 mpl
PLU405_config: unconfig
@@ -654,10 +689,10 @@ W7OLMC_config \
W7OLMG_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx w7o
WALNUT405_config:unconfig
WALNUT405_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx walnut405
XPEDITE1K_config:unconfig
XPEDITE1K_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx xpedite1k
#########################################################################
@@ -687,6 +722,9 @@ CPC45_ROMBOOT_config: unconfig
CU824_config: unconfig
@./mkconfig $(@:_config=) ppc mpc824x cu824
debris_config: unconfig
@./mkconfig $(@:_config=) ppc mpc824x debris etin
eXalion_config: unconfig
@./mkconfig $(@:_config=) ppc mpc824x eXalion
@@ -752,8 +790,23 @@ hymod_config: unconfig
IPHASE4539_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8260 iphase4539
MPC8260ADS_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8260 mpc8260ads
MPC8260ADS_config \
MPC8260ADS_33MHz_config \
MPC8260ADS_40MHz_config \
MPC8272ADS_config \
PQ2FADS_config \
PQ2FADS-VR_config \
PQ2FADS-ZU_config \
PQ2FADS-ZU_66MHz_config \
: unconfig
$(if $(findstring PQ2FADS,$@), \
@echo "#define CONFIG_ADSTYPE CFG_PQ2FADS" > include/config.h, \
@echo "#define CONFIG_ADSTYPE CFG_"$(subst MPC,,$(word 1,$(subst _, ,$@))) > include/config.h)
$(if $(findstring MHz,$@), \
@echo "#define CONFIG_8260_CLKIN" $(subst MHz,,$(word 2,$(subst _, ,$@)))"000000" >> include/config.h, \
$(if $(findstring VR,$@), \
@echo "#define CONFIG_8260_CLKIN 66000000" >> include/config.h))
@./mkconfig -a MPC8260ADS ppc mpc8260 mpc8260ads
MPC8266ADS_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8260 mpc8266ads
@@ -897,6 +950,9 @@ MPC8540ADS_config: unconfig
MPC8560ADS_config: unconfig
@./mkconfig $(@:_config=) ppc mpc85xx mpc8560ads
stxgp3_config: unconfig
@./mkconfig $(@:_config=) ppc mpc85xx stxgp3
#########################################################################
## 74xx/7xx Systems
#########################################################################
@@ -913,9 +969,6 @@ DB64360_config: unconfig
DB64460_config: unconfig
@./mkconfig DB64460 ppc 74xx_7xx db64460 Marvell
debris_config: unconfig
@./mkconfig $(@:_config=) ppc mpc824x debris etin
ELPPC_config: unconfig
@./mkconfig $(@:_config=) ppc 74xx_7xx elppc eltec
@@ -940,6 +993,9 @@ ZUMA_config: unconfig
## StrongARM Systems
#########################################################################
assabet_config : unconfig
@./mkconfig $(@:_config=) arm sa1100 assabet
dnp1110_config : unconfig
@./mkconfig $(@:_config=) arm sa1100 dnp1110
@@ -1200,6 +1256,17 @@ ADNPESC1_config: unconfig
@./mkconfig -a ADNPESC1 nios nios adnpesc1 ssv
#========================================================================
# MicroBlaze
#========================================================================
#########################################################################
## Microblaze
#########################################################################
suzaku_config: unconfig
@ >include/config.h
@echo "#define CONFIG_SUZAKU 1" >> include/config.h
@./mkconfig -a $(@:_config=) microblaze microblaze suzaku AtmarkTechno
#########################################################################
## MIPS32 AU1X00
#########################################################################
@@ -1229,8 +1296,8 @@ clean:
rm -f examples/hello_world examples/timer \
examples/eepro100_eeprom examples/sched \
examples/mem_to_mem_idma2intr examples/82559_eeprom
rm -f tools/img2srec tools/mkimage tools/envcrc tools/gen_eth_addr
rm -f tools/mpc86x_clk
rm -f tools/easylogo/easylogo tools/bmp_logo
rm -f tools/gdb/astest tools/gdb/gdbcont tools/gdb/gdbsend
rm -f tools/env/fw_printenv tools/env/fw_setenv

2489
README

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -0,0 +1,29 @@
#
# (C) Copyright 2004 Atmark Techno, Inc.
#
# Yasushi SHOJI <yashi@atmark-techno.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 = 0x80F00000
PLATFORM_CPPFLAGS += -mno-xl-soft-mul
PLATFORM_CPPFLAGS += -mno-xl-soft-div
PLATFORM_CPPFLAGS += -mxl-barrel-shift

View File

@@ -0,0 +1,46 @@
/*
* (C) Copyright 2004 Atmark Techno, Inc.
*
* Yasushi SHOJI <yashi@atmark-techno.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>
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
unsigned long flash_init(void)
{
return 0;
}
void flash_print_info(flash_info_t *info)
{
}
int flash_erase(flash_info_t *info, int s_first, int s_last)
{
return 0;
}
int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
return 0;
}

View File

@@ -0,0 +1,29 @@
/*
* (C) Copyright 2004 Atmark Techno, Inc.
*
* Yasushi SHOJI <yashi@atmark-techno.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>
void do_reset(void)
{
}

View File

@@ -0,0 +1,65 @@
/*
* (C) Copyright 2004 Atmark Techno, Inc.
*
* Yasushi SHOJI <yashi@atmark-techno.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
*/
OUTPUT_ARCH(microblaze)
ENTRY(_start)
SECTIONS
{
.text ALIGN(0x4):
{
__text_start = .;
cpu/microblaze/start.o (.text)
*(.text)
__text_end = .;
}
.rodata ALIGN(0x4):
{
__rodata_start = .;
*(.rodata)
__rodata_end = .;
}
.data ALIGN(0x4):
{
__data_start = .;
*(.data)
__data_end = .;
}
.u_boot_cmd ALIGN(0x4):
{
__u_boot_cmd_start = .;
*(.u_boot_cmd)
__u_boot_cmd_end = .;
}
.bss ALIGN(0x4):
{
__bss_start = .;
*(.bss)
__bss_start = .;
}
}

49
board/assabet/Makefile Normal file
View File

@@ -0,0 +1,49 @@
#
# (C) Copyright 2000-2004
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# 2004 (c) MontaVista Software, Inc.
#
# 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 := assabet.o
SOBJS := setup.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
#########################################################################

121
board/assabet/assabet.c Normal file
View File

@@ -0,0 +1,121 @@
/*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* 2004 (c) MontaVista Software, Inc.
*
* 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 <SA-1100.h>
/* ------------------------------------------------------------------------- */
/*
* Board dependent initialisation
*/
#define ECOR 0x8000
#define ECOR_RESET 0x80
#define ECOR_LEVEL_IRQ 0x40
#define ECOR_WR_ATTRIB 0x04
#define ECOR_ENABLE 0x01
#define ECSR 0x8002
#define ECSR_IOIS8 0x20
#define ECSR_PWRDWN 0x04
#define ECSR_INT 0x02
#define SMC_IO_SHIFT 2
#define NCR_0 (*((volatile u_char *)(0x100000a0)))
#define NCR_ENET_OSC_EN (1<<3)
static inline u8
readb(volatile u8 * p)
{
return *p;
}
static inline void
writeb(u8 v, volatile u8 * p)
{
*p = v;
}
static void
smc_init(void)
{
u8 ecor;
u8 ecsr;
volatile u8 *addr = (volatile u8 *)(0x18000000 + (1 << 25));
NCR_0 |= NCR_ENET_OSC_EN;
udelay(100);
ecor = readb(addr + (ECOR << SMC_IO_SHIFT)) & ~ECOR_RESET;
writeb(ecor | ECOR_RESET, addr + (ECOR << SMC_IO_SHIFT));
udelay(100);
/*
* The device will ignore all writes to the enable bit while
* reset is asserted, even if the reset bit is cleared in the
* same write. Must clear reset first, then enable the device.
*/
writeb(ecor, addr + (ECOR << SMC_IO_SHIFT));
writeb(ecor | ECOR_ENABLE, addr + (ECOR << SMC_IO_SHIFT));
/*
* Set the appropriate byte/word mode.
*/
ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8;
ecsr |= ECSR_IOIS8;
writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT));
udelay(100);
}
static void
neponset_init(void)
{
smc_init();
}
int
board_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
gd->bd->bi_arch_number = 25; /* Intel Assabet Board */
gd->bd->bi_boot_params = 0xc0000100;
neponset_init();
return 0;
}
int
dram_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
return (0);
}

7
board/assabet/config.mk Normal file
View File

@@ -0,0 +1,7 @@
#
# SA-1110 based Intel Assabet board
#
# The Intel Assabet 1 bank of 32 MiB SDRAM
#
TEXT_BASE = 0xc1f00000

136
board/assabet/setup.S Normal file
View File

@@ -0,0 +1,136 @@
/*
* Memory Setup stuff - taken from blob memsetup.S
*
* Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
* Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
* 2004 (c) MontaVista Software, Inc.
*
* 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"
/*-----------------------------------------------------------------------
* Board defines:
*/
#define MDCNFG 0x00
#define MDCAS00 0x04
#define MDCAS01 0x08
#define MDCAS02 0x0C
#define MSC0 0x10
#define MSC1 0x14
#define MECR 0x18
#define MDREFR 0x1C
#define MDCAS20 0x20
#define MDCAS21 0x24
#define MDCAS22 0x28
#define MSC2 0x2C
#define SMCNFG 0x30
#define ASSABET_BCR (0x12000000)
#define ASSABET_BCR_DB1110 (0x00a07490 | (0<<16) | (0<<17))
#define ASSABET_SCR_nNEPONSET (1 << 9)
#define NEPONSET_LEDS (0x10000010)
/*-----------------------------------------------------------------------
* Setup parameters for the board:
*/
MEM_BASE: .long 0xa0000000
MEM_START: .long 0xc0000000
mdcnfg: .long 0x72547254
mdcas00: .long 0xaaaaaa7f
mdcas01: .long 0xaaaaaaaa
mdcas02: .long 0xaaaaaaaa
msc0: .long 0x4b384370
msc1: .long 0x22212419
mecr: .long 0x994a994a
mdrefr: .long 0x04340327
mdcas20: .long 0xaaaaaa7f
mdcas21: .long 0xaaaaaaaa
mdcas22: .long 0xaaaaaaaa
msc2: .long 0x42196669
smcnfg: .long 0x00000000
BCR: .long ASSABET_BCR
BCR_DB1110: .long ASSABET_BCR_DB1110
LEDS: .long NEPONSET_LEDS
.globl memsetup
memsetup:
/* Setting up the memory and stuff */
ldr r0, MEM_BASE
ldr r1, mdcas00
str r1, [r0, #MDCAS00]
ldr r1, mdcas01
str r1, [r0, #MDCAS01]
ldr r1, mdcas02
str r1, [r0, #MDCAS02]
ldr r1, mdcas20
str r1, [r0, #MDCAS20]
ldr r1, mdcas21
str r1, [r0, #MDCAS21]
ldr r1, mdcas22
str r1, [r0, #MDCAS22]
ldr r1, mdrefr
str r1, [r0, #MDREFR]
ldr r1, mecr
str r1, [r0, #MECR]
ldr r1, msc0
str r1, [r0, #MSC0]
ldr r1, msc1
str r1, [r0, #MSC1]
ldr r1, msc2
str r1, [r0, #MSC2]
ldr r1, smcnfg
str r1, [r0, #SMCNFG]
ldr r1, mdcnfg
str r1, [r0, #MDCNFG]
/* Load something to activate bank */
ldr r2, MEM_START
.rept 8
ldr r3, [r2]
.endr
/* Enable SDRAM */
orr r1, r1, #0x00000001
str r1, [r0, #MDCNFG]
ldr r1, BCR
ldr r2, BCR_DB1110
str r2, [r1]
ldr r1, LEDS
mov r0, #0x3
str r0, [r1]
/* All done... */
mov pc, lr

57
board/assabet/u-boot.lds Normal file
View File

@@ -0,0 +1,57 @@
/*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
* 2004 (c) MontaVista Software, Inc.
*
* 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/sa1100/start.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}

View File

@@ -73,9 +73,6 @@ SECTIONS
lib_ppc/extable.o (.text)
lib_generic/zlib.o (.text)
/* . = env_offset;*/
/* common/environment.o(.text)*/
*(.text)
*(.fixup)
*(.got1)
@@ -142,6 +139,13 @@ SECTIONS
*(.bss)
*(COMMON)
}
. = 0xFFFF8000;
.ppcenv :
{
common/environment.o(.ppcenv);
}
_end = . ;
PROVIDE (end = .);
}

View File

@@ -669,8 +669,7 @@ static int write_word (flash_info_t *info, ulong dest, ulong data)
int i;
/* Check if Flash is (sufficiently) erased */
if ((*((volatile CFG_FLASH_WORD_SIZE *)dest) &
(CFG_FLASH_WORD_SIZE)data) != (CFG_FLASH_WORD_SIZE)data) {
if ((*((volatile ulong *)dest) & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */

View File

@@ -182,21 +182,29 @@ void pci_init_board(void)
#endif
/*****************************************************************************
* provide the PCI Reset Function
* provide the IDE Reset Function
*****************************************************************************/
#ifdef CFG_CMD_IDE
#define GPIO_PSC1_4 0x01000000ul
#if defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET)
#define GPIO_PSC1_4 0x01000000UL
void init_ide_reset (void)
{
debug ("init_ide_reset\n");
/* Configure PSC1_4 as GPIO output for ATA reset */
*(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4;
*(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4;
}
void ide_set_reset (int idereset)
{
debug ("ide_reset(%d)\n", idereset);
if (idereset) {
*(vu_long *) MPC5XXX_WU_GPIO_DATA &= ~GPIO_PSC1_4;
} else {
*(vu_long *) MPC5XXX_WU_GPIO_DATA |= GPIO_PSC1_4;
*(vu_long *) MPC5XXX_WU_GPIO_DATA |= GPIO_PSC1_4;
}
/* Configure PSC1_4 as GPIO output for ATA reset */
/* (it does not matter we do this every time) */
*(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4;
*(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4;
}
#endif
#endif /* defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET) */

View File

@@ -24,6 +24,7 @@
#include <common.h>
#include <mpc824x.h>
#include <pci.h>
#include <i2c.h>
int checkboard (void)
{
@@ -52,28 +53,70 @@ int checkflash (void)
long int initdram (int board_type)
{
long size;
#if 0
long new_bank0_end;
long mear1;
long emear1;
#endif
int m, row, col, bank, i;
unsigned long start, end;
uint32_t mccr1;
uint32_t mear1 = 0, emear1 = 0, msar1 = 0, emsar1 = 0;
uint32_t mear2 = 0, emear2 = 0, msar2 = 0, emsar2 = 0;
uint8_t mber = 0;
size = get_ram_size(CFG_SDRAM_BASE, CFG_MAX_RAM_SIZE);
i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
#if 0
new_bank0_end = size - 1;
mear1 = mpc824x_mpc107_getreg(MEAR1);
emear1 = mpc824x_mpc107_getreg(EMEAR1);
mear1 = (mear1 & 0xFFFFFF00) |
((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
emear1 = (emear1 & 0xFFFFFF00) |
((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
mpc824x_mpc107_setreg(MEAR1, mear1);
mpc824x_mpc107_setreg(EMEAR1, emear1);
#endif
if (i2c_reg_read (0x50, 2) != 0x04) return 0; /* Memory type */
m = i2c_reg_read (0x50, 5); /* # of physical banks */
row = i2c_reg_read (0x50, 3); /* # of rows */
col = i2c_reg_read (0x50, 4); /* # of columns */
bank = i2c_reg_read (0x50, 17); /* # of logical banks */
return (size);
CONFIG_READ_WORD(MCCR1, mccr1);
mccr1 &= 0xffff0000;
start = CFG_SDRAM_BASE;
end = start + (1 << (col + row + 3) ) * bank - 1;
for (i = 0; i < m; i++) {
mccr1 |= ((row == 13)? 2 : (bank == 4)? 0 : 3) << i * 2;
if (i < 4) {
msar1 |= ((start >> 20) & 0xff) << i * 8;
emsar1 |= ((start >> 28) & 0xff) << i * 8;
mear1 |= ((end >> 20) & 0xff) << i * 8;
emear1 |= ((end >> 28) & 0xff) << i * 8;
} else {
msar2 |= ((start >> 20) & 0xff) << (i-4) * 8;
emsar2 |= ((start >> 28) & 0xff) << (i-4) * 8;
mear2 |= ((end >> 20) & 0xff) << (i-4) * 8;
emear2 |= ((end >> 28) & 0xff) << (i-4) * 8;
}
mber |= 1 << i;
start += (1 << (col + row + 3) ) * bank;
end += (1 << (col + row + 3) ) * bank;
}
for (; i < 8; i++) {
if (i < 4) {
msar1 |= 0xff << i * 8;
emsar1 |= 0x30 << i * 8;
mear1 |= 0xff << i * 8;
emear1 |= 0x30 << i * 8;
} else {
msar2 |= 0xff << (i-4) * 8;
emsar2 |= 0x30 << (i-4) * 8;
mear2 |= 0xff << (i-4) * 8;
emear2 |= 0x30 << (i-4) * 8;
}
}
CONFIG_WRITE_WORD(MCCR1, mccr1);
CONFIG_WRITE_WORD(MSAR1, msar1);
CONFIG_WRITE_WORD(EMSAR1, emsar1);
CONFIG_WRITE_WORD(MEAR1, mear1);
CONFIG_WRITE_WORD(EMEAR1, emear1);
CONFIG_WRITE_WORD(MSAR2, msar2);
CONFIG_WRITE_WORD(EMSAR2, emsar2);
CONFIG_WRITE_WORD(MEAR2, mear2);
CONFIG_WRITE_WORD(EMEAR2, emear2);
CONFIG_WRITE_BYTE(MBER, mber);
return (1 << (col + row + 3) ) * bank * m;
}
/*

View File

@@ -2,6 +2,9 @@
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2004
* Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
*
* See file CREDITS for list of people who contributed to this
* project.
*
@@ -25,90 +28,84 @@
#include <mpc5xxx.h>
#include <pci.h>
#if defined(CONFIG_MPC5200_DDR)
#include "mt46v16m16-75.h"
#else
#include "mt48lc16m16a2-75.h"
#endif
#ifndef CFG_RAMBOOT
static void sdram_start (int hi_addr)
{
long hi_addr_bit = hi_addr ? 0x01000000 : 0;
#ifdef CONFIG_MPC5200_DDR
/* unlock mode register */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xf05f0f00 | hi_addr_bit;
*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 | hi_addr_bit;
__asm__ volatile ("sync");
/* precharge all banks */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xf05f0f02 | hi_addr_bit;
*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
__asm__ volatile ("sync");
#if SDRAM_DDR
/* set mode register: extended mode */
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x40090000;
*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
__asm__ volatile ("sync");
/* set mode register: reset DLL */
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x058d0000;
/* precharge all banks */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xf05f0f02 | hi_addr_bit;
/* auto refresh */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xf05f0f04 | hi_addr_bit;
/* set mode register */
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x018d0000;
/* normal operation */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0x705f0f00 | hi_addr_bit;
#else
/* unlock mode register */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0000 | hi_addr_bit;
/* precharge all banks */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002 | hi_addr_bit;
/* set mode register */
#if defined(CONFIG_MPC5200)
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x00cd0000;
#elif defined(CONFIG_MGT5100)
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000;
*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
__asm__ volatile ("sync");
#endif
/* precharge all banks */
*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
__asm__ volatile ("sync");
/* auto refresh */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0004 | hi_addr_bit;
/* auto refresh */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0004 | hi_addr_bit;
*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 | hi_addr_bit;
__asm__ volatile ("sync");
/* set mode register */
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x00cd0000;
*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE;
__asm__ volatile ("sync");
/* normal operation */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0x504f0000 | hi_addr_bit;
#endif
*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
__asm__ volatile ("sync");
}
#endif
/*
* ATTENTION: Although partially referenced initdram does NOT make real use
* use of CFG_SDRAM_BASE. The code does not work if CFG_SDRAM_BASE
* is something else than 0x00000000.
*/
#if defined(CONFIG_MPC5200)
long int initdram (int board_type)
{
ulong dramsize = 0;
#ifdef CONFIG_MPC5200_DDR
ulong dramsize2 = 0;
#endif
#ifndef CFG_RAMBOOT
ulong test1, test2;
/* configure SDRAM start/end */
#if defined(CONFIG_MPC5200)
/* setup SDRAM chip selects */
*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e;/* 2G at 0x0 */
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000;/* disabled */
__asm__ volatile ("sync");
#ifdef CONFIG_MPC5200_DDR
/* setup config registers */
*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0x73722930;
*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x47770000;
*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
__asm__ volatile ("sync");
/* set tap delay to 0x10 */
*(vu_long *)MPC5XXX_CDM_PORCFG = 0x10000000;
#else
/* setup config registers */
*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0xd2322800;
*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x8ad70000;
#if SDRAM_DDR
/* set tap delay */
*(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
__asm__ volatile ("sync");
#endif
#elif defined(CONFIG_MGT5100)
*(vu_long *)MPC5XXX_SDRAM_START = 0x00000000;
*(vu_long *)MPC5XXX_SDRAM_STOP = 0x0000ffff;/* 2G */
*(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
/* setup config registers */
*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0xc2222600;
*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x88b70004;
/* address select register */
*(vu_long *)MPC5XXX_SDRAM_XLBSEL = 0x03000000;
#endif
/* find RAM size using SDRAM CS0 only */
sdram_start(0);
test1 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x80000000);
sdram_start(1);
@@ -119,11 +116,23 @@ long int initdram (int board_type)
} else {
dramsize = test2;
}
#if defined(CONFIG_MPC5200)
*(vu_long *)MPC5XXX_SDRAM_CS0CFG =
(0x13 + __builtin_ffs(dramsize >> 20) - 1);
#ifdef CONFIG_MPC5200_DDR
/* memory smaller than 1MB is impossible */
if (dramsize < (1 << 20)) {
dramsize = 0;
}
/* set SDRAM CS0 size according to the amount of RAM found */
if (dramsize > 0) {
*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 + __builtin_ffs(dramsize >> 20) - 1;
} else {
*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
}
/* let SDRAM CS1 start right after CS0 */
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e;/* 2G */
/* find RAM size using SDRAM CS1 only */
sdram_start(0);
test1 = get_ram_size((ulong *)(CFG_SDRAM_BASE + dramsize), 0x80000000);
sdram_start(1);
@@ -134,34 +143,94 @@ long int initdram (int board_type)
} else {
dramsize2 = test2;
}
*(vu_long *)MPC5XXX_SDRAM_CS1CFG =
dramsize + (0x13 + __builtin_ffs(dramsize2 >> 20) - 1);
#else
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
#endif
#elif defined(CONFIG_MGT5100)
*(vu_long *)MPC5XXX_SDRAM_STOP = ((dramsize - 1) >> 15);
#endif
#else /* CFG_RAMBOOT */
#ifdef CONFIG_MGT5100
*(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
dramsize = ((*(vu_long *)MPC5XXX_SDRAM_STOP + 1) << 15);
#else
dramsize = ((1 << (*(vu_long *)MPC5XXX_SDRAM_CS0CFG - 0x13)) << 20);
#ifdef CONFIG_MPC5200_DDR
dramsize2 = ((1 << (*(vu_long *)MPC5XXX_SDRAM_CS1CFG - 0x13)) << 20);
#endif
#endif
/* memory smaller than 1MB is impossible */
if (dramsize2 < (1 << 20)) {
dramsize2 = 0;
}
/* set SDRAM CS1 size according to the amount of RAM found */
if (dramsize2 > 0) {
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize
| (0x13 + __builtin_ffs(dramsize2 >> 20) - 1);
} else {
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
}
#else /* CFG_RAMBOOT */
/* retrieve size of memory connected to SDRAM CS0 */
dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF;
if (dramsize >= 0x13) {
dramsize = (1 << (dramsize - 0x13)) << 20;
} else {
dramsize = 0;
}
/* retrieve size of memory connected to SDRAM CS1 */
dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF;
if (dramsize2 >= 0x13) {
dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
} else {
dramsize2 = 0;
}
#endif /* CFG_RAMBOOT */
return dramsize + dramsize2;
}
#elif defined(CONFIG_MGT5100)
long int initdram (int board_type)
{
ulong dramsize = 0;
#ifndef CFG_RAMBOOT
ulong test1, test2;
/* setup and enable SDRAM chip selects */
*(vu_long *)MPC5XXX_SDRAM_START = 0x00000000;
*(vu_long *)MPC5XXX_SDRAM_STOP = 0x0000ffff;/* 2G */
*(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
__asm__ volatile ("sync");
/* setup config registers */
*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
/* address select register */
*(vu_long *)MPC5XXX_SDRAM_XLBSEL = SDRAM_ADDRSEL;
__asm__ volatile ("sync");
/* find RAM size */
sdram_start(0);
test1 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x80000000);
sdram_start(1);
test2 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x80000000);
if (test1 > test2) {
sdram_start(0);
dramsize = test1;
} else {
dramsize = test2;
}
/* set SDRAM end address according to size */
*(vu_long *)MPC5XXX_SDRAM_STOP = ((dramsize - 1) >> 15);
#else /* CFG_RAMBOOT */
/* Retrieve amount of SDRAM available */
dramsize = ((*(vu_long *)MPC5XXX_SDRAM_STOP + 1) << 15);
#endif /* CFG_RAMBOOT */
#ifdef CONFIG_MPC5200_DDR
dramsize += dramsize2;
#endif
/* return total ram size */
return dramsize;
}
#else
#error Neither CONFIG_MPC5200 or CONFIG_MGT5100 defined
#endif
int checkboard (void)
{
#if defined(CONFIG_MPC5200)

View File

@@ -0,0 +1,37 @@
/*
* (C) Copyright 2004
* Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.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
*/
#define SDRAM_DDR 1 /* is DDR */
#if defined(CONFIG_MPC5200)
/* Settings for XLB = 132 MHz */
#define SDRAM_MODE 0x018D0000
#define SDRAM_EMODE 0x40090000
#define SDRAM_CONTROL 0x705f0f00
#define SDRAM_CONFIG1 0x73722930
#define SDRAM_CONFIG2 0x47770000
#define SDRAM_TAPDELAY 0x10000000
#else
#error CONFIG_MPC5200 not defined
#endif

View File

@@ -0,0 +1,43 @@
/*
* (C) Copyright 2004
* Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.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
*/
#define SDRAM_DDR 0 /* is SDR */
#if defined(CONFIG_MPC5200)
/* Settings for XLB = 132 MHz */
#define SDRAM_MODE 0x00CD0000
#define SDRAM_CONTROL 0x504F0000
#define SDRAM_CONFIG1 0xD2322800
#define SDRAM_CONFIG2 0x8AD70000
#elif defined(CONFIG_MGT5100)
/* Settings for XLB = 66 MHz */
#define SDRAM_MODE 0x008D0000
#define SDRAM_CONTROL 0x504F0000
#define SDRAM_CONFIG1 0xC2222600
#define SDRAM_CONFIG2 0x88B70004
#define SDRAM_ADDRSEL 0x02000000
#else
#error Neither CONFIG_MPC5200 or CONFIG_MGT5100 defined
#endif

44
board/jse/Makefile Normal file
View File

@@ -0,0 +1,44 @@
#
# Copyright 2004 Picture Elements, Inc.
# Stephen Williams <steve@icarus.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 $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
OBJS = $(BOARD).o sdram.o flash.o host_bridge.o
SOBJS = init.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
#########################################################################

48
board/jse/README.txt Normal file
View File

@@ -0,0 +1,48 @@
JSE Configuration Details
Memory Bank 0 -- Flash chip
---------------------------
0xfff00000 - 0xffffffff
The flash chip is really only 512Kbytes, but the high address bit of
the 1Meg region is ignored, so the flash is replicated through the
region. Thus, this is consistent with a flash base address 0xfff80000.
The placement at the end is to be consistent with reset behavior,
where the processor itself initially uses this bus to load the branch
vector and start running.
On-Chip Memory
--------------
0xf4000000 - 0xf4000fff
The 405GPr includes a 4K on-chip memory that can be placed however
software chooses. I choose to place the memory at this address, to
keep it out of the cachable areas.
Memory Bank 1 -- SystemACE Controller
-------------------------------------
0xf0000000 - 0xf00fffff
The SystemACE chip is along on peripheral bank CS#1. We don't need
much space, but 1Meg is the smallest we can configure the chip to
allocate. We need it far away from the flash region, because this
region is set to be non-cached.
Internal Peripherals
--------------------
0xef600300 - 0xef6008ff
These are scattered various peripherals internal to the PPC405GPr
chip.
SDRAM
-----
0x00000000 - 0x07ffffff (128 MBytes)

24
board/jse/config.mk Normal file
View File

@@ -0,0 +1,24 @@
#
# (C) Copyright 2003 Picture Elements, Inc.
#
# 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
#
#
# Picture Elements, Inc. JSE boards
#
TEXT_BASE = 0xFFF80000

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

@@ -0,0 +1,671 @@
/*
* (C) Copyright 2000-2004
* 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
*/
/*
* Modified 4/5/2001
* Wait for completion of each sector erase command issued
* 4/5/2001
* Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
*/
#include <common.h>
#include <ppc4xx.h>
#include <asm/processor.h>
#if CFG_MAX_FLASH_BANKS != 1
#error "CFG_MAX_FLASH_BANKS must be 1"
#endif
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*-----------------------------------------------------------------------
* Functions
*/
static ulong flash_get_size (vu_long * addr, flash_info_t * info);
static int write_word (flash_info_t * info, ulong dest, ulong data);
static void flash_get_offsets (ulong base, flash_info_t * info);
#define ADDR0 0x5555
#define ADDR1 0x2aaa
#define FLASH_WORD_SIZE unsigned char
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
unsigned long size_b0;
unsigned long base_b0;
/* Init: no FLASHes known */
flash_info[0].flash_id = FLASH_UNKNOWN;
/* Static FLASH Bank configuration here - FIXME XXX */
size_b0 =
flash_get_size ((vu_long *) FLASH_BASE0_PRELIM,
&flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", size_b0, size_b0 << 20);
}
/* Only one bank */
/* Setup offsets */
flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]);
/* Monitor protection ON by default */
(void) flash_protect (FLAG_PROTECT_SET,
FLASH_BASE0_PRELIM,
FLASH_BASE0_PRELIM + monitor_flash_len - 1,
&flash_info[0]);
flash_info[0].size = size_b0;
return size_b0;
}
/*-----------------------------------------------------------------------
*/
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_SST) ||
(info->flash_id == FLASH_AM040)) {
for (i = 0; i < info->sector_count; i++)
info->start[i] = base + (i * 0x00010000);
} else {
if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00004000;
info->start[2] = base + 0x00006000;
info->start[3] = base + 0x00008000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] =
base + (i * 0x00010000) - 0x00030000;
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00004000;
info->start[i--] = base + info->size - 0x00006000;
info->start[i--] = base + info->size - 0x00008000;
for (; i >= 0; i--) {
info->start[i] = base + i * 0x00010000;
}
}
}
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t * info)
{
int i;
int k;
int size;
int erased;
volatile unsigned long *flash;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD:
printf ("AMD ");
break;
case FLASH_MAN_FUJ:
printf ("FUJITSU ");
break;
case FLASH_MAN_SST:
printf ("SST ");
break;
default:
printf ("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AM040:
printf ("AM29F040 (512 Kbit, uniform sector size)\n");
break;
case FLASH_AM400B:
printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
break;
case FLASH_AM400T:
printf ("AM29LV400T (4 Mbit, top boot sector)\n");
break;
case FLASH_AM800B:
printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
break;
case FLASH_AM800T:
printf ("AM29LV800T (8 Mbit, top boot sector)\n");
break;
case FLASH_AM160B:
printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
break;
case FLASH_AM160T:
printf ("AM29LV160T (16 Mbit, top boot sector)\n");
break;
case FLASH_AM320B:
printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
break;
case FLASH_AM320T:
printf ("AM29LV320T (32 Mbit, top boot sector)\n");
break;
case FLASH_SST800A:
printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
break;
case FLASH_SST160A:
printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
break;
default:
printf ("Unknown Chip Type\n");
break;
}
printf (" Size: %ld KB in %d Sectors\n",
info->size >> 10, info->sector_count);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; ++i) {
/*
* 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 ");
#if 0 /* test-only */
printf (" %08lX%s",
info->start[i], info->protect[i] ? " (RO)" : " "
#else
printf (" %08lX%s%s",
info->start[i],
erased ? " E" : " ", info->protect[i] ? "RO " : " "
#endif
);
}
printf ("\n");
return;
}
/*-----------------------------------------------------------------------
*/
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
static ulong flash_get_size (vu_long * addr, flash_info_t * info)
{
short i;
FLASH_WORD_SIZE value;
ulong base = (ulong) addr;
volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) addr;
/* Write auto select command: read Manufacturer ID */
addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00900090;
#ifdef CONFIG_ADCIOP
value = addr2[2];
#else
value = addr2[0];
#endif
switch (value) {
case (FLASH_WORD_SIZE) AMD_MANUFACT:
info->flash_id = FLASH_MAN_AMD;
break;
case (FLASH_WORD_SIZE) FUJ_MANUFACT:
info->flash_id = FLASH_MAN_FUJ;
break;
case (FLASH_WORD_SIZE) SST_MANUFACT:
info->flash_id = FLASH_MAN_SST;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* no or unknown flash */
}
#ifdef CONFIG_ADCIOP
value = addr2[0]; /* device ID */
/* printf("\ndev_code=%x\n", value); */
#else
value = addr2[1]; /* device ID */
#endif
switch (value) {
case (FLASH_WORD_SIZE) AMD_ID_F040B:
info->flash_id += FLASH_AM040;
info->sector_count = 8;
info->size = 0x0080000; /* => 512 ko */
break;
case (FLASH_WORD_SIZE) AMD_ID_LV040B:
info->flash_id += FLASH_AM040;
info->sector_count = 8;
info->size = 0x0080000; /* => 512 ko */
break;
case (FLASH_WORD_SIZE) AMD_ID_LV400T:
info->flash_id += FLASH_AM400T;
info->sector_count = 11;
info->size = 0x00080000;
break; /* => 0.5 MB */
case (FLASH_WORD_SIZE) AMD_ID_LV400B:
info->flash_id += FLASH_AM400B;
info->sector_count = 11;
info->size = 0x00080000;
break; /* => 0.5 MB */
case (FLASH_WORD_SIZE) AMD_ID_LV800T:
info->flash_id += FLASH_AM800T;
info->sector_count = 19;
info->size = 0x00100000;
break; /* => 1 MB */
case (FLASH_WORD_SIZE) AMD_ID_LV800B:
info->flash_id += FLASH_AM800B;
info->sector_count = 19;
info->size = 0x00100000;
break; /* => 1 MB */
case (FLASH_WORD_SIZE) AMD_ID_LV160T:
info->flash_id += FLASH_AM160T;
info->sector_count = 35;
info->size = 0x00200000;
break; /* => 2 MB */
case (FLASH_WORD_SIZE) AMD_ID_LV160B:
info->flash_id += FLASH_AM160B;
info->sector_count = 35;
info->size = 0x00200000;
break; /* => 2 MB */
#if 0 /* enable when device IDs are available */
case (FLASH_WORD_SIZE) AMD_ID_LV320T:
info->flash_id += FLASH_AM320T;
info->sector_count = 67;
info->size = 0x00400000;
break; /* => 4 MB */
case (FLASH_WORD_SIZE) AMD_ID_LV320B:
info->flash_id += FLASH_AM320B;
info->sector_count = 67;
info->size = 0x00400000;
break; /* => 4 MB */
#endif
case (FLASH_WORD_SIZE) SST_ID_xF800A:
info->flash_id += FLASH_SST800A;
info->sector_count = 16;
info->size = 0x00100000;
break; /* => 1 MB */
case (FLASH_WORD_SIZE) SST_ID_xF160A:
info->flash_id += FLASH_SST160A;
info->sector_count = 32;
info->size = 0x00200000;
break; /* => 2 MB */
default:
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
}
/* set up sector start address table */
if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
(info->flash_id == FLASH_AM040)) {
for (i = 0; i < info->sector_count; i++)
info->start[i] = base + (i * 0x00010000);
} else {
if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00004000;
info->start[2] = base + 0x00006000;
info->start[3] = base + 0x00008000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] =
base + (i * 0x00010000) - 0x00030000;
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00004000;
info->start[i--] = base + info->size - 0x00006000;
info->start[i--] = base + info->size - 0x00008000;
for (; i >= 0; i--) {
info->start[i] = base + i * 0x00010000;
}
}
}
/* check for protected sectors */
for (i = 0; i < info->sector_count; i++) {
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
/* D0 = 1 if protected */
#ifdef CONFIG_ADCIOP
addr2 = (volatile FLASH_WORD_SIZE *) (info->start[i]);
info->protect[i] = addr2[4] & 1;
#else
addr2 = (volatile FLASH_WORD_SIZE *) (info->start[i]);
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
info->protect[i] = 0;
else
info->protect[i] = addr2[2] & 1;
#endif
}
/*
* Prevent writes to uninitialized FLASH.
*/
if (info->flash_id != FLASH_UNKNOWN) {
#if 0 /* test-only */
#ifdef CONFIG_ADCIOP
addr2 = (volatile unsigned char *) info->start[0];
addr2[ADDR0] = 0xAA;
addr2[ADDR1] = 0x55;
addr2[ADDR0] = 0xF0; /* reset bank */
#else
addr2 = (FLASH_WORD_SIZE *) info->start[0];
*addr2 = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
#endif
#else /* test-only */
addr2 = (FLASH_WORD_SIZE *) info->start[0];
*addr2 = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
#endif /* test-only */
}
return (info->size);
}
int wait_for_DQ7 (flash_info_t * info, int sect)
{
ulong start, now, last;
volatile FLASH_WORD_SIZE *addr =
(FLASH_WORD_SIZE *) (info->start[sect]);
start = get_timer (0);
last = start;
while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) !=
(FLASH_WORD_SIZE) 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 */
putc ('.');
last = now;
}
}
return 0;
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]);
volatile FLASH_WORD_SIZE *addr2;
int flag, prot, sect, l_sect;
int i;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
if (info->flash_id == FLASH_UNKNOWN) {
printf ("Can't erase unknown flash type - aborted\n");
return 1;
}
prot = 0;
for (sect = s_first; sect <= s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n", prot);
} else {
printf ("\n");
}
l_sect = -1;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts ();
/* Start erase on unprotected sectors */
for (sect = s_first; sect <= s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
addr2 = (FLASH_WORD_SIZE *) (info->start[sect]);
printf ("Erasing sector %p\n", addr2); /* CLH */
if ((info->flash_id & FLASH_VENDMASK) ==
FLASH_MAN_SST) {
addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
addr2[0] = (FLASH_WORD_SIZE) 0x00500050; /* block erase */
for (i = 0; i < 50; i++)
udelay (1000); /* wait 1 ms */
} else {
addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
addr2[0] = (FLASH_WORD_SIZE) 0x00300030; /* sector erase */
}
l_sect = sect;
/*
* Wait for each sector to complete, it's more
* reliable. According to AMD Spec, you must
* issue all erase commands within a specified
* timeout. This has been seen to fail, especially
* if printf()s are included (for debug)!!
*/
wait_for_DQ7 (info, sect);
}
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts ();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
#if 0
/*
* We wait for the last triggered sector
*/
if (l_sect < 0)
goto DONE;
wait_for_DQ7 (info, l_sect);
DONE:
#endif
/* reset to read mode */
addr = (FLASH_WORD_SIZE *) info->start[0];
addr[0] = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
printf (" done\n");
return 0;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
ulong cp, wp, data;
int i, l, rc;
wp = (addr & ~3); /* get lower word aligned address */
/*
* handle unaligned start bytes
*/
if ((l = addr - wp) != 0) {
data = 0;
for (i = 0, cp = wp; i < l; ++i, ++cp) {
data = (data << 8) | (*(uchar *) cp);
}
for (; i < 4 && cnt > 0; ++i) {
data = (data << 8) | *src++;
--cnt;
++cp;
}
for (; cnt == 0 && i < 4; ++i, ++cp) {
data = (data << 8) | (*(uchar *) cp);
}
if ((rc = write_word (info, wp, data)) != 0) {
return (rc);
}
wp += 4;
}
/*
* handle word aligned part
*/
while (cnt >= 4) {
data = 0;
for (i = 0; i < 4; ++i) {
data = (data << 8) | *src++;
}
if ((rc = write_word (info, wp, data)) != 0) {
return (rc);
}
wp += 4;
cnt -= 4;
}
if (cnt == 0) {
return (0);
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
for (; i < 4; ++i, ++cp) {
data = (data << 8) | (*(uchar *) cp);
}
return (write_word (info, wp, data));
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word (flash_info_t * info, ulong dest, ulong data)
{
volatile FLASH_WORD_SIZE *addr2 =
(FLASH_WORD_SIZE *) (info->start[0]);
volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest;
volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
ulong start;
int i;
/* Check if Flash is (sufficiently) erased */
if ((*((volatile FLASH_WORD_SIZE *) dest) &
(FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
return (2);
}
for (i = 0; i < 4 / sizeof (FLASH_WORD_SIZE); i++) {
int flag;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts ();
addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0;
dest2[i] = data2[i];
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts ();
/* data polling for D7 */
start = get_timer (0);
while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) !=
(data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
return (1);
}
}
}
return (0);
}

89
board/jse/host_bridge.c Normal file
View File

@@ -0,0 +1,89 @@
/*
* Copyright (c) 2004 Picture Elements, Inc.
* Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form 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
*/
#ident "$Id:$"
# include <common.h>
# include <pci.h>
# include "jse_priv.h"
/*
* The JSE board has an Intel 21555 non-transparent bridge for
* communication with the host. We need to render it harmless on the
* JSE side, but leave it alone on the host (primary) side. Normally,
* this will all be done before the host BIOS can gain access to the
* board, due to the Primary Access Lockout bit.
*
* The host_bridge_init function is called as a late initialization
* function, after most of the board is set up, including a PCI scan.
*/
void host_bridge_init (void)
{
/* The bridge chip is at a fixed location. */
pci_dev_t dev = PCI_BDF (0, 10, 0);
int rc;
u32 val32;
rc = pci_read_config_dword (dev, 0, &val32);
/* Set subsystem ID --
The primary side sees this value at 0x2c. We set it here so
that the host can tell what sort of device this is:
We are a Picture Elements [0x12c5] JSE [0x008a]. */
pci_write_config_dword (dev, 0x6c, 0x008a12c5);
/* Downstream (Primary-to-Secondary) BARs are set up mostly
off. We need only the Memory-0 Bar so that the host can get
at the CSR region to set up tables and the lot. */
/* Downstream Memory 0 setup (4K for CSR) */
pci_write_config_dword (dev, 0xac, 0xfffff000);
/* Downstream Memory 1 setup (off) */
pci_write_config_dword (dev, 0xb0, 0x00000000);
/* Downstream Memory 2 setup (off) */
pci_write_config_dword (dev, 0xb4, 0x00000000);
/* Downstream Memory 3 setup (off) */
pci_write_config_dword (dev, 0xb8, 0x00000000);
/* Upstream (Secondary-to-Primary) BARs are used to get at
host memory from the JSE card. Create two regions: a small
one to manage individual word reads/writes, and a larger
one for doing bulk frame moves. */
/* Upstream Memory 0 Setup -- (BAR2) 4K non-prefetchable */
pci_write_config_dword (dev, 0xc4, 0xfffff000);
/* Upstream Memory 1 setup -- (BAR3) 4K non-prefetchable */
pci_write_config_dword (dev, 0xc8, 0xfffff000);
/* Upstream Memory 2 (BAR4) uses page translation, and is set
up in CCR1. Configure for 4K pages. */
/* Set CCR1,0 reigsters. This clears the Primary PCI Lockout
bit as well, so we are done configuring after this
point. Therefore, this must be the last step.
CC1[15:12]= 0 (disable I2O message unit)
CC1[11:8] = 0x5 (4K page size)
CC0[11] = 1 (Secondary Clock Disable: disable clock)
CC0[10] = 0 (Primary Access Lockout: allow primary access)
*/
pci_write_config_dword (dev, 0xcc, 0x05000800);
}

105
board/jse/init.S Normal file
View File

@@ -0,0 +1,105 @@
/*------------------------------------------------------------------------+ */
/* */
/* This source code has been made available to you by IBM on an AS-IS */
/* basis. Anyone receiving this source is licensed under IBM */
/* copyrights to use it in any way he or she deems fit, including */
/* copying it, modifying it, compiling it, and redistributing it either */
/* with or without modifications. No license under IBM patents or */
/* patent applications is to be implied by the copyright license. */
/* */
/* Any user of this software should understand that IBM cannot provide */
/* technical support for this software and will not be responsible for */
/* any consequences resulting from the use of this software. */
/* */
/* Any person who transfers this source code or any derivative work */
/* must include the IBM copyright notice, this paragraph, and the */
/* preceding two paragraphs in the transferred software. */
/* */
/* COPYRIGHT I B M CORPORATION 1995 */
/* LICENSED MATERIAL - PROGRAM PROPERTY OF I B M */
/*------------------------------------------------------------------------- */
/*------------------------------------------------------------------------- */
/* Function: ext_bus_cntlr_init */
/* Description: Initializes the External Bus Controller for the external */
/* peripherals. IMPORTANT: For pass1 this code must run from */
/* cache since you can not reliably change a peripheral banks */
/* timing register (pbxap) while running code from that bank. */
/* For ex., since we are running from ROM on bank 0, we can NOT */
/* execute the code that modifies bank 0 timings from ROM, so */
/* we run it from cache. */
/* */
/* */
/* The layout for the PEI JSE board: */
/* Bank 0 - Flash and SRAM */
/* Bank 1 - SystemACE */
/* Bank 2 - not used */
/* Bank 3 - not used */
/* Bank 4 - not used */
/* Bank 5 - not used */
/* Bank 6 - not used */
/* Bank 7 - not used */
/*------------------------------------------------------------------------- */
#include <ppc4xx.h>
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
#define cpc0_cr0 0xB1
.globl ext_bus_cntlr_init
ext_bus_cntlr_init:
mflr r4 /* save link register */
bl ..getAddr
..getAddr:
mflr r3 /* get address of ..getAddr */
mtlr r4 /* restore link register */
addi r4,0,14 /* set ctr to 10; used to prefetch */
mtctr r4 /* 10 cache lines to fit this function */
/* in cache (gives us 8x10=80 instrctns) */
..ebcloop:
icbt r0,r3 /* prefetch cache line for addr in r3 */
addi r3,r3,32 /* move to next cache line */
bdnz ..ebcloop /* continue for 10 cache lines */
/*----------------------------------------------------------------- */
/* Delay to ensure all accesses to ROM are complete before changing */
/* bank 0 timings. 200usec should be enough. */
/* 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */
/*----------------------------------------------------------------- */
addis r3,0,0x0
ori r3,r3,0xA000 /* ensure 200usec have passed since reset */
mtctr r3
..spinlp:
bdnz ..spinlp /* spin loop */
/*----------------------------------------------------------------- */
/* Memory Bank 0 (Flash) initialization */
/*----------------------------------------------------------------- */
addi r4,0,pb0ap
mtdcr ebccfga,r4
addis r4,0,0x9B01
ori r4,r4,0x5480
mtdcr ebccfgd,r4
addi r4,0,pb0cr
mtdcr ebccfga,r4
addis r4,0,0xFFF1 /* BAS=0xFFF,BS=0x0(1MB),BU=0x3(R/W), */
ori r4,r4,0x8000 /* BW=0x0( 8 bits) */
mtdcr ebccfgd,r4
blr
/*----------------------------------------------------------------------- */
/* Function: sdram_init */
/* Description: This function is called by cpu/ppc4xx/start.S code */
/* to get the SDRAM initialized. */
/*----------------------------------------------------------------------- */
.globl sdram_init
sdram_init:
blr

160
board/jse/jse.c Normal file
View File

@@ -0,0 +1,160 @@
/*
* Copyright (c) 2004 Picture Elements, Inc.
* Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form 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 <ppc4xx.h>
# include <asm/processor.h>
# include <asm/io.h>
# include "jse_priv.h"
/*
* This function is run very early, out of flash, and before devices are
* initialized. It is called by lib_ppc/board.c:board_init_f by virtue
* of being in the init_sequence array.
*
* The SDRAM has been initialized already -- start.S:start called
* init.S:init_sdram early on -- but it is not yet being used for
* anything, not even stack. So be careful.
*/
int board_early_init_f (void)
{
/*-------------------------------------------------------------------------+
| Interrupt controller setup for the JSE board.
| Note: IRQ 0-15 405GP internally generated; active high; level sensitive
| IRQ 16 405GP internally generated; active low; level sensitive
| IRQ 17-24 RESERVED/UNUSED
| IRQ 25 (EXT IRQ 0) PCI SLOT 0; active low; level sensitive
| IRQ 26 (EXT IRQ 1) PCI SLOT 1; active low; level sensitive
| IRQ 27 (EXT IRQ 2) JP2C CHIP ; active low; level sensitive
| IRQ 28 (EXT IRQ 3) PCI bridge; active low; level sensitive
| IRQ 29 (EXT IRQ 4) SystemACE IRQ; active high
| IRQ 30 (EXT IRQ 5) SystemACE BRdy (unused)
| IRQ 31 (EXT IRQ 6) (unused)
+-------------------------------------------------------------------------*/
mtdcr (uicsr, 0xFFFFFFFF); /* clear all ints */
mtdcr (uicer, 0x00000000); /* disable all ints */
mtdcr (uiccr, 0x00000000); /* set all to be non-critical */
mtdcr (uicpr, 0xFFFFFF87); /* set int polarities */
mtdcr (uictr, 0x10000000); /* set int trigger levels */
mtdcr (uicsr, 0xFFFFFFFF); /* clear all ints */
/* Configure the interface to the SystemACE MCU port.
The SystemACE is fast, but there is no reason to have
excessivly tight timings. So the settings are slightly
generous. */
/* EBC0_B1AP: BME=1, TWT=2, CSN=0, OEN=1,
WBN=0, WBF=1, TH=0, RE=0, SOR=0, BEM=0, PEN=0 */
mtdcr (ebccfga, pb1ap);
mtdcr (ebccfgd, 0x01011000);
/* EBC0_B1CR: BAS=x, BS=0(1MB), BU=3(R/W), BW=0(8bits) */
mtdcr (ebccfga, pb1cr);
mtdcr (ebccfgd, CFG_SYSTEMACE_BASE | 0x00018000);
/* Enable the /PerWE output as /PerWE, instead of /PCIINT. */
/* CPC0_CR1 |= PCIPW */
mtdcr (0xb2, mfdcr (0xb2) | 0x00004000);
return 0;
}
#ifdef CONFIG_BOARD_PRE_INIT
int board_pre_init (void)
{
return board_early_init_f ();
}
#endif
/*
* This function is also called by lib_ppc/board.c:board_init_f (it is
* also in the init_sequence array) but later. Many more things are
* configured, but we are still running from flash.
*/
int checkboard (void)
{
unsigned vers, status;
/* check that the SystemACE chip is alive. */
printf ("ACE: ");
vers = readw (CFG_SYSTEMACE_BASE + 0x16);
printf ("SystemACE %u.%u (build %u)",
(vers >> 12) & 0x0f, (vers >> 8) & 0x0f, vers & 0xff);
status = readl (CFG_SYSTEMACE_BASE + 0x04);
#ifdef DEBUG
printf (" STATUS=0x%08x", status);
#endif
/* If the flash card is present and there is an initial error,
then force a restart of the program. */
if (status & 0x00000010) {
printf (" CFDETECT");
if (status & 0x04) {
/* CONTROLREG = CFGPROG */
writew (0x1000, CFG_SYSTEMACE_BASE + 0x18);
udelay (500);
/* CONTROLREG = CFGRESET */
writew (0x0080, CFG_SYSTEMACE_BASE + 0x18);
udelay (500);
writew (0x0000, CFG_SYSTEMACE_BASE + 0x18);
/* CONTROLREG = CFGSTART */
writew (0x0020, CFG_SYSTEMACE_BASE + 0x18);
status = readl (CFG_SYSTEMACE_BASE + 0x04);
}
}
/* Wait for the SystemACE to program its chain of devices. */
while ((status & 0x84) == 0x00) {
udelay (500);
status = readl (CFG_SYSTEMACE_BASE + 0x04);
}
if (status & 0x04)
printf (" CFG-ERROR");
if (status & 0x80)
printf (" CFGDONE");
printf ("\n");
/* Force /RTS to active. The board it not wired quite
correctly to use cts/rtc flow control, so just force the
/RST active and forget about it. */
writeb (readb (0xef600404) | 0x03, 0xef600404);
printf ("JSE: ready\n");
return 0;
}
/* **** No more functions called by board_init_f. **** */
/*
* This function is called by lib_ppc/board.c:board_init_r. At this
* point, basic setup is done, U-Boot has been moved into SDRAM and
* PCI has been set up. From here we done late setup.
*/
int misc_init_r (void)
{
host_bridge_init ();
return 0;
}

25
board/jse/jse_priv.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef __jse_priv_H
#define __jse_prov_H
/*
* Copyright (c) 2004 Picture Elements, Inc.
* Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form 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
*/
extern void host_bridge_init(void);
#endif

182
board/jse/sdram.c Normal file
View File

@@ -0,0 +1,182 @@
/*
* Copyright (c) 2004 Picture Elements, Inc.
* Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form 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 <ppc4xx.h>
#include <asm/processor.h>
# define SDRAM_LEN 0x08000000
/*
* this is even after checkboard. It returns the size of the SDRAM
* that we have installed. This function is called by board_init_f
* in lib_ppc/board.c to initialize the memory and return what I
* found.
*/
long int initdram (int board_type)
{
/* Configure the SDRAMS */
/* disable memory controller */
mtdcr (memcfga, mem_mcopt1);
mtdcr (memcfgd, 0x00000000);
udelay (500);
/* Clear SDRAM0_BESR0 (Bus Error Syndrome Register) */
mtdcr (memcfga, mem_besra);
mtdcr (memcfgd, 0xffffffff);
/* Clear SDRAM0_BESR1 (Bus Error Syndrome Register) */
mtdcr (memcfga, mem_besrb);
mtdcr (memcfgd, 0xffffffff);
/* Clear SDRAM0_ECCCFG (disable ECC) */
mtdcr (memcfga, mem_ecccf);
mtdcr (memcfgd, 0x00000000);
/* Clear SDRAM0_ECCESR (ECC Error Syndrome Register) */
mtdcr (memcfga, mem_eccerr);
mtdcr (memcfgd, 0xffffffff);
/* Timing register: CASL=2, PTA=2, CTP=2, LDF=1, RFTA=5, RCD=2 */
mtdcr (memcfga, mem_sdtr1);
mtdcr (memcfgd, 0x010a4016);
/* Memory Bank 0 Config == BA=0x00000000, SZ=64M, AM=3, BE=1 */
mtdcr (memcfga, mem_mb0cf);
mtdcr (memcfgd, 0x00084001);
/* Memory Bank 1 Config == BA=0x04000000, SZ=64M, AM=3, BE=1 */
mtdcr (memcfga, mem_mb1cf);
mtdcr (memcfgd, 0x04084001);
/* Memory Bank 2 Config == BE=0 */
mtdcr (memcfga, mem_mb2cf);
mtdcr (memcfgd, 0x00000000);
/* Memory Bank 3 Config == BE=0 */
mtdcr (memcfga, mem_mb3cf);
mtdcr (memcfgd, 0x00000000);
/* refresh timer = 0x400 */
mtdcr (memcfga, mem_rtr);
mtdcr (memcfgd, 0x04000000);
/* Power management idle timer set to the default. */
mtdcr (memcfga, mem_pmit);
mtdcr (memcfgd, 0x07c00000);
udelay (500);
/* Enable banks (DCE=1, BPRF=1, ECCDD=1, EMDUL=1) */
mtdcr (memcfga, mem_mcopt1);
mtdcr (memcfgd, 0x80e00000);
return SDRAM_LEN;
}
/*
* The U-Boot core, as part of the initialization to prepare for
* loading the monitor into SDRAM, requests of this function that the
* memory be tested. Return 0 if the memory tests OK.
*/
int testdram (void)
{
unsigned long idx;
unsigned val;
unsigned errors;
volatile unsigned long *sdram;
#ifdef DEBUG
printf ("SDRAM Controller Registers --\n");
mtdcr (memcfga, mem_mcopt1);
val = mfdcr (memcfgd);
printf (" SDRAM0_CFG : 0x%08x\n", val);
mtdcr (memcfga, 0x24);
val = mfdcr (memcfgd);
printf (" SDRAM0_STATUS: 0x%08x\n", val);
mtdcr (memcfga, mem_mb0cf);
val = mfdcr (memcfgd);
printf (" SDRAM0_B0CR : 0x%08x\n", val);
mtdcr (memcfga, mem_mb1cf);
val = mfdcr (memcfgd);
printf (" SDRAM0_B1CR : 0x%08x\n", val);
mtdcr (memcfga, mem_sdtr1);
val = mfdcr (memcfgd);
printf (" SDRAM0_TR : 0x%08x\n", val);
mtdcr (memcfga, mem_rtr);
val = mfdcr (memcfgd);
printf (" SDRAM0_RTR : 0x%08x\n", val);
#endif
/* Wait for memory to be ready by testing MRSCMPbit
bit. Really, there should already have been plenty of time,
given it was started long ago. But, best to check. */
for (idx = 0; idx < 1000000; idx += 1) {
mtdcr (memcfga, 0x24);
val = mfdcr (memcfgd);
if (val & 0x80000000)
break;
}
if (!(val & 0x80000000)) {
printf ("SDRAM ERROR: SDRAM0_STATUS never set!\n");
return 1;
}
/* Start memory test. */
printf ("test: %u MB - ", SDRAM_LEN / 1048576);
sdram = (unsigned long *) CFG_SDRAM_BASE;
printf ("write - ");
for (idx = 2; idx < SDRAM_LEN / 4; idx += 2) {
sdram[idx + 0] = idx;
sdram[idx + 1] = ~idx;
}
printf ("read - ");
errors = 0;
for (idx = 2; idx < SDRAM_LEN / 4; idx += 2) {
if (sdram[idx + 0] != idx)
errors += 1;
if (sdram[idx + 1] != ~idx)
errors += 1;
if (errors > 0)
break;
}
if (errors > 0) {
printf ("NOT OK\n");
printf ("FIRST ERROR at %p: 0x%08lx:0x%08lx != 0x%08lx:0x%08lx\n",
sdram + idx, sdram[idx + 0], sdram[idx + 1], idx, ~idx);
return 1;
}
printf ("ok\n");
return 0;
}

140
board/jse/u-boot.lds Normal file
View File

@@ -0,0 +1,140 @@
/*
* (C) Copyright 2000-2004
* 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 : {
/* The start.o file includes the initial jump vector that
must be located in the beginning. It is the basic run-
time function that calls all other functions. */
cpu/ppc4xx/start.o (.text)
board/jse/init.o (.text)
cpu/ppc4xx/kgdb.o (.text)
/* . = env_offset;*/
/* common/environment.o(.text)*/
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
*(.rodata.str1.4)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x00FF) & 0xFFFFFF00;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(256);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(256);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

View File

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

View File

@@ -1,81 +0,0 @@
/*
* (C) Copyright 2004
* Klaus Heydeck, Kieback & Peter GmbH & Co KG, heydeck@kieback-peter.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>
#include "../common/kup.h"
#define SL811_ADR (0x50000000)
#define SL811_DAT (0x50000001)
static void sl811_write_index_data (__u8 index, __u8 data)
{
*(volatile unsigned char *) (SL811_ADR) = index;
__asm__ ("eieio");
*(volatile unsigned char *) (SL811_DAT) = data;
__asm__ ("eieio");
}
static __u8 sl811_read_index_data (__u8 index)
{
__u8 data;
*(volatile unsigned char *) (SL811_ADR) = index;
__asm__ ("eieio");
data = *(volatile unsigned char *) (SL811_DAT);
__asm__ ("eieio");
return (data);
}
int usb_init_kup4x (void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
int i;
unsigned char tmp;
memctl = &immap->im_memctl;
memctl->memc_or7 = 0xFFFF8726;
memctl->memc_br7 = 0x50000401; /* start at 0x50000000 */
/* BP 14 low = USB ON */
immap->im_cpm.cp_pbdat &= ~(BP_USB_VCC);
/* PB 14 nomal port */
immap->im_cpm.cp_pbpar &= ~(BP_USB_VCC);
/* output */
immap->im_cpm.cp_pbdir |= (BP_USB_VCC);
puts ("USB: ");
for (i = 0x10; i < 0xff; i++) {
sl811_write_index_data (i, i);
tmp = (sl811_read_index_data (i));
if (tmp != i) {
printf ("SL811 compare error index=0x%02x read=0x%02x\n", i, tmp);
return (-1);
}
}
printf ("SL811 ready\n");
return (0);
}

View File

@@ -9,7 +9,7 @@
* (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com
* Added support for the 16M dram simm on the 8260ads boards
*
* (C) Copyright 2003 Arabella Software Ltd.
* (C) Copyright 2003-2004 Arabella Software Ltd.
* Yuli Barcohen <yuli@arabellasw.com>
* Added support for SDRAM DIMMs SPD EEPROM, MII, Ethernet PHY init.
*
@@ -47,121 +47,137 @@
* according to the five values podr/pdir/ppar/psor/pdat for that entry
*/
#define CFG_FCC1 (CONFIG_ETHER_INDEX == 1)
#define CFG_FCC2 (CONFIG_ETHER_INDEX == 2)
#define CFG_FCC3 (CONFIG_ETHER_INDEX == 3)
const iop_conf_t iop_conf_tab[4][32] = {
/* Port A configuration */
{ /* conf ppar psor pdir podr pdat */
/* PA31 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 TxENB */
/* PA30 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 TxClav */
/* PA29 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 TxSOC */
/* PA28 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 RxENB */
/* PA27 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 RxSOC */
/* PA26 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 RxClav */
/* PA25 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[0] */
/* PA24 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[1] */
/* PA23 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[2] */
/* PA22 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[3] */
/* PA21 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[4] */
/* PA20 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[5] */
/* PA19 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[6] */
/* PA18 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[7] */
/* PA17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[7] */
/* PA16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[6] */
/* PA15 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[5] */
/* PA14 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[4] */
/* PA13 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[3] */
/* PA12 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[2] */
/* PA11 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[1] */
/* PA10 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[0] */
/* PA9 */ { 0, 1, 1, 1, 0, 0 }, /* FCC1 L1TXD */
/* PA8 */ { 0, 1, 1, 0, 0, 0 }, /* FCC1 L1RXD */
/* PA7 */ { 0, 0, 0, 1, 0, 0 }, /* PA7 */
/* PA6 */ { 1, 1, 1, 1, 0, 0 }, /* TDM A1 L1RSYNC */
/* PA5 */ { 0, 0, 0, 1, 0, 0 }, /* PA5 */
/* PA4 */ { 0, 0, 0, 1, 0, 0 }, /* PA4 */
/* PA3 */ { 0, 0, 0, 1, 0, 0 }, /* PA3 */
/* PA2 */ { 0, 0, 0, 1, 0, 0 }, /* PA2 */
/* PA1 */ { 1, 0, 0, 0, 0, 0 }, /* FREERUN */
/* PA0 */ { 0, 0, 0, 1, 0, 0 } /* PA0 */
{ /* conf ppar psor pdir podr pdat */
/* PA31 */ { CFG_FCC1, 1, 1, 0, 0, 0 }, /* FCC1 MII COL */
/* PA30 */ { CFG_FCC1, 1, 1, 0, 0, 0 }, /* FCC1 MII CRS */
/* PA29 */ { CFG_FCC1, 1, 1, 1, 0, 0 }, /* FCC1 MII TX_ER */
/* PA28 */ { CFG_FCC1, 1, 1, 1, 0, 0 }, /* FCC1 MII TX_EN */
/* PA27 */ { CFG_FCC1, 1, 1, 0, 0, 0 }, /* FCC1 MII RX_DV */
/* PA26 */ { CFG_FCC1, 1, 1, 0, 0, 0 }, /* FCC1 MII RX_ER */
/* PA25 */ { 0, 0, 0, 0, 0, 0 }, /* PA25 */
/* PA24 */ { 0, 0, 0, 0, 0, 0 }, /* PA24 */
/* PA23 */ { 0, 0, 0, 0, 0, 0 }, /* PA23 */
/* PA22 */ { 0, 0, 0, 0, 0, 0 }, /* PA22 */
/* PA21 */ { CFG_FCC1, 1, 0, 1, 0, 0 }, /* FCC1 MII TxD[3] */
/* PA20 */ { CFG_FCC1, 1, 0, 1, 0, 0 }, /* FCC1 MII TxD[2] */
/* PA19 */ { CFG_FCC1, 1, 0, 1, 0, 0 }, /* FCC1 MII TxD[1] */
/* PA18 */ { CFG_FCC1, 1, 0, 1, 0, 0 }, /* FCC1 MII TxD[0] */
/* PA17 */ { CFG_FCC1, 1, 0, 0, 0, 0 }, /* FCC1 MII RxD[0] */
/* PA16 */ { CFG_FCC1, 1, 0, 0, 0, 0 }, /* FCC1 MII RxD[1] */
/* PA15 */ { CFG_FCC1, 1, 0, 0, 0, 0 }, /* FCC1 MII RxD[2] */
/* PA14 */ { CFG_FCC1, 1, 0, 0, 0, 0 }, /* FCC1 MII RxD[3] */
/* PA13 */ { 0, 0, 0, 0, 0, 0 }, /* PA13 */
/* PA12 */ { 0, 0, 0, 0, 0, 0 }, /* PA12 */
/* PA11 */ { 0, 0, 0, 0, 0, 0 }, /* PA11 */
/* PA10 */ { 0, 0, 0, 0, 0, 0 }, /* PA10 */
/* PA9 */ { 0, 0, 0, 0, 0, 0 }, /* PA9 */
/* PA8 */ { 0, 0, 0, 0, 0, 0 }, /* PA8 */
/* PA7 */ { 0, 0, 0, 1, 0, 0 }, /* PA7 */
/* PA6 */ { 0, 0, 0, 0, 0, 0 }, /* PA6 */
/* PA5 */ { 0, 0, 0, 1, 0, 0 }, /* PA5 */
/* PA4 */ { 0, 0, 0, 1, 0, 0 }, /* PA4 */
/* PA3 */ { 0, 0, 0, 1, 0, 0 }, /* PA3 */
/* PA2 */ { 0, 0, 0, 1, 0, 0 }, /* PA2 */
/* PA1 */ { 0, 0, 0, 0, 0, 0 }, /* PA1 */
/* PA0 */ { 0, 0, 0, 1, 0, 0 } /* PA0 */
},
/* Port B configuration */
{ /* conf ppar psor pdir podr pdat */
/* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */
/* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */
/* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */
/* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */
/* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */
/* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */
/* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */
/* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */
/* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */
/* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */
/* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */
/* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */
/* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */
/* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */
/* PB17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RX_DIV */
/* PB16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RX_ERR */
/* PB15 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TX_ERR */
/* PB14 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TX_EN */
/* PB13 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:COL */
/* PB12 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:CRS */
/* PB11 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
/* PB10 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
/* PB9 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
/* PB8 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
/* PB7 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
/* PB6 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
/* PB5 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
/* PB4 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
/* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
{ /* conf ppar psor pdir podr pdat */
/* PB31 */ { CFG_FCC2, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */
/* PB30 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */
/* PB29 */ { CFG_FCC2, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */
/* PB28 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */
/* PB27 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */
/* PB26 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */
/* PB25 */ { CFG_FCC2, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */
/* PB24 */ { CFG_FCC2, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */
/* PB23 */ { CFG_FCC2, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */
/* PB22 */ { CFG_FCC2, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */
/* PB21 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */
/* PB20 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */
/* PB19 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */
/* PB18 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */
/* PB17 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:RX_DIV */
/* PB16 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:RX_ERR */
/* PB15 */ { CFG_FCC3, 1, 0, 1, 0, 0 }, /* FCC3:TX_ERR */
/* PB14 */ { CFG_FCC3, 1, 0, 1, 0, 0 }, /* FCC3:TX_EN */
/* PB13 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:COL */
/* PB12 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:CRS */
/* PB11 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
/* PB10 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
/* PB9 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
/* PB8 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
/* PB7 */ { CFG_FCC3, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
/* PB6 */ { CFG_FCC3, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
/* PB5 */ { CFG_FCC3, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
/* PB4 */ { CFG_FCC3, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
/* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
},
/* Port C */
{ /* conf ppar psor pdir podr pdat */
/* PC31 */ { 0, 0, 0, 1, 0, 0 }, /* PC31 */
/* PC30 */ { 0, 0, 0, 1, 0, 0 }, /* PC30 */
/* PC29 */ { 0, 1, 1, 0, 0, 0 }, /* SCC1 EN *CLSN */
/* PC28 */ { 0, 0, 0, 1, 0, 0 }, /* PC28 */
/* PC27 */ { 0, 0, 0, 1, 0, 0 }, /* UART Clock in */
/* PC26 */ { 0, 0, 0, 1, 0, 0 }, /* PC26 */
/* PC25 */ { 0, 0, 0, 1, 0, 0 }, /* PC25 */
/* PC24 */ { 0, 0, 0, 1, 0, 0 }, /* PC24 */
/* PC23 */ { 0, 1, 0, 1, 0, 0 }, /* ATMTFCLK */
/* PC22 */ { 0, 1, 0, 0, 0, 0 }, /* ATMRFCLK */
/* PC21 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN RXCLK */
/* PC20 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN TXCLK */
/* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII Rx Clock (CLK13) */
/* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII Tx Clock (CLK14) */
/* PC17 */ { 0, 0, 0, 1, 0, 0 }, /* PC17 */
/* PC16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC Tx Clock (CLK16) */
/* PC15 */ { 0, 0, 0, 1, 0, 0 }, /* PC15 */
/* PC14 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN *CD */
/* PC13 */ { 0, 0, 0, 1, 0, 0 }, /* PC13 */
/* PC12 */ { 0, 1, 0, 1, 0, 0 }, /* PC12 */
/* PC11 */ { 0, 0, 0, 1, 0, 0 }, /* LXT971 transmit control */
/* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* LXT970 FETHMDC */
/* PC9 */ { 1, 0, 0, 0, 0, 0 }, /* LXT970 FETHMDIO */
/* PC8 */ { 0, 0, 0, 1, 0, 0 }, /* PC8 */
/* PC7 */ { 0, 0, 0, 1, 0, 0 }, /* PC7 */
/* PC6 */ { 0, 0, 0, 1, 0, 0 }, /* PC6 */
/* PC5 */ { 0, 0, 0, 1, 0, 0 }, /* PC5 */
/* PC4 */ { 0, 0, 0, 1, 0, 0 }, /* PC4 */
/* PC3 */ { 0, 0, 0, 1, 0, 0 }, /* PC3 */
/* PC2 */ { 0, 0, 0, 1, 0, 1 }, /* ENET FDE */
/* PC1 */ { 0, 0, 0, 1, 0, 0 }, /* ENET DSQE */
/* PC0 */ { 0, 0, 0, 1, 0, 0 }, /* ENET LBK */
{ /* conf ppar psor pdir podr pdat */
/* PC31 */ { 0, 0, 0, 0, 0, 0 }, /* PC31 */
/* PC30 */ { 0, 0, 0, 0, 0, 0 }, /* PC30 */
/* PC29 */ { 0, 0, 0, 0, 0, 0 }, /* PC29 */
/* PC28 */ { 0, 0, 0, 0, 0, 0 }, /* PC28 */
/* PC27 */ { 0, 0, 0, 0, 0, 0 }, /* PC27 */
/* PC26 */ { 0, 0, 0, 0, 0, 0 }, /* PC26 */
/* PC25 */ { 0, 0, 0, 0, 0, 0 }, /* PC25 */
/* PC24 */ { 0, 0, 0, 0, 0, 0 }, /* PC24 */
/* PC23 */ { 0, 0, 0, 0, 0, 0 }, /* PC23 */
/* PC22 */ { CFG_FCC1, 1, 0, 0, 0, 0 }, /* FCC1 MII Tx Clock (CLK10) */
/* PC21 */ { CFG_FCC1, 1, 0, 0, 0, 0 }, /* FCC1 MII Rx Clock (CLK11) */
/* PC20 */ { 0, 0, 0, 0, 0, 0 }, /* PC20 */
#if CONFIG_ADSTYPE == CFG_8272ADS
/* PC19 */ { 1, 0, 0, 1, 0, 0 }, /* FETHMDC */
/* PC18 */ { 1, 0, 0, 0, 0, 0 }, /* FETHMDIO */
/* PC17 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII Rx Clock (CLK15) */
/* PC16 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII Tx Clock (CLK16) */
#else
/* PC19 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII Rx Clock (CLK13) */
/* PC18 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII Tx Clock (CLK14) */
/* PC17 */ { 0, 0, 0, 0, 0, 0 }, /* PC17 */
/* PC16 */ { 0, 0, 0, 0, 0, 0 }, /* PC16 */
#endif /* CONFIG_ADSTYPE == CFG_8272ADS */
/* PC15 */ { 0, 0, 0, 0, 0, 0 }, /* PC15 */
/* PC14 */ { 0, 0, 0, 0, 0, 0 }, /* PC14 */
/* PC13 */ { 0, 0, 0, 0, 0, 0 }, /* PC13 */
/* PC12 */ { 0, 0, 0, 0, 0, 0 }, /* PC12 */
/* PC11 */ { 0, 0, 0, 0, 0, 0 }, /* PC11 */
#if CONFIG_ADSTYPE == CFG_8272ADS
/* PC10 */ { 0, 0, 0, 0, 0, 0 }, /* PC10 */
/* PC9 */ { 0, 0, 0, 0, 0, 0 }, /* PC9 */
#else
/* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* FETHMDC */
/* PC9 */ { 1, 0, 0, 0, 0, 0 }, /* FETHMDIO */
#endif /* CONFIG_ADSTYPE == CFG_8272ADS */
/* PC8 */ { 0, 0, 0, 0, 0, 0 }, /* PC8 */
/* PC7 */ { 0, 0, 0, 0, 0, 0 }, /* PC7 */
/* PC6 */ { 0, 0, 0, 0, 0, 0 }, /* PC6 */
/* PC5 */ { 0, 0, 0, 0, 0, 0 }, /* PC5 */
/* PC4 */ { 0, 0, 0, 0, 0, 0 }, /* PC4 */
/* PC3 */ { 0, 0, 0, 0, 0, 0 }, /* PC3 */
/* PC2 */ { 0, 0, 0, 0, 0, 0 }, /* PC2 */
/* PC1 */ { 0, 0, 0, 0, 0, 0 }, /* PC1 */
/* PC0 */ { 0, 0, 0, 0, 0, 0 }, /* PC0 */
},
/* Port D */
{ /* conf ppar psor pdir podr pdat */
/* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 UART RxD */
/* PD30 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 UART TxD */
/* PD29 */ { 0, 1, 0, 1, 0, 0 }, /* SCC1 EN TENA */
/* PD29 */ { 0, 0, 0, 0, 0, 0 }, /* PD29 */
/* PD28 */ { 0, 1, 0, 0, 0, 0 }, /* PD28 */
/* PD27 */ { 0, 1, 1, 1, 0, 0 }, /* PD27 */
/* PD26 */ { 0, 0, 0, 1, 0, 0 }, /* PD26 */
@@ -198,19 +214,25 @@ void reset_phy (void)
{
vu_long *bcsr = (vu_long *)CFG_BCSR;
/* reset the FEC port */
bcsr[1] &= ~FETH1_RST;
/* Reset the PHY */
#if CFG_PHY_ADDR == 0
bcsr[1] &= ~(FETHIEN1 | FETH1_RST);
udelay(2);
bcsr[1] |= FETH1_RST;
#else
bcsr[3] &= ~(FETHIEN2 | FETH2_RST);
udelay(2);
bcsr[3] |= FETH2_RST;
#endif /* CFG_PHY_ADDR == 0 */
udelay(1000);
#ifdef CONFIG_MII
#if CONFIG_ADSTYPE == CFG_PQ2FADS
#if CONFIG_ADSTYPE >= CFG_PQ2FADS
/*
* Do not bypass Rx/Tx (de)scrambler (fix configuration error)
* Enable autonegotiation.
*/
miiphy_write(0, 16, 0x610);
miiphy_write(0, PHY_BMCR, PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
miiphy_write(CFG_PHY_ADDR, 16, 0x610);
miiphy_write(CFG_PHY_ADDR, PHY_BMCR, PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
#else
/*
* Ethernet PHY is configured (by means of configuration pins)
@@ -218,9 +240,9 @@ void reset_phy (void)
* to advertise all capabilities, including 100Mb/s, and
* restart autonegotiation.
*/
miiphy_write(0, PHY_ANAR, 0x01E1); /* Advertise all capabilities */
miiphy_write(0, PHY_DCR, 0x0000); /* Do not bypass Rx/Tx (de)scrambler */
miiphy_write(0, PHY_BMCR, PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
miiphy_write(CFG_PHY_ADDR, PHY_ANAR, 0x01E1); /* Advertise all capabilities */
miiphy_write(CFG_PHY_ADDR, PHY_DCR, 0x0000); /* Do not bypass Rx/Tx (de)scrambler */
miiphy_write(CFG_PHY_ADDR, PHY_BMCR, PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
#endif /* CONFIG_ADSTYPE == CFG_PQ2FADS */
#endif /* CONFIG_MII */
}
@@ -229,7 +251,12 @@ int board_early_init_f (void)
{
vu_long *bcsr = (vu_long *)CFG_BCSR;
bcsr[1] = ~FETHIEN1 & ~RS232EN_1;
#if (CONFIG_CONS_INDEX == 1) || (CONFIG_KGDB_INDEX == 1)
bcsr[1] &= ~RS232EN_1;
#endif
#if (CONFIG_CONS_INDEX > 1) || (CONFIG_KGDB_INDEX > 1)
bcsr[1] &= ~RS232EN_2;
#endif
#if CONFIG_ADSTYPE != CFG_8260ADS /* PCI mode can be selected */
#if CONFIG_ADSTYPE == CFG_PQ2FADS
@@ -252,8 +279,10 @@ int board_early_init_f (void)
long int initdram (int board_type)
{
#if CONFIG_ADSTYPE == CFG_PQ2FADS
#if CONFIG_ADSTYPE == CFG_PQ2FADS
long int msize = 32;
#elif CONFIG_ADSTYPE == CFG_8272ADS
long int msize = 64;
#else
long int msize = 16;
#endif
@@ -470,6 +499,8 @@ int checkboard (void)
puts ("Board: Motorola MPC8266ADS\n");
#elif CONFIG_ADSTYPE == CFG_PQ2FADS
puts ("Board: Motorola PQ2FADS-ZU\n");
#elif CONFIG_ADSTYPE == CFG_8272ADS
puts ("Board: Motorola MPC8272ADS\n");
#else
puts ("Board: unknown\n");
#endif

40
board/netphone/Makefile Normal file
View File

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

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

@@ -0,0 +1,28 @@
#
# (C) Copyright 2000-2004
# 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
#
#
# netVia Boards
#
TEXT_BASE = 0x40000000

528
board/netphone/flash.c Normal file
View File

@@ -0,0 +1,528 @@
/*
* (C) Copyright 2000-2004
* 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>
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*-----------------------------------------------------------------------
* Functions
*/
static ulong flash_get_size(vu_long * addr, flash_info_t * info);
static int write_byte(flash_info_t * info, ulong dest, uchar data);
static void flash_get_offsets(ulong base, flash_info_t * info);
/*-----------------------------------------------------------------------
*/
unsigned long flash_init(void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
unsigned long size;
#if CONFIG_NETPHONE_VERSION == 2
unsigned long size1;
#endif
int i;
/* Init: no FLASHes known */
for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i)
flash_info[i].flash_id = FLASH_UNKNOWN;
size = flash_get_size((vu_long *) FLASH_BASE0_PRELIM, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
size, size << 20);
}
/* Remap FLASH according to real size */
memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size & 0xFFFF8000);
memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | (memctl->memc_br0 & ~(BR_BA_MSK));
/* Re-do sizing to get full correct info */
size = flash_get_size((vu_long *) CFG_FLASH_BASE, &flash_info[0]);
flash_get_offsets(CFG_FLASH_BASE, &flash_info[0]);
/* monitor protection ON by default */
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]);
#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
flash_info[0].size = size;
#if CONFIG_NETPHONE_VERSION == 2
size1 = flash_get_size((vu_long *) FLASH_BASE4_PRELIM, &flash_info[1]);
if (flash_info[1].flash_id == FLASH_UNKNOWN && size1 > 0) {
printf("## Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n", size1, size1 << 20);
}
/* Remap FLASH according to real size */
memctl->memc_or4 = CFG_OR_TIMING_FLASH | (-size1 & 0xFFFF8000);
memctl->memc_br4 = (CFG_FLASH_BASE4 & BR_BA_MSK) | (memctl->memc_br4 & ~(BR_BA_MSK));
/* Re-do sizing to get full correct info */
size1 = flash_get_size((vu_long *) CFG_FLASH_BASE4, &flash_info[1]);
flash_get_offsets(CFG_FLASH_BASE4, &flash_info[1]);
size += size1;
#endif
return (size);
}
/*-----------------------------------------------------------------------
*/
static void flash_get_offsets(ulong base, flash_info_t * info)
{
int i;
/* set up sector start address table */
if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) {
for (i = 0; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00010000);
}
} else if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00004000;
info->start[2] = base + 0x00006000;
info->start[3] = base + 0x00008000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00010000) - 0x00030000;
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00004000;
info->start[i--] = base + info->size - 0x00006000;
info->start[i--] = base + info->size - 0x00008000;
for (; i >= 0; i--) {
info->start[i] = base + i * 0x00010000;
}
}
}
/*-----------------------------------------------------------------------
*/
void flash_print_info(flash_info_t * info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
printf("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD:
printf("AMD ");
break;
case FLASH_MAN_FUJ:
printf("FUJITSU ");
break;
case FLASH_MAN_MX:
printf("MXIC ");
break;
default:
printf("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AM040:
printf("AM29LV040B (4 Mbit, bottom boot sect)\n");
break;
case FLASH_AM400B:
printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
break;
case FLASH_AM400T:
printf("AM29LV400T (4 Mbit, top boot sector)\n");
break;
case FLASH_AM800B:
printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
break;
case FLASH_AM800T:
printf("AM29LV800T (8 Mbit, top boot sector)\n");
break;
case FLASH_AM160B:
printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
break;
case FLASH_AM160T:
printf("AM29LV160T (16 Mbit, top boot sector)\n");
break;
case FLASH_AM320B:
printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
break;
case FLASH_AM320T:
printf("AM29LV320T (32 Mbit, top boot sector)\n");
break;
default:
printf("Unknown Chip Type\n");
break;
}
printf(" Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count);
printf(" Sector Start Addresses:");
for (i = 0; i < info->sector_count; ++i) {
if ((i % 5) == 0)
printf("\n ");
printf(" %08lX%s", info->start[i], info->protect[i] ? " (RO)" : " ");
}
printf("\n");
}
/*-----------------------------------------------------------------------
*/
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
static ulong flash_get_size(vu_long * addr, flash_info_t * info)
{
short i;
uchar mid;
uchar pid;
vu_char *caddr = (vu_char *) addr;
ulong base = (ulong) addr;
/* Write auto select command: read Manufacturer ID */
caddr[0x0555] = 0xAA;
caddr[0x02AA] = 0x55;
caddr[0x0555] = 0x90;
mid = caddr[0];
switch (mid) {
case (AMD_MANUFACT & 0xFF):
info->flash_id = FLASH_MAN_AMD;
break;
case (FUJ_MANUFACT & 0xFF):
info->flash_id = FLASH_MAN_FUJ;
break;
case (MX_MANUFACT & 0xFF):
info->flash_id = FLASH_MAN_MX;
break;
case (STM_MANUFACT & 0xFF):
info->flash_id = FLASH_MAN_STM;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* no or unknown flash */
}
pid = caddr[1]; /* device ID */
switch (pid) {
case (AMD_ID_LV400T & 0xFF):
info->flash_id += FLASH_AM400T;
info->sector_count = 11;
info->size = 0x00080000;
break; /* => 512 kB */
case (AMD_ID_LV400B & 0xFF):
info->flash_id += FLASH_AM400B;
info->sector_count = 11;
info->size = 0x00080000;
break; /* => 512 kB */
case (AMD_ID_LV800T & 0xFF):
info->flash_id += FLASH_AM800T;
info->sector_count = 19;
info->size = 0x00100000;
break; /* => 1 MB */
case (AMD_ID_LV800B & 0xFF):
info->flash_id += FLASH_AM800B;
info->sector_count = 19;
info->size = 0x00100000;
break; /* => 1 MB */
case (AMD_ID_LV160T & 0xFF):
info->flash_id += FLASH_AM160T;
info->sector_count = 35;
info->size = 0x00200000;
break; /* => 2 MB */
case (AMD_ID_LV160B & 0xFF):
info->flash_id += FLASH_AM160B;
info->sector_count = 35;
info->size = 0x00200000;
break; /* => 2 MB */
case (AMD_ID_LV040B & 0xFF):
info->flash_id += FLASH_AM040;
info->sector_count = 8;
info->size = 0x00080000;
break;
case (STM_ID_M29W040B & 0xFF):
info->flash_id += FLASH_AM040;
info->sector_count = 8;
info->size = 0x00080000;
break;
#if 0 /* enable when device IDs are available */
case (AMD_ID_LV320T & 0xFF):
info->flash_id += FLASH_AM320T;
info->sector_count = 67;
info->size = 0x00400000;
break; /* => 4 MB */
case (AMD_ID_LV320B & 0xFF):
info->flash_id += FLASH_AM320B;
info->sector_count = 67;
info->size = 0x00400000;
break; /* => 4 MB */
#endif
default:
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
}
printf(" ");
/* set up sector start address table */
if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) {
for (i = 0; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00010000);
}
} else if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00004000;
info->start[2] = base + 0x00006000;
info->start[3] = base + 0x00008000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00010000) - 0x00030000;
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00004000;
info->start[i--] = base + info->size - 0x00006000;
info->start[i--] = base + info->size - 0x00008000;
for (; i >= 0; i--) {
info->start[i] = base + i * 0x00010000;
}
}
/* check for protected sectors */
for (i = 0; i < info->sector_count; i++) {
/* read sector protection: D0 = 1 if protected */
caddr = (volatile unsigned char *)(info->start[i]);
info->protect[i] = caddr[2] & 1;
}
/*
* Prevent writes to uninitialized FLASH.
*/
if (info->flash_id != FLASH_UNKNOWN) {
caddr = (vu_char *) info->start[0];
caddr[0x0555] = 0xAA;
caddr[0x02AA] = 0x55;
caddr[0x0555] = 0xF0;
udelay(20000);
}
return (info->size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase(flash_info_t * info, int s_first, int s_last)
{
vu_char *addr = (vu_char *) (info->start[0]);
int flag, prot, sect, l_sect;
ulong start, now, last;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf("- missing\n");
} else {
printf("- no sectors to erase\n");
}
return 1;
}
if ((info->flash_id == FLASH_UNKNOWN) ||
(info->flash_id > FLASH_AMD_COMP)) {
printf("Can't erase unknown flash type %08lx - aborted\n", info->flash_id);
return 1;
}
prot = 0;
for (sect = s_first; sect <= s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf("- Warning: %d protected sectors will not be erased!\n", prot);
} else {
printf("\n");
}
l_sect = -1;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
addr[0x0555] = 0x80;
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
/* Start erase on unprotected sectors */
for (sect = s_first; sect <= s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
addr = (vu_char *) (info->start[sect]);
addr[0] = 0x30;
l_sect = sect;
}
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay(1000);
/*
* We wait for the last triggered sector
*/
if (l_sect < 0)
goto DONE;
start = get_timer(0);
last = start;
addr = (vu_char *) (info->start[l_sect]);
while ((addr[0] & 0x80) != 0x80) {
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf("Timeout\n");
return 1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc('.');
last = now;
}
}
DONE:
/* reset to read mode */
addr = (vu_char *) info->start[0];
addr[0] = 0xF0; /* reset bank */
printf(" done\n");
return 0;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
int rc;
while (cnt > 0) {
if ((rc = write_byte(info, addr++, *src++)) != 0) {
return (rc);
}
--cnt;
}
return (0);
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_byte(flash_info_t * info, ulong dest, uchar data)
{
vu_char *addr = (vu_char *) (info->start[0]);
ulong start;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((*((vu_char *) dest) & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
addr[0x0555] = 0xA0;
*((vu_char *) dest) = data;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer(0);
while ((*((vu_char *) dest) & 0x80) != (data & 0x80)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
return (1);
}
}
return (0);
}

716
board/netphone/netphone.c Normal file
View File

@@ -0,0 +1,716 @@
/*
* (C) Copyright 2000-2004
* Pantelis Antoniou, Intracom S.A., panto@intracom.gr
* 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
*/
/*
* Pantelis Antoniou, Intracom S.A., panto@intracom.gr
* U-Boot port on NetTA4 board
*/
#include <common.h>
#include <miiphy.h>
#include <sed156x.h>
#include <status_led.h>
#include "mpc8xx.h"
#ifdef CONFIG_HW_WATCHDOG
#include <watchdog.h>
#endif
/****************************************************************/
/* some sane bit macros */
#define _BD(_b) (1U << (31-(_b)))
#define _BDR(_l, _h) (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
#define _BW(_b) (1U << (15-(_b)))
#define _BWR(_l, _h) (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
#define _BB(_b) (1U << (7-(_b)))
#define _BBR(_l, _h) (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
#define _B(_b) _BD(_b)
#define _BR(_l, _h) _BDR(_l, _h)
/****************************************************************/
/*
* Check Board Identity:
*
* Return 1 always.
*/
int checkboard(void)
{
printf ("Intracom NetPhone V%d\n", CONFIG_NETPHONE_VERSION);
return (0);
}
/****************************************************************/
#define _NOT_USED_ 0xFFFFFFFF
/****************************************************************/
#define CS_0000 0x00000000
#define CS_0001 0x10000000
#define CS_0010 0x20000000
#define CS_0011 0x30000000
#define CS_0100 0x40000000
#define CS_0101 0x50000000
#define CS_0110 0x60000000
#define CS_0111 0x70000000
#define CS_1000 0x80000000
#define CS_1001 0x90000000
#define CS_1010 0xA0000000
#define CS_1011 0xB0000000
#define CS_1100 0xC0000000
#define CS_1101 0xD0000000
#define CS_1110 0xE0000000
#define CS_1111 0xF0000000
#define BS_0000 0x00000000
#define BS_0001 0x01000000
#define BS_0010 0x02000000
#define BS_0011 0x03000000
#define BS_0100 0x04000000
#define BS_0101 0x05000000
#define BS_0110 0x06000000
#define BS_0111 0x07000000
#define BS_1000 0x08000000
#define BS_1001 0x09000000
#define BS_1010 0x0A000000
#define BS_1011 0x0B000000
#define BS_1100 0x0C000000
#define BS_1101 0x0D000000
#define BS_1110 0x0E000000
#define BS_1111 0x0F000000
#define GPL0_AAAA 0x00000000
#define GPL0_AAA0 0x00200000
#define GPL0_AAA1 0x00300000
#define GPL0_000A 0x00800000
#define GPL0_0000 0x00A00000
#define GPL0_0001 0x00B00000
#define GPL0_111A 0x00C00000
#define GPL0_1110 0x00E00000
#define GPL0_1111 0x00F00000
#define GPL1_0000 0x00000000
#define GPL1_0001 0x00040000
#define GPL1_1110 0x00080000
#define GPL1_1111 0x000C0000
#define GPL2_0000 0x00000000
#define GPL2_0001 0x00010000
#define GPL2_1110 0x00020000
#define GPL2_1111 0x00030000
#define GPL3_0000 0x00000000
#define GPL3_0001 0x00004000
#define GPL3_1110 0x00008000
#define GPL3_1111 0x0000C000
#define GPL4_0000 0x00000000
#define GPL4_0001 0x00001000
#define GPL4_1110 0x00002000
#define GPL4_1111 0x00003000
#define GPL5_0000 0x00000000
#define GPL5_0001 0x00000400
#define GPL5_1110 0x00000800
#define GPL5_1111 0x00000C00
#define LOOP 0x00000080
#define EXEN 0x00000040
#define AMX_COL 0x00000000
#define AMX_ROW 0x00000020
#define AMX_MAR 0x00000030
#define NA 0x00000008
#define UTA 0x00000004
#define TODT 0x00000002
#define LAST 0x00000001
#define A10_AAAA GPL0_AAAA
#define A10_AAA0 GPL0_AAA0
#define A10_AAA1 GPL0_AAA1
#define A10_000A GPL0_000A
#define A10_0000 GPL0_0000
#define A10_0001 GPL0_0001
#define A10_111A GPL0_111A
#define A10_1110 GPL0_1110
#define A10_1111 GPL0_1111
#define RAS_0000 GPL1_0000
#define RAS_0001 GPL1_0001
#define RAS_1110 GPL1_1110
#define RAS_1111 GPL1_1111
#define CAS_0000 GPL2_0000
#define CAS_0001 GPL2_0001
#define CAS_1110 GPL2_1110
#define CAS_1111 GPL2_1111
#define WE_0000 GPL3_0000
#define WE_0001 GPL3_0001
#define WE_1110 GPL3_1110
#define WE_1111 GPL3_1111
/* #define CAS_LATENCY 3 */
#define CAS_LATENCY 2
const uint sdram_table[0x40] = {
#if CAS_LATENCY == 3
/* RSS */
CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_0000 | BS_1111 | A10_0001 | RAS_1111 | CAS_0001 | WE_1111 | AMX_COL | UTA, /* READ */
CS_0001 | BS_0001 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA, /* PALL */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | TODT | LAST, /* NOP */
_NOT_USED_, _NOT_USED_,
/* RBS */
CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_0001 | BS_1111 | A10_0001 | RAS_1111 | CAS_0001 | WE_1111 | AMX_COL | UTA, /* READ */
CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_0001 | BS_0001 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL, /* PALL */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | TODT | LAST, /* NOP */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* WSS */
CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_0000 | BS_0001 | A10_0000 | RAS_1111 | CAS_0001 | WE_0000 | AMX_COL | UTA, /* WRITE */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA, /* PALL */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | TODT | LAST, /* NOP */
_NOT_USED_, _NOT_USED_, _NOT_USED_,
/* WBS */
CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_0001 | BS_0000 | A10_0000 | RAS_1111 | CAS_0001 | WE_0000 | AMX_COL, /* WRITE */
CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1111 | BS_0001 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA, /* PALL */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | TODT | LAST, /* NOP */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_,
#endif
#if CAS_LATENCY == 2
/* RSS */
CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1110 | BS_1110 | A10_0000 | RAS_1111 | CAS_1110 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_0001 | BS_0001 | A10_0000 | RAS_1111 | CAS_0001 | WE_1111 | AMX_COL | UTA, /* READ */
CS_1110 | BS_1111 | A10_0001 | RAS_1110 | CAS_1111 | WE_1110 | AMX_COL, /* NOP */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA | TODT | LAST, /* PALL */
_NOT_USED_,
_NOT_USED_, _NOT_USED_,
/* RBS */
CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1110 | BS_1110 | A10_0000 | RAS_1111 | CAS_1110 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_0001 | BS_0000 | A10_0000 | RAS_1111 | CAS_0001 | WE_1111 | AMX_COL | UTA, /* READ */
CS_1111 | BS_0000 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1111 | BS_0000 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1111 | BS_0001 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1110 | BS_1111 | A10_0001 | RAS_1110 | CAS_1111 | WE_1110 | AMX_COL, /* NOP */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA | TODT | LAST, /* PALL */
_NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* WSS */
CS_0001 | BS_1111 | A10_AAA0 | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1110 | BS_1110 | A10_0000 | RAS_1111 | CAS_1110 | WE_1110 | AMX_COL, /* NOP */
CS_0000 | BS_0001 | A10_0001 | RAS_1110 | CAS_0001 | WE_0000 | AMX_COL | UTA, /* WRITE */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA | TODT | LAST, /* PALL */
_NOT_USED_,
_NOT_USED_, _NOT_USED_,
_NOT_USED_,
/* WBS */
CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1110 | BS_1110 | A10_0000 | RAS_1111 | CAS_1110 | WE_1110 | AMX_COL, /* NOP */
CS_0001 | BS_0000 | A10_0000 | RAS_1111 | CAS_0001 | WE_0001 | AMX_COL, /* WRITE */
CS_1111 | BS_0000 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1111 | BS_0000 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1110 | BS_0001 | A10_0001 | RAS_1110 | CAS_1111 | WE_1110 | AMX_COL | UTA, /* NOP */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA | TODT | LAST, /* PALL */
_NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_,
#endif
/* UPT */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_0001 | WE_1111 | AMX_COL | UTA | LOOP, /* ATRFR */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | LOOP, /* NOP */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | TODT | LAST, /* NOP */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_,
/* EXC */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA | LAST,
_NOT_USED_,
/* REG */
CS_1110 | BS_1111 | A10_1110 | RAS_1110 | CAS_1110 | WE_1110 | AMX_MAR | UTA,
CS_0001 | BS_1111 | A10_0001 | RAS_0001 | CAS_0001 | WE_0001 | AMX_MAR | UTA | LAST,
};
#if CONFIG_NETPHONE_VERSION == 2
static const uint nandcs_table[0x40] = {
/* RSS */
CS_1000 | GPL4_1111 | GPL5_1111 | UTA,
CS_0000 | GPL4_1110 | GPL5_1111 | UTA,
CS_0000 | GPL4_0000 | GPL5_1111 | UTA,
CS_0000 | GPL4_0000 | GPL5_1111 | UTA,
CS_0000 | GPL4_0000 | GPL5_1111,
CS_0000 | GPL4_0001 | GPL5_1111 | UTA,
CS_0000 | GPL4_1111 | GPL5_1111 | UTA,
CS_0011 | GPL4_1111 | GPL5_1111 | UTA | LAST, /* NOP */
/* RBS */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* WSS */
CS_1000 | GPL4_1111 | GPL5_1110 | UTA,
CS_0000 | GPL4_1111 | GPL5_0000 | UTA,
CS_0000 | GPL4_1111 | GPL5_0000 | UTA,
CS_0000 | GPL4_1111 | GPL5_0000 | UTA,
CS_0000 | GPL4_1111 | GPL5_0001 | UTA,
CS_0000 | GPL4_1111 | GPL5_1111 | UTA,
CS_0000 | GPL4_1111 | GPL5_1111,
CS_0011 | GPL4_1111 | GPL5_1111 | UTA | LAST,
/* WBS */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* UPT */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* EXC */
CS_0001 | LAST,
_NOT_USED_,
/* REG */
CS_1110 ,
CS_0001 | LAST,
};
#endif
/* 0xC8 = 0b11001000 , CAS3, >> 2 = 0b00 11 0 010 */
/* 0x88 = 0b10001000 , CAS2, >> 2 = 0b00 10 0 010 */
#define MAR_SDRAM_INIT ((CAS_LATENCY << 6) | 0x00000008LU)
/* 8 */
#define CFG_MAMR ((CFG_MAMR_PTA << MAMR_PTA_SHIFT) | MAMR_PTAE | \
MAMR_AMA_TYPE_0 | MAMR_DSA_1_CYCL | MAMR_G0CLA_A11 | \
MAMR_RLFA_1X | MAMR_WLFA_1X | MAMR_TLFA_4X)
void check_ram(unsigned int addr, unsigned int size)
{
unsigned int i, j, v, vv;
volatile unsigned int *p;
unsigned int pv;
p = (unsigned int *)addr;
pv = (unsigned int)p;
for (i = 0; i < size / sizeof(unsigned int); i++, pv += sizeof(unsigned int))
*p++ = pv;
p = (unsigned int *)addr;
for (i = 0; i < size / sizeof(unsigned int); i++) {
v = (unsigned int)p;
vv = *p;
if (vv != v) {
printf("%p: read %08x instead of %08x\n", p, vv, v);
hang();
}
p++;
}
for (j = 0; j < 5; j++) {
switch (j) {
case 0: v = 0x00000000; break;
case 1: v = 0xffffffff; break;
case 2: v = 0x55555555; break;
case 3: v = 0xaaaaaaaa; break;
default:v = 0xdeadbeef; break;
}
p = (unsigned int *)addr;
for (i = 0; i < size / sizeof(unsigned int); i++) {
*p = v;
vv = *p;
if (vv != v) {
printf("%p: read %08x instead of %08x\n", p, vv, v);
hang();
}
*p = ~v;
p++;
}
}
}
long int initdram(int board_type)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
long int size;
upmconfig(UPMB, (uint *) sdram_table, sizeof(sdram_table) / sizeof(sdram_table[0]));
/*
* Preliminary prescaler for refresh
*/
memctl->memc_mptpr = MPTPR_PTP_DIV8;
memctl->memc_mar = MAR_SDRAM_INIT; /* 32-bit address to be output on the address bus if AMX = 0b11 */
/*
* Map controller bank 3 to the SDRAM bank at preliminary address.
*/
memctl->memc_or3 = CFG_OR3_PRELIM;
memctl->memc_br3 = CFG_BR3_PRELIM;
memctl->memc_mbmr = CFG_MAMR & ~MAMR_PTAE; /* no refresh yet */
udelay(200);
/* perform SDRAM initialisation sequence */
memctl->memc_mcr = MCR_OP_RUN | MCR_UPM_B | MCR_MB_CS3 | MCR_MLCF(1) | MCR_MAD(0x3C); /* precharge all */
udelay(1);
memctl->memc_mcr = MCR_OP_RUN | MCR_UPM_B | MCR_MB_CS3 | MCR_MLCF(2) | MCR_MAD(0x30); /* refresh 2 times(0) */
udelay(1);
memctl->memc_mcr = MCR_OP_RUN | MCR_UPM_B | MCR_MB_CS3 | MCR_MLCF(1) | MCR_MAD(0x3E); /* exception program (write mar)*/
udelay(1);
memctl->memc_mbmr |= MAMR_PTAE; /* enable refresh */
udelay(10000);
{
u32 d1, d2;
d1 = 0xAA55AA55;
*(volatile u32 *)0 = d1;
d2 = *(volatile u32 *)0;
if (d1 != d2) {
printf("DRAM fails: wrote 0x%08x read 0x%08x\n", d1, d2);
hang();
}
d1 = 0x55AA55AA;
*(volatile u32 *)0 = d1;
d2 = *(volatile u32 *)0;
if (d1 != d2) {
printf("DRAM fails: wrote 0x%08x read 0x%08x\n", d1, d2);
hang();
}
}
size = get_ram_size((long *)0, SDRAM_MAX_SIZE);
if (size == 0) {
printf("SIZE is zero: LOOP on 0\n");
for (;;) {
*(volatile u32 *)0 = 0;
(void)*(volatile u32 *)0;
}
}
return size;
}
/* ------------------------------------------------------------------------- */
void reset_phys(void)
{
int phyno;
unsigned short v;
udelay(10000);
/* reset the damn phys */
mii_init();
for (phyno = 0; phyno < 32; ++phyno) {
miiphy_read(phyno, PHY_PHYIDR1, &v);
if (v == 0xFFFF)
continue;
miiphy_write(phyno, PHY_BMCR, PHY_BMCR_POWD);
udelay(10000);
miiphy_write(phyno, PHY_BMCR, PHY_BMCR_RESET | PHY_BMCR_AUTON);
udelay(10000);
}
}
/* ------------------------------------------------------------------------- */
/* GP = general purpose, SP = special purpose (on chip peripheral) */
/* bits that can have a special purpose or can be configured as inputs/outputs */
#define PA_GP_INMASK 0
#define PA_GP_OUTMASK (_BW(3) | _BW(7) | _BW(10) | _BW(14) | _BW(15))
#define PA_SP_MASK 0
#define PA_ODR_VAL 0
#define PA_GP_OUTVAL (_BW(3) | _BW(14) | _BW(15))
#define PA_SP_DIRVAL 0
#define PB_GP_INMASK _B(28)
#define PB_GP_OUTMASK (_B(19) | _B(23) | _B(26) | _B(27) | _B(29) | _B(30))
#define PB_SP_MASK (_BR(22, 25))
#define PB_ODR_VAL 0
#define PB_GP_OUTVAL (_B(26) | _B(27) | _B(29) | _B(30))
#define PB_SP_DIRVAL 0
#if CONFIG_NETPHONE_VERSION == 1
#define PC_GP_INMASK _BW(12)
#define PC_GP_OUTMASK (_BW(10) | _BW(11) | _BW(13) | _BW(15))
#elif CONFIG_NETPHONE_VERSION == 2
#define PC_GP_INMASK (_BW(13) | _BW(15))
#define PC_GP_OUTMASK (_BW(10) | _BW(11) | _BW(12))
#endif
#define PC_SP_MASK 0
#define PC_SOVAL 0
#define PC_INTVAL 0
#define PC_GP_OUTVAL (_BW(10) | _BW(11))
#define PC_SP_DIRVAL 0
#if CONFIG_NETPHONE_VERSION == 1
#define PE_GP_INMASK _B(31)
#define PE_GP_OUTMASK (_B(17) | _B(18) |_B(20) | _B(24) | _B(27) | _B(28) | _B(29) | _B(30))
#define PE_GP_OUTVAL (_B(20) | _B(24) | _B(27) | _B(28))
#elif CONFIG_NETPHONE_VERSION == 2
#define PE_GP_INMASK _BR(28, 31)
#define PE_GP_OUTMASK (_B(17) | _B(18) |_B(20) | _B(24) | _B(27))
#define PE_GP_OUTVAL (_B(20) | _B(24) | _B(27))
#endif
#define PE_SP_MASK 0
#define PE_ODR_VAL 0
#define PE_SP_DIRVAL 0
int board_early_init_f(void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile iop8xx_t *ioport = &immap->im_ioport;
volatile cpm8xx_t *cpm = &immap->im_cpm;
volatile memctl8xx_t *memctl = &immap->im_memctl;
/* NAND chip select */
#if CONFIG_NETPHONE_VERSION == 1
memctl->memc_or1 = ((0xFFFFFFFFLU & ~(NAND_SIZE - 1)) | OR_CSNT_SAM | OR_BI | OR_SCY_8_CLK | OR_EHTR | OR_TRLX);
memctl->memc_br1 = ((NAND_BASE & BR_BA_MSK) | BR_PS_8 | BR_V);
#elif CONFIG_NETPHONE_VERSION == 2
upmconfig(UPMA, (uint *) nandcs_table, sizeof(nandcs_table) / sizeof(nandcs_table[0]));
memctl->memc_or1 = ((0xFFFFFFFFLU & ~(NAND_SIZE - 1)) | OR_BI | OR_G5LS);
memctl->memc_br1 = ((NAND_BASE & BR_BA_MSK) | BR_PS_8 | BR_V | BR_MS_UPMA);
memctl->memc_mamr = 0; /* all clear */
#endif
/* DSP chip select */
memctl->memc_or2 = ((0xFFFFFFFFLU & ~(DSP_SIZE - 1)) | OR_CSNT_SAM | OR_BI | OR_ACS_DIV2 | OR_SETA | OR_TRLX);
memctl->memc_br2 = ((DSP_BASE & BR_BA_MSK) | BR_PS_16 | BR_V);
#if CONFIG_NETPHONE_VERSION == 1
memctl->memc_br4 &= ~BR_V;
#endif
memctl->memc_br5 &= ~BR_V;
memctl->memc_br6 &= ~BR_V;
memctl->memc_br7 &= ~BR_V;
ioport->iop_padat = PA_GP_OUTVAL;
ioport->iop_paodr = PA_ODR_VAL;
ioport->iop_padir = PA_GP_OUTMASK | PA_SP_DIRVAL;
ioport->iop_papar = PA_SP_MASK;
cpm->cp_pbdat = PB_GP_OUTVAL;
cpm->cp_pbodr = PB_ODR_VAL;
cpm->cp_pbdir = PB_GP_OUTMASK | PB_SP_DIRVAL;
cpm->cp_pbpar = PB_SP_MASK;
ioport->iop_pcdat = PC_GP_OUTVAL;
ioport->iop_pcdir = PC_GP_OUTMASK | PC_SP_DIRVAL;
ioport->iop_pcso = PC_SOVAL;
ioport->iop_pcint = PC_INTVAL;
ioport->iop_pcpar = PC_SP_MASK;
cpm->cp_pedat = PE_GP_OUTVAL;
cpm->cp_peodr = PE_ODR_VAL;
cpm->cp_pedir = PE_GP_OUTMASK | PE_SP_DIRVAL;
cpm->cp_pepar = PE_SP_MASK;
return 0;
}
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#include <linux/mtd/nand.h>
extern ulong nand_probe(ulong physadr);
extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
void nand_init(void)
{
unsigned long totlen;
totlen = nand_probe(CFG_NAND_BASE);
printf ("%4lu MB\n", totlen >> 20);
}
#endif
#ifdef CONFIG_HW_WATCHDOG
void hw_watchdog_reset(void)
{
/* XXX add here the really funky stuff */
}
#endif
#ifdef CONFIG_SHOW_ACTIVITY
static volatile int left_to_poll = PHONE_CONSOLE_POLL_HZ; /* poll */
/* called from timer interrupt every 1/CFG_HZ sec */
void board_show_activity(ulong timestamp)
{
if (left_to_poll > -PHONE_CONSOLE_POLL_HZ)
--left_to_poll;
}
extern void phone_console_do_poll(void);
static void do_poll(void)
{
unsigned int base;
while (left_to_poll <= 0) {
phone_console_do_poll();
base = left_to_poll + PHONE_CONSOLE_POLL_HZ;
do {
left_to_poll = base;
} while (base != left_to_poll);
}
}
/* called when looping */
void show_activity(int arg)
{
do_poll();
}
#endif
#if defined(CFG_CONSOLE_IS_IN_ENV) && defined(CFG_CONSOLE_OVERWRITE_ROUTINE)
int overwrite_console(void)
{
/* printf("overwrite_console called\n"); */
return 0;
}
#endif
extern int drv_phone_init(void);
extern int drv_phone_use_me(void);
extern int drv_phone_is_idle(void);
int misc_init_r(void)
{
return drv_phone_init();
}
int last_stage_init(void)
{
int i;
#if CONFIG_NETPHONE_VERSION == 2
/* assert peripheral reset */
((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pcdat &= ~_BW(12);
for (i = 0; i < 10; i++)
udelay(1000);
((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pcdat |= _BW(12);
#endif
reset_phys();
/* check in order to enable the local console */
left_to_poll = PHONE_CONSOLE_POLL_HZ;
i = CFG_HZ * 2;
while (i > 0) {
if (tstc()) {
getc();
break;
}
do_poll();
if (drv_phone_use_me()) {
status_led_set(0, STATUS_LED_ON);
while (!drv_phone_is_idle()) {
do_poll();
udelay(1000000 / CFG_HZ);
}
console_assign(stdin, "phone");
console_assign(stdout, "phone");
console_assign(stderr, "phone");
setenv("bootdelay", "-1");
break;
}
udelay(1000000 / CFG_HZ);
i--;
left_to_poll--;
}
left_to_poll = PHONE_CONSOLE_POLL_HZ;
return 0;
}

File diff suppressed because it is too large Load Diff

138
board/netphone/u-boot.lds Normal file
View File

@@ -0,0 +1,138 @@
/*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
.text :
{
cpu/mpc8xx/start.o (.text)
cpu/mpc8xx/traps.o (.text)
common/dlmalloc.o (.text)
lib_ppc/ppcstring.o (.text)
lib_generic/vsprintf.o (.text)
lib_generic/crc32.o (.text)
lib_generic/zlib.o (.text)
lib_ppc/cache.o (.text)
lib_ppc/time.o (.text)
. = DEFINED(env_offset) ? env_offset : .;
common/environment.o (.text)
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
*(.rodata.str1.4)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x00FF) & 0xFFFFFF00;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(256);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(256);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

View File

@@ -0,0 +1,135 @@
/*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
.text :
{
/* WARNING - the following is hand-optimized to fit within */
/* the sector layout of our flash chips! XXX FIXME XXX */
cpu/mpc8xx/start.o (.text)
common/dlmalloc.o (.text)
lib_generic/vsprintf.o (.text)
lib_generic/crc32.o (.text)
. = env_offset;
common/environment.o(.text)
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x0FFF) & 0xFFFFF000;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__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(4096);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(4096);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

40
board/netta/Makefile Normal file
View File

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

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

@@ -0,0 +1,28 @@
#
# (C) Copyright 2000-2004
# 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
#
#
# netVia Boards
#
TEXT_BASE = 0x40000000

1031
board/netta/dsp.c Normal file

File diff suppressed because it is too large Load Diff

508
board/netta/flash.c Normal file
View File

@@ -0,0 +1,508 @@
/*
* (C) Copyright 2000-2004
* 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>
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*-----------------------------------------------------------------------
* Functions
*/
static ulong flash_get_size(vu_long * addr, flash_info_t * info);
static int write_byte(flash_info_t * info, ulong dest, uchar data);
static void flash_get_offsets(ulong base, flash_info_t * info);
/*-----------------------------------------------------------------------
*/
unsigned long flash_init(void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
unsigned long size;
int i;
/* Init: no FLASHes known */
for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i)
flash_info[i].flash_id = FLASH_UNKNOWN;
size = flash_get_size((vu_long *) FLASH_BASE0_PRELIM, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", size, size << 20);
}
/* Remap FLASH according to real size */
memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size & 0xFFFF8000);
memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | (memctl->memc_br0 & ~(BR_BA_MSK));
/* Re-do sizing to get full correct info */
size = flash_get_size((vu_long *) CFG_FLASH_BASE, &flash_info[0]);
flash_get_offsets(CFG_FLASH_BASE, &flash_info[0]);
/* monitor protection ON by default */
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]);
#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
flash_info[0].size = size;
return (size);
}
/*-----------------------------------------------------------------------
*/
static void flash_get_offsets(ulong base, flash_info_t * info)
{
int i;
/* set up sector start address table */
if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) {
for (i = 0; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00010000);
}
} else if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00004000;
info->start[2] = base + 0x00006000;
info->start[3] = base + 0x00008000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00010000) - 0x00030000;
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00004000;
info->start[i--] = base + info->size - 0x00006000;
info->start[i--] = base + info->size - 0x00008000;
for (; i >= 0; i--) {
info->start[i] = base + i * 0x00010000;
}
}
}
/*-----------------------------------------------------------------------
*/
void flash_print_info(flash_info_t * info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
printf("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD:
printf("AMD ");
break;
case FLASH_MAN_FUJ:
printf("FUJITSU ");
break;
case FLASH_MAN_MX:
printf("MXIC ");
break;
default:
printf("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AM040:
printf("AM29LV040B (4 Mbit, bottom boot sect)\n");
break;
case FLASH_AM400B:
printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
break;
case FLASH_AM400T:
printf("AM29LV400T (4 Mbit, top boot sector)\n");
break;
case FLASH_AM800B:
printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
break;
case FLASH_AM800T:
printf("AM29LV800T (8 Mbit, top boot sector)\n");
break;
case FLASH_AM160B:
printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
break;
case FLASH_AM160T:
printf("AM29LV160T (16 Mbit, top boot sector)\n");
break;
case FLASH_AM320B:
printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
break;
case FLASH_AM320T:
printf("AM29LV320T (32 Mbit, top boot sector)\n");
break;
default:
printf("Unknown Chip Type\n");
break;
}
printf(" Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count);
printf(" Sector Start Addresses:");
for (i = 0; i < info->sector_count; ++i) {
if ((i % 5) == 0)
printf("\n ");
printf(" %08lX%s", info->start[i], info->protect[i] ? " (RO)" : " ");
}
printf("\n");
}
/*-----------------------------------------------------------------------
*/
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
static ulong flash_get_size(vu_long * addr, flash_info_t * info)
{
short i;
uchar mid;
uchar pid;
vu_char *caddr = (vu_char *) addr;
ulong base = (ulong) addr;
/* Write auto select command: read Manufacturer ID */
caddr[0x0555] = 0xAA;
caddr[0x02AA] = 0x55;
caddr[0x0555] = 0x90;
mid = caddr[0];
switch (mid) {
case (AMD_MANUFACT & 0xFF):
info->flash_id = FLASH_MAN_AMD;
break;
case (FUJ_MANUFACT & 0xFF):
info->flash_id = FLASH_MAN_FUJ;
break;
case (MX_MANUFACT & 0xFF):
info->flash_id = FLASH_MAN_MX;
break;
case (STM_MANUFACT & 0xFF):
info->flash_id = FLASH_MAN_STM;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* no or unknown flash */
}
pid = caddr[1]; /* device ID */
switch (pid) {
case (AMD_ID_LV400T & 0xFF):
info->flash_id += FLASH_AM400T;
info->sector_count = 11;
info->size = 0x00080000;
break; /* => 512 kB */
case (AMD_ID_LV400B & 0xFF):
info->flash_id += FLASH_AM400B;
info->sector_count = 11;
info->size = 0x00080000;
break; /* => 512 kB */
case (AMD_ID_LV800T & 0xFF):
info->flash_id += FLASH_AM800T;
info->sector_count = 19;
info->size = 0x00100000;
break; /* => 1 MB */
case (AMD_ID_LV800B & 0xFF):
info->flash_id += FLASH_AM800B;
info->sector_count = 19;
info->size = 0x00100000;
break; /* => 1 MB */
case (AMD_ID_LV160T & 0xFF):
info->flash_id += FLASH_AM160T;
info->sector_count = 35;
info->size = 0x00200000;
break; /* => 2 MB */
case (AMD_ID_LV160B & 0xFF):
info->flash_id += FLASH_AM160B;
info->sector_count = 35;
info->size = 0x00200000;
break; /* => 2 MB */
case (AMD_ID_LV040B & 0xFF):
info->flash_id += FLASH_AM040;
info->sector_count = 8;
info->size = 0x00080000;
break;
case (STM_ID_M29W040B & 0xFF):
info->flash_id += FLASH_AM040;
info->sector_count = 8;
info->size = 0x00080000;
break;
#if 0 /* enable when device IDs are available */
case (AMD_ID_LV320T & 0xFF):
info->flash_id += FLASH_AM320T;
info->sector_count = 67;
info->size = 0x00400000;
break; /* => 4 MB */
case (AMD_ID_LV320B & 0xFF):
info->flash_id += FLASH_AM320B;
info->sector_count = 67;
info->size = 0x00400000;
break; /* => 4 MB */
#endif
default:
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
}
printf(" ");
/* set up sector start address table */
if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) {
for (i = 0; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00010000);
}
} else if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00004000;
info->start[2] = base + 0x00006000;
info->start[3] = base + 0x00008000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00010000) - 0x00030000;
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00004000;
info->start[i--] = base + info->size - 0x00006000;
info->start[i--] = base + info->size - 0x00008000;
for (; i >= 0; i--) {
info->start[i] = base + i * 0x00010000;
}
}
/* check for protected sectors */
for (i = 0; i < info->sector_count; i++) {
/* read sector protection: D0 = 1 if protected */
caddr = (volatile unsigned char *)(info->start[i]);
info->protect[i] = caddr[2] & 1;
}
/*
* Prevent writes to uninitialized FLASH.
*/
if (info->flash_id != FLASH_UNKNOWN) {
caddr = (vu_char *) info->start[0];
caddr[0x0555] = 0xAA;
caddr[0x02AA] = 0x55;
caddr[0x0555] = 0xF0;
udelay(20000);
}
return (info->size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase(flash_info_t * info, int s_first, int s_last)
{
vu_char *addr = (vu_char *) (info->start[0]);
int flag, prot, sect, l_sect;
ulong start, now, last;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf("- missing\n");
} else {
printf("- no sectors to erase\n");
}
return 1;
}
if ((info->flash_id == FLASH_UNKNOWN) ||
(info->flash_id > FLASH_AMD_COMP)) {
printf("Can't erase unknown flash type %08lx - aborted\n", info->flash_id);
return 1;
}
prot = 0;
for (sect = s_first; sect <= s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf("- Warning: %d protected sectors will not be erased!\n", prot);
} else {
printf("\n");
}
l_sect = -1;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
addr[0x0555] = 0x80;
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
/* Start erase on unprotected sectors */
for (sect = s_first; sect <= s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
addr = (vu_char *) (info->start[sect]);
addr[0] = 0x30;
l_sect = sect;
}
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay(1000);
/*
* We wait for the last triggered sector
*/
if (l_sect < 0)
goto DONE;
start = get_timer(0);
last = start;
addr = (vu_char *) (info->start[l_sect]);
while ((addr[0] & 0x80) != 0x80) {
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf("Timeout\n");
return 1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc('.');
last = now;
}
}
DONE:
/* reset to read mode */
addr = (vu_char *) info->start[0];
addr[0] = 0xF0; /* reset bank */
printf(" done\n");
return 0;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
int rc;
while (cnt > 0) {
if ((rc = write_byte(info, addr++, *src++)) != 0) {
return (rc);
}
--cnt;
}
return (0);
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_byte(flash_info_t * info, ulong dest, uchar data)
{
vu_char *addr = (vu_char *) (info->start[0]);
ulong start;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((*((vu_char *) dest) & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
addr[0x0555] = 0xA0;
*((vu_char *) dest) = data;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer(0);
while ((*((vu_char *) dest) & 0x80) != (data & 0x80)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
return (1);
}
}
return (0);
}

575
board/netta/netta.c Normal file
View File

@@ -0,0 +1,575 @@
/*
* (C) Copyright 2000-2004
* 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
*/
/*
* Pantelis Antoniou, Intracom S.A., panto@intracom.gr
* U-Boot port on NetTA4 board
*/
#include <common.h>
#include <miiphy.h>
#include "mpc8xx.h"
#ifdef CONFIG_HW_WATCHDOG
#include <watchdog.h>
#endif
/****************************************************************/
/* some sane bit macros */
#define _BD(_b) (1U << (31-(_b)))
#define _BDR(_l, _h) (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
#define _BW(_b) (1U << (15-(_b)))
#define _BWR(_l, _h) (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
#define _BB(_b) (1U << (7-(_b)))
#define _BBR(_l, _h) (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
#define _B(_b) _BD(_b)
#define _BR(_l, _h) _BDR(_l, _h)
/****************************************************************/
/*
* Check Board Identity:
*
* Return 1 always.
*/
int checkboard(void)
{
printf ("Intracom NETTA"
#if defined(CONFIG_NETTA_ISDN)
" with ISDN support"
#endif
"\n"
);
return (0);
}
/****************************************************************/
#define _NOT_USED_ 0xFFFFFFFF
/****************************************************************/
#define CS_0000 0x00000000
#define CS_0001 0x10000000
#define CS_0010 0x20000000
#define CS_0011 0x30000000
#define CS_0100 0x40000000
#define CS_0101 0x50000000
#define CS_0110 0x60000000
#define CS_0111 0x70000000
#define CS_1000 0x80000000
#define CS_1001 0x90000000
#define CS_1010 0xA0000000
#define CS_1011 0xB0000000
#define CS_1100 0xC0000000
#define CS_1101 0xD0000000
#define CS_1110 0xE0000000
#define CS_1111 0xF0000000
#define BS_0000 0x00000000
#define BS_0001 0x01000000
#define BS_0010 0x02000000
#define BS_0011 0x03000000
#define BS_0100 0x04000000
#define BS_0101 0x05000000
#define BS_0110 0x06000000
#define BS_0111 0x07000000
#define BS_1000 0x08000000
#define BS_1001 0x09000000
#define BS_1010 0x0A000000
#define BS_1011 0x0B000000
#define BS_1100 0x0C000000
#define BS_1101 0x0D000000
#define BS_1110 0x0E000000
#define BS_1111 0x0F000000
#define A10_AAAA 0x00000000
#define A10_AAA0 0x00200000
#define A10_AAA1 0x00300000
#define A10_000A 0x00800000
#define A10_0000 0x00A00000
#define A10_0001 0x00B00000
#define A10_111A 0x00C00000
#define A10_1110 0x00E00000
#define A10_1111 0x00F00000
#define RAS_0000 0x00000000
#define RAS_0001 0x00040000
#define RAS_1110 0x00080000
#define RAS_1111 0x000C0000
#define CAS_0000 0x00000000
#define CAS_0001 0x00010000
#define CAS_1110 0x00020000
#define CAS_1111 0x00030000
#define WE_0000 0x00000000
#define WE_0001 0x00004000
#define WE_1110 0x00008000
#define WE_1111 0x0000C000
#define GPL4_0000 0x00000000
#define GPL4_0001 0x00001000
#define GPL4_1110 0x00002000
#define GPL4_1111 0x00003000
#define GPL5_0000 0x00000000
#define GPL5_0001 0x00000400
#define GPL5_1110 0x00000800
#define GPL5_1111 0x00000C00
#define LOOP 0x00000080
#define EXEN 0x00000040
#define AMX_COL 0x00000000
#define AMX_ROW 0x00000020
#define AMX_MAR 0x00000030
#define NA 0x00000008
#define UTA 0x00000004
#define TODT 0x00000002
#define LAST 0x00000001
/* #define CAS_LATENCY 3 */
#define CAS_LATENCY 2
const uint sdram_table[0x40] = {
#if CAS_LATENCY == 3
/* RSS */
CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_0000 | BS_1111 | A10_0001 | RAS_1111 | CAS_0001 | WE_1111 | AMX_COL | UTA, /* READ */
CS_0001 | BS_0001 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA, /* PALL */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | TODT | LAST, /* NOP */
_NOT_USED_, _NOT_USED_,
/* RBS */
CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_0001 | BS_1111 | A10_0001 | RAS_1111 | CAS_0001 | WE_1111 | AMX_COL | UTA, /* READ */
CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_0001 | BS_0001 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL, /* PALL */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | TODT | LAST, /* NOP */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* WSS */
CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_0000 | BS_0001 | A10_0000 | RAS_1111 | CAS_0001 | WE_0000 | AMX_COL | UTA, /* WRITE */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA, /* PALL */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | TODT | LAST, /* NOP */
_NOT_USED_, _NOT_USED_, _NOT_USED_,
/* WBS */
CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_0001 | BS_0000 | A10_0000 | RAS_1111 | CAS_0001 | WE_0000 | AMX_COL, /* WRITE */
CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1111 | BS_0001 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA, /* PALL */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | TODT | LAST, /* NOP */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_,
#endif
#if CAS_LATENCY == 2
/* RSS */
CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1110 | BS_1110 | A10_0000 | RAS_1111 | CAS_1110 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_0001 | BS_0001 | A10_0000 | RAS_1111 | CAS_0001 | WE_1111 | AMX_COL | UTA, /* READ */
CS_1110 | BS_1111 | A10_0001 | RAS_1110 | CAS_1111 | WE_1110 | AMX_COL, /* NOP */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA | TODT | LAST, /* PALL */
_NOT_USED_,
_NOT_USED_, _NOT_USED_,
/* RBS */
CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1110 | BS_1110 | A10_0000 | RAS_1111 | CAS_1110 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_0001 | BS_0000 | A10_0000 | RAS_1111 | CAS_0001 | WE_1111 | AMX_COL | UTA, /* READ */
CS_1111 | BS_0000 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1111 | BS_0000 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1111 | BS_0001 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1110 | BS_1111 | A10_0001 | RAS_1110 | CAS_1111 | WE_1110 | AMX_COL, /* NOP */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA | TODT | LAST, /* PALL */
_NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* WSS */
CS_0001 | BS_1111 | A10_AAA0 | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1110 | BS_1110 | A10_0000 | RAS_1111 | CAS_1110 | WE_1110 | AMX_COL, /* NOP */
CS_0000 | BS_0001 | A10_0001 | RAS_1110 | CAS_0001 | WE_0000 | AMX_COL | UTA, /* WRITE */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA | TODT | LAST, /* PALL */
_NOT_USED_,
_NOT_USED_, _NOT_USED_,
_NOT_USED_,
/* WBS */
CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* ACT */
CS_1110 | BS_1110 | A10_0000 | RAS_1111 | CAS_1110 | WE_1110 | AMX_COL, /* NOP */
CS_0001 | BS_0000 | A10_0000 | RAS_1111 | CAS_0001 | WE_0001 | AMX_COL, /* WRITE */
CS_1111 | BS_0000 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1111 | BS_0000 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
CS_1110 | BS_0001 | A10_0001 | RAS_1110 | CAS_1111 | WE_1110 | AMX_COL | UTA, /* NOP */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA | TODT | LAST, /* PALL */
_NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_,
#endif
/* UPT */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_0001 | WE_1111 | AMX_COL | UTA | LOOP, /* ATRFR */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA, /* NOP */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | LOOP, /* NOP */
CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | TODT | LAST, /* NOP */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_,
/* EXC */
CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA | LAST,
_NOT_USED_,
/* REG */
CS_1110 | BS_1111 | A10_1110 | RAS_1110 | CAS_1110 | WE_1110 | AMX_MAR | UTA,
CS_0001 | BS_1111 | A10_0001 | RAS_0001 | CAS_0001 | WE_0001 | AMX_MAR | UTA | LAST,
};
/* 0xC8 = 0b11001000 , CAS3, >> 2 = 0b00 11 0 010 */
/* 0x88 = 0b10001000 , CAS2, >> 2 = 0b00 10 0 010 */
#define MAR_SDRAM_INIT ((CAS_LATENCY << 6) | 0x00000008LU)
/* 8 */
#define CFG_MAMR ((CFG_MAMR_PTA << MAMR_PTA_SHIFT) | MAMR_PTAE | \
MAMR_AMA_TYPE_0 | MAMR_DSA_1_CYCL | MAMR_G0CLA_A11 | \
MAMR_RLFA_1X | MAMR_WLFA_1X | MAMR_TLFA_4X)
void check_ram(unsigned int addr, unsigned int size)
{
unsigned int i, j, v, vv;
volatile unsigned int *p;
unsigned int pv;
p = (unsigned int *)addr;
pv = (unsigned int)p;
for (i = 0; i < size / sizeof(unsigned int); i++, pv += sizeof(unsigned int))
*p++ = pv;
p = (unsigned int *)addr;
for (i = 0; i < size / sizeof(unsigned int); i++) {
v = (unsigned int)p;
vv = *p;
if (vv != v) {
printf("%p: read %08x instead of %08x\n", p, vv, v);
hang();
}
p++;
}
for (j = 0; j < 5; j++) {
switch (j) {
case 0: v = 0x00000000; break;
case 1: v = 0xffffffff; break;
case 2: v = 0x55555555; break;
case 3: v = 0xaaaaaaaa; break;
default:v = 0xdeadbeef; break;
}
p = (unsigned int *)addr;
for (i = 0; i < size / sizeof(unsigned int); i++) {
*p = v;
vv = *p;
if (vv != v) {
printf("%p: read %08x instead of %08x\n", p, vv, v);
hang();
}
*p = ~v;
p++;
}
}
}
long int initdram(int board_type)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
long int size;
upmconfig(UPMB, (uint *) sdram_table, sizeof(sdram_table) / sizeof(uint));
/*
* Preliminary prescaler for refresh
*/
memctl->memc_mptpr = MPTPR_PTP_DIV8;
memctl->memc_mar = MAR_SDRAM_INIT; /* 32-bit address to be output on the address bus if AMX = 0b11 */
/*
* Map controller bank 3 to the SDRAM bank at preliminary address.
*/
memctl->memc_or3 = CFG_OR3_PRELIM;
memctl->memc_br3 = CFG_BR3_PRELIM;
memctl->memc_mbmr = CFG_MAMR & ~MAMR_PTAE; /* no refresh yet */
udelay(200);
/* perform SDRAM initialisation sequence */
memctl->memc_mcr = MCR_OP_RUN | MCR_UPM_B | MCR_MB_CS3 | MCR_MLCF(1) | MCR_MAD(0x3C); /* precharge all */
udelay(1);
memctl->memc_mcr = MCR_OP_RUN | MCR_UPM_B | MCR_MB_CS3 | MCR_MLCF(2) | MCR_MAD(0x30); /* refresh 2 times(0) */
udelay(1);
memctl->memc_mcr = MCR_OP_RUN | MCR_UPM_B | MCR_MB_CS3 | MCR_MLCF(1) | MCR_MAD(0x3E); /* exception program (write mar)*/
udelay(1);
memctl->memc_mbmr |= MAMR_PTAE; /* enable refresh */
udelay(10000);
{
u32 d1, d2;
d1 = 0xAA55AA55;
*(volatile u32 *)0 = d1;
d2 = *(volatile u32 *)0;
if (d1 != d2) {
printf("DRAM fails: wrote 0x%08x read 0x%08x\n", d1, d2);
hang();
}
d1 = 0x55AA55AA;
*(volatile u32 *)0 = d1;
d2 = *(volatile u32 *)0;
if (d1 != d2) {
printf("DRAM fails: wrote 0x%08x read 0x%08x\n", d1, d2);
hang();
}
}
size = get_ram_size((long *)0, SDRAM_MAX_SIZE);
#if 0
printf("check 0\n");
check_ram(( 0 << 20), (2 << 20));
printf("check 16\n");
check_ram((16 << 20), (2 << 20));
printf("check 32\n");
check_ram((32 << 20), (2 << 20));
printf("check 48\n");
check_ram((48 << 20), (2 << 20));
#endif
if (size == 0) {
printf("SIZE is zero: LOOP on 0\n");
for (;;) {
*(volatile u32 *)0 = 0;
(void)*(volatile u32 *)0;
}
}
return size;
}
/* ------------------------------------------------------------------------- */
int misc_init_r(void)
{
return(0);
}
void reset_phys(void)
{
int phyno;
unsigned short v;
/* reset the damn phys */
mii_init();
for (phyno = 0; phyno < 32; ++phyno) {
miiphy_read(phyno, PHY_PHYIDR1, &v);
if (v == 0xFFFF)
continue;
miiphy_write(phyno, PHY_BMCR, PHY_BMCR_POWD);
udelay(10000);
miiphy_write(phyno, PHY_BMCR, PHY_BMCR_RESET | PHY_BMCR_AUTON);
udelay(10000);
}
}
extern int board_dsp_reset(void);
int last_stage_init(void)
{
int r;
reset_phys();
r = board_dsp_reset();
if (r < 0)
printf("*** WARNING *** DSP reset failed (run diagnostics)\n");
return 0;
}
/* ------------------------------------------------------------------------- */
/* GP = general purpose, SP = special purpose (on chip peripheral) */
/* bits that can have a special purpose or can be configured as inputs/outputs */
#define PA_GP_INMASK (_BWR(3) | _BWR(7, 9) | _BW(11))
#define PA_GP_OUTMASK (_BW(6) | _BW(10) | _BWR(12, 15))
#define PA_SP_MASK (_BWR(0, 2) | _BWR(4, 5))
#define PA_ODR_VAL 0
#define PA_GP_OUTVAL (_BW(13) | _BWR(14, 15))
#define PA_SP_DIRVAL 0
#define PB_GP_INMASK (_B(28) | _B(31))
#define PB_GP_OUTMASK (_BR(16, 19) | _BR(26, 27) | _BR(29, 30))
#define PB_SP_MASK (_BR(22, 25))
#define PB_ODR_VAL 0
#define PB_GP_OUTVAL (_BR(16, 19) | _BR(26, 27) | _BR(29, 31))
#define PB_SP_DIRVAL 0
#define PC_GP_INMASK (_BW(5) | _BW(7) | _BW(8) | _BWR(9, 11) | _BWR(13, 15))
#define PC_GP_OUTMASK (_BW(6) | _BW(12))
#define PC_SP_MASK (_BW(4) | _BW(8))
#define PC_SOVAL 0
#define PC_INTVAL _BW(7)
#define PC_GP_OUTVAL (_BW(6) | _BW(12))
#define PC_SP_DIRVAL 0
#define PD_GP_INMASK 0
#define PD_GP_OUTMASK _BWR(3, 15)
#define PD_SP_MASK 0
#define PD_GP_OUTVAL (_BWR(5, 7) | _BW(9) | _BW(11))
#define PD_SP_DIRVAL 0
int board_early_init_f(void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile iop8xx_t *ioport = &immap->im_ioport;
volatile cpm8xx_t *cpm = &immap->im_cpm;
volatile memctl8xx_t *memctl = &immap->im_memctl;
/* CS1: NAND chip select */
memctl->memc_or1 = ((0xFFFFFFFFLU & ~(NAND_SIZE - 1)) | OR_BI | OR_SCY_2_CLK | OR_TRLX | OR_ACS_DIV2) ;
memctl->memc_br1 = ((NAND_BASE & BR_BA_MSK) | BR_PS_8 | BR_V);
/* CS2: DSP */
memctl->memc_or2 = ((0xFFFFFFFFLU & ~(DSP_SIZE - 1)) | OR_CSNT_SAM | OR_BI | OR_SCY_7_CLK | OR_ACS_DIV2);
memctl->memc_br2 = ((DSP_BASE & BR_BA_MSK) | BR_PS_16 | BR_V);
/* CS4: External register chip select */
memctl->memc_or4 = ((0xFFFFFFFFLU & ~(ER_SIZE - 1)) | OR_BI | OR_SCY_4_CLK);
memctl->memc_br4 = ((ER_BASE & BR_BA_MSK) | BR_PS_32 | BR_V);
/* CS5: dummy for accurate delay */
memctl->memc_or5 = ((0xFFFFFFFFLU & ~(DUMMY_SIZE - 1)) | OR_CSNT_SAM | OR_BI | OR_SCY_0_CLK | OR_ACS_DIV2);
memctl->memc_br5 = ((DUMMY_BASE & BR_BA_MSK) | BR_PS_32 | BR_V);
ioport->iop_padat = PA_GP_OUTVAL;
ioport->iop_paodr = PA_ODR_VAL;
ioport->iop_padir = PA_GP_OUTMASK | PA_SP_DIRVAL;
ioport->iop_papar = PA_SP_MASK;
cpm->cp_pbdat = PB_GP_OUTVAL;
cpm->cp_pbodr = PB_ODR_VAL;
cpm->cp_pbdir = PB_GP_OUTMASK | PB_SP_DIRVAL;
cpm->cp_pbpar = PB_SP_MASK;
ioport->iop_pcdat = PC_GP_OUTVAL;
ioport->iop_pcdir = PC_GP_OUTMASK | PC_SP_DIRVAL;
ioport->iop_pcso = PC_SOVAL;
ioport->iop_pcint = PC_INTVAL;
ioport->iop_pcpar = PC_SP_MASK;
ioport->iop_pddat = PD_GP_OUTVAL;
ioport->iop_pddir = PD_GP_OUTMASK | PD_SP_DIRVAL;
ioport->iop_pdpar = PD_SP_MASK;
ioport->iop_pddat |= (1 << (15 - 6)) | (1 << (15 - 7));
return 0;
}
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#include <linux/mtd/nand.h>
extern ulong nand_probe(ulong physadr);
extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
void nand_init(void)
{
unsigned long totlen = nand_probe(CFG_NAND_BASE);
printf ("%4lu MB\n", totlen >> 20);
}
#endif
#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
int pcmcia_init(void)
{
return 0;
}
#endif
#ifdef CONFIG_POST
/*
* Returns 1 if keys pressed to start the power-on long-running tests
* Called from board_init_f().
*/
int post_hotkeys_pressed(void)
{
return 0; /* No hotkeys supported */
}
#endif
#ifdef CONFIG_HW_WATCHDOG
void hw_watchdog_reset(void)
{
/* XXX add here the really funky stuff */
}
#endif

138
board/netta/u-boot.lds Normal file
View File

@@ -0,0 +1,138 @@
/*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
.text :
{
cpu/mpc8xx/start.o (.text)
cpu/mpc8xx/traps.o (.text)
common/dlmalloc.o (.text)
lib_ppc/ppcstring.o (.text)
lib_generic/vsprintf.o (.text)
lib_generic/crc32.o (.text)
lib_generic/zlib.o (.text)
lib_ppc/cache.o (.text)
lib_ppc/time.o (.text)
. = DEFINED(env_offset) ? env_offset : .;
common/environment.o (.text)
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
*(.rodata.str1.4)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x00FF) & 0xFFFFFF00;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(256);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(256);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

View File

@@ -0,0 +1,135 @@
/*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
.text :
{
/* WARNING - the following is hand-optimized to fit within */
/* the sector layout of our flash chips! XXX FIXME XXX */
cpu/mpc8xx/start.o (.text)
common/dlmalloc.o (.text)
lib_generic/vsprintf.o (.text)
lib_generic/crc32.o (.text)
. = env_offset;
common/environment.o(.text)
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x0FFF) & 0xFFFFF000;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__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(4096);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(4096);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

View File

@@ -91,6 +91,7 @@ tlbtab:
tlbentry( CFG_ISRAM_BASE, SZ_4K, 0x80000000, 0, AC_R|AC_W|AC_X )
tlbentry( CFG_ISRAM_BASE + 0x1000, SZ_4K, 0x80001000, 0, AC_R|AC_W|AC_X )
tlbentry( CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
tlbentry( CFG_SDRAM_BASE+0x10000000, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
tlbentry( CFG_PCI_BASE, SZ_256M, 0x00000000, 2, AC_R|AC_W|SA_G|SA_I )
tlbentry( CFG_PCI_MEMBASE, SZ_256M, 0x00000000, 3, AC_R|AC_W|SA_G|SA_I )
tlbtab_end

48
board/stxgp3/Makefile Normal file
View File

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

33
board/stxgp3/config.mk Normal file
View File

@@ -0,0 +1,33 @@
# Modified by Xianghua Xiao, X.Xiao@motorola.com
# (C) Copyright 2002,2003 Motorola Inc.
#
# Copied from ADS85xx for STx GP3 - Dan Malek
#
# 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
#
#
# default CCARBAR is at 0xff700000
# assume U-Boot is less than 0.5MB
#
TEXT_BASE = 0xfff80000
PLATFORM_CPPFLAGS += -DCONFIG_MPC85xx=1
PLATFORM_CPPFLAGS += -DCONFIG_MPC8560=1
PLATFORM_CPPFLAGS += -DCONFIG_E500=1

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

@@ -0,0 +1,517 @@
/*
* (C) Copyright 2003, Dan Malek, Embedded Edge, LLC. <dan@embeddededge.com>
* Copied from ADS85xx.
* Updated to support the Silicon Tx GP3 8560. We should only find
* two Intel 28F640 parts in 16-bit mode (i.e. 32-bit wide flash),
* but I left other code here in case people order custom boards.
*
* (C) Copyright 2003 Motorola Inc.
* Xianghua Xiao,(X.Xiao@motorola.com)
*
* (C) Copyright 2000, 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com
* Add support the Sharp chips on the mpc8260ads.
* I started with board/ip860/flash.c and made changes I found in
* the MTD project by David Schleef.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#if !defined(CFG_NO_FLASH)
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
#if defined(CFG_ENV_IS_IN_FLASH)
# ifndef CFG_ENV_ADDR
# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
# endif
# ifndef CFG_ENV_SIZE
# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
# endif
# ifndef CFG_ENV_SECT_SIZE
# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
# endif
#endif
#undef DEBUG
/*-----------------------------------------------------------------------
* Functions
*/
static ulong flash_get_size (vu_long *addr, flash_info_t *info);
static int write_word (flash_info_t *info, ulong dest, ulong data);
static int clear_block_lock_bit(vu_long * addr);
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
unsigned long size;
int i;
/* Init: enable write,
* or we cannot even write flash commands
*/
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
/* set the default sector offset */
}
/* Static FLASH Bank configuration here - FIXME XXX */
size = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
size, size<<20);
}
/* Re-do sizing to get full correct info */
size = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
flash_info[0].size = size;
#if !defined(CONFIG_RAM_AS_FLASH)
#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_IS_IN_FLASH
/* ENV protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR+CFG_ENV_SECT_SIZE-1,
&flash_info[0]);
#endif
#endif
return (size);
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_INTEL: printf ("Intel "); break;
case FLASH_MAN_SHARP: printf ("Sharp "); break;
default: printf ("Unknown Vendor "); break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F640C3T: printf ("28F640C3T (64 Mbit x 2, 128 x 128k)\n");
break;
default: printf ("Unknown Chip Type\n");
break;
}
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
}
/*
* The following code cannot be run from FLASH!
*/
static ulong flash_get_size (vu_long *addr, flash_info_t *info)
{
short i;
ulong value;
ulong base = (ulong)addr;
ulong sector_offset;
#ifdef DEBUG
printf("Check flash at 0x%08x\n",(uint)addr);
#endif
/* Write "Intelligent Identifier" command: read Manufacturer ID */
*addr = 0x90909090;
udelay(20);
asm("sync");
value = addr[0] & 0x00FF00FF;
#ifdef DEBUG
printf("manufacturer=0x%x\n",(uint)value);
#endif
switch (value) {
case MT_MANUFACT: /* SHARP, MT or => Intel */
case INTEL_ALT_MANU:
info->flash_id = FLASH_MAN_INTEL;
break;
default:
printf("unknown manufacturer: %x\n", (unsigned int)value);
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* no or unknown flash */
}
value = addr[1]; /* device ID */
#ifdef DEBUG
printf("deviceID=0x%x\n",(uint)value);
#endif
switch (value) {
case (INTEL_ID_28F640C3T):
info->flash_id += FLASH_28F640C3T;
info->sector_count = 135;
info->size = 0x01000000;
sector_offset = 0x20000;
break; /* => 2x8 MB */
default:
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
}
/* set up sector start address table
* The first 127 blocks are large, the last 8 are small.
*/
for (i = 0; i < 127; i++) {
info->start[i] = base;
base += sector_offset;
/* Sectors are locked upon reset */
info->protect[i] = 0;
}
for (i = 127; i < 135; i++) {
info->start[i] = base;
base += 0x4000;
/* Sectors are locked upon reset */
info->protect[i] = 0;
}
/*
* Prevent writes to uninitialized FLASH.
*/
if (info->flash_id != FLASH_UNKNOWN) {
addr = (vu_long *)info->start[0];
*addr = 0xFFFFFF; /* reset bank to read array mode */
asm("sync");
}
return (info->size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
int flag, prot, sect;
ulong start, now, last;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
if ( ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL)
&& ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_SHARP) ) {
printf ("Can't erase unknown flash type %08lx - aborted\n",
info->flash_id);
return 1;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
#ifdef DEBUG
printf("\nFlash Erase:\n");
#endif
/* Make Sure Block Lock Bit is not set. */
if(clear_block_lock_bit((vu_long *)(info->start[s_first]))){
return 1;
}
/* Start erase on unprotected sectors */
#if defined(DEBUG)
printf("Begin to erase now,s_first=0x%x s_last=0x%x...\n",s_first,s_last);
#endif
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
vu_long *addr = (vu_long *)(info->start[sect]);
asm("sync");
last = start = get_timer (0);
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
/* Reset Array */
*addr = 0xffffffff;
asm("sync");
/* Clear Status Register */
*addr = 0x50505050;
asm("sync");
/* Single Block Erase Command */
*addr = 0x20202020;
asm("sync");
/* Confirm */
*addr = 0xD0D0D0D0;
asm("sync");
if((info->flash_id & FLASH_TYPEMASK) != FLASH_LH28F016SCT) {
/* Resume Command, as per errata update */
*addr = 0xD0D0D0D0;
asm("sync");
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
while ((*addr & 0x00800080) != 0x00800080) {
if(*addr & 0x00200020){
printf("Error in Block Erase - Lock Bit may be set!\n");
printf("Status Register = 0x%X\n", (uint)*addr);
*addr = 0xFFFFFFFF; /* reset bank */
asm("sync");
return 1;
}
if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
*addr = 0xFFFFFFFF; /* reset bank */
asm("sync");
return 1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc ('.');
last = now;
}
}
/* reset to read mode */
*addr = 0xFFFFFFFF;
asm("sync");
}
}
printf ("flash erase done\n");
return 0;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong cp, wp, data;
int i, l, rc;
wp = (addr & ~3); /* get lower word aligned address */
/*
* handle unaligned start bytes
*/
if ((l = addr - wp) != 0) {
data = 0;
for (i=0, cp=wp; i<l; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
for (; i<4 && cnt>0; ++i) {
data = (data << 8) | *src++;
--cnt;
++cp;
}
for (; cnt==0 && i<4; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
wp += 4;
}
/*
* handle word aligned part
*/
while (cnt >= 4) {
data = 0;
for (i=0; i<4; ++i) {
data = (data << 8) | *src++;
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
wp += 4;
cnt -= 4;
}
if (cnt == 0) {
return (0);
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
for (; i<4; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
return (write_word(info, wp, data));
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word (flash_info_t *info, ulong dest, ulong data)
{
vu_long *addr = (vu_long *)dest;
ulong start, csr;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((*addr & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
/* Write Command */
*addr = 0x10101010;
asm("sync");
/* Write Data */
*addr = data;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
flag = 0;
while (((csr = *addr) & 0x00800080) != 0x00800080) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
flag = 1;
break;
}
}
if (csr & 0x40404040) {
printf ("CSR indicates write error (%08lx) at %08lx\n", csr, (ulong)addr);
flag = 1;
}
/* Clear Status Registers Command */
*addr = 0x50505050;
asm("sync");
/* Reset to read array mode */
*addr = 0xFFFFFFFF;
asm("sync");
return (flag);
}
/*-----------------------------------------------------------------------
* Clear Block Lock Bit, returns:
* 0 - OK
* 1 - Timeout
*/
static int clear_block_lock_bit(vu_long * addr)
{
ulong start, now;
/* Reset Array */
*addr = 0xffffffff;
asm("sync");
/* Clear Status Register */
*addr = 0x50505050;
asm("sync");
*addr = 0x60606060;
asm("sync");
*addr = 0xd0d0d0d0;
asm("sync");
start = get_timer (0);
while((*addr & 0x00800080) != 0x00800080){
if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout on clearing Block Lock Bit\n");
*addr = 0xFFFFFFFF; /* reset bank */
asm("sync");
return 1;
}
}
return 0;
}
#endif /* !CFG_NO_FLASH */

153
board/stxgp3/init.S Normal file
View File

@@ -0,0 +1,153 @@
/*
* Copyright (C) 2003 Embedded Edge, LLC
* Dan Malek <dan@embeddededge.com>
* Copied from ADS85xx.
* Updates for Silicon Tx GP3 8560. We only support 32-bit flash
* and DDR with SPD EEPROM configuration.
*
* Copyright (C) 2002,2003, Motorola Inc.
* Xianghua Xiao <X.Xiao@motorola.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 <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
#include <config.h>
#include <mpc85xx.h>
#define entry_start \
mflr r1 ; \
bl 0f ;
#define entry_end \
0: mflr r0 ; \
mtlr r1 ; \
blr ;
/* TLB1 entries configuration: */
.section .bootpg, "ax"
.globl tlb1_entry
tlb1_entry:
entry_start
/* If RAMBOOT, we are testing and the BDI has set up
* much of the MMU already.
* TLB 4,5 SDRAM
* TLB 15 is default CCSRBAR.
*/
.long 0x09 /* the following data table uses a few of 16 TLB entries */
.long TLB1_MAS0(1,1,0)
.long TLB1_MAS1(1,1,0,0,BOOKE_PAGESZ_1M)
.long TLB1_MAS2(((CFG_CCSRBAR>>12) & 0xfffff),0,0,0,0,1,0,1,0)
.long TLB1_MAS3(((CFG_CCSRBAR>>12) & 0xfffff),0,0,0,0,0,1,0,1,0,1)
.long TLB1_MAS0(1,2,0)
.long TLB1_MAS1(1,1,0,0,BOOKE_PAGESZ_16M)
.long TLB1_MAS2(((CFG_FLASH_BASE>>12) & 0xfffff),0,0,0,0,1,0,1,0)
.long TLB1_MAS3(((CFG_FLASH_BASE>>12) & 0xfffff),0,0,0,0,0,1,0,1,0,1)
.long TLB1_MAS0(1,3,0)
.long TLB1_MAS1(1,1,0,0,BOOKE_PAGESZ_1M)
.long TLB1_MAS2(((CFG_LBC_LCLDEVS_BASE>>12) & 0xfffff),0,0,0,0,1,0,1,0)
.long TLB1_MAS3(((CFG_LBC_LCLDEVS_BASE>>12) & 0xfffff),0,0,0,0,0,1,0,1,0,1)
.long TLB1_MAS0(1,4,0)
.long TLB1_MAS1(0,0,0,0,BOOKE_PAGESZ_1M)
.long TLB1_MAS2(0,0,0,0,0,0,0,0,0)
.long TLB1_MAS3(0,0,0,0,0,0,1,0,1,0,1)
.long TLB1_MAS0(1,5,0)
.long TLB1_MAS1(0,0,0,0,BOOKE_PAGESZ_1M)
.long TLB1_MAS2(0,0,0,0,0,0,0,0,0)
.long TLB1_MAS3(0,0,0,0,0,0,1,0,1,0,1)
.long TLB1_MAS0(1,6,0)
.long TLB1_MAS1(1,1,0,0,BOOKE_PAGESZ_64M)
#if defined(CONFIG_RAM_AS_FLASH)
.long TLB1_MAS2(((CFG_LBC_SDRAM_BASE>>12) & 0xfffff),0,0,0,0,1,0,1,0)
#else
.long TLB1_MAS2(((CFG_LBC_SDRAM_BASE>>12) & 0xfffff),0,0,0,0,0,0,0,0)
#endif
.long TLB1_MAS3(((CFG_LBC_SDRAM_BASE>>12) & 0xfffff),0,0,0,0,0,1,0,1,0,1)
.long TLB1_MAS0(1,7,0)
.long TLB1_MAS1(1,1,0,0,BOOKE_PAGESZ_16K)
#ifdef CONFIG_L2_INIT_RAM
.long TLB1_MAS2(((CFG_INIT_RAM_ADDR>>12) & 0xfffff),0,0,0,1,0,0,0,0)
#else
.long TLB1_MAS2(((CFG_INIT_RAM_ADDR>>12) & 0xfffff),0,0,0,0,0,0,0,0)
#endif
.long TLB1_MAS3(((CFG_INIT_RAM_ADDR>>12) & 0xfffff),0,0,0,0,0,1,0,1,0,1)
.long TLB1_MAS0(1,8,0)
.long TLB1_MAS1(1,1,0,0,BOOKE_PAGESZ_256M)
.long TLB1_MAS2(((CFG_PCI_MEM_BASE>>12) & 0xfffff),0,0,0,0,1,0,1,0)
.long TLB1_MAS3(((CFG_PCI_MEM_BASE>>12) & 0xfffff),0,0,0,0,0,1,0,1,0,1)
#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
.long TLB1_MAS0(1,15,0)
.long TLB1_MAS1(1,1,0,0,BOOKE_PAGESZ_1M)
.long TLB1_MAS2(((CFG_CCSRBAR_DEFAULT>>12) & 0xfffff),0,0,0,0,1,0,1,0)
.long TLB1_MAS3(((CFG_CCSRBAR_DEFAULT>>12) & 0xfffff),0,0,0,0,0,1,0,1,0,1)
#else
.long TLB1_MAS0(1,15,0)
.long TLB1_MAS1(0,0,0,0,BOOKE_PAGESZ_1M)
.long TLB1_MAS2(0,0,0,0,0,0,0,0,0)
.long TLB1_MAS3(0,0,0,0,0,0,1,0,1,0,1)
#endif
entry_end
/* LAW(Local Access Window) configuration:
* 0000_0000-8000_0000: Up to 2G DDR
* f000_0000-f3ff_ffff: PCI(256M)
* f400_0000-f7ff_ffff: RapidIO(128M)
* f800_0000-ffff_ffff: localbus(128M)
* f800_0000-fbff_ffff: LBC SDRAM(64M)
* fc00_0000-fcff_ffff: LBC BCSR (1M, Chip select 1)
* fdf0_0000-fdff_ffff: CCSRBAR(1M)
* ff00_0000-ffff_ffff: Flash(16M)
* We don't need a local window for CCSRBAR and flash because they
* reside in their default mapped spaces.
*/
#define LAWBAR0 0
#define LAWAR0 ((LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & LAWAR_SIZE_2G)) & ~LAWAR_EN)
#define LAWBAR1 ((CFG_PCI_MEM_BASE>>12) & 0xfffff)
#define LAWAR1 (LAWAR_EN | LAWAR_TRGT_IF_PCIX | (LAWAR_SIZE & LAWAR_SIZE_256M))
#if !defined(CONFIG_RAM_AS_FLASH)
#define LAWBAR2 ((CFG_LBC_SDRAM_BASE>>12) & 0xfffff)
#define LAWAR2 (LAWAR_EN | LAWAR_TRGT_IF_LBC | (LAWAR_SIZE & LAWAR_SIZE_128M))
#else
#define LAWBAR2 0
#define LAWAR2 ((LAWAR_TRGT_IF_LBC | (LAWAR_SIZE & LAWAR_SIZE_128M)) & ~LAWAR_EN)
#endif
.section .bootpg, "ax"
.globl law_entry
law_entry:
entry_start
.long 0x03
.long LAWBAR0,LAWAR0,LAWBAR1,LAWAR1,LAWBAR2,LAWAR2
entry_end

424
board/stxgp3/stxgp3.c Normal file
View File

@@ -0,0 +1,424 @@
/*
* (C) Copyright 2003, Embedded Edge, LLC
* Dan Malek, <dan@embeddededge.com>
* Copied from ADS85xx.
* Updates for Silicon Tx GP3 8560
*
* (C) Copyright 2003,Motorola Inc.
* Xianghua Xiao, (X.Xiao@motorola.com)
*
* (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.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
*/
extern long int spd_sdram (void);
#include <common.h>
#include <asm/processor.h>
#include <asm/immap_85xx.h>
#include <ioports.h>
#include <asm/io.h>
#include <spd.h>
#include <miiphy.h>
long int fixed_sdram (void);
/*
* I/O Port configuration table
*
* if conf is 1, then that port pin will be configured at boot time
* according to the five values podr/pdir/ppar/psor/pdat for that entry
*/
const iop_conf_t iop_conf_tab[4][32] = {
/* Port A configuration */
{ /* conf ppar psor pdir podr pdat */
/* PA31 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 TxENB */
/* PA30 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 TxClav */
/* PA29 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 TxSOC */
/* PA28 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 RxENB */
/* PA27 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 RxSOC */
/* PA26 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 RxClav */
/* PA25 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[0] */
/* PA24 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[1] */
/* PA23 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[2] */
/* PA22 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[3] */
/* PA21 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[4] */
/* PA20 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[5] */
/* PA19 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[6] */
/* PA18 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[7] */
/* PA17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[7] */
/* PA16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[6] */
/* PA15 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[5] */
/* PA14 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[4] */
/* PA13 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[3] */
/* PA12 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[2] */
/* PA11 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[1] */
/* PA10 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[0] */
/* PA9 */ { 0, 1, 1, 1, 0, 0 }, /* FCC1 L1TXD */
/* PA8 */ { 0, 1, 1, 0, 0, 0 }, /* FCC1 L1RXD */
/* PA7 */ { 0, 0, 0, 1, 0, 0 }, /* PA7 */
/* PA6 */ { 0, 1, 1, 1, 0, 0 }, /* TDM A1 L1RSYNC */
/* PA5 */ { 0, 0, 0, 1, 0, 0 }, /* PA5 */
/* PA4 */ { 0, 0, 0, 1, 0, 0 }, /* PA4 */
/* PA3 */ { 0, 0, 0, 1, 0, 0 }, /* PA3 */
/* PA2 */ { 0, 0, 0, 1, 0, 0 }, /* PA2 */
/* PA1 */ { 1, 0, 0, 0, 0, 0 }, /* FREERUN */
/* PA0 */ { 0, 0, 0, 1, 0, 0 } /* PA0 */
},
/* Port B configuration */
{ /* conf ppar psor pdir podr pdat */
/* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */
/* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */
/* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */
/* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */
/* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */
/* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */
/* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */
/* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */
/* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */
/* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */
/* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */
/* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */
/* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */
/* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */
/* PB17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RX_DIV */
/* PB16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RX_ERR */
/* PB15 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TX_ERR */
/* PB14 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TX_EN */
/* PB13 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:COL */
/* PB12 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:CRS */
/* PB11 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
/* PB10 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
/* PB9 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
/* PB8 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
/* PB7 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
/* PB6 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
/* PB5 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
/* PB4 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
/* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
},
/* Port C */
{ /* conf ppar psor pdir podr pdat */
/* PC31 */ { 0, 0, 0, 1, 0, 0 }, /* PC31 */
/* PC30 */ { 0, 0, 0, 1, 0, 0 }, /* PC30 */
/* PC29 */ { 0, 1, 1, 0, 0, 0 }, /* SCC1 EN *CLSN */
/* PC28 */ { 0, 0, 0, 1, 0, 0 }, /* PC28 */
/* PC27 */ { 0, 0, 0, 1, 0, 0 }, /* UART Clock in */
/* PC26 */ { 0, 0, 0, 1, 0, 0 }, /* PC26 */
/* PC25 */ { 0, 0, 0, 1, 0, 0 }, /* PC25 */
/* PC24 */ { 0, 0, 0, 1, 0, 0 }, /* PC24 */
/* PC23 */ { 0, 1, 0, 1, 0, 0 }, /* ATMTFCLK */
/* PC22 */ { 0, 1, 0, 0, 0, 0 }, /* ATMRFCLK */
/* PC21 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN RXCLK */
/* PC20 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN TXCLK */
/* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK CLK13 */
/* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC Tx Clock (CLK14) */
/* PC17 */ { 0, 0, 0, 1, 0, 0 }, /* PC17 */
/* PC16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC Tx Clock (CLK16) */
/* PC15 */ { 0, 1, 0, 0, 0, 0 }, /* PC15 */
/* PC14 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN *CD */
/* PC13 */ { 0, 0, 0, 1, 0, 0 }, /* PC13 */
/* PC12 */ { 0, 1, 0, 1, 0, 0 }, /* PC12 */
/* PC11 */ { 0, 0, 0, 1, 0, 0 }, /* LXT971 transmit control */
/* PC10 */ { 0, 0, 0, 1, 0, 0 }, /* FETHMDC */
/* PC9 */ { 0, 0, 0, 0, 0, 0 }, /* FETHMDIO */
/* PC8 */ { 0, 0, 0, 1, 0, 0 }, /* PC8 */
/* PC7 */ { 0, 0, 0, 1, 0, 0 }, /* PC7 */
/* PC6 */ { 0, 0, 0, 1, 0, 0 }, /* PC6 */
/* PC5 */ { 0, 0, 0, 1, 0, 0 }, /* PC5 */
/* PC4 */ { 0, 0, 0, 1, 0, 0 }, /* PC4 */
/* PC3 */ { 0, 0, 0, 1, 0, 0 }, /* PC3 */
/* PC2 */ { 0, 0, 0, 1, 0, 1 }, /* ENET FDE */
/* PC1 */ { 0, 0, 0, 1, 0, 0 }, /* ENET DSQE */
/* PC0 */ { 0, 0, 0, 1, 0, 0 }, /* ENET LBK */
},
/* Port D */
{ /* conf ppar psor pdir podr pdat */
/* PD31 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN RxD */
/* PD30 */ { 0, 1, 1, 1, 0, 0 }, /* SCC1 EN TxD */
/* PD29 */ { 0, 1, 0, 1, 0, 0 }, /* SCC1 EN TENA */
/* PD28 */ { 1, 1, 0, 0, 0, 0 }, /* SCC2 RxD */
/* PD27 */ { 1, 1, 0, 1, 0, 0 }, /* SCC2 TxD */
/* PD26 */ { 0, 0, 0, 1, 0, 0 }, /* PD26 */
/* PD25 */ { 0, 0, 0, 1, 0, 0 }, /* PD25 */
/* PD24 */ { 0, 0, 0, 1, 0, 0 }, /* PD24 */
/* PD23 */ { 0, 0, 0, 1, 0, 0 }, /* PD23 */
/* PD22 */ { 0, 0, 0, 1, 0, 0 }, /* PD22 */
/* PD21 */ { 0, 0, 0, 1, 0, 0 }, /* PD21 */
/* PD20 */ { 0, 0, 0, 1, 0, 0 }, /* PD20 */
/* PD19 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
/* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD18 */
/* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */
/* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */
/* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */
/* PD14 */ { 1, 1, 1, 0, 0, 0 }, /* I2C CLK */
/* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* PD13 */
/* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* PD12 */
/* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* PD11 */
/* PD10 */ { 0, 0, 0, 0, 0, 0 }, /* PD10 */
/* PD9 */ { 0, 1, 0, 1, 0, 0 }, /* SMC1 TXD */
/* PD8 */ { 0, 1, 0, 0, 0, 0 }, /* SMC1 RXD */
/* PD7 */ { 0, 0, 0, 1, 0, 1 }, /* PD7 */
/* PD6 */ { 0, 0, 0, 1, 0, 1 }, /* PD6 */
/* PD5 */ { 0, 0, 0, 1, 0, 1 }, /* PD5 */
/* PD4 */ { 0, 0, 0, 1, 0, 1 }, /* PD4 */
/* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
}
};
static uint64_t blinky_increment;
static uint64_t next_led_update;
static uint led_bit;
int board_pre_init (void)
{
#if defined(CONFIG_PCI)
volatile immap_t *immr = (immap_t *)CFG_IMMR;
volatile ccsr_pcix_t *pci = &immr->im_pcix;
pci->peer &= 0xfffffffdf; /* disable master abort */
#endif
return 0;
}
void reset_phy (void)
{
volatile uint *blatch;
blatch = (volatile uint *)CFG_LBC_LCLDEVS_BASE;
/* reset Giga bit Ethernet port if needed here */
*blatch &= ~0x000000c0;
udelay(100);
*blatch = 0x000000c1; /* Light one led, too */
udelay(1000);
#if 0 /* This is the port we really want to use for debugging. */
/* reset the CPM FEC port */
#if (CONFIG_ETHER_INDEX == 2)
bcsr->bcsr2 &= ~FETH2_RST;
udelay(2);
bcsr->bcsr2 |= FETH2_RST;
udelay(1000);
#elif (CONFIG_ETHER_INDEX == 3)
bcsr->bcsr3 &= ~FETH3_RST;
udelay(2);
bcsr->bcsr3 |= FETH3_RST;
udelay(1000);
#endif
#if defined(CONFIG_MII) && defined(CONFIG_ETHER_ON_FCC)
miiphy_reset(0x0); /* reset PHY */
miiphy_write(0, PHY_MIPSCR, 0xf028); /* change PHY address to 0x02 */
miiphy_write(0x02, PHY_BMCR, PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
#endif /* CONFIG_MII */
#endif
}
int checkboard (void)
{
sys_info_t sysinfo;
get_sys_info (&sysinfo);
printf ("Board: Silicon Tx GPPP 8560 Board\n");
printf ("\tCPU: %lu MHz\n", sysinfo.freqProcessor / 1000000);
printf ("\tCCB: %lu MHz\n", sysinfo.freqSystemBus / 1000000);
printf ("\tDDR: %lu MHz\n", sysinfo.freqSystemBus / 2000000);
if((CFG_LBC_LCRR & 0x0f) == 2 || (CFG_LBC_LCRR & 0x0f) == 4 \
|| (CFG_LBC_LCRR & 0x0f) == 8) {
printf ("\tLBC: %lu MHz\n", sysinfo.freqSystemBus / 1000000 /(CFG_LBC_LCRR & 0x0f));
} else {
printf("\tLBC: unknown\n");
}
printf("\tCPM: %lu Mhz\n", sysinfo.freqSystemBus / 1000000);
printf("L1 D-cache 32KB, L1 I-cache 32KB enabled.\n");
return (0);
}
/* Blinkin' LEDS for Robert.
*/
void
show_activity(int flag)
{
volatile uint *blatch;
if (next_led_update > get_ticks())
return;
blatch = (volatile uint *)CFG_LBC_LCLDEVS_BASE;
led_bit >>= 1;
if (led_bit == 0)
led_bit = 0x08;
*blatch = (0xc0 | led_bit);
eieio();
next_led_update += (get_tbclk() / 4);
}
long int initdram (int board_type)
{
long dram_size = 0;
extern long spd_sdram (void);
volatile immap_t *immap = (immap_t *)CFG_IMMR;
#if defined(CONFIG_DDR_DLL)
volatile ccsr_gur_t *gur= &immap->im_gur;
uint temp_ddrdll = 0;
/* Work around to stabilize DDR DLL */
temp_ddrdll = gur->ddrdllcr;
gur->ddrdllcr = ((temp_ddrdll & 0xff) << 16) | 0x80000000;
asm("sync;isync;msync");
#endif
dram_size = spd_sdram ();
#if defined(CONFIG_DDR_ECC)
{
/* Initialize all of memory for ECC, then
* enable errors */
uint *p = 0;
uint i = 0;
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile ccsr_ddr_t *ddr= &immap->im_ddr;
dma_init();
for (*p = 0; p < (uint *)(8 * 1024); p++) {
if (((unsigned int)p & 0x1f) == 0) { dcbz(p); }
*p = (unsigned int)0xdeadbeef;
if (((unsigned int)p & 0x1c) == 0x1c) { dcbf(p); }
}
/* 8K */
dma_xfer((uint *)0x2000,0x2000,(uint *)0);
/* 16K */
dma_xfer((uint *)0x4000,0x4000,(uint *)0);
/* 32K */
dma_xfer((uint *)0x8000,0x8000,(uint *)0);
/* 64K */
dma_xfer((uint *)0x10000,0x10000,(uint *)0);
/* 128k */
dma_xfer((uint *)0x20000,0x20000,(uint *)0);
/* 256k */
dma_xfer((uint *)0x40000,0x40000,(uint *)0);
/* 512k */
dma_xfer((uint *)0x80000,0x80000,(uint *)0);
/* 1M */
dma_xfer((uint *)0x100000,0x100000,(uint *)0);
/* 2M */
dma_xfer((uint *)0x200000,0x200000,(uint *)0);
/* 4M */
dma_xfer((uint *)0x400000,0x400000,(uint *)0);
for (i = 1; i < dram_size / 0x800000; i++) {
dma_xfer((uint *)(0x800000*i),0x800000,(uint *)0);
}
/* Enable errors for ECC */
ddr->err_disable = 0x00000000;
asm("sync;isync;msync");
}
#endif
return dram_size;
}
#if defined(CFG_DRAM_TEST)
int testdram (void)
{
uint *pstart = (uint *) CFG_MEMTEST_START;
uint *pend = (uint *) CFG_MEMTEST_END;
uint *p;
printf("SDRAM test phase 1:\n");
for (p = pstart; p < pend; p++)
*p = 0xaaaaaaaa;
for (p = pstart; p < pend; p++) {
if (*p != 0xaaaaaaaa) {
printf ("SDRAM test fails at: %08x\n", (uint) p);
return 1;
}
}
printf("SDRAM test phase 2:\n");
for (p = pstart; p < pend; p++)
*p = 0x55555555;
for (p = pstart; p < pend; p++) {
if (*p != 0x55555555) {
printf ("SDRAM test fails at: %08x\n", (uint) p);
return 1;
}
}
printf("SDRAM test passed.\n");
return 0;
}
#endif
#if !defined(CONFIG_SPD_EEPROM)
/*************************************************************************
* fixed sdram init -- doesn't use serial presence detect.
************************************************************************/
long int fixed_sdram (void)
{
#ifndef CFG_RAMBOOT
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile ccsr_ddr_t *ddr= &immap->im_ddr;
ddr->cs0_bnds = CFG_DDR_CS0_BNDS;
ddr->cs0_config = CFG_DDR_CS0_CONFIG;
ddr->timing_cfg_1 = CFG_DDR_TIMING_1;
ddr->timing_cfg_2 = CFG_DDR_TIMING_2;
ddr->sdram_mode = CFG_DDR_MODE;
ddr->sdram_interval = CFG_DDR_INTERVAL;
#if defined (CONFIG_DDR_ECC)
ddr->err_disable = 0x0000000D;
ddr->err_sbe = 0x00ff0000;
#endif
asm("sync;isync;msync");
udelay(500);
#if defined (CONFIG_DDR_ECC)
/* Enable ECC checking */
ddr->sdram_cfg = (CFG_DDR_CONTROL | 0x20000000);
#else
ddr->sdram_cfg = CFG_DDR_CONTROL;
#endif
asm("sync; isync; msync");
udelay(500);
#endif
return ( CFG_SDRAM_SIZE * 1024 * 1024);
}
#endif /* !defined(CONFIG_SPD_EEPROM) */

157
board/stxgp3/u-boot.lds Normal file
View File

@@ -0,0 +1,157 @@
/*
* (C) Copyright 2003 Embedded Edge, LLC
* Dan Malek, <dan@embeddededge.com>
* Copied from ADS85xx.
* Updates for Silicon Tx GP3 8560.
*
* (C) Copyright 2002,2003,Motorola,Inc.
* Xianghua Xiao, X.Xiao@motorola.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
*/
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
.bootpg 0xFFFFF000 :
{
cpu/mpc85xx/start.o (.bootpg)
board/stxgp3/init.o (.bootpg)
} = 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 :
{
cpu/mpc85xx/start.o (.text)
board/stxgp3/init.o (.text)
cpu/mpc85xx/commproc.o (.text)
cpu/mpc85xx/traps.o (.text)
cpu/mpc85xx/interrupts.o (.text)
cpu/mpc85xx/serial_scc.o (.text)
cpu/mpc85xx/ether_fcc.o (.text)
cpu/mpc85xx/cpu_init.o (.text)
cpu/mpc85xx/cpu.o (.text)
cpu/mpc85xx/tsec.o (.text)
cpu/mpc85xx/speed.o (.text)
cpu/mpc85xx/i2c.o (.text)
cpu/mpc85xx/spd_sdram.o (.text)
common/dlmalloc.o (.text)
lib_generic/crc32.o (.text)
lib_ppc/extable.o (.text)
lib_generic/zlib.o (.text)
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
*(.rodata.str1.4)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x00FF) & 0xFFFFFF00;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
__fixup_entries = (. - _FIXUP_TABLE_) >> 2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(256);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(256);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

View File

@@ -48,35 +48,30 @@ int checkboard(void)
long int initdram(int board_type)
{
#if 1
long size;
long new_bank0_end;
long new_bank1_end;
long mear1;
long emear1;
/*
write_bat(IBAT1, ((CFG_MAX_RAM_SIZE/2) | BATU_BL_256M | BATU_VS | BATU_VP),
( (CFG_MAX_RAM_SIZE/2)| BATL_PP_10 | BATL_MEMCOHERENCE));
write_bat(DBAT1, ((CFG_MAX_RAM_SIZE/2) | BATU_BL_256M | BATU_VS | BATU_VP),
( (CFG_MAX_RAM_SIZE/2)| BATL_PP_10 | BATL_MEMCOHERENCE));
*/
size = get_ram_size(CFG_SDRAM_BASE, CFG_MAX_RAM_SIZE);
new_bank0_end = size - 1;
new_bank0_end = size/2 - 1;
new_bank1_end = size - 1;
mear1 = mpc824x_mpc107_getreg(MEAR1);
emear1 = mpc824x_mpc107_getreg(EMEAR1);
mear1 = (mear1 & 0xFFFFFF00) |
((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
emear1 = (emear1 & 0xFFFFFF00) |
((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
mear1 = (mear1 & 0xFFFF0000) |
((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) |
((new_bank1_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT << 8);
emear1 = (emear1 & 0xFFFF0000) |
((new_bank0_end & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) |
((new_bank1_end & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT << 8);
mpc824x_mpc107_setreg(MEAR1, mear1);
mpc824x_mpc107_setreg(EMEAR1, emear1);
return (size);
#else
return (CFG_MAX_RAM_SIZE);
#endif
}

View File

@@ -242,6 +242,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
if (hdr->ih_arch != IH_CPU_NIOS)
#elif defined(__M68K__)
if (hdr->ih_arch != IH_CPU_M68K)
#elif defined(__microblaze__)
if (hdr->ih_arch != IH_CPU_MICROBLAZE)
#else
# error Unknown CPU type
#endif
@@ -1185,6 +1187,7 @@ print_type (image_header_t *hdr)
case IH_CPU_SPARC: arch = "SPARC"; break;
case IH_CPU_SPARC64: arch = "SPARC 64 Bit"; break;
case IH_CPU_M68K: arch = "M68K"; break;
case IH_CPU_MICROBLAZE: arch = "Microblaze"; break;
default: arch = "Unknown Architecture"; break;
}

View File

@@ -60,6 +60,11 @@ static unsigned long mips_io_port_base = 0;
# define SHOW_BOOT_PROGRESS(arg)
#endif
#ifdef __PPC__
# define EIEIO __asm__ volatile ("eieio")
#else
# define EIEIO /* nothing */
#endif
#undef IDE_DEBUG
@@ -782,15 +787,15 @@ set_pcmcia_timing (int pmode)
/* ------------------------------------------------------------------------- */
#ifdef __PPC__
#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA)
static void __inline__
ide_outb(int dev, int port, unsigned char val)
{
PRINTF ("ide_outb (dev= %d, port= %d, val= 0x%02x) : @ 0x%08lx\n",
PRINTF ("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
dev, port, val, (ATA_CURR_BASE(dev)+port));
/* Ensure I/O operations complete */
__asm__ volatile("eieio");
EIEIO;
*((uchar *)(ATA_CURR_BASE(dev)+port)) = val;
}
#else /* ! __PPC__ */
@@ -802,15 +807,15 @@ ide_outb(int dev, int port, unsigned char val)
#endif /* __PPC__ */
#ifdef __PPC__
#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA)
static unsigned char __inline__
ide_inb(int dev, int port)
{
uchar val;
/* Ensure I/O operations complete */
__asm__ volatile("eieio");
EIEIO;
val = *((uchar *)(ATA_CURR_BASE(dev)+port));
PRINTF ("ide_inb (dev= %d, port= %d) : @ 0x%08lx -> 0x%02x\n",
PRINTF ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n",
dev, port, (ATA_CURR_BASE(dev)+port), val);
return (val);
}
@@ -833,9 +838,9 @@ output_data_short(int dev, ulong *sect_buf, int words)
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
while (words--) {
__asm__ volatile ("eieio");
EIEIO;
*pbuf = *dbuf++;
__asm__ volatile ("eieio");
EIEIO;
}
if (words&1)
@@ -856,6 +861,8 @@ input_swap_data(int dev, ulong *sect_buf, int words)
volatile ushort *pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
ushort *dbuf = (ushort *)sect_buf;
PRINTF("in input swap data base for read is %lx\n", (unsigned long) pbuf);
while (words--) {
*dbuf++ = ld_le16(pbuf);
*dbuf++ = ld_le16(pbuf);
@@ -878,7 +885,7 @@ input_swap_data(int dev, ulong *sect_buf, int words)
#endif /* __LITTLE_ENDIAN || CONFIG_AU1X00 */
#ifdef __PPC__
#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA)
static void
output_data(int dev, ulong *sect_buf, int words)
{
@@ -889,9 +896,9 @@ output_data(int dev, ulong *sect_buf, int words)
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
while (words--) {
__asm__ volatile ("eieio");
EIEIO;
*pbuf = *dbuf++;
__asm__ volatile ("eieio");
EIEIO;
*pbuf = *dbuf++;
}
#else /* CONFIG_HMI10 */
@@ -903,13 +910,13 @@ output_data(int dev, ulong *sect_buf, int words)
pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD);
dbuf = (uchar *)sect_buf;
while (words--) {
__asm__ volatile ("eieio");
EIEIO;
*pbuf_even = *dbuf++;
__asm__ volatile ("eieio");
EIEIO;
*pbuf_odd = *dbuf++;
__asm__ volatile ("eieio");
EIEIO;
*pbuf_even = *dbuf++;
__asm__ volatile ("eieio");
EIEIO;
*pbuf_odd = *dbuf++;
}
#endif /* CONFIG_HMI10 */
@@ -922,7 +929,7 @@ output_data(int dev, ulong *sect_buf, int words)
}
#endif /* __PPC__ */
#ifdef __PPC__
#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA)
static void
input_data(int dev, ulong *sect_buf, int words)
{
@@ -932,10 +939,13 @@ input_data(int dev, ulong *sect_buf, int words)
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
PRINTF("in input data base for read is %lx\n", (unsigned long) pbuf);
while (words--) {
__asm__ volatile ("eieio");
EIEIO;
*dbuf++ = *pbuf;
__asm__ volatile ("eieio");
EIEIO;
*dbuf++ = *pbuf;
}
#else /* CONFIG_HMI10 */
@@ -947,13 +957,13 @@ 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--) {
__asm__ volatile ("eieio");
EIEIO;
*dbuf++ = *pbuf_even;
__asm__ volatile ("eieio");
EIEIO;
*dbuf++ = *pbuf_odd;
__asm__ volatile ("eieio");
EIEIO;
*dbuf++ = *pbuf_even;
__asm__ volatile ("eieio");
EIEIO;
*dbuf++ = *pbuf_odd;
}
#endif /* CONFIG_HMI10 */
@@ -977,9 +987,9 @@ input_data_short(int dev, ulong *sect_buf, int words)
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
while (words--) {
__asm__ volatile ("eieio");
EIEIO;
*dbuf++ = *pbuf;
__asm__ volatile ("eieio");
EIEIO;
}
if (words&1) {
@@ -1169,13 +1179,12 @@ static void ide_ident (block_dev_desc_t *dev_desc)
#ifdef CONFIG_LBA48
if (iop->command_set_2 & 0x0400) { /* LBA 48 support */
dev_desc->lba48support = 1;
dev_desc->lba48 = (unsigned long long)iop->lba48_capacity[0] |
dev_desc->lba48 = 1;
dev_desc->lba = (unsigned long long)iop->lba48_capacity[0] |
((unsigned long long)iop->lba48_capacity[1] << 16) |
((unsigned long long)iop->lba48_capacity[2] << 32) |
((unsigned long long)iop->lba48_capacity[3] << 48);
} else {
dev_desc->lba48support = 0;
dev_desc->lba48 = 0;
}
#endif /* CONFIG_LBA48 */
@@ -1576,7 +1585,7 @@ static void ide_led (uchar led, uchar status)
#define AT_PRINTF(fmt,args...)
#endif
#ifdef __PPC__
#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA)
/* since ATAPI may use commands with not 4 bytes alligned length
* we have our own transfer functions, 2 bytes alligned */
static void
@@ -1588,8 +1597,11 @@ output_data_shorts(int dev, ushort *sect_buf, int shorts)
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
PRINTF("in output data shorts base for read is %lx\n", (unsigned long) pbuf);
while (shorts--) {
__asm__ volatile ("eieio");
EIEIO;
*pbuf = *dbuf++;
}
#else /* CONFIG_HMI10 */
@@ -1600,9 +1612,9 @@ output_data_shorts(int dev, ushort *sect_buf, int shorts)
pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN);
pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD);
while (shorts--) {
__asm__ volatile ("eieio");
EIEIO;
*pbuf_even = *dbuf++;
__asm__ volatile ("eieio");
EIEIO;
*pbuf_odd = *dbuf++;
}
#endif /* CONFIG_HMI10 */
@@ -1617,8 +1629,11 @@ input_data_shorts(int dev, ushort *sect_buf, int shorts)
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
PRINTF("in input data shorts base for read is %lx\n", (unsigned long) pbuf);
while (shorts--) {
__asm__ volatile ("eieio");
EIEIO;
*dbuf++ = *pbuf;
}
#else /* CONFIG_HMI10 */
@@ -1629,9 +1644,9 @@ input_data_shorts(int dev, ushort *sect_buf, int shorts)
pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN);
pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD);
while (shorts--) {
__asm__ volatile ("eieio");
EIEIO;
*dbuf++ = *pbuf_even;
__asm__ volatile ("eieio");
EIEIO;
*dbuf++ = *pbuf_odd;
}
#endif /* CONFIG_HMI10 */

View File

@@ -49,6 +49,8 @@ static int part_num=0;
static struct part_info part;
#ifndef CONFIG_JFFS2_NAND
struct part_info*
jffs2_part_info(int part_num)
{
@@ -88,6 +90,33 @@ jffs2_part_info(int part_num)
}
return 0;
}
#else /* CONFIG_JFFS2_NAND */
struct part_info*
jffs2_part_info(int part_num)
{
if(part_num==0){
if(part.usr_priv==(void*)1)
return &part;
memset(&part, 0, sizeof(part));
part.offset = CONFIG_JFFS2_NAND_OFF;
part.size = CONFIG_JFFS2_NAND_SIZE; /* the bigger size the slower jffs2 */
#ifndef CONFIG_JFFS2_NAND_DEV
#define CONFIG_JFFS2_NAND_DEV 0
#endif
/* nand device with the JFFS2 parition plus 1 */
part.usr_priv = (void*)(CONFIG_JFFS2_NAND_DEV+1);
return &part;
}
return 0;
}
#endif /* CONFIG_JFFS2_NAND */
#endif /* ifndef CFG_JFFS_CUSTOM_PART */
int

View File

@@ -963,6 +963,8 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])
return 0;
}
#ifndef CONFIG_CRC32_VERIFY
int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong addr, length;
@@ -992,6 +994,62 @@ int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 0;
}
#else /* CONFIG_CRC32_VERIFY */
int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong addr, length;
ulong crc;
ulong *ptr;
ulong vcrc;
int verify;
int ac;
char **av;
if (argc < 3) {
usage:
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
av = argv + 1;
ac = argc - 1;
if (strcmp(*av, "-v") == 0) {
verify = 1;
av++;
ac--;
if (ac < 3)
goto usage;
} else
verify = 0;
addr = simple_strtoul(*av++, NULL, 16);
addr += base_address;
length = simple_strtoul(*av++, NULL, 16);
crc = crc32(0, (const uchar *) addr, length);
if (!verify) {
printf ("CRC32 for %08lx ... %08lx ==> %08lx\n",
addr, addr + length - 1, crc);
if (ac > 2) {
ptr = (ulong *) simple_strtoul (*av++, NULL, 16);
*ptr = crc;
}
} else {
vcrc = simple_strtoul(*av++, NULL, 16);
if (vcrc != crc) {
printf ("CRC32 for %08lx ... %08lx ==> %08lx != %08lx ** ERROR **\n",
addr, addr + length - 1, crc, vcrc);
return 1;
}
}
return 0;
}
#endif /* CONFIG_CRC32_VERIFY */
/**************************************************/
#if (CONFIG_COMMANDS & CFG_CMD_MEMORY)
U_BOOT_CMD(
@@ -1032,12 +1090,25 @@ U_BOOT_CMD(
"[.b, .w, .l] addr1 addr2 count\n - compare memory\n"
);
#ifndef CONFIG_CRC32_VERIFY
U_BOOT_CMD(
crc32, 4, 1, do_mem_crc,
"crc32 - checksum calculation\n",
"address count [addr]\n - compute CRC32 checksum [save at addr]\n"
);
#else /* CONFIG_CRC32_VERIFY */
U_BOOT_CMD(
crc32, 5, 1, do_mem_crc,
"crc32 - checksum calculation\n",
"address count [addr]\n - compute CRC32 checksum [save at addr]\n"
"-v address count crc\n - verify crc of memory area\n"
);
#endif /* CONFIG_CRC32_VERIFY */
U_BOOT_CMD(
base, 2, 1, do_mem_base,
"base - print or set address offset\n",

View File

@@ -27,10 +27,13 @@
#include <common.h>
#include <command.h>
#include <miiphy.h>
#if (CONFIG_COMMANDS & CFG_CMD_MII)
#include <miiphy.h>
#define CONFIG_TERSE_MII /* XXX necessary here because "miivals.h" is missing */
#ifdef CONFIG_TERSE_MII
/*
* Display values from last command.
*/
@@ -144,5 +147,419 @@ U_BOOT_CMD(
"mii write <addr> <reg> <data> - write MII PHY <addr> register <reg>\n"
);
#else /* ! CONFIG_TERSE_MII ================================================= */
#include <miivals.h>
typedef struct _MII_reg_desc_t {
ushort regno;
char * name;
} MII_reg_desc_t;
MII_reg_desc_t reg_0_5_desc_tbl[] = {
{ 0, "PHY control register" },
{ 1, "PHY status register" },
{ 2, "PHY ID 1 register" },
{ 3, "PHY ID 2 register" },
{ 4, "Autonegotiation advertisement register" },
{ 5, "Autonegotiation partner abilities register" },
};
typedef struct _MII_field_desc_t {
ushort hi;
ushort lo;
ushort mask;
char * name;
} MII_field_desc_t;
MII_field_desc_t reg_0_desc_tbl[] = {
{ 15, 15, 0x01, "reset" },
{ 14, 14, 0x01, "loopback" },
{ 13, 6, 0x81, "speed selection" }, /* special */
{ 12, 12, 0x01, "A/N enable" },
{ 11, 11, 0x01, "power-down" },
{ 10, 10, 0x01, "isolate" },
{ 9, 9, 0x01, "restart A/N" },
{ 8, 8, 0x01, "duplex" }, /* special */
{ 7, 7, 0x01, "collision test enable" },
{ 5, 0, 0x3f, "(reserved)" }
};
MII_field_desc_t reg_1_desc_tbl[] = {
{ 15, 15, 0x01, "100BASE-T4 able" },
{ 14, 14, 0x01, "100BASE-X full duplex able" },
{ 13, 13, 0x01, "100BASE-X half duplex able" },
{ 12, 12, 0x01, "10 Mbps full duplex able" },
{ 11, 11, 0x01, "10 Mbps half duplex able" },
{ 10, 10, 0x01, "100BASE-T2 full duplex able" },
{ 9, 9, 0x01, "100BASE-T2 half duplex able" },
{ 8, 8, 0x01, "extended status" },
{ 7, 7, 0x01, "(reserved)" },
{ 6, 6, 0x01, "MF preamble suppression" },
{ 5, 5, 0x01, "A/N complete" },
{ 4, 4, 0x01, "remote fault" },
{ 3, 3, 0x01, "A/N able" },
{ 2, 2, 0x01, "link status" },
{ 1, 1, 0x01, "jabber detect" },
{ 0, 0, 0x01, "extended capabilities" },
};
MII_field_desc_t reg_2_desc_tbl[] = {
{ 15, 0, 0xffff, "OUI portion" },
};
MII_field_desc_t reg_3_desc_tbl[] = {
{ 15, 10, 0x3f, "OUI portion" },
{ 9, 4, 0x3f, "manufacturer part number" },
{ 3, 0, 0x0f, "manufacturer rev. number" },
};
MII_field_desc_t reg_4_desc_tbl[] = {
{ 15, 15, 0x01, "next page able" },
{ 14, 14, 0x01, "reserved" },
{ 13, 13, 0x01, "remote fault" },
{ 12, 12, 0x01, "reserved" },
{ 11, 11, 0x01, "asymmetric pause" },
{ 10, 10, 0x01, "pause enable" },
{ 9, 9, 0x01, "100BASE-T4 able" },
{ 8, 8, 0x01, "100BASE-TX full duplex able" },
{ 7, 7, 0x01, "100BASE-TX able" },
{ 6, 6, 0x01, "10BASE-T full duplex able" },
{ 5, 5, 0x01, "10BASE-T able" },
{ 4, 0, 0x1f, "xxx to do" },
};
MII_field_desc_t reg_5_desc_tbl[] = {
{ 15, 15, 0x01, "next page able" },
{ 14, 14, 0x01, "acknowledge" },
{ 13, 13, 0x01, "remote fault" },
{ 12, 12, 0x01, "(reserved)" },
{ 11, 11, 0x01, "asymmetric pause able" },
{ 10, 10, 0x01, "pause able" },
{ 9, 9, 0x01, "100BASE-T4 able" },
{ 8, 8, 0x01, "100BASE-X full duplex able" },
{ 7, 7, 0x01, "100BASE-TX able" },
{ 6, 6, 0x01, "10BASE-T full duplex able" },
{ 5, 5, 0x01, "10BASE-T able" },
{ 4, 0, 0x1f, "xxx to do" },
};
#define DESC0LEN (sizeof(reg_0_desc_tbl)/sizeof(reg_0_desc_tbl[0]))
#define DESC1LEN (sizeof(reg_1_desc_tbl)/sizeof(reg_1_desc_tbl[0]))
#define DESC2LEN (sizeof(reg_2_desc_tbl)/sizeof(reg_2_desc_tbl[0]))
#define DESC3LEN (sizeof(reg_3_desc_tbl)/sizeof(reg_3_desc_tbl[0]))
#define DESC4LEN (sizeof(reg_4_desc_tbl)/sizeof(reg_4_desc_tbl[0]))
#define DESC5LEN (sizeof(reg_5_desc_tbl)/sizeof(reg_5_desc_tbl[0]))
typedef struct _MII_field_desc_and_len_t {
MII_field_desc_t * pdesc;
ushort len;
} MII_field_desc_and_len_t;
MII_field_desc_and_len_t desc_and_len_tbl[] = {
{ reg_0_desc_tbl, DESC0LEN },
{ reg_1_desc_tbl, DESC1LEN },
{ reg_2_desc_tbl, DESC2LEN },
{ reg_3_desc_tbl, DESC3LEN },
{ reg_4_desc_tbl, DESC4LEN },
{ reg_5_desc_tbl, DESC5LEN },
};
static void dump_reg(
ushort regval,
MII_reg_desc_t * prd,
MII_field_desc_and_len_t * pdl);
static int special_field(
ushort regno,
MII_field_desc_t * pdesc,
ushort regval);
void MII_dump_0_to_5(
ushort regvals[6],
uchar reglo,
uchar reghi)
{
ulong i;
for (i = 0; i < 6; i++) {
if ((reglo <= i) && (i <= reghi))
dump_reg(regvals[i], &reg_0_5_desc_tbl[i],
&desc_and_len_tbl[i]);
}
}
static void dump_reg(
ushort regval,
MII_reg_desc_t * prd,
MII_field_desc_and_len_t * pdl)
{
ulong i;
ushort mask_in_place;
MII_field_desc_t * pdesc;
printf("%u. (%04hx) -- %s --\n",
prd->regno, regval, prd->name);
for (i = 0; i < pdl->len; i++) {
pdesc = &pdl->pdesc[i];
mask_in_place = pdesc->mask << pdesc->lo;
printf(" (%04hx:%04hx) %u.",
mask_in_place,
regval & mask_in_place,
prd->regno);
if (special_field(prd->regno, pdesc, regval)) {
}
else {
if (pdesc->hi == pdesc->lo)
printf("%2u ", pdesc->lo);
else
printf("%2u-%2u", pdesc->hi, pdesc->lo);
printf(" = %5u %s",
(regval & mask_in_place) >> pdesc->lo,
pdesc->name);
}
printf("\n");
}
printf("\n");
}
/* Special fields:
** 0.6,13
** 0.8
** 2.15-0
** 3.15-0
** 4.4-0
** 5.4-0
*/
static int special_field(
ushort regno,
MII_field_desc_t * pdesc,
ushort regval)
{
if ((regno == 0) && (pdesc->lo == 6)) {
ushort speed_bits = regval & MII_CTL_SPEED_MASK;
printf("%2u,%2u = b%u%u speed selection = %s Mbps",
6, 13,
(regval >> 6) & 1,
(regval >> 13) & 1,
speed_bits == MII_CTL_SPEED_1000_MBPS ? "1000" :
speed_bits == MII_CTL_SPEED_100_MBPS ? "100" :
speed_bits == MII_CTL_SPEED_10_MBPS ? "10" :
"???");
return 1;
}
else if ((regno == 0) && (pdesc->lo == 8)) {
printf("%2u = %5u duplex = %s",
pdesc->lo,
(regval >> pdesc->lo) & 1,
((regval >> pdesc->lo) & 1) ? "full" : "half");
return 1;
}
else if ((regno == 4) && (pdesc->lo == 0)) {
ushort sel_bits = (regval >> pdesc->lo) & pdesc->mask;
printf("%2u-%2u = %5u selector = %s",
pdesc->hi, pdesc->lo, sel_bits,
sel_bits == MII_AN_ADV_IEEE_802_3 ?
"IEEE 802.3" :
sel_bits == MII_AN_ADV_IEEE_802_9_ISLAN_16T ?
"IEEE 802.9 ISLAN-16T" :
"???");
return 1;
}
else if ((regno == 5) && (pdesc->lo == 0)) {
ushort sel_bits = (regval >> pdesc->lo) & pdesc->mask;
printf("%2u-%2u = %u selector = %s",
pdesc->hi, pdesc->lo, sel_bits,
sel_bits == MII_AN_PARTNER_IEEE_802_3 ?
"IEEE 802.3" :
sel_bits == MII_AN_PARTNER_IEEE_802_9_ISLAN_16T ?
"IEEE 802.9 ISLAN-16T" :
"???");
return 1;
}
return 0;
}
uint last_op;
uint last_data;
uint last_addr_lo;
uint last_addr_hi;
uint last_reg_lo;
uint last_reg_hi;
static void extract_range(
char * input,
unsigned char * plo,
unsigned char * phi)
{
char * end;
*plo = simple_strtoul(input, &end, 16);
if (*end == '-') {
end++;
*phi = simple_strtoul(end, NULL, 16);
}
else {
*phi = *plo;
}
}
/* ---------------------------------------------------------------- */
int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
char op;
unsigned char addrlo, addrhi, reglo, reghi;
unsigned char addr, reg;
unsigned short data;
int rcode = 0;
#ifdef CONFIG_8xx
mii_init ();
#endif
/*
* We use the last specified parameters, unless new ones are
* entered.
*/
op = last_op;
addrlo = last_addr_lo;
addrhi = last_addr_hi;
reglo = last_reg_lo;
reghi = last_reg_hi;
data = last_data;
if ((flag & CMD_FLAG_REPEAT) == 0) {
op = argv[1][0];
if (argc >= 3)
extract_range(argv[2], &addrlo, &addrhi);
if (argc >= 4)
extract_range(argv[3], &reglo, &reghi);
if (argc >= 5)
data = simple_strtoul (argv[4], NULL, 16);
}
/*
* check info/read/write.
*/
if (op == 'i') {
unsigned char j, start, end;
unsigned int oui;
unsigned char model;
unsigned char rev;
/*
* Look for any and all PHYs. Valid addresses are 0..31.
*/
if (argc >= 3) {
start = addr; end = addr + 1;
} else {
start = 0; end = 32;
}
for (j = start; j < end; j++) {
if (miiphy_info (j, &oui, &model, &rev) == 0) {
printf("PHY 0x%02X: "
"OUI = 0x%04X, "
"Model = 0x%02X, "
"Rev = 0x%02X, "
"%3dbaseT, %s\n",
j, oui, model, rev,
miiphy_speed (j),
miiphy_duplex (j) == FULL ? "FDX" : "HDX");
}
}
} else if (op == 'r') {
for (addr = addrlo; addr <= addrhi; addr++) {
for (reg = reglo; reg <= reghi; reg++) {
data = 0xffff;
if (miiphy_read (addr, reg, &data) != 0) {
printf(
"Error reading from the PHY addr=%02x reg=%02x\n",
addr, reg);
rcode = 1;
}
else {
if ((addrlo != addrhi) || (reglo != reghi))
printf("addr=%02x reg=%02x data=",
(uint)addr, (uint)reg);
printf("%04X\n", data & 0x0000FFFF);
}
}
if ((addrlo != addrhi) && (reglo != reghi))
printf("\n");
}
} else if (op == 'w') {
for (addr = addrlo; addr <= addrhi; addr++) {
for (reg = reglo; reg <= reghi; reg++) {
if (miiphy_write (addr, reg, data) != 0) {
printf("Error writing to the PHY addr=%02x reg=%02x\n",
addr, reg);
rcode = 1;
}
}
}
} else if (op == 'd') {
ushort regs[6];
int ok = 1;
if ((reglo > 5) || (reghi > 5)) {
printf(
"The MII dump command only formats the "
"standard MII registers, 0-5.\n");
return 1;
}
for (addr = addrlo; addr <= addrhi; addr++) {
for (reg = 0; reg < 6; reg++) {
if (miiphy_read(addr, reg, &regs[reg]) != 0) {
ok = 0;
printf(
"Error reading from the PHY addr=%02x reg=%02x\n",
addr, reg);
rcode = 1;
}
}
if (ok)
MII_dump_0_to_5(regs, reglo, reghi);
printf("\n");
}
} else {
printf("Usage:\n%s\n", cmdtp->usage);
return 1;
}
/*
* Save the parameters for repeats.
*/
last_op = op;
last_addr_lo = addrlo;
last_addr_hi = addrhi;
last_reg_lo = reglo;
last_reg_hi = reghi;
last_data = data;
return rcode;
}
/***************************************************/
U_BOOT_CMD(
mii, 5, 1, do_mii,
"mii - MII utility commands\n",
"info <addr> - display MII PHY info\n"
"mii read <addr> <reg> - read MII PHY <addr> register <reg>\n"
"mii write <addr> <reg> <data> - write MII PHY <addr> register <reg>\n"
"mii dump <addr> <reg> - pretty-print <addr> <reg> (0-5 only)\n"
"Addr and/or reg may be ranges, e.g. 2-7.\n"
);
#endif /* CONFIG_TERSE_MII */
#endif /* CFG_CMD_MII */

View File

@@ -9,6 +9,7 @@
#include <command.h>
#include <malloc.h>
#include <asm/io.h>
#include <watchdog.h>
#ifdef CONFIG_SHOW_BOOT_PROGRESS
# include <status_led.h>
@@ -63,6 +64,7 @@ struct nand_oob_config {
#define NANDRW_READ 0x01
#define NANDRW_WRITE 0x00
#define NANDRW_JFFS2 0x02
#define NANDRW_JFFS2_SKIP 0x04
/*
* Function Prototypes
@@ -207,6 +209,11 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
}
else if (cmdtail && !strncmp(cmdtail, ".jffs2", 2))
cmd |= NANDRW_JFFS2; /* skip bad blocks */
else if (cmdtail && !strncmp(cmdtail, ".jffs2s", 2)) {
cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */
if (cmd & NANDRW_READ)
cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */
}
#ifdef SXNI855T
/* need ".e" same as ".j" for compatibility with older units */
else if (cmdtail && !strcmp(cmdtail, ".e"))
@@ -225,7 +232,7 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
&total, (u_char*)addr);
printf (" %d bytes %s: %s\n", total,
(cmd & NANDRW_READ) ? "read" : "write",
(cmd & NANDRW_READ) ? "read" : "written",
ret ? "ERROR" : "OK");
return ret;
@@ -258,7 +265,7 @@ U_BOOT_CMD(
"nand - NAND sub-system\n",
"info - show available NAND devices\n"
"nand device [dev] - show or set current device\n"
"nand read[.jffs2] addr off size\n"
"nand read[.jffs2[s]] addr off size\n"
"nand write[.jffs2] addr off size - read/write `size' bytes starting\n"
" at offset `off' to/from memory address `addr'\n"
"nand erase [clean] [off size] - erase `size' bytes from\n"
@@ -420,6 +427,7 @@ static void nand_print_bad(struct nand_chip* nand)
* 1: NANDRW_READ read, fail on bad block
* 2: NANDRW_WRITE | NANDRW_JFFS2 write, skip bad blocks
* 3: NANDRW_READ | NANDRW_JFFS2 read, data all 0xff for bad blocks
* 7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks
*/
static int nand_rw (struct nand_chip* nand, int cmd,
size_t start, size_t len,
@@ -450,6 +458,10 @@ static int nand_rw (struct nand_chip* nand, int cmd,
}
continue;
}
else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) {
start += erasesize;
continue;
}
else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
/* skip bad block */
start += erasesize;
@@ -1657,4 +1669,17 @@ static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
}
#endif
#ifdef CONFIG_JFFS2_NAND
int read_jffs2_nand(size_t start, size_t len,
size_t * retlen, u_char * buf, int nanddev)
{
return nand_rw(nand_dev_desc + nanddev, NANDRW_READ | NANDRW_JFFS2,
start, len, retlen, buf);
}
#endif /* CONFIG_JFFS2_NAND */
#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */

View File

@@ -94,52 +94,50 @@ U_BOOT_CMD(
);
#endif /* CFG_CMD_NFS */
static void netboot_update_env(void)
static void netboot_update_env (void)
{
char tmp[16] ;
char tmp[22];
if (NetOurGatewayIP) {
ip_to_string (NetOurGatewayIP, tmp);
setenv("gatewayip", tmp);
}
if (NetOurGatewayIP) {
ip_to_string (NetOurGatewayIP, tmp);
setenv ("gatewayip", tmp);
}
if (NetOurSubnetMask) {
ip_to_string (NetOurSubnetMask, tmp);
setenv("netmask", tmp);
}
if (NetOurSubnetMask) {
ip_to_string (NetOurSubnetMask, tmp);
setenv ("netmask", tmp);
}
if (NetOurHostName[0])
setenv("hostname", NetOurHostName);
if (NetOurHostName[0])
setenv ("hostname", NetOurHostName);
if (NetOurRootPath[0])
setenv("rootpath", NetOurRootPath);
if (NetOurRootPath[0])
setenv ("rootpath", NetOurRootPath);
if (NetOurIP) {
ip_to_string (NetOurIP, tmp);
setenv("ipaddr", tmp);
}
if (NetOurIP) {
ip_to_string (NetOurIP, tmp);
setenv ("ipaddr", tmp);
}
if (NetServerIP) {
ip_to_string (NetServerIP, tmp);
setenv("serverip", tmp);
}
if (NetOurDNSIP) {
ip_to_string (NetOurDNSIP, tmp);
setenv("dnsip", tmp);
}
if (NetServerIP) {
ip_to_string (NetServerIP, tmp);
setenv ("serverip", tmp);
}
if (NetOurDNSIP) {
ip_to_string (NetOurDNSIP, tmp);
setenv ("dnsip", tmp);
}
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS2)
if (NetOurDNS2IP) {
ip_to_string (NetOurDNS2IP, tmp);
setenv("dnsip2", tmp);
}
if (NetOurDNS2IP) {
ip_to_string (NetOurDNS2IP, tmp);
setenv ("dnsip2", tmp);
}
#endif
if (NetOurNISDomain[0])
setenv("domain", NetOurNISDomain);
if (NetOurNISDomain[0])
setenv ("domain", NetOurNISDomain);
}
static int
netboot_common (int proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
{
@@ -238,4 +236,47 @@ U_BOOT_CMD(
);
#endif /* CFG_CMD_PING */
#if (CONFIG_COMMANDS & CFG_CMD_CDP)
static void cdp_update_env(void)
{
char tmp[16];
if (CDPApplianceVLAN != htons(-1)) {
printf("CDP offered appliance VLAN %d\n", ntohs(CDPApplianceVLAN));
VLAN_to_string(CDPApplianceVLAN, tmp);
setenv("vlan", tmp);
NetOurVLAN = CDPApplianceVLAN;
}
if (CDPNativeVLAN != htons(-1)) {
printf("CDP offered native VLAN %d\n", ntohs(CDPNativeVLAN));
VLAN_to_string(CDPNativeVLAN, tmp);
setenv("nvlan", tmp);
NetOurNativeVLAN = CDPNativeVLAN;
}
}
int do_cdp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int r;
r = NetLoop(CDP);
if (r < 0) {
printf("cdp failed; perhaps not a CISCO switch?\n");
return 1;
}
cdp_update_env();
return 0;
}
U_BOOT_CMD(
cdp, 1, 1, do_cdp,
"cdp - Perform CDP network configuration\n",
);
#endif /* CFG_CMD_CDP */
#endif /* CFG_CMD_NET */

View File

@@ -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
@@ -63,6 +63,9 @@
#if defined(CONFIG_LWMON)
#include <i2c.h>
#endif
#ifdef CONFIG_PXA_PCMCIA
#include <asm/arch/pxa-regs.h>
#endif
#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
@@ -86,32 +89,35 @@ static int hardware_disable(int slot);
static int hardware_enable (int slot);
static int voltage_set(int slot, int vcc, int vpp);
#ifndef CONFIG_I82365
#if (! defined(CONFIG_I82365)) && (! defined(CONFIG_PXA_PCMCIA))
static u_int m8xx_get_graycode(u_int size);
#endif /* CONFIG_I82365 */
#endif /* !CONFIG_I82365, !CONFIG_PXA_PCMCIA */
#if 0
static u_int m8xx_get_speed(u_int ns, u_int is_io);
#endif
/* -------------------------------------------------------------------- */
#ifndef CONFIG_PXA_PCMCIA
/* look up table for pgcrx registers */
static u_int *pcmcia_pgcrx[2] = {
&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
};
#define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
#endif /* CONFIG_PXA_PCMCIA */
#endif /* CONFIG_I82365 */
#ifdef CONFIG_IDE_8xx_PCCARD
#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
static void print_funcid (int func);
static void print_fixed (volatile uchar *p);
static int identify (volatile uchar *p);
static int check_ide_device (int slot);
#endif /* CONFIG_IDE_8xx_PCCARD */
#endif /* CONFIG_IDE_8xx_PCCARD, CONFIG_PXA_PCMCIA */
const char *indent = "\t ";
@@ -151,8 +157,7 @@ int pcmcia_on (void)
rc = i82365_init();
if (rc == 0)
{
if (rc == 0) {
rc = check_ide_device(0);
}
@@ -160,6 +165,8 @@ int pcmcia_on (void)
}
#else
#ifndef CONFIG_PXA_PCMCIA
#ifdef CONFIG_HMI10
# define HMI10_FRAM_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(2) | PCMCIA_SL(4))
#endif
@@ -280,8 +287,108 @@ int pcmcia_on (void)
}
return (rc);
}
#endif /* CONFIG_PXA_PCMCIA */
#endif /* CONFIG_I82365 */
#ifdef CONFIG_PXA_PCMCIA
static int hardware_enable (int slot)
{
return 0; /* No hardware to enable */
}
static int hardware_disable(int slot)
{
return 0; /* No hardware to disable */
}
static int voltage_set(int slot, int vcc, int vpp)
{
return 0;
}
void msWait(unsigned msVal)
{
udelay(msVal*1000);
}
int pcmcia_on (void)
{
unsigned int reg_arr[] = {
0x48000028, CFG_MCMEM0_VAL,
0x4800002c, CFG_MCMEM1_VAL,
0x48000030, CFG_MCATT0_VAL,
0x48000034, CFG_MCATT1_VAL,
0x48000038, CFG_MCIO0_VAL,
0x4800003c, CFG_MCIO1_VAL,
0, 0
};
int i, rc;
#ifdef CONFIG_EXADRON1
int cardDetect;
volatile unsigned int *v_pBCRReg =
(volatile unsigned int *) 0x08000000;
#endif
debug ("%s\n", __FUNCTION__);
i = 0;
while (reg_arr[i])
*((volatile unsigned int *) reg_arr[i++]) |= reg_arr[i++];
udelay (1000);
debug ("%s: programmed mem controller \n", __FUNCTION__);
#ifdef CONFIG_EXADRON1
/*define useful BCR masks */
#define BCR_CF_INIT_VAL 0x00007230
#define BCR_CF_PWRON_BUSOFF_RESETOFF_VAL 0x00007231
#define BCR_CF_PWRON_BUSOFF_RESETON_VAL 0x00007233
#define BCR_CF_PWRON_BUSON_RESETON_VAL 0x00007213
#define BCR_CF_PWRON_BUSON_RESETOFF_VAL 0x00007211
/* we see from the GPIO bit if the card is present */
cardDetect = !(GPLR0 & GPIO_bit (14));
if (cardDetect) {
printf ("No PCMCIA card found!\n");
}
/* reset the card via the BCR line */
*v_pBCRReg = (unsigned) BCR_CF_INIT_VAL;
msWait (500);
*v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETOFF_VAL;
msWait (500);
*v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETON_VAL;
msWait (500);
*v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETON_VAL;
msWait (500);
*v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETOFF_VAL;
msWait (1500);
/* enable address bus */
GPCR1 = 0x01;
/* and the first CF slot */
MECR = 0x00000002;
#endif /* EXADRON 1 */
rc = check_ide_device (0); /* use just slot 0 */
return rc;
}
#endif /* CONFIG_PXA_PCMCIA */
/* -------------------------------------------------------------------- */
#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
@@ -296,6 +403,9 @@ static int pcmcia_off (void)
return 0;
}
#else
#ifndef CONFIG_PXA_PCMCIA
static int pcmcia_off (void)
{
int i;
@@ -327,13 +437,23 @@ static int pcmcia_off (void)
hardware_disable(_slot_);
return 0;
}
#endif /* CONFIG_PXA_PCMCIA */
#endif /* CONFIG_I82365 */
#ifdef CONFIG_PXA_PCMCIA
static int pcmcia_off (void)
{
return 0;
}
#endif
#endif /* CFG_CMD_PCMCIA */
/* -------------------------------------------------------------------- */
#ifdef CONFIG_IDE_8xx_PCCARD
#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
#define MAX_TUPEL_SZ 512
#define MAX_FEATURES 4
@@ -2370,7 +2490,7 @@ static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
/* -------------------------------------------------------------------- */
#ifndef CONFIG_I82365
#if ( ! defined(CONFIG_I82365) && ! defined(CONFIG_PXA_PCMCIA) )
static u_int m8xx_get_graycode(u_int size)
{
@@ -2444,7 +2564,7 @@ static u_int m8xx_get_speed(u_int ns, u_int is_io)
/* -------------------------------------------------------------------- */
#ifdef CONFIG_IDE_8xx_PCCARD
#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
static void print_funcid (int func)
{
puts (indent);
@@ -2486,7 +2606,7 @@ static void print_funcid (int func)
/* -------------------------------------------------------------------- */
#ifdef CONFIG_IDE_8xx_PCCARD
#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
static void print_fixed (volatile uchar *p)
{
if (p == NULL)
@@ -2544,7 +2664,7 @@ static void print_fixed (volatile uchar *p)
/* -------------------------------------------------------------------- */
#ifdef CONFIG_IDE_8xx_PCCARD
#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
#define MAX_IDENT_CHARS 64
#define MAX_IDENT_FIELDS 4
@@ -2606,6 +2726,370 @@ static int identify (volatile uchar *p)
}
#endif /* CONFIG_IDE_8xx_PCCARD */
/* -------------------------------------------------------------------- */
/* NETTA board by Intracom S.A. */
/* -------------------------------------------------------------------- */
#if defined(CONFIG_NETTA)
/* some sane bit macros */
#define _BD(_b) (1U << (31-(_b)))
#define _BDR(_l, _h) (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
#define _BW(_b) (1U << (15-(_b)))
#define _BWR(_l, _h) (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
#define _BB(_b) (1U << (7-(_b)))
#define _BBR(_l, _h) (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
#define _B(_b) _BD(_b)
#define _BR(_l, _h) _BDR(_l, _h)
#define PCMCIA_BOARD_MSG "NETTA"
static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
static void cfg_vppd(int no)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
unsigned short mask;
if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
return;
mask = vppd_masks[no];
immap->im_ioport.iop_papar &= ~mask;
immap->im_ioport.iop_paodr &= ~mask;
immap->im_ioport.iop_padir |= mask;
}
static void set_vppd(int no, int what)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
unsigned short mask;
if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
return;
mask = vppd_masks[no];
if (what)
immap->im_ioport.iop_padat |= mask;
else
immap->im_ioport.iop_padat &= ~mask;
}
static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
static void cfg_vccd(int no)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
unsigned short mask;
if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
return;
mask = vccd_masks[no];
immap->im_ioport.iop_papar &= ~mask;
immap->im_ioport.iop_paodr &= ~mask;
immap->im_ioport.iop_padir |= mask;
}
static void set_vccd(int no, int what)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
unsigned short mask;
if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
return;
mask = vccd_masks[no];
if (what)
immap->im_ioport.iop_padat |= mask;
else
immap->im_ioport.iop_padat &= ~mask;
}
static const unsigned short oc_mask = _BW(8);
static void cfg_oc(void)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
unsigned short mask = oc_mask;
immap->im_ioport.iop_pcdir &= ~mask;
immap->im_ioport.iop_pcso &= ~mask;
immap->im_ioport.iop_pcint &= ~mask;
immap->im_ioport.iop_pcpar &= ~mask;
}
static int get_oc(void)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
unsigned short mask = oc_mask;
int what;
what = !!(immap->im_ioport.iop_pcdat & mask);;
return what;
}
static const unsigned short shdn_mask = _BW(12);
static void cfg_shdn(void)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
unsigned short mask;
mask = shdn_mask;
immap->im_ioport.iop_papar &= ~mask;
immap->im_ioport.iop_paodr &= ~mask;
immap->im_ioport.iop_padir |= mask;
}
static void set_shdn(int what)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
unsigned short mask;
mask = shdn_mask;
if (what)
immap->im_ioport.iop_padat |= mask;
else
immap->im_ioport.iop_padat &= ~mask;
}
static void cfg_ports (void);
static int hardware_enable(int slot)
{
volatile immap_t *immap;
volatile cpm8xx_t *cp;
volatile pcmconf8xx_t *pcmp;
volatile sysconf8xx_t *sysp;
uint reg, pipr, mask;
int i;
debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
udelay(10000);
immap = (immap_t *)CFG_IMMR;
sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
/* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
cfg_ports ();
/* clear interrupt state, and disable interrupts */
pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
/*
* Disable interrupts, DMA, and PCMCIA buffers
* (isolate the interface) and assert RESET signal
*/
debug ("Disable PCMCIA buffers and assert RESET\n");
reg = 0;
reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
PCMCIA_PGCRX(_slot_) = reg;
udelay(500);
/*
* Make sure there is a card in the slot, then configure the interface.
*/
udelay(10000);
debug ("[%d] %s: PIPR(%p)=0x%x\n",
__LINE__,__FUNCTION__,
&(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
printf (" No Card found\n");
return (1);
}
/*
* Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
*/
mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
pipr = pcmp->pcmc_pipr;
debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
pipr,
(reg&PCMCIA_VS1(slot))?"n":"ff",
(reg&PCMCIA_VS2(slot))?"n":"ff");
if ((pipr & mask) == mask) {
set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
set_vccd(0, 0); set_vccd(1, 1); /* 5V on, 3V off */
puts (" 5.0V card found: ");
} else {
set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
set_vccd(0, 1); set_vccd(1, 0); /* 5V off, 3V on */
puts (" 3.3V card found: ");
}
/* Wait 500 ms; use this to check for over-current */
for (i=0; i<5000; ++i) {
if (!get_oc()) {
printf (" *** Overcurrent - Safety shutdown ***\n");
set_vccd(0, 0); set_vccd(1, 0); /* VAVPP => Hi-Z */
return (1);
}
udelay (100);
}
debug ("Enable PCMCIA buffers and stop RESET\n");
reg = PCMCIA_PGCRX(_slot_);
reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
PCMCIA_PGCRX(_slot_) = reg;
udelay(250000); /* some cards need >150 ms to come up :-( */
debug ("# hardware_enable done\n");
return (0);
}
#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
static int hardware_disable(int slot)
{
volatile immap_t *immap;
volatile pcmconf8xx_t *pcmp;
u_long reg;
debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
immap = (immap_t *)CFG_IMMR;
pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
/* Configure PCMCIA General Control Register */
debug ("Disable PCMCIA buffers and assert RESET\n");
reg = 0;
reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
PCMCIA_PGCRX(_slot_) = reg;
/* All voltages off / Hi-Z */
set_vppd(0, 1); set_vppd(1, 1);
set_vccd(0, 1); set_vccd(1, 1);
udelay(10000);
return (0);
}
#endif /* CFG_CMD_PCMCIA */
static int voltage_set(int slot, int vcc, int vpp)
{
volatile immap_t *immap;
volatile cpm8xx_t *cp;
volatile pcmconf8xx_t *pcmp;
u_long reg;
ushort sreg;
debug ("voltage_set: "
PCMCIA_BOARD_MSG
" Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
immap = (immap_t *)CFG_IMMR;
cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
/*
* Disable PCMCIA buffers (isolate the interface)
* and assert RESET signal
*/
debug ("Disable PCMCIA buffers and assert RESET\n");
reg = PCMCIA_PGCRX(_slot_);
reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
PCMCIA_PGCRX(_slot_) = reg;
udelay(500);
/*
* Configure Port C pins for
* 5 Volts Enable and 3 Volts enable,
* Turn all power pins to Hi-Z
*/
debug ("PCMCIA power OFF\n");
cfg_ports (); /* Enables switch, but all in Hi-Z */
sreg = immap->im_ioport.iop_pcdat;
set_vppd(0, 1); set_vppd(1, 1);
switch(vcc) {
case 0:
break; /* Switch off */
case 33:
set_vccd(0, 1); set_vccd(1, 0);
break;
case 50:
set_vccd(0, 0); set_vccd(1, 1);
break;
default:
goto done;
}
/* Checking supported voltages */
debug ("PIPR: 0x%x --> %s\n",
pcmp->pcmc_pipr,
(pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
done:
debug ("Enable PCMCIA buffers and stop RESET\n");
reg = PCMCIA_PGCRX(_slot_);
reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
PCMCIA_PGCRX(_slot_) = reg;
udelay(500);
debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
slot+'A');
return (0);
}
static void cfg_ports (void)
{
volatile immap_t *immap;
volatile cpm8xx_t *cp;
immap = (immap_t *)CFG_IMMR;
cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
cfg_vppd(0); cfg_vppd(1); /* VPPD0,VPPD1 VAVPP => Hi-Z */
cfg_vccd(0); cfg_vccd(1); /* 3V and 5V off */
cfg_shdn();
cfg_oc();
/*
* Configure Port A for TPS2211 PC-Card Power-Interface Switch
*
* Switch off all voltages, assert shutdown
*/
set_vppd(0, 1); set_vppd(1, 1);
set_vccd(0, 0); set_vccd(1, 0);
set_shdn(1);
udelay(100000);
}
#endif /* NETTA */
/* -------------------------------------------------------------------- */
#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */

View File

@@ -598,14 +598,14 @@ U_BOOT_CMD(
usb, 5, 1, do_usb,
"usb - USB sub-system\n",
"reset - reset (rescan) USB controller\n"
"usb stop [f] - stop USB [f]=force stop\n"
"usb tree - show USB device tree\n"
"usb info [dev] - show available USB devices\n"
"usb scan - (re-)scan USB bus for storage devices\n"
"usb device [dev] - show or set current USB storage device\n"
"usb part [dev] - print partition table of one or all USB storage devices\n"
"usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"
" to memory address `addr'\n"
"usb stop [f] - stop USB [f]=force stop\n"
"usb tree - show USB device tree\n"
"usb info [dev] - show available USB devices\n"
"usb scan - (re-)scan USB bus for storage devices\n"
"usb device [dev] - show or set current USB storage device\n"
"usb part [dev] - print partition table of one or all USB storage devices\n"
"usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"
" to memory address `addr'\n"
);

View File

@@ -74,6 +74,159 @@ U_BOOT_CMD(
" - echo args to console; \\c suppresses newline\n"
);
#ifdef CFG_HUSH_PARSER
int
do_test (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
char **ap;
int left, adv, expr, last_expr, neg, last_cmp;
/* args? */
if (argc < 3)
return 1;
#if 0
{
printf("test:");
left = 1;
while (argv[left])
printf(" %s", argv[left++]);
}
#endif
last_expr = 0;
left = argc - 1; ap = argv + 1;
if (left > 0 && strcmp(ap[0], "!") == 0) {
neg = 1;
ap++;
left--;
} else
neg = 0;
expr = -1;
last_cmp = -1;
last_expr = -1;
while (left > 0) {
if (strcmp(ap[0], "-o") == 0 || strcmp(ap[0], "-a") == 0)
adv = 1;
else if (strcmp(ap[0], "-z") == 0 || strcmp(ap[0], "-n") == 0)
adv = 2;
else
adv = 3;
if (left < adv) {
expr = 1;
break;
}
if (adv == 1) {
if (strcmp(ap[0], "-o") == 0) {
last_expr = expr;
last_cmp = 0;
} else if (strcmp(ap[0], "-a") == 0) {
last_expr = expr;
last_cmp = 1;
} else {
expr = 1;
break;
}
}
if (adv == 2) {
if (strcmp(ap[0], "-z") == 0)
expr = strlen(ap[1]) == 0 ? 0 : 1;
else if (strcmp(ap[0], "-n") == 0)
expr = strlen(ap[1]) == 0 ? 1 : 0;
else {
expr = 1;
break;
}
if (last_cmp == 0)
expr = last_expr || expr;
else if (last_cmp == 1)
expr = last_expr && expr;
last_cmp = -1;
}
if (adv == 3) {
if (strcmp(ap[1], "=") == 0)
expr = strcmp(ap[0], ap[2]) == 0;
else if (strcmp(ap[1], "!=") == 0)
expr = strcmp(ap[0], ap[2]) != 0;
else if (strcmp(ap[1], ">") == 0)
expr = strcmp(ap[0], ap[2]) > 0;
else if (strcmp(ap[1], "<") == 0)
expr = strcmp(ap[0], ap[2]) < 0;
else if (strcmp(ap[1], "-eq") == 0)
expr = simple_strtol(ap[0], NULL, 10) == simple_strtol(ap[2], NULL, 10);
else if (strcmp(ap[1], "-ne") == 0)
expr = simple_strtol(ap[0], NULL, 10) != simple_strtol(ap[2], NULL, 10);
else if (strcmp(ap[1], "-lt") == 0)
expr = simple_strtol(ap[0], NULL, 10) < simple_strtol(ap[2], NULL, 10);
else if (strcmp(ap[1], "-le") == 0)
expr = simple_strtol(ap[0], NULL, 10) <= simple_strtol(ap[2], NULL, 10);
else if (strcmp(ap[1], "-gt") == 0)
expr = simple_strtol(ap[0], NULL, 10) > simple_strtol(ap[2], NULL, 10);
else if (strcmp(ap[1], "-ge") == 0)
expr = simple_strtol(ap[0], NULL, 10) >= simple_strtol(ap[2], NULL, 10);
else {
expr = 1;
break;
}
if (last_cmp == 0)
expr = last_expr || expr;
else if (last_cmp == 1)
expr = last_expr && expr;
last_cmp = -1;
}
ap += adv; left -= adv;
}
if (neg)
expr = !expr;
expr = !expr;
#if 0
printf(": returns %d\n", expr);
#endif
return expr;
}
U_BOOT_CMD(
test, CFG_MAXARGS, 1, do_test,
"test - minimal test like /bin/sh\n",
"[args..]\n"
" - test functionality\n"
);
int
do_exit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int r;
r = 0;
if (argc > 1)
r = simple_strtoul(argv[1], NULL, 10);
return -r - 2;
}
U_BOOT_CMD(
exit, 2, 1, do_exit,
"exit - exit script\n",
" - exit functionality\n"
);
#endif
/*
* Use puts() instead of printf() to avoid printf buffer overflow
* for long help messages
@@ -217,3 +370,285 @@ cmd_tbl_t *find_cmd (const char *cmd)
return NULL; /* not found or ambiguous command */
}
#ifdef CONFIG_AUTO_COMPLETE
int var_complete(int argc, char *argv[], char last_char, int maxv, char *cmdv[])
{
static char tmp_buf[512];
int space;
space = last_char == '\0' || last_char == ' ' || last_char == '\t';
if (space && argc == 1)
return env_complete("", maxv, cmdv, sizeof(tmp_buf), tmp_buf);
if (!space && argc == 2)
return env_complete(argv[1], maxv, cmdv, sizeof(tmp_buf), tmp_buf);
return 0;
}
static void install_auto_complete_handler(const char *cmd,
int (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]))
{
cmd_tbl_t *cmdtp;
cmdtp = find_cmd(cmd);
if (cmdtp == NULL)
return;
cmdtp->complete = complete;
}
void install_auto_complete(void)
{
install_auto_complete_handler("printenv", var_complete);
install_auto_complete_handler("setenv", var_complete);
#if (CONFIG_COMMANDS & CFG_CMD_RUN)
install_auto_complete_handler("run", var_complete);
#endif
}
/*************************************************************************************/
static int complete_cmdv(int argc, char *argv[], char last_char, int maxv, char *cmdv[])
{
cmd_tbl_t *cmdtp;
const char *p;
int len, clen;
int n_found = 0;
const char *cmd;
/* sanity? */
if (maxv < 2)
return -2;
cmdv[0] = NULL;
if (argc == 0) {
/* output full list of commands */
for (cmdtp = &__u_boot_cmd_start; cmdtp != &__u_boot_cmd_end; cmdtp++) {
if (n_found >= maxv - 2) {
cmdv[n_found++] = "...";
break;
}
cmdv[n_found++] = cmdtp->name;
}
cmdv[n_found] = NULL;
return n_found;
}
/* more than one arg or one but the start of the next */
if (argc > 1 || (last_char == '\0' || last_char == ' ' || last_char == '\t')) {
cmdtp = find_cmd(argv[0]);
if (cmdtp == NULL || cmdtp->complete == NULL) {
cmdv[0] = NULL;
return 0;
}
return (*cmdtp->complete)(argc, argv, last_char, maxv, cmdv);
}
cmd = argv[0];
/*
* Some commands allow length modifiers (like "cp.b");
* compare command name only until first dot.
*/
p = strchr(cmd, '.');
if (p == NULL)
len = strlen(cmd);
else
len = p - cmd;
/* return the partial matches */
for (cmdtp = &__u_boot_cmd_start; cmdtp != &__u_boot_cmd_end; cmdtp++) {
clen = strlen(cmdtp->name);
if (clen < len)
continue;
if (memcmp(cmd, cmdtp->name, len) != 0)
continue;
/* too many! */
if (n_found >= maxv - 2) {
cmdv[n_found++] = "...";
break;
}
cmdv[n_found++] = cmdtp->name;
}
cmdv[n_found] = NULL;
return n_found;
}
static int make_argv(char *s, int argvsz, char *argv[])
{
int argc = 0;
/* split into argv */
while (argc < argvsz - 1) {
/* skip any white space */
while ((*s == ' ') || (*s == '\t'))
++s;
if (*s == '\0') /* end of s, no more args */
break;
argv[argc++] = s; /* begin of argument string */
/* find end of string */
while (*s && (*s != ' ') && (*s != '\t'))
++s;
if (*s == '\0') /* end of s, no more args */
break;
*s++ = '\0'; /* terminate current arg */
}
argv[argc] = NULL;
return argc;
}
static void print_argv(const char *banner, const char *leader, const char *sep, int linemax, char *argv[])
{
int ll = leader != NULL ? strlen(leader) : 0;
int sl = sep != NULL ? strlen(sep) : 0;
int len, i;
if (banner) {
puts("\n");
puts(banner);
}
i = linemax; /* force leader and newline */
while (*argv != NULL) {
len = strlen(*argv) + sl;
if (i + len >= linemax) {
puts("\n");
if (leader)
puts(leader);
i = ll - sl;
} else if (sep)
puts(sep);
puts(*argv++);
i += len;
}
printf("\n");
}
static int find_common_prefix(char *argv[])
{
int i, len;
char *anchor, *s, *t;
if (*argv == NULL)
return 0;
/* begin with max */
anchor = *argv++;
len = strlen(anchor);
while ((t = *argv++) != NULL) {
s = anchor;
for (i = 0; i < len; i++, t++, s++) {
if (*t != *s)
break;
}
len = s - anchor;
}
return len;
}
static char tmp_buf[CFG_CBSIZE]; /* copy of console I/O buffer */
int cmd_auto_complete(const char *const prompt, char *buf, int *np, int *colp)
{
int n = *np, col = *colp;
char *argv[CFG_MAXARGS + 1]; /* NULL terminated */
char *cmdv[20];
char *s, *t;
const char *sep;
int i, j, k, len, seplen, argc;
int cnt;
char last_char;
if (strcmp(prompt, CFG_PROMPT) != 0)
return 0; /* not in normal console */
cnt = strlen(buf);
if (cnt >= 1)
last_char = buf[cnt - 1];
else
last_char = '\0';
/* copy to secondary buffer which will be affected */
strcpy(tmp_buf, buf);
/* separate into argv */
argc = make_argv(tmp_buf, sizeof(argv)/sizeof(argv[0]), argv);
/* do the completion and return the possible completions */
i = complete_cmdv(argc, argv, last_char, sizeof(cmdv)/sizeof(cmdv[0]), cmdv);
/* no match; bell and out */
if (i == 0) {
if (argc > 1) /* allow tab for non command */
return 0;
putc('\a');
return 1;
}
s = NULL;
len = 0;
sep = NULL;
seplen = 0;
if (i == 1) { /* one match; perfect */
k = strlen(argv[argc - 1]);
s = cmdv[0] + k;
len = strlen(s);
sep = " ";
seplen = 1;
} else if (i > 1 && (j = find_common_prefix(cmdv)) != 0) { /* more */
k = strlen(argv[argc - 1]);
j -= k;
if (j > 0) {
s = cmdv[0] + k;
len = j;
}
}
if (s != NULL) {
k = len + seplen;
/* make sure it fits */
if (n + k >= CFG_CBSIZE - 2) {
putc('\a');
return 1;
}
t = buf + cnt;
for (i = 0; i < len; i++)
*t++ = *s++;
if (sep != NULL)
for (i = 0; i < seplen; i++)
*t++ = sep[i];
*t = '\0';
n += k;
col += k;
puts(t - k);
if (sep == NULL)
putc('\a');
*np = n;
*colp = col;
} else {
print_argv(NULL, " ", " ", 78, cmdv);
puts(prompt);
puts(buf);
}
return 1;
}
#endif

View File

@@ -412,6 +412,9 @@ int console_init_r (void)
DECLARE_GLOBAL_DATA_PTR;
char *stdinname, *stdoutname, *stderrname;
device_t *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
#ifdef CFG_CONSOLE_ENV_OVERWRITE
int i;
#endif /* CFG_CONSOLE_ENV_OVERWRITE */
/* set default handlers at first */
gd->jt[XF_getc] = serial_getc;
@@ -483,7 +486,7 @@ int console_init_r (void)
for (i = 0; i < 3; i++) {
setenv (stdio_names[i], stdio_devices[i]->name);
}
#endif /* CFG_CONSOLE_ENV_OVERWRITE */
#endif /* CFG_CONSOLE_ENV_OVERWRITE */
#if 0
/* If nothing usable installed, use only the initial console */

View File

@@ -260,3 +260,44 @@ void env_relocate (void)
disable_nvram();
#endif
}
#ifdef CONFIG_AUTO_COMPLETE
int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf)
{
int i, nxt, len, vallen, found;
const char *lval, *rval;
found = 0;
cmdv[0] = NULL;
len = strlen(var);
/* now iterate over the variables and select those that match */
for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
for (nxt=i; env_get_char(nxt) != '\0'; ++nxt)
;
lval = env_get_addr(i);
rval = strchr(lval, '=');
if (rval != NULL) {
vallen = rval - lval;
rval++;
} else
vallen = strlen(lval);
if (len > 0 && (vallen < len || memcmp(lval, var, len) != 0))
continue;
if (found >= maxv - 2 || bufsz < vallen + 1) {
cmdv[found++] = "...";
break;
}
cmdv[found++] = buf;
memcpy(buf, lval, vallen); buf += vallen; bufsz -= vallen;
*buf++ = '\0'; bufsz--;
}
cmdv[found] = NULL;
return found;
}
#endif

View File

@@ -53,7 +53,8 @@
defined(CONFIG_R360MPI) || \
defined(CONFIG_TQM8xxL) || \
defined(CONFIG_RRVISION) || \
defined(CONFIG_TRAB) ) && \
defined(CONFIG_TRAB) || \
defined(CONFIG_PPCHAMELEONEVB) ) && \
defined(ENV_CRC) /* Environment embedded in U-Boot .ppcenv section */
/* XXX - This only works with GNU C */
# define __PPCENV__ __attribute__ ((section(".ppcenv")))

View File

@@ -290,6 +290,7 @@ char **global_argv;
unsigned int global_argc;
#endif
unsigned int last_return_code;
int nesting_level;
#ifndef __U_BOOT__
extern char **environ; /* This is in <unistd.h>, but protected with __USE_GNU */
#endif
@@ -416,7 +417,9 @@ static int b_check_space(o_string *o, int len);
static int b_addchr(o_string *o, int ch);
static void b_reset(o_string *o);
static int b_addqchr(o_string *o, int ch, int quote);
#ifndef __U_BOOT__
static int b_adduint(o_string *o, unsigned int i);
#endif
/* in_str manipulations: */
static int static_get(struct in_str *i);
static int static_peek(struct in_str *i);
@@ -936,6 +939,7 @@ char *simple_itoa(unsigned int i)
return p + 1;
}
#ifndef __U_BOOT__
static int b_adduint(o_string *o, unsigned int i)
{
int r;
@@ -944,6 +948,7 @@ static int b_adduint(o_string *o, unsigned int i)
do r=b_addchr(o, *p++); while (r==0 && *p);
return r;
}
#endif
static int static_get(struct in_str *i)
{
@@ -1843,7 +1848,7 @@ static int run_list_real(struct pipe *pi)
if (rmode == RES_THEN || rmode == RES_ELSE) if_code = next_if_code;
if (rmode == RES_THEN && if_code) continue;
if (rmode == RES_ELSE && !if_code) continue;
if (rmode == RES_ELIF && !if_code) continue;
if (rmode == RES_ELIF && !if_code) break;
if (rmode == RES_FOR && pi->num_progs) {
if (!list) {
/* if no variable values after "in" we skip "for" */
@@ -1921,6 +1926,10 @@ static int run_list_real(struct pipe *pi)
}
last_return_code=rcode;
#else
if (rcode < -1) {
last_return_code = -rcode - 2;
return -2; /* exit */
}
last_return_code=(rcode == 0) ? 0 : 1;
#endif
#ifndef __U_BOOT__
@@ -2145,6 +2154,10 @@ static int xglob(o_string *dest, int flags, glob_t *pglob)
}
#endif
#ifdef __U_BOOT__
static char *get_dollar_var(char ch);
#endif
/* This is used to get/check local shell variables */
static char *get_local_var(const char *s)
{
@@ -2152,6 +2165,12 @@ static char *get_local_var(const char *s)
if (!s)
return NULL;
#ifdef __U_BOOT__
if (*s == '$')
return get_dollar_var(s[1]);
#endif
for (cur = top_vars; cur; cur=cur->next)
if(strcmp(cur->name, s)==0)
return cur->value;
@@ -2168,12 +2187,19 @@ static int set_local_var(const char *s, int flg_export)
int result=0;
struct variables *cur;
#ifdef __U_BOOT__
/* might be possible! */
if (!isalpha(*s))
return -1;
#endif
name=strdup(s);
#ifdef __U_BOOT__
if (getenv(name) != NULL) {
printf ("ERROR: "
"There is a global environment variable with the same name.\n");
free(name);
return -1;
}
#endif
@@ -2278,7 +2304,10 @@ static void unset_local_var(const char *name)
static int is_assignment(const char *s)
{
if (s==NULL || !isalpha(*s)) return 0;
if (s == NULL)
return 0;
if (!isalpha(*s)) return 0;
++s;
while(isalnum(*s) || *s=='_') ++s;
return *s=='=';
@@ -2749,15 +2778,35 @@ static int parse_group(o_string *dest, struct p_context *ctx,
* see the bash man page under "Parameter Expansion" */
static char *lookup_param(char *src)
{
char *p=NULL;
if (src) {
char *p;
if (!src)
return NULL;
p = getenv(src);
if (!p)
p = get_local_var(src);
}
return p;
}
#ifdef __U_BOOT__
static char *get_dollar_var(char ch)
{
static char buf[40];
buf[0] = '\0';
switch (ch) {
case '?':
sprintf(buf, "%u", (unsigned int)last_return_code);
break;
default:
return NULL;
}
return buf;
}
#endif
/* return code: 0 for OK, 1 for syntax error */
static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input)
{
@@ -2799,7 +2848,15 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i
break;
#endif
case '?':
#ifndef __U_BOOT__
b_adduint(dest,last_return_code);
#else
ctx->child->sp++;
b_addchr(dest, SPECIAL_VAR_SYMBOL);
b_addchr(dest, '$');
b_addchr(dest, '?');
b_addchr(dest, SPECIAL_VAR_SYMBOL);
#endif
advance = 1;
break;
#ifndef __U_BOOT__
@@ -2885,8 +2942,11 @@ int parse_stream(o_string *dest, struct p_context *ctx,
if (input->__promptme == 0) return 1;
#endif
next = (ch == '\n') ? 0 : b_peek(input);
debug_printf("parse_stream: ch=%c (%d) m=%d quote=%d\n",
ch,ch,m,dest->quote);
debug_printf("parse_stream: ch=%c (%d) m=%d quote=%d - %c\n",
ch >= ' ' ? ch : '.', ch, m,
dest->quote, ctx->stack == NULL ? '*' : '.');
if (m==0 || ((m==1 || m==2) && dest->quote)) {
b_addqchr(dest, ch, dest->quote);
} else {
@@ -3107,7 +3167,18 @@ int parse_stream_outer(struct in_str *inp, int flag)
#ifndef __U_BOOT__
run_list(ctx.list_head);
#else
if (((code = run_list(ctx.list_head)) == -1))
code = run_list(ctx.list_head);
if (code == -2) { /* exit */
b_free(&temp);
code = 0;
/* XXX hackish way to not allow exit from main loop */
if (inp->peek == file_peek) {
printf("exit not allowed from main input shell.\n");
continue;
}
break;
}
if (code == -1)
flag_repeat = 0;
#endif
} else {

View File

@@ -365,6 +365,10 @@ void main_loop (void)
u_boot_hush_start ();
#endif
#ifdef CONFIG_AUTO_COMPLETE
install_auto_complete();
#endif
#ifdef CONFIG_PREBOOT
if ((p = getenv ("preboot")) != NULL) {
# ifdef CONFIG_AUTOBOOT_KEYED
@@ -608,6 +612,14 @@ int readline (const char *const prompt)
*/
if (n < CFG_CBSIZE-2) {
if (c == '\t') { /* expand TABs */
#ifdef CONFIG_AUTO_COMPLETE
/* if auto completion triggered just continue */
*p = '\0';
if (cmd_auto_complete(prompt, console_buffer, &n, &col)) {
p = console_buffer + n; /* reset */
continue;
}
#endif
puts (tab_seq+(col&07));
col += 8 - (col&07);
} else {
@@ -714,8 +726,8 @@ static void process_macros (const char *input, char *output)
int inputcnt = strlen (input);
int outputcnt = CFG_CBSIZE;
int state = 0; /* 0 = waiting for '$' */
/* 1 = waiting for '(' */
/* 2 = waiting for ')' */
/* 1 = waiting for '(' or '{' */
/* 2 = waiting for ')' or '}' */
/* 3 = waiting for ''' */
#ifdef DEBUG_PARSER
char *output_start = output;
@@ -753,7 +765,7 @@ static void process_macros (const char *input, char *output)
}
break;
case 1: /* Waiting for ( */
if (c == '(') {
if (c == '(' || c == '{') {
state++;
varname_start = input;
} else {
@@ -768,7 +780,7 @@ static void process_macros (const char *input, char *output)
}
break;
case 2: /* Waiting for ) */
if (c == ')') {
if (c == ')' || c == '}') {
int i;
char envname[CFG_CBSIZE], *envval;
int envcnt = input-varname_start-1; /* Varname # of chars */

View File

@@ -203,6 +203,8 @@ int miiphy_link (unsigned char addr)
{
unsigned short reg;
/* dummy read; needed to latch some phys */
(void)miiphy_read(addr, PHY_BMSR, &reg);
if (miiphy_read (addr, PHY_BMSR, &reg)) {
puts ("PHY_BMSR read failed, assuming no link\n");
return (0);

43
cpu/microblaze/Makefile Normal file
View File

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

25
cpu/microblaze/cpu.c Normal file
View File

@@ -0,0 +1,25 @@
/*
* (C) Copyright 2004 Atmark Techno, Inc.
*
* Yasushi SHOJI <yashi@atmark-techno.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
*/
/* EMPTY FILE */

View File

@@ -0,0 +1,32 @@
/*
* (C) Copyright 2004 Atmark Techno, Inc.
*
* Yasushi SHOJI <yashi@atmark-techno.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
*/
void enable_interrupts(void)
{
}
int disable_interrupts(void)
{
return 0;
}

36
cpu/microblaze/start.S Normal file
View File

@@ -0,0 +1,36 @@
/*
* (C) Copyright 2004 Atmark Techno, Inc.
*
* Yasushi SHOJI <yashi@atmark-techno.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>
.text
.global _start
_start:
addi r1, r0, CFG_SDRAM_BASE /* init stack pointer */
addi r1, r1, CFG_SDRAM_SIZE /* set sp to high up */
brai board_init
1: bri 1b

View File

@@ -103,6 +103,9 @@ boot_cold:
boot_warm:
mfmsr r5 /* save msr contents */
/* Move CSBoot and adjust instruction pointer */
/*--------------------------------------------------------------*/
#if defined(CFG_LOWBOOT)
#if defined(CFG_RAMBOOT)
#error CFG_LOWBOOT is incompatible with CFG_RAMBOOT
@@ -113,19 +116,15 @@ boot_warm:
stw r3, 0x4(r4) /* CS0 start */
lis r3, STOP_REG(CFG_BOOTCS_START, CFG_BOOTCS_SIZE)@h
ori r3, r3, STOP_REG(CFG_BOOTCS_START, CFG_BOOTCS_SIZE)@l
stw r3, 0x8(r4) /* CS0 stop */
lis r3, 0x00047800@h
ori r3, r3, 0x00047800@l
stw r3, 0x300(r4) /* set timing, CS0/boot conf reg */
lis r3, 0x02010000@h
ori r3, r3, 0x02010000@l
stw r3, 0x54(r4) /* CS0 and Boot enable, IPBI ctrl reg */
stw r3, 0x54(r4) /* CS0 and Boot enable */
lis r3, lowboot_reentry@h
ori r3, r3, lowboot_reentry@l
lis r3, lowboot_reentry@h /* jump from bootlow address space (0x0000xxxx) */
ori r3, r3, lowboot_reentry@l /* to the address space the linker used */
mtlr r3
blr /* jump to flash based address */
blr
lowboot_reentry:
lis r3, START_REG(CFG_BOOTCS_START)@h
@@ -134,12 +133,9 @@ lowboot_reentry:
lis r3, STOP_REG(CFG_BOOTCS_START, CFG_BOOTCS_SIZE)@h
ori r3, r3, STOP_REG(CFG_BOOTCS_START, CFG_BOOTCS_SIZE)@l
stw r3, 0x50(r4) /* Boot stop */
lis r3, 0x00047800@h
ori r3, r3, 0x00047800@l
stw r3, 0x300(r4) /* set timing, CS0/boot conf reg */
lis r3, 0x02000001@h
ori r3, r3, 0x02000001@l
stw r3, 0x54(r4) /* Boot enable, CS0 disable, wait state enable */
stw r3, 0x54(r4) /* Boot enable, CS0 disable */
#endif /* CFG_LOWBOOT */
#if defined(CFG_DEFAULT_MBAR) && !defined(CFG_RAMBOOT)

View File

@@ -36,7 +36,7 @@
* added 8260 masks by
* Marius Groeger <mag@sysgo.de>
*
* added HiP7 (8270/8275/8280) processors support by
* added HiP7 (824x/827x/8280) processors support by
* Yuli Barcohen <yuli@arabellasw.com>
*/
@@ -129,6 +129,10 @@ int checkcpu (void)
case 0x0A01:
puts ("0.1 1K49M");
break;
case 0x0C00:
case 0x0D00:
printf ("0.0 0K50M");
break;
default:
printf ("unknown [immr=0x%04x,k=0x%04x]", m, k);
break;

View File

@@ -291,8 +291,8 @@ void pci_mpc8250_init (struct pci_controller *hose)
immap->im_memctl.memc_pcibr0 = PCI_MSTR0_LOCAL | PCIBR_ENABLE;
#ifdef CONFIG_MPC8266ADS
immap->im_memctl.memc_pcimsk0 = PCIMSK1_MASK;
immap->im_memctl.memc_pcibr0 = PCI_MSTR1_LOCAL | PCIBR_ENABLE;
immap->im_memctl.memc_pcimsk1 = PCIMSK1_MASK;
immap->im_memctl.memc_pcibr1 = PCI_MSTR1_LOCAL | PCIBR_ENABLE;
#endif
/* Release PCI RST (by default the PCI RST signal is held low) */

View File

@@ -49,9 +49,12 @@ static int tsec_send(struct eth_device* dev, volatile void *packet, int length);
static int tsec_recv(struct eth_device* dev);
static int tsec_init(struct eth_device* dev, bd_t * bd);
static void tsec_halt(struct eth_device* dev);
static void init_registers(volatile tsec_t *regs);
static void startup_tsec(volatile tsec_t *regs);
static void init_phy(volatile tsec_t *regs);
static void init_registers(tsec_t *regs);
static void startup_tsec(tsec_t *regs);
static void init_phy(tsec_t *regs);
uint read_phy_reg(tsec_t *regbase, uint phyid, uint offset);
static int phy_id = -1;
/* Initialize device structure. returns 0 on failure, 1 on
* success */
@@ -59,6 +62,7 @@ int tsec_initialize(bd_t *bis)
{
struct eth_device* dev;
int i;
tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
dev = (struct eth_device*) malloc(sizeof *dev);
@@ -67,7 +71,7 @@ int tsec_initialize(bd_t *bis)
memset(dev, 0, sizeof *dev);
sprintf(dev->name, "MOTOROLA ETHERNET");
sprintf(dev->name, "MOTO ETHERNET");
dev->iobase = 0;
dev->priv = 0;
dev->init = tsec_init;
@@ -81,6 +85,45 @@ int tsec_initialize(bd_t *bis)
eth_register(dev);
/* Reconfigure the PHY to advertise everything here
* so that it works with both gigabit and 10/100 */
#ifdef CONFIG_PHY_M88E1011
/* Assign a Physical address to the TBI */
regs->tbipa=TBIPA_VALUE;
/* reset the management interface */
regs->miimcfg=MIIMCFG_RESET;
regs->miimcfg=MIIMCFG_INIT_VALUE;
/* Wait until the bus is free */
while(regs->miimind & MIIMIND_BUSY);
/* Locate PHYs. Skip TBIPA, which we know is 31.
*/
for (i=0; i<31; i++) {
if (read_phy_reg(regs, i, 2) == 0x141) {
if (phy_id == -1)
phy_id = i;
#ifdef TSEC_DEBUG
printf("Found Marvell PHY at 0x%02x\n", i);
#endif
}
}
#ifdef TSEC_DEBUG
printf("Using PHY ID 0x%02x\n", phy_id);
#endif
write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_RESET);
RESET_ERRATA(regs, phy_id);
/* Configure the PHY to advertise gbit and 10/100 */
write_phy_reg(regs, phy_id, MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT);
write_phy_reg(regs, phy_id, MIIM_ANAR, MIIM_ANAR_INIT);
/* Reset the PHY so the new settings take effect */
write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_RESET);
#endif
return 1;
}
@@ -89,12 +132,12 @@ int tsec_initialize(bd_t *bis)
* and brings the interface up */
int tsec_init(struct eth_device* dev, bd_t * bd)
{
volatile tsec_t *regs;
tsec_t *regs;
uint tempval;
char tmpbuf[MAC_ADDR_LEN];
int i;
regs = (volatile tsec_t *)(TSEC_BASE_ADDR);
regs = (tsec_t *)(TSEC_BASE_ADDR);
/* Make sure the controller is stopped */
tsec_halt(dev);
@@ -146,7 +189,7 @@ int tsec_init(struct eth_device* dev, bd_t * bd)
/* and then passes those bits on to the variable specified in */
/* value */
/* Before it does the read, it needs to clear the command field */
uint read_phy_reg(volatile tsec_t *regbase, uint phyid, uint offset)
uint read_phy_reg(tsec_t *regbase, uint phyid, uint offset)
{
uint value;
@@ -173,7 +216,7 @@ uint read_phy_reg(volatile tsec_t *regbase, uint phyid, uint offset)
}
/* Setup the PHY */
static void init_phy(volatile tsec_t *regs)
static void init_phy(tsec_t *regs)
{
uint testval;
unsigned int timeout = TSEC_TIMEOUT;
@@ -198,17 +241,17 @@ static void init_phy(volatile tsec_t *regs)
#endif
/* Set the PHY to gigabit, full duplex, Auto-negotiate */
write_phy_reg(regs, 0, MIIM_CONTROL, MIIM_CONTROL_INIT);
write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_INIT);
/* Wait until TBI_STATUS indicates AN is done */
/* Wait until STATUS indicates Auto-Negotiation is done */
DBGPRINT("Waiting for Auto-negotiation to complete\n");
testval=read_phy_reg(regs, 0, MIIM_TBI_STATUS);
testval=read_phy_reg(regs, phy_id, MIIM_STATUS);
while((!(testval & MIIM_TBI_STATUS_AN_DONE))&& timeout--) {
testval=read_phy_reg(regs, 0, MIIM_TBI_STATUS);
while((!(testval & MIIM_STATUS_AN_DONE))&& timeout--) {
testval=read_phy_reg(regs, phy_id, MIIM_STATUS);
}
if(testval & MIIM_TBI_STATUS_AN_DONE)
if(testval & MIIM_STATUS_AN_DONE)
DBGPRINT("Auto-negotiation done\n");
else
DBGPRINT("Auto-negotiation timed-out.\n");
@@ -216,7 +259,7 @@ static void init_phy(volatile tsec_t *regs)
#ifdef CONFIG_PHY_CIS8201
/* Find out what duplexity (duplicity?) we have */
/* Read it twice to make sure */
testval=read_phy_reg(regs, 0, MIIM_AUX_CONSTAT);
testval=read_phy_reg(regs, phy_id, MIIM_AUX_CONSTAT);
if(testval & MIIM_AUXCONSTAT_DUPLEX) {
DBGPRINT("Enet starting in full duplex\n");
@@ -246,17 +289,17 @@ static void init_phy(volatile tsec_t *regs)
#ifdef CONFIG_PHY_M88E1011
/* Read the PHY to see what speed and duplex we are */
testval=read_phy_reg(regs, 0, MIIM_PHY_STATUS);
testval=read_phy_reg(regs, phy_id, MIIM_PHY_STATUS);
timeout = TSEC_TIMEOUT;
while((!(testval & MIIM_PHYSTAT_SPDDONE)) && timeout--) {
testval = read_phy_reg(regs,0,MIIM_PHY_STATUS);
testval = read_phy_reg(regs,phy_id,MIIM_PHY_STATUS);
}
if(!(testval & MIIM_PHYSTAT_SPDDONE))
DBGPRINT("Enet: Speed not resolved\n");
testval=read_phy_reg(regs, 0, MIIM_PHY_STATUS);
testval=read_phy_reg(regs, phy_id, MIIM_PHY_STATUS);
if(testval & MIIM_PHYSTAT_DUPLEX) {
DBGPRINT("Enet starting in Full Duplex\n");
regs->maccfg2 |= MACCFG2_FULL_DUPLEX;
@@ -280,7 +323,7 @@ static void init_phy(volatile tsec_t *regs)
}
static void init_registers(volatile tsec_t *regs)
static void init_registers(tsec_t *regs)
{
/* Clear IEVENT */
regs->ievent = IEVENT_INIT_CLEAR;
@@ -322,7 +365,7 @@ static void init_registers(volatile tsec_t *regs)
}
static void startup_tsec(volatile tsec_t *regs)
static void startup_tsec(tsec_t *regs)
{
int i;
@@ -363,7 +406,7 @@ static int tsec_send(struct eth_device* dev, volatile void *packet, int length)
{
int i;
int result = 0;
volatile tsec_t * regs = (volatile tsec_t *)(TSEC_BASE_ADDR);
tsec_t * regs = (tsec_t *)(TSEC_BASE_ADDR);
/* Find an empty buffer descriptor */
for(i=0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
@@ -397,7 +440,7 @@ static int tsec_send(struct eth_device* dev, volatile void *packet, int length)
static int tsec_recv(struct eth_device* dev)
{
int length;
volatile tsec_t *regs = (volatile tsec_t *)(TSEC_BASE_ADDR);
tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
while(!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) {
@@ -428,7 +471,7 @@ static int tsec_recv(struct eth_device* dev)
static void tsec_halt(struct eth_device* dev)
{
volatile tsec_t *regs = (volatile tsec_t *)(TSEC_BASE_ADDR);
tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS);
@@ -438,4 +481,44 @@ static void tsec_halt(struct eth_device* dev)
regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN);
}
#ifndef CONFIG_BITBANGMII
/*
* Read a MII PHY register.
*
* Returns:
* 0 on success
*/
int miiphy_read(unsigned char addr,
unsigned char reg,
unsigned short *value)
{
tsec_t *regs;
unsigned short rv;
regs = (tsec_t *)(TSEC_BASE_ADDR);
rv = (unsigned short)read_phy_reg(regs, addr, reg);
*value = rv;
return 0;
}
/*
* Write a MII PHY register.
*
* Returns:
* 0 on success
*/
int miiphy_write(unsigned char addr,
unsigned char reg,
unsigned short value)
{
tsec_t *regs;
regs = (tsec_t *)(TSEC_BASE_ADDR);
write_phy_reg(regs, addr, reg, value);
return 0;
}
#endif /* CONFIG_BITBANGMII */
#endif /* CONFIG_TSEC_ENET */

View File

@@ -19,6 +19,9 @@
#include <net.h>
#include <mpc85xx.h>
/* TSEC1 is offset 0x24000, TSEC2 is offset 0x25000
#define TSEC_BASE_ADDR (CFG_IMMR + 0x25000)
*/
#define TSEC_BASE_ADDR (CFG_IMMR + 0x24000)
#define TSEC_MEM_SIZE 0x01000
@@ -56,16 +59,16 @@
#define MIIMIND_BUSY 0x00000001
#define MIIMIND_NOTVALID 0x00000004
#define MIIM_TBICON 0x11
#define MIIM_TBICON_GMII 0x00000010
#define MIIM_TBICON_AN 0x00000100
#define MIIM_CONTROL 0x00
#define MIIM_CONTROL_INIT 0x00001140
#define MIIM_ANEN 0x00001000
#define MIIM_CONTROL_RESET 0x00009140
#define MIIM_TBI_STATUS 0x1
#define MIIM_TBI_STATUS_AN_DONE 0x00000020
#define MIIM_STATUS 0x1
#define MIIM_STATUS_AN_DONE 0x00000020
#define MIIM_GBIT_CONTROL 0x9
#define MIIM_GBIT_CONTROL_INIT 0xe00
#define MIIM_TBI_ANEX 0x6
#define MIIM_TBI_ANEX_NP 0x00000004
@@ -89,11 +92,11 @@
#endif
#ifdef CONFIG_PHY_M88E1011
#define MIIM_ANAR 0x04
#define MIIM_ANAR_ADVERTISEMENT 0x01e1
#define MIIM_ANAR 0x4
#define MIIM_ANAR_INIT 0x1e1
#define MIIM_GBIT_CON 0x09
#define MIIM_GBIT_CON_ADVERT 0x1e00
#define MIIM_GBIT_CON_ADVERT 0x0e00
#define MIIM_PHY_STATUS 0x11
#define MIIM_PHYSTAT_SPEED 0xc000
@@ -130,6 +133,15 @@
} while(0)
/* This works around errata in reseting the PHY */
#define RESET_ERRATA(regs, ID) do { \
write_phy_reg(regs, (ID), 0x1d, 0x1f); \
write_phy_reg(regs, (ID), 0x1e, 0x200c); \
write_phy_reg(regs, (ID), 0x1d, 0x5); \
write_phy_reg(regs, (ID), 0x1e, 0x0); \
write_phy_reg(regs, (ID), 0x1e, 0x100); \
} while(0)
#define IEVENT_INIT_CLEAR 0xffffffff
#define IEVENT_BABR 0x80000000
#define IEVENT_RXC 0x40000000

View File

@@ -29,13 +29,71 @@
#undef ET_DEBUG
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(FEC_ENET)
#if (CONFIG_COMMANDS & CFG_CMD_NET) && \
(defined(FEC_ENET) || defined(CONFIG_ETHER_ON_FEC1) || defined(CONFIG_ETHER_ON_FEC2))
/* compatibility test, if only FEC_ENET defined assume ETHER on FEC1 */
#if defined(FEC_ENET) && !defined(CONFIG_ETHER_ON_FEC1) && !defined(CONFIG_ETHER_ON_FEC2)
#define CONFIG_ETHER_ON_FEC1 1
#endif
/* define WANT_MII when MII support is required */
#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_FEC1_PHY) || defined(CONFIG_FEC2_PHY)
#define WANT_MII
#else
#undef WANT_MII
#endif
#if defined(WANT_MII)
#include <miiphy.h>
#endif
#if defined(CONFIG_RMII) && !defined(WANT_MII)
#error RMII support is unusable without a working PHY.
#endif
#ifdef CFG_DISCOVER_PHY
#include <miiphy.h>
static void mii_discover_phy(void);
static int mii_discover_phy(struct eth_device *dev);
#endif
static struct ether_fcc_info_s
{
int ether_index;
int fecp_offset;
int phy_addr;
int actual_phy_addr;
int initialized;
}
ether_fcc_info[] = {
#if defined(CONFIG_ETHER_ON_FEC1)
{
0,
offsetof(immap_t, im_cpm.cp_fec1),
#if defined(CONFIG_FEC1_PHY)
CONFIG_FEC1_PHY,
#else
-1, /* discover */
#endif
-1,
0,
},
#endif
#if defined(CONFIG_ETHER_ON_FEC2)
{
1,
offsetof(immap_t, im_cpm.cp_fec2),
#if defined(CONFIG_FEC2_PHY)
CONFIG_FEC2_PHY,
#else
-1,
#endif
-1,
0,
},
#endif
};
/* Ethernet Transmit and Receive Buffers */
#define DBUF_LENGTH 1520
@@ -47,8 +105,11 @@ static void mii_discover_phy(void);
#define PKT_MINBUF_SIZE 64
#define PKT_MAXBLR_SIZE 1520
static char txbuf[DBUF_LENGTH];
#ifdef __GNUC__
static char txbuf[DBUF_LENGTH] __attribute__ ((aligned(8)));
#else
#error txbuf must be aligned.
#endif
static uint rxIdx; /* index of the current RX buffer */
static uint txIdx; /* index of the current TX buffer */
@@ -74,28 +135,49 @@ static void fec_halt(struct eth_device* dev);
int fec_initialize(bd_t *bis)
{
struct eth_device* dev;
struct ether_fcc_info_s *efis;
int i;
dev = (struct eth_device*) malloc(sizeof *dev);
memset(dev, 0, sizeof *dev);
for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++) {
sprintf(dev->name, "FEC ETHERNET");
dev->iobase = 0;
dev->priv = 0;
dev->init = fec_init;
dev->halt = fec_halt;
dev->send = fec_send;
dev->recv = fec_recv;
dev = malloc(sizeof(*dev));
if (dev == NULL)
hang();
eth_register(dev);
memset(dev, 0, sizeof(*dev));
/* for FEC1 make sure that the name of the interface is the same
as the old one for compatibility reasons */
if (i == 0) {
sprintf (dev->name, "FEC ETHERNET");
} else {
sprintf (dev->name, "FEC%d ETHERNET",
ether_fcc_info[i].ether_index + 1);
}
efis = &ether_fcc_info[i];
/*
* reset actual phy addr
*/
efis->actual_phy_addr = -1;
dev->priv = efis;
dev->init = fec_init;
dev->halt = fec_halt;
dev->send = fec_send;
dev->recv = fec_recv;
eth_register(dev);
}
return 1;
}
static int fec_send(struct eth_device* dev, volatile void *packet, int length)
{
int j, rc;
volatile immap_t *immr = (immap_t *) CFG_IMMR;
volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
struct ether_fcc_info_s *efis = dev->priv;
volatile fec_t *fecp = (volatile fec_t *)(CFG_IMMR + efis->fecp_offset);
/* section 16.9.23.3
* Wait for ready
@@ -142,50 +224,66 @@ static int fec_send(struct eth_device* dev, volatile void *packet, int length)
return rc;
}
static int fec_recv(struct eth_device* dev)
static int fec_recv (struct eth_device *dev)
{
struct ether_fcc_info_s *efis = dev->priv;
volatile fec_t *fecp =
(volatile fec_t *) (CFG_IMMR + efis->fecp_offset);
int length;
volatile immap_t *immr = (immap_t *) CFG_IMMR;
volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
for (;;) {
/* section 16.9.23.2 */
if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
length = -1;
break; /* nothing received - leave for() loop */
}
for (;;) {
/* section 16.9.23.2 */
if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
length = -1;
break; /* nothing received - leave for() loop */
}
length = rtx->rxbd[rxIdx].cbd_datlen;
length = rtx->rxbd[rxIdx].cbd_datlen;
if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) {
if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) {
#ifdef ET_DEBUG
printf("%s[%d] err: %x\n",
__FUNCTION__,__LINE__,rtx->rxbd[rxIdx].cbd_sc);
printf ("%s[%d] err: %x\n",
__FUNCTION__, __LINE__,
rtx->rxbd[rxIdx].cbd_sc);
#endif
} else {
/* Pass the packet up to the protocol layers. */
NetReceive(NetRxPackets[rxIdx], length - 4);
} else {
volatile uchar *rx = NetRxPackets[rxIdx];
length -= 4;
#if (CONFIG_COMMANDS & CFG_CMD_CDP)
if ((rx[0] & 1) != 0
&& memcmp ((uchar *) rx, NetBcastAddr, 6) != 0
&& memcmp ((uchar *) rx, NetCDPAddr, 6) != 0)
rx = NULL;
#endif
/*
* Pass the packet up to the protocol layers.
*/
if (rx != NULL)
NetReceive (rx, length);
}
/* Give the buffer back to the FEC. */
rtx->rxbd[rxIdx].cbd_datlen = 0;
/* wrap around buffer index when necessary */
if ((rxIdx + 1) >= PKTBUFSRX) {
rtx->rxbd[PKTBUFSRX - 1].cbd_sc =
(BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
rxIdx = 0;
} else {
rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
rxIdx++;
}
__asm__ ("eieio");
/* Try to fill Buffer Descriptors */
fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */
}
/* Give the buffer back to the FEC. */
rtx->rxbd[rxIdx].cbd_datlen = 0;
/* wrap around buffer index when necessary */
if ((rxIdx + 1) >= PKTBUFSRX) {
rtx->rxbd[PKTBUFSRX - 1].cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
rxIdx = 0;
} else {
rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
rxIdx++;
}
__asm__ ("eieio");
/* Try to fill Buffer Descriptors */
fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */
}
return length;
return length;
}
/**************************************************************
@@ -210,34 +308,255 @@ static int fec_recv(struct eth_device* dev)
#define FEC_RESET_DELAY 50
static int fec_init(struct eth_device* dev, bd_t * bd)
#if defined(CONFIG_RMII)
static inline void fec_10Mbps(struct eth_device *dev)
{
struct ether_fcc_info_s *efis = dev->priv;
int fecidx = efis->ether_index;
uint mask = (fecidx == 0) ? 0x0000010 : 0x0000008;
int i;
if ((unsigned int)fecidx >= 2)
hang();
((volatile immap_t *)CFG_IMMR)->im_cpm.cp_cptr |= mask;
}
static inline void fec_100Mbps(struct eth_device *dev)
{
struct ether_fcc_info_s *efis = dev->priv;
int fecidx = efis->ether_index;
uint mask = (fecidx == 0) ? 0x0000010 : 0x0000008;
if ((unsigned int)fecidx >= 2)
hang();
((volatile immap_t *)CFG_IMMR)->im_cpm.cp_cptr &= ~mask;
}
#endif
static inline void fec_full_duplex(struct eth_device *dev)
{
struct ether_fcc_info_s *efis = dev->priv;
volatile fec_t *fecp = (volatile fec_t *)(CFG_IMMR + efis->fecp_offset);
fecp->fec_r_cntrl &= ~FEC_RCNTRL_DRT;
fecp->fec_x_cntrl |= FEC_TCNTRL_FDEN; /* FD enable */
}
static inline void fec_half_duplex(struct eth_device *dev)
{
struct ether_fcc_info_s *efis = dev->priv;
volatile fec_t *fecp = (volatile fec_t *)(CFG_IMMR + efis->fecp_offset);
fecp->fec_r_cntrl |= FEC_RCNTRL_DRT;
fecp->fec_x_cntrl &= ~FEC_TCNTRL_FDEN; /* FD disable */
}
static void fec_pin_init(int fecidx)
{
DECLARE_GLOBAL_DATA_PTR;
bd_t *bd = gd->bd;
volatile immap_t *immr = (immap_t *) CFG_IMMR;
volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
volatile fec_t *fecp;
#if defined(CONFIG_FADS) /* FADS family uses FPGA (BCSR) to control PHYs */
#if defined(CONFIG_DUET_ADS)
*(vu_char *)BCSR5 &= ~(BCSR5_MII1_EN | BCSR5_MII1_RST);
#else
/* configure FADS for fast (FEC) ethernet, half-duplex */
/* The LXT970 needs about 50ms to recover from reset, so
* wait for it by discovering the PHY before leaving eth_init().
/*
* only two FECs please
*/
{
volatile uint *bcsr4 = (volatile uint *) BCSR4;
*bcsr4 = (*bcsr4 & ~(BCSR4_FETH_EN | BCSR4_FETHCFG1))
| (BCSR4_FETHCFG0 | BCSR4_FETHFDE | BCSR4_FETHRST);
if ((unsigned int)fecidx >= 2)
hang();
if (fecidx == 0)
fecp = &immr->im_cpm.cp_fec1;
else
fecp = &immr->im_cpm.cp_fec2;
/*
* Set MII speed to 2.5 MHz or slightly below.
* * According to the MPC860T (Rev. D) Fast ethernet controller user
* * manual (6.2.14),
* * the MII management interface clock must be less than or equal
* * to 2.5 MHz.
* * This MDC frequency is equal to system clock / (2 * MII_SPEED).
* * Then MII_SPEED = system_clock / 2 * 2,5 Mhz.
*/
fecp->fec_mii_speed = ((bd->bi_intfreq + 4999999) / 5000000) << 1;
#if defined(CONFIG_NETTA) || defined(CONFIG_NETPHONE)
/* our PHYs are the limit at 2.5 MHz */
fecp->fec_mii_speed <<= 1;
#endif
#if defined(CONFIG_DUET) && defined(WANT_MII)
/* use MDC for MII */
immr->im_ioport.iop_pdpar |= 0x0080;
immr->im_ioport.iop_pddir &= ~0x0080;
#endif
if (fecidx == 0) {
#if defined(CONFIG_ETHER_ON_FEC1)
#if defined(CONFIG_DUET) /* MPC87x/88x have got 2 FECs and different pinout */
#if !defined(CONFIG_RMII)
immr->im_ioport.iop_papar |= 0xf830;
immr->im_ioport.iop_padir |= 0x0830;
immr->im_ioport.iop_padir &= ~0xf000;
immr->im_cpm.cp_pbpar |= 0x00001001;
immr->im_cpm.cp_pbdir &= ~0x00001001;
immr->im_ioport.iop_pcpar |= 0x000c;
immr->im_ioport.iop_pcdir &= ~0x000c;
immr->im_cpm.cp_pepar |= 0x00000003;
immr->im_cpm.cp_pedir |= 0x00000003;
immr->im_cpm.cp_peso &= ~0x00000003;
immr->im_cpm.cp_cptr &= ~0x00000100;
#else
#if !defined(CONFIG_FEC1_PHY_NORXERR)
immr->im_ioport.iop_papar |= 0x1000;
immr->im_ioport.iop_padir &= ~0x1000;
#endif
immr->im_ioport.iop_papar |= 0xe810;
immr->im_ioport.iop_padir |= 0x0810;
immr->im_ioport.iop_padir &= ~0xe000;
immr->im_cpm.cp_pbpar |= 0x00000001;
immr->im_cpm.cp_pbdir &= ~0x00000001;
immr->im_cpm.cp_cptr |= 0x00000100;
immr->im_cpm.cp_cptr &= ~0x00000050;
#endif /* !CONFIG_RMII */
#elif !defined(CONFIG_ICU862) && !defined(CONFIG_IAD210)
/*
* Configure all of port D for MII.
*/
immr->im_ioport.iop_pdpar = 0x1fff;
/*
* Bits moved from Rev. D onward
*/
if ((get_immr(0) & 0xffff) < 0x0501)
immr->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */
else
immr->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */
#else
/*
* Configure port A for MII.
*/
#if defined(CONFIG_ICU862) && defined(CFG_DISCOVER_PHY)
/*
* On the ICU862 board the MII-MDC pin is routed to PD8 pin
* * of CPU, so for this board we need to configure Utopia and
* * enable PD8 to MII-MDC function
*/
immr->im_ioport.iop_pdpar |= 0x4080;
#endif
/*
* Has Utopia been configured?
*/
if (immr->im_ioport.iop_pdpar & (0x8000 >> 1)) {
/*
* YES - Use MUXED mode for UTOPIA bus.
* This frees Port A for use by MII (see 862UM table 41-6).
*/
immr->im_ioport.utmode &= ~0x80;
} else {
/*
* NO - set SPLIT mode for UTOPIA bus.
*
* This doesn't really effect UTOPIA (which isn't
* enabled anyway) but just tells the 862
* to use port A for MII (see 862UM table 41-6).
*/
immr->im_ioport.utmode |= 0x80;
}
#endif /* !defined(CONFIG_ICU862) */
#endif /* CONFIG_ETHER_ON_FEC1 */
} else if (fecidx == 1) {
#if defined(CONFIG_ETHER_ON_FEC2)
#if defined(CONFIG_DUET) /* MPC87x/88x have got 2 FECs and different pinout */
#if !defined(CONFIG_RMII)
#warning this configuration is not tested; please report if it works
immr->im_cpm.cp_pepar |= 0x0003fffc;
immr->im_cpm.cp_pedir |= 0x0003fffc;
immr->im_cpm.cp_peso &= ~0x000087fc;
immr->im_cpm.cp_peso |= 0x00037800;
immr->im_cpm.cp_cptr &= ~0x00000080;
#else
#if !defined(CONFIG_FEC2_PHY_NORXERR)
immr->im_cpm.cp_pepar |= 0x00000010;
immr->im_cpm.cp_pedir |= 0x00000010;
immr->im_cpm.cp_peso &= ~0x00000010;
#endif
immr->im_cpm.cp_pepar |= 0x00039620;
immr->im_cpm.cp_pedir |= 0x00039620;
immr->im_cpm.cp_peso |= 0x00031000;
immr->im_cpm.cp_peso &= ~0x00008620;
immr->im_cpm.cp_cptr |= 0x00000080;
immr->im_cpm.cp_cptr &= ~0x00000028;
#endif /* CONFIG_RMII */
#endif /* CONFIG_DUET */
#endif /* CONFIG_ETHER_ON_FEC2 */
/* reset the LXT970 PHY */
*bcsr4 &= ~BCSR4_FETHRST;
udelay (10);
*bcsr4 |= BCSR4_FETHRST;
udelay (10);
}
}
static int fec_init (struct eth_device *dev, bd_t * bd)
{
struct ether_fcc_info_s *efis = dev->priv;
volatile immap_t *immr = (immap_t *) CFG_IMMR;
volatile fec_t *fecp =
(volatile fec_t *) (CFG_IMMR + efis->fecp_offset);
int i;
if (efis->ether_index == 0) {
#if defined(CONFIG_FADS) /* FADS family uses FPGA (BCSR) to control PHYs */
#if defined(CONFIG_DUET_ADS)
*(vu_char *) BCSR5 &= ~(BCSR5_MII1_EN | BCSR5_MII1_RST);
#else
/* configure FADS for fast (FEC) ethernet, half-duplex */
/* The LXT970 needs about 50ms to recover from reset, so
* wait for it by discovering the PHY before leaving eth_init().
*/
{
volatile uint *bcsr4 = (volatile uint *) BCSR4;
*bcsr4 = (*bcsr4 & ~(BCSR4_FETH_EN | BCSR4_FETHCFG1))
| (BCSR4_FETHCFG0 | BCSR4_FETHFDE |
BCSR4_FETHRST);
/* reset the LXT970 PHY */
*bcsr4 &= ~BCSR4_FETHRST;
udelay (10);
*bcsr4 |= BCSR4_FETHRST;
udelay (10);
}
#endif /* CONFIG_DUET_ADS */
#endif /* CONFIG_FADS */
}
/* Whack a reset.
* A delay is required between a reset of the FEC block and
* initialization of other FEC registers because the reset takes
@@ -269,15 +588,22 @@ static int fec_init(struct eth_device* dev, bd_t * bd)
/* Set station address
*/
#define ea eth_get_dev()->enetaddr
fecp->fec_addr_low = (ea[0] << 24) | (ea[1] << 16) |
(ea[2] << 8) | (ea[3] ) ;
fecp->fec_addr_high = (ea[4] << 8) | (ea[5] ) ;
fecp->fec_addr_low = (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
fecp->fec_addr_high = (ea[4] << 8) | (ea[5]);
#undef ea
#if (CONFIG_COMMANDS & CFG_CMD_CDP)
/*
* Turn on multicast address hash table
*/
fecp->fec_hash_table_high = 0xffffffff;
fecp->fec_hash_table_low = 0xffffffff;
#else
/* Clear multicast address hash table
*/
fecp->fec_hash_table_high = 0;
fecp->fec_hash_table_low = 0;
fecp->fec_hash_table_low = 0;
#endif
/* Set maximum receive buffer size.
*/
@@ -295,9 +621,10 @@ static int fec_init(struct eth_device* dev, bd_t * bd)
if (!rtx) {
#ifdef CFG_ALLOC_DPRAM
rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + dpram_alloc_align(sizeof(RTXBD),8));
rtx = (RTXBD *) (immr->im_cpm.cp_dpmem +
dpram_alloc_align (sizeof (RTXBD), 8));
#else
rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + CPM_FEC_BASE);
rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + CPM_FEC_BASE);
#endif
}
/*
@@ -306,8 +633,8 @@ static int fec_init(struct eth_device* dev, bd_t * bd)
* Empty, Wrap
*/
for (i = 0; i < PKTBUFSRX; i++) {
rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
rtx->rxbd[i].cbd_datlen = 0; /* Reset */
rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
rtx->rxbd[i].cbd_datlen = 0; /* Reset */
rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
}
rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
@@ -318,8 +645,8 @@ static int fec_init(struct eth_device* dev, bd_t * bd)
* Last, Tx CRC
*/
for (i = 0; i < TX_BUF_CNT; i++) {
rtx->txbd[i].cbd_sc = BD_ENET_TX_LAST | BD_ENET_TX_TC;
rtx->txbd[i].cbd_datlen = 0; /* Reset */
rtx->txbd[i].cbd_sc = BD_ENET_TX_LAST | BD_ENET_TX_TC;
rtx->txbd[i].cbd_datlen = 0; /* Reset */
rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]);
}
rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
@@ -331,10 +658,10 @@ static int fec_init(struct eth_device* dev, bd_t * bd)
/* Enable MII mode
*/
#if 0 /* Full duplex mode */
#if 0 /* Full duplex mode */
fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE;
fecp->fec_x_cntrl = FEC_TCNTRL_FDEN;
#else /* Half duplex mode */
#else /* Half duplex mode */
fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE | FEC_RCNTRL_DRT;
fecp->fec_x_cntrl = 0;
#endif
@@ -343,86 +670,69 @@ static int fec_init(struct eth_device* dev, bd_t * bd)
*/
fecp->fec_fun_code = 0x78000000;
/* Set MII speed to 2.5 MHz or slightly below.
* According to the MPC860T (Rev. D) Fast ethernet controller user
* manual (6.2.14),
* the MII management interface clock must be less than or equal
* to 2.5 MHz.
* This MDC frequency is equal to system clock / (2 * MII_SPEED).
* Then MII_SPEED = system_clock / 2 * 2,5 Mhz.
/*
* Setup the pin configuration of the FEC
*/
fecp->fec_mii_speed = ((bd->bi_intfreq + 4999999) / 5000000) << 1;
#if defined(CONFIG_DUET) /* MPC87x/88x have got 2 FECs and different pinout */
immr->im_ioport.iop_papar |= 0xf830;
immr->im_ioport.iop_padir |= 0x0830;
immr->im_ioport.iop_padir &= ~0xf000;
immr->im_cpm.cp_pbpar |= 0x00001001;
immr->im_cpm.cp_pbdir &= ~0x00001001;
immr->im_ioport.iop_pcpar |= 0x000c;
immr->im_ioport.iop_pcdir &= ~0x000c;
immr->im_ioport.iop_pdpar |= 0x0080;
immr->im_ioport.iop_pddir &= ~0x0080;
immr->im_cpm.cp_pepar |= 0x00000003;
immr->im_cpm.cp_pedir |= 0x00000003;
immr->im_cpm.cp_peso &= ~0x00000003;
#elif !defined(CONFIG_ICU862) && !defined(CONFIG_IAD210)
/* Configure all of port D for MII.
*/
immr->im_ioport.iop_pdpar = 0x1fff;
/* Bits moved from Rev. D onward */
if ((get_immr (0) & 0xffff) < 0x0501) {
immr->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */
} else {
immr->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */
}
#else
/* Configure port A for MII.
*/
#if defined(CONFIG_ICU862) && defined(CFG_DISCOVER_PHY)
/* On the ICU862 board the MII-MDC pin is routed to PD8 pin
* of CPU, so for this board we need to configure Utopia and
* enable PD8 to MII-MDC function */
immr->im_ioport.iop_pdpar |= 0x4080;
#endif
/* Has Utopia been configured? */
if (immr->im_ioport.iop_pdpar & (0x8000 >> 1)) {
/*
* YES - Use MUXED mode for UTOPIA bus.
* This frees Port A for use by MII (see 862UM table 41-6).
*/
immr->im_ioport.utmode &= ~0x80;
} else {
/*
* NO - set SPLIT mode for UTOPIA bus.
*
* This doesn't really effect UTOPIA (which isn't
* enabled anyway) but just tells the 862
* to use port A for MII (see 862UM table 41-6).
*/
immr->im_ioport.utmode |= 0x80;
}
#endif /* !defined(CONFIG_ICU862) */
fec_pin_init (efis->ether_index);
rxIdx = 0;
txIdx = 0;
/* Now enable the transmit and receive processing
/*
* Now enable the transmit and receive processing
*/
fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN;
if (efis->phy_addr == -1) {
#ifdef CFG_DISCOVER_PHY
/* wait for the PHY to wake up after reset
/*
* wait for the PHY to wake up after reset
*/
efis->actual_phy_addr = mii_discover_phy (dev);
#else
efis->actual_phy_addr = -1;
#endif
if (efis->actual_phy_addr == -1) {
printf ("Unable to discover phy!\n");
return 0;
}
} else {
efis->actual_phy_addr = efis->phy_addr;
}
#if defined(CONFIG_MII) && defined(CONFIG_RMII)
/* the MII interface is connected to FEC1
* so for the miiphy_xxx function to work we must
* call mii_init since fec_halt messes the thing up
*/
mii_discover_phy();
if (efis->ether_index != 0)
mii_init();
/*
* adapt the RMII speed to the speed of the phy
*/
if (miiphy_speed (efis->actual_phy_addr) == _100BASET) {
fec_100Mbps (dev);
} else {
fec_10Mbps (dev);
}
#endif
#if defined(CONFIG_MII)
/*
* adapt to the half/full speed settings
*/
if (miiphy_duplex (efis->actual_phy_addr) == FULL) {
fec_full_duplex (dev);
} else {
fec_half_duplex (dev);
}
#endif
/* And last, try to fill Rx Buffer Descriptors */
fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */
fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */
efis->initialized = 1;
return 1;
}
@@ -430,24 +740,37 @@ static int fec_init(struct eth_device* dev, bd_t * bd)
static void fec_halt(struct eth_device* dev)
{
#if 0
volatile immap_t *immr = (immap_t *)CFG_IMMR;
immr->im_cpm.cp_scc[SCC_ENET].scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
#endif
struct ether_fcc_info_s *efis = dev->priv;
volatile fec_t *fecp = (volatile fec_t *)(CFG_IMMR + efis->fecp_offset);
int i;
/* avoid halt if initialized; mii gets stuck otherwise */
if (!efis->initialized)
return;
/* Whack a reset.
* A delay is required between a reset of the FEC block and
* initialization of other FEC registers because the reset takes
* some time to complete. If you don't delay, subsequent writes
* to FEC registers might get killed by the reset routine which is
* still in progress.
*/
fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
for (i = 0;
(fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
++i) {
udelay (1);
}
if (i == FEC_RESET_DELAY) {
printf ("FEC_RESET_DELAY timeout\n");
return;
}
efis->initialized = 0;
}
#if 0
void restart(void)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
immr->im_cpm.cp_scc[SCC_ENET].scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
}
#endif
#if defined(CFG_DISCOVER_PHY) || (CONFIG_COMMANDS & CFG_CMD_MII)
static int phyaddr = -1; /* didn't find a PHY yet */
static uint phytype;
#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
/* Make MII read/write commands for the FEC.
*/
@@ -489,14 +812,20 @@ mii_send(uint mii_cmd)
{
uint mii_reply;
volatile fec_t *ep;
int cnt;
ep = &(((immap_t *)CFG_IMMR)->im_cpm.cp_fec);
ep->fec_mii_data = mii_cmd; /* command to phy */
/* wait for mii complete */
while (!(ep->fec_ievent & FEC_ENET_MII))
; /* spin until done */
cnt = 0;
while (!(ep->fec_ievent & FEC_ENET_MII)) {
if (++cnt > 1000) {
printf("mii_send STUCK!\n");
break;
}
}
mii_reply = ep->fec_mii_data; /* result from phy */
ep->fec_ievent = FEC_ENET_MII; /* clear MII complete */
#if 0
@@ -508,12 +837,13 @@ mii_send(uint mii_cmd)
#endif /* CFG_DISCOVER_PHY || (CONFIG_COMMANDS & CFG_CMD_MII) */
#if defined(CFG_DISCOVER_PHY)
static void
mii_discover_phy(void)
static int mii_discover_phy(struct eth_device *dev)
{
#define MAX_PHY_PASSES 11
uint phyno;
int pass;
uint phytype;
int phyaddr;
phyaddr = -1; /* didn't find a PHY yet */
for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) {
@@ -571,12 +901,11 @@ mii_discover_phy(void)
if (phyaddr < 0) {
printf("No PHY device found.\n");
}
return phyaddr;
}
#endif /* CFG_DISCOVER_PHY */
#if (CONFIG_COMMANDS & CFG_CMD_MII) && !defined(CONFIG_BITBANGMII)
static int mii_init_done = 0;
#if (defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)) && !defined(CONFIG_BITBANGMII)
/****************************************************************************
* mii_init -- Initialize the MII for MII command without ethernet
@@ -585,16 +914,11 @@ static int mii_init_done = 0;
*/
void mii_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
bd_t *bd = gd->bd;
volatile immap_t *immr = (immap_t *) CFG_IMMR;
volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
int i;
int i, j;
if (mii_init_done != 0) {
return;
}
for (j = 0; j < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); j++) {
/* Whack a reset.
* A delay is required between a reset of the FEC block and
@@ -623,76 +947,16 @@ void mii_init (void)
*/
fecp->fec_ievent = 0xffc0;
/* Set MII speed to 2.5 MHz or slightly below.
* According to the MPC860T (Rev. D) Fast ethernet controller user
* manual (6.2.14),
* the MII management interface clock must be less than or equal
* to 2.5 MHz.
* This MDC frequency is equal to system clock / (2 * MII_SPEED).
* Then MII_SPEED = system_clock / 2 * 2,5 Mhz.
*/
fecp->fec_mii_speed = ((bd->bi_intfreq + 4999999) / 5000000) << 1;
#if defined(CONFIG_DUET) /* MPC87x/88x have got 2 FECs and different pinout */
immr->im_ioport.iop_papar |= 0xf830;
immr->im_ioport.iop_padir |= 0x0830;
immr->im_ioport.iop_padir &= ~0xf000;
immr->im_cpm.cp_pbpar |= 0x00001001;
immr->im_cpm.cp_pbdir &= ~0x00001001;
immr->im_ioport.iop_pcpar |= 0x000c;
immr->im_ioport.iop_pcdir &= ~0x000c;
immr->im_ioport.iop_pdpar |= 0x0080;
immr->im_ioport.iop_pddir &= ~0x0080;
immr->im_cpm.cp_pepar |= 0x00000003;
immr->im_cpm.cp_pedir |= 0x00000003;
immr->im_cpm.cp_peso &= ~0x00000003;
#elif !defined(CONFIG_ICU862) && !defined(CONFIG_IAD210)
/* Configure all of port D for MII.
*/
immr->im_ioport.iop_pdpar = 0x1fff;
/* Bits moved from Rev. D onward */
if ((get_immr (0) & 0xffff) < 0x0501) {
immr->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */
} else {
immr->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */
}
#else
/* Configure port A for MII.
/* Setup the pin configuration of the FEC(s)
*/
fec_pin_init(ether_fcc_info[i].ether_index);
#if defined(CONFIG_ICU862)
/* On the ICU862 board the MII-MDC pin is routed to PD8 pin
* of CPU, so for this board we need to configure Utopia and
* enable PD8 to MII-MDC function */
immr->im_ioport.iop_pdpar |= 0x4080;
#endif
/* Has Utopia been configured? */
if (immr->im_ioport.iop_pdpar & (0x8000 >> 1)) {
/*
* YES - Use MUXED mode for UTOPIA bus.
* This frees Port A for use by MII (see 862UM table 41-6).
*/
immr->im_ioport.utmode &= ~0x80;
} else {
/*
* NO - set SPLIT mode for UTOPIA bus.
*
* This doesn't really effect UTOPIA (which isn't
* enabled anyway) but just tells the 862
* to use port A for MII (see 862UM table 41-6).
*/
immr->im_ioport.utmode |= 0x80;
}
#endif /* !defined(CONFIG_ICU862) */
/* Now enable the transmit and receive processing
*/
fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN;
mii_init_done = 1;
}
}
/*****************************************************************************
* Read and write a MII PHY register, routines used by MII Utilities
*
@@ -714,28 +978,23 @@ int miiphy_read(unsigned char addr, unsigned char reg, unsigned short *value)
rdreg = mii_send(mk_mii_read(addr, reg));
*value = rdreg;
#ifdef MII_DEBUG
printf ("0x%04x\n", *value);
#endif
return 0;
}
int miiphy_write(unsigned char addr, unsigned char reg, unsigned short value)
{
short rdreg; /* register working value */
#ifdef MII_DEBUG
printf ("miiphy_write(0x%x) @ 0x%x = ", reg, addr);
#endif
rdreg = mii_send(mk_mii_write(addr, reg, value));
#ifdef MII_DEBUG
printf ("0x%04x\n", value);
#endif
return 0;
}
#endif /* (CONFIG_COMMANDS & CFG_CMD_MII) && !defined(CONFIG_BITBANGMII)*/

View File

@@ -87,12 +87,8 @@ void dev_print (block_dev_desc_t *dev_desc)
if ((dev_desc->lba * dev_desc->blksz)>0L) {
ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem;
lbaint_t lba;
#ifdef CONFIG_LBA48
if (dev_desc->lba48support)
lba = dev_desc->lba48;
else
#endif
lba = dev_desc->lba;
lba = dev_desc->lba;
lba512 = (lba * (dev_desc->blksz/512));
mb = (10 * lba512) / 2048; /* 2048 = (1024 * 1024) / 512 MB */
@@ -104,7 +100,7 @@ void dev_print (block_dev_desc_t *dev_desc)
gb_quot = gb / 10;
gb_rem = gb - (10 * gb_quot);
#ifdef CONFIG_LBA48
if (dev_desc->lba48support)
if (dev_desc->lba48)
printf (" Supports 48-bit addressing\n");
#endif
#if defined(CFG_64BIT_LBA) && defined(CFG_64BIT_VSPRINTF)

View File

@@ -1,9 +1,12 @@
---------------------------------------------------------------------------
Build target Flash address | BDI "go" command | Reset Vector
---------------------------------------------------------------------------
MPC5200LITE 0xFFF00000 | 0xFFF00100 | 0xFFF00100
MPC5200LITE_LOWBOOT 0xFF000000 | 0xFF000100 | 0x00000100
MPC5200LITE_LOWBOOT08 0xFF800000 | 0xFF800100 | 0x00000100
Lite5200 0xFFF00000 | 0xFFF00100 | 0xFFF00100
Lite5200_LOWBOOT 0xFF000000 | 0xFF000100 | 0x00000100
Lite5200_LOWBOOT08 0xFF800000 | 0xFF800100 | 0x00000100
icecube_5200 0xFFF00000 | 0xFFF00100 | 0xFFF00100
icecube_5200_LOWBOOT 0xFF000000 | 0xFF000100 | 0x00000100
icecube_5200_LOWBOOT08 0xFF800000 | 0xFF800100 | 0x00000100
icecube_5200_DDR 0xFFF00000 | 0xFFF00100 | 0xFFF00100
icecube_5200_DDR_LOWBOOT 0xFF800000 | 0xFF800100 | 0x00000100
icecube_5200_DDR_LOWBOOT08 0xFF800000 | 0xFF800100 | 0x00000100

24
doc/README.JFFS2_NAND Normal file
View File

@@ -0,0 +1,24 @@
JFFS2 NAND support:
To ebable, use the following #define in the board configuration file:
#define CONFIG_JFFS2_NAND 1
Configuration of partitions is similar to how this is done in U-Boot
for JFFS2 on top NOR flash. If a single parition is used, it can be
configured using the following #defines in the configuration file:
#define CONFIG_JFFS2_NAND_DEV 0 /* nand device jffs2 lives on */
#define CONFIG_JFFS2_NAND_OFF 0 /* start of jffs2 partition */
#define CONFIG_JFFS2_NAND_SIZE 2*1024*1024 /* size of jffs2 partition */
If more than a single partition is desired, the user can define a
CFG_JFFS_CUSTOM_PART macro and implement a
struct part_info* jffs2_part_info(int part_num)
function in a board-specific module. An example of such function is
available in common/cmd_jffs2.c
The default configuration for the DAVE board has a single JFFS2
partition of 2 MB size.

48
doc/README.PXA_CF Normal file
View File

@@ -0,0 +1,48 @@
These are brief instructions on how to add support for CF adapters to
custom designed PXA boards. You need to set the parameters in the
config file. This should work for most implementations especially if you
follow the connections of the standard lubbock. Anyway just the block
marked memory configuration should be touched since the other parameters
are imposed by the PXA architecture.
#define CONFIG_PXA_PCMCIA 1
#define CONFIG_PXA_IDE 1
#define CONFIG_PCMCIA_SLOT_A 1
/* just to keep build system happy */
#define CFG_PCMCIA_MEM_ADDR 0x28000000
#define CFG_PCMCIA_MEM_SIZE 0x10000000
#define CFG_MECR_VAL 0x00000000
#define CFG_MCMEM0_VAL 0x00004204
#define CFG_MCMEM1_VAL 0x00000000
#define CFG_MCATT0_VAL 0x00010504
#define CFG_MCATT1_VAL 0x00000000
#define CFG_MCIO0_VAL 0x00008407
#define CFG_MCIO1_VAL 0x00000000
/* memory configuration */
#define CFG_IDE_MAXBUS 1
/* max. 1 IDE bus */
#define CFG_IDE_MAXDEVICE 1
/* max. 1 drive per IDE bus */
#define CFG_ATA_IDE0_OFFSET 0x0000
#define CFG_ATA_BASE_ADDR 0x20000000
/* Offset for data I/O */
#define CFG_ATA_DATA_OFFSET 0x1f0
/* Offset for normal register accesses */
#define CFG_ATA_REG_OFFSET 0x1f0
/* Offset for alternate registers */
#define CFG_ATA_ALT_OFFSET 0x3f0
Another important point is that maybe you have to power the pcmcia
subsystem. This is very board specific, for an example on how to
do it please search for CONFIG_EXADRON1 in cmd_pcmcia.c

15
doc/README.VLAN Normal file
View File

@@ -0,0 +1,15 @@
U-Boot has networking support for VLANs (802.1q), and CDP (Cisco
Discovery Protocol).
You control the sending/receiving of VLAN tagged packets with the
"vlan" environmental variable. When not present no tagging is
performed.
CDP is used mainly to discover your device VLAN(s) when connected to
a Cisco switch.
Note: In order to enable CDP support a small change is needed in the
networking driver. You have to enable reception of the
01:00:0c:cc:cc:cc MAC address which is a multicast address.
Various defines control CDP; see the README section.

View File

@@ -37,9 +37,10 @@ OBJS = 3c589.o 5701rls.o ali512x.o \
pci.o pci_auto.o pci_indirect.o \
pcnet.o plb2800_eth.o \
ps2ser.o ps2mult.o pc_keyb.o keyboard.o \
rtl8019.o rtl8139.o \
s3c24x0_i2c.o sed13806.o \
serial.o serial_max3100.o serial_pl011.o serial_pl010.o \
rtl8019.o rtl8139.o rtl8169.o \
s3c24x0_i2c.o sed13806.o sed156x.o \
serial.o serial_max3100.o serial_pl010.o serial_pl011.o \
serial_xuartlite.o sl811_usb.o \
smc91111.o smiLynxEM.o status_led.o sym53c8xx.o \
ti_pci1410a.o tigon3.o w83c553f.o omap1510_i2c.o \
usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \

View File

@@ -103,14 +103,14 @@ int pci_hose_write_config_##size##_via_dword(struct pci_controller *hose,\
pci_dev_t dev, \
int offset, type val) \
{ \
u32 val32, mask, ldata; \
u32 val32, mask, ldata, shift; \
\
if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)\
return -1; \
\
mask = val_mask; \
ldata = (((unsigned long)val) & mask) << ((offset & (int)off_mask) * 8);\
mask <<= ((mask & (int)off_mask) * 8); \
shift = ((offset & (int)off_mask) * 8); \
ldata = (((unsigned long)val) & val_mask) << shift; \
mask = val_mask << shift; \
val32 = (val32 & ~mask) | ldata; \
\
if (pci_hose_write_config_dword(hose, dev, offset & 0xfc, val32) < 0)\

888
drivers/rtl8169.c Normal file
View File

@@ -0,0 +1,888 @@
/*
* rtl8169.c : U-Boot driver for the RealTek RTL8169
*
* Masami Komiya (mkomiya@sonare.it)
*
* Most part is taken from r8169.c of etherboot
*
*/
/**************************************************************************
* r8169.c: Etherboot device driver for the RealTek RTL-8169 Gigabit
* Written 2003 by Timothy Legge <tlegge@rogers.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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Portions of this code based on:
* r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver
* for Linux kernel 2.4.x.
*
* Written 2002 ShuChen <shuchen@realtek.com.tw>
* See Linux Driver for full information
*
* Linux Driver Version 1.27a, 10.02.2002
*
* Thanks to:
* Jean Chen of RealTek Semiconductor Corp. for
* providing the evaluation NIC used to develop
* this driver. RealTek's support for Etherboot
* is appreciated.
*
* REVISION HISTORY:
* ================
*
* v1.0 11-26-2003 timlegge Initial port of Linux driver
* v1.5 01-17-2004 timlegge Initial driver output cleanup
*
* Indent Options: indent -kr -i8
***************************************************************************/
#include <common.h>
#include <malloc.h>
#include <net.h>
#include <asm/io.h>
#include <pci.h>
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
defined(CONFIG_RTL8169)
#undef DEBUG_RTL8169
#undef DEBUG_RTL8169_TX
#undef DEBUG_RTL8169_RX
#define drv_version "v1.5"
#define drv_date "01-17-2004"
static u32 ioaddr;
/* Condensed operations for readability. */
#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
#define currticks() get_timer(0)
#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
/* media options */
#define MAX_UNITS 8
static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
/* MAC address length*/
#define MAC_ADDR_LEN 6
/* max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4).*/
#define MAX_ETH_FRAME_SIZE 1536
#define TX_FIFO_THRESH 256 /* In bytes */
#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */
#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */
#define RxPacketMaxSize 0x0800 /* Maximum size supported is 16K-1 */
#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
#define NUM_TX_DESC 1 /* Number of Tx descriptor registers */
#define NUM_RX_DESC 4 /* Number of Rx descriptor registers */
#define RX_BUF_SIZE 1536 /* Rx Buffer size */
#define RX_BUF_LEN 8192
#define RTL_MIN_IO_SIZE 0x80
#define TX_TIMEOUT (6*HZ)
/* write/read MMIO register */
#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg))
#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg))
#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg))
#define RTL_R8(reg) readb (ioaddr + (reg))
#define RTL_R16(reg) readw (ioaddr + (reg))
#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg)))
#define ETH_FRAME_LEN MAX_ETH_FRAME_SIZE
#define ETH_ALEN MAC_ADDR_LEN
#define ETH_ZLEN 60
enum RTL8169_registers {
MAC0 = 0, /* Ethernet hardware address. */
MAR0 = 8, /* Multicast filter. */
TxDescStartAddr = 0x20,
TxHDescStartAddr = 0x28,
FLASH = 0x30,
ERSR = 0x36,
ChipCmd = 0x37,
TxPoll = 0x38,
IntrMask = 0x3C,
IntrStatus = 0x3E,
TxConfig = 0x40,
RxConfig = 0x44,
RxMissed = 0x4C,
Cfg9346 = 0x50,
Config0 = 0x51,
Config1 = 0x52,
Config2 = 0x53,
Config3 = 0x54,
Config4 = 0x55,
Config5 = 0x56,
MultiIntr = 0x5C,
PHYAR = 0x60,
TBICSR = 0x64,
TBI_ANAR = 0x68,
TBI_LPAR = 0x6A,
PHYstatus = 0x6C,
RxMaxSize = 0xDA,
CPlusCmd = 0xE0,
RxDescStartAddr = 0xE4,
EarlyTxThres = 0xEC,
FuncEvent = 0xF0,
FuncEventMask = 0xF4,
FuncPresetState = 0xF8,
FuncForceEvent = 0xFC,
};
enum RTL8169_register_content {
/*InterruptStatusBits */
SYSErr = 0x8000,
PCSTimeout = 0x4000,
SWInt = 0x0100,
TxDescUnavail = 0x80,
RxFIFOOver = 0x40,
RxUnderrun = 0x20,
RxOverflow = 0x10,
TxErr = 0x08,
TxOK = 0x04,
RxErr = 0x02,
RxOK = 0x01,
/*RxStatusDesc */
RxRES = 0x00200000,
RxCRC = 0x00080000,
RxRUNT = 0x00100000,
RxRWT = 0x00400000,
/*ChipCmdBits */
CmdReset = 0x10,
CmdRxEnb = 0x08,
CmdTxEnb = 0x04,
RxBufEmpty = 0x01,
/*Cfg9346Bits */
Cfg9346_Lock = 0x00,
Cfg9346_Unlock = 0xC0,
/*rx_mode_bits */
AcceptErr = 0x20,
AcceptRunt = 0x10,
AcceptBroadcast = 0x08,
AcceptMulticast = 0x04,
AcceptMyPhys = 0x02,
AcceptAllPhys = 0x01,
/*RxConfigBits */
RxCfgFIFOShift = 13,
RxCfgDMAShift = 8,
/*TxConfigBits */
TxInterFrameGapShift = 24,
TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
/*rtl8169_PHYstatus */
TBI_Enable = 0x80,
TxFlowCtrl = 0x40,
RxFlowCtrl = 0x20,
_1000bpsF = 0x10,
_100bps = 0x08,
_10bps = 0x04,
LinkStatus = 0x02,
FullDup = 0x01,
/*GIGABIT_PHY_registers */
PHY_CTRL_REG = 0,
PHY_STAT_REG = 1,
PHY_AUTO_NEGO_REG = 4,
PHY_1000_CTRL_REG = 9,
/*GIGABIT_PHY_REG_BIT */
PHY_Restart_Auto_Nego = 0x0200,
PHY_Enable_Auto_Nego = 0x1000,
/* PHY_STAT_REG = 1; */
PHY_Auto_Neco_Comp = 0x0020,
/* PHY_AUTO_NEGO_REG = 4; */
PHY_Cap_10_Half = 0x0020,
PHY_Cap_10_Full = 0x0040,
PHY_Cap_100_Half = 0x0080,
PHY_Cap_100_Full = 0x0100,
/* PHY_1000_CTRL_REG = 9; */
PHY_Cap_1000_Full = 0x0200,
PHY_Cap_Null = 0x0,
/*_MediaType*/
_10_Half = 0x01,
_10_Full = 0x02,
_100_Half = 0x04,
_100_Full = 0x08,
_1000_Full = 0x10,
/*_TBICSRBit*/
TBILinkOK = 0x02000000,
};
static struct {
const char *name;
u8 version; /* depend on RTL8169 docs */
u32 RxConfigMask; /* should clear the bits supported by this chip */
} rtl_chip_info[] = {
{"RTL-8169", 0x00, 0xff7e1880,},
{"RTL-8169", 0x04, 0xff7e1880,},
};
enum _DescStatusBit {
OWNbit = 0x80000000,
EORbit = 0x40000000,
FSbit = 0x20000000,
LSbit = 0x10000000,
};
struct TxDesc {
u32 status;
u32 vlan_tag;
u32 buf_addr;
u32 buf_Haddr;
};
struct RxDesc {
u32 status;
u32 vlan_tag;
u32 buf_addr;
u32 buf_Haddr;
};
/* Define the TX Descriptor */
static u8 tx_ring[NUM_TX_DESC * sizeof(struct TxDesc) + 256];
/* __attribute__ ((aligned(256))); */
/* Create a static buffer of size RX_BUF_SZ for each
TX Descriptor. All descriptors point to a
part of this buffer */
static unsigned char txb[NUM_TX_DESC * RX_BUF_SIZE];
/* Define the RX Descriptor */
static u8 rx_ring[NUM_RX_DESC * sizeof(struct TxDesc) + 256];
/* __attribute__ ((aligned(256))); */
/* Create a static buffer of size RX_BUF_SZ for each
RX Descriptor All descriptors point to a
part of this buffer */
static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE];
struct rtl8169_private {
void *mmio_addr; /* memory map physical address */
int chipset;
unsigned long cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
unsigned long cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
unsigned long dirty_tx;
unsigned char *TxDescArrays; /* Index of Tx Descriptor buffer */
unsigned char *RxDescArrays; /* Index of Rx Descriptor buffer */
struct TxDesc *TxDescArray; /* Index of 256-alignment Tx Descriptor buffer */
struct RxDesc *RxDescArray; /* Index of 256-alignment Rx Descriptor buffer */
unsigned char *RxBufferRings; /* Index of Rx Buffer */
unsigned char *RxBufferRing[NUM_RX_DESC]; /* Index of Rx Buffer array */
unsigned char *Tx_skbuff[NUM_TX_DESC];
} tpx;
static struct rtl8169_private *tpc;
static const u16 rtl8169_intr_mask =
SYSErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr |
TxOK | RxErr | RxOK;
static const unsigned int rtl8169_rx_config =
(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
static struct pci_device_id supported[] = {
{PCI_VENDOR_ID_REALTEK, 0x8169},
{}
};
void mdio_write(int RegAddr, int value)
{
int i;
RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
udelay(1000);
for (i = 2000; i > 0; i--) {
/* Check if the RTL8169 has completed writing to the specified MII register */
if (!(RTL_R32(PHYAR) & 0x80000000)) {
break;
} else {
udelay(100);
}
}
}
int mdio_read(int RegAddr)
{
int i, value = -1;
RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
udelay(1000);
for (i = 2000; i > 0; i--) {
/* Check if the RTL8169 has completed retrieving data from the specified MII register */
if (RTL_R32(PHYAR) & 0x80000000) {
value = (int) (RTL_R32(PHYAR) & 0xFFFF);
break;
} else {
udelay(100);
}
}
return value;
}
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
static int rtl8169_init_board(struct eth_device *dev)
{
int i;
u32 tmp;
#ifdef DEBUG_RTL8169
printf ("%s\n", __FUNCTION__);
#endif
ioaddr = dev->iobase;
/* Soft reset the chip. */
RTL_W8(ChipCmd, CmdReset);
/* Check that the chip has finished the reset. */
for (i = 1000; i > 0; i--)
if ((RTL_R8(ChipCmd) & CmdReset) == 0)
break;
else
udelay(10);
/* identify chip attached to board */
tmp = RTL_R32(TxConfig);
tmp = ((tmp & 0x7c000000) + ((tmp & 0x00800000) << 2)) >> 24;
for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--){
if (tmp == rtl_chip_info[i].version) {
tpc->chipset = i;
goto match;
}
}
/* if unknown chip, assume array element #0, original RTL-8169 in this case */
printf("PCI device %s: unknown chip version, assuming RTL-8169\n", dev->name);
printf("PCI device: TxConfig = 0x%hX\n", (unsigned long) RTL_R32(TxConfig));
tpc->chipset = 0;
match:
return 0;
}
/**************************************************************************
RECV - Receive a frame
***************************************************************************/
static int rtl_recv(struct eth_device *dev)
{
/* return true if there's an ethernet packet ready to read */
/* nic->packet should contain data on return */
/* nic->packetlen should contain length of data */
int cur_rx;
int length = 0;
#ifdef DEBUG_RTL8169_RX
printf ("%s\n", __FUNCTION__);
#endif
ioaddr = dev->iobase;
cur_rx = tpc->cur_rx;
if ((tpc->RxDescArray[cur_rx].status & OWNbit) == 0) {
if (!(tpc->RxDescArray[cur_rx].status & RxRES)) {
unsigned char rxdata[RX_BUF_LEN];
length = (int) (tpc->RxDescArray[cur_rx].
status & 0x00001FFF) - 4;
memcpy(rxdata, tpc->RxBufferRing[cur_rx], length);
NetReceive(rxdata, length);
if (cur_rx == NUM_RX_DESC - 1)
tpc->RxDescArray[cur_rx].status =
(OWNbit | EORbit) + RX_BUF_SIZE;
else
tpc->RxDescArray[cur_rx].status =
OWNbit + RX_BUF_SIZE;
tpc->RxDescArray[cur_rx].buf_addr =
virt_to_bus(tpc->RxBufferRing[cur_rx]);
} else {
puts("Error Rx");
}
cur_rx = (cur_rx + 1) % NUM_RX_DESC;
tpc->cur_rx = cur_rx;
return 1;
}
tpc->cur_rx = cur_rx;
return (0); /* initially as this is called to flush the input */
}
#define HZ 1000
/**************************************************************************
SEND - Transmit a frame
***************************************************************************/
static int rtl_send(struct eth_device *dev, volatile void *packet, int length)
{
/* send the packet to destination */
u32 to;
u8 *ptxb;
int entry = tpc->cur_tx % NUM_TX_DESC;
u32 len = length;
#ifdef DEBUG_RTL8169_TX
int stime = currticks();
printf ("%s\n", __FUNCTION__);
printf("sending %d bytes\n", len);
#endif
ioaddr = dev->iobase;
/* point to the current txb incase multiple tx_rings are used */
ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE];
memcpy(ptxb, (char *)packet, (int)length);
while (len < ETH_ZLEN)
ptxb[len++] = '\0';
tpc->TxDescArray[entry].buf_addr = virt_to_bus(ptxb);
if (entry != (NUM_TX_DESC - 1)) {
tpc->TxDescArray[entry].status =
(OWNbit | FSbit | LSbit) | ((len > ETH_ZLEN) ?
len : ETH_ZLEN);
} else {
tpc->TxDescArray[entry].status =
(OWNbit | EORbit | FSbit | LSbit) |
((len > ETH_ZLEN) ? length : ETH_ZLEN);
}
RTL_W8(TxPoll, 0x40); /* set polling bit */
tpc->cur_tx++;
to = currticks() + TX_TIMEOUT;
while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to)); /* wait */
if (currticks() >= to) {
#ifdef DEBUG_RTL8169_TX
puts ("tx timeout/error\n");
printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime);
#endif
return 0;
} else {
#ifdef DEBUG_RTL8169_TX
puts("tx done\n");
#endif
return length;
}
}
static void rtl8169_set_rx_mode(struct eth_device *dev)
{
u32 mc_filter[2]; /* Multicast hash filter */
int rx_mode;
u32 tmp = 0;
#ifdef DEBUG_RTL8169
printf ("%s\n", __FUNCTION__);
#endif
/* IFF_ALLMULTI */
/* Too many to filter perfectly -- accept all multicasts. */
rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
mc_filter[1] = mc_filter[0] = 0xffffffff;
tmp = rtl8169_rx_config | rx_mode | (RTL_R32(RxConfig) &
rtl_chip_info[tpc->chipset].RxConfigMask);
RTL_W32(RxConfig, tmp);
RTL_W32(MAR0 + 0, mc_filter[0]);
RTL_W32(MAR0 + 4, mc_filter[1]);
}
static void rtl8169_hw_start(struct eth_device *dev)
{
u32 i;
#ifdef DEBUG_RTL8169
int stime = currticks();
printf ("%s\n", __FUNCTION__);
#endif
#if 0
/* Soft reset the chip. */
RTL_W8(ChipCmd, CmdReset);
/* Check that the chip has finished the reset. */
for (i = 1000; i > 0; i--) {
if ((RTL_R8(ChipCmd) & CmdReset) == 0)
break;
else
udelay(10);
}
#endif
RTL_W8(Cfg9346, Cfg9346_Unlock);
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
RTL_W8(EarlyTxThres, EarlyTxThld);
/* For gigabit rtl8169 */
RTL_W16(RxMaxSize, RxPacketMaxSize);
/* Set Rx Config register */
i = rtl8169_rx_config | (RTL_R32(RxConfig) &
rtl_chip_info[tpc->chipset].RxConfigMask);
RTL_W32(RxConfig, i);
/* Set DMA burst size and Interframe Gap Time */
RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
(InterFrameGap << TxInterFrameGapShift));
tpc->cur_rx = 0;
RTL_W32(TxDescStartAddr, virt_to_le32desc(tpc->TxDescArray));
RTL_W32(RxDescStartAddr, virt_to_le32desc(tpc->RxDescArray));
RTL_W8(Cfg9346, Cfg9346_Lock);
udelay(10);
RTL_W32(RxMissed, 0);
rtl8169_set_rx_mode(dev);
/* no early-rx interrupts */
RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
#ifdef DEBUG_RTL8169
printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime);
#endif
}
static void rtl8169_init_ring(struct eth_device *dev)
{
int i;
#ifdef DEBUG_RTL8169
int stime = currticks();
printf ("%s\n", __FUNCTION__);
#endif
tpc->cur_rx = 0;
tpc->cur_tx = 0;
tpc->dirty_tx = 0;
memset(tpc->TxDescArray, 0x0, NUM_TX_DESC * sizeof(struct TxDesc));
memset(tpc->RxDescArray, 0x0, NUM_RX_DESC * sizeof(struct RxDesc));
for (i = 0; i < NUM_TX_DESC; i++) {
tpc->Tx_skbuff[i] = &txb[i];
}
for (i = 0; i < NUM_RX_DESC; i++) {
if (i == (NUM_RX_DESC - 1))
tpc->RxDescArray[i].status =
(OWNbit | EORbit) + RX_BUF_SIZE;
else
tpc->RxDescArray[i].status = OWNbit + RX_BUF_SIZE;
tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
tpc->RxDescArray[i].buf_addr =
virt_to_bus(tpc->RxBufferRing[i]);
}
#ifdef DEBUG_RTL8169
printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime);
#endif
}
/**************************************************************************
RESET - Finish setting up the ethernet interface
***************************************************************************/
static void rtl_reset(struct eth_device *dev, bd_t *bis)
{
int i;
u8 diff;
u32 TxPhyAddr, RxPhyAddr;
#ifdef DEBUG_RTL8169
int stime = currticks();
printf ("%s\n", __FUNCTION__);
#endif
tpc->TxDescArrays = tx_ring;
if (tpc->TxDescArrays == 0)
puts("Allot Error");
/* Tx Desscriptor needs 256 bytes alignment; */
TxPhyAddr = virt_to_bus(tpc->TxDescArrays);
diff = 256 - (TxPhyAddr - ((TxPhyAddr >> 8) << 8));
TxPhyAddr += diff;
tpc->TxDescArray = (struct TxDesc *) (tpc->TxDescArrays + diff);
tpc->RxDescArrays = rx_ring;
/* Rx Desscriptor needs 256 bytes alignment; */
RxPhyAddr = virt_to_bus(tpc->RxDescArrays);
diff = 256 - (RxPhyAddr - ((RxPhyAddr >> 8) << 8));
RxPhyAddr += diff;
tpc->RxDescArray = (struct RxDesc *) (tpc->RxDescArrays + diff);
if (tpc->TxDescArrays == NULL || tpc->RxDescArrays == NULL) {
puts("Allocate RxDescArray or TxDescArray failed\n");
return;
}
rtl8169_init_ring(dev);
rtl8169_hw_start(dev);
/* Construct a perfect filter frame with the mac address as first match
* and broadcast for all others */
for (i = 0; i < 192; i++)
txb[i] = 0xFF;
txb[0] = dev->enetaddr[0];
txb[1] = dev->enetaddr[1];
txb[2] = dev->enetaddr[2];
txb[3] = dev->enetaddr[3];
txb[4] = dev->enetaddr[4];
txb[5] = dev->enetaddr[5];
#ifdef DEBUG_RTL8169
printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime);
#endif
}
/**************************************************************************
HALT - Turn off ethernet interface
***************************************************************************/
static void rtl_halt(struct eth_device *dev)
{
int i;
#ifdef DEBUG_RTL8169
printf ("%s\n", __FUNCTION__);
#endif
ioaddr = dev->iobase;
/* Stop the chip's Tx and Rx DMA processes. */
RTL_W8(ChipCmd, 0x00);
/* Disable interrupts by clearing the interrupt mask. */
RTL_W16(IntrMask, 0x0000);
RTL_W32(RxMissed, 0);
tpc->TxDescArrays = NULL;
tpc->RxDescArrays = NULL;
tpc->TxDescArray = NULL;
tpc->RxDescArray = NULL;
for (i = 0; i < NUM_RX_DESC; i++) {
tpc->RxBufferRing[i] = NULL;
}
}
/**************************************************************************
INIT - Look for an adapter, this routine's visible to the outside
***************************************************************************/
#define board_found 1
#define valid_link 0
static int rtl_init(struct eth_device *dev, bd_t *bis)
{
static int board_idx = -1;
static int printed_version = 0;
int i, rc;
int option = -1, Cap10_100 = 0, Cap1000 = 0;
#ifdef DEBUG_RTL8169
printf ("%s\n", __FUNCTION__);
#endif
ioaddr = dev->iobase;
board_idx++;
printed_version = 1;
/* point to private storage */
tpc = &tpx;
rc = rtl8169_init_board(dev);
if (rc)
return rc;
/* Get MAC address. FIXME: read EEPROM */
for (i = 0; i < MAC_ADDR_LEN; i++)
dev->enetaddr[i] = RTL_R8(MAC0 + i);
#ifdef DEBUG_RTL8169
printf("MAC Address");
for (i = 0; i < MAC_ADDR_LEN; i++)
printf(":%02x", dev->enetaddr[i]);
putc('\n');
#endif
#ifdef DEBUG_RTL8169
/* Print out some hardware info */
printf("%s: at ioaddr 0x%x\n", dev->name, ioaddr);
#endif
/* if TBI is not endbled */
if (!(RTL_R8(PHYstatus) & TBI_Enable)) {
int val = mdio_read(PHY_AUTO_NEGO_REG);
option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
/* Force RTL8169 in 10/100/1000 Full/Half mode. */
if (option > 0) {
#ifdef DEBUG_RTL8169
printf("%s: Force-mode Enabled.\n", dev->name);
#endif
Cap10_100 = 0, Cap1000 = 0;
switch (option) {
case _10_Half:
Cap10_100 = PHY_Cap_10_Half;
Cap1000 = PHY_Cap_Null;
break;
case _10_Full:
Cap10_100 = PHY_Cap_10_Full;
Cap1000 = PHY_Cap_Null;
break;
case _100_Half:
Cap10_100 = PHY_Cap_100_Half;
Cap1000 = PHY_Cap_Null;
break;
case _100_Full:
Cap10_100 = PHY_Cap_100_Full;
Cap1000 = PHY_Cap_Null;
break;
case _1000_Full:
Cap10_100 = PHY_Cap_Null;
Cap1000 = PHY_Cap_1000_Full;
break;
default:
break;
}
mdio_write(PHY_AUTO_NEGO_REG, Cap10_100 | (val & 0x1F)); /* leave PHY_AUTO_NEGO_REG bit4:0 unchanged */
mdio_write(PHY_1000_CTRL_REG, Cap1000);
} else {
#ifdef DEBUG_RTL8169
printf("%s: Auto-negotiation Enabled.\n",
dev->name);
#endif
/* enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged */
mdio_write(PHY_AUTO_NEGO_REG,
PHY_Cap_10_Half | PHY_Cap_10_Full |
PHY_Cap_100_Half | PHY_Cap_100_Full |
(val & 0x1F));
/* enable 1000 Full Mode */
mdio_write(PHY_1000_CTRL_REG, PHY_Cap_1000_Full);
}
/* Enable auto-negotiation and restart auto-nigotiation */
mdio_write(PHY_CTRL_REG,
PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego);
udelay(100);
/* wait for auto-negotiation process */
for (i = 10000; i > 0; i--) {
/* check if auto-negotiation complete */
if (mdio_read(PHY_STAT_REG) & PHY_Auto_Neco_Comp) {
udelay(100);
option = RTL_R8(PHYstatus);
if (option & _1000bpsF) {
#ifdef DEBUG_RTL8169
printf("%s: 1000Mbps Full-duplex operation.\n",
dev->name);
#endif
} else {
#ifdef DEBUG_RTL8169
printf
("%s: %sMbps %s-duplex operation.\n",
dev->name,
(option & _100bps) ? "100" :
"10",
(option & FullDup) ? "Full" :
"Half");
#endif
}
break;
} else {
udelay(100);
}
} /* end for-loop to wait for auto-negotiation process */
} else {
udelay(100);
#ifdef DEBUG_RTL8169
printf
("%s: 1000Mbps Full-duplex operation, TBI Link %s!\n",
dev->name,
(RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed");
#endif
}
return 1;
}
int rtl8169_initialize(bd_t *bis)
{
pci_dev_t devno;
int card_number = 0;
struct eth_device *dev;
u32 iobase;
int idx=0;
while(1){
/* Find RTL8169 */
if ((devno = pci_find_devices(supported, idx++)) < 0)
break;
pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
iobase &= ~0xf;
debug ("rtl8169: REALTEK RTL8169 @0x%x\n", iobase);
dev = (struct eth_device *)malloc(sizeof *dev);
sprintf (dev->name, "RTL8169#%d", card_number);
dev->priv = (void *) devno;
dev->iobase = (int)bus_to_phys(iobase);
dev->init = rtl_reset;
dev->halt = rtl_halt;
dev->send = rtl_send;
dev->recv = rtl_recv;
eth_register (dev);
rtl_init(dev, bis);
card_number++;
}
return card_number;
}
#endif

566
drivers/sed156x.c Normal file
View File

@@ -0,0 +1,566 @@
/*
* (C) Copyright 2003
*
* Pantelis Antoniou <panto@intracom.gr>
* Intracom S.A.
*
* 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 <watchdog.h>
#include <sed156x.h>
#ifdef CONFIG_SED156X
/* configure according to the selected display */
#if defined(CONFIG_SED156X_PG12864Q)
#define LCD_WIDTH 128
#define LCD_HEIGHT 64
#define LCD_LINES 64
#define LCD_PAGES 9
#define LCD_COLUMNS 132
#else
#error Unsupported SED156x configuration
#endif
/* include the font data */
#include <video_font.h>
#if VIDEO_FONT_WIDTH != 8 || VIDEO_FONT_HEIGHT != 16
#error Expecting VIDEO_FONT_WIDTH == 8 && VIDEO_FONT_HEIGHT == 16
#endif
#define LCD_BYTE_WIDTH (LCD_WIDTH / 8)
#define VIDEO_FONT_BYTE_WIDTH (VIDEO_FONT_WIDTH / 8)
#define LCD_TEXT_WIDTH (LCD_WIDTH / VIDEO_FONT_WIDTH)
#define LCD_TEXT_HEIGHT (LCD_HEIGHT / VIDEO_FONT_HEIGHT)
#define LCD_BYTE_LINESZ (LCD_BYTE_WIDTH * VIDEO_FONT_HEIGHT)
const int sed156x_text_width = LCD_TEXT_WIDTH;
const int sed156x_text_height = LCD_TEXT_HEIGHT;
/**************************************************************************************/
#define SED156X_SPI_RXD() (SED156X_SPI_RXD_PORT & SED156X_SPI_RXD_MASK)
#define SED156X_SPI_TXD(x) \
do { \
if (x) \
SED156X_SPI_TXD_PORT |= SED156X_SPI_TXD_MASK; \
else \
SED156X_SPI_TXD_PORT &= ~SED156X_SPI_TXD_MASK; \
} while(0)
#define SED156X_SPI_CLK(x) \
do { \
if (x) \
SED156X_SPI_CLK_PORT |= SED156X_SPI_CLK_MASK; \
else \
SED156X_SPI_CLK_PORT &= ~SED156X_SPI_CLK_MASK; \
} while(0)
#define SED156X_SPI_CLK_TOGGLE() (SED156X_SPI_CLK_PORT ^= SED156X_SPI_CLK_MASK)
#define SED156X_SPI_BIT_DELAY() /* no delay */
#define SED156X_CS(x) \
do { \
if (x) \
SED156X_CS_PORT |= SED156X_CS_MASK; \
else \
SED156X_CS_PORT &= ~SED156X_CS_MASK; \
} while(0)
#define SED156X_A0(x) \
do { \
if (x) \
SED156X_A0_PORT |= SED156X_A0_MASK; \
else \
SED156X_A0_PORT &= ~SED156X_A0_MASK; \
} while(0)
/**************************************************************************************/
/*** LCD Commands ***/
#define LCD_ON 0xAF /* Display ON */
#define LCD_OFF 0xAE /* Display OFF */
#define LCD_LADDR 0x40 /* Display start line set + (6-bit) address */
#define LCD_PADDR 0xB0 /* Page address set + (4-bit) page */
#define LCD_CADRH 0x10 /* Column address set upper + (4-bit) column hi */
#define LCD_CADRL 0x00 /* Column address set lower + (4-bit) column lo */
#define LCD_ADC_NRM 0xA0 /* ADC select Normal */
#define LCD_ADC_REV 0xA1 /* ADC select Reverse */
#define LCD_DSP_NRM 0xA6 /* LCD display Normal */
#define LCD_DSP_REV 0xA7 /* LCD display Reverse */
#define LCD_DPT_NRM 0xA4 /* Display all points Normal */
#define LCD_DPT_ALL 0xA5 /* Display all points ON */
#define LCD_BIAS9 0xA2 /* LCD bias set 1/9 */
#define LCD_BIAS7 0xA3 /* LCD bias set 1/7 */
#define LCD_CAINC 0xE0 /* Read/modify/write */
#define LCD_CAEND 0xEE /* End */
#define LCD_RESET 0xE2 /* Reset */
#define LCD_C_NRM 0xC0 /* Common output mode select Normal direction */
#define LCD_C_RVS 0xC8 /* Common output mode select Reverse direction */
#define LCD_PWRMD 0x28 /* Power control set + (3-bit) mode */
#define LCD_RESRT 0x20 /* V5 v. reg. int. resistor ratio set + (3-bit) ratio */
#define LCD_EVSET 0x81 /* Electronic volume mode set + byte = (6-bit) volume */
#define LCD_SIOFF 0xAC /* Static indicator OFF */
#define LCD_SION 0xAD /* Static indicator ON + byte = (2-bit) mode */
#define LCD_NOP 0xE3 /* NOP */
#define LCD_TEST 0xF0 /* Test/Test mode reset (Note: *DO NOT USE*) */
/*-------------------------------------------------------------------------------
Compound commands
-------------------------------------------------------------------------------
Command Description Commands
---------- ------------------------ -------------------------------------
POWS_ON POWER SAVER ON command LCD_OFF, LCD_D_ALL
POWS_OFF POWER SAVER OFF command LCD_D_NRM
SLEEPON SLEEP mode LCD_SIOFF, POWS_ON
SLEEPOFF SLEEP mode cancel LCD_D_NRM, LCD_SION, LCD_SIS_???
STDBYON STAND BY mode LCD_SION, POWS_ON
STDBYOFF STAND BY mode cancel LCD_D_NRM
-------------------------------------------------------------------------------*/
/*** LCD various parameters ***/
#define LCD_PPB 8 /* Pixels per byte (display is B/W, 1 bit per pixel) */
/*** LCD Status byte masks ***/
#define LCD_S_BUSY 0x80 /* Status Read - BUSY mask */
#define LCD_S_ADC 0x40 /* Status Read - ADC mask */
#define LCD_S_ONOFF 0x20 /* Status Read - ON/OFF mask */
#define LCD_S_RESET 0x10 /* Status Read - RESET mask */
/*** LCD commands parameter masks ***/
#define LCD_M_LADDR 0x3F /* Display start line (6-bit) address mask */
#define LCD_M_PADDR 0x0F /* Page address (4-bit) page mask */
#define LCD_M_CADRH 0x0F /* Column address upper (4-bit) column hi mask */
#define LCD_M_CADRL 0x0F /* Column address lower (4-bit) column lo mask */
#define LCD_M_PWRMD 0x07 /* Power control (3-bit) mode mask */
#define LCD_M_RESRT 0x07 /* V5 v. reg. int. resistor ratio (3-bit) ratio mask */
#define LCD_M_EVSET 0x3F /* Electronic volume mode byte (6-bit) volume mask */
#define LCD_M_SION 0x03 /* Static indicator ON (2-bit) mode mask */
/*** LCD Power control cirquits control masks ***/
#define LCD_PWRBSTR 0x04 /* Power control mode - Booster cirquit ON */
#define LCD_PWRVREG 0x02 /* Power control mode - Voltage regulator cirquit ON */
#define LCD_PWRVFOL 0x01 /* Power control mode - Voltage follower cirquit ON */
/*** LCD Static indicator states ***/
#define LCD_SIS_OFF 0x00 /* Static indicator register set - OFF state */
#define LCD_SIS_BL 0x01 /* Static indicator register set - 1s blink state */
#define LCD_SIS_RBL 0x02 /* Static indicator register set - .5s rapid blink state */
#define LCD_SIS_ON 0x03 /* Static indicator register set - constantly on state */
/*** LCD functions special parameters (commands) ***/
#define LCD_PREVP 0x80 /* Page number for moving to previous */
#define LCD_NEXTP 0x81 /* or next page */
#define LCD_ERR_P 0xFF /* Error in page number */
/*** LCD initialization settings ***/
#define LCD_BIAS LCD_BIAS9 /* Bias: 1/9 */
#define LCD_ADCMODE LCD_ADC_NRM /* ADC mode: normal */
#define LCD_COMDIR LCD_C_NRM /* Common output mode: normal */
#define LCD_RRATIO 0 /* Resistor ratio: 0 */
#define LCD_CNTRST 0x1C /* electronic volume: 1Ch */
#define LCD_POWERM (LCD_PWRBSTR | LCD_PWRVREG | LCD_PWRVFOL) /* Power mode: All on */
/**************************************************************************************/
static inline unsigned int sed156x_transfer(unsigned int val)
{
unsigned int rx;
int b;
rx = 0; b = 8;
while (--b >= 0) {
SED156X_SPI_TXD(val & 0x80);
val <<= 1;
SED156X_SPI_CLK_TOGGLE();
SED156X_SPI_BIT_DELAY();
rx <<= 1;
if (SED156X_SPI_RXD())
rx |= 1;
SED156X_SPI_CLK_TOGGLE();
SED156X_SPI_BIT_DELAY();
}
return rx;
}
unsigned int sed156x_data_transfer(unsigned int val)
{
unsigned int rx;
SED156X_SPI_CLK(1);
SED156X_CS(0);
SED156X_A0(1);
rx = sed156x_transfer(val);
SED156X_CS(1);
return rx;
}
void sed156x_data_block_transfer(const u8 *p, int size)
{
SED156X_SPI_CLK(1);
SED156X_CS(0);
SED156X_A0(1);
while (--size >= 0)
sed156x_transfer(*p++);
SED156X_CS(1);
}
unsigned int sed156x_cmd_transfer(unsigned int val)
{
unsigned int rx;
SED156X_SPI_CLK(1);
SED156X_CS(0);
SED156X_A0(0);
rx = sed156x_transfer(val);
SED156X_CS(1);
SED156X_A0(1);
return rx;
}
/******************************************************************************/
static u8 hw_screen[LCD_PAGES][LCD_COLUMNS];
static u8 last_hw_screen[LCD_PAGES][LCD_COLUMNS];
static u8 sw_screen[LCD_BYTE_WIDTH * LCD_HEIGHT];
void sed156x_sync(void)
{
int i, j, last_page;
u8 *d;
const u8 *s, *e, *b, *r;
u8 v0, v1, v2, v3, v4, v5, v6, v7;
/* copy and rotate sw_screen to hw_screen */
for (i = 0; i < LCD_HEIGHT / 8; i++) {
d = &hw_screen[i][0];
s = &sw_screen[LCD_BYTE_WIDTH * 8 * i + LCD_BYTE_WIDTH - 1];
for (j = 0; j < LCD_WIDTH / 8; j++) {
v0 = s[0 * LCD_BYTE_WIDTH];
v1 = s[1 * LCD_BYTE_WIDTH];
v2 = s[2 * LCD_BYTE_WIDTH];
v3 = s[3 * LCD_BYTE_WIDTH];
v4 = s[4 * LCD_BYTE_WIDTH];
v5 = s[5 * LCD_BYTE_WIDTH];
v6 = s[6 * LCD_BYTE_WIDTH];
v7 = s[7 * LCD_BYTE_WIDTH];
d[0] = ((v7 & 0x01) << 7) |
((v6 & 0x01) << 6) |
((v5 & 0x01) << 5) |
((v4 & 0x01) << 4) |
((v3 & 0x01) << 3) |
((v2 & 0x01) << 2) |
((v1 & 0x01) << 1) |
(v0 & 0x01) ;
d[1] = ((v7 & 0x02) << 6) |
((v6 & 0x02) << 5) |
((v5 & 0x02) << 4) |
((v4 & 0x02) << 3) |
((v3 & 0x02) << 2) |
((v2 & 0x02) << 1) |
((v1 & 0x02) << 0) |
((v0 & 0x02) >> 1) ;
d[2] = ((v7 & 0x04) << 5) |
((v6 & 0x04) << 4) |
((v5 & 0x04) << 3) |
((v4 & 0x04) << 2) |
((v3 & 0x04) << 1) |
(v2 & 0x04) |
((v1 & 0x04) >> 1) |
((v0 & 0x04) >> 2) ;
d[3] = ((v7 & 0x08) << 4) |
((v6 & 0x08) << 3) |
((v5 & 0x08) << 2) |
((v4 & 0x08) << 1) |
(v3 & 0x08) |
((v2 & 0x08) >> 1) |
((v1 & 0x08) >> 2) |
((v0 & 0x08) >> 3) ;
d[4] = ((v7 & 0x10) << 3) |
((v6 & 0x10) << 2) |
((v5 & 0x10) << 1) |
(v4 & 0x10) |
((v3 & 0x10) >> 1) |
((v2 & 0x10) >> 2) |
((v1 & 0x10) >> 3) |
((v0 & 0x10) >> 4) ;
d[5] = ((v7 & 0x20) << 2) |
((v6 & 0x20) << 1) |
(v5 & 0x20) |
((v4 & 0x20) >> 1) |
((v3 & 0x20) >> 2) |
((v2 & 0x20) >> 3) |
((v1 & 0x20) >> 4) |
((v0 & 0x20) >> 5) ;
d[6] = ((v7 & 0x40) << 1) |
(v6 & 0x40) |
((v5 & 0x40) >> 1) |
((v4 & 0x40) >> 2) |
((v3 & 0x40) >> 3) |
((v2 & 0x40) >> 4) |
((v1 & 0x40) >> 5) |
((v0 & 0x40) >> 6) ;
d[7] = (v7 & 0x80) |
((v6 & 0x80) >> 1) |
((v5 & 0x80) >> 2) |
((v4 & 0x80) >> 3) |
((v3 & 0x80) >> 4) |
((v2 & 0x80) >> 5) |
((v1 & 0x80) >> 6) |
((v0 & 0x80) >> 7) ;
d += 8;
s--;
}
}
/* and now output only the differences */
for (i = 0; i < LCD_PAGES; i++) {
b = &hw_screen[i][0];
e = &hw_screen[i][LCD_COLUMNS];
d = &last_hw_screen[i][0];
s = b;
last_page = -1;
/* update only the differences */
do {
while (s < e && *s == *d) {
s++;
d++;
}
if (s == e)
break;
r = s;
while (s < e && *s != *d)
*d++ = *s++;
j = r - b;
if (i != last_page) {
sed156x_cmd_transfer(LCD_PADDR | i);
last_page = i;
}
sed156x_cmd_transfer(LCD_CADRH | ((j >> 4) & 0x0F));
sed156x_cmd_transfer(LCD_CADRL | (j & 0x0F));
sed156x_data_block_transfer(r, s - r);
} while (s < e);
}
/********
for (i = 0; i < LCD_PAGES; i++) {
sed156x_cmd_transfer(LCD_PADDR | i);
sed156x_cmd_transfer(LCD_CADRH | 0);
sed156x_cmd_transfer(LCD_CADRL | 0);
sed156x_data_block_transfer(&hw_screen[i][0], LCD_COLUMNS);
}
memcpy(last_hw_screen, hw_screen, sizeof(last_hw_screen));
********/
}
void sed156x_clear(void)
{
memset(sw_screen, 0, sizeof(sw_screen));
}
void sed156x_output_at(int x, int y, const char *str, int size)
{
int i, j;
u8 *p;
const u8 *s;
if ((unsigned int)y >= LCD_TEXT_HEIGHT || (unsigned int)x >= LCD_TEXT_WIDTH)
return;
p = &sw_screen[y * VIDEO_FONT_HEIGHT * LCD_BYTE_WIDTH + x * VIDEO_FONT_BYTE_WIDTH];
while (--size >= 0) {
s = &video_fontdata[((int)*str++ & 0xff) * VIDEO_FONT_BYTE_WIDTH * VIDEO_FONT_HEIGHT];
for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
for (j = 0; j < VIDEO_FONT_BYTE_WIDTH; j++)
*p++ = *s++;
p += LCD_BYTE_WIDTH - VIDEO_FONT_BYTE_WIDTH;
}
p -= (LCD_BYTE_LINESZ - VIDEO_FONT_BYTE_WIDTH);
if (x >= LCD_TEXT_WIDTH)
break;
x++;
}
}
void sed156x_reverse_at(int x, int y, int size)
{
int i, j;
u8 *p;
if ((unsigned int)y >= LCD_TEXT_HEIGHT || (unsigned int)x >= LCD_TEXT_WIDTH)
return;
p = &sw_screen[y * VIDEO_FONT_HEIGHT * LCD_BYTE_WIDTH + x * VIDEO_FONT_BYTE_WIDTH];
while (--size >= 0) {
for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
for (j = 0; j < VIDEO_FONT_BYTE_WIDTH; j++, p++)
*p = ~*p;
p += LCD_BYTE_WIDTH - VIDEO_FONT_BYTE_WIDTH;
}
p -= (LCD_BYTE_LINESZ - VIDEO_FONT_BYTE_WIDTH);
if (x >= LCD_TEXT_WIDTH)
break;
x++;
}
}
void sed156x_scroll_line(void)
{
memmove(&sw_screen[0],
&sw_screen[LCD_BYTE_LINESZ],
LCD_BYTE_WIDTH * (LCD_HEIGHT - VIDEO_FONT_HEIGHT));
}
void sed156x_scroll(int dx, int dy)
{
u8 *p1 = NULL, *p2 = NULL, *p3 = NULL; /* pacify gcc */
int adx, ady, i, sz;
adx = dx > 0 ? dx : -dx;
ady = dy > 0 ? dy : -dy;
/* overscroll? erase everything */
if (adx >= LCD_TEXT_WIDTH || ady >= LCD_TEXT_HEIGHT) {
memset(sw_screen, 0, sizeof(sw_screen));
return;
}
sz = LCD_BYTE_LINESZ * ady;
if (dy > 0) {
p1 = &sw_screen[0];
p2 = &sw_screen[sz];
p3 = &sw_screen[LCD_BYTE_WIDTH * LCD_HEIGHT - sz];
} else if (dy < 0) {
p1 = &sw_screen[sz];
p2 = &sw_screen[0];
p3 = &sw_screen[0];
}
if (ady > 0) {
memmove(p1, p2, LCD_BYTE_WIDTH * LCD_HEIGHT - sz);
memset(p3, 0, sz);
}
sz = VIDEO_FONT_BYTE_WIDTH * adx;
if (dx > 0) {
p1 = &sw_screen[0];
p2 = &sw_screen[0] + sz;
p3 = &sw_screen[0] + LCD_BYTE_WIDTH - sz;
} else if (dx < 0) {
p1 = &sw_screen[0] + sz;
p2 = &sw_screen[0];
p3 = &sw_screen[0];
}
/* xscroll */
if (adx > 0) {
for (i = 0; i < LCD_HEIGHT; i++) {
memmove(p1, p2, LCD_BYTE_WIDTH - sz);
memset(p3, 0, sz);
p1 += LCD_BYTE_WIDTH;
p2 += LCD_BYTE_WIDTH;
p3 += LCD_BYTE_WIDTH;
}
}
}
void sed156x_init(void)
{
int i;
SED156X_CS(1);
SED156X_A0(1);
/* Send initialization commands to the LCD */
sed156x_cmd_transfer(LCD_OFF); /* Turn display OFF */
sed156x_cmd_transfer(LCD_BIAS); /* set the LCD Bias, */
sed156x_cmd_transfer(LCD_ADCMODE); /* ADC mode, */
sed156x_cmd_transfer(LCD_COMDIR); /* common output mode, */
sed156x_cmd_transfer(LCD_RESRT | LCD_RRATIO); /* resistor ratio, */
sed156x_cmd_transfer(LCD_EVSET); /* electronic volume, */
sed156x_cmd_transfer(LCD_CNTRST);
sed156x_cmd_transfer(LCD_PWRMD | LCD_POWERM); /* and power mode */
sed156x_cmd_transfer(LCD_PADDR | 0); /* cursor home */
sed156x_cmd_transfer(LCD_CADRH | 0);
sed156x_cmd_transfer(LCD_CADRL | 0);
sed156x_cmd_transfer(LCD_LADDR | 0); /* and display start line */
sed156x_cmd_transfer(LCD_DSP_NRM); /* LCD display Normal */
/* clear everything */
memset(sw_screen, 0, sizeof(sw_screen));
memset(hw_screen, 0, sizeof(hw_screen));
memset(last_hw_screen, 0, sizeof(last_hw_screen));
for (i = 0; i < LCD_PAGES; i++) {
sed156x_cmd_transfer(LCD_PADDR | i);
sed156x_cmd_transfer(LCD_CADRH | 0);
sed156x_cmd_transfer(LCD_CADRL | 0);
sed156x_data_block_transfer(&hw_screen[i][0], LCD_COLUMNS);
}
sed156x_clear();
sed156x_sync();
sed156x_cmd_transfer(LCD_ON); /* Turn display ON */
}
#endif /* CONFIG_SED156X */

View File

@@ -0,0 +1,77 @@
/*
* (C) Copyright 2004 Atmark Techno, Inc.
*
* Yasushi SHOJI <yashi@atmark-techno.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>
#ifdef CONFIG_MICROBLZE
#include <asm/serial_xuartlite.h>
/* FIXME: we should convert these to in32 and out32 */
#define IO_WORD(offset) (*(volatile unsigned long *)(offset))
#define IO_SERIAL(offset) IO_WORD(CONFIG_SERIAL_BASE + (offset))
#define IO_SERIAL_RX_FIFO IO_SERIAL(XUL_RX_FIFO_OFFSET)
#define IO_SERIAL_TX_FIFO IO_SERIAL(XUL_TX_FIFO_OFFSET)
#define IO_SERIAL_STATUS IO_SERIAL(XUL_STATUS_REG_OFFSET)
#define IO_SERIAL_CONTROL IO_SERIAL(XUL_CONTROL_REG_OFFSET)
int serial_init(void)
{
/* FIXME: Nothing for now. We should initialize fifo, etc */
return 0;
}
void serial_setbrg(void)
{
/* FIXME: what's this for? */
}
void serial_putc(const char c)
{
if (c == '\n') serial_putc('\r');
while (IO_SERIAL_STATUS & XUL_SR_TX_FIFO_FULL);
IO_SERIAL_TX_FIFO = (unsigned char) (c & 0xff);
return 0;
}
void serial_puts(const char * s)
{
while (*s) {
serial_putc(*s++);
}
}
int serial_getc(void)
{
while (!(IO_SERIAL_STATUS & XUL_SR_RX_FIFO_VALID_DATA));
return IO_SERIAL_RX_FIFO & 0xff;
}
int serial_tstc(void)
{
return (IO_SERIAL_STATUS & XUL_SR_RX_FIFO_VALID_DATA);
}
#endif /* CONFIG_MICROBLZE */

104
drivers/sl811.h Normal file
View File

@@ -0,0 +1,104 @@
#ifndef __UBOOT_SL811_H
#define __UBOOT_SL811_H
#undef SL811_DEBUG
#ifdef SL811_DEBUG
#define PDEBUG(level, fmt, args...) \
if (debug >= (level)) printf("[%s:%d] " fmt, \
__PRETTY_FUNCTION__, __LINE__ , ## args)
#else
#define PDEBUG(level, fmt, args...) do {} while(0)
#endif
/* Sl811 host control register */
#define SL811_CTRL_A 0x00
#define SL811_ADDR_A 0x01
#define SL811_LEN_A 0x02
#define SL811_STS_A 0x03 /* read */
#define SL811_PIDEP_A 0x03 /* write */
#define SL811_CNT_A 0x04 /* read */
#define SL811_DEV_A 0x04 /* write */
#define SL811_CTRL1 0x05
#define SL811_INTR 0x06
#define SL811_CTRL_B 0x08
#define SL811_ADDR_B 0x09
#define SL811_LEN_B 0x0A
#define SL811_STS_B 0x0B /* read */
#define SL811_PIDEP_B 0x0B /* write */
#define SL811_CNT_B 0x0C /* read */
#define SL811_DEV_B 0x0C /* write */
#define SL811_INTRSTS 0x0D /* write clears bitwise */
#define SL811_HWREV 0x0E /* read */
#define SL811_SOFLOW 0x0E /* write */
#define SL811_SOFCNTDIV 0x0F /* read */
#define SL811_CTRL2 0x0F /* write */
/* USB control register bits (addr 0x00 and addr 0x08) */
#define SL811_USB_CTRL_ARM 0x01
#define SL811_USB_CTRL_ENABLE 0x02
#define SL811_USB_CTRL_DIR_OUT 0x04
#define SL811_USB_CTRL_ISO 0x10
#define SL811_USB_CTRL_SOF 0x20
#define SL811_USB_CTRL_TOGGLE_1 0x40
#define SL811_USB_CTRL_PREAMBLE 0x80
/* USB status register bits (addr 0x03 and addr 0x0B) */
#define SL811_USB_STS_ACK 0x01
#define SL811_USB_STS_ERROR 0x02
#define SL811_USB_STS_TIMEOUT 0x04
#define SL811_USB_STS_TOGGLE_1 0x08
#define SL811_USB_STS_SETUP 0x10
#define SL811_USB_STS_OVERFLOW 0x20
#define SL811_USB_STS_NAK 0x40
#define SL811_USB_STS_STALL 0x80
/* Control register 1 bits (addr 0x05) */
#define SL811_CTRL1_SOF 0x01
#define SL811_CTRL1_RESET 0x08
#define SL811_CTRL1_JKSTATE 0x10
#define SL811_CTRL1_SPEED_LOW 0x20
#define SL811_CTRL1_SUSPEND 0x40
/* Interrut enable (addr 0x06) and interrupt status register bits (addr 0x0D) */
#define SL811_INTR_DONE_A 0x01
#define SL811_INTR_DONE_B 0x02
#define SL811_INTR_SOF 0x10
#define SL811_INTR_INSRMV 0x20
#define SL811_INTR_DETECT 0x40
#define SL811_INTR_NOTPRESENT 0x40
#define SL811_INTR_SPEED_FULL 0x80 /* only in status reg */
/* HW rev and SOF lo register bits (addr 0x0E) */
#define SL811_HWR_HWREV 0xF0
/* SOF counter and control reg 2 (addr 0x0F) */
#define SL811_CTL2_SOFHI 0x3F
#define SL811_CTL2_DSWAP 0x40
#define SL811_CTL2_HOST 0x80
/* Set up for 1-ms SOF time. */
#define SL811_12M_LOW 0xE0
#define SL811_12M_HI 0x2E
#define SL811_DATA_START 0x10
#define SL811_DATA_LIMIT 240
/* Requests: bRequest << 8 | bmRequestType */
#define RH_GET_STATUS 0x0080
#define RH_CLEAR_FEATURE 0x0100
#define RH_SET_FEATURE 0x0300
#define RH_SET_ADDRESS 0x0500
#define RH_GET_DESCRIPTOR 0x0680
#define RH_SET_DESCRIPTOR 0x0700
#define RH_GET_CONFIGURATION 0x0880
#define RH_SET_CONFIGURATION 0x0900
#define RH_GET_STATE 0x0280
#define RH_GET_INTERFACE 0x0A80
#define RH_SET_INTERFACE 0x0B00
#define RH_SYNC_FRAME 0x0C80
#define PIDEP(pid, ep) (((pid) & 0x0f) << 4 | (ep))
#endif /* __UBOOT_SL811_H */

705
drivers/sl811_usb.c Normal file
View File

@@ -0,0 +1,705 @@
/*
* (C) Copyright 2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* This code is based on linux driver for sl811hs chip, source at
* drivers/usb/host/sl811.c:
*
* SL811 Host Controller Interface driver for USB.
*
* Copyright (c) 2003/06, Courage Co., Ltd.
*
* Based on:
* 1.uhci.c by Linus Torvalds, Johannes Erdfelt, Randy Dunlap,
* Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber,
* Adam Richter, Gregory P. Smith;
* 2.Original SL811 driver (hc_sl811.o) by Pei Liu <pbl@cypress.com>
* 3.Rewrited as sl811.o by Yin Aihua <yinah:couragetech.com.cn>
*
* 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_USB_SL811HS
#include <mpc8xx.h>
#include <usb.h>
#include "sl811.h"
#include "../board/kup/common/kup.h"
#ifdef __PPC__
# define EIEIO __asm__ volatile ("eieio")
#else
# define EIEIO /* nothing */
#endif
#define SL811_ADR (0x50000000)
#define SL811_DAT (0x50000001)
#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
#ifdef SL811_DEBUG
static int debug = 9;
#endif
static int root_hub_devnum = 0;
static struct usb_port_status rh_status = { 0 };/* root hub port status */
static int sl811_rh_submit_urb(struct usb_device *usb_dev, unsigned long pipe,
void *data, int buf_len, struct devrequest *cmd);
static void sl811_write (__u8 index, __u8 data)
{
*(volatile unsigned char *) (SL811_ADR) = index;
EIEIO;
*(volatile unsigned char *) (SL811_DAT) = data;
EIEIO;
}
static __u8 sl811_read (__u8 index)
{
__u8 data;
*(volatile unsigned char *) (SL811_ADR) = index;
EIEIO;
data = *(volatile unsigned char *) (SL811_DAT);
EIEIO;
return (data);
}
/*
* Read consecutive bytes of data from the SL811H/SL11H buffer
*/
static void inline sl811_read_buf(__u8 offset, __u8 *buf, __u8 size)
{
*(volatile unsigned char *) (SL811_ADR) = offset;
EIEIO;
while (size--) {
*buf++ = *(volatile unsigned char *) (SL811_DAT);
EIEIO;
}
}
/*
* Write consecutive bytes of data to the SL811H/SL11H buffer
*/
static void inline sl811_write_buf(__u8 offset, __u8 *buf, __u8 size)
{
*(volatile unsigned char *) (SL811_ADR) = offset;
EIEIO;
while (size--) {
*(volatile unsigned char *) (SL811_DAT) = *buf++;
EIEIO;
}
}
int usb_init_kup4x (void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
int i;
unsigned char tmp;
memctl = &immap->im_memctl;
memctl->memc_or7 = 0xFFFF8726;
memctl->memc_br7 = 0x50000401; /* start at 0x50000000 */
/* BP 14 low = USB ON */
immap->im_cpm.cp_pbdat &= ~(BP_USB_VCC);
/* PB 14 nomal port */
immap->im_cpm.cp_pbpar &= ~(BP_USB_VCC);
/* output */
immap->im_cpm.cp_pbdir |= (BP_USB_VCC);
puts ("USB: ");
for (i = 0x10; i < 0xff; i++) {
sl811_write(i, i);
tmp = (sl811_read(i));
if (tmp != i) {
printf ("SL811 compare error index=0x%02x read=0x%02x\n", i, tmp);
return (-1);
}
}
printf ("SL811 ready\n");
return (0);
}
/*
* This function resets SL811HS controller and detects the speed of
* the connecting device
*
* Return: 0 = no device attached; 1 = USB device attached
*/
static int sl811_hc_reset(void)
{
int status ;
sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_12M_HI);
sl811_write(SL811_CTRL1, SL811_CTRL1_RESET);
mdelay(20);
/* Disable hardware SOF generation, clear all irq status. */
sl811_write(SL811_CTRL1, 0);
mdelay(2);
sl811_write(SL811_INTRSTS, 0xff);
status = sl811_read(SL811_INTRSTS);
if (status & SL811_INTR_NOTPRESENT) {
/* Device is not present */
PDEBUG(0, "Device not present\n");
rh_status.wPortStatus &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE);
rh_status.wPortChange |= USB_PORT_STAT_C_CONNECTION;
sl811_write(SL811_INTR, SL811_INTR_INSRMV);
return 0;
}
/* Send SOF to address 0, endpoint 0. */
sl811_write(SL811_LEN_B, 0);
sl811_write(SL811_PIDEP_B, PIDEP(USB_PID_SOF, 0));
sl811_write(SL811_DEV_B, 0x00);
sl811_write(SL811_SOFLOW, SL811_12M_LOW);
if (status & SL811_INTR_SPEED_FULL) {
/* full speed device connect directly to root hub */
PDEBUG (0, "Full speed Device attached\n");
sl811_write(SL811_CTRL1, SL811_CTRL1_RESET);
mdelay(20);
sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_12M_HI);
sl811_write(SL811_CTRL1, SL811_CTRL1_SOF);
/* start the SOF or EOP */
sl811_write(SL811_CTRL_B, SL811_USB_CTRL_ARM);
rh_status.wPortStatus |= USB_PORT_STAT_CONNECTION;
rh_status.wPortStatus &= ~USB_PORT_STAT_LOW_SPEED;
mdelay(2);
sl811_write(SL811_INTRSTS, 0xff);
} else {
/* slow speed device connect directly to root-hub */
PDEBUG(0, "Low speed Device attached\n");
sl811_write(SL811_CTRL1, SL811_CTRL1_RESET);
mdelay(20);
sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_CTL2_DSWAP | SL811_12M_HI);
sl811_write(SL811_CTRL1, SL811_CTRL1_SPEED_LOW | SL811_CTRL1_SOF);
/* start the SOF or EOP */
sl811_write(SL811_CTRL_B, SL811_USB_CTRL_ARM);
rh_status.wPortStatus |= USB_PORT_STAT_CONNECTION | USB_PORT_STAT_LOW_SPEED;
mdelay(2);
sl811_write(SL811_INTRSTS, 0xff);
}
rh_status.wPortChange |= USB_PORT_STAT_C_CONNECTION;
sl811_write(SL811_INTR, /*SL811_INTR_INSRMV*/SL811_INTR_DONE_A);
return 1;
}
int usb_lowlevel_init(void)
{
root_hub_devnum = 0;
sl811_hc_reset();
return 0;
}
int usb_lowlevel_stop(void)
{
sl811_hc_reset();
return 0;
}
int sl811_send_packet(int dir_to_host, int data1, __u8 *buffer, int len)
{
__u8 ctrl = SL811_USB_CTRL_ARM | SL811_USB_CTRL_ENABLE;
__u16 status;
int err = 0;
if (len > 239)
return -1;
if (!dir_to_host)
ctrl |= SL811_USB_CTRL_DIR_OUT;
if (data1)
ctrl |= SL811_USB_CTRL_TOGGLE_1;
sl811_write(SL811_ADDR_A, 0x10);
sl811_write(SL811_LEN_A, len);
if (!dir_to_host && len)
sl811_write_buf(0x10, buffer, len);
while (err < 3) {
if (sl811_read(SL811_SOFCNTDIV)*64 < len * 8 * 2)
ctrl |= SL811_USB_CTRL_SOF;
else
ctrl &= ~SL811_USB_CTRL_SOF;
sl811_write(SL811_CTRL_A, ctrl);
while (!(sl811_read(SL811_INTRSTS) & SL811_INTR_DONE_A))
; /* do nothing */
sl811_write(SL811_INTRSTS, 0xff);
status = sl811_read(SL811_STS_A);
if (status & SL811_USB_STS_ACK) {
int remainder = sl811_read(SL811_CNT_A);
if (remainder) {
PDEBUG(0, "usb transfer remainder = %d\n", remainder);
len -= remainder;
}
if (dir_to_host && len)
sl811_read_buf(0x10, buffer, len);
return len;
}
if ((status & SL811_USB_STS_NAK) == SL811_USB_STS_NAK)
continue;
PDEBUG(0, "usb transfer error %#x\n", (int)status);
err++;
}
return -1;
}
int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
int len)
{
int dir_out = usb_pipeout(pipe);
int ep = usb_pipeendpoint(pipe);
__u8* buf = (__u8*)buffer;
int max = usb_maxpacket(dev, pipe);
int done = 0;
PDEBUG(7, "dev = %ld pipe = %ld buf = %p size = %d dir_out = %d\n",
usb_pipedevice(pipe), usb_pipeendpoint(pipe), buffer, len, dir_out);
dev->status = 0;
sl811_write(SL811_DEV_A, usb_pipedevice(pipe));
sl811_write(SL811_PIDEP_A, PIDEP(!dir_out ? USB_PID_IN : USB_PID_OUT, ep));
while (done < len) {
int res = sl811_send_packet(!dir_out, usb_gettoggle(dev, ep, dir_out),
buf+done,
max > len - done ? len - done : max);
if (res < 0) {
dev->status = res;
return res;
}
if (!dir_out && res < max) /* short packet */
break;
done += res;
usb_dotoggle(dev, ep, dir_out);
}
dev->act_len = done;
return 0;
}
int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
int len,struct devrequest *setup)
{
int done = 0;
int devnum = usb_pipedevice(pipe);
dev->status = 0;
if (devnum == root_hub_devnum)
return sl811_rh_submit_urb(dev, pipe, buffer, len, setup);
PDEBUG(7, "dev = %d pipe = %ld buf = %p size = %d rt = %#x req = %#x\n",
devnum, usb_pipeendpoint(pipe), buffer, len, (int)setup->requesttype,
(int)setup->request);
sl811_write(SL811_DEV_A, devnum);
sl811_write(SL811_PIDEP_A, PIDEP(USB_PID_SETUP, 0));
/* setup phase */
if (sl811_send_packet(0, 0, (__u8*)setup, sizeof(*setup)) == sizeof(*setup)) {
int dir_in = setup->requesttype & USB_DIR_IN;
__u8* buf = (__u8*)buffer;
int data1 = 1;
int max = usb_maxpacket(dev, pipe);
/* data phase */
sl811_write(SL811_PIDEP_A,
PIDEP(dir_in ? USB_PID_IN : USB_PID_OUT, 0));
while (done < len) {
int res = sl811_send_packet(dir_in, data1, buf+done,
max > len - done ? len - done : max);
if (res < 0)
return res;
done += res;
if (dir_in && res < max) /* short packet */
break;
data1 = !data1;
}
/* status phase */
sl811_write(SL811_PIDEP_A,
PIDEP(!dir_in ? USB_PID_IN : USB_PID_OUT, 0));
if (sl811_send_packet(!dir_in, 1, 0, 0) < 0) {
PDEBUG(0, "status phase failed!\n");
dev->status = -1;
}
} else {
PDEBUG(0, "setup phase failed!\n");
dev->status = -1;
}
dev->act_len = done;
return done;
}
int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
int len, int interval)
{
PDEBUG(7, "dev = %p pipe = %#lx buf = %p size = %d int = %d\n", dev, pipe,
buffer, len, interval);
return -1;
}
/*
* SL811 Virtual Root Hub
*/
/* Device descriptor */
static __u8 sl811_rh_dev_des[] =
{
0x12, /* __u8 bLength; */
0x01, /* __u8 bDescriptorType; Device */
0x10, /* __u16 bcdUSB; v1.1 */
0x01,
0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
0x00, /* __u8 bDeviceSubClass; */
0x00, /* __u8 bDeviceProtocol; */
0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
0x00, /* __u16 idVendor; */
0x00,
0x00, /* __u16 idProduct; */
0x00,
0x00, /* __u16 bcdDevice; */
0x00,
0x00, /* __u8 iManufacturer; */
0x02, /* __u8 iProduct; */
0x01, /* __u8 iSerialNumber; */
0x01 /* __u8 bNumConfigurations; */
};
/* Configuration descriptor */
static __u8 sl811_rh_config_des[] =
{
0x09, /* __u8 bLength; */
0x02, /* __u8 bDescriptorType; Configuration */
0x19, /* __u16 wTotalLength; */
0x00,
0x01, /* __u8 bNumInterfaces; */
0x01, /* __u8 bConfigurationValue; */
0x00, /* __u8 iConfiguration; */
0x40, /* __u8 bmAttributes;
Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup,
4..0: resvd */
0x00, /* __u8 MaxPower; */
/* interface */
0x09, /* __u8 if_bLength; */
0x04, /* __u8 if_bDescriptorType; Interface */
0x00, /* __u8 if_bInterfaceNumber; */
0x00, /* __u8 if_bAlternateSetting; */
0x01, /* __u8 if_bNumEndpoints; */
0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */
0x00, /* __u8 if_bInterfaceSubClass; */
0x00, /* __u8 if_bInterfaceProtocol; */
0x00, /* __u8 if_iInterface; */
/* endpoint */
0x07, /* __u8 ep_bLength; */
0x05, /* __u8 ep_bDescriptorType; Endpoint */
0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
0x03, /* __u8 ep_bmAttributes; Interrupt */
0x08, /* __u16 ep_wMaxPacketSize; */
0x00,
0xff /* __u8 ep_bInterval; 255 ms */
};
/* root hub class descriptor*/
static __u8 sl811_rh_hub_des[] =
{
0x09, /* __u8 bLength; */
0x29, /* __u8 bDescriptorType; Hub-descriptor */
0x01, /* __u8 bNbrPorts; */
0x00, /* __u16 wHubCharacteristics; */
0x00,
0x50, /* __u8 bPwrOn2pwrGood; 2ms */
0x00, /* __u8 bHubContrCurrent; 0 mA */
0xfc, /* __u8 DeviceRemovable; *** 7 Ports max *** */
0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */
};
/*
* helper routine for returning string descriptors in UTF-16LE
* input can actually be ISO-8859-1; ASCII is its 7-bit subset
*/
static int ascii2utf (char *s, u8 *utf, int utfmax)
{
int retval;
for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) {
*utf++ = *s++;
*utf++ = 0;
}
return retval;
}
/*
* root_hub_string is used by each host controller's root hub code,
* so that they're identified consistently throughout the system.
*/
int usb_root_hub_string (int id, int serial, char *type, __u8 *data, int len)
{
char buf [30];
/* assert (len > (2 * (sizeof (buf) + 1)));
assert (strlen (type) <= 8);*/
/* language ids */
if (id == 0) {
*data++ = 4; *data++ = 3; /* 4 bytes data */
*data++ = 0; *data++ = 0; /* some language id */
return 4;
/* serial number */
} else if (id == 1) {
sprintf (buf, "%x", serial);
/* product description */
} else if (id == 2) {
sprintf (buf, "USB %s Root Hub", type);
/* id 3 == vendor description */
/* unsupported IDs --> "stall" */
} else
return 0;
data [0] = 2 + ascii2utf (buf, data + 2, len - 2);
data [1] = 3;
return data [0];
}
/* helper macro */
#define OK(x) len = (x); break
/*
* This function handles all USB request to the the virtual root hub
*/
static int sl811_rh_submit_urb(struct usb_device *usb_dev, unsigned long pipe,
void *data, int buf_len, struct devrequest *cmd)
{
__u8 data_buf[16];
__u8 *bufp = data_buf;
int len = 0;
int status = 0;
__u16 bmRType_bReq;
__u16 wValue;
__u16 wIndex;
__u16 wLength;
if (usb_pipeint(pipe)) {
PDEBUG(0, "interrupt transfer unimplemented!\n");
return 0;
}
bmRType_bReq = cmd->requesttype | (cmd->request << 8);
wValue = le16_to_cpu (cmd->value);
wIndex = le16_to_cpu (cmd->index);
wLength = le16_to_cpu (cmd->length);
PDEBUG(5, "submit rh urb, req = %d(%x) val = %#x index = %#x len=%d\n",
bmRType_bReq, bmRType_bReq, wValue, wIndex, wLength);
/* Request Destination:
without flags: Device,
USB_RECIP_INTERFACE: interface,
USB_RECIP_ENDPOINT: endpoint,
USB_TYPE_CLASS means HUB here,
USB_RECIP_OTHER | USB_TYPE_CLASS almost ever means HUB_PORT here
*/
switch (bmRType_bReq) {
case RH_GET_STATUS:
*(__u16 *)bufp = cpu_to_le16(1);
OK(2);
case RH_GET_STATUS | USB_RECIP_INTERFACE:
*(__u16 *)bufp = cpu_to_le16(0);
OK(2);
case RH_GET_STATUS | USB_RECIP_ENDPOINT:
*(__u16 *)bufp = cpu_to_le16(0);
OK(2);
case RH_GET_STATUS | USB_TYPE_CLASS:
*(__u32 *)bufp = cpu_to_le32(0);
OK(4);
case RH_GET_STATUS | USB_RECIP_OTHER | USB_TYPE_CLASS:
*(__u32 *)bufp = cpu_to_le32(rh_status.wPortChange<<16 | rh_status.wPortStatus);
OK(4);
case RH_CLEAR_FEATURE | USB_RECIP_ENDPOINT:
switch (wValue) {
case 1:
OK(0);
}
break;
case RH_CLEAR_FEATURE | USB_TYPE_CLASS:
switch (wValue) {
case C_HUB_LOCAL_POWER:
OK(0);
case C_HUB_OVER_CURRENT:
OK(0);
}
break;
case RH_CLEAR_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:
switch (wValue) {
case USB_PORT_FEAT_ENABLE:
rh_status.wPortStatus &= ~USB_PORT_STAT_ENABLE;
OK(0);
case USB_PORT_FEAT_SUSPEND:
rh_status.wPortStatus &= ~USB_PORT_STAT_SUSPEND;
OK(0);
case USB_PORT_FEAT_POWER:
rh_status.wPortStatus &= ~USB_PORT_STAT_POWER;
OK(0);
case USB_PORT_FEAT_C_CONNECTION:
rh_status.wPortChange &= ~USB_PORT_STAT_C_CONNECTION;
OK(0);
case USB_PORT_FEAT_C_ENABLE:
rh_status.wPortChange &= ~USB_PORT_STAT_C_ENABLE;
OK(0);
case USB_PORT_FEAT_C_SUSPEND:
rh_status.wPortChange &= ~USB_PORT_STAT_C_SUSPEND;
OK(0);
case USB_PORT_FEAT_C_OVER_CURRENT:
rh_status.wPortChange &= ~USB_PORT_STAT_C_OVERCURRENT;
OK(0);
case USB_PORT_FEAT_C_RESET:
rh_status.wPortChange &= ~USB_PORT_STAT_C_RESET;
OK(0);
}
break;
case RH_SET_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
rh_status.wPortStatus |= USB_PORT_STAT_SUSPEND;
OK(0);
case USB_PORT_FEAT_RESET:
rh_status.wPortStatus |= USB_PORT_STAT_RESET;
rh_status.wPortChange = 0;
rh_status.wPortChange |= USB_PORT_STAT_C_RESET;
rh_status.wPortStatus &= ~USB_PORT_STAT_RESET;
rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;
OK(0);
case USB_PORT_FEAT_POWER:
rh_status.wPortStatus |= USB_PORT_STAT_POWER;
OK(0);
case USB_PORT_FEAT_ENABLE:
rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;
OK(0);
}
break;
case RH_SET_ADDRESS:
root_hub_devnum = wValue;
OK(0);
case RH_GET_DESCRIPTOR:
switch ((wValue & 0xff00) >> 8) {
case USB_DT_DEVICE:
len = sizeof(sl811_rh_dev_des);
bufp = sl811_rh_dev_des;
OK(len);
case USB_DT_CONFIG:
len = sizeof(sl811_rh_config_des);
bufp = sl811_rh_config_des;
OK(len);
case USB_DT_STRING:
len = usb_root_hub_string(wValue & 0xff, (int)(long)0, "SL811HS", data, wLength);
if (len > 0) {
bufp = data;
OK(len);
}
default:
status = -32;
}
break;
case RH_GET_DESCRIPTOR | USB_TYPE_CLASS:
len = sizeof(sl811_rh_hub_des);
bufp = sl811_rh_hub_des;
OK(len);
case RH_GET_CONFIGURATION:
bufp[0] = 0x01;
OK(1);
case RH_SET_CONFIGURATION:
OK(0);
default:
PDEBUG(1, "unsupported root hub command\n");
status = -32;
}
len = min(len, buf_len);
if (data != bufp)
memcpy(data, bufp, len);
PDEBUG(5, "len = %d, status = %d\n", len, status);
usb_dev->status = status;
usb_dev->act_len = len;
return status == 0 ? len : status;
}
#endif /* CONFIG_USB_SL811HS */

View File

@@ -45,6 +45,10 @@ ifeq ($(ARCH),m68k)
LOAD_ADDR = 0x20000 -L $(clibdir)
endif
ifeq ($(ARCH),microblaze)
LOAD_ADDR = 0x80F00000
endif
include $(TOPDIR)/config.mk
SREC = hello_world.srec

View File

@@ -51,6 +51,9 @@ SECTIONS
.sdata : { *(.sdata) }
. = ALIGN(4);
__bss_start = .;
.sbss : { *(.sbss) }
.bss : { *(.bss) }
_end = .;
}

View File

@@ -57,4 +57,5 @@ SECTIONS
}
. = ALIGN(4);
__bss_end = .;
_end = .;
}

View File

@@ -94,6 +94,18 @@ gd_t *global_data;
" move.l (%%a0), %%a0\n" \
" jmp (%%a0)\n" \
: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "a0");
#elif defined(CONFIG_MICROBLZE)
/*
* r31 holds the pointer to the global_data. r5 is a call-clobbered.
*/
#define EXPORT_FUNC(x) \
asm volatile ( \
" .globl " #x "\n" \
#x ":\n" \
" lwi r5, r31, %0\n" \
" lwi r5, r5, %1\n" \
" bra r5\n" \
: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r5");
#else
#error stubs definition missing for this architecture
#endif
@@ -110,8 +122,17 @@ static void __attribute__((unused)) dummy(void)
#include <_exports.h>
}
extern unsigned long __bss_start, _end;
void app_startup(char **argv)
{
unsigned long * cp = &__bss_start;
/* Zero out BSS */
while (cp < &_end) {
*cp++ = 0;
}
#if defined(CONFIG_I386)
/* x86 does not have a dedicated register for passing global_data */
global_data = (gd_t *)argv[-1];

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